Skip to content

Commit

Permalink
feat: clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
janrtvld committed Dec 3, 2024
1 parent 821d4a1 commit 0ad3f72
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 62 deletions.
1 change: 0 additions & 1 deletion apps/easypid/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ config.resolver.nodeModulesPaths = [
path.resolve(workspaceRoot, 'node_modules'),
]
config.resolver.sourceExts = [...config.resolver.sourceExts, 'js', 'json', 'ts', 'tsx', 'cjs', 'mjs']
config.resolver.assetExts = [...config.resolver.assetExts, 'bin']
config.resolver.extraNodeModules = {
// Needed for cosmjs trying to import node crypto
crypto: require.resolve('./src/polyfills/crypto.ts'),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { DisplayImage, FormattedSubmission, TrustedEntity } from '@package/agent'

import type { OverAskingResponse, VerificationAnalysisResult } from '@easypid/use-cases/ValidateVerification'
import type { OverAskingResponse, VerificationAnalysisResult } from '@easypid/use-cases/OverAskingApi'

Check failure on line 3 in apps/easypid/src/features/share/FunkePresentationNotificationScreen.tsx

View workflow job for this annotation

GitHub Actions / Validate

Module '"@easypid/use-cases/OverAskingApi"' has no exported member 'VerificationAnalysisResult'.
import { type SlideStep, SlideWizard } from '@package/app'
import { LoadingRequestSlide } from '../receive/slides/LoadingRequestSlide'
import { VerifyPartySlide } from '../receive/slides/VerifyPartySlide'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OverAskingResponse } from '@easypid/use-cases/ValidateVerification'
import type { OverAskingResponse } from '@easypid/use-cases/OverAskingApi'
import {
AnimatedStack,
Circle,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OverAskingResponse, VerificationAnalysisResult } from '@easypid/use-cases/ValidateVerification'
import type { OverAskingResponse, VerificationAnalysisResult } from '@easypid/use-cases/OverAskingApi'

Check failure on line 1 in apps/easypid/src/features/share/slides/ShareCredentialsSlide.tsx

View workflow job for this annotation

GitHub Actions / Validate

Module '"@easypid/use-cases/OverAskingApi"' has no exported member 'VerificationAnalysisResult'.
import type { DisplayImage, FormattedSubmission } from '@package/agent'
import { DualResponseButtons, usePushToWallet, useScrollViewPosition } from '@package/app'
import { useWizard } from '@package/app'
Expand Down
56 changes: 21 additions & 35 deletions apps/easypid/src/hooks/useOverAskingAi.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useEffect, useState } from 'react'

import { useLLM } from '@easypid/llm/useLLM'
import type { OverAskingResponse, VerificationAnalysisInput } from '@easypid/use-cases/ValidateVerification'
import { analyzeVerification as analyzeVerificationApi } from '@easypid/use-cases/ValidateVerification'

// todos: add a timeout to both api and local calls
import type { OverAskingInput, OverAskingResponse } from '@easypid/use-cases/OverAskingApi'
import { checkForOverAskingApi as analyzeVerificationApi } from '@easypid/use-cases/OverAskingApi'

const fallbackResponse: OverAskingResponse = {
validRequest: 'could_not_determine',
Expand All @@ -17,13 +15,8 @@ export function useOverAskingAi() {

const { generate, response, error, isModelReady, isModelGenerating } = useLLM()

useEffect(() => {
console.log('response', response)
}, [response])

useEffect(() => {
if (error) {
console.error('Error generating using LLM:', error)
setIsProcessingOverAsking(false)
setOverAskingResponse(fallbackResponse)
return
Expand All @@ -32,7 +25,7 @@ export function useOverAskingAi() {
if (!response || isModelGenerating) return

try {
const result = formatResult(response)
const result = formatLocalResult(response)
setOverAskingResponse(result)
} catch (e) {
console.error('Error parsing AI response:', e)
Expand All @@ -41,18 +34,18 @@ export function useOverAskingAi() {
}
}, [response, isModelGenerating, error])

const checkForOverAsking = async (input: VerificationAnalysisInput) => {
const checkForOverAsking = async (input: OverAskingInput) => {
setIsProcessingOverAsking(true)
if (isModelReady) {
console.log('Model ready, using local LLM')
const prompt = formatPrompt(input)
console.debug('Local LLM ready, using local LLM')
const prompt = formatLocalPrompt(input)
await generate(prompt)
} else {
console.log('Local LLM not ready, using API')
console.debug('Local LLM not ready, using API')
await analyzeVerificationApi(input)
.then(setOverAskingResponse)
.catch((e) => {
console.error('Error analyzing verification:', e)
console.error('Error analyzing verification using API:', e)
setOverAskingResponse(fallbackResponse)
})
.finally(() => setIsProcessingOverAsking(false))
Expand All @@ -66,9 +59,15 @@ export function useOverAskingAi() {
}
}

const formatResult = (response: string) => {
// AI responds in XML format, so we need to parse it
// Expected format:
// <response>
// <reason>Your concise reason for the assessment</reason>
// <valid_request>yes</valid_request> <!-- Use 'yes', 'no', or 'could_not_determine' -->
// </response>
const formatLocalResult = (response: string) => {
const match = response.match(/<response>([\s\S]*?)<\/response>/)
if (!match) return
if (!match) return fallbackResponse

const responseContent = match[1]

Expand All @@ -85,13 +84,11 @@ const formatResult = (response: string) => {
return fallbackResponse
}

const formatPrompt = (input: VerificationAnalysisInput) => {
const formatLocalPrompt = (input: OverAskingInput) => {
const cards = input.cards
.map(
(credential) =>
`${credential.name} - ${credential.subtitle}. Requested attributes: ${credential.requestedAttributes.join(', ')}`
)
.map((credential) => `- ${credential.name}. Requested attributes: ${credential.requestedAttributes.join(', ')}`)
.join('\n')

return `
You are an AI assistant specializing in data privacy analysis. Your task is to evaluate data verification requests and determine if they are asking for an appropriate amount of information or if they are overasking.
Expand All @@ -105,10 +102,6 @@ ${input.verifier.name}
${input.verifier.domain}
</verifier_domain>
<request_name>
${input.name}
</request_name>
<request_purpose>
${input.purpose}
</request_purpose>
Expand All @@ -118,20 +111,13 @@ ${cards}
</requested_cards>
Provide a small evaluation of the request, and provide your final response in the following XML structure:
Provide a short reason for your assessment of the request. Use the following XML structure:
<response>
<reason>Your concise reason for the assessment</reason>
<valid_request>yes</valid_request> <!-- Use 'yes', 'no', or 'could_not_determine' -->
</response>
Example of a properly formatted response:
<response>
<reason>Request aligns with purpose. Information amount appropriate. Verifier seems legitimate.</reason>
<valid_request>yes</valid_request>
</response>
Remember: Provide a concise reason and use the correct XML structure in your response. Do not add any text outside of the specified tags.
Remember: DO NOT add any text outside of the specified tags. DO NOT bother responding with anything other than the XML structure.
`
}
28 changes: 13 additions & 15 deletions apps/easypid/src/llm/useLLM.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Platform } from 'react-native'
import { LLAMA3_2_1B_QLORA_URL, LLAMA3_2_1B_TOKENIZER } from 'react-native-executorch'
import { useMMKVBoolean } from 'react-native-mmkv'
import RnExecutorch, { subscribeToDownloadProgress, subscribeToTokenGenerated } from './RnExecutorchModule'
import { DEFAULT_CONTEXT_WINDOW_LENGTH, DEFAULT_SYSTEM_PROMPT, EOT_TOKEN } from './constants'
import { DEFAULT_CONTEXT_WINDOW_LENGTH, EOT_TOKEN } from './constants'
import type { Model, ResourceSource } from './types'

const interrupt = () => {
Expand Down Expand Up @@ -38,13 +38,9 @@ export function removeIsModelDownloading() {
export const useLLM = ({
modelSource = LLAMA3_2_1B_QLORA_URL,
tokenizerSource = LLAMA3_2_1B_TOKENIZER,
systemPrompt = DEFAULT_SYSTEM_PROMPT,
contextWindowLength = DEFAULT_CONTEXT_WINDOW_LENGTH,
}: {
modelSource?: ResourceSource
tokenizerSource?: ResourceSource
systemPrompt?: string
contextWindowLength?: number
} = {}): Model => {
const [error, setError] = useState<string | null>(null)
const [isModelActivated, setIsModelActivated] = useIsModelActivated()
Expand All @@ -55,6 +51,16 @@ export const useLLM = ({
const [downloadProgress, setDownloadProgress] = useState(0)
const initialized = useRef(false)

useEffect(() => {
if (!response) return
console.debug('Local LLM response', response)
}, [response])

useEffect(() => {
if (!error) return
console.debug('Local LLM error', error)
}, [error])

useEffect(() => {
const unsubscribeDownloadProgress = subscribeToDownloadProgress((data) => {
if (data) {
Expand All @@ -77,7 +83,7 @@ export const useLLM = ({
try {
try {
setIsModelDownloading(true)
await RnExecutorch.loadLLM(modelSource, tokenizerSource, systemPrompt, contextWindowLength)
await RnExecutorch.loadLLM(modelSource, tokenizerSource, '', DEFAULT_CONTEXT_WINDOW_LENGTH)
await RnExecutorch
} catch (error) {
console.log('ERROR LOADING MODEL', error)
Expand All @@ -92,15 +98,7 @@ export const useLLM = ({
setError(message)
initialized.current = false
}
}, [
contextWindowLength,
modelSource,
systemPrompt,
tokenizerSource,
setIsModelReady,
setIsModelActivated,
setIsModelDownloading,
])
}, [modelSource, tokenizerSource, setIsModelReady, setIsModelActivated, setIsModelDownloading])

const generate = useCallback(
async (input: string): Promise<void> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const PLAYGROUND_URL = 'https://funke.animo.id'

export const EXCLUDED_ATTRIBUTES_FOR_ANALYSIS = ['Issuing authority', 'Issuing country', 'Issued at', 'Expires at']

export type VerificationAnalysisInput = {
export type OverAskingInput = {
verifier: {
name: string
domain: string
Expand All @@ -21,17 +21,12 @@ export type OverAskingResponse = {
reason: string
}

export type VerificationAnalysisResult = {
isLoading: boolean
result: OverAskingResponse | undefined
}

export const analyzeVerification = async ({
export const checkForOverAskingApi = async ({
verifier,
name,
purpose,
cards,
}: VerificationAnalysisInput): Promise<OverAskingResponse> => {
}: OverAskingInput): Promise<OverAskingResponse> => {
try {
const cardsWithoutExcludedAttributes = cards.map((card) => ({
...card,
Expand Down

0 comments on commit 0ad3f72

Please sign in to comment.