@ai-sdk/harness 1.0.101 → 1.0.102
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 +19 -0
- package/dist/agent/index.d.ts +65 -4
- package/dist/agent/index.js +493 -441
- package/dist/agent/index.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/utils/index.d.ts +17 -3
- package/dist/utils/index.js +321 -18
- package/dist/utils/index.js.map +1 -1
- package/package.json +3 -3
- package/src/agent/harness-agent-session.ts +5 -0
- package/src/agent/harness-agent-settings.ts +82 -3
- package/src/agent/harness-agent.ts +67 -0
- package/src/agent/internal/harness-stream-text-result.ts +33 -13
- package/src/agent/internal/run-prompt.ts +209 -87
- package/src/agent/internal/turn-telemetry.ts +293 -444
- package/src/utils/index.ts +5 -0
- package/src/utils/write-instructions.ts +373 -0
- package/src/utils/write-skills.ts +59 -2
- package/src/v1/harness-v1-session.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.102",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@ai-sdk/provider": "4.0.10",
|
|
48
48
|
"@ai-sdk/provider-utils": "5.0.36",
|
|
49
|
-
"ai": "7.0.
|
|
49
|
+
"ai": "7.0.93"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"ws": "^8.21.0",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@ai-sdk/otel": "1.0.
|
|
61
|
+
"@ai-sdk/otel": "1.0.93",
|
|
62
62
|
"@opentelemetry/sdk-trace-base": "2.7.1",
|
|
63
63
|
"@types/node": "22.19.19",
|
|
64
64
|
"@types/ws": "^8.5.13",
|
|
@@ -34,6 +34,7 @@ import type {
|
|
|
34
34
|
import { validateLifecycleStateData } from './internal/lifecycle-state-validation';
|
|
35
35
|
import { runPrompt } from './internal/run-prompt';
|
|
36
36
|
import { getRestrictedSandboxSession } from '../utils/get-restricted-sandbox-session';
|
|
37
|
+
import type { HarnessAgentLifecycleCallbacks } from './internal/turn-telemetry';
|
|
37
38
|
|
|
38
39
|
type HarnessAgentTurnResult<
|
|
39
40
|
TOOLS extends ToolSet,
|
|
@@ -207,6 +208,7 @@ export class HarnessAgentSession {
|
|
|
207
208
|
responseFormat: HarnessV1ResponseFormat | undefined;
|
|
208
209
|
output: OUTPUT | undefined;
|
|
209
210
|
telemetry: TelemetryOptions | undefined;
|
|
211
|
+
callbacks: HarnessAgentLifecycleCallbacks<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
210
212
|
stopConditions: ReadonlyArray<StopCondition<TOOLS, RUNTIME_CONTEXT>>;
|
|
211
213
|
}): HarnessAgentTurnResult<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
|
|
212
214
|
const session = this.requireReusableSession();
|
|
@@ -246,6 +248,7 @@ export class HarnessAgentSession {
|
|
|
246
248
|
responseFormat: options.responseFormat,
|
|
247
249
|
output: options.output,
|
|
248
250
|
telemetry: options.telemetry,
|
|
251
|
+
callbacks: options.callbacks,
|
|
249
252
|
stopConditions: options.stopConditions,
|
|
250
253
|
toolApproval: this.toolApproval,
|
|
251
254
|
pendingToolApprovals: this.getPendingToolApprovals(),
|
|
@@ -305,6 +308,7 @@ export class HarnessAgentSession {
|
|
|
305
308
|
responseFormat: HarnessV1ResponseFormat | undefined;
|
|
306
309
|
output: OUTPUT | undefined;
|
|
307
310
|
telemetry: TelemetryOptions | undefined;
|
|
311
|
+
callbacks: HarnessAgentLifecycleCallbacks<TOOLS, RUNTIME_CONTEXT, OUTPUT>;
|
|
308
312
|
stopConditions: ReadonlyArray<StopCondition<TOOLS, RUNTIME_CONTEXT>>;
|
|
309
313
|
toolApprovalContinuations?: readonly ToolApprovalResponse[] | undefined;
|
|
310
314
|
toolResultContinuations?: readonly ToolResultPart[] | undefined;
|
|
@@ -341,6 +345,7 @@ export class HarnessAgentSession {
|
|
|
341
345
|
responseFormat: options.responseFormat,
|
|
342
346
|
output: options.output,
|
|
343
347
|
telemetry: options.telemetry,
|
|
348
|
+
callbacks: options.callbacks,
|
|
344
349
|
stopConditions: options.stopConditions,
|
|
345
350
|
toolApproval: this.toolApproval,
|
|
346
351
|
pendingToolApprovals: this.getPendingToolApprovals(),
|
|
@@ -19,6 +19,14 @@ import type {
|
|
|
19
19
|
import type {
|
|
20
20
|
ActiveTools,
|
|
21
21
|
AgentCallParameters,
|
|
22
|
+
GenerateTextOnEndCallback,
|
|
23
|
+
GenerateTextOnStartCallback,
|
|
24
|
+
GenerateTextOnStepEndCallback,
|
|
25
|
+
GenerateTextOnStepStartCallback,
|
|
26
|
+
OnLanguageModelCallEndCallback,
|
|
27
|
+
OnLanguageModelCallStartCallback,
|
|
28
|
+
OnToolExecutionEndCallback,
|
|
29
|
+
OnToolExecutionStartCallback,
|
|
22
30
|
OutputInterface as Output,
|
|
23
31
|
Prompt,
|
|
24
32
|
StopCondition,
|
|
@@ -78,10 +86,12 @@ type HarnessTools<TOOLS extends ToolSet> = ActiveTools<NoInfer<TOOLS>>;
|
|
|
78
86
|
/**
|
|
79
87
|
* Construction-time settings for a `HarnessAgent`.
|
|
80
88
|
*
|
|
81
|
-
* Prompt, abortSignal,
|
|
89
|
+
* Prompt, abortSignal, and custom call options belong on the
|
|
82
90
|
* `AgentCallParameters` / `AgentStreamParameters` passed to `generate` /
|
|
83
|
-
* `stream`.
|
|
84
|
-
*
|
|
91
|
+
* `stream`. Lifecycle callbacks can be configured here for every call, while
|
|
92
|
+
* the callbacks supported by `AgentCallParameters` can also be added per call.
|
|
93
|
+
* `prepareCall` can derive turn-scoped model, skills, instructions, and tools
|
|
94
|
+
* from custom call options.
|
|
85
95
|
*/
|
|
86
96
|
type HarnessAgentToolFilteringSettings<TOOLS extends ToolSet> =
|
|
87
97
|
| {
|
|
@@ -153,6 +163,14 @@ export type HarnessAgentSettings<
|
|
|
153
163
|
*/
|
|
154
164
|
readonly instructions?: string;
|
|
155
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Additional HTTP headers to be sent with every model request.
|
|
168
|
+
*
|
|
169
|
+
* `authorization`, `x-api-key`, `user-agent`, and `x-client-app` are
|
|
170
|
+
* managed by the harness and are not allowed.
|
|
171
|
+
*/
|
|
172
|
+
readonly headers?: Record<string, string | undefined>;
|
|
173
|
+
|
|
156
174
|
/**
|
|
157
175
|
* Schema for validating the custom options passed to each agent call.
|
|
158
176
|
*/
|
|
@@ -242,6 +260,67 @@ export type HarnessAgentSettings<
|
|
|
242
260
|
>
|
|
243
261
|
>;
|
|
244
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Called when an agent call begins, before any model steps.
|
|
265
|
+
*/
|
|
266
|
+
readonly onStart?: GenerateTextOnStartCallback<
|
|
267
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>,
|
|
268
|
+
RUNTIME_CONTEXT,
|
|
269
|
+
NoInfer<OUTPUT>
|
|
270
|
+
>;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Called when a model step begins.
|
|
274
|
+
*/
|
|
275
|
+
readonly onStepStart?: GenerateTextOnStepStartCallback<
|
|
276
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>,
|
|
277
|
+
NoInfer<RUNTIME_CONTEXT>,
|
|
278
|
+
NoInfer<OUTPUT>
|
|
279
|
+
>;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Called immediately before the harness begins emitting a model response.
|
|
283
|
+
*/
|
|
284
|
+
readonly onLanguageModelCallStart?: OnLanguageModelCallStartCallback;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Called after a model response is complete and before its tool execution
|
|
288
|
+
* lifecycle callbacks are delivered.
|
|
289
|
+
*/
|
|
290
|
+
readonly onLanguageModelCallEnd?: OnLanguageModelCallEndCallback<
|
|
291
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>
|
|
292
|
+
>;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Called before each harness or host tool execution is reported.
|
|
296
|
+
*/
|
|
297
|
+
readonly onToolExecutionStart?: OnToolExecutionStartCallback<
|
|
298
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>
|
|
299
|
+
>;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Called after each harness or host tool execution is reported.
|
|
303
|
+
*/
|
|
304
|
+
readonly onToolExecutionEnd?: OnToolExecutionEndCallback<
|
|
305
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>
|
|
306
|
+
>;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Called after each completed model step.
|
|
310
|
+
*/
|
|
311
|
+
readonly onStepEnd?: GenerateTextOnStepEndCallback<
|
|
312
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>,
|
|
313
|
+
NoInfer<RUNTIME_CONTEXT>
|
|
314
|
+
>;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Called when an agent call completes successfully.
|
|
318
|
+
*/
|
|
319
|
+
readonly onEnd?: GenerateTextOnEndCallback<
|
|
320
|
+
NoInfer<HarnessAllTools<THarness, TUserTools>>,
|
|
321
|
+
NoInfer<RUNTIME_CONTEXT>
|
|
322
|
+
>;
|
|
323
|
+
|
|
245
324
|
/**
|
|
246
325
|
* Built-in tool permission mode. Defaults to `'allow-all'`, preserving the
|
|
247
326
|
* existing bypass-permissions behavior unless users opt in.
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
asArray,
|
|
11
11
|
asSchema,
|
|
12
12
|
generateId,
|
|
13
|
+
normalizeHeaders,
|
|
13
14
|
validateTypes,
|
|
14
15
|
type Context,
|
|
15
16
|
type Experimental_SandboxSession as SandboxSession,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
type ToolResultPart,
|
|
19
20
|
type ToolSet,
|
|
20
21
|
} from '@ai-sdk/provider-utils';
|
|
22
|
+
import { mergeCallbacks } from 'ai/internal';
|
|
21
23
|
import type {
|
|
22
24
|
Agent,
|
|
23
25
|
AgentCallParameters,
|
|
@@ -65,6 +67,7 @@ import {
|
|
|
65
67
|
import { resolveHarnessAgentToolFiltering } from './internal/tool-filtering';
|
|
66
68
|
import { resolveSandboxDefaultWorkingDirectory } from '../utils/resolve-sandbox-default-working-directory';
|
|
67
69
|
import { getRestrictedSandboxSession } from '../utils/get-restricted-sandbox-session';
|
|
70
|
+
import type { HarnessAgentLifecycleCallbacks } from './internal/turn-telemetry';
|
|
68
71
|
|
|
69
72
|
export type { HarnessAllTools } from './harness-agent-tool-types';
|
|
70
73
|
|
|
@@ -203,6 +206,7 @@ export class HarnessAgent<
|
|
|
203
206
|
| HarnessV1BuiltinToolFiltering
|
|
204
207
|
| undefined;
|
|
205
208
|
private readonly permissionMode: HarnessAgentPermissionMode;
|
|
209
|
+
private readonly headers: Readonly<Record<string, string>> | undefined;
|
|
206
210
|
|
|
207
211
|
constructor(
|
|
208
212
|
settings: HarnessAgentSettings<
|
|
@@ -219,6 +223,22 @@ export class HarnessAgent<
|
|
|
219
223
|
this.stopConditions =
|
|
220
224
|
settings.stopWhen == null ? [] : asArray(settings.stopWhen);
|
|
221
225
|
this.sandboxConfig = sandboxConfig;
|
|
226
|
+
const forbiddenHeaders = new Set([
|
|
227
|
+
'authorization',
|
|
228
|
+
'x-api-key',
|
|
229
|
+
'user-agent',
|
|
230
|
+
'x-client-app',
|
|
231
|
+
]);
|
|
232
|
+
const forbiddenHeader = Object.keys(settings.headers ?? {})
|
|
233
|
+
.map(name => name.toLowerCase())
|
|
234
|
+
.find(name => forbiddenHeaders.has(name));
|
|
235
|
+
if (forbiddenHeader != null) {
|
|
236
|
+
throw new Error(
|
|
237
|
+
`HarnessAgent: \`headers\` must not include the managed header \`${forbiddenHeader}\`.`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const headers = normalizeHeaders(settings.headers);
|
|
241
|
+
this.headers = Object.keys(headers).length === 0 ? undefined : headers;
|
|
222
242
|
this.id = settings.id;
|
|
223
243
|
const userTools = settings.tools ?? ({} as TUserTools);
|
|
224
244
|
assertNoReservedQuestionTool({
|
|
@@ -502,6 +522,7 @@ export class HarnessAgent<
|
|
|
502
522
|
try {
|
|
503
523
|
const baseStartOptions = {
|
|
504
524
|
sessionId,
|
|
525
|
+
...(this.headers == null ? {} : { headers: this.headers }),
|
|
505
526
|
resumeFrom: validatedResumeFrom,
|
|
506
527
|
continueFrom: effectiveContinueFrom,
|
|
507
528
|
permissionMode: this.permissionMode,
|
|
@@ -708,6 +729,7 @@ export class HarnessAgent<
|
|
|
708
729
|
runtimeContext: input.runtimeContext,
|
|
709
730
|
abortSignal: input.options.abortSignal,
|
|
710
731
|
responseFormat,
|
|
732
|
+
callbacks: this._resolveLifecycleCallbacks(input.options),
|
|
711
733
|
}),
|
|
712
734
|
prompt: turnInput.prompt,
|
|
713
735
|
});
|
|
@@ -734,6 +756,7 @@ export class HarnessAgent<
|
|
|
734
756
|
runtimeContext: input.runtimeContext,
|
|
735
757
|
abortSignal: input.abortSignal,
|
|
736
758
|
responseFormat,
|
|
759
|
+
callbacks: this._resolveLifecycleCallbacks(),
|
|
737
760
|
}),
|
|
738
761
|
toolApprovalContinuations: turnInput.toolApprovalContinuations,
|
|
739
762
|
toolResultContinuations: turnInput.toolResultContinuations,
|
|
@@ -745,6 +768,11 @@ export class HarnessAgent<
|
|
|
745
768
|
runtimeContext: RUNTIME_CONTEXT;
|
|
746
769
|
abortSignal: AbortSignal | undefined;
|
|
747
770
|
responseFormat: HarnessV1ResponseFormat | undefined;
|
|
771
|
+
callbacks: HarnessAgentLifecycleCallbacks<
|
|
772
|
+
HarnessAllTools<THarness, TUserTools>,
|
|
773
|
+
RUNTIME_CONTEXT,
|
|
774
|
+
OUTPUT
|
|
775
|
+
>;
|
|
748
776
|
}) {
|
|
749
777
|
return {
|
|
750
778
|
model: input.turnSettings.model,
|
|
@@ -759,10 +787,49 @@ export class HarnessAgent<
|
|
|
759
787
|
responseFormat: input.responseFormat,
|
|
760
788
|
output: this.settings.output,
|
|
761
789
|
telemetry: this.settings.telemetry,
|
|
790
|
+
callbacks: input.callbacks,
|
|
762
791
|
stopConditions: this.stopConditions,
|
|
763
792
|
};
|
|
764
793
|
}
|
|
765
794
|
|
|
795
|
+
private _resolveLifecycleCallbacks(
|
|
796
|
+
call?: AgentCallParameters<
|
|
797
|
+
CALL_OPTIONS,
|
|
798
|
+
HarnessAllTools<THarness, TUserTools>,
|
|
799
|
+
RUNTIME_CONTEXT
|
|
800
|
+
>,
|
|
801
|
+
): HarnessAgentLifecycleCallbacks<
|
|
802
|
+
HarnessAllTools<THarness, TUserTools>,
|
|
803
|
+
RUNTIME_CONTEXT,
|
|
804
|
+
OUTPUT
|
|
805
|
+
> {
|
|
806
|
+
return {
|
|
807
|
+
onStart: mergeCallbacks(
|
|
808
|
+
this.settings.onStart,
|
|
809
|
+
call?.onStart ?? call?.experimental_onStart,
|
|
810
|
+
),
|
|
811
|
+
onStepStart: mergeCallbacks(
|
|
812
|
+
this.settings.onStepStart,
|
|
813
|
+
call?.onStepStart ?? call?.experimental_onStepStart,
|
|
814
|
+
),
|
|
815
|
+
onLanguageModelCallStart: this.settings.onLanguageModelCallStart,
|
|
816
|
+
onLanguageModelCallEnd: this.settings.onLanguageModelCallEnd,
|
|
817
|
+
onToolExecutionStart: mergeCallbacks(
|
|
818
|
+
this.settings.onToolExecutionStart,
|
|
819
|
+
call?.onToolExecutionStart ?? call?.experimental_onToolCallStart,
|
|
820
|
+
),
|
|
821
|
+
onToolExecutionEnd: mergeCallbacks(
|
|
822
|
+
this.settings.onToolExecutionEnd,
|
|
823
|
+
call?.onToolExecutionEnd ?? call?.experimental_onToolCallFinish,
|
|
824
|
+
),
|
|
825
|
+
onStepEnd: mergeCallbacks(
|
|
826
|
+
this.settings.onStepEnd,
|
|
827
|
+
call?.onStepEnd ?? call?.onStepFinish,
|
|
828
|
+
),
|
|
829
|
+
onEnd: mergeCallbacks(this.settings.onEnd, call?.onEnd ?? call?.onFinish),
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
|
|
766
833
|
private _resolveContinueTurnInput(options: {
|
|
767
834
|
prompt?: string | ModelMessage[];
|
|
768
835
|
messages?: ModelMessage[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DelayedPromise,
|
|
3
|
-
|
|
3
|
+
type InferToolSetContext,
|
|
4
4
|
type AssistantModelMessage,
|
|
5
5
|
type Context,
|
|
6
6
|
type ToolModelMessage,
|
|
@@ -154,9 +154,10 @@ export class HarnessStreamTextResult<
|
|
|
154
154
|
|
|
155
155
|
private readonly tools: TOOLS;
|
|
156
156
|
private readonly runtimeContext: RUNTIME_CONTEXT;
|
|
157
|
-
private readonly toolsContext:
|
|
157
|
+
private readonly toolsContext: InferToolSetContext<TOOLS>;
|
|
158
158
|
private readonly providerName: string;
|
|
159
|
-
private readonly
|
|
159
|
+
private readonly callId: string;
|
|
160
|
+
private modelId: string;
|
|
160
161
|
private readonly outputSpecification: OUTPUT | undefined;
|
|
161
162
|
|
|
162
163
|
// Accumulators that span the whole turn.
|
|
@@ -170,16 +171,18 @@ export class HarnessStreamTextResult<
|
|
|
170
171
|
constructor(options: {
|
|
171
172
|
tools: TOOLS;
|
|
172
173
|
runtimeContext: RUNTIME_CONTEXT;
|
|
173
|
-
toolsContext:
|
|
174
|
+
toolsContext: InferToolSetContext<TOOLS>;
|
|
174
175
|
harnessId: string;
|
|
175
|
-
|
|
176
|
+
callId: string;
|
|
177
|
+
modelId: string;
|
|
176
178
|
output: OUTPUT | undefined;
|
|
177
179
|
}) {
|
|
178
180
|
this.tools = options.tools;
|
|
179
181
|
this.runtimeContext = options.runtimeContext;
|
|
180
182
|
this.toolsContext = options.toolsContext;
|
|
181
183
|
this.providerName = `harness:${options.harnessId}`;
|
|
182
|
-
this.
|
|
184
|
+
this.callId = options.callId;
|
|
185
|
+
this.modelId = options.modelId;
|
|
183
186
|
this.outputSpecification = options.output;
|
|
184
187
|
|
|
185
188
|
let controllerRef!: ReadableStreamDefaultController<TextStreamPart<TOOLS>>;
|
|
@@ -224,6 +227,12 @@ export class HarnessStreamTextResult<
|
|
|
224
227
|
this.appendToCurrentStepContent(part);
|
|
225
228
|
}
|
|
226
229
|
|
|
230
|
+
setModelId(modelId: string): void {
|
|
231
|
+
if (this.stepsBuffer.length === 0) {
|
|
232
|
+
this.modelId = modelId;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
227
236
|
/**
|
|
228
237
|
* Push a continuation input into the consumer stream without attributing it
|
|
229
238
|
* to the next model step. Approval responses and client tool results arrive
|
|
@@ -262,7 +271,7 @@ export class HarnessStreamTextResult<
|
|
|
262
271
|
const rawFinishReason = input.finishReason.raw;
|
|
263
272
|
|
|
264
273
|
const step = new DefaultStepResult<TOOLS, RUNTIME_CONTEXT>({
|
|
265
|
-
callId:
|
|
274
|
+
callId: this.callId,
|
|
266
275
|
stepNumber: this.stepNumber,
|
|
267
276
|
provider: this.providerName,
|
|
268
277
|
modelId: this.modelId,
|
|
@@ -276,7 +285,7 @@ export class HarnessStreamTextResult<
|
|
|
276
285
|
warnings: input.warnings.length > 0 ? input.warnings : undefined,
|
|
277
286
|
request: {},
|
|
278
287
|
response: {
|
|
279
|
-
id:
|
|
288
|
+
id: `${this.callId}-${this.stepNumber}`,
|
|
280
289
|
timestamp: new Date(),
|
|
281
290
|
modelId: this.modelId,
|
|
282
291
|
messages: [],
|
|
@@ -363,7 +372,7 @@ export class HarnessStreamTextResult<
|
|
|
363
372
|
this.stepsBuffer.length > 0
|
|
364
373
|
? this.stepsBuffer[this.stepsBuffer.length - 1]!
|
|
365
374
|
: new DefaultStepResult<TOOLS, RUNTIME_CONTEXT>({
|
|
366
|
-
callId:
|
|
375
|
+
callId: this.callId,
|
|
367
376
|
stepNumber: 0,
|
|
368
377
|
provider: this.providerName,
|
|
369
378
|
modelId: this.modelId,
|
|
@@ -377,7 +386,7 @@ export class HarnessStreamTextResult<
|
|
|
377
386
|
warnings: undefined,
|
|
378
387
|
request: {},
|
|
379
388
|
response: {
|
|
380
|
-
id:
|
|
389
|
+
id: `${this.callId}-0`,
|
|
381
390
|
timestamp: new Date(),
|
|
382
391
|
modelId: this.modelId,
|
|
383
392
|
messages: [],
|
|
@@ -823,6 +832,19 @@ export class HarnessStreamTextResult<
|
|
|
823
832
|
}
|
|
824
833
|
return;
|
|
825
834
|
}
|
|
835
|
+
case 'reasoning-delta': {
|
|
836
|
+
const last =
|
|
837
|
+
this.currentStepContent[this.currentStepContent.length - 1];
|
|
838
|
+
if (last && last.type === 'reasoning') {
|
|
839
|
+
(last as { text: string }).text += part.text;
|
|
840
|
+
} else {
|
|
841
|
+
this.currentStepContent.push({
|
|
842
|
+
type: 'reasoning',
|
|
843
|
+
text: part.text,
|
|
844
|
+
} as ContentPart<TOOLS>);
|
|
845
|
+
}
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
826
848
|
case 'tool-call':
|
|
827
849
|
case 'tool-approval-request':
|
|
828
850
|
case 'tool-approval-response':
|
|
@@ -833,9 +855,7 @@ export class HarnessStreamTextResult<
|
|
|
833
855
|
} as ContentPart<TOOLS>);
|
|
834
856
|
return;
|
|
835
857
|
default:
|
|
836
|
-
//
|
|
837
|
-
// not directly stored as ContentParts. (Reasoning content parts
|
|
838
|
-
// would belong here; we omit them for v0.)
|
|
858
|
+
// Boundary, raw, error, and finish parts are not ContentParts.
|
|
839
859
|
return;
|
|
840
860
|
}
|
|
841
861
|
}
|