@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,127 @@
|
|
|
1
|
+
// @geenius-ai/solidjs — src/primitives/createMemory.ts
|
|
2
|
+
|
|
3
|
+
import { createSignal } from 'solid-js'
|
|
4
|
+
import type {
|
|
5
|
+
MemoryEntry,
|
|
6
|
+
MemoryQuery,
|
|
7
|
+
MemoryNamespace,
|
|
8
|
+
MemoryImportance,
|
|
9
|
+
MemoryType,
|
|
10
|
+
} from '@geenius-ai/shared'
|
|
11
|
+
|
|
12
|
+
export interface CreateMemoryOptions {
|
|
13
|
+
storeFn: (entry: Omit<MemoryEntry, 'id' | 'accessCount' | 'lastAccessedAt' | 'createdAt' | 'updatedAt'>) => Promise<MemoryEntry>
|
|
14
|
+
searchFn: (query: MemoryQuery) => Promise<MemoryEntry[]>
|
|
15
|
+
deleteFn: (id: string) => Promise<void>
|
|
16
|
+
clearFn: (namespace: MemoryNamespace, scopeId: string) => Promise<void>
|
|
17
|
+
defaultNamespace?: MemoryNamespace
|
|
18
|
+
defaultScopeId?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createMemory(options: CreateMemoryOptions) {
|
|
22
|
+
const {
|
|
23
|
+
storeFn, searchFn, deleteFn, clearFn,
|
|
24
|
+
defaultNamespace = 'user',
|
|
25
|
+
defaultScopeId = '',
|
|
26
|
+
} = options
|
|
27
|
+
|
|
28
|
+
const [memories, setMemories] = createSignal<MemoryEntry[]>([])
|
|
29
|
+
const [isLoading, setIsLoading] = createSignal(false)
|
|
30
|
+
const [error, setError] = createSignal<Error | null>(null)
|
|
31
|
+
|
|
32
|
+
const store = async (
|
|
33
|
+
key: string,
|
|
34
|
+
value: string,
|
|
35
|
+
opts?: {
|
|
36
|
+
namespace?: MemoryNamespace
|
|
37
|
+
type?: MemoryType
|
|
38
|
+
importance?: MemoryImportance
|
|
39
|
+
metadata?: Record<string, unknown>
|
|
40
|
+
scopeId?: string
|
|
41
|
+
},
|
|
42
|
+
) => {
|
|
43
|
+
setIsLoading(true)
|
|
44
|
+
setError(null)
|
|
45
|
+
try {
|
|
46
|
+
const entry = await storeFn({
|
|
47
|
+
namespace: opts?.namespace ?? defaultNamespace,
|
|
48
|
+
type: opts?.type ?? 'fact',
|
|
49
|
+
importance: opts?.importance ?? 'medium',
|
|
50
|
+
key,
|
|
51
|
+
value,
|
|
52
|
+
metadata: opts?.metadata,
|
|
53
|
+
scopeId: opts?.scopeId ?? defaultScopeId,
|
|
54
|
+
})
|
|
55
|
+
setMemories(prev => [...prev, entry])
|
|
56
|
+
return entry
|
|
57
|
+
} catch (err) {
|
|
58
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
59
|
+
setError(e)
|
|
60
|
+
throw e
|
|
61
|
+
} finally {
|
|
62
|
+
setIsLoading(false)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const recall = async (key: string, namespace?: MemoryNamespace) => {
|
|
67
|
+
setIsLoading(true)
|
|
68
|
+
setError(null)
|
|
69
|
+
try {
|
|
70
|
+
const results = await searchFn({
|
|
71
|
+
namespace: namespace ?? defaultNamespace,
|
|
72
|
+
key,
|
|
73
|
+
scopeId: defaultScopeId,
|
|
74
|
+
limit: 1,
|
|
75
|
+
})
|
|
76
|
+
return results.length > 0 ? results[0] : null
|
|
77
|
+
} catch (err) {
|
|
78
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
79
|
+
setError(e)
|
|
80
|
+
throw e
|
|
81
|
+
} finally {
|
|
82
|
+
setIsLoading(false)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const search = async (query: MemoryQuery) => {
|
|
87
|
+
setIsLoading(true)
|
|
88
|
+
setError(null)
|
|
89
|
+
try {
|
|
90
|
+
const results = await searchFn({ scopeId: defaultScopeId, ...query })
|
|
91
|
+
setMemories(results)
|
|
92
|
+
return results
|
|
93
|
+
} catch (err) {
|
|
94
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
95
|
+
setError(e)
|
|
96
|
+
throw e
|
|
97
|
+
} finally {
|
|
98
|
+
setIsLoading(false)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const remove = async (id: string) => {
|
|
103
|
+
setError(null)
|
|
104
|
+
try {
|
|
105
|
+
await deleteFn(id)
|
|
106
|
+
setMemories(prev => prev.filter(m => m.id !== id))
|
|
107
|
+
} catch (err) {
|
|
108
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
109
|
+
setError(e)
|
|
110
|
+
throw e
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const clear = async (namespace?: MemoryNamespace) => {
|
|
115
|
+
setError(null)
|
|
116
|
+
try {
|
|
117
|
+
await clearFn(namespace ?? defaultNamespace, defaultScopeId)
|
|
118
|
+
setMemories([])
|
|
119
|
+
} catch (err) {
|
|
120
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
121
|
+
setError(e)
|
|
122
|
+
throw e
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return { store, recall, search, remove, clear, memories, isLoading, error }
|
|
127
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// @geenius-ai/solidjs — src/primitives/createModelTest.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Model test primitive — run tests on individual or batch models.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createSignal } from 'solid-js'
|
|
8
|
+
import type { AIGenerationType } from '@geenius-ai/shared'
|
|
9
|
+
|
|
10
|
+
export interface ModelTestResult {
|
|
11
|
+
model: string
|
|
12
|
+
type: AIGenerationType
|
|
13
|
+
result: string
|
|
14
|
+
durationMs: number
|
|
15
|
+
timestamp: number
|
|
16
|
+
error?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CreateModelTestOptions {
|
|
20
|
+
callGenerateText?: (args: any) => Promise<string>
|
|
21
|
+
callGenerateImage?: (args: any) => Promise<string>
|
|
22
|
+
callGenerateAudio?: (args: any) => Promise<string>
|
|
23
|
+
callGenerateVideo?: (args: any) => Promise<string>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CreateModelTestReturn {
|
|
27
|
+
runTest: (model: string, prompt: string, type?: AIGenerationType) => Promise<ModelTestResult>
|
|
28
|
+
runBatchTest: (models: string[], prompt: string) => Promise<ModelTestResult[]>
|
|
29
|
+
results: () => ModelTestResult[]
|
|
30
|
+
isRunning: () => boolean
|
|
31
|
+
clearResults: () => void
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createModelTest(options: CreateModelTestOptions = {}): CreateModelTestReturn {
|
|
35
|
+
const [results, setResults] = createSignal<ModelTestResult[]>([])
|
|
36
|
+
const [isRunning, setIsRunning] = createSignal(false)
|
|
37
|
+
|
|
38
|
+
async function runTest(model: string, prompt: string, type: AIGenerationType = 'text'): Promise<ModelTestResult> {
|
|
39
|
+
setIsRunning(true)
|
|
40
|
+
const start = Date.now()
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
let result = ''
|
|
44
|
+
switch (type) {
|
|
45
|
+
case 'text':
|
|
46
|
+
if (!options.callGenerateText) throw new Error('callGenerateText not provided')
|
|
47
|
+
result = await options.callGenerateText({ model, messages: [{ role: 'user', content: prompt }], caller: 'model-test' })
|
|
48
|
+
break
|
|
49
|
+
case 'image':
|
|
50
|
+
if (!options.callGenerateImage) throw new Error('callGenerateImage not provided')
|
|
51
|
+
result = await options.callGenerateImage({ prompt, model })
|
|
52
|
+
break
|
|
53
|
+
case 'audio':
|
|
54
|
+
if (!options.callGenerateAudio) throw new Error('callGenerateAudio not provided')
|
|
55
|
+
result = await options.callGenerateAudio({ prompt })
|
|
56
|
+
break
|
|
57
|
+
case 'video':
|
|
58
|
+
if (!options.callGenerateVideo) throw new Error('callGenerateVideo not provided')
|
|
59
|
+
result = await options.callGenerateVideo({ prompt })
|
|
60
|
+
break
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Unsupported test type: ${type}`)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const testResult: ModelTestResult = { model, type, result, durationMs: Date.now() - start, timestamp: Date.now() }
|
|
66
|
+
setResults(prev => [...prev, testResult])
|
|
67
|
+
return testResult
|
|
68
|
+
} catch (err) {
|
|
69
|
+
const testResult: ModelTestResult = { model, type, result: '', durationMs: Date.now() - start, timestamp: Date.now(), error: err instanceof Error ? err.message : 'Test failed' }
|
|
70
|
+
setResults(prev => [...prev, testResult])
|
|
71
|
+
return testResult
|
|
72
|
+
} finally {
|
|
73
|
+
setIsRunning(false)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function runBatchTest(models: string[], prompt: string): Promise<ModelTestResult[]> {
|
|
78
|
+
setIsRunning(true)
|
|
79
|
+
const batch: ModelTestResult[] = []
|
|
80
|
+
for (const model of models) {
|
|
81
|
+
const r = await runTest(model, prompt)
|
|
82
|
+
batch.push(r)
|
|
83
|
+
}
|
|
84
|
+
setIsRunning(false)
|
|
85
|
+
return batch
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { runTest, runBatchTest, results, isRunning, clearResults: () => setResults([]) }
|
|
89
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// @geenius-ai/solidjs — src/primitives/createSkills.ts
|
|
2
|
+
|
|
3
|
+
import { createSignal, createMemo } from 'solid-js'
|
|
4
|
+
import type {
|
|
5
|
+
SkillDefinition,
|
|
6
|
+
SkillContext,
|
|
7
|
+
SkillResult,
|
|
8
|
+
SkillCategory,
|
|
9
|
+
} from '@geenius-ai/shared'
|
|
10
|
+
import { BUILT_IN_SKILLS } from '@geenius-ai/shared'
|
|
11
|
+
|
|
12
|
+
export interface CreateSkillsOptions {
|
|
13
|
+
executeFn: (context: SkillContext) => Promise<SkillResult>
|
|
14
|
+
customSkills?: SkillDefinition[]
|
|
15
|
+
defaultModel?: string
|
|
16
|
+
userId?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function createSkills(options: CreateSkillsOptions) {
|
|
20
|
+
const { executeFn, customSkills = [], defaultModel, userId } = options
|
|
21
|
+
const [result, setResult] = createSignal<SkillResult | null>(null)
|
|
22
|
+
const [isExecuting, setIsExecuting] = createSignal(false)
|
|
23
|
+
const [error, setError] = createSignal<Error | null>(null)
|
|
24
|
+
|
|
25
|
+
const allSkills = createMemo(() => {
|
|
26
|
+
const map = new Map<string, SkillDefinition>()
|
|
27
|
+
for (const skill of Object.values(BUILT_IN_SKILLS)) map.set(skill.id, skill)
|
|
28
|
+
for (const skill of customSkills) map.set(skill.id, skill)
|
|
29
|
+
return Array.from(map.values())
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const byCategory = (category: SkillCategory) =>
|
|
33
|
+
allSkills().filter(s => s.category === category)
|
|
34
|
+
|
|
35
|
+
const search = (query: string) => {
|
|
36
|
+
const q = query.toLowerCase()
|
|
37
|
+
return allSkills().filter(s =>
|
|
38
|
+
s.name.toLowerCase().includes(q) ||
|
|
39
|
+
s.description.toLowerCase().includes(q) ||
|
|
40
|
+
s.tags?.some(t => t.toLowerCase().includes(q))
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const getSkill = (id: string) => allSkills().find(s => s.id === id)
|
|
45
|
+
|
|
46
|
+
const execute = async (
|
|
47
|
+
skillId: string,
|
|
48
|
+
params: Record<string, unknown>,
|
|
49
|
+
context?: Record<string, unknown>,
|
|
50
|
+
) => {
|
|
51
|
+
setIsExecuting(true)
|
|
52
|
+
setError(null)
|
|
53
|
+
try {
|
|
54
|
+
const res = await executeFn({
|
|
55
|
+
skillId,
|
|
56
|
+
params,
|
|
57
|
+
userId,
|
|
58
|
+
context,
|
|
59
|
+
model: defaultModel,
|
|
60
|
+
})
|
|
61
|
+
setResult(res)
|
|
62
|
+
return res
|
|
63
|
+
} catch (err) {
|
|
64
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
65
|
+
setError(e)
|
|
66
|
+
throw e
|
|
67
|
+
} finally {
|
|
68
|
+
setIsExecuting(false)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
skills: allSkills,
|
|
74
|
+
byCategory,
|
|
75
|
+
search,
|
|
76
|
+
getSkill,
|
|
77
|
+
execute,
|
|
78
|
+
result,
|
|
79
|
+
isExecuting,
|
|
80
|
+
error,
|
|
81
|
+
reset: () => { setResult(null); setError(null) },
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @geenius-ai/solidjs — src/primitives/createTextToSpeech.ts
|
|
2
|
+
|
|
3
|
+
import { createSignal } from 'solid-js'
|
|
4
|
+
|
|
5
|
+
export interface CreateTextToSpeechOptions {
|
|
6
|
+
callGenerateAudio: (args: any) => Promise<string>
|
|
7
|
+
defaultVoice?: string
|
|
8
|
+
defaultModel?: string
|
|
9
|
+
autoPlay?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createTextToSpeech(options: CreateTextToSpeechOptions) {
|
|
13
|
+
const [isGenerating, setIsGenerating] = createSignal(false)
|
|
14
|
+
const [isSpeaking, setIsSpeaking] = createSignal(false)
|
|
15
|
+
const [error, setError] = createSignal<string | null>(null)
|
|
16
|
+
const [audioUrl, setAudioUrl] = createSignal<string | null>(null)
|
|
17
|
+
let currentAudio: HTMLAudioElement | null = null
|
|
18
|
+
|
|
19
|
+
async function speak(text: string, opts?: { voice?: string; model?: string; speed?: number }) {
|
|
20
|
+
setIsGenerating(true)
|
|
21
|
+
setError(null)
|
|
22
|
+
try {
|
|
23
|
+
const base64 = await options.callGenerateAudio({
|
|
24
|
+
prompt: text,
|
|
25
|
+
voice: opts?.voice ?? options.defaultVoice ?? 'alloy',
|
|
26
|
+
model: opts?.model ?? options.defaultModel,
|
|
27
|
+
speed: opts?.speed,
|
|
28
|
+
})
|
|
29
|
+
const url = base64.startsWith('http') ? base64 : `data:audio/mp3;base64,${base64}`
|
|
30
|
+
setAudioUrl(url)
|
|
31
|
+
|
|
32
|
+
if (options.autoPlay !== false) {
|
|
33
|
+
stop()
|
|
34
|
+
const audio = new Audio(url)
|
|
35
|
+
currentAudio = audio
|
|
36
|
+
setIsSpeaking(true)
|
|
37
|
+
audio.onended = () => setIsSpeaking(false)
|
|
38
|
+
await audio.play()
|
|
39
|
+
}
|
|
40
|
+
return url
|
|
41
|
+
} catch (err) {
|
|
42
|
+
setError(err instanceof Error ? err.message : 'TTS failed')
|
|
43
|
+
throw err
|
|
44
|
+
} finally {
|
|
45
|
+
setIsGenerating(false)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function stop() {
|
|
50
|
+
currentAudio?.pause()
|
|
51
|
+
currentAudio = null
|
|
52
|
+
setIsSpeaking(false)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { speak, stop, isGenerating, isSpeaking, error, audioUrl, clearError: () => setError(null) }
|
|
56
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @geenius-ai/solidjs — src/primitives/createVideoGeneration.ts
|
|
2
|
+
|
|
3
|
+
import { createSignal } from 'solid-js'
|
|
4
|
+
|
|
5
|
+
export interface GeneratedVideo {
|
|
6
|
+
url: string
|
|
7
|
+
prompt: string
|
|
8
|
+
model: string
|
|
9
|
+
timestamp: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CreateVideoGenerationOptions {
|
|
13
|
+
callGenerateVideo: (args: any) => Promise<string>
|
|
14
|
+
defaultModel?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createVideoGeneration(options: CreateVideoGenerationOptions) {
|
|
18
|
+
const [videos, setVideos] = createSignal<GeneratedVideo[]>([])
|
|
19
|
+
const [isGenerating, setIsGenerating] = createSignal(false)
|
|
20
|
+
const [error, setError] = createSignal<string | null>(null)
|
|
21
|
+
|
|
22
|
+
async function generate(prompt: string, opts?: {
|
|
23
|
+
model?: string; duration?: number; aspectRatio?: '16:9' | '9:16' | '1:1'
|
|
24
|
+
startImage?: string; endImage?: string
|
|
25
|
+
}) {
|
|
26
|
+
setIsGenerating(true)
|
|
27
|
+
setError(null)
|
|
28
|
+
try {
|
|
29
|
+
const model = opts?.model ?? options.defaultModel ?? 'minimax/video-01'
|
|
30
|
+
const result = await options.callGenerateVideo({ prompt, model, ...opts })
|
|
31
|
+
setVideos(prev => [{ url: result, prompt, model, timestamp: Date.now() }, ...prev])
|
|
32
|
+
return result
|
|
33
|
+
} catch (err) {
|
|
34
|
+
setError(err instanceof Error ? err.message : 'Video generation failed')
|
|
35
|
+
throw err
|
|
36
|
+
} finally {
|
|
37
|
+
setIsGenerating(false)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
generate, videos, isGenerating, error,
|
|
43
|
+
clearVideos: () => setVideos([]),
|
|
44
|
+
clearError: () => setError(null),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@geenius-ai/solidjs'
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* @geenius-ai — styles.css (premium vanilla CSS for AI components)
|
|
2
|
+
* oklch colors, dark-mode-first, responsive, data-* targeted
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
--gai-bg: oklch(0.13 0.02 260);
|
|
7
|
+
--gai-surface: oklch(0.18 0.02 260);
|
|
8
|
+
--gai-surface-hover: oklch(0.22 0.02 260);
|
|
9
|
+
--gai-text: oklch(0.94 0.01 260);
|
|
10
|
+
--gai-text-muted: oklch(0.62 0.02 260);
|
|
11
|
+
--gai-border: oklch(0.28 0.02 260);
|
|
12
|
+
--gai-primary: oklch(0.65 0.22 265);
|
|
13
|
+
--gai-primary-dim: oklch(0.65 0.22 265 / 0.12);
|
|
14
|
+
--gai-success: oklch(0.68 0.18 155);
|
|
15
|
+
--gai-error: oklch(0.62 0.2 25);
|
|
16
|
+
--gai-warning: oklch(0.7 0.18 80);
|
|
17
|
+
--gai-radius: 12px;
|
|
18
|
+
--gai-radius-sm: 8px;
|
|
19
|
+
--gai-font: system-ui, -apple-system, sans-serif;
|
|
20
|
+
--gai-font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
21
|
+
--gai-transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-theme="light"] {
|
|
25
|
+
--gai-bg: oklch(0.97 0.005 260);
|
|
26
|
+
--gai-surface: oklch(1 0 0);
|
|
27
|
+
--gai-surface-hover: oklch(0.96 0.005 260);
|
|
28
|
+
--gai-text: oklch(0.15 0.02 260);
|
|
29
|
+
--gai-text-muted: oklch(0.5 0.02 260);
|
|
30
|
+
--gai-border: oklch(0.88 0.01 260);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ─── Chat Window ───────────────────────────────── */
|
|
34
|
+
[data-chat-window] {
|
|
35
|
+
display: flex; flex-direction: column; height: 100%;
|
|
36
|
+
font-family: var(--gai-font); color: var(--gai-text); background: var(--gai-bg);
|
|
37
|
+
border: 1px solid var(--gai-border); border-radius: var(--gai-radius);
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
}
|
|
40
|
+
[data-chat-header] { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem; background: var(--gai-surface); border-bottom: 1px solid var(--gai-border); }
|
|
41
|
+
[data-chat-messages] { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
|
|
42
|
+
[data-chat-message] { max-width: 80%; padding: 0.75rem 1rem; border-radius: var(--gai-radius); font-size: 0.875rem; line-height: 1.5; }
|
|
43
|
+
[data-chat-message][data-role="user"] { align-self: flex-end; background: var(--gai-primary); color: white; border-bottom-right-radius: 4px; }
|
|
44
|
+
[data-chat-message][data-role="assistant"] { align-self: flex-start; background: var(--gai-surface); border: 1px solid var(--gai-border); border-bottom-left-radius: 4px; }
|
|
45
|
+
[data-chat-input-form] { display: flex; gap: 0.5rem; padding: 0.75rem 1rem; border-top: 1px solid var(--gai-border); background: var(--gai-surface); }
|
|
46
|
+
[data-chat-input] { flex: 1; padding: 0.625rem 1rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); background: var(--gai-bg); color: var(--gai-text); font-size: 0.875rem; outline: none; transition: border-color var(--gai-transition); }
|
|
47
|
+
[data-chat-input]:focus { border-color: var(--gai-primary); }
|
|
48
|
+
[data-chat-send] { padding: 0.625rem 1.25rem; background: var(--gai-primary); color: white; border: none; border-radius: var(--gai-radius-sm); font-weight: 600; font-size: 0.8125rem; cursor: pointer; transition: opacity var(--gai-transition); }
|
|
49
|
+
[data-chat-send]:hover { opacity: 0.85; }
|
|
50
|
+
[data-chat-send]:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
51
|
+
[data-chat-typing] { font-size: 0.75rem; color: var(--gai-text-muted); font-style: italic; padding: 0.25rem 1rem; }
|
|
52
|
+
|
|
53
|
+
/* ─── Model Selector ────────────────────────────── */
|
|
54
|
+
[data-model-selector] { position: relative; }
|
|
55
|
+
[data-model-selector-trigger] { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); background: var(--gai-surface); color: var(--gai-text); font-size: 0.8125rem; cursor: pointer; transition: border-color var(--gai-transition); }
|
|
56
|
+
[data-model-selector-trigger]:hover { border-color: var(--gai-primary); }
|
|
57
|
+
[data-model-selector-dropdown] { position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px; background: var(--gai-surface); border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); box-shadow: 0 8px 24px oklch(0 0 0 / 0.2); z-index: 50; max-height: 240px; overflow-y: auto; }
|
|
58
|
+
[data-model-option] { display: flex; align-items: center; gap: 0.5rem; padding: 0.625rem 1rem; font-size: 0.8125rem; cursor: pointer; transition: background var(--gai-transition); }
|
|
59
|
+
[data-model-option]:hover { background: var(--gai-surface-hover); }
|
|
60
|
+
[data-model-option][data-selected] { color: var(--gai-primary); font-weight: 600; }
|
|
61
|
+
|
|
62
|
+
/* ─── AI Log Table ──────────────────────────────── */
|
|
63
|
+
[data-ai-log-table] { border: 1px solid var(--gai-border); border-radius: var(--gai-radius); overflow: hidden; }
|
|
64
|
+
[data-ai-log-header] { display: grid; grid-template-columns: 1fr 1fr 0.6fr 0.6fr 0.4fr; gap: 0; padding: 0.5rem 1rem; background: var(--gai-surface); font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--gai-text-muted); }
|
|
65
|
+
[data-ai-log-row] { display: grid; grid-template-columns: 1fr 1fr 0.6fr 0.6fr 0.4fr; gap: 0; padding: 0.625rem 1rem; border-top: 1px solid oklch(0 0 0 / 0.04); font-size: 0.8125rem; transition: background var(--gai-transition); }
|
|
66
|
+
[data-ai-log-row]:hover { background: var(--gai-surface-hover); }
|
|
67
|
+
[data-ai-log-empty] { text-align: center; padding: 3rem 1rem; color: var(--gai-text-muted); }
|
|
68
|
+
[data-ai-log-skeleton] { height: 2.5rem; background: var(--gai-surface); border-radius: var(--gai-radius-sm); animation: gai-pulse 1.5s infinite; margin-bottom: 0.25rem; }
|
|
69
|
+
|
|
70
|
+
/* ─── Model Test Runner ─────────────────────────── */
|
|
71
|
+
[data-model-test] { border: 1px solid var(--gai-border); border-radius: var(--gai-radius); overflow: hidden; }
|
|
72
|
+
[data-model-test-header] { padding: 1rem; background: var(--gai-surface); border-bottom: 1px solid var(--gai-border); }
|
|
73
|
+
[data-model-test-form] { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; }
|
|
74
|
+
[data-model-test-input] { padding: 0.625rem 1rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); background: var(--gai-bg); color: var(--gai-text); font-size: 0.875rem; }
|
|
75
|
+
[data-model-test-run] { align-self: flex-start; padding: 0.625rem 1.5rem; background: var(--gai-primary); color: white; border: none; border-radius: var(--gai-radius-sm); font-weight: 600; cursor: pointer; }
|
|
76
|
+
[data-model-test-results] { padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem; }
|
|
77
|
+
[data-model-test-result] { padding: 0.75rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); font-size: 0.8125rem; }
|
|
78
|
+
[data-model-test-result][data-success="true"] { border-left: 3px solid var(--gai-success); }
|
|
79
|
+
[data-model-test-result][data-success="false"] { border-left: 3px solid var(--gai-error); }
|
|
80
|
+
|
|
81
|
+
/* ─── Generation Card ───────────────────────────── */
|
|
82
|
+
[data-generation-card] { border: 1px solid var(--gai-border); border-radius: var(--gai-radius); overflow: hidden; transition: box-shadow var(--gai-transition); }
|
|
83
|
+
[data-generation-card]:hover { box-shadow: 0 4px 16px oklch(0 0 0 / 0.12); }
|
|
84
|
+
[data-generation-preview] { aspect-ratio: 16/9; background: var(--gai-surface); display: flex; align-items: center; justify-content: center; overflow: hidden; }
|
|
85
|
+
[data-generation-preview] img { width: 100%; height: 100%; object-fit: cover; }
|
|
86
|
+
[data-generation-meta] { padding: 0.75rem 1rem; }
|
|
87
|
+
[data-generation-type] { font-size: 0.625rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--gai-primary); }
|
|
88
|
+
[data-generation-prompt] { font-size: 0.8125rem; margin-top: 0.25rem; color: var(--gai-text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
89
|
+
[data-generation-actions] { display: flex; gap: 0.5rem; padding: 0.5rem 1rem; border-top: 1px solid var(--gai-border); }
|
|
90
|
+
|
|
91
|
+
/* ─── Image Generator ───────────────────────────── */
|
|
92
|
+
[data-image-generator] { border: 1px solid var(--gai-border); border-radius: var(--gai-radius); }
|
|
93
|
+
[data-image-gen-form] { padding: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
|
|
94
|
+
[data-image-gen-textarea] { padding: 0.75rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); background: var(--gai-bg); color: var(--gai-text); font-size: 0.875rem; resize: vertical; min-height: 80px; font-family: var(--gai-font); }
|
|
95
|
+
[data-image-gen-submit] { align-self: flex-start; padding: 0.625rem 1.5rem; background: var(--gai-primary); color: white; border: none; border-radius: var(--gai-radius-sm); font-weight: 600; cursor: pointer; }
|
|
96
|
+
[data-image-gen-gallery] { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 0.75rem; padding: 1rem; }
|
|
97
|
+
|
|
98
|
+
/* ─── Voice Selector ────────────────────────────── */
|
|
99
|
+
[data-voice-selector] { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
100
|
+
[data-voice-option] { display: flex; align-items: center; gap: 0.75rem; padding: 0.625rem 1rem; border: 1px solid var(--gai-border); border-radius: var(--gai-radius-sm); cursor: pointer; transition: all var(--gai-transition); }
|
|
101
|
+
[data-voice-option]:hover { background: var(--gai-surface-hover); }
|
|
102
|
+
[data-voice-option][data-selected] { border-color: var(--gai-primary); background: var(--gai-primary-dim); }
|
|
103
|
+
[data-voice-name] { font-size: 0.875rem; font-weight: 600; }
|
|
104
|
+
[data-voice-preview] { margin-left: auto; padding: 0.375rem 0.75rem; border: 1px solid var(--gai-border); border-radius: 6px; background: transparent; color: var(--gai-text); font-size: 0.75rem; cursor: pointer; }
|
|
105
|
+
|
|
106
|
+
/* ─── Shared ─────────────────────────────────────── */
|
|
107
|
+
[data-ai-empty] { text-align: center; padding: 3rem 1rem; color: var(--gai-text-muted); }
|
|
108
|
+
[data-ai-empty-icon] { font-size: 2.5rem; margin-bottom: 0.5rem; }
|
|
109
|
+
[data-ai-error] { padding: 1rem; border: 1px solid var(--gai-error); border-radius: var(--gai-radius-sm); background: oklch(0.62 0.2 25 / 0.08); color: var(--gai-error); font-size: 0.875rem; }
|
|
110
|
+
[data-ai-loading] { display: flex; align-items: center; justify-content: center; padding: 2rem; color: var(--gai-text-muted); }
|
|
111
|
+
[data-ai-badge] { display: inline-flex; padding: 0.125rem 0.5rem; border-radius: 999px; font-size: 0.625rem; font-weight: 700; }
|
|
112
|
+
[data-ai-badge][data-variant="success"] { background: oklch(0.68 0.18 155 / 0.12); color: var(--gai-success); }
|
|
113
|
+
[data-ai-badge][data-variant="error"] { background: oklch(0.62 0.2 25 / 0.12); color: var(--gai-error); }
|
|
114
|
+
[data-ai-badge][data-variant="info"] { background: var(--gai-primary-dim); color: var(--gai-primary); }
|
|
115
|
+
|
|
116
|
+
/* ─── Pages ──────────────────────────────────────── */
|
|
117
|
+
[data-ai-page] { display: flex; flex-direction: column; gap: 1.5rem; padding: 1.5rem; max-width: 1200px; margin: 0 auto; }
|
|
118
|
+
[data-ai-page-header] h1 { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.02em; }
|
|
119
|
+
[data-ai-page-header] p { font-size: 0.875rem; color: var(--gai-text-muted); margin-top: 0.25rem; }
|
|
120
|
+
|
|
121
|
+
@keyframes gai-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
|
122
|
+
|
|
123
|
+
@media (max-width: 768px) {
|
|
124
|
+
[data-ai-log-header], [data-ai-log-row] { grid-template-columns: 1fr 1fr 0.5fr; }
|
|
125
|
+
[data-chat-message] { max-width: 90%; }
|
|
126
|
+
[data-image-gen-gallery] { grid-template-columns: 1fr; }
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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": "preserve",
|
|
18
|
+
"jsxImportSource": "solid-js"
|
|
19
|
+
},
|
|
20
|
+
"include": [
|
|
21
|
+
"src"
|
|
22
|
+
],
|
|
23
|
+
"exclude": [
|
|
24
|
+
"node_modules",
|
|
25
|
+
"dist"
|
|
26
|
+
]
|
|
27
|
+
}
|