@zerotal/ai 1.6.2 → 1.7.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/api-surface.md +620 -0
- package/package.json +5 -4
- package/src/config.ts +1 -14
package/api-surface.md
ADDED
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
# @zerotal/ai — public API surface
|
|
2
|
+
|
|
3
|
+
<!-- AUTO-GENERATED by scripts/api-surface.ts. Do not edit by hand.
|
|
4
|
+
Run `bun run api:surface` to regenerate after an intentional API change. -->
|
|
5
|
+
|
|
6
|
+
## . `(./src/index.ts)`
|
|
7
|
+
|
|
8
|
+
class AiAgentLimitError = {
|
|
9
|
+
new (message: string, context?: Record<string, unknown>): AiAgentLimitError
|
|
10
|
+
readonly code: string
|
|
11
|
+
readonly context?: Record<string, unknown> | undefined
|
|
12
|
+
readonly status: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class AiCancelledError = {
|
|
16
|
+
new (message?: string): AiCancelledError
|
|
17
|
+
readonly code: string
|
|
18
|
+
readonly context?: Record<string, unknown> | undefined
|
|
19
|
+
readonly status: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class AiConfigError = {
|
|
23
|
+
new (message: string, context?: Record<string, unknown>): AiConfigError
|
|
24
|
+
readonly code: string
|
|
25
|
+
readonly context?: Record<string, unknown> | undefined
|
|
26
|
+
readonly status: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class AiDriverUnavailableError = {
|
|
30
|
+
new (driver: string, packageName: string): AiDriverUnavailableError
|
|
31
|
+
readonly code: string
|
|
32
|
+
readonly context?: Record<string, unknown> | undefined
|
|
33
|
+
readonly status: number
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class AiError = {
|
|
37
|
+
new (message: string, code?: string, status?: number, context?: Record<string, unknown>): AiError
|
|
38
|
+
readonly code: string
|
|
39
|
+
readonly context?: Record<string, unknown> | undefined
|
|
40
|
+
readonly status: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class AiFake = {
|
|
44
|
+
new (_app: Application, _original: Binding): AiFake
|
|
45
|
+
static install: () => AiFake
|
|
46
|
+
agent: (request: AiAgentRequest) => Promise<AiAgentResult>
|
|
47
|
+
assertNotPrompted: (expected: string | RegExp | ((prompt: string) => boolean)) => void
|
|
48
|
+
assertNothingPrompted: () => void
|
|
49
|
+
assertPromptCount: (count: number) => void
|
|
50
|
+
assertPrompted: (expected: string | RegExp | ((prompt: string) => boolean)) => void
|
|
51
|
+
assertSystemPrompted: (expected: string | RegExp | ((prompt: string) => boolean)) => void
|
|
52
|
+
calls: CapturedGeneration[]
|
|
53
|
+
countTokens: (request: AiRequest | string) => Promise<number>
|
|
54
|
+
drivers: () => string[]
|
|
55
|
+
embed: (input: string | string[], _options?: Omit<AiEmbedRequest, 'input'>) => Promise<AiEmbedResponse>
|
|
56
|
+
generate: (request: AiRequest | string) => Promise<AiResponse>
|
|
57
|
+
handlerFor: (name: string) => AiQueueHandler | undefined
|
|
58
|
+
object: <T = Record<string, unknown>>(request: AiRequest | string) => Promise<T>
|
|
59
|
+
onGenerated: (name: string, handler: AiQueueHandler) => AiFake
|
|
60
|
+
prompts: string[]
|
|
61
|
+
queue: (request: AiRequest, options: AiQueueOptions) => Promise<void>
|
|
62
|
+
refuse: (category?: string | null, explanation?: string | null) => AiFake
|
|
63
|
+
respondWith: (...texts: string[]) => AiFake
|
|
64
|
+
respondWithObject: (...objects: unknown[]) => AiFake
|
|
65
|
+
restore: () => void
|
|
66
|
+
stream: (request: AiRequest | string) => AsyncIterable<AiStreamChunk>
|
|
67
|
+
text: (request: AiRequest | string) => Promise<string>
|
|
68
|
+
verify: () => Promise<DriverStatus>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class AiGenerated = {
|
|
72
|
+
new (driver: string, model: string, operation: string, inputTokens: number, outputTokens: number, cacheReadTokens: number, durationMs: number, costUsd: number, ok: boolean, preview: string, error?: string | undefined): AiGenerated
|
|
73
|
+
readonly cacheReadTokens: number
|
|
74
|
+
readonly costUsd: number
|
|
75
|
+
readonly driver: string
|
|
76
|
+
readonly durationMs: number
|
|
77
|
+
readonly error?: string | undefined
|
|
78
|
+
readonly inputTokens: number
|
|
79
|
+
readonly model: string
|
|
80
|
+
readonly ok: boolean
|
|
81
|
+
readonly operation: string
|
|
82
|
+
readonly outputTokens: number
|
|
83
|
+
readonly preview: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class AiGenerationJob = {
|
|
87
|
+
new (request: AiRequest, options: AiQueueOptions): AiGenerationJob
|
|
88
|
+
static fromPayload: (data: Record<string, unknown>) => AiGenerationJob
|
|
89
|
+
_chain: SerializedJob[] | undefined
|
|
90
|
+
batchId: string | undefined
|
|
91
|
+
className: string
|
|
92
|
+
debounceKey: () => string
|
|
93
|
+
handle: () => Promise<void>
|
|
94
|
+
payload: () => Record<string, unknown>
|
|
95
|
+
readonly debounce?: number
|
|
96
|
+
readonly maxAttempts: number
|
|
97
|
+
readonly queue: string
|
|
98
|
+
readonly retryDelay: number
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
class AiManager = {
|
|
102
|
+
new (config: AiConfigShape): AiManager
|
|
103
|
+
agent: (request: AiAgentRequest) => Promise<AiAgentResult>
|
|
104
|
+
countTokens: (request: AiRequest | string) => Promise<number>
|
|
105
|
+
driver: (name?: string) => AiDriver
|
|
106
|
+
drivers: () => string[]
|
|
107
|
+
embed: (input: string | string[], options?: Omit<AiEmbedRequest, 'input'>) => Promise<AiEmbedResponse>
|
|
108
|
+
embeddingsDriver: (name?: string) => EmbeddingsDriver
|
|
109
|
+
extend: (name: string, factory: DriverResolver) => AiManager
|
|
110
|
+
extendEmbeddings: (name: string, factory: EmbeddingsResolver) => AiManager
|
|
111
|
+
generate: (request: AiRequest | string) => Promise<AiResponse>
|
|
112
|
+
handlerFor: (name: string) => AiQueueHandler | undefined
|
|
113
|
+
object: <T = Record<string, unknown>>(request: AiRequest | string, schema: SchemaInput | ((rule: RuleBuilder) => SchemaInput)) => Promise<T>
|
|
114
|
+
onGenerated: (name: string, handler: AiQueueHandler) => AiManager
|
|
115
|
+
queue: (request: AiRequest, options: AiQueueOptions) => Promise<void>
|
|
116
|
+
readonly config: AiConfigShape
|
|
117
|
+
stream: (request: AiRequest | string) => AsyncIterable<AiStreamChunk>
|
|
118
|
+
text: (request: AiRequest | string) => Promise<string>
|
|
119
|
+
verify: (name?: string) => Promise<DriverStatus>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class AiProvider = {
|
|
123
|
+
new (app: Application): AiProvider
|
|
124
|
+
static dependsOn?: (new (app: Application) => ServiceProvider)[]
|
|
125
|
+
static environments: AppEnvironment[]
|
|
126
|
+
static priority?: number
|
|
127
|
+
static provides: readonly ['ai']
|
|
128
|
+
devProcesses: () => DevProcessDefinition[]
|
|
129
|
+
doctorChecks: () => DoctorCheck[]
|
|
130
|
+
onBooted: () => Promise<void>
|
|
131
|
+
onBooting: () => Promise<void>
|
|
132
|
+
onRegister: () => void
|
|
133
|
+
onRequestProcessed: (_ctx: HttpContext) => Promise<void>
|
|
134
|
+
onRequestReceived: (_ctx: HttpContext) => Promise<void>
|
|
135
|
+
onResponseSent: (_ctx: HttpContext) => Promise<void>
|
|
136
|
+
onStarted: () => Promise<void>
|
|
137
|
+
onStarting: () => Promise<void>
|
|
138
|
+
onStopped: () => Promise<void>
|
|
139
|
+
onStopping: () => Promise<void>
|
|
140
|
+
replContext: () => Record<string, unknown>
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class AiRateLimitError = {
|
|
144
|
+
new (message: string, retryAfterSeconds?: number | undefined): AiRateLimitError
|
|
145
|
+
readonly code: string
|
|
146
|
+
readonly context?: Record<string, unknown> | undefined
|
|
147
|
+
readonly retryAfterSeconds?: number | undefined
|
|
148
|
+
readonly status: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
class AiRefused = {
|
|
152
|
+
new (driver: string, model: string, category: string | null, preview: string): AiRefused
|
|
153
|
+
readonly category: string | null
|
|
154
|
+
readonly driver: string
|
|
155
|
+
readonly model: string
|
|
156
|
+
readonly preview: string
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
class AiRefusedError = {
|
|
160
|
+
new (category: string | null, explanation: string | null, partialText?: string): AiRefusedError
|
|
161
|
+
readonly category: string | null
|
|
162
|
+
readonly code: string
|
|
163
|
+
readonly context?: Record<string, unknown> | undefined
|
|
164
|
+
readonly explanation: string | null
|
|
165
|
+
readonly partialText: string
|
|
166
|
+
readonly status: number
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
class AiRequestError = {
|
|
170
|
+
new (message: string, providerStatus: number, context?: Record<string, unknown>): AiRequestError
|
|
171
|
+
readonly code: string
|
|
172
|
+
readonly context?: Record<string, unknown> | undefined
|
|
173
|
+
readonly providerStatus: number
|
|
174
|
+
readonly status: number
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
class AiSchemaError = {
|
|
178
|
+
new (message: string, context?: Record<string, unknown>): AiSchemaError
|
|
179
|
+
readonly code: string
|
|
180
|
+
readonly context?: Record<string, unknown> | undefined
|
|
181
|
+
readonly status: number
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
class AiSpendCommand = {
|
|
185
|
+
new (): AiSpendCommand
|
|
186
|
+
static args: ArgDef[]
|
|
187
|
+
static commandName: string
|
|
188
|
+
static description: string
|
|
189
|
+
static flags: FlagDef[]
|
|
190
|
+
static needsApp: boolean
|
|
191
|
+
_readLine: () => Promise<string>
|
|
192
|
+
_writer: OutputWriter
|
|
193
|
+
app: unknown
|
|
194
|
+
args: Record<string, string>
|
|
195
|
+
ask: (question: string, defaultValue?: string) => Promise<string>
|
|
196
|
+
choice: (question: string, options: string[]) => Promise<string>
|
|
197
|
+
confirm: (question: string, defaultValue?: boolean) => Promise<boolean>
|
|
198
|
+
dim: (msg: string) => void
|
|
199
|
+
error: (msg: string) => void
|
|
200
|
+
flags: Record<string, string | number | boolean>
|
|
201
|
+
info: (msg: string) => void
|
|
202
|
+
line: (msg: string) => void
|
|
203
|
+
newLine: () => void
|
|
204
|
+
run: () => Promise<void>
|
|
205
|
+
secret: (question: string) => Promise<string>
|
|
206
|
+
section: (title: string) => void
|
|
207
|
+
table: (rows: [string, string][], indent?: number) => void
|
|
208
|
+
warn: (msg: string) => void
|
|
209
|
+
write: (msg: string) => void
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
class AiSpendLimitError = {
|
|
213
|
+
new (message: string, context?: Record<string, unknown>): AiSpendLimitError
|
|
214
|
+
readonly code: string
|
|
215
|
+
readonly context?: Record<string, unknown> | undefined
|
|
216
|
+
readonly status: number
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
class AiTestCommand = {
|
|
220
|
+
new (): AiTestCommand
|
|
221
|
+
static args: ArgDef[]
|
|
222
|
+
static commandName: string
|
|
223
|
+
static description: string
|
|
224
|
+
static flags: FlagDef[]
|
|
225
|
+
static needsApp: boolean
|
|
226
|
+
_readLine: () => Promise<string>
|
|
227
|
+
_writer: OutputWriter
|
|
228
|
+
app: unknown
|
|
229
|
+
args: Record<string, string>
|
|
230
|
+
ask: (question: string, defaultValue?: string) => Promise<string>
|
|
231
|
+
choice: (question: string, options: string[]) => Promise<string>
|
|
232
|
+
confirm: (question: string, defaultValue?: boolean) => Promise<boolean>
|
|
233
|
+
dim: (msg: string) => void
|
|
234
|
+
error: (msg: string) => void
|
|
235
|
+
flags: Record<string, string | number | boolean>
|
|
236
|
+
info: (msg: string) => void
|
|
237
|
+
line: (msg: string) => void
|
|
238
|
+
newLine: () => void
|
|
239
|
+
run: () => Promise<void>
|
|
240
|
+
secret: (question: string) => Promise<string>
|
|
241
|
+
section: (title: string) => void
|
|
242
|
+
table: (rows: [string, string][], indent?: number) => void
|
|
243
|
+
warn: (msg: string) => void
|
|
244
|
+
write: (msg: string) => void
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
class AiToolCalled = {
|
|
248
|
+
new (driver: string, tool: string, step: number, durationMs: number, ok: boolean, error?: string | undefined): AiToolCalled
|
|
249
|
+
readonly driver: string
|
|
250
|
+
readonly durationMs: number
|
|
251
|
+
readonly error?: string | undefined
|
|
252
|
+
readonly ok: boolean
|
|
253
|
+
readonly step: number
|
|
254
|
+
readonly tool: string
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
class AnthropicDriver = {
|
|
258
|
+
new (config: AnthropicConfigShape, inject?: LoadedAnthropic): AnthropicDriver
|
|
259
|
+
countTokens: (request: AiRequest) => Promise<number>
|
|
260
|
+
model: string
|
|
261
|
+
object: <T>(request: AiRequest, schema: SchemaInput) => Promise<AiObjectResponse<T>>
|
|
262
|
+
readonly name: 'anthropic'
|
|
263
|
+
stream: (request: AiRequest) => AsyncIterable<AiStreamChunk>
|
|
264
|
+
text: (request: AiRequest) => Promise<AiResponse>
|
|
265
|
+
verify: () => Promise<DriverStatus>
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
class OllamaDriver = {
|
|
269
|
+
new (config: OllamaConfigShape, fetchImpl?: typeof fetch): OllamaDriver
|
|
270
|
+
countTokens: (_request: AiRequest) => Promise<number>
|
|
271
|
+
model: string
|
|
272
|
+
object: <T>(request: AiRequest, schema: SchemaInput) => Promise<AiObjectResponse<T>>
|
|
273
|
+
readonly name: 'ollama'
|
|
274
|
+
stream: (request: AiRequest) => AsyncIterable<AiStreamChunk>
|
|
275
|
+
text: (request: AiRequest) => Promise<AiResponse>
|
|
276
|
+
verify: () => Promise<DriverStatus>
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
class OllamaEmbeddingsDriver = {
|
|
280
|
+
new (config: { model: string; baseUrl: string; timeout: number; }, fetchImpl?: typeof fetch): OllamaEmbeddingsDriver
|
|
281
|
+
embed: (request: AiEmbedRequest) => Promise<AiEmbedResponse>
|
|
282
|
+
model: string
|
|
283
|
+
readonly name: 'ollama'
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
class OpenAiDriver = {
|
|
287
|
+
new (config: OpenAiConfigShape, fetchImpl?: typeof fetch): OpenAiDriver
|
|
288
|
+
countTokens: (_request: AiRequest) => Promise<number>
|
|
289
|
+
model: string
|
|
290
|
+
object: <T>(request: AiRequest, schema: SchemaInput) => Promise<AiObjectResponse<T>>
|
|
291
|
+
readonly name: 'openai'
|
|
292
|
+
stream: (request: AiRequest) => AsyncIterable<AiStreamChunk>
|
|
293
|
+
text: (request: AiRequest) => Promise<AiResponse>
|
|
294
|
+
verify: () => Promise<DriverStatus>
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
class OpenAiEmbeddingsDriver = {
|
|
298
|
+
new (config: { apiKey: string; model: string; baseUrl: string; timeout: number; }, fetchImpl?: typeof fetch): OpenAiEmbeddingsDriver
|
|
299
|
+
embed: (request: AiEmbedRequest) => Promise<AiEmbedResponse>
|
|
300
|
+
model: string
|
|
301
|
+
readonly name: 'openai'
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
class UnknownAiDriverError = {
|
|
305
|
+
new (driver: string, known?: string[]): UnknownAiDriverError
|
|
306
|
+
readonly code: string
|
|
307
|
+
readonly context?: Record<string, unknown> | undefined
|
|
308
|
+
readonly status: number
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const Ai = AiManager
|
|
312
|
+
|
|
313
|
+
function AiConfig = (options?: DeepPartial<AiConfigShape>) => AiConfigShape
|
|
314
|
+
|
|
315
|
+
function AiConfigFromEnv = () => AiConfigShape
|
|
316
|
+
|
|
317
|
+
function estimateCost = (model: string, usage: AiUsage) => number
|
|
318
|
+
|
|
319
|
+
function modelPrice = (model: string) => ModelPrice | undefined
|
|
320
|
+
|
|
321
|
+
function modelRejectsSampling = (model: string) => boolean
|
|
322
|
+
|
|
323
|
+
function modelStats = () => ModelStat[]
|
|
324
|
+
|
|
325
|
+
function recentGenerations = (limit?: number) => AiDelivery[]
|
|
326
|
+
|
|
327
|
+
function refusalRate = () => number
|
|
328
|
+
|
|
329
|
+
function registerModelPrice = (model: string, price: ModelPrice) => void
|
|
330
|
+
|
|
331
|
+
function resetSpend = () => void
|
|
332
|
+
|
|
333
|
+
function resetStats = () => void
|
|
334
|
+
|
|
335
|
+
function spentToday = () => number
|
|
336
|
+
|
|
337
|
+
function strippedConstraints = (input: SchemaInput) => string[]
|
|
338
|
+
|
|
339
|
+
function tool = <I extends Record<string, unknown> = Record<string, unknown>>(options: { name: string; description: string; input: ((rule: RuleBuilder) => Record<string, FieldRule>) | SchemaInput; handle: (input: I, ctx: AiToolContext) => Promise<unknown> | unknown;}) => AiTool
|
|
340
|
+
|
|
341
|
+
function toSchema = (input: SchemaInput) => Schema
|
|
342
|
+
|
|
343
|
+
function translateSchema = (input: SchemaInput) => JsonSchema
|
|
344
|
+
|
|
345
|
+
function validateAiConfig = (config: AiConfigShape) => void
|
|
346
|
+
|
|
347
|
+
interface AgentOptions = {
|
|
348
|
+
maxResumes: number
|
|
349
|
+
maxSteps: number
|
|
350
|
+
signal: AbortSignal
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
interface AiAgentConfigShape = {
|
|
354
|
+
lock: boolean
|
|
355
|
+
lockTtl: number
|
|
356
|
+
maxResumes: number
|
|
357
|
+
maxSteps: number
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
interface AiAgentRequest = {
|
|
361
|
+
cache?: boolean
|
|
362
|
+
driver?: string
|
|
363
|
+
effort?: AiEffort
|
|
364
|
+
lock?: string
|
|
365
|
+
maxResumes?: number
|
|
366
|
+
maxSteps?: number
|
|
367
|
+
maxTokens?: number
|
|
368
|
+
messages?: AiMessage[]
|
|
369
|
+
model?: string
|
|
370
|
+
prompt?: string
|
|
371
|
+
providerOptions?: AiProviderOptions
|
|
372
|
+
signal?: AbortSignal
|
|
373
|
+
system?: string
|
|
374
|
+
temperature?: number
|
|
375
|
+
tools?: AiTool<Record<string, unknown>>[]
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
interface AiAgentResult = {
|
|
379
|
+
model: string
|
|
380
|
+
steps: AiAgentStep[]
|
|
381
|
+
stopReason: AiStopReason
|
|
382
|
+
text: string
|
|
383
|
+
usage: AiUsage
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
interface AiAgentStep = {
|
|
387
|
+
call: AiToolCall
|
|
388
|
+
durationMs: number
|
|
389
|
+
isError: boolean
|
|
390
|
+
result: string
|
|
391
|
+
step: number
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
interface AiConfigShape = {
|
|
395
|
+
agent: AiAgentConfigShape
|
|
396
|
+
default: string
|
|
397
|
+
drivers: { anthropic?: AnthropicConfigShape; openai?: OpenAiConfigShape; ollama?: OllamaConfigShape;}
|
|
398
|
+
embeddings: EmbeddingsConfigShape
|
|
399
|
+
limits: AiLimitsConfigShape
|
|
400
|
+
redact: boolean
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
interface AiDelivery = {
|
|
404
|
+
at: number
|
|
405
|
+
cacheReadTokens: number
|
|
406
|
+
costUsd: number
|
|
407
|
+
driver: string
|
|
408
|
+
durationMs: number
|
|
409
|
+
error?: string
|
|
410
|
+
inputTokens: number
|
|
411
|
+
model: string
|
|
412
|
+
ok: boolean
|
|
413
|
+
operation: string
|
|
414
|
+
outputTokens: number
|
|
415
|
+
preview: string
|
|
416
|
+
refused: boolean
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
interface AiDriver = {
|
|
420
|
+
agent?: (request: AiRequest, options: AgentOptions) => Promise<AiAgentResult>
|
|
421
|
+
countTokens: (request: AiRequest) => Promise<number>
|
|
422
|
+
object: <T>(request: AiRequest, schema: SchemaInput) => Promise<AiObjectResponse<T>>
|
|
423
|
+
readonly model: string
|
|
424
|
+
readonly name: string
|
|
425
|
+
stream: (request: AiRequest) => AsyncIterable<AiStreamChunk>
|
|
426
|
+
text: (request: AiRequest) => Promise<AiResponse>
|
|
427
|
+
verify: () => Promise<DriverStatus>
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
interface AiEmbedRequest = {
|
|
431
|
+
driver?: string
|
|
432
|
+
input: string | string[]
|
|
433
|
+
model?: string
|
|
434
|
+
signal?: AbortSignal
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
interface AiEmbedResponse = {
|
|
438
|
+
embeddings: number[][]
|
|
439
|
+
model: string
|
|
440
|
+
usage: Pick<AiUsage, 'inputTokens'>
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
interface AiLimitsConfigShape = {
|
|
444
|
+
perDayUsd: number
|
|
445
|
+
perRequestUsd: number
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
interface AiMessage = {
|
|
449
|
+
content: string
|
|
450
|
+
raw?: unknown
|
|
451
|
+
role: AiRole
|
|
452
|
+
toolCalls?: AiToolCall[]
|
|
453
|
+
toolResults?: AiToolResult[]
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
interface AiObjectResponse = {
|
|
457
|
+
model: string
|
|
458
|
+
object: T
|
|
459
|
+
raw?: unknown
|
|
460
|
+
usage: AiUsage
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
interface AiQueueOptions = {
|
|
464
|
+
handler: string
|
|
465
|
+
meta?: Record<string, unknown>
|
|
466
|
+
queue?: string
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
interface AiRequest = {
|
|
470
|
+
cache?: boolean
|
|
471
|
+
driver?: string
|
|
472
|
+
effort?: AiEffort
|
|
473
|
+
maxTokens?: number
|
|
474
|
+
messages?: AiMessage[]
|
|
475
|
+
model?: string
|
|
476
|
+
prompt?: string
|
|
477
|
+
providerOptions?: AiProviderOptions
|
|
478
|
+
signal?: AbortSignal
|
|
479
|
+
system?: string
|
|
480
|
+
temperature?: number
|
|
481
|
+
tools?: AiTool<Record<string, unknown>>[]
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
interface AiResponse = {
|
|
485
|
+
assistantTurn: AiMessage
|
|
486
|
+
model: string
|
|
487
|
+
raw?: unknown
|
|
488
|
+
stopReason: AiStopReason
|
|
489
|
+
text: string
|
|
490
|
+
toolCalls: AiToolCall[]
|
|
491
|
+
usage: AiUsage
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
interface AiTool = {
|
|
495
|
+
description: string
|
|
496
|
+
handler: (input: I, ctx: AiToolContext) => Promise<unknown> | unknown
|
|
497
|
+
inputSchema: JsonSchema
|
|
498
|
+
name: string
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
interface AiToolCall = {
|
|
502
|
+
id: string
|
|
503
|
+
input: Record<string, unknown>
|
|
504
|
+
name: string
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
interface AiToolContext = {
|
|
508
|
+
signal: AbortSignal
|
|
509
|
+
step: number
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
interface AiToolResult = {
|
|
513
|
+
content: string
|
|
514
|
+
id: string
|
|
515
|
+
isError?: boolean
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
interface AiUsage = {
|
|
519
|
+
cacheReadTokens: number
|
|
520
|
+
cacheWriteTokens: number
|
|
521
|
+
inputTokens: number
|
|
522
|
+
outputTokens: number
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
interface AnthropicConfigShape = {
|
|
526
|
+
apiKey: string
|
|
527
|
+
baseUrl?: string
|
|
528
|
+
cacheSystem: boolean
|
|
529
|
+
effort: AiEffort
|
|
530
|
+
fallbacks: boolean
|
|
531
|
+
maxTokens: number
|
|
532
|
+
model: string
|
|
533
|
+
streamMaxTokens: number
|
|
534
|
+
temperature?: number
|
|
535
|
+
timeout: number
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
interface CapturedGeneration = {
|
|
539
|
+
operation: string
|
|
540
|
+
prompt: string
|
|
541
|
+
request: AiRequest
|
|
542
|
+
system: string | undefined
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
interface DriverStatus = {
|
|
546
|
+
detail: string
|
|
547
|
+
model: string
|
|
548
|
+
ok: boolean
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
interface EmbeddingsConfigShape = {
|
|
552
|
+
default: string
|
|
553
|
+
drivers: { openai?: { apiKey: string; model: string; baseUrl: string; timeout: number; }; ollama?: { model: string; baseUrl: string; timeout: number; };}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
interface EmbeddingsDriver = {
|
|
557
|
+
embed: (request: AiEmbedRequest) => Promise<AiEmbedResponse>
|
|
558
|
+
readonly model: string
|
|
559
|
+
readonly name: string
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
interface JsonSchema = {
|
|
563
|
+
additionalProperties?: false
|
|
564
|
+
anyOf?: JsonSchema[]
|
|
565
|
+
description?: string
|
|
566
|
+
enum?: (string | number)[]
|
|
567
|
+
format?: string
|
|
568
|
+
items?: JsonSchema
|
|
569
|
+
properties?: Record<string, JsonSchema>
|
|
570
|
+
required?: string[]
|
|
571
|
+
type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'integer' | 'null'
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
interface ModelPrice = {
|
|
575
|
+
input: number
|
|
576
|
+
output: number
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
interface ModelStat = {
|
|
580
|
+
cacheReadTokens: number
|
|
581
|
+
calls: number
|
|
582
|
+
costUsd: number
|
|
583
|
+
failures: number
|
|
584
|
+
inputTokens: number
|
|
585
|
+
model: string
|
|
586
|
+
outputTokens: number
|
|
587
|
+
p50: number
|
|
588
|
+
p95: number
|
|
589
|
+
refusals: number
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
interface OllamaConfigShape = {
|
|
593
|
+
baseUrl: string
|
|
594
|
+
model: string
|
|
595
|
+
timeout: number
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
interface OpenAiConfigShape = {
|
|
599
|
+
apiKey: string
|
|
600
|
+
baseUrl: string
|
|
601
|
+
maxTokens: number
|
|
602
|
+
model: string
|
|
603
|
+
timeout: number
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
type AiConfigInput = { default?: string | undefined; drivers?: DeepPartial<{ anthropic?: AnthropicConfigShape; openai?: OpenAiConfigShape; ollama?: OllamaConfigShape; }> | undefined; embeddings?: DeepPartial<EmbeddingsConfigShape> | undefined; limits?: DeepPartial<AiLimitsConfigShape> | undefined; redact?: boolean | undefined; agent?: DeepPartial<AiAgentConfigShape> | undefined;}
|
|
607
|
+
|
|
608
|
+
type AiEffort = 'max' | 'medium' | 'low' | 'high' | 'xhigh'
|
|
609
|
+
|
|
610
|
+
type AiProviderOptions = { [x: string]: Record<string, unknown>;}
|
|
611
|
+
|
|
612
|
+
type AiQueueHandler = (response: AiResponse, meta: Record<string, unknown>) => Promise<void> | void
|
|
613
|
+
|
|
614
|
+
type AiRole = 'user' | 'assistant'
|
|
615
|
+
|
|
616
|
+
type AiStopReason = 'end_turn' | 'max_tokens' | 'tool_use' | 'pause_turn' | 'refusal' | 'stop_sequence' | 'unknown'
|
|
617
|
+
|
|
618
|
+
type AiStreamChunk = { type: 'text'; text: string;} | { type: 'thinking'; text: string;} | { type: 'tool_call'; call: AiToolCall;} | { type: 'done'; response: AiResponse;}
|
|
619
|
+
|
|
620
|
+
type SchemaInput = { [x: string]: FieldRuleDefinition | FieldRule;}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/ai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "experimental",
|
|
6
6
|
"private": false,
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"CHANGELOG.md",
|
|
15
|
+
"api-surface.md",
|
|
15
16
|
"src",
|
|
16
17
|
"!src/**/*.test.ts",
|
|
17
18
|
"!src/**/*.test.tsx",
|
|
@@ -29,9 +30,9 @@
|
|
|
29
30
|
"typecheck": "tsc --noEmit"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@zerotal/core": "1.
|
|
33
|
-
"@zerotal/validator": "1.
|
|
34
|
-
"@zerotal/queue": "1.
|
|
33
|
+
"@zerotal/core": "1.7.0",
|
|
34
|
+
"@zerotal/validator": "1.7.0",
|
|
35
|
+
"@zerotal/queue": "1.7.0"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
38
|
"@anthropic-ai/sdk": ">=0.70.0"
|
package/src/config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { deepMerge } from "@zerotal/core";
|
|
2
|
+
import type { DeepPartial } from "@zerotal/core";
|
|
2
3
|
import { AiConfigError } from "./errors.ts";
|
|
3
4
|
import type {
|
|
4
5
|
AiConfigShape,
|
|
@@ -9,20 +10,6 @@ import type {
|
|
|
9
10
|
} from "./types.ts";
|
|
10
11
|
import { modelRejectsSampling } from "./pricing.ts";
|
|
11
12
|
|
|
12
|
-
/**
|
|
13
|
-
* Recursively-optional view of the config, so callers override only what they
|
|
14
|
-
* care about.
|
|
15
|
-
*
|
|
16
|
-
* `NonNullable` before the `extends object` test is load-bearing: every driver
|
|
17
|
-
* block is already optional, so `AnthropicConfigShape | undefined` does not
|
|
18
|
-
* extend `object` and the recursion would stop one level too early — leaving
|
|
19
|
-
* `{ drivers: { anthropic: { apiKey } } }`, the single most common thing anyone
|
|
20
|
-
* writes in `config/ai.ts`, a type error.
|
|
21
|
-
*/
|
|
22
|
-
type DeepPartial<T> = {
|
|
23
|
-
[K in keyof T]?: NonNullable<T[K]> extends object ? DeepPartial<NonNullable<T[K]>> : T[K];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
13
|
/**
|
|
27
14
|
* What {@link AiConfig} accepts — every key optional, all the way down. The
|
|
28
15
|
* same type the factory's parameter is written as, exported under a name
|