@ai-sdk/harness 1.0.42 → 1.0.43
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 +8 -0
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +105 -22
- package/dist/agent/index.js.map +1 -1
- package/dist/bridge/index.d.ts +0 -6
- package/dist/bridge/index.js +0 -24
- package/dist/bridge/index.js.map +1 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.js +0 -10
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +0 -3
- package/dist/utils/index.js +0 -69
- package/dist/utils/index.js.map +1 -1
- package/package.json +3 -1
- package/src/agent/harness-agent-session.ts +4 -0
- package/src/agent/internal/run-prompt.ts +22 -3
- package/src/agent/internal/turn-telemetry.ts +126 -17
- package/src/bridge/index.ts +1 -43
- package/src/utils/sandbox-channel.ts +0 -66
- package/src/v1/harness-v1-bridge-protocol.ts +0 -17
- package/src/v1/harness-v1-lifecycle-state.ts +1 -1
- package/src/v1/harness-v1-session.ts +2 -2
- package/src/v1/harness-v1.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @ai-sdk/harness
|
|
2
2
|
|
|
3
|
+
## 1.0.43
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a9a22e1: fix(harness): fix telemetry end events to report `final-step` text and reasoning for multi-step turns
|
|
8
|
+
- 9e4e816: fix(harness): avoid emitting `onTurnFinished` / `onTurnFailed` when turn is suspended mid-flight
|
|
9
|
+
- ea3063f: fix(harness): remove broken bridge `channel.interrupt()` layer and its usage
|
|
10
|
+
|
|
3
11
|
## 1.0.42
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -403,7 +403,7 @@ type HarnessV1ResumeSessionState = HarnessV1LifecycleStateBase & {
|
|
|
403
403
|
/**
|
|
404
404
|
* Opaque payload returned by `doSuspendTurn` and accepted by a future
|
|
405
405
|
* `HarnessV1.doStart({ continueFrom })` to reconnect to the same session before
|
|
406
|
-
* continuing the
|
|
406
|
+
* continuing the suspended turn.
|
|
407
407
|
*/
|
|
408
408
|
type HarnessV1ContinueTurnState = HarnessV1LifecycleStateBase & {
|
|
409
409
|
readonly type: 'continue-turn';
|
|
@@ -783,7 +783,7 @@ type HarnessV1Session = {
|
|
|
783
783
|
/**
|
|
784
784
|
* Continue the in-flight turn **without a new user prompt**, returning the
|
|
785
785
|
* same control surface as `doPromptTurn`. Used to keep consuming a turn that
|
|
786
|
-
* was
|
|
786
|
+
* was suspended at a process boundary (the workflow slice loop), after the
|
|
787
787
|
* session itself has been resumed via `doStart({ continueFrom })`:
|
|
788
788
|
*
|
|
789
789
|
* - When the runtime's turn is still live and reachable (bridge `attach` /
|
|
@@ -792,7 +792,7 @@ type HarnessV1Session = {
|
|
|
792
792
|
* - When the live turn is gone (bridge respawned `rerun`, or a host-resident
|
|
793
793
|
* runtime like Pi whose turn cannot survive its process), the adapter
|
|
794
794
|
* re-drives the runtime's own thread from its persisted state. Lossy: work
|
|
795
|
-
* in flight at the
|
|
795
|
+
* in flight at the suspension is recomputed.
|
|
796
796
|
*
|
|
797
797
|
* Required on every adapter. The behaviour an adapter can guarantee follows
|
|
798
798
|
* from its architecture; the contract is uniform.
|
|
@@ -915,7 +915,7 @@ type HarnessV1<TBuiltinTools extends ToolSet = ToolSet> = {
|
|
|
915
915
|
}) => PromiseLike<HarnessV1Bootstrap>;
|
|
916
916
|
/**
|
|
917
917
|
* Start a fresh session, resume a parked session via `resumeFrom`, or resume
|
|
918
|
-
*
|
|
918
|
+
* a suspended turn via `continueFrom`. The host then issues prompts against
|
|
919
919
|
* the returned session, ending with `doDetach`, `doStop`, or `doDestroy`.
|
|
920
920
|
*/
|
|
921
921
|
doStart(options: HarnessV1StartOptions): PromiseLike<HarnessV1Session>;
|
package/dist/agent/index.js
CHANGED
|
@@ -937,6 +937,42 @@ var NOOP = {
|
|
|
937
937
|
async error() {
|
|
938
938
|
}
|
|
939
939
|
};
|
|
940
|
+
function normalizeFinishReason(finishReason) {
|
|
941
|
+
if (finishReason != null && typeof finishReason === "object" && "unified" in finishReason) {
|
|
942
|
+
return finishReason.unified;
|
|
943
|
+
}
|
|
944
|
+
return finishReason;
|
|
945
|
+
}
|
|
946
|
+
function addTokenCounts(tokenCount1, tokenCount2) {
|
|
947
|
+
return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 != null ? tokenCount1 : 0) + (tokenCount2 != null ? tokenCount2 : 0);
|
|
948
|
+
}
|
|
949
|
+
function normalizeUsage(usage) {
|
|
950
|
+
if (usage == null || typeof usage !== "object" || !("inputTokens" in usage) || !("outputTokens" in usage)) {
|
|
951
|
+
return usage;
|
|
952
|
+
}
|
|
953
|
+
const inputTokens = usage.inputTokens;
|
|
954
|
+
const outputTokens = usage.outputTokens;
|
|
955
|
+
if (inputTokens == null || typeof inputTokens !== "object" || outputTokens == null || typeof outputTokens !== "object") {
|
|
956
|
+
return usage;
|
|
957
|
+
}
|
|
958
|
+
const input = inputTokens;
|
|
959
|
+
const output = outputTokens;
|
|
960
|
+
return {
|
|
961
|
+
inputTokens: input.total,
|
|
962
|
+
inputTokenDetails: {
|
|
963
|
+
noCacheTokens: input.noCache,
|
|
964
|
+
cacheReadTokens: input.cacheRead,
|
|
965
|
+
cacheWriteTokens: input.cacheWrite
|
|
966
|
+
},
|
|
967
|
+
outputTokens: output.total,
|
|
968
|
+
outputTokenDetails: {
|
|
969
|
+
textTokens: output.text,
|
|
970
|
+
reasoningTokens: output.reasoning
|
|
971
|
+
},
|
|
972
|
+
totalTokens: addTokenCounts(input.total, output.total),
|
|
973
|
+
raw: usage.raw
|
|
974
|
+
};
|
|
975
|
+
}
|
|
940
976
|
function createTurnTelemetry(opts) {
|
|
941
977
|
var _a3;
|
|
942
978
|
if (opts.telemetry == null) return NOOP;
|
|
@@ -952,6 +988,10 @@ function createTurnTelemetry(opts) {
|
|
|
952
988
|
let stepOpen = false;
|
|
953
989
|
let stepNumber = 0;
|
|
954
990
|
let ended = false;
|
|
991
|
+
let finalStepText = "";
|
|
992
|
+
let finalStepReasoning = [];
|
|
993
|
+
let finalStepProviderMetadata;
|
|
994
|
+
let outputToolCalls = [];
|
|
955
995
|
const openTools = /* @__PURE__ */ new Map();
|
|
956
996
|
const cast = (event) => event;
|
|
957
997
|
const fireStart = async () => {
|
|
@@ -1020,17 +1060,37 @@ function createTurnTelemetry(opts) {
|
|
|
1020
1060
|
};
|
|
1021
1061
|
const inferenceEnd = async (info) => {
|
|
1022
1062
|
var _a4;
|
|
1063
|
+
const finishReason = normalizeFinishReason(info.finishReason);
|
|
1064
|
+
const usage = normalizeUsage(info.usage);
|
|
1023
1065
|
await ((_a4 = dispatcher.onLanguageModelCallEnd) == null ? void 0 : _a4.call(
|
|
1024
1066
|
dispatcher,
|
|
1025
1067
|
cast({
|
|
1026
1068
|
callId,
|
|
1027
|
-
finishReason
|
|
1069
|
+
finishReason,
|
|
1028
1070
|
responseId: callId,
|
|
1029
|
-
usage
|
|
1030
|
-
content: info.content
|
|
1071
|
+
usage,
|
|
1072
|
+
content: info.content,
|
|
1073
|
+
performance: {
|
|
1074
|
+
responseTimeMs: void 0,
|
|
1075
|
+
timeToFirstOutputMs: void 0,
|
|
1076
|
+
timeBetweenOutputChunksMs: void 0
|
|
1077
|
+
}
|
|
1031
1078
|
})
|
|
1032
1079
|
));
|
|
1033
1080
|
};
|
|
1081
|
+
const recordOutputContent = (content) => {
|
|
1082
|
+
finalStepText = "";
|
|
1083
|
+
finalStepReasoning = [];
|
|
1084
|
+
for (const part of content) {
|
|
1085
|
+
if (part.type === "text") {
|
|
1086
|
+
finalStepText += part.text;
|
|
1087
|
+
} else if (part.type === "reasoning") {
|
|
1088
|
+
finalStepReasoning.push({ text: part.text });
|
|
1089
|
+
} else if (part.type === "tool-call") {
|
|
1090
|
+
outputToolCalls.push(part);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1034
1094
|
const closeOpenTools = async () => {
|
|
1035
1095
|
var _a4;
|
|
1036
1096
|
for (const call of openTools.values()) {
|
|
@@ -1061,10 +1121,14 @@ function createTurnTelemetry(opts) {
|
|
|
1061
1121
|
var _a4, _b3;
|
|
1062
1122
|
if (!stepOpen) return;
|
|
1063
1123
|
const content = (_a4 = info.content) != null ? _a4 : [];
|
|
1124
|
+
const finishReason = normalizeFinishReason(info.finishReason);
|
|
1125
|
+
const usage = normalizeUsage(info.usage);
|
|
1126
|
+
recordOutputContent(content);
|
|
1127
|
+
finalStepProviderMetadata = info.providerMetadata;
|
|
1064
1128
|
await closeOpenTools();
|
|
1065
1129
|
await inferenceEnd({
|
|
1066
|
-
finishReason
|
|
1067
|
-
usage
|
|
1130
|
+
finishReason,
|
|
1131
|
+
usage,
|
|
1068
1132
|
content
|
|
1069
1133
|
});
|
|
1070
1134
|
await ((_b3 = dispatcher.onStepEnd) == null ? void 0 : _b3.call(
|
|
@@ -1072,8 +1136,8 @@ function createTurnTelemetry(opts) {
|
|
|
1072
1136
|
cast({
|
|
1073
1137
|
callId,
|
|
1074
1138
|
stepNumber,
|
|
1075
|
-
finishReason
|
|
1076
|
-
usage
|
|
1139
|
+
finishReason,
|
|
1140
|
+
usage,
|
|
1077
1141
|
providerMetadata: info.providerMetadata,
|
|
1078
1142
|
content,
|
|
1079
1143
|
response: {
|
|
@@ -1115,6 +1179,7 @@ function createTurnTelemetry(opts) {
|
|
|
1115
1179
|
async toolEnd(toolCallId, output) {
|
|
1116
1180
|
var _a4;
|
|
1117
1181
|
const call = openTools.get(toolCallId);
|
|
1182
|
+
const normalizedOutput = output.ok ? { type: "tool-result", output: output.output } : { type: "error", error: output.error };
|
|
1118
1183
|
if (call == null) return;
|
|
1119
1184
|
openTools.delete(toolCallId);
|
|
1120
1185
|
await ((_a4 = dispatcher.onToolExecutionEnd) == null ? void 0 : _a4.call(
|
|
@@ -1131,19 +1196,21 @@ function createTurnTelemetry(opts) {
|
|
|
1131
1196
|
dynamic: true
|
|
1132
1197
|
},
|
|
1133
1198
|
toolContext: void 0,
|
|
1134
|
-
toolOutput:
|
|
1199
|
+
toolOutput: normalizedOutput
|
|
1135
1200
|
})
|
|
1136
1201
|
));
|
|
1137
1202
|
},
|
|
1138
1203
|
async end(info) {
|
|
1139
1204
|
var _a4, _b3;
|
|
1140
1205
|
if (ended) return;
|
|
1206
|
+
const finishReason = normalizeFinishReason(info.finishReason);
|
|
1207
|
+
const usage = normalizeUsage(info.usage);
|
|
1141
1208
|
if (!started) await fireStart();
|
|
1142
1209
|
if (stepOpen) {
|
|
1143
1210
|
await closeOpenTools();
|
|
1144
1211
|
await inferenceEnd({
|
|
1145
|
-
finishReason
|
|
1146
|
-
usage
|
|
1212
|
+
finishReason,
|
|
1213
|
+
usage,
|
|
1147
1214
|
content: []
|
|
1148
1215
|
});
|
|
1149
1216
|
await ((_a4 = dispatcher.onStepEnd) == null ? void 0 : _a4.call(
|
|
@@ -1151,8 +1218,8 @@ function createTurnTelemetry(opts) {
|
|
|
1151
1218
|
cast({
|
|
1152
1219
|
callId,
|
|
1153
1220
|
stepNumber,
|
|
1154
|
-
finishReason
|
|
1155
|
-
usage
|
|
1221
|
+
finishReason,
|
|
1222
|
+
usage,
|
|
1156
1223
|
providerMetadata: void 0,
|
|
1157
1224
|
content: [],
|
|
1158
1225
|
response: {
|
|
@@ -1171,10 +1238,17 @@ function createTurnTelemetry(opts) {
|
|
|
1171
1238
|
cast({
|
|
1172
1239
|
callId,
|
|
1173
1240
|
operationId: "ai.harness",
|
|
1174
|
-
finishReason
|
|
1175
|
-
usage
|
|
1176
|
-
totalUsage:
|
|
1241
|
+
finishReason,
|
|
1242
|
+
usage,
|
|
1243
|
+
totalUsage: usage,
|
|
1177
1244
|
content: [],
|
|
1245
|
+
text: finalStepText,
|
|
1246
|
+
finalStep: {
|
|
1247
|
+
reasoning: finalStepReasoning,
|
|
1248
|
+
providerMetadata: finalStepProviderMetadata
|
|
1249
|
+
},
|
|
1250
|
+
toolCalls: outputToolCalls,
|
|
1251
|
+
files: [],
|
|
1178
1252
|
steps: new Array(stepNumber),
|
|
1179
1253
|
response: {
|
|
1180
1254
|
id: callId,
|
|
@@ -1317,9 +1391,11 @@ function runPrompt(input) {
|
|
|
1317
1391
|
runtimeContext: input.runtimeContext
|
|
1318
1392
|
});
|
|
1319
1393
|
const settleFailure = (err) => {
|
|
1320
|
-
var _a4, _b4;
|
|
1321
|
-
(_a4 = input.
|
|
1322
|
-
|
|
1394
|
+
var _a4, _b4, _c2;
|
|
1395
|
+
if (!((_a4 = input.isTurnSuspending) == null ? void 0 : _a4.call(input))) {
|
|
1396
|
+
(_b4 = input.onTurnFailed) == null ? void 0 : _b4.call(input);
|
|
1397
|
+
}
|
|
1398
|
+
if ((_c2 = input.abortSignal) == null ? void 0 : _c2.aborted) {
|
|
1323
1399
|
result.abort({
|
|
1324
1400
|
error: err,
|
|
1325
1401
|
...input.abortSignal.reason !== void 0 ? { reason: getErrorMessage(input.abortSignal.reason) } : {}
|
|
@@ -1329,7 +1405,7 @@ function runPrompt(input) {
|
|
|
1329
1405
|
result.fail(err);
|
|
1330
1406
|
};
|
|
1331
1407
|
const done = (async () => {
|
|
1332
|
-
var _a4, _b4, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k;
|
|
1408
|
+
var _a4, _b4, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k, _l;
|
|
1333
1409
|
let bridge;
|
|
1334
1410
|
try {
|
|
1335
1411
|
bridge = await toHarnessStream({
|
|
@@ -1932,10 +2008,15 @@ function runPrompt(input) {
|
|
|
1932
2008
|
await telemetry.toolEnd(toolCall.toolCallId, execution.outcome);
|
|
1933
2009
|
}
|
|
1934
2010
|
}
|
|
1935
|
-
|
|
1936
|
-
|
|
2011
|
+
const isTurnSuspending = ((_j = input.isTurnSuspending) == null ? void 0 : _j.call(input)) === true;
|
|
2012
|
+
if (isTurnSuspending) {
|
|
2013
|
+
if (finalFinish == null) {
|
|
2014
|
+
result.discardCurrentStepContent();
|
|
2015
|
+
}
|
|
2016
|
+
} else if (finalFinish != null) {
|
|
2017
|
+
(_k = input.onTurnFinished) == null ? void 0 : _k.call(input);
|
|
1937
2018
|
} else {
|
|
1938
|
-
(
|
|
2019
|
+
(_l = input.onTurnFailed) == null ? void 0 : _l.call(input);
|
|
1939
2020
|
}
|
|
1940
2021
|
await result.finish(
|
|
1941
2022
|
finalFinish ? {
|
|
@@ -2146,6 +2227,7 @@ var HarnessAgentSession = class {
|
|
|
2146
2227
|
onTurnFailed: () => {
|
|
2147
2228
|
this.finishTrackedTurn({ turnId });
|
|
2148
2229
|
},
|
|
2230
|
+
isTurnSuspending: () => this.activeTurnSequence === turnId && this.suspendedTurnState != null,
|
|
2149
2231
|
onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
|
|
2150
2232
|
});
|
|
2151
2233
|
return turn;
|
|
@@ -2200,6 +2282,7 @@ var HarnessAgentSession = class {
|
|
|
2200
2282
|
onTurnFailed: () => {
|
|
2201
2283
|
this.finishTrackedTurn({ turnId });
|
|
2202
2284
|
},
|
|
2285
|
+
isTurnSuspending: () => this.activeTurnSequence === turnId && this.suspendedTurnState != null,
|
|
2203
2286
|
onStopConditionMet: () => this.captureStopConditionBoundary({ session, turnId })
|
|
2204
2287
|
});
|
|
2205
2288
|
return turn;
|