@delofarag/ai-utils 1.4.3 → 1.5.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/README.md +354 -216
- package/dist/heart/agent.d.ts +1 -1
- package/dist/heart/agent.d.ts.map +1 -1
- package/dist/heart/agent.js +3 -8
- package/dist/heart/agent.js.map +1 -1
- package/dist/heart/chain.d.ts +1 -1
- package/dist/heart/chain.d.ts.map +1 -1
- package/dist/heart/chain.js +4 -4
- package/dist/heart/chain.js.map +1 -1
- package/dist/heart/chatbot.d.ts +1 -1
- package/dist/heart/memorychain.d.ts +2 -2
- package/dist/heart/memorychain.js +6 -6
- package/dist/heart/memorychain.js.map +1 -1
- package/dist/heart/tools/zodios/ZodiosToolRegistry.d.ts +1 -1
- package/dist/heart/tools/zodios/ZodiosToolRegistry.d.ts.map +1 -1
- package/dist/helpers/chatbot.d.ts +33 -0
- package/dist/helpers/chatbot.d.ts.map +1 -0
- package/dist/helpers/chatbot.js +72 -0
- package/dist/helpers/chatbot.js.map +1 -0
- package/dist/helpers/helpers.d.ts +25 -0
- package/dist/helpers/helpers.d.ts.map +1 -0
- package/dist/helpers/helpers.js +43 -0
- package/dist/helpers/helpers.js.map +1 -0
- package/dist/helpers/llms.d.ts +92 -0
- package/dist/helpers/llms.d.ts.map +1 -0
- package/dist/helpers/llms.js +49 -0
- package/dist/helpers/llms.js.map +1 -0
- package/dist/helpers/memory.d.ts +91 -0
- package/dist/helpers/memory.d.ts.map +1 -0
- package/dist/helpers/memory.js +351 -0
- package/dist/helpers/memory.js.map +1 -0
- package/dist/helpers/rag.d.ts +42 -0
- package/dist/helpers/rag.d.ts.map +1 -0
- package/dist/helpers/rag.js +66 -0
- package/dist/helpers/rag.js.map +1 -0
- package/dist/helpers.d.ts +3 -3
- package/dist/index.d.ts +10 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/magic-funcs/answerers/ask.d.ts +18 -2
- package/dist/magic-funcs/answerers/ask.d.ts.map +1 -1
- package/dist/magic-funcs/answerers/ask.js +20 -9
- package/dist/magic-funcs/answerers/ask.js.map +1 -1
- package/dist/magic-funcs/answerers/websearch.d.ts +15 -0
- package/dist/magic-funcs/answerers/websearch.d.ts.map +1 -1
- package/dist/magic-funcs/answerers/websearch.js +15 -0
- package/dist/magic-funcs/answerers/websearch.js.map +1 -1
- package/dist/magic-funcs/evaluators/classify.d.ts +20 -1
- package/dist/magic-funcs/evaluators/classify.d.ts.map +1 -1
- package/dist/magic-funcs/evaluators/classify.js +22 -3
- package/dist/magic-funcs/evaluators/classify.js.map +1 -1
- package/dist/magic-funcs/evaluators/decide.d.ts +18 -0
- package/dist/magic-funcs/evaluators/decide.d.ts.map +1 -1
- package/dist/magic-funcs/evaluators/decide.js +21 -3
- package/dist/magic-funcs/evaluators/decide.js.map +1 -1
- package/dist/magic-funcs/optimizers/promptify.d.ts +18 -0
- package/dist/magic-funcs/optimizers/promptify.d.ts.map +1 -1
- package/dist/magic-funcs/optimizers/promptify.js +21 -3
- package/dist/magic-funcs/optimizers/promptify.js.map +1 -1
- package/dist/magic-funcs/optimizers/ragify.d.ts +16 -0
- package/dist/magic-funcs/optimizers/ragify.d.ts.map +1 -1
- package/dist/magic-funcs/optimizers/ragify.js +19 -3
- package/dist/magic-funcs/optimizers/ragify.js.map +1 -1
- package/dist/magic-funcs/parsers/extract.d.ts +23 -0
- package/dist/magic-funcs/parsers/extract.d.ts.map +1 -1
- package/dist/magic-funcs/parsers/extract.js +26 -3
- package/dist/magic-funcs/parsers/extract.js.map +1 -1
- package/dist/magic-funcs/parsers/rewrite.d.ts +19 -0
- package/dist/magic-funcs/parsers/rewrite.d.ts.map +1 -1
- package/dist/magic-funcs/parsers/rewrite.js +22 -2
- package/dist/magic-funcs/parsers/rewrite.js.map +1 -1
- package/dist/magic-funcs/parsers/structure.d.ts +22 -0
- package/dist/magic-funcs/parsers/structure.d.ts.map +1 -1
- package/dist/magic-funcs/parsers/structure.js +27 -4
- package/dist/magic-funcs/parsers/structure.js.map +1 -1
- package/dist/magic-funcs/parsers/summarize.d.ts +20 -0
- package/dist/magic-funcs/parsers/summarize.d.ts.map +1 -1
- package/dist/magic-funcs/parsers/summarize.js +23 -3
- package/dist/magic-funcs/parsers/summarize.js.map +1 -1
- package/dist/memory.d.ts +1 -1
- package/dist/modalities/image-gen/generateImages.d.ts +56 -0
- package/dist/modalities/image-gen/generateImages.d.ts.map +1 -0
- package/dist/modalities/image-gen/generateImages.js +66 -0
- package/dist/modalities/image-gen/generateImages.js.map +1 -0
- package/dist/modalities/image-gen/helpers.d.ts +15 -0
- package/dist/modalities/image-gen/helpers.d.ts.map +1 -0
- package/dist/modalities/image-gen/helpers.js +17 -0
- package/dist/modalities/image-gen/helpers.js.map +1 -0
- package/dist/modalities/openrouter.d.ts +11 -0
- package/dist/modalities/openrouter.d.ts.map +1 -0
- package/dist/modalities/openrouter.js +39 -0
- package/dist/modalities/openrouter.js.map +1 -0
- package/dist/modalities/speech/VoiceEngine.d.ts +3 -0
- package/dist/modalities/speech/VoiceEngine.d.ts.map +1 -0
- package/dist/modalities/speech/VoiceEngine.js +3 -0
- package/dist/modalities/speech/VoiceEngine.js.map +1 -0
- package/dist/modalities/speech/stt/helpers.d.ts +3 -0
- package/dist/modalities/speech/stt/helpers.d.ts.map +1 -0
- package/dist/modalities/speech/stt/helpers.js +28 -0
- package/dist/modalities/speech/stt/helpers.js.map +1 -0
- package/dist/modalities/speech/stt/stt.d.ts +113 -0
- package/dist/modalities/speech/stt/stt.d.ts.map +1 -0
- package/dist/modalities/speech/stt/stt.js +177 -0
- package/dist/modalities/speech/stt/stt.js.map +1 -0
- package/dist/modalities/speech/tts/helpers.d.ts +12 -0
- package/dist/modalities/speech/tts/helpers.d.ts.map +1 -0
- package/dist/modalities/speech/tts/helpers.js +10 -0
- package/dist/modalities/speech/tts/helpers.js.map +1 -0
- package/dist/modalities/speech/tts/tts.d.ts +115 -0
- package/dist/modalities/speech/tts/tts.d.ts.map +1 -0
- package/dist/modalities/speech/tts/tts.js +142 -0
- package/dist/modalities/speech/tts/tts.js.map +1 -0
- package/dist/modalities/vision/helpers.d.ts +3 -0
- package/dist/modalities/vision/helpers.d.ts.map +1 -0
- package/dist/modalities/vision/helpers.js +7 -0
- package/dist/modalities/vision/helpers.js.map +1 -0
- package/dist/modalities/vision/vision.d.ts +55 -0
- package/dist/modalities/vision/vision.d.ts.map +1 -0
- package/dist/modalities/vision/vision.js +71 -0
- package/dist/modalities/vision/vision.js.map +1 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,369 +1,507 @@
|
|
|
1
1
|
# @delofarag/ai-utils
|
|
2
2
|
|
|
3
|
-
Ein
|
|
3
|
+
Ein praktisches Utility-Package für LLM-Apps mit LangChain:
|
|
4
|
+
|
|
5
|
+
- `Chain`, `MemoryChain`, `Agent`
|
|
6
|
+
- RAG-Helper (FAISS, Supabase, In-Memory)
|
|
7
|
+
- Tooling (`ToolRegistry`, `createRAGTool`, `tavilySearchTool`)
|
|
8
|
+
- Magic-Funcs (Parser, Evaluator, Optimizer, Answerer)
|
|
9
|
+
- Modalities (STT, TTS, Vision, Image Generation)
|
|
4
10
|
|
|
5
11
|
---
|
|
6
12
|
|
|
7
|
-
##
|
|
13
|
+
## Standard-Default (wichtig)
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
Im Package gilt als Standard-LLM-Default für die allgemeine Nutzung:
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
- **Provider:** `openrouter`
|
|
18
|
+
- **Model:** `openai/gpt-5.4-mini`
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
- **API-Key:** `process.env.CHATGROQ_API_KEY`
|
|
20
|
+
Wenn du nichts explizit setzt, orientiere dich an diesem Default in deinen Aufrufen.
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
Für modality-spezifische Flows (`stt`, `tts`, `vision`, `image-gen`) wird zusätzlich mit `type` gearbeitet, damit passende Modelle gewählt werden koennen.
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
---
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm i @delofarag/ai-utils
|
|
30
|
+
```
|
|
25
31
|
|
|
26
32
|
---
|
|
27
33
|
|
|
28
|
-
##
|
|
34
|
+
## Environment Variables
|
|
35
|
+
|
|
36
|
+
Empfohlen in `.env`:
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
```env
|
|
39
|
+
OPENROUTER_API_KEY=...
|
|
40
|
+
CHATGROQ_API_KEY=...
|
|
41
|
+
TAVILY_API_KEY=...
|
|
42
|
+
NEXT_PUBLIC_SUPABASE_URL=...
|
|
43
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
|
|
44
|
+
SUPABASE_SERVICE_ROLE_KEY=...
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Welche Variable wofuer?
|
|
31
48
|
|
|
32
|
-
|
|
49
|
+
- `OPENROUTER_API_KEY`: OpenRouter-Modelle und Modalities
|
|
50
|
+
- `CHATGROQ_API_KEY`: wenn du `provider: "chatgroq"` nutzt
|
|
51
|
+
- `TAVILY_API_KEY`: `websearch()` / `tavilySearchTool`
|
|
52
|
+
- Supabase-Variablen: fuer `createSupabaseVectoreStore()` und `getSupabaseVectorStore()`
|
|
33
53
|
|
|
34
|
-
|
|
54
|
+
---
|
|
35
55
|
|
|
36
|
-
|
|
56
|
+
## Schnellstart: `getLLM()`
|
|
37
57
|
|
|
38
58
|
```ts
|
|
39
|
-
import {
|
|
59
|
+
import { getLLM } from "@delofarag/ai-utils"
|
|
60
|
+
|
|
61
|
+
const llm = getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Beispiele:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
const llmOpenRouter = getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" })
|
|
68
|
+
const llmGroq = getLLM({ provider: "chatgroq", model: "llama-3.3-70b-versatile" })
|
|
69
|
+
const llmLocal = getLLM({ provider: "local", model: "llama3.2:3b" })
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Modality-spezifisch:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
getLLM({ provider: "openrouter", type: "stt" })
|
|
76
|
+
getLLM({ provider: "openrouter", type: "tts" })
|
|
77
|
+
getLLM({ provider: "openrouter", type: "vision" })
|
|
78
|
+
getLLM({ provider: "openrouter", type: "image-gen" })
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Core Classes
|
|
84
|
+
|
|
85
|
+
## 1) `Chain`
|
|
86
|
+
|
|
87
|
+
Stateless LLM-Chain fuer strukturierte Ergebnisse.
|
|
88
|
+
|
|
89
|
+
### Besseres Praxisbeispiel (custom output schema)
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { Chain, getLLM } from "@delofarag/ai-utils"
|
|
40
93
|
import { z } from "zod/v3"
|
|
41
94
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
95
|
+
const productBriefSchema = z.object({
|
|
96
|
+
title: z.string().describe("Kurzer Produktname"),
|
|
97
|
+
targetAudience: z.string().describe("Wer soll das Produkt nutzen?"),
|
|
98
|
+
keyBenefits: z.array(z.string()).describe("Top Vorteile"),
|
|
99
|
+
pricePositioning: z.enum(["budget", "mid", "premium"])
|
|
45
100
|
})
|
|
46
|
-
// alternativ: z.record(z.string()) für beliebige Key-Value-Struktur
|
|
47
101
|
|
|
48
102
|
const chain = new Chain({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
output
|
|
103
|
+
llm: getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" }),
|
|
104
|
+
prompt: "Du bist ein Product-Marketing-Assistent.",
|
|
105
|
+
output: productBriefSchema
|
|
52
106
|
})
|
|
53
107
|
|
|
54
|
-
const result = await chain.invoke({
|
|
55
|
-
|
|
108
|
+
const result = await chain.invoke({
|
|
109
|
+
product: "AI-Notizapp fuer Teams",
|
|
110
|
+
market: "DACH SaaS"
|
|
111
|
+
})
|
|
56
112
|
```
|
|
57
113
|
|
|
58
|
-
|
|
114
|
+
### RAG mit `Chain`
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { Chain, createFaissStore } from "@delofarag/ai-utils"
|
|
118
|
+
import { z } from "zod/v3"
|
|
119
|
+
|
|
120
|
+
const vectorStore = await createFaissStore(["Dokument A", "Dokument B"])
|
|
59
121
|
|
|
60
|
-
|
|
122
|
+
const chain = new Chain({
|
|
123
|
+
prompt: "Beantworte Fragen nur mit Kontext.",
|
|
124
|
+
output: z.object({ output: z.string() }),
|
|
125
|
+
vectorStore
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
await chain.addContext(["Dokument C"])
|
|
129
|
+
|
|
130
|
+
const answer = await chain.invoke({ question: "Was steht in Dokument C?" })
|
|
131
|
+
```
|
|
61
132
|
|
|
62
133
|
---
|
|
63
134
|
|
|
64
|
-
|
|
135
|
+
## 2) `MemoryChain`
|
|
65
136
|
|
|
66
|
-
|
|
137
|
+
`Chain` + Conversation Memory ueber `thread_id`.
|
|
67
138
|
|
|
68
|
-
|
|
139
|
+
### Basis
|
|
69
140
|
|
|
70
|
-
|
|
141
|
+
```ts
|
|
142
|
+
import { MemoryChain, getLLM } from "@delofarag/ai-utils"
|
|
143
|
+
|
|
144
|
+
const memoryChain = new MemoryChain({
|
|
145
|
+
llm: getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" }),
|
|
146
|
+
prompt: "Du bist ein hilfreicher Assistent."
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
await memoryChain.invoke({ thread_id: "u1", input: "Ich heisse Max." })
|
|
150
|
+
const r2 = await memoryChain.invoke({ thread_id: "u1", input: "Wie heisse ich?" })
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### RAG mit `MemoryChain`
|
|
71
154
|
|
|
72
155
|
```ts
|
|
73
|
-
import { MemoryChain,
|
|
156
|
+
import { MemoryChain, createFaissStore } from "@delofarag/ai-utils"
|
|
157
|
+
import { z } from "zod/v3"
|
|
74
158
|
|
|
75
|
-
const
|
|
159
|
+
const vectorStore = await createFaissStore(["Policy A", "Policy B"])
|
|
76
160
|
|
|
77
161
|
const memoryChain = new MemoryChain({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
162
|
+
prompt: "Nutze Kontext und Gespraechshistorie.",
|
|
163
|
+
vectorStore,
|
|
164
|
+
output: z.object({ output: z.string() })
|
|
81
165
|
})
|
|
82
166
|
|
|
83
|
-
const
|
|
84
|
-
thread_id: "
|
|
85
|
-
|
|
86
|
-
})
|
|
87
|
-
const result2 = await memoryChain.invoke({
|
|
88
|
-
thread_id: "user-123",
|
|
89
|
-
input: "Wie heiße ich?"
|
|
167
|
+
const response = await memoryChain.invoke({
|
|
168
|
+
thread_id: "support-77",
|
|
169
|
+
question: "Welche Regel steht in Policy B?"
|
|
90
170
|
})
|
|
91
|
-
// result2.output ≈ "Du heißt Max."
|
|
92
171
|
```
|
|
93
172
|
|
|
94
|
-
|
|
173
|
+
---
|
|
95
174
|
|
|
96
|
-
|
|
175
|
+
## 3) `Agent`
|
|
97
176
|
|
|
98
|
-
|
|
177
|
+
Tool-using Agent auf Basis von `createReactAgent`.
|
|
99
178
|
|
|
100
|
-
###
|
|
179
|
+
### Basis
|
|
101
180
|
|
|
102
|
-
|
|
181
|
+
```ts
|
|
182
|
+
import { Agent, ToolRegistry, getLLM } from "@delofarag/ai-utils"
|
|
183
|
+
import { z } from "zod/v3"
|
|
103
184
|
|
|
104
|
-
|
|
185
|
+
const tools = new ToolRegistry([
|
|
186
|
+
{
|
|
187
|
+
name: "sum",
|
|
188
|
+
description: "Addiert zwei Zahlen",
|
|
189
|
+
schema: z.object({ a: z.number(), b: z.number() }),
|
|
190
|
+
func: ({ a, b }) => a + b
|
|
191
|
+
}
|
|
192
|
+
]).allTools
|
|
105
193
|
|
|
106
|
-
|
|
194
|
+
const agent = new Agent({
|
|
195
|
+
llm: getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" }),
|
|
196
|
+
prompt: "Du darfst Tools nutzen wenn noetig.",
|
|
197
|
+
tools
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const result = await agent.invoke({ input: "Was ist 8 + 13?" })
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### RAG mit `Agent` (als Tool)
|
|
107
204
|
|
|
108
205
|
```ts
|
|
109
|
-
import { Agent, ToolRegistry, createRAGTool, createFaissStore
|
|
206
|
+
import { Agent, ToolRegistry, createRAGTool, createFaissStore } from "@delofarag/ai-utils"
|
|
110
207
|
|
|
111
|
-
const vectorStore = await createFaissStore(["
|
|
208
|
+
const vectorStore = await createFaissStore(["Release Notes 2026-04", "Known Issues"])
|
|
112
209
|
const ragTool = createRAGTool({
|
|
113
210
|
vectorStore,
|
|
114
|
-
name: "
|
|
115
|
-
description: "
|
|
211
|
+
name: "search_docs",
|
|
212
|
+
description: "Sucht relevante Produktdokumente"
|
|
116
213
|
})
|
|
117
214
|
|
|
118
215
|
const registry = new ToolRegistry([
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
216
|
+
{
|
|
217
|
+
name: "search_docs",
|
|
218
|
+
description: "Sucht relevante Produktdokumente",
|
|
219
|
+
schema: ragTool.schema as any,
|
|
220
|
+
func: ragTool.func as any
|
|
221
|
+
}
|
|
122
222
|
])
|
|
123
223
|
|
|
124
224
|
const agent = new Agent({
|
|
125
|
-
prompt: "
|
|
126
|
-
tools: registry.allTools,
|
|
127
|
-
llm: getLLM({ type: "groq" }),
|
|
128
|
-
memory: new SmartCheckpointSaver(new MemorySaver(), { llm }) // optional
|
|
225
|
+
prompt: "Nutze search_docs fuer faktenbasierte Antworten.",
|
|
226
|
+
tools: [...registry.allTools, ragTool]
|
|
129
227
|
})
|
|
130
|
-
|
|
131
|
-
const result = await agent.invoke({
|
|
132
|
-
thread_id: "session-1", // nötig wenn memory gesetzt
|
|
133
|
-
input: "Was steht heute in den Nachrichten zu KI?"
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
agent.addTool(weiteresTool) // Tools nachträglich hinzufügen
|
|
137
228
|
```
|
|
138
229
|
|
|
139
|
-
|
|
230
|
+
---
|
|
140
231
|
|
|
141
|
-
|
|
232
|
+
## Tool Registry (eigene Section)
|
|
142
233
|
|
|
143
|
-
|
|
234
|
+
`ToolRegistry` konvertiert einfache Tool-Definitionen zu `DynamicStructuredTool` und bietet:
|
|
144
235
|
|
|
145
|
-
|
|
236
|
+
- `getTool(name)`
|
|
237
|
+
- `getTools(...names)`
|
|
238
|
+
- `allTools`
|
|
146
239
|
|
|
147
|
-
|
|
240
|
+
```ts
|
|
241
|
+
import { ToolRegistry } from "@delofarag/ai-utils"
|
|
242
|
+
import { z } from "zod/v3"
|
|
243
|
+
|
|
244
|
+
const registry = new ToolRegistry([
|
|
245
|
+
{
|
|
246
|
+
name: "get_weather",
|
|
247
|
+
description: "Liefert Wetter fuer eine Stadt",
|
|
248
|
+
schema: z.object({ city: z.string() }),
|
|
249
|
+
func: async ({ city }) => `${city}: sonnig`
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: "get_time",
|
|
253
|
+
description: "Liefert aktuelle Zeit",
|
|
254
|
+
schema: z.object({}),
|
|
255
|
+
func: async () => new Date().toISOString()
|
|
256
|
+
}
|
|
257
|
+
])
|
|
148
258
|
|
|
149
|
-
|
|
259
|
+
const weatherTool = registry.getTool("get_weather")
|
|
260
|
+
const tools = registry.allTools
|
|
261
|
+
```
|
|
150
262
|
|
|
151
|
-
|
|
263
|
+
### Tavily Tooling
|
|
152
264
|
|
|
153
265
|
```ts
|
|
154
|
-
import {
|
|
266
|
+
import { tavilySearchTool, TavilySearch } from "@delofarag/ai-utils"
|
|
155
267
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
vectorStore
|
|
268
|
+
const tavily = new TavilySearch({
|
|
269
|
+
tavilyApiKey: process.env.TAVILY_API_KEY,
|
|
270
|
+
maxResults: 5,
|
|
271
|
+
topic: "general",
|
|
272
|
+
includeAnswer: false
|
|
162
273
|
})
|
|
163
274
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
],
|
|
171
|
-
prompt: "Du bist ein Assistent mit Webzugang."
|
|
172
|
-
})
|
|
275
|
+
const response = await tavily.invoke({ query: "latest AI regulation EU" })
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Memory Section (ausfuehrlich)
|
|
173
281
|
|
|
174
|
-
|
|
175
|
-
for await (const chunk of simpleChatbot.chat({ input: "Hallo!", thread_id: "user-1" })) {
|
|
176
|
-
process.stdout.write(chunk)
|
|
177
|
-
}
|
|
282
|
+
### `MemorySaver` (in-memory, schnell fuer local/dev)
|
|
178
283
|
|
|
179
|
-
|
|
180
|
-
|
|
284
|
+
```ts
|
|
285
|
+
import { MemorySaver, SmartCheckpointSaver, getLLM } from "@delofarag/ai-utils"
|
|
286
|
+
|
|
287
|
+
const memory = new SmartCheckpointSaver(new MemorySaver(), {
|
|
288
|
+
llm: getLLM({ provider: "openrouter", model: "openai/gpt-5.4-mini" }),
|
|
289
|
+
messagesBeforeSummary: 12,
|
|
290
|
+
maxSummaries: 7
|
|
291
|
+
})
|
|
181
292
|
```
|
|
182
293
|
|
|
183
|
-
|
|
294
|
+
### `SmartCheckpointSaver`
|
|
184
295
|
|
|
185
|
-
|
|
296
|
+
Was es macht:
|
|
297
|
+
|
|
298
|
+
- fasst alte Chatverlaeufe zusammen
|
|
299
|
+
- reduziert Token-Kosten
|
|
300
|
+
- erhaelt wichtige Fakten ueber mehrere Sessions
|
|
301
|
+
|
|
302
|
+
Wichtige Optionen:
|
|
186
303
|
|
|
187
|
-
|
|
304
|
+
- `messagesBeforeSummary` (default `12`)
|
|
305
|
+
- `maxSummaries` (default `7`)
|
|
306
|
+
- `llm` (default OpenRouter `gpt-5.4-mini`)
|
|
307
|
+
- `debug`
|
|
188
308
|
|
|
189
|
-
###
|
|
309
|
+
### `SupabaseCheckpointSaver`
|
|
190
310
|
|
|
191
|
-
|
|
311
|
+
Persistiert Checkpoints in Supabase.
|
|
192
312
|
|
|
193
313
|
```ts
|
|
194
|
-
import {
|
|
195
|
-
import {
|
|
314
|
+
import { SupabaseCheckpointSaver, type SupabaseCheckpointRow } from "@delofarag/ai-utils"
|
|
315
|
+
import { SupabaseTable } from "@delofarag/supabase-utils"
|
|
196
316
|
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
317
|
+
const checkpointsTable = new SupabaseTable<SupabaseCheckpointRow>({
|
|
318
|
+
// ... deine SupabaseTable Konfiguration
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
const saver = new SupabaseCheckpointSaver(checkpointsTable)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Typischer Einsatz:
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
import { MemoryChain } from "@delofarag/ai-utils"
|
|
205
328
|
|
|
206
|
-
const
|
|
207
|
-
|
|
329
|
+
const memoryChain = new MemoryChain({
|
|
330
|
+
prompt: "Du bist ein Support Assistant.",
|
|
331
|
+
memory: saver
|
|
332
|
+
})
|
|
208
333
|
```
|
|
209
334
|
|
|
210
|
-
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## RAG Utilities (Detail)
|
|
211
338
|
|
|
212
|
-
|
|
339
|
+
### Vector Stores
|
|
213
340
|
|
|
214
|
-
|
|
341
|
+
- `createRAMVectoreStore(data)`
|
|
342
|
+
- `createSupabaseVectoreStore(data, config?)`
|
|
343
|
+
- `getSupabaseVectorStore(config?)`
|
|
344
|
+
- `createFaissStore(data, config?)`
|
|
345
|
+
- `loadFaissStore({ path })`
|
|
346
|
+
- `turn_to_docs(data)`
|
|
215
347
|
|
|
216
|
-
|
|
348
|
+
### RAG Chain
|
|
217
349
|
|
|
218
|
-
-
|
|
219
|
-
|
|
220
|
-
|
|
350
|
+
- `createRAGChain({ vectorStore, llm, prompt?, num_of_results_from_vdb? })`
|
|
351
|
+
|
|
352
|
+
### RAG Tool
|
|
353
|
+
|
|
354
|
+
- `createRAGTool({ vectorStore, name, description })`
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
import { createRAGTool, createFaissStore } from "@delofarag/ai-utils"
|
|
221
358
|
|
|
222
|
-
|
|
359
|
+
const vectorStore = await createFaissStore(["FAQ 1", "FAQ 2"])
|
|
360
|
+
const ragTool = createRAGTool({
|
|
361
|
+
vectorStore,
|
|
362
|
+
name: "search_faq",
|
|
363
|
+
description: "Sucht in FAQ-Dokumenten"
|
|
364
|
+
})
|
|
365
|
+
```
|
|
223
366
|
|
|
224
367
|
---
|
|
225
368
|
|
|
226
369
|
## Magic-Funcs
|
|
227
370
|
|
|
228
|
-
Kleine, wiederverwendbare LLM-Funktionen. **Struktur:** Immer `{ llm?, ...params }` – `llm` optional, sonst Default (Groq).
|
|
229
|
-
|
|
230
371
|
### Answerers
|
|
231
|
-
|
|
232
|
-
-
|
|
233
|
-
- **websearch(query)** – Sucht im Web (Tavily), braucht `TAVILY_API_KEY`
|
|
372
|
+
- `ask({ question, llm? })`
|
|
373
|
+
- `websearch(query)` (braucht `TAVILY_API_KEY`)
|
|
234
374
|
|
|
235
375
|
### Evaluators
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
- **decide({ material, kriteria_to_decide })** – Ja/Nein/Unclear plus Begründung
|
|
376
|
+
- `classify({ data, classes, context?, llm? })`
|
|
377
|
+
- `decide({ material, kriteria_to_decide, llm? })`
|
|
239
378
|
|
|
240
379
|
### Parsers
|
|
241
|
-
|
|
242
|
-
-
|
|
243
|
-
-
|
|
244
|
-
-
|
|
245
|
-
- **summarize({ data, fokuss?, maxWords? })** – Fasst zusammen
|
|
380
|
+
- `extract({ data, schema, goal?, llm? })`
|
|
381
|
+
- `structure({ data, into, retries?, llm? })`
|
|
382
|
+
- `rewrite({ data, instruction, llm? })`
|
|
383
|
+
- `summarize({ data, fokuss?, maxWords?, llm? })`
|
|
246
384
|
|
|
247
385
|
### Optimizers
|
|
386
|
+
- `promptify({ request, agentRole?, llm? })`
|
|
387
|
+
- `ragify({ data, llm? })`
|
|
248
388
|
|
|
249
|
-
|
|
250
|
-
- **ragify({ data })** – Optimiert Text für RAG (strukturierter, informationsdicht)
|
|
251
|
-
|
|
252
|
-
**Beispiel – immer gleiche Struktur:**
|
|
389
|
+
Beispiel:
|
|
253
390
|
|
|
254
391
|
```ts
|
|
255
392
|
import { classify, extract, summarize } from "@delofarag/ai-utils"
|
|
256
393
|
import { z } from "zod/v3"
|
|
257
394
|
|
|
258
|
-
const
|
|
259
|
-
data: "
|
|
395
|
+
const sentiment = await classify({
|
|
396
|
+
data: "Das Produkt ist wirklich gut.",
|
|
260
397
|
classes: ["positiv", "negativ", "neutral"] as const
|
|
261
398
|
})
|
|
262
399
|
|
|
263
|
-
const
|
|
264
|
-
data: "Max
|
|
265
|
-
schema: z.object({
|
|
400
|
+
const person = await extract({
|
|
401
|
+
data: "Max ist 30 und lebt in Berlin.",
|
|
402
|
+
schema: z.object({
|
|
403
|
+
name: z.string(),
|
|
404
|
+
age: z.number(),
|
|
405
|
+
city: z.string()
|
|
406
|
+
})
|
|
266
407
|
})
|
|
267
408
|
|
|
268
|
-
const
|
|
409
|
+
const short = await summarize({
|
|
410
|
+
data: "Sehr langer Text...",
|
|
411
|
+
maxWords: 50
|
|
412
|
+
})
|
|
269
413
|
```
|
|
270
414
|
|
|
271
415
|
---
|
|
272
416
|
|
|
273
|
-
##
|
|
417
|
+
## Modalities
|
|
274
418
|
|
|
275
|
-
|
|
419
|
+
### STT
|
|
276
420
|
|
|
277
|
-
-
|
|
278
|
-
-
|
|
279
|
-
- **getSupabaseVectorStore({ supabase, table_name?, RPC_function? })** – Bestehenden Store holen
|
|
280
|
-
- **createFaissStore({ data, save_path?, embeddings? })** – FAISS-Store (lokal, speicherbar)
|
|
281
|
-
- **loadFaissStore({ path, embeddings? })** – FAISS-Store laden
|
|
421
|
+
- `stt(...)`
|
|
422
|
+
- `createSTTPhoneSocketSession(...)` fuer live phone socket chunks (Twilio/Telnyx-style)
|
|
282
423
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
- **createRAGTool({ vectorStore, name, description })** – Erzeugt ein Tool, mit dem der Agent den Vector Store durchsucht. In `tools` übergeben oder via `agent.addTool()`.
|
|
286
|
-
|
|
287
|
-
**Retrieval-Chains** (in `rag.ts`):
|
|
288
|
-
|
|
289
|
-
- **createRAGChain({ vectorStore, llm, prompt?, num_of_results_from_vdb? })** – Retrieval-Chain
|
|
290
|
-
- **createRAGChainFromRetriever({ retriever, llm, prompt? })** – Alternative mit eigenem Retriever
|
|
291
|
-
|
|
292
|
-
**Typischer Ablauf:**
|
|
293
|
-
|
|
294
|
-
1. Vector Store erstellen: `createFaissStore({ data })` oder `createSupabaseVectoreStore({ data })`
|
|
295
|
-
2. **Chain/MemoryChain:** `chain.setContext(vectorStore)` – RAG wird automatisch eingebaut. Optional `chain.addContext(weitereDaten)` für weitere Docs
|
|
296
|
-
3. **Agent/Chatbot:** `createRAGTool({ vectorStore, name, description })` als Tool übergeben
|
|
297
|
-
|
|
298
|
-
---
|
|
424
|
+
```ts
|
|
425
|
+
import { stt } from "@delofarag/ai-utils"
|
|
299
426
|
|
|
300
|
-
|
|
427
|
+
const result = await stt({
|
|
428
|
+
audio: "./call.wav",
|
|
429
|
+
prompt: "Transcribe in German."
|
|
430
|
+
})
|
|
431
|
+
```
|
|
301
432
|
|
|
302
|
-
###
|
|
433
|
+
### TTS
|
|
303
434
|
|
|
304
|
-
|
|
435
|
+
- `tts(...)`
|
|
436
|
+
- `streamTTSOverPhoneSocket(...)` fuer chunked outbound audio
|
|
305
437
|
|
|
306
438
|
```ts
|
|
307
|
-
import {
|
|
308
|
-
import { SupabaseTable } from "@delofarag/supabase-utils"
|
|
439
|
+
import { tts, streamTTSOverPhoneSocket } from "@delofarag/ai-utils"
|
|
309
440
|
|
|
310
|
-
const
|
|
311
|
-
|
|
441
|
+
const speech = await tts({
|
|
442
|
+
text: "Willkommen beim Support.",
|
|
443
|
+
model: "nova"
|
|
444
|
+
})
|
|
312
445
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
446
|
+
await streamTTSOverPhoneSocket({
|
|
447
|
+
text: "Einen Moment bitte.",
|
|
448
|
+
model: "nova",
|
|
449
|
+
onChunk: async (chunk) => {
|
|
450
|
+
// socket send
|
|
451
|
+
}
|
|
316
452
|
})
|
|
317
453
|
```
|
|
318
454
|
|
|
319
|
-
|
|
455
|
+
### Vision
|
|
320
456
|
|
|
321
|
-
|
|
457
|
+
```ts
|
|
458
|
+
import { vision } from "@delofarag/ai-utils"
|
|
322
459
|
|
|
323
|
-
|
|
460
|
+
const result = await vision({
|
|
461
|
+
prompt: "Was ist auf dem Bild zu sehen?",
|
|
462
|
+
images: ["https://example.com/photo.jpg"]
|
|
463
|
+
})
|
|
464
|
+
```
|
|
324
465
|
|
|
325
|
-
|
|
326
|
-
- Die Zusammenfassung ersetzt die alten Messages → weniger Tokens, längerer Kontext
|
|
327
|
-
- `maxSummaries` (Default: 7): Maximal so viele Summaries werden behalten. Sobald eine neue erstellt würde und das Limit überschritten wäre, wird die älteste Summary gelöscht (Rolling-Window)
|
|
466
|
+
### Image Generation
|
|
328
467
|
|
|
329
468
|
```ts
|
|
330
|
-
import {
|
|
469
|
+
import { generateImages } from "@delofarag/ai-utils"
|
|
331
470
|
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
messagesBeforeSummary: 12,
|
|
336
|
-
maxSummaries: 7,
|
|
471
|
+
const generated = await generateImages({
|
|
472
|
+
prompt: "Generate a clean product hero image",
|
|
473
|
+
imageConfig: { aspect_ratio: "16:9", image_size: "2K" }
|
|
337
474
|
})
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
338
478
|
|
|
339
|
-
|
|
479
|
+
## Session / Stream Helpers
|
|
480
|
+
|
|
481
|
+
```ts
|
|
482
|
+
import { session, StreamResponse } from "@delofarag/ai-utils"
|
|
340
483
|
```
|
|
341
484
|
|
|
342
|
-
|
|
485
|
+
- `session({ streamable, ... })`: CLI-like interactive loop
|
|
486
|
+
- `StreamResponse(asyncIterable)`: streambares NDJSON-HTTP-Response-Objekt
|
|
343
487
|
|
|
344
488
|
---
|
|
345
489
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
| **tavilySearchTool** | Web-Suche (TAVILY_API_KEY) |
|
|
356
|
-
| **Magic-Funcs** | ask, websearch, classify, decide, extract, structure, rewrite, summarize, promptify, ragify |
|
|
357
|
-
| **RAG** | createRAGTool, Supabase/FAISS Vector Stores, createRAGChain |
|
|
358
|
-
| **SupabaseCheckpointSaver** | Persistente Memory in Supabase |
|
|
359
|
-
| **SmartCheckpointSaver** | Memory mit Auto-Summarization |
|
|
360
|
-
| **getLLM()** | LLM aus Groq, OpenRouter oder Ollama |
|
|
490
|
+
## Export Overview (high-level)
|
|
491
|
+
|
|
492
|
+
Top-level Exports decken u. a. ab:
|
|
493
|
+
|
|
494
|
+
- Helpers (`helpers`, `memory`, `rag`, `llms`, `chatbot`)
|
|
495
|
+
- Core (`Agent`, `Chain`, `MemoryChain`)
|
|
496
|
+
- Tools (`ToolRegistry`, `Tavily`, `RAGTool`, Zodios registries)
|
|
497
|
+
- Magic-Funcs (answerers/evaluators/parsers/optimizers)
|
|
498
|
+
- Modalities (`stt`, `tts`, `vision`, `generateImages`)
|
|
361
499
|
|
|
362
500
|
---
|
|
363
501
|
|
|
364
|
-
##
|
|
502
|
+
## Empfehlungen
|
|
365
503
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
504
|
+
- Fuer strukturierte Outputs immer `zod/v3` verwenden.
|
|
505
|
+
- Fuer Produktion API-Keys als ENV setzen, nicht hardcoden.
|
|
506
|
+
- Bei langen Chats `SmartCheckpointSaver` verwenden.
|
|
507
|
+
- RAG als Tool im `Agent` ist in der Praxis oft robuster als RAG-only Prompting.
|