@pi-unipi/background-tasks 2.6.3 → 2.6.4
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/package.json +3 -2
- package/src/__tests__/anthropic-attribution.test.ts +0 -195
- package/src/__tests__/config.test.ts +0 -137
- package/src/__tests__/core.test.ts +0 -493
- package/src/__tests__/delegate-artifacts.test.ts +0 -528
- package/src/__tests__/delegate-budget.test.ts +0 -456
- package/src/__tests__/delegate-launch.test.ts +0 -676
- package/src/__tests__/delegate-result-package.test.ts +0 -350
- package/src/__tests__/delegate-seed.test.ts +0 -392
- package/src/__tests__/durable-fs.test.ts +0 -559
- package/src/__tests__/extension-api.test.ts +0 -579
- package/src/__tests__/fusion-artifacts.test.ts +0 -1039
- package/src/__tests__/fusion-budget.test.ts +0 -1356
- package/src/__tests__/fusion-claude-cache.test.ts +0 -320
- package/src/__tests__/fusion-config.test.ts +0 -335
- package/src/__tests__/fusion-context-prompts.test.ts +0 -670
- package/src/__tests__/fusion-evaluation.test.ts +0 -315
- package/src/__tests__/fusion-extraction-equivalence.test.ts +0 -58
- package/src/__tests__/fusion-golden-bytes.test.ts +0 -35
- package/src/__tests__/fusion-high-cardinality.test.ts +0 -192
- package/src/__tests__/fusion-model-selector.test.ts +0 -205
- package/src/__tests__/fusion-orchestrator.test.ts +0 -1194
- package/src/__tests__/fusion-rpc.test.ts +0 -369
- package/src/__tests__/fusion-sdk.test.ts +0 -1226
- package/src/__tests__/fusion-v5-core.test.ts +0 -219
- package/src/__tests__/fusion-validate-orchestrator.test.ts +0 -240
- package/src/__tests__/fusion-web-fetch.test.ts +0 -485
- package/src/__tests__/fusion-workflows.test.ts +0 -59
- package/src/__tests__/helpers/delegate-deterministic-seed.ts +0 -109
- package/src/__tests__/helpers/delegate-seed-subprocess.ts +0 -10
- package/src/__tests__/helpers/fusion-canonical-subprocess.ts +0 -21
- package/src/__tests__/helpers/fusion-canonical.ts +0 -140
- package/src/__tests__/helpers/fusion-fake-pi.ts +0 -279
- package/src/__tests__/helpers/fusion-golden-corpus.ts +0 -500
- package/src/__tests__/helpers/fusion-high-cardinality.ts +0 -140
- package/src/__tests__/helpers/normalize.ts +0 -22
- package/src/__tests__/helpers/pi-hook-contract-evidence.json +0 -18
- package/src/__tests__/pi-launch.test.ts +0 -202
- package/src/__tests__/registry.test.ts +0 -1580
- package/src/__tests__/scripted-provider/delegate-ambient-provider.test.ts +0 -130
- package/src/__tests__/scripted-provider/delegate-child-guard.test.ts +0 -631
- package/src/__tests__/scripted-provider/delegate-guard-provider.ts +0 -403
- package/src/__tests__/scripted-provider/follow-up.test.ts +0 -448
- package/src/__tests__/scripted-provider/fusion-output-recovery.test.ts +0 -132
- package/src/__tests__/scripted-provider/fusion-reason.test.ts +0 -310
- package/src/__tests__/scripted-provider/fusion-runtime-guard.test.ts +0 -163
- package/src/__tests__/scripted-provider/hook-contract-provider.ts +0 -179
- package/src/__tests__/scripted-provider/hook-probe-a.ts +0 -3
- package/src/__tests__/scripted-provider/hook-probe-b.ts +0 -3
- package/src/__tests__/scripted-provider/hook-probe-extension.ts +0 -126
- package/src/__tests__/scripted-provider/output-recovery-provider.ts +0 -153
- package/src/__tests__/scripted-provider/pi-hook-contract-evidence.json +0 -18
- package/src/__tests__/scripted-provider/pi-hook-contract.test.ts +0 -477
- package/src/__tests__/scripted-provider/runtime-guard-probe.ts +0 -28
- package/src/__tests__/scripted-provider/runtime-guard-provider.ts +0 -49
- package/src/__tests__/scripted-provider/scripted-provider-extension.ts +0 -408
- package/src/__tests__/task-manager.test.ts +0 -479
- package/src/__tests__/windows-taskkill.test.ts +0 -161
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
import { appendFileSync } from 'node:fs';
|
|
2
|
-
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
3
|
-
import {
|
|
4
|
-
createAssistantMessageEventStream,
|
|
5
|
-
type AssistantMessage,
|
|
6
|
-
type AssistantMessageEventStream,
|
|
7
|
-
type Context,
|
|
8
|
-
type Model,
|
|
9
|
-
type Api,
|
|
10
|
-
type Message,
|
|
11
|
-
type TextContent,
|
|
12
|
-
type ToolCall,
|
|
13
|
-
} from '@earendil-works/pi-ai';
|
|
14
|
-
|
|
15
|
-
const PROVIDER = 'pi-bg-scripted';
|
|
16
|
-
const MODEL_ID = 'scripted-model';
|
|
17
|
-
const API = 'pi-bg-scripted-api';
|
|
18
|
-
const DEFAULT_USAGE = {
|
|
19
|
-
input: 10,
|
|
20
|
-
output: 5,
|
|
21
|
-
cacheRead: 0,
|
|
22
|
-
cacheWrite: 0,
|
|
23
|
-
totalTokens: 15,
|
|
24
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type Scenario =
|
|
28
|
-
| 'bg-run-follow-up'
|
|
29
|
-
| 'notify-false'
|
|
30
|
-
| 'wake-false'
|
|
31
|
-
| 'failed-follow-up'
|
|
32
|
-
| 'display-only-bg'
|
|
33
|
-
| 'json-tool-telemetry'
|
|
34
|
-
| 'fusion-reason';
|
|
35
|
-
type ScriptedStopReason = 'stop' | 'length' | 'toolUse';
|
|
36
|
-
|
|
37
|
-
type JsonObject = Record<PropertyKey, unknown>;
|
|
38
|
-
|
|
39
|
-
interface ScriptedToolCall extends Omit<ToolCall, 'arguments'> {
|
|
40
|
-
arguments: JsonObject;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
interface ScriptedAssistantMessage extends Omit<AssistantMessage, 'content' | 'stopReason'> {
|
|
44
|
-
content: ScriptedBlock[];
|
|
45
|
-
stopReason: ScriptedStopReason;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type ScriptedBlock = TextContent | ScriptedToolCall;
|
|
49
|
-
|
|
50
|
-
function parseScenario(value: string | undefined): Scenario {
|
|
51
|
-
if (
|
|
52
|
-
value === 'bg-run-follow-up' ||
|
|
53
|
-
value === 'notify-false' ||
|
|
54
|
-
value === 'wake-false' ||
|
|
55
|
-
value === 'failed-follow-up' ||
|
|
56
|
-
value === 'display-only-bg' ||
|
|
57
|
-
value === 'json-tool-telemetry' ||
|
|
58
|
-
value === 'fusion-reason'
|
|
59
|
-
)
|
|
60
|
-
return value;
|
|
61
|
-
return 'bg-run-follow-up';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function record(event: JsonObject): void {
|
|
65
|
-
const path = process.env['UNIPI_BG_SCRIPTED_EVENTS'];
|
|
66
|
-
if (!path) return;
|
|
67
|
-
appendFileSync(path, `${JSON.stringify({ ...event, timestamp: Date.now() })}\n`, 'utf8');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function text(value: string): TextContent {
|
|
71
|
-
return { type: 'text', text: value };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function toolCall(name: string, args: JsonObject, id: string): ScriptedToolCall {
|
|
75
|
-
return { type: 'toolCall', id, name, arguments: args };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function assistant(
|
|
79
|
-
content: ScriptedBlock[],
|
|
80
|
-
stopReason: ScriptedStopReason,
|
|
81
|
-
): ScriptedAssistantMessage {
|
|
82
|
-
return {
|
|
83
|
-
role: 'assistant',
|
|
84
|
-
content,
|
|
85
|
-
api: API,
|
|
86
|
-
provider: PROVIDER,
|
|
87
|
-
model: MODEL_ID,
|
|
88
|
-
usage: DEFAULT_USAGE,
|
|
89
|
-
stopReason,
|
|
90
|
-
timestamp: Date.now(),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function shellNode(script: string): string {
|
|
95
|
-
return `node -e ${JSON.stringify(script)}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function messageText(message: Message): string {
|
|
99
|
-
return typeof message.content === 'string'
|
|
100
|
-
? message.content
|
|
101
|
-
: Array.isArray(message.content)
|
|
102
|
-
? message.content.map((part) => ('text' in part ? part.text : part.type)).join(' ')
|
|
103
|
-
: '';
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function summarizeMessage(message: Message): string {
|
|
107
|
-
const customType =
|
|
108
|
-
'customType' in message && typeof message.customType === 'string'
|
|
109
|
-
? message.customType
|
|
110
|
-
: undefined;
|
|
111
|
-
const toolName =
|
|
112
|
-
'toolName' in message && typeof message.toolName === 'string' ? message.toolName : undefined;
|
|
113
|
-
return [message.role, customType, toolName, messageText(message)]
|
|
114
|
-
.filter(Boolean)
|
|
115
|
-
.join(':')
|
|
116
|
-
.slice(0, 500);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
interface EventDrivenContractCheck {
|
|
120
|
-
readonly systemPrompt: boolean;
|
|
121
|
-
readonly toolDescriptions: boolean;
|
|
122
|
-
readonly launchReceipt: boolean;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function inspectEventDrivenContract(context: Context): EventDrivenContractCheck {
|
|
126
|
-
const systemPrompt = context.systemPrompt ?? '';
|
|
127
|
-
const toolDescription = (name: string): string =>
|
|
128
|
-
context.tools?.find((tool) => tool.name === name)?.description ?? '';
|
|
129
|
-
const bgRunResult = context.messages
|
|
130
|
-
.filter(
|
|
131
|
-
(message) =>
|
|
132
|
-
message.role === 'toolResult' && 'toolName' in message && message.toolName === 'bg_run',
|
|
133
|
-
)
|
|
134
|
-
.map(messageText)
|
|
135
|
-
.at(-1);
|
|
136
|
-
return {
|
|
137
|
-
systemPrompt:
|
|
138
|
-
systemPrompt.includes('Do not call sleep, bg_status, or bg_logs merely to wait') &&
|
|
139
|
-
systemPrompt.includes('automatically starts a follow-up agent turn') &&
|
|
140
|
-
systemPrompt.includes('A running result is not an instruction to poll again') &&
|
|
141
|
-
!systemPrompt.includes('After bg_run, use bg_status and bg_logs to inspect progress'),
|
|
142
|
-
toolDescriptions:
|
|
143
|
-
toolDescription('bg_run').includes('do not sleep or poll merely to wait') &&
|
|
144
|
-
toolDescription('bg_status').includes('not a waiting primitive') &&
|
|
145
|
-
toolDescription('bg_logs').includes('not a waiting primitive'),
|
|
146
|
-
launchReceipt:
|
|
147
|
-
bgRunResult?.includes('Terminal notification: enabled.') === true &&
|
|
148
|
-
bgRunResult.includes('Automatic follow-up turn: enabled.') &&
|
|
149
|
-
bgRunResult.includes('Next action: do not poll or sleep'),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function responseFor(
|
|
154
|
-
scenario: Scenario,
|
|
155
|
-
callCount: number,
|
|
156
|
-
contract: EventDrivenContractCheck,
|
|
157
|
-
context: Context,
|
|
158
|
-
): ScriptedAssistantMessage {
|
|
159
|
-
if (scenario === 'fusion-reason') {
|
|
160
|
-
if (callCount === 1) {
|
|
161
|
-
return assistant(
|
|
162
|
-
[toolCall('fusion_reason', { prompt: 'scripted fusion prompt' }, 'call-fusion-reason')],
|
|
163
|
-
'toolUse',
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
if (callCount === 2) {
|
|
167
|
-
return assistant(
|
|
168
|
-
[text('Fusion launched; waiting for its terminal notification without polling.')],
|
|
169
|
-
'stop',
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
if (callCount === 3) {
|
|
173
|
-
const transcript = context.messages.map(messageText).join('\n');
|
|
174
|
-
const match =
|
|
175
|
-
/<task-id>((?:reason|investigate|research|validate)-[0-9a-f]{32})<\/task-id>/u.exec(
|
|
176
|
-
transcript,
|
|
177
|
-
);
|
|
178
|
-
if (match?.[1] === undefined) {
|
|
179
|
-
return assistant([text('Fusion terminal notification did not contain a task id.')], 'stop');
|
|
180
|
-
}
|
|
181
|
-
return assistant(
|
|
182
|
-
[toolCall('bg_result', { taskId: match[1], delivery: 'inline' }, 'call-fusion-result')],
|
|
183
|
-
'toolUse',
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
return assistant([text('Parent observed verified Fusion result from bg_result.')], 'stop');
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (scenario === 'json-tool-telemetry') {
|
|
190
|
-
if (callCount === 1) {
|
|
191
|
-
return assistant(
|
|
192
|
-
[
|
|
193
|
-
toolCall('scripted_echo', { value: 'ok' }, 'call-scripted-ok'),
|
|
194
|
-
toolCall('scripted_echo', { value: 'fail', fail: true }, 'call-scripted-fail'),
|
|
195
|
-
],
|
|
196
|
-
'toolUse',
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
return assistant([text('JSON tool telemetry complete.')], 'stop');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (scenario === 'bg-run-follow-up') {
|
|
203
|
-
if (callCount === 1) {
|
|
204
|
-
return assistant(
|
|
205
|
-
[
|
|
206
|
-
toolCall(
|
|
207
|
-
'bg_run',
|
|
208
|
-
{
|
|
209
|
-
name: 'Scripted Wakeup',
|
|
210
|
-
command: shellNode(
|
|
211
|
-
"setTimeout(() => { console.log('scripted wakeup done'); }, 150);",
|
|
212
|
-
),
|
|
213
|
-
isAgent: false,
|
|
214
|
-
notifyOnCompletion: true,
|
|
215
|
-
},
|
|
216
|
-
'call-bg-run-wakeup',
|
|
217
|
-
),
|
|
218
|
-
],
|
|
219
|
-
'toolUse',
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
if (callCount === 2) {
|
|
223
|
-
if (!contract.systemPrompt || !contract.toolDescriptions || !contract.launchReceipt) {
|
|
224
|
-
return assistant([toolCall('bg_status', {}, 'call-bug-181-regressive-poll')], 'toolUse');
|
|
225
|
-
}
|
|
226
|
-
return assistant(
|
|
227
|
-
[text('Initial bg_run tool turn yielded without polling for the terminal event.')],
|
|
228
|
-
'stop',
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
return assistant(
|
|
232
|
-
[text('Follow-up turn observed background-task-notification for Scripted Wakeup.')],
|
|
233
|
-
'stop',
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (scenario === 'notify-false') {
|
|
238
|
-
if (callCount === 1) {
|
|
239
|
-
return assistant(
|
|
240
|
-
[
|
|
241
|
-
toolCall(
|
|
242
|
-
'bg_run',
|
|
243
|
-
{
|
|
244
|
-
name: 'No Notify Scripted',
|
|
245
|
-
command: shellNode("setTimeout(() => { console.log('quiet done'); }, 80);"),
|
|
246
|
-
isAgent: false,
|
|
247
|
-
notifyOnCompletion: false,
|
|
248
|
-
triggerOnCompletion: true,
|
|
249
|
-
},
|
|
250
|
-
'call-bg-run-no-notify',
|
|
251
|
-
),
|
|
252
|
-
],
|
|
253
|
-
'toolUse',
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
return assistant([text('No-notify initial turn finished.')], 'stop');
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (scenario === 'wake-false') {
|
|
260
|
-
if (callCount === 1) {
|
|
261
|
-
return assistant(
|
|
262
|
-
[
|
|
263
|
-
toolCall(
|
|
264
|
-
'bg_run',
|
|
265
|
-
{
|
|
266
|
-
name: 'No Wake Scripted',
|
|
267
|
-
command: shellNode("setTimeout(() => { console.log('notify only done'); }, 80);"),
|
|
268
|
-
isAgent: false,
|
|
269
|
-
notifyOnCompletion: true,
|
|
270
|
-
triggerOnCompletion: false,
|
|
271
|
-
},
|
|
272
|
-
'call-bg-run-no-wake',
|
|
273
|
-
),
|
|
274
|
-
],
|
|
275
|
-
'toolUse',
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
return assistant([text('Notification-only initial turn finished.')], 'stop');
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (scenario === 'failed-follow-up') {
|
|
282
|
-
if (callCount === 1) {
|
|
283
|
-
return assistant(
|
|
284
|
-
[
|
|
285
|
-
toolCall(
|
|
286
|
-
'bg_run',
|
|
287
|
-
{
|
|
288
|
-
name: 'Failing Scripted',
|
|
289
|
-
command: shellNode(
|
|
290
|
-
"setTimeout(() => { console.error('scripted failure'); process.exit(7); }, 80);",
|
|
291
|
-
),
|
|
292
|
-
isAgent: false,
|
|
293
|
-
notifyOnCompletion: true,
|
|
294
|
-
},
|
|
295
|
-
'call-bg-run-failed',
|
|
296
|
-
),
|
|
297
|
-
],
|
|
298
|
-
'toolUse',
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
if (callCount === 2) return assistant([text('Failing task initial turn finished.')], 'stop');
|
|
302
|
-
return assistant(
|
|
303
|
-
[text('Follow-up turn observed failed background task notification.')],
|
|
304
|
-
'stop',
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return assistant([text(`Display-only scenario provider call ${String(callCount)}.`)], 'stop');
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function pushMessage(stream: AssistantMessageEventStream, message: ScriptedAssistantMessage): void {
|
|
312
|
-
const partial: AssistantMessage = { ...message, content: [] };
|
|
313
|
-
stream.push({ type: 'start', partial: { ...partial } });
|
|
314
|
-
message.content.forEach((block, contentIndex) => {
|
|
315
|
-
if (block.type === 'text') {
|
|
316
|
-
const partialText: TextContent = { type: 'text', text: '' };
|
|
317
|
-
partial.content = [...partial.content, partialText];
|
|
318
|
-
stream.push({ type: 'text_start', contentIndex, partial: { ...partial } });
|
|
319
|
-
partialText.text = block.text;
|
|
320
|
-
stream.push({ type: 'text_delta', contentIndex, delta: block.text, partial: { ...partial } });
|
|
321
|
-
stream.push({ type: 'text_end', contentIndex, content: block.text, partial: { ...partial } });
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const partialToolCall: ToolCall = {
|
|
326
|
-
type: 'toolCall',
|
|
327
|
-
id: block.id,
|
|
328
|
-
name: block.name,
|
|
329
|
-
arguments: {},
|
|
330
|
-
};
|
|
331
|
-
partial.content = [...partial.content, partialToolCall];
|
|
332
|
-
stream.push({ type: 'toolcall_start', contentIndex, partial: { ...partial } });
|
|
333
|
-
const json = JSON.stringify(block.arguments);
|
|
334
|
-
stream.push({ type: 'toolcall_delta', contentIndex, delta: json, partial: { ...partial } });
|
|
335
|
-
partialToolCall.arguments = block.arguments;
|
|
336
|
-
stream.push({ type: 'toolcall_end', contentIndex, toolCall: block, partial: { ...partial } });
|
|
337
|
-
});
|
|
338
|
-
stream.push({ type: 'done', reason: message.stopReason, message });
|
|
339
|
-
stream.end(message);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
export default function scriptedProviderExtension(pi: ExtensionAPI): void {
|
|
343
|
-
let callCount = 0;
|
|
344
|
-
const scenario = parseScenario(process.env['UNIPI_BG_SCRIPTED_SCENARIO']);
|
|
345
|
-
|
|
346
|
-
const ScriptedEchoParams = {
|
|
347
|
-
type: 'object',
|
|
348
|
-
properties: {
|
|
349
|
-
value: { type: 'string' },
|
|
350
|
-
fail: { type: 'boolean' },
|
|
351
|
-
},
|
|
352
|
-
additionalProperties: false,
|
|
353
|
-
} as const;
|
|
354
|
-
pi.registerTool<typeof ScriptedEchoParams, { value: string }>({
|
|
355
|
-
name: 'scripted_echo',
|
|
356
|
-
label: 'Scripted Echo',
|
|
357
|
-
description: 'Test-only deterministic scripted provider tool',
|
|
358
|
-
parameters: ScriptedEchoParams,
|
|
359
|
-
execute(_toolCallId, input) {
|
|
360
|
-
if (input.fail) return Promise.reject(new Error('scripted echo failed intentionally'));
|
|
361
|
-
return Promise.resolve({
|
|
362
|
-
content: [{ type: 'text' as const, text: input.value ?? 'ok' }],
|
|
363
|
-
details: { value: input.value ?? 'ok' },
|
|
364
|
-
});
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
pi.registerProvider(PROVIDER, {
|
|
369
|
-
name: 'Pi Background Tasks Scripted Provider',
|
|
370
|
-
baseUrl: 'http://localhost:0',
|
|
371
|
-
apiKey: 'UNIPI_BG_SCRIPTED_API_KEY',
|
|
372
|
-
api: API,
|
|
373
|
-
models: [
|
|
374
|
-
{
|
|
375
|
-
id: MODEL_ID,
|
|
376
|
-
name: 'Scripted Model',
|
|
377
|
-
reasoning: false,
|
|
378
|
-
input: ['text'],
|
|
379
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
380
|
-
contextWindow: 272_000,
|
|
381
|
-
maxTokens: 4096,
|
|
382
|
-
},
|
|
383
|
-
],
|
|
384
|
-
streamSimple(_model: Model<Api>, context: Context): AssistantMessageEventStream {
|
|
385
|
-
callCount += 1;
|
|
386
|
-
const eventDrivenContract = inspectEventDrivenContract(context);
|
|
387
|
-
record({
|
|
388
|
-
type: 'provider_call',
|
|
389
|
-
scenario,
|
|
390
|
-
callCount,
|
|
391
|
-
eventDrivenContract,
|
|
392
|
-
roles: context.messages.map((message) => message.role),
|
|
393
|
-
customTypes: context.messages.flatMap((message) =>
|
|
394
|
-
'customType' in message && typeof message.customType === 'string'
|
|
395
|
-
? [message.customType]
|
|
396
|
-
: [],
|
|
397
|
-
),
|
|
398
|
-
lastRole: context.messages.at(-1)?.role,
|
|
399
|
-
summaries: context.messages.map(summarizeMessage),
|
|
400
|
-
});
|
|
401
|
-
const stream = createAssistantMessageEventStream();
|
|
402
|
-
queueMicrotask(() => {
|
|
403
|
-
pushMessage(stream, responseFor(scenario, callCount, eventDrivenContract, context));
|
|
404
|
-
});
|
|
405
|
-
return stream;
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
}
|