experimental-a2 0.14.1 → 0.16.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/CHANGELOG.md +81 -0
- package/dist/actor-client.d.ts +1 -1
- package/dist/{actor-BfQSE0KC.d.ts → actor-ohPC-81x.d.ts} +5 -5
- package/dist/{actor-BfQSE0KC.d.ts.map → actor-ohPC-81x.d.ts.map} +1 -1
- package/dist/actor-react.d.ts +3 -3
- package/dist/actor.d.ts +1 -1
- package/dist/actor.js +1 -1
- package/dist/ai-CrLYwNEx.js +2431 -0
- package/dist/ai-CrLYwNEx.js.map +1 -0
- package/dist/{ai-Cai-lCbj.d.ts → ai-HJ9fHfYI.d.ts} +72 -13
- package/dist/ai-HJ9fHfYI.d.ts.map +1 -0
- package/dist/ai-server.d.ts +4 -5
- package/dist/ai-server.d.ts.map +1 -1
- package/dist/ai-server.js +755 -290
- package/dist/ai-server.js.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.js +1 -1999
- package/dist/client-BYzHjkwU.js.map +1 -1
- package/dist/{client-BAEABRZB.d.ts → client-CzyacQpJ.d.ts} +9 -9
- package/dist/client-CzyacQpJ.d.ts.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/idempotent-id-BRJVeylj.js +13 -0
- package/dist/idempotent-id-BRJVeylj.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -1
- package/dist/otel.d.ts +1 -1
- package/dist/react.d.ts +13 -13
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js.map +1 -1
- package/dist/reducer-DEMjEY_O.js.map +1 -1
- package/dist/{reducer-BcS9VDKC.d.ts → reducer-otzHjuJj.d.ts} +3 -3
- package/dist/{reducer-BcS9VDKC.d.ts.map → reducer-otzHjuJj.d.ts.map} +1 -1
- package/dist/scheduler-qstash.d.ts +2 -2
- package/dist/scheduler-qstash.js +1 -1
- package/dist/scheduler-vercel.d.ts +2 -2
- package/dist/scheduler-vercel.js +1 -1
- package/dist/{server-CjJSGcF7.js → server-BD5ckxZb.js} +39 -26
- package/dist/server-BD5ckxZb.js.map +1 -0
- package/dist/{server-Bp5Nd1pF.d.ts → server-DbD7IJVK.d.ts} +5 -5
- package/dist/{server-Bp5Nd1pF.d.ts.map → server-DbD7IJVK.d.ts.map} +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.js +1 -1
- package/dist/{store-D_yhNdPz.d.ts → store-DyZM6fS5.d.ts} +3 -2
- package/dist/{store-D_yhNdPz.d.ts.map → store-DyZM6fS5.d.ts.map} +1 -1
- package/dist/store-N8PXxDAS.js.map +1 -1
- package/dist/store-memory.d.ts +1 -1
- package/dist/store-postgres.d.ts +1 -1
- package/dist/store-redis-http.d.ts +1 -1
- package/dist/store-redis-http.js +1 -1
- package/dist/{store-redis-notify-D2EI6gwX.js → store-redis-notify-BVLUfI3j.js} +14 -13
- package/dist/store-redis-notify-BVLUfI3j.js.map +1 -0
- package/dist/store-redis.d.ts +1 -1
- package/dist/store-redis.js +1 -1
- package/dist/store-sqlite.d.ts +1 -1
- package/dist/{telemetry-CpeclqB2.d.ts → telemetry-B5jzpy6y.d.ts} +2 -2
- package/dist/telemetry-B5jzpy6y.d.ts.map +1 -0
- package/docs/concepts/04-state.mdx +9 -4
- package/docs/guides/06-ai-agents.mdx +134 -43
- package/docs/reference/01-api.mdx +129 -27
- package/examples/playground/app/agent/[agentId]/agent-client.tsx +20 -28
- package/examples/playground/app/agent/[agentId]/agent-queue.test.tsx +123 -0
- package/examples/playground/app/agent/[agentId]/agent-queue.tsx +37 -43
- package/examples/playground/app/agent/[agentId]/compaction-panel.tsx +44 -24
- package/examples/playground/app/agent/compaction-timeline.test.ts +47 -7
- package/examples/playground/app/agent/compaction-timeline.ts +13 -3
- package/examples/playground/app/chat/[chatId]/chat-client.tsx +1 -5
- package/examples/playground/app/chat/[chatId]/session.ts +17 -2
- package/examples/playground/app/chat/model.test.ts +4 -4
- package/examples/playground/app/chat/model.ts +18 -6
- package/examples/playground/app/chat/server.ts +6 -3
- package/examples/playground/package.json +3 -1
- package/package.json +1 -1
- package/src/ai-client-state.ts +0 -2
- package/src/ai-context-schema.ts +296 -0
- package/src/ai-context.ts +680 -0
- package/src/ai-control-server.ts +160 -131
- package/src/ai-control-state.ts +6 -0
- package/src/ai-control.ts +6 -7
- package/src/ai-coordinator.ts +92 -38
- package/src/ai-id.ts +6 -0
- package/src/ai-input-tokens.ts +75 -0
- package/src/ai-message-projection.ts +348 -0
- package/src/ai-server.ts +232 -334
- package/src/ai-stored-state.ts +484 -0
- package/src/ai.ts +252 -418
- package/src/client.ts +21 -15
- package/src/idempotent-id.ts +11 -0
- package/src/index.ts +1 -0
- package/src/react.ts +25 -19
- package/src/reducer.ts +2 -1
- package/src/server.ts +73 -56
- package/src/store-redis-core.ts +15 -17
- package/src/store.ts +1 -0
- package/src/telemetry.ts +2 -1
- package/dist/ai-Cai-lCbj.d.ts.map +0 -1
- package/dist/ai-control-CcD4hh3y.js +0 -119
- package/dist/ai-control-CcD4hh3y.js.map +0 -1
- package/dist/ai.js.map +0 -1
- package/dist/client-BAEABRZB.d.ts.map +0 -1
- package/dist/server-CjJSGcF7.js.map +0 -1
- package/dist/store-redis-notify-D2EI6gwX.js.map +0 -1
- package/dist/telemetry-CpeclqB2.d.ts.map +0 -1
package/src/ai-coordinator.ts
CHANGED
|
@@ -8,8 +8,10 @@ import type {
|
|
|
8
8
|
GenerationCompletedPayload,
|
|
9
9
|
GenerationFailedPayload,
|
|
10
10
|
GenerationRequestedPayload,
|
|
11
|
+
GenerationReason,
|
|
11
12
|
GenerationStartedPayload,
|
|
12
13
|
InputRequestedPayload,
|
|
14
|
+
InputRespondedPayload,
|
|
13
15
|
MessageCreatedPayload,
|
|
14
16
|
MessageInterruptedPayload,
|
|
15
17
|
ToolCalledPayload,
|
|
@@ -18,12 +20,51 @@ import type {
|
|
|
18
20
|
import type { Contract, ContractEvent, EventDefs } from './contract.ts'
|
|
19
21
|
import type { Reducer } from './reducer.ts'
|
|
20
22
|
|
|
23
|
+
type CompletedCall = Pick<
|
|
24
|
+
ToolCalledPayload,
|
|
25
|
+
| 'requestId'
|
|
26
|
+
| 'generationId'
|
|
27
|
+
| 'messageId'
|
|
28
|
+
| 'toolCallId'
|
|
29
|
+
| 'toolName'
|
|
30
|
+
| 'providerExecuted'
|
|
31
|
+
| 'supportsDeferredResults'
|
|
32
|
+
>
|
|
33
|
+
|
|
21
34
|
export type CoordinatorCall = {
|
|
22
|
-
call: ToolCalledPayload
|
|
23
35
|
approval?: ApprovalRequestedPayload
|
|
24
36
|
response?: ApprovalRespondedPayload
|
|
25
|
-
terminal: boolean
|
|
26
37
|
work?: ControlWork
|
|
38
|
+
} & (
|
|
39
|
+
| { call: ToolCalledPayload; terminal: false }
|
|
40
|
+
| { call: CompletedCall; terminal: true }
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
const completeCall = (candidate: CoordinatorCall): CoordinatorCall => {
|
|
44
|
+
const {
|
|
45
|
+
requestId,
|
|
46
|
+
generationId,
|
|
47
|
+
messageId,
|
|
48
|
+
toolCallId,
|
|
49
|
+
toolName,
|
|
50
|
+
providerExecuted,
|
|
51
|
+
supportsDeferredResults,
|
|
52
|
+
} = candidate.call
|
|
53
|
+
return {
|
|
54
|
+
terminal: true,
|
|
55
|
+
call: {
|
|
56
|
+
requestId,
|
|
57
|
+
generationId,
|
|
58
|
+
messageId,
|
|
59
|
+
toolCallId,
|
|
60
|
+
toolName,
|
|
61
|
+
...(providerExecuted === undefined ? {} : { providerExecuted }),
|
|
62
|
+
...(supportsDeferredResults === undefined
|
|
63
|
+
? {}
|
|
64
|
+
: { supportsDeferredResults }),
|
|
65
|
+
},
|
|
66
|
+
...(candidate.work === undefined ? {} : { work: candidate.work }),
|
|
67
|
+
}
|
|
27
68
|
}
|
|
28
69
|
|
|
29
70
|
export type CoordinatorResponse = {
|
|
@@ -32,13 +73,11 @@ export type CoordinatorResponse = {
|
|
|
32
73
|
status: 'requested' | 'generating' | 'waiting' | 'failed'
|
|
33
74
|
stepCount: number
|
|
34
75
|
activeRequestId?: string
|
|
76
|
+
requestReason: GenerationReason
|
|
77
|
+
sourceGenerationId?: string
|
|
35
78
|
generation?: GenerationStartedPayload
|
|
36
|
-
promptThroughIndex?: number
|
|
37
79
|
source?: {
|
|
38
80
|
generation: GenerationStartedPayload
|
|
39
|
-
promptThroughIndex: number
|
|
40
|
-
failed: boolean
|
|
41
|
-
canCompact: boolean
|
|
42
81
|
}
|
|
43
82
|
completion?: GenerationCompletedPayload
|
|
44
83
|
failure?: GenerationFailedPayload
|
|
@@ -53,6 +92,7 @@ export type CoordinatorResponse = {
|
|
|
53
92
|
|
|
54
93
|
export type AICoordinatorState = {
|
|
55
94
|
closed: boolean
|
|
95
|
+
unsettledTools?: Record<string, true>
|
|
56
96
|
queued: Array<{ messageId: string; generate: boolean }>
|
|
57
97
|
response?: CoordinatorResponse
|
|
58
98
|
calibration?: { model: string; inputTokens: number; estimate: number }
|
|
@@ -96,8 +136,7 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
96
136
|
case 'ai.generation.requested': {
|
|
97
137
|
const request = event.payload as GenerationRequestedPayload
|
|
98
138
|
if (request.reason === 'message') {
|
|
99
|
-
const responseMessageId =
|
|
100
|
-
request.responseMessageId ?? `${request.messageId}:assistant`
|
|
139
|
+
const responseMessageId = request.responseMessageId
|
|
101
140
|
const requested = state.queued.findIndex(
|
|
102
141
|
(item) => item.messageId === request.messageId,
|
|
103
142
|
)
|
|
@@ -115,6 +154,10 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
115
154
|
status: 'requested',
|
|
116
155
|
stepCount: 0,
|
|
117
156
|
activeRequestId: event.id,
|
|
157
|
+
requestReason: request.reason,
|
|
158
|
+
...(request.sourceGenerationId === undefined
|
|
159
|
+
? {}
|
|
160
|
+
: { sourceGenerationId: request.sourceGenerationId }),
|
|
118
161
|
calls: [],
|
|
119
162
|
inputs: [],
|
|
120
163
|
},
|
|
@@ -129,8 +172,12 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
129
172
|
if (
|
|
130
173
|
(request.reason === 'tool' &&
|
|
131
174
|
(!continuationReady(state) ||
|
|
132
|
-
|
|
133
|
-
|
|
175
|
+
request.sourceGenerationId !==
|
|
176
|
+
state.response.generation?.generationId)) ||
|
|
177
|
+
(request.sourceGenerationId !== undefined &&
|
|
178
|
+
request.sourceGenerationId !==
|
|
179
|
+
(state.response.generation ?? state.response.source?.generation)
|
|
180
|
+
?.generationId) ||
|
|
134
181
|
(request.reason === 'retry' && state.response.status !== 'failed') ||
|
|
135
182
|
(request.reason === 'input' &&
|
|
136
183
|
state.response.inputResponse === undefined)
|
|
@@ -139,23 +186,21 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
139
186
|
}
|
|
140
187
|
return updateResponse(state, (response) => {
|
|
141
188
|
const generation = response.generation ?? response.source?.generation
|
|
142
|
-
const promptThroughIndex =
|
|
143
|
-
response.promptThroughIndex ?? response.source?.promptThroughIndex
|
|
144
189
|
return {
|
|
145
190
|
rootMessageId: response.rootMessageId,
|
|
146
191
|
responseMessageId: response.responseMessageId,
|
|
147
192
|
status: 'requested',
|
|
148
193
|
stepCount: response.stepCount,
|
|
149
194
|
activeRequestId: event.id,
|
|
150
|
-
|
|
195
|
+
requestReason: request.reason,
|
|
196
|
+
...(request.sourceGenerationId === undefined
|
|
197
|
+
? {}
|
|
198
|
+
: { sourceGenerationId: request.sourceGenerationId }),
|
|
199
|
+
...(generation === undefined
|
|
151
200
|
? {}
|
|
152
201
|
: {
|
|
153
202
|
source: {
|
|
154
203
|
generation,
|
|
155
|
-
promptThroughIndex,
|
|
156
|
-
failed:
|
|
157
|
-
response.failure?.generationId === generation.generationId,
|
|
158
|
-
canCompact: response.calls.every((call) => call.terminal),
|
|
159
204
|
},
|
|
160
205
|
}),
|
|
161
206
|
calls: [],
|
|
@@ -179,11 +224,12 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
179
224
|
status: 'generating',
|
|
180
225
|
stepCount: response.stepCount,
|
|
181
226
|
generation,
|
|
182
|
-
...(generation.promptThroughIndex === undefined
|
|
183
|
-
? {}
|
|
184
|
-
: { promptThroughIndex: generation.promptThroughIndex }),
|
|
185
227
|
...(response.source === undefined ? {} : { source: response.source }),
|
|
186
228
|
activeRequestId: generation.requestId,
|
|
229
|
+
requestReason: response.requestReason,
|
|
230
|
+
...(response.sourceGenerationId === undefined
|
|
231
|
+
? {}
|
|
232
|
+
: { sourceGenerationId: response.sourceGenerationId }),
|
|
187
233
|
calls: [],
|
|
188
234
|
inputs: [],
|
|
189
235
|
}))
|
|
@@ -191,7 +237,8 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
191
237
|
case 'ai.generation.completed': {
|
|
192
238
|
const completion = event.payload as GenerationCompletedPayload
|
|
193
239
|
if (
|
|
194
|
-
state.response?.generation?.
|
|
240
|
+
state.response?.generation?.requestId !== completion.requestId ||
|
|
241
|
+
state.response.generation.generationId !== completion.generationId
|
|
195
242
|
) {
|
|
196
243
|
return state
|
|
197
244
|
}
|
|
@@ -223,11 +270,13 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
223
270
|
const failure = event.payload as GenerationFailedPayload
|
|
224
271
|
const response = state.response
|
|
225
272
|
const ownsActiveGeneration =
|
|
226
|
-
response?.generation?.generationId === failure.generationId
|
|
273
|
+
response?.generation?.generationId === failure.generationId &&
|
|
274
|
+
response.generation.requestId === failure.requestId
|
|
227
275
|
const ownsActiveStepLimit =
|
|
228
276
|
failure.stepLimit === true &&
|
|
229
|
-
response?.
|
|
230
|
-
|
|
277
|
+
response?.requestReason === 'tool' &&
|
|
278
|
+
response.sourceGenerationId === failure.generationId &&
|
|
279
|
+
response.source?.generation.requestId === failure.requestId &&
|
|
231
280
|
response.responseMessageId === failure.responseMessageId
|
|
232
281
|
if (!ownsActiveGeneration && !ownsActiveStepLimit) {
|
|
233
282
|
return state
|
|
@@ -258,7 +307,10 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
258
307
|
}
|
|
259
308
|
case 'ai.tool.called': {
|
|
260
309
|
const call = event.payload as ToolCalledPayload
|
|
261
|
-
if (
|
|
310
|
+
if (
|
|
311
|
+
state.response?.generation?.requestId !== call.requestId ||
|
|
312
|
+
state.response.generation.generationId !== call.generationId
|
|
313
|
+
) {
|
|
262
314
|
return state
|
|
263
315
|
}
|
|
264
316
|
return updateResponse(state, (response) => ({
|
|
@@ -273,7 +325,10 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
273
325
|
}
|
|
274
326
|
case 'ai.approval.requested': {
|
|
275
327
|
const approval = event.payload as ApprovalRequestedPayload
|
|
276
|
-
if (
|
|
328
|
+
if (
|
|
329
|
+
state.response?.generation?.requestId !== approval.requestId ||
|
|
330
|
+
state.response.generation.generationId !== approval.generationId
|
|
331
|
+
) {
|
|
277
332
|
return state
|
|
278
333
|
}
|
|
279
334
|
return updateResponse(state, (response) => ({
|
|
@@ -289,7 +344,8 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
289
344
|
const approval = event.payload as ApprovalRespondedPayload
|
|
290
345
|
if (
|
|
291
346
|
state.response?.responseMessageId !== approval.messageId ||
|
|
292
|
-
state.response.generation?.
|
|
347
|
+
state.response.generation?.requestId !== approval.requestId ||
|
|
348
|
+
state.response.generation.generationId !== approval.generationId
|
|
293
349
|
) {
|
|
294
350
|
return state
|
|
295
351
|
}
|
|
@@ -306,7 +362,8 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
306
362
|
const result = event.payload as ToolResultPayload
|
|
307
363
|
if (
|
|
308
364
|
result.preliminary === true ||
|
|
309
|
-
state.response?.generation?.
|
|
365
|
+
state.response?.generation?.requestId !== result.requestId ||
|
|
366
|
+
state.response.generation.generationId !== result.generationId
|
|
310
367
|
) {
|
|
311
368
|
return state
|
|
312
369
|
}
|
|
@@ -314,7 +371,7 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
314
371
|
...response,
|
|
315
372
|
calls: response.calls.map((candidate) =>
|
|
316
373
|
candidate.call.toolCallId === result.toolCallId
|
|
317
|
-
?
|
|
374
|
+
? completeCall(candidate)
|
|
318
375
|
: candidate,
|
|
319
376
|
),
|
|
320
377
|
}))
|
|
@@ -323,7 +380,8 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
323
380
|
const input = event.payload as InputRequestedPayload
|
|
324
381
|
if (
|
|
325
382
|
state.response?.responseMessageId !== input.messageId ||
|
|
326
|
-
state.response.generation?.
|
|
383
|
+
state.response.generation?.requestId !== input.requestId ||
|
|
384
|
+
state.response.generation.generationId !== input.generationId
|
|
327
385
|
) {
|
|
328
386
|
return state
|
|
329
387
|
}
|
|
@@ -341,12 +399,7 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
341
399
|
}))
|
|
342
400
|
}
|
|
343
401
|
case 'ai.input.responded': {
|
|
344
|
-
const input = event.payload as
|
|
345
|
-
messageId: string
|
|
346
|
-
generationId: string
|
|
347
|
-
inputId: string
|
|
348
|
-
name: string
|
|
349
|
-
}
|
|
402
|
+
const input = event.payload as InputRespondedPayload
|
|
350
403
|
const requested = state.response?.inputs.find(
|
|
351
404
|
(candidate) =>
|
|
352
405
|
candidate.messageId === input.messageId &&
|
|
@@ -356,7 +409,8 @@ export const foldCoordinator = <M extends UIMessage, D extends EventDefs>(
|
|
|
356
409
|
)
|
|
357
410
|
if (
|
|
358
411
|
state.response?.responseMessageId !== input.messageId ||
|
|
359
|
-
state.response.generation?.
|
|
412
|
+
state.response.generation?.requestId !== input.requestId ||
|
|
413
|
+
state.response.generation.generationId !== input.generationId ||
|
|
360
414
|
requested === undefined
|
|
361
415
|
) {
|
|
362
416
|
return state
|
|
@@ -386,7 +440,7 @@ export const aiCoordinatorReducer = <
|
|
|
386
440
|
): Reducer<D, AICoordinatorState> =>
|
|
387
441
|
contract
|
|
388
442
|
.reducer({
|
|
389
|
-
name: 'a2.ai.coordinator.
|
|
443
|
+
name: 'a2.ai.coordinator.v6',
|
|
390
444
|
initialState: {
|
|
391
445
|
closed: false,
|
|
392
446
|
queued: [],
|
package/src/ai-id.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer'
|
|
2
|
+
import { asSchema } from 'ai'
|
|
3
|
+
import type { Instructions, ModelMessage, ToolSet } from 'ai'
|
|
4
|
+
import type { AICoordinatorState } from './ai-coordinator.ts'
|
|
5
|
+
|
|
6
|
+
const withoutProviderOptions = <T extends object>(value: T): T => {
|
|
7
|
+
const result = { ...value }
|
|
8
|
+
Reflect.deleteProperty(result, 'providerOptions')
|
|
9
|
+
return result
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const estimatedMessage = (message: ModelMessage): unknown => ({
|
|
13
|
+
...withoutProviderOptions(message),
|
|
14
|
+
content:
|
|
15
|
+
typeof message.content === 'string'
|
|
16
|
+
? message.content
|
|
17
|
+
: message.content.map((part) =>
|
|
18
|
+
part.type === 'tool-result'
|
|
19
|
+
? {
|
|
20
|
+
...withoutProviderOptions(part),
|
|
21
|
+
output: {
|
|
22
|
+
...withoutProviderOptions(part.output),
|
|
23
|
+
...(part.output.type === 'content'
|
|
24
|
+
? {
|
|
25
|
+
value: part.output.value.map(withoutProviderOptions),
|
|
26
|
+
}
|
|
27
|
+
: {}),
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
: withoutProviderOptions(part),
|
|
31
|
+
),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export const estimateInputTokens = async (options: {
|
|
35
|
+
messages: ModelMessage[]
|
|
36
|
+
instructions: Instructions | undefined
|
|
37
|
+
tools: ToolSet
|
|
38
|
+
}): Promise<number> => {
|
|
39
|
+
const tools = await Promise.all(
|
|
40
|
+
Object.entries(options.tools).map(async ([name, tool]) => ({
|
|
41
|
+
name,
|
|
42
|
+
description: tool.description,
|
|
43
|
+
inputSchema: await asSchema(tool.inputSchema).jsonSchema,
|
|
44
|
+
})),
|
|
45
|
+
)
|
|
46
|
+
const instructions = options.instructions
|
|
47
|
+
return Math.ceil(
|
|
48
|
+
Buffer.byteLength(
|
|
49
|
+
JSON.stringify({
|
|
50
|
+
messages: options.messages.map(estimatedMessage),
|
|
51
|
+
instructions:
|
|
52
|
+
instructions === undefined || typeof instructions === 'string'
|
|
53
|
+
? instructions
|
|
54
|
+
: Array.isArray(instructions)
|
|
55
|
+
? instructions.map(estimatedMessage)
|
|
56
|
+
: estimatedMessage(instructions),
|
|
57
|
+
tools,
|
|
58
|
+
}),
|
|
59
|
+
'utf8',
|
|
60
|
+
) / 4,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const measuredInputTokens = (options: {
|
|
65
|
+
estimate: number
|
|
66
|
+
model: string
|
|
67
|
+
calibration: AICoordinatorState['calibration']
|
|
68
|
+
}): number => {
|
|
69
|
+
const previous = options.calibration
|
|
70
|
+
return previous !== undefined &&
|
|
71
|
+
previous.model === options.model &&
|
|
72
|
+
options.estimate >= previous.estimate
|
|
73
|
+
? Math.ceil(previous.inputTokens + options.estimate - previous.estimate)
|
|
74
|
+
: options.estimate
|
|
75
|
+
}
|