@ai-sdk/harness 1.0.128 → 1.0.130
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 +23 -0
- package/dist/agent/index.d.ts +18 -4
- package/dist/agent/index.js +22 -11
- package/dist/agent/index.js.map +1 -1
- package/package.json +5 -5
- package/src/agent/harness-agent-session.ts +9 -1
- package/src/agent/harness-agent-settings.ts +11 -4
- package/src/agent/harness-agent.ts +26 -9
- package/src/agent/internal/sandbox-bootstrap.ts +1 -1
- package/src/agent/internal/turn-telemetry.ts +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.130",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@ai-sdk/provider": "4.0.
|
|
48
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
49
|
-
"ai": "7.0.
|
|
47
|
+
"@ai-sdk/provider": "4.0.19",
|
|
48
|
+
"@ai-sdk/provider-utils": "5.0.50",
|
|
49
|
+
"ai": "7.0.120"
|
|
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.120",
|
|
62
62
|
"@opentelemetry/sdk-trace-base": "2.7.1",
|
|
63
63
|
"@types/node": "22.19.19",
|
|
64
64
|
"@types/ws": "^8.5.13",
|
|
@@ -67,6 +67,7 @@ type ActiveTurnSettings = {
|
|
|
67
67
|
readonly persisted: HarnessV1TurnSettings;
|
|
68
68
|
readonly tools: ToolSet;
|
|
69
69
|
readonly toolsContext: Record<string, Context | undefined>;
|
|
70
|
+
readonly runtimeContext: Context;
|
|
70
71
|
readonly activeTools: ToolSet;
|
|
71
72
|
readonly builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
72
73
|
};
|
|
@@ -124,6 +125,7 @@ export class HarnessAgentSession {
|
|
|
124
125
|
private readonly resumedToolsContext:
|
|
125
126
|
| Record<string, Context | undefined>
|
|
126
127
|
| undefined;
|
|
128
|
+
private readonly resumedRuntimeContext: Context | undefined;
|
|
127
129
|
|
|
128
130
|
/**
|
|
129
131
|
* Whether this session was created from `resumeFrom` or `continueFrom`.
|
|
@@ -143,6 +145,7 @@ export class HarnessAgentSession {
|
|
|
143
145
|
pendingToolResults?: readonly HarnessAgentPendingToolResult[];
|
|
144
146
|
turnSettings?: HarnessV1TurnSettings;
|
|
145
147
|
resumedToolsContext?: Record<string, Context | undefined>;
|
|
148
|
+
resumedRuntimeContext?: Context;
|
|
146
149
|
turnState?: HarnessAgentTurnState;
|
|
147
150
|
}) {
|
|
148
151
|
this.sessionId = options.sessionId;
|
|
@@ -160,6 +163,7 @@ export class HarnessAgentSession {
|
|
|
160
163
|
}
|
|
161
164
|
this.persistedTurnSettings = options.turnSettings;
|
|
162
165
|
this.resumedToolsContext = options.resumedToolsContext;
|
|
166
|
+
this.resumedRuntimeContext = options.resumedRuntimeContext;
|
|
163
167
|
this.turnState =
|
|
164
168
|
options.turnState ??
|
|
165
169
|
(this.pendingToolApprovals.size > 0
|
|
@@ -234,6 +238,7 @@ export class HarnessAgentSession {
|
|
|
234
238
|
persisted: this.persistedTurnSettings,
|
|
235
239
|
tools: options.tools,
|
|
236
240
|
toolsContext: options.toolsContext,
|
|
241
|
+
runtimeContext: options.runtimeContext,
|
|
237
242
|
activeTools: options.activeTools,
|
|
238
243
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
239
244
|
};
|
|
@@ -334,6 +339,7 @@ export class HarnessAgentSession {
|
|
|
334
339
|
instructions: options.instructions,
|
|
335
340
|
tools: options.tools,
|
|
336
341
|
toolsContext: options.toolsContext,
|
|
342
|
+
runtimeContext: options.runtimeContext,
|
|
337
343
|
activeTools: options.activeTools,
|
|
338
344
|
toolSpecs: options.toolSpecs,
|
|
339
345
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
@@ -355,7 +361,7 @@ export class HarnessAgentSession {
|
|
|
355
361
|
builtinToolFiltering: turnSettings.builtinToolFiltering,
|
|
356
362
|
sandboxSession: getRestrictedSandboxSession(sandboxSession),
|
|
357
363
|
sessionWorkDir: this.sessionWorkDir,
|
|
358
|
-
runtimeContext:
|
|
364
|
+
runtimeContext: turnSettings.runtimeContext as RUNTIME_CONTEXT,
|
|
359
365
|
abortSignal: options.abortSignal,
|
|
360
366
|
responseFormat: options.responseFormat,
|
|
361
367
|
output: options.output,
|
|
@@ -792,6 +798,7 @@ export class HarnessAgentSession {
|
|
|
792
798
|
instructions: string | undefined;
|
|
793
799
|
tools: ToolSet;
|
|
794
800
|
toolsContext: Record<string, Context | undefined>;
|
|
801
|
+
runtimeContext: Context;
|
|
795
802
|
activeTools: ToolSet;
|
|
796
803
|
toolSpecs: HarnessAgentToolSpec[];
|
|
797
804
|
builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
|
|
@@ -826,6 +833,7 @@ export class HarnessAgentSession {
|
|
|
826
833
|
persisted,
|
|
827
834
|
tools: options.tools,
|
|
828
835
|
toolsContext: this.resumedToolsContext ?? options.toolsContext,
|
|
836
|
+
runtimeContext: this.resumedRuntimeContext ?? options.runtimeContext,
|
|
829
837
|
activeTools,
|
|
830
838
|
builtinToolFiltering: options.builtinToolFiltering,
|
|
831
839
|
};
|
|
@@ -45,8 +45,9 @@ export type HarnessAgentToolApprovalConfiguration = Readonly<
|
|
|
45
45
|
export type HarnessAgentSandboxConfig = {
|
|
46
46
|
/**
|
|
47
47
|
* Optional fixed working directory for all sessions, relative to the
|
|
48
|
-
* sandbox's default working directory.
|
|
49
|
-
*
|
|
48
|
+
* sandbox's default working directory. Use `'.'` to use the default
|
|
49
|
+
* working directory itself. When omitted, sessions keep the existing
|
|
50
|
+
* `<harnessId>-<sessionId>` work directory.
|
|
50
51
|
*/
|
|
51
52
|
readonly workDir?: string;
|
|
52
53
|
|
|
@@ -159,6 +160,12 @@ export type HarnessAgentSettings<
|
|
|
159
160
|
*/
|
|
160
161
|
readonly toolsContext?: InferToolSetContext<TUserTools>;
|
|
161
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Runtime context passed to lifecycle callbacks and telemetry.
|
|
165
|
+
* `prepareCall` can replace it for each new turn.
|
|
166
|
+
*/
|
|
167
|
+
readonly runtimeContext?: RUNTIME_CONTEXT;
|
|
168
|
+
|
|
162
169
|
/**
|
|
163
170
|
* Skills made available to the underlying runtime. Each adapter decides how
|
|
164
171
|
* to surface skills. `prepareCall` can replace them between completed turns.
|
|
@@ -233,7 +240,7 @@ export type HarnessAgentSettings<
|
|
|
233
240
|
NoInfer<OUTPUT>,
|
|
234
241
|
CALL_OPTIONS
|
|
235
242
|
>,
|
|
236
|
-
'model' | 'skills' | 'instructions' | 'tools'
|
|
243
|
+
'model' | 'skills' | 'instructions' | 'tools' | 'runtimeContext'
|
|
237
244
|
> & {
|
|
238
245
|
toolsContext: InferToolSetContext<TUserTools>;
|
|
239
246
|
},
|
|
@@ -246,7 +253,7 @@ export type HarnessAgentSettings<
|
|
|
246
253
|
NoInfer<OUTPUT>,
|
|
247
254
|
CALL_OPTIONS
|
|
248
255
|
>,
|
|
249
|
-
'model' | 'skills' | 'instructions' | 'tools'
|
|
256
|
+
'model' | 'skills' | 'instructions' | 'tools' | 'runtimeContext'
|
|
250
257
|
> & {
|
|
251
258
|
toolsContext: InferToolSetContext<TUserTools>;
|
|
252
259
|
} & Omit<Prompt, 'system' | 'instructions' | 'allowSystemInMessages'>
|
|
@@ -114,8 +114,10 @@ type PreparedHarnessAgentTurnSettings<
|
|
|
114
114
|
type PreparedHarnessAgentPromptTurnInput<
|
|
115
115
|
THarness extends HarnessAgentAdapter<any>,
|
|
116
116
|
TUserTools extends ToolSet,
|
|
117
|
+
RUNTIME_CONTEXT extends Context,
|
|
117
118
|
> = PreparedHarnessAgentTurnSettings<THarness, TUserTools> & {
|
|
118
119
|
prompt: HarnessAgentPrompt;
|
|
120
|
+
runtimeContext: RUNTIME_CONTEXT;
|
|
119
121
|
};
|
|
120
122
|
|
|
121
123
|
type PreparedHarnessAgentContinueTurnInput<
|
|
@@ -340,6 +342,12 @@ export class HarnessAgent<
|
|
|
340
342
|
* non-serializable host objects.
|
|
341
343
|
*/
|
|
342
344
|
toolsContext?: ToolsContextSettings<TUserTools>['toolsContext'];
|
|
345
|
+
/**
|
|
346
|
+
* Rebinds host-only runtime context for an unfinished turn resumed with
|
|
347
|
+
* `continueFrom` (directly or through `resumeFrom`). Runtime context is
|
|
348
|
+
* not serialized into lifecycle state.
|
|
349
|
+
*/
|
|
350
|
+
runtimeContext?: RUNTIME_CONTEXT;
|
|
343
351
|
/**
|
|
344
352
|
* Existing sandbox session to run the harness in. When provided, the
|
|
345
353
|
* caller retains ownership of the sandbox lifecycle.
|
|
@@ -611,6 +619,7 @@ export class HarnessAgent<
|
|
|
611
619
|
pendingToolResults: effectiveContinueFrom?.pendingToolResults,
|
|
612
620
|
turnSettings: effectiveContinueFrom?.turnSettings,
|
|
613
621
|
resumedToolsContext: options?.toolsContext,
|
|
622
|
+
resumedRuntimeContext: options?.runtimeContext,
|
|
614
623
|
turnState:
|
|
615
624
|
effectiveContinueFrom == null
|
|
616
625
|
? 'idle'
|
|
@@ -646,10 +655,11 @@ export class HarnessAgent<
|
|
|
646
655
|
>
|
|
647
656
|
> {
|
|
648
657
|
const continueTurnInput = this._resolveContinueTurnInput(options);
|
|
649
|
-
const runtimeContext =
|
|
658
|
+
const runtimeContext =
|
|
659
|
+
this.settings.runtimeContext ?? ({} as RUNTIME_CONTEXT);
|
|
650
660
|
const { result, done } =
|
|
651
661
|
continueTurnInput == null
|
|
652
|
-
? await this._startPromptTurn({ options
|
|
662
|
+
? await this._startPromptTurn({ options })
|
|
653
663
|
: await this._startContinueTurn({
|
|
654
664
|
session: options.session,
|
|
655
665
|
turnInput: continueTurnInput,
|
|
@@ -675,10 +685,11 @@ export class HarnessAgent<
|
|
|
675
685
|
>
|
|
676
686
|
> {
|
|
677
687
|
const continueTurnInput = this._resolveContinueTurnInput(options);
|
|
678
|
-
const runtimeContext =
|
|
688
|
+
const runtimeContext =
|
|
689
|
+
this.settings.runtimeContext ?? ({} as RUNTIME_CONTEXT);
|
|
679
690
|
const { result, ready } =
|
|
680
691
|
continueTurnInput == null
|
|
681
|
-
? await this._startPromptTurn({ options
|
|
692
|
+
? await this._startPromptTurn({ options })
|
|
682
693
|
: await this._startContinueTurn({
|
|
683
694
|
session: options.session,
|
|
684
695
|
turnInput: continueTurnInput,
|
|
@@ -706,7 +717,8 @@ export class HarnessAgent<
|
|
|
706
717
|
OUTPUT
|
|
707
718
|
>
|
|
708
719
|
> {
|
|
709
|
-
const runtimeContext =
|
|
720
|
+
const runtimeContext =
|
|
721
|
+
this.settings.runtimeContext ?? ({} as RUNTIME_CONTEXT);
|
|
710
722
|
const { result, done } = await this._startContinueTurn({
|
|
711
723
|
session: options.session,
|
|
712
724
|
turnInput: {
|
|
@@ -740,7 +752,8 @@ export class HarnessAgent<
|
|
|
740
752
|
OUTPUT
|
|
741
753
|
>
|
|
742
754
|
> {
|
|
743
|
-
const runtimeContext =
|
|
755
|
+
const runtimeContext =
|
|
756
|
+
this.settings.runtimeContext ?? ({} as RUNTIME_CONTEXT);
|
|
744
757
|
const { result, ready } = await this._startContinueTurn({
|
|
745
758
|
session: options.session,
|
|
746
759
|
turnInput: {
|
|
@@ -777,7 +790,6 @@ export class HarnessAgent<
|
|
|
777
790
|
RUNTIME_CONTEXT
|
|
778
791
|
> &
|
|
779
792
|
HarnessAgentCallExtensions;
|
|
780
|
-
runtimeContext: RUNTIME_CONTEXT;
|
|
781
793
|
}): Promise<
|
|
782
794
|
HarnessAgentTurnResult<THarness, TUserTools, RUNTIME_CONTEXT, OUTPUT>
|
|
783
795
|
> {
|
|
@@ -791,7 +803,7 @@ export class HarnessAgent<
|
|
|
791
803
|
>({
|
|
792
804
|
...this._buildTurnOptions({
|
|
793
805
|
turnSettings: turnInput,
|
|
794
|
-
runtimeContext:
|
|
806
|
+
runtimeContext: turnInput.runtimeContext,
|
|
795
807
|
abortSignal: input.options.abortSignal,
|
|
796
808
|
responseFormat,
|
|
797
809
|
callbacks: this._resolveLifecycleCallbacks(input.options),
|
|
@@ -960,7 +972,9 @@ export class HarnessAgent<
|
|
|
960
972
|
RUNTIME_CONTEXT
|
|
961
973
|
> &
|
|
962
974
|
HarnessAgentCallExtensions,
|
|
963
|
-
): Promise<
|
|
975
|
+
): Promise<
|
|
976
|
+
PreparedHarnessAgentPromptTurnInput<THarness, TUserTools, RUNTIME_CONTEXT>
|
|
977
|
+
> {
|
|
964
978
|
let callOptions = options;
|
|
965
979
|
if (
|
|
966
980
|
this.settings.callOptionsSchema != null &&
|
|
@@ -1002,6 +1016,7 @@ export class HarnessAgent<
|
|
|
1002
1016
|
skills: this.settings.skills,
|
|
1003
1017
|
instructions: this.settings.instructions,
|
|
1004
1018
|
tools: this.settings.tools,
|
|
1019
|
+
runtimeContext: this.settings.runtimeContext,
|
|
1005
1020
|
toolsContext:
|
|
1006
1021
|
this.settings.toolsContext ?? ({} as InferToolSetContext<TUserTools>),
|
|
1007
1022
|
...promptOptions,
|
|
@@ -1028,6 +1043,8 @@ export class HarnessAgent<
|
|
|
1028
1043
|
|
|
1029
1044
|
return {
|
|
1030
1045
|
prompt: this._resolvePromptTurnInput(preparedCallArgs),
|
|
1046
|
+
runtimeContext:
|
|
1047
|
+
preparedCallArgs.runtimeContext ?? ({} as RUNTIME_CONTEXT),
|
|
1031
1048
|
...this._prepareTurnSettings({
|
|
1032
1049
|
model: preparedCallArgs.model,
|
|
1033
1050
|
skills: preparedCallArgs.skills,
|
|
@@ -60,7 +60,7 @@ export function normalizeSandboxWorkDir(workDir: string): string {
|
|
|
60
60
|
|
|
61
61
|
const normalized = posix.normalize(workDir);
|
|
62
62
|
if (
|
|
63
|
-
normalized === '.' ||
|
|
63
|
+
((normalized === '.' || normalized === './') && workDir !== '.') ||
|
|
64
64
|
normalized === '..' ||
|
|
65
65
|
normalized.startsWith('../')
|
|
66
66
|
) {
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ModelMessage,
|
|
5
5
|
ToolSet,
|
|
6
6
|
} from '@ai-sdk/provider-utils';
|
|
7
|
-
import {
|
|
7
|
+
import { createRestrictedTelemetryDispatcher } from 'ai/internal';
|
|
8
8
|
import type {
|
|
9
9
|
ContentPart,
|
|
10
10
|
GenerateTextOnEndCallback,
|
|
@@ -42,7 +42,7 @@ export type HarnessAgentLifecycleCallbacks<
|
|
|
42
42
|
onEnd?: GenerateTextOnEndCallback<TOOLS, RUNTIME_CONTEXT>;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
type Dispatcher = ReturnType<typeof
|
|
45
|
+
type Dispatcher = ReturnType<typeof createRestrictedTelemetryDispatcher>;
|
|
46
46
|
|
|
47
47
|
export interface TurnLifecycle<
|
|
48
48
|
TOOLS extends ToolSet,
|
|
@@ -107,7 +107,11 @@ export function createTurnLifecycle<
|
|
|
107
107
|
const telemetry =
|
|
108
108
|
options.telemetry == null
|
|
109
109
|
? ({} as Dispatcher)
|
|
110
|
-
:
|
|
110
|
+
: createRestrictedTelemetryDispatcher<TOOLS, RUNTIME_CONTEXT, OUTPUT>({
|
|
111
|
+
telemetry: options.telemetry,
|
|
112
|
+
includeRuntimeContext: options.telemetry.includeRuntimeContext,
|
|
113
|
+
includeToolsContext: options.telemetry.includeToolsContext,
|
|
114
|
+
});
|
|
111
115
|
const provider = `harness:${options.harnessId}`;
|
|
112
116
|
let modelId = options.modelId ?? '';
|
|
113
117
|
let started = false;
|