@geenius/ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/config.json +11 -0
- package/.env.example +2 -0
- package/.github/CODEOWNERS +1 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
- package/.github/dependabot.yml +11 -0
- package/.github/workflows/ci.yml +23 -0
- package/.github/workflows/release.yml +29 -0
- package/.node-version +1 -0
- package/.nvmrc +1 -0
- package/.prettierrc +7 -0
- package/.project/ACCOUNT.yaml +4 -0
- package/.project/IDEAS.yaml +7 -0
- package/.project/PROJECT.yaml +11 -0
- package/.project/ROADMAP.yaml +15 -0
- package/CHANGELOG.md +15 -0
- package/CODE_OF_CONDUCT.md +26 -0
- package/CONTRIBUTING.md +61 -0
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/SECURITY.md +18 -0
- package/SUPPORT.md +14 -0
- package/package.json +75 -0
- package/packages/convex/package.json +42 -0
- package/packages/convex/src/index.ts +8 -0
- package/packages/convex/src/mutations/messages.ts +29 -0
- package/packages/convex/src/queries/messages.ts +24 -0
- package/packages/convex/src/schema.ts +20 -0
- package/packages/convex/tsconfig.json +11 -0
- package/packages/convex/tsup.config.ts +17 -0
- package/packages/react/README.md +1 -0
- package/packages/react/package.json +60 -0
- package/packages/react/src/components/AILogTable.tsx +90 -0
- package/packages/react/src/components/ChatWindow.tsx +118 -0
- package/packages/react/src/components/GenerationCard.tsx +73 -0
- package/packages/react/src/components/ImageGenerator.tsx +103 -0
- package/packages/react/src/components/ModelSelector.tsx +44 -0
- package/packages/react/src/components/ModelTestRunner.tsx +148 -0
- package/packages/react/src/components/VoiceSelector.tsx +51 -0
- package/packages/react/src/components/index.ts +9 -0
- package/packages/react/src/hooks/index.ts +12 -0
- package/packages/react/src/hooks/useAI.ts +158 -0
- package/packages/react/src/hooks/useAILogs.ts +40 -0
- package/packages/react/src/hooks/useAIModels.ts +53 -0
- package/packages/react/src/hooks/useChat.ts +141 -0
- package/packages/react/src/hooks/useContentManager.ts +108 -0
- package/packages/react/src/hooks/useImageGeneration.ts +82 -0
- package/packages/react/src/hooks/useMemory.ts +161 -0
- package/packages/react/src/hooks/useModelTest.ts +126 -0
- package/packages/react/src/hooks/useRealtimeAudio.ts +203 -0
- package/packages/react/src/hooks/useSkills.ts +114 -0
- package/packages/react/src/hooks/useTextToSpeech.ts +99 -0
- package/packages/react/src/hooks/useTranscription.ts +119 -0
- package/packages/react/src/hooks/useVideoGeneration.ts +79 -0
- package/packages/react/src/index.ts +42 -0
- package/packages/react/src/pages/AILogsPage.tsx +98 -0
- package/packages/react/src/pages/ChatPage.tsx +42 -0
- package/packages/react/src/pages/ModelTestPage.tsx +33 -0
- package/packages/react/src/pages/index.ts +5 -0
- package/packages/react/tsconfig.json +26 -0
- package/packages/react/tsup.config.ts +22 -0
- package/packages/react-css/README.md +1 -0
- package/packages/react-css/package.json +45 -0
- package/packages/react-css/src/ai.css +857 -0
- package/packages/react-css/src/components/AILogTable.tsx +90 -0
- package/packages/react-css/src/components/ChatWindow.tsx +118 -0
- package/packages/react-css/src/components/GenerationCard.tsx +73 -0
- package/packages/react-css/src/components/ImageGenerator.tsx +103 -0
- package/packages/react-css/src/components/ModelSelector.tsx +44 -0
- package/packages/react-css/src/components/ModelTestRunner.tsx +148 -0
- package/packages/react-css/src/components/VoiceSelector.tsx +51 -0
- package/packages/react-css/src/components/index.ts +9 -0
- package/packages/react-css/src/hooks/index.ts +12 -0
- package/packages/react-css/src/hooks/useAI.ts +153 -0
- package/packages/react-css/src/hooks/useAILogs.ts +40 -0
- package/packages/react-css/src/hooks/useAIModels.ts +51 -0
- package/packages/react-css/src/hooks/useChat.ts +145 -0
- package/packages/react-css/src/hooks/useContentManager.ts +108 -0
- package/packages/react-css/src/hooks/useImageGeneration.ts +82 -0
- package/packages/react-css/src/hooks/useMemory.ts +161 -0
- package/packages/react-css/src/hooks/useModelTest.ts +122 -0
- package/packages/react-css/src/hooks/useRealtimeAudio.ts +203 -0
- package/packages/react-css/src/hooks/useSkills.ts +114 -0
- package/packages/react-css/src/hooks/useTextToSpeech.ts +99 -0
- package/packages/react-css/src/hooks/useTranscription.ts +119 -0
- package/packages/react-css/src/hooks/useVideoGeneration.ts +79 -0
- package/packages/react-css/src/index.ts +35 -0
- package/packages/react-css/src/pages/AILogsPage.tsx +98 -0
- package/packages/react-css/src/pages/ChatPage.tsx +42 -0
- package/packages/react-css/src/pages/ModelTestPage.tsx +33 -0
- package/packages/react-css/src/pages/index.ts +5 -0
- package/packages/react-css/src/styles.css +127 -0
- package/packages/react-css/tsconfig.json +26 -0
- package/packages/react-css/tsup.config.ts +2 -0
- package/packages/shared/README.md +1 -0
- package/packages/shared/package.json +71 -0
- package/packages/shared/src/__tests__/ai.test.ts +67 -0
- package/packages/shared/src/ai-client.ts +243 -0
- package/packages/shared/src/config.ts +235 -0
- package/packages/shared/src/content.ts +249 -0
- package/packages/shared/src/convex/helpers.ts +163 -0
- package/packages/shared/src/convex/index.ts +16 -0
- package/packages/shared/src/convex/schemas.ts +146 -0
- package/packages/shared/src/convex/validators.ts +136 -0
- package/packages/shared/src/index.ts +107 -0
- package/packages/shared/src/memory.ts +197 -0
- package/packages/shared/src/providers/base.ts +103 -0
- package/packages/shared/src/providers/elevenlabs.ts +155 -0
- package/packages/shared/src/providers/index.ts +28 -0
- package/packages/shared/src/providers/openai-compatible.ts +286 -0
- package/packages/shared/src/providers/registry.ts +113 -0
- package/packages/shared/src/providers/replicate-fal.ts +230 -0
- package/packages/shared/src/skills.ts +273 -0
- package/packages/shared/src/types.ts +501 -0
- package/packages/shared/tsconfig.json +25 -0
- package/packages/shared/tsup.config.ts +22 -0
- package/packages/shared/vitest.config.ts +4 -0
- package/packages/solidjs/README.md +1 -0
- package/packages/solidjs/package.json +59 -0
- package/packages/solidjs/src/components/ChatWindow.tsx +78 -0
- package/packages/solidjs/src/components/GenerationCard.tsx +62 -0
- package/packages/solidjs/src/components/ModelTestRunner.tsx +119 -0
- package/packages/solidjs/src/components/index.ts +5 -0
- package/packages/solidjs/src/index.ts +32 -0
- package/packages/solidjs/src/pages/ChatPage.tsx +22 -0
- package/packages/solidjs/src/pages/ModelTestPage.tsx +22 -0
- package/packages/solidjs/src/pages/index.ts +4 -0
- package/packages/solidjs/src/primitives/createAI.ts +79 -0
- package/packages/solidjs/src/primitives/createChat.ts +100 -0
- package/packages/solidjs/src/primitives/createContentManager.ts +61 -0
- package/packages/solidjs/src/primitives/createImageGeneration.ts +46 -0
- package/packages/solidjs/src/primitives/createMemory.ts +127 -0
- package/packages/solidjs/src/primitives/createModelTest.ts +89 -0
- package/packages/solidjs/src/primitives/createSkills.ts +83 -0
- package/packages/solidjs/src/primitives/createTextToSpeech.ts +56 -0
- package/packages/solidjs/src/primitives/createVideoGeneration.ts +46 -0
- package/packages/solidjs/src/primitives/index.ts +8 -0
- package/packages/solidjs/tsconfig.json +27 -0
- package/packages/solidjs/tsup.config.ts +21 -0
- package/packages/solidjs-css/README.md +1 -0
- package/packages/solidjs-css/package.json +44 -0
- package/packages/solidjs-css/src/ai.css +857 -0
- package/packages/solidjs-css/src/components/ChatWindow.tsx +78 -0
- package/packages/solidjs-css/src/components/GenerationCard.tsx +62 -0
- package/packages/solidjs-css/src/components/ModelTestRunner.tsx +119 -0
- package/packages/solidjs-css/src/components/index.ts +5 -0
- package/packages/solidjs-css/src/index.ts +26 -0
- package/packages/solidjs-css/src/pages/ChatPage.tsx +22 -0
- package/packages/solidjs-css/src/pages/ModelTestPage.tsx +22 -0
- package/packages/solidjs-css/src/pages/index.ts +4 -0
- package/packages/solidjs-css/src/primitives/createAI.ts +79 -0
- package/packages/solidjs-css/src/primitives/createChat.ts +100 -0
- package/packages/solidjs-css/src/primitives/createContentManager.ts +61 -0
- package/packages/solidjs-css/src/primitives/createImageGeneration.ts +46 -0
- package/packages/solidjs-css/src/primitives/createMemory.ts +127 -0
- package/packages/solidjs-css/src/primitives/createModelTest.ts +89 -0
- package/packages/solidjs-css/src/primitives/createSkills.ts +83 -0
- package/packages/solidjs-css/src/primitives/createTextToSpeech.ts +56 -0
- package/packages/solidjs-css/src/primitives/createVideoGeneration.ts +46 -0
- package/packages/solidjs-css/src/primitives/index.ts +1 -0
- package/packages/solidjs-css/src/styles.css +127 -0
- package/packages/solidjs-css/tsconfig.json +27 -0
- package/packages/solidjs-css/tsup.config.ts +2 -0
- package/pnpm-workspace.yaml +2 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// @geenius-ai/react — src/hooks/useTranscription.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Audio transcription hook (Whisper, Groq ASR, etc.)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback, useRef } from 'react'
|
|
8
|
+
import { useAction } from 'convex/react'
|
|
9
|
+
|
|
10
|
+
export interface TranscriptionResult {
|
|
11
|
+
text: string
|
|
12
|
+
timestamp: number
|
|
13
|
+
durationMs: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UseTranscriptionOptions {
|
|
17
|
+
transcribeAction: any
|
|
18
|
+
defaultModel?: string
|
|
19
|
+
/** Enable browser microphone recording */
|
|
20
|
+
enableMicrophone?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface UseTranscriptionReturn {
|
|
24
|
+
transcribe: (audioBase64: string, options?: {
|
|
25
|
+
model?: string
|
|
26
|
+
language?: string
|
|
27
|
+
prompt?: string
|
|
28
|
+
}) => Promise<string>
|
|
29
|
+
startRecording: () => Promise<void>
|
|
30
|
+
stopRecording: () => Promise<string>
|
|
31
|
+
isTranscribing: boolean
|
|
32
|
+
isRecording: boolean
|
|
33
|
+
lastResult: TranscriptionResult | null
|
|
34
|
+
error: string | null
|
|
35
|
+
clearError: () => void
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function useTranscription(options: UseTranscriptionOptions): UseTranscriptionReturn {
|
|
39
|
+
const [isTranscribing, setIsTranscribing] = useState(false)
|
|
40
|
+
const [isRecording, setIsRecording] = useState(false)
|
|
41
|
+
const [lastResult, setLastResult] = useState<TranscriptionResult | null>(null)
|
|
42
|
+
const [error, setError] = useState<string | null>(null)
|
|
43
|
+
const mediaRecorderRef = useRef<MediaRecorder | null>(null)
|
|
44
|
+
const chunksRef = useRef<Blob[]>([])
|
|
45
|
+
const action = useAction(options.transcribeAction)
|
|
46
|
+
|
|
47
|
+
const transcribe = useCallback(async (audioBase64: string, opts?: {
|
|
48
|
+
model?: string; language?: string; prompt?: string
|
|
49
|
+
}) => {
|
|
50
|
+
setIsTranscribing(true)
|
|
51
|
+
setError(null)
|
|
52
|
+
const start = Date.now()
|
|
53
|
+
try {
|
|
54
|
+
const text = await action({
|
|
55
|
+
audio: audioBase64,
|
|
56
|
+
model: opts?.model ?? options.defaultModel,
|
|
57
|
+
language: opts?.language,
|
|
58
|
+
prompt: opts?.prompt,
|
|
59
|
+
})
|
|
60
|
+
setLastResult({ text, timestamp: Date.now(), durationMs: Date.now() - start })
|
|
61
|
+
return text
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const msg = err instanceof Error ? err.message : 'Transcription failed'
|
|
64
|
+
setError(msg)
|
|
65
|
+
throw err
|
|
66
|
+
} finally {
|
|
67
|
+
setIsTranscribing(false)
|
|
68
|
+
}
|
|
69
|
+
}, [action, options.defaultModel])
|
|
70
|
+
|
|
71
|
+
const startRecording = useCallback(async () => {
|
|
72
|
+
if (!options.enableMicrophone) throw new Error('Microphone not enabled')
|
|
73
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
|
|
74
|
+
const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' })
|
|
75
|
+
chunksRef.current = []
|
|
76
|
+
mediaRecorder.ondataavailable = (e) => {
|
|
77
|
+
if (e.data.size > 0) chunksRef.current.push(e.data)
|
|
78
|
+
}
|
|
79
|
+
mediaRecorder.start()
|
|
80
|
+
mediaRecorderRef.current = mediaRecorder
|
|
81
|
+
setIsRecording(true)
|
|
82
|
+
}, [options.enableMicrophone])
|
|
83
|
+
|
|
84
|
+
const stopRecording = useCallback(async () => {
|
|
85
|
+
return new Promise<string>((resolve, reject) => {
|
|
86
|
+
const recorder = mediaRecorderRef.current
|
|
87
|
+
if (!recorder) { reject(new Error('Not recording')); return }
|
|
88
|
+
|
|
89
|
+
recorder.onstop = async () => {
|
|
90
|
+
setIsRecording(false)
|
|
91
|
+
const blob = new Blob(chunksRef.current, { type: 'audio/webm' })
|
|
92
|
+
const arrayBuffer = await blob.arrayBuffer()
|
|
93
|
+
const bytes = new Uint8Array(arrayBuffer)
|
|
94
|
+
let binary = ''
|
|
95
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
96
|
+
binary += String.fromCharCode(bytes[i]!)
|
|
97
|
+
}
|
|
98
|
+
const base64 = btoa(binary)
|
|
99
|
+
|
|
100
|
+
// Stop all tracks
|
|
101
|
+
recorder.stream.getTracks().forEach(t => t.stop())
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const text = await transcribe(base64)
|
|
105
|
+
resolve(text)
|
|
106
|
+
} catch (err) {
|
|
107
|
+
reject(err)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
recorder.stop()
|
|
111
|
+
})
|
|
112
|
+
}, [transcribe])
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
transcribe, startRecording, stopRecording,
|
|
116
|
+
isTranscribing, isRecording, lastResult, error,
|
|
117
|
+
clearError: () => setError(null),
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// @geenius-ai/react — src/hooks/useVideoGeneration.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Video generation hook (Replicate, Fal, etc.)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback } from 'react'
|
|
8
|
+
import { useAction } from 'convex/react'
|
|
9
|
+
|
|
10
|
+
export interface GeneratedVideo {
|
|
11
|
+
url: string
|
|
12
|
+
prompt: string
|
|
13
|
+
model: string
|
|
14
|
+
timestamp: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface UseVideoGenerationOptions {
|
|
18
|
+
generateVideoAction: any
|
|
19
|
+
defaultModel?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface UseVideoGenerationReturn {
|
|
23
|
+
generate: (prompt: string, options?: {
|
|
24
|
+
model?: string
|
|
25
|
+
duration?: number
|
|
26
|
+
aspectRatio?: '16:9' | '9:16' | '1:1'
|
|
27
|
+
resolution?: '720p' | '1080p' | '4k'
|
|
28
|
+
startImage?: string
|
|
29
|
+
endImage?: string
|
|
30
|
+
}) => Promise<string>
|
|
31
|
+
videos: GeneratedVideo[]
|
|
32
|
+
isGenerating: boolean
|
|
33
|
+
error: string | null
|
|
34
|
+
clearVideos: () => void
|
|
35
|
+
clearError: () => void
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function useVideoGeneration(options: UseVideoGenerationOptions): UseVideoGenerationReturn {
|
|
39
|
+
const [videos, setVideos] = useState<GeneratedVideo[]>([])
|
|
40
|
+
const [isGenerating, setIsGenerating] = useState(false)
|
|
41
|
+
const [error, setError] = useState<string | null>(null)
|
|
42
|
+
const action = useAction(options.generateVideoAction)
|
|
43
|
+
|
|
44
|
+
const generate = useCallback(async (prompt: string, opts?: {
|
|
45
|
+
model?: string; duration?: number
|
|
46
|
+
aspectRatio?: '16:9' | '9:16' | '1:1'
|
|
47
|
+
resolution?: '720p' | '1080p' | '4k'
|
|
48
|
+
startImage?: string; endImage?: string
|
|
49
|
+
}) => {
|
|
50
|
+
setIsGenerating(true)
|
|
51
|
+
setError(null)
|
|
52
|
+
try {
|
|
53
|
+
const model = opts?.model ?? options.defaultModel ?? 'minimax/video-01'
|
|
54
|
+
const result = await action({
|
|
55
|
+
prompt, model,
|
|
56
|
+
duration: opts?.duration,
|
|
57
|
+
aspectRatio: opts?.aspectRatio,
|
|
58
|
+
resolution: opts?.resolution,
|
|
59
|
+
startImage: opts?.startImage,
|
|
60
|
+
endImage: opts?.endImage,
|
|
61
|
+
})
|
|
62
|
+
const vid: GeneratedVideo = { url: result, prompt, model, timestamp: Date.now() }
|
|
63
|
+
setVideos(prev => [vid, ...prev])
|
|
64
|
+
return result
|
|
65
|
+
} catch (err) {
|
|
66
|
+
const msg = err instanceof Error ? err.message : 'Video generation failed'
|
|
67
|
+
setError(msg)
|
|
68
|
+
throw err
|
|
69
|
+
} finally {
|
|
70
|
+
setIsGenerating(false)
|
|
71
|
+
}
|
|
72
|
+
}, [action, options.defaultModel])
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
generate, videos, isGenerating, error,
|
|
76
|
+
clearVideos: () => setVideos([]),
|
|
77
|
+
clearError: () => setError(null),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// @geenius-ai/react — src/index.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @geenius-ai/react
|
|
5
|
+
*
|
|
6
|
+
* React hooks, headless components, and page compositions for AI-powered
|
|
7
|
+
* Convex applications. All components are unstyled with data-* attributes
|
|
8
|
+
* for easy CSS targeting.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Hooks — Core
|
|
12
|
+
export { useAI, type UseAIOptions, type UseAIReturn } from './hooks/useAI'
|
|
13
|
+
export { useChat, type UseChatOptions, type UseChatReturn } from './hooks/useChat'
|
|
14
|
+
export { useAILogs, type UseAILogsOptions, type UseAILogsReturn } from './hooks/useAILogs'
|
|
15
|
+
export { useModelTest, type UseModelTestOptions, type UseModelTestReturn, type ModelTestResult } from './hooks/useModelTest'
|
|
16
|
+
export { useAIModels, type UseAIModelsOptions, type UseAIModelsReturn } from './hooks/useAIModels'
|
|
17
|
+
|
|
18
|
+
// Hooks — Multi-modal
|
|
19
|
+
export { useImageGeneration, type UseImageGenerationOptions, type UseImageGenerationReturn, type GeneratedImage } from './hooks/useImageGeneration'
|
|
20
|
+
export { useTextToSpeech, type UseTextToSpeechOptions, type UseTextToSpeechReturn } from './hooks/useTextToSpeech'
|
|
21
|
+
export { useVideoGeneration, type UseVideoGenerationOptions, type UseVideoGenerationReturn, type GeneratedVideo } from './hooks/useVideoGeneration'
|
|
22
|
+
export { useTranscription, type UseTranscriptionOptions, type UseTranscriptionReturn, type TranscriptionResult } from './hooks/useTranscription'
|
|
23
|
+
export { useRealtimeAudio, type UseRealtimeAudioOptions, type UseRealtimeAudioReturn } from './hooks/useRealtimeAudio'
|
|
24
|
+
|
|
25
|
+
// Hooks — Content, Memory, Skills
|
|
26
|
+
export { useContentManager, type UseContentManagerOptions, type UseContentManagerReturn } from './hooks/useContentManager'
|
|
27
|
+
export { useMemory, type UseMemoryOptions, type UseMemoryReturn } from './hooks/useMemory'
|
|
28
|
+
export { useSkills, type UseSkillsOptions, type UseSkillsReturn } from './hooks/useSkills'
|
|
29
|
+
|
|
30
|
+
// Components
|
|
31
|
+
export { ChatWindow, type ChatWindowComponentProps } from './components/ChatWindow'
|
|
32
|
+
export { ModelSelector, type ModelSelectorProps } from './components/ModelSelector'
|
|
33
|
+
export { AILogTable, type AILogTableComponentProps } from './components/AILogTable'
|
|
34
|
+
export { ModelTestRunner, type ModelTestRunnerProps } from './components/ModelTestRunner'
|
|
35
|
+
export { GenerationCard, type GenerationCardProps } from './components/GenerationCard'
|
|
36
|
+
export { ImageGenerator, type ImageGeneratorComponentProps } from './components/ImageGenerator'
|
|
37
|
+
export { VoiceSelector, type VoiceSelectorComponentProps } from './components/VoiceSelector'
|
|
38
|
+
|
|
39
|
+
// Pages
|
|
40
|
+
export { ChatPage, type ChatPageProps } from './pages/ChatPage'
|
|
41
|
+
export { ModelTestPage, type ModelTestPageProps } from './pages/ModelTestPage'
|
|
42
|
+
export { AILogsPage, type AILogsPageProps } from './pages/AILogsPage'
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// @geenius-ai/react — src/pages/AILogsPage.tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AI logs dashboard page with stats and log table.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState } from 'react'
|
|
8
|
+
import { AILogTable } from '../components/AILogTable'
|
|
9
|
+
import { useAILogs, type UseAILogsOptions } from '../hooks/useAILogs'
|
|
10
|
+
import type { AIRequestStatus, AILogEntry } from '@geenius-ai/shared'
|
|
11
|
+
|
|
12
|
+
export interface AILogsPageProps {
|
|
13
|
+
/** Query reference: api.ai.listLogs */
|
|
14
|
+
listLogsQuery: any
|
|
15
|
+
className?: string
|
|
16
|
+
title?: string
|
|
17
|
+
onRowClick?: (log: AILogEntry) => void
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function AILogsPage(props: AILogsPageProps) {
|
|
21
|
+
const [modelFilter, setModelFilter] = useState('')
|
|
22
|
+
const [statusFilter, setStatusFilter] = useState<AIRequestStatus | ''>('')
|
|
23
|
+
|
|
24
|
+
const { logs, isLoading } = useAILogs({
|
|
25
|
+
listLogsQuery: props.listLogsQuery,
|
|
26
|
+
filters: {
|
|
27
|
+
model: modelFilter || undefined,
|
|
28
|
+
status: (statusFilter || undefined) as AIRequestStatus | undefined,
|
|
29
|
+
},
|
|
30
|
+
limit: 100,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
// Calculate quick stats
|
|
34
|
+
const totalCalls = logs.length
|
|
35
|
+
const successCalls = logs.filter(l => l.status === 'success').length
|
|
36
|
+
const errorCalls = totalCalls - successCalls
|
|
37
|
+
const totalCost = logs.reduce((sum, l) => sum + (l.totalCostUsd ?? 0), 0)
|
|
38
|
+
const totalTokens = logs.reduce((sum, l) => sum + (l.totalTokens ?? 0), 0)
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className={props.className} data-ai-page="logs">
|
|
42
|
+
<div data-ai-page-header>
|
|
43
|
+
<h1 data-ai-page-title>{props.title ?? 'AI Logs'}</h1>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{/* Stats cards */}
|
|
47
|
+
<div data-ai-stats-grid>
|
|
48
|
+
<div data-ai-stat>
|
|
49
|
+
<span data-ai-stat-label>Total Calls</span>
|
|
50
|
+
<span data-ai-stat-value>{totalCalls}</span>
|
|
51
|
+
</div>
|
|
52
|
+
<div data-ai-stat data-ai-status="success">
|
|
53
|
+
<span data-ai-stat-label>Success</span>
|
|
54
|
+
<span data-ai-stat-value>{successCalls}</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div data-ai-stat data-ai-status="error">
|
|
57
|
+
<span data-ai-stat-label>Errors</span>
|
|
58
|
+
<span data-ai-stat-value>{errorCalls}</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div data-ai-stat>
|
|
61
|
+
<span data-ai-stat-label>Total Cost</span>
|
|
62
|
+
<span data-ai-stat-value>${totalCost.toFixed(2)}</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div data-ai-stat>
|
|
65
|
+
<span data-ai-stat-label>Total Tokens</span>
|
|
66
|
+
<span data-ai-stat-value>{totalTokens.toLocaleString()}</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
{/* Filters */}
|
|
71
|
+
<div data-ai-filters>
|
|
72
|
+
<input
|
|
73
|
+
type="text"
|
|
74
|
+
placeholder="Filter by model…"
|
|
75
|
+
value={modelFilter}
|
|
76
|
+
onChange={(e) => setModelFilter(e.target.value)}
|
|
77
|
+
data-ai-filter-input
|
|
78
|
+
/>
|
|
79
|
+
<select
|
|
80
|
+
value={statusFilter}
|
|
81
|
+
onChange={(e) => setStatusFilter(e.target.value as AIRequestStatus | '')}
|
|
82
|
+
data-ai-filter-select
|
|
83
|
+
>
|
|
84
|
+
<option value="">All statuses</option>
|
|
85
|
+
<option value="success">Success</option>
|
|
86
|
+
<option value="error">Error</option>
|
|
87
|
+
</select>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
{/* Log table */}
|
|
91
|
+
<AILogTable
|
|
92
|
+
logs={logs}
|
|
93
|
+
isLoading={isLoading}
|
|
94
|
+
onRowClick={props.onRowClick}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// @geenius-ai/react — src/pages/ChatPage.tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Full chatbot page — sidebar + conversation.
|
|
5
|
+
* Compose with your own layout and styling.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useState } from 'react'
|
|
9
|
+
import { ChatWindow, type ChatWindowComponentProps } from '../components/ChatWindow'
|
|
10
|
+
|
|
11
|
+
export interface ChatPageProps extends Omit<ChatWindowComponentProps, 'conversationId'> {
|
|
12
|
+
className?: string
|
|
13
|
+
/** Initial conversation ID */
|
|
14
|
+
conversationId?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ChatPage(props: ChatPageProps) {
|
|
18
|
+
const [activeConversationId, setActiveConversationId] = useState<string | undefined>(props.conversationId)
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className={props.className} data-ai-page="chat">
|
|
22
|
+
<div data-ai-page-header>
|
|
23
|
+
<h1 data-ai-page-title>AI Chat</h1>
|
|
24
|
+
<button
|
|
25
|
+
onClick={() => setActiveConversationId(undefined)}
|
|
26
|
+
data-ai-new-chat
|
|
27
|
+
>
|
|
28
|
+
New Chat
|
|
29
|
+
</button>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<ChatWindow
|
|
33
|
+
{...props}
|
|
34
|
+
conversationId={activeConversationId}
|
|
35
|
+
onNewConversation={(id) => {
|
|
36
|
+
setActiveConversationId(id)
|
|
37
|
+
props.onNewConversation?.(id)
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @geenius-ai/react — src/pages/ModelTestPage.tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Model test page — extracted from the pattern used in 15+ apps.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ModelTestRunner, type ModelTestRunnerProps } from '../components/ModelTestRunner'
|
|
8
|
+
import { DEFAULT_MODELS } from '@geenius-ai/shared'
|
|
9
|
+
import type { AIGenerationType } from '@geenius-ai/shared'
|
|
10
|
+
|
|
11
|
+
export interface ModelTestPageProps extends ModelTestRunnerProps {
|
|
12
|
+
title?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function ModelTestPage(props: ModelTestPageProps) {
|
|
16
|
+
const models = props.availableModels ?? DEFAULT_MODELS.map(m => m.id)
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className={props.className} data-ai-page="model-test">
|
|
20
|
+
<div data-ai-page-header>
|
|
21
|
+
<h1 data-ai-page-title>{props.title ?? 'Model Test Lab'}</h1>
|
|
22
|
+
<p data-ai-page-subtitle>
|
|
23
|
+
Test AI models individually or compare them side-by-side
|
|
24
|
+
</p>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<ModelTestRunner
|
|
28
|
+
{...props}
|
|
29
|
+
availableModels={models}
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"rootDir": "./src",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"isolatedModules": true,
|
|
17
|
+
"jsx": "react-jsx"
|
|
18
|
+
},
|
|
19
|
+
"include": [
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
22
|
+
"exclude": [
|
|
23
|
+
"node_modules",
|
|
24
|
+
"dist"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: {
|
|
5
|
+
index: 'src/index.ts',
|
|
6
|
+
'hooks/index': 'src/hooks/index.ts',
|
|
7
|
+
'components/index': 'src/components/index.ts',
|
|
8
|
+
'pages/index': 'src/pages/index.ts',
|
|
9
|
+
},
|
|
10
|
+
format: ['esm'],
|
|
11
|
+
dts: true,
|
|
12
|
+
clean: true,
|
|
13
|
+
sourcemap: true,
|
|
14
|
+
jsx: 'automatic',
|
|
15
|
+
external: [
|
|
16
|
+
'react',
|
|
17
|
+
'react-dom',
|
|
18
|
+
'convex',
|
|
19
|
+
'convex/react',
|
|
20
|
+
'@geenius-ai/shared',
|
|
21
|
+
],
|
|
22
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# ✦ @geenius-ai/react-css\n\n> Geenius AI — React hooks and components (vanilla CSS variant)\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius-ai/react-css\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-ai/react-css';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@geenius-ai/react-css",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Geenius AI — React hooks and components (vanilla CSS variant)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./styles.css": "./dist/styles.css"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"lint": "tsc --noEmit",
|
|
20
|
+
"clean": "rm -rf dist"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"react": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@geenius-ai/shared": "workspace:*"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "^19.0.0",
|
|
36
|
+
"react": "^19.2.4",
|
|
37
|
+
"tsup": "^8.5.1",
|
|
38
|
+
"typescript": "~6.0.2"
|
|
39
|
+
},
|
|
40
|
+
"author": "Antigravity HQ",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=20.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|