@adonis-agora/agent 0.81.1 → 0.83.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 +17 -0
- package/dist/assets/spa/assets/{index-MrDjRM3K.js → index-DMoSumym.js} +2 -2
- package/dist/assets/spa/index.html +1 -1
- package/dist/src/agent-loop.d.ts.map +1 -1
- package/dist/src/agent-loop.js +87 -6
- package/dist/src/agent-loop.js.map +1 -1
- package/dist/src/diagnostics.d.ts +52 -1
- package/dist/src/diagnostics.d.ts.map +1 -1
- package/dist/src/diagnostics.js +6 -0
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/turn-timing.d.ts +11 -0
- package/dist/src/turn-timing.d.ts.map +1 -0
- package/dist/src/turn-timing.js +20 -0
- package/dist/src/turn-timing.js.map +1 -0
- package/package.json +22 -22
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
rel="stylesheet"
|
|
11
11
|
/>
|
|
12
12
|
<title>agent · governance console</title>
|
|
13
|
-
<script type="module" crossorigin src="./assets/index-
|
|
13
|
+
<script type="module" crossorigin src="./assets/index-DMoSumym.js"></script>
|
|
14
14
|
<link rel="stylesheet" crossorigin href="./assets/index-BxmGk7Ik.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent-loop.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../src/agent-loop.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,KAAK,kBAAkB,EAAyB,MAAM,8BAA8B,CAAC;AAoB9F,OAAO,EACL,KAAK,WAAW,EAMhB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,YAAY,EAQlB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAOL,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AAKrB,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,KAAK,cAAc,EAAyB,MAAM,0BAA0B,CAAC;AACtF,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,yBAAyB,CAAC;AAEnF,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EACL,KAAK,iBAAiB,EAIvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EAIrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAA6C,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EACV,SAAS,EAET,wBAAwB,EAEzB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAanG,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAA4B,KAAK,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAS3F,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,QAAQ,EAGR,OAAO,EACP,aAAa,EAGb,eAAe,EACf,cAAc,EAEd,UAAU,EAGX,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,OAAO;IAC9C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,uGAAuG;IACvG,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;IAC/C,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,GAAG,EAAE,MAAM,CAAC;IACZ,4FAA4F;IAC5F,YAAY,EAAE,MAAM,GAAG,aAAa,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC;;;;;;;;;;;;;;;OAeG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClD,gHAAgH;IAChH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AA2CD,4FAA4F;AAC5F,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAU5F;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,QAAQ,IAAI,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C;;;;;;;;OAQG;IACH,aAAa,CACX,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,SAAS,EACd,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChF;;;OAGG;IACH,QAAQ,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/B;;;;OAIG;IACH,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7C;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9E;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC;;;;;;;;;OASG;IACH,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,cAGC;CACF;AA2BD,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,cAGC;CACF;AAgLD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAwV/C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,GAAG,EAAE,OAAO,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,GAAG,cAAc,EAAE,CAOnB;AA89CD,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AA8M1D,qGAAqG;AACrG;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,CAgBjE;AA6CD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,kEAAkE,CAAC;AAIlG;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAE1E;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAiBpE;AASD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAY5E;AAED,MAAM,WAAW,eAAe,CAAC,OAAO,GAAG,OAAO;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sGAAsG;IACtG,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAG,OAAO,EAClD,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAQnC"}
|
package/dist/src/agent-loop.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { turnChannel } from './genui/channels.js';
|
|
2
2
|
import { GenuiTurnTelemetry, observeGenuiFrames } from './genui-telemetry.js';
|
|
3
3
|
import { DEFAULT_REFUSAL_REASON } from './refusal.js';
|
|
4
|
+
import { observeFirstText } from './turn-timing.js';
|
|
4
5
|
export { DEFAULT_REFUSAL_REASON } from './refusal.js';
|
|
5
6
|
import { createHash } from 'node:crypto';
|
|
6
7
|
import { resolveActionProposalApproval } from './action-proposal-approval.js';
|
|
@@ -8,7 +9,7 @@ import { prepareActionProposal } from './action-proposal-preparation.js';
|
|
|
8
9
|
import { actionProposalReceipt } from './action-proposal-receipt.js';
|
|
9
10
|
import { danglingToolCallIds, settleDanglingToolCalls } from './dangling-tool-calls.js';
|
|
10
11
|
import { detachedDelivered, detachedStarted, } from './delegation.js';
|
|
11
|
-
import { publishAgentDelegated, publishAgentMessage, publishAgentRetrieved, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, spannedAgent, } from './diagnostics.js';
|
|
12
|
+
import { publishAgentDelegated, publishAgentMessage, publishAgentRetrieved, publishAgentRunCancelled, publishAgentRunFailed, publishAgentRunFinished, publishAgentRunStarted, publishAgentToolCall, publishAgentToolRetry, spannedAgent, } from './diagnostics.js';
|
|
12
13
|
import { ASK_TOOL_NAME, askInputSchema, askToolDefinition, DEFAULT_INTAKE_PREAMBLE, isHumanDecision, normalizeElicitationReply, settleElicitation, } from './elicitation.js';
|
|
13
14
|
import { buildMemoryBlock, offerMemories, REMEMBER_TOOL_NAME, rememberInputSchema, rememberToolDefinition, writeMemory, } from './memory.js';
|
|
14
15
|
import { channelChoiceLimits, createNegotiatedUiCollector, withDelivered, } from './negotiated-tool-ui.js';
|
|
@@ -1026,8 +1027,12 @@ async function invokeClaimedTool(turn, claimed, presentationOnly) {
|
|
|
1026
1027
|
// Execution retains every narrowing the offer and preparation had, including an agent-only list.
|
|
1027
1028
|
const allowedTools = intersectAllow(personaOf(turn.input)?.allowedTools, deps.toolAllowList);
|
|
1028
1029
|
const invokeOptions = allowedTools === undefined ? {} : { allowedTools };
|
|
1030
|
+
// Set only when the step's body runs here: a checkpoint read back from the journal has no timing.
|
|
1031
|
+
let ranAt;
|
|
1032
|
+
const timing = () => ranAt === undefined ? { replayed: true } : { durationMs: Date.now() - ranAt };
|
|
1029
1033
|
try {
|
|
1030
1034
|
const raw = await hooks.step(`tool:${call.id}`, async () => {
|
|
1035
|
+
ranAt = Date.now();
|
|
1031
1036
|
// Pushed components stream as they happen and ride this step's RESULT into the journal (see
|
|
1032
1037
|
// `wrapToolStepOutput`), so a replay neither re-streams nor re-persists them.
|
|
1033
1038
|
const ui = createNegotiatedUiCollector(call.id, {
|
|
@@ -1112,7 +1117,7 @@ async function invokeClaimedTool(turn, claimed, presentationOnly) {
|
|
|
1112
1117
|
raw['@@adonis-agent/tool-preflight-denied'] === 1 &&
|
|
1113
1118
|
'reason' in raw &&
|
|
1114
1119
|
typeof raw.reason === 'string') {
|
|
1115
|
-
return { status: 'failed', error: raw.reason, denied: true };
|
|
1120
|
+
return { status: 'failed', error: raw.reason, denied: true, ...timing() };
|
|
1116
1121
|
}
|
|
1117
1122
|
const { output, ui, text } = unwrapToolStepOutput(raw);
|
|
1118
1123
|
if (text)
|
|
@@ -1123,7 +1128,7 @@ async function invokeClaimedTool(turn, claimed, presentationOnly) {
|
|
|
1123
1128
|
if (claimed.terminal === true) {
|
|
1124
1129
|
turn.halt.terminal = true;
|
|
1125
1130
|
}
|
|
1126
|
-
return { status: 'executed', output };
|
|
1131
|
+
return { status: 'executed', output, ...timing() };
|
|
1127
1132
|
}
|
|
1128
1133
|
catch (error) {
|
|
1129
1134
|
if (isReplayIntegrityError(error) || hooks.isControlFlowError?.(error) === true) {
|
|
@@ -1133,9 +1138,17 @@ async function invokeClaimedTool(turn, claimed, presentationOnly) {
|
|
|
1133
1138
|
status: 'failed',
|
|
1134
1139
|
error: error instanceof Error ? error.message : String(error),
|
|
1135
1140
|
...(error instanceof ToolPreflightDeniedError ? { denied: true } : {}),
|
|
1141
|
+
...timing(),
|
|
1136
1142
|
};
|
|
1137
1143
|
}
|
|
1138
1144
|
}
|
|
1145
|
+
/** The timing a settled invocation carries onto its `tool-call` diagnostic. */
|
|
1146
|
+
function toolTiming(outcome) {
|
|
1147
|
+
return {
|
|
1148
|
+
...(outcome.durationMs !== undefined ? { durationMs: outcome.durationMs } : {}),
|
|
1149
|
+
...(outcome.replayed === true ? { replayed: true } : {}),
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1139
1152
|
/** Persist one settled invocation and shape the result the model is fed. */
|
|
1140
1153
|
async function recordToolOutcome(turn, claimed, outcome, deciderRef = turn.input.actor.id, meta) {
|
|
1141
1154
|
const { deps, hooks } = turn;
|
|
@@ -1180,7 +1193,14 @@ async function recordToolOutcome(turn, claimed, outcome, deciderRef = turn.input
|
|
|
1180
1193
|
});
|
|
1181
1194
|
await settle();
|
|
1182
1195
|
});
|
|
1183
|
-
publishAgentToolCall({
|
|
1196
|
+
publishAgentToolCall({
|
|
1197
|
+
runId: hooks.runId,
|
|
1198
|
+
toolCallId: call.id,
|
|
1199
|
+
toolName: call.name,
|
|
1200
|
+
toolType,
|
|
1201
|
+
status: 'failed',
|
|
1202
|
+
...toolTiming(outcome),
|
|
1203
|
+
});
|
|
1184
1204
|
return {
|
|
1185
1205
|
id: call.id,
|
|
1186
1206
|
name: call.name,
|
|
@@ -1200,7 +1220,14 @@ async function recordToolOutcome(turn, claimed, outcome, deciderRef = turn.input
|
|
|
1200
1220
|
});
|
|
1201
1221
|
await settle();
|
|
1202
1222
|
});
|
|
1203
|
-
publishAgentToolCall({
|
|
1223
|
+
publishAgentToolCall({
|
|
1224
|
+
runId: hooks.runId,
|
|
1225
|
+
toolCallId: call.id,
|
|
1226
|
+
toolName: call.name,
|
|
1227
|
+
toolType,
|
|
1228
|
+
status: 'executed',
|
|
1229
|
+
...toolTiming(outcome),
|
|
1230
|
+
});
|
|
1204
1231
|
return { id: call.id, name: call.name, output: outcome.output };
|
|
1205
1232
|
}
|
|
1206
1233
|
/**
|
|
@@ -1424,6 +1451,7 @@ async function elicitToolCall(turn, claimed) {
|
|
|
1424
1451
|
}));
|
|
1425
1452
|
publishAgentToolCall({
|
|
1426
1453
|
runId: hooks.runId,
|
|
1454
|
+
toolCallId: call.id,
|
|
1427
1455
|
toolName: call.name,
|
|
1428
1456
|
toolType: 'action',
|
|
1429
1457
|
status: result.skipped ? 'rejected' : 'executed',
|
|
@@ -1646,6 +1674,7 @@ async function runClaimedToolCall(turn, claimed) {
|
|
|
1646
1674
|
});
|
|
1647
1675
|
publishAgentToolCall({
|
|
1648
1676
|
runId: hooks.runId,
|
|
1677
|
+
toolCallId: call.id,
|
|
1649
1678
|
toolName: call.name,
|
|
1650
1679
|
toolType,
|
|
1651
1680
|
status: 'rejected',
|
|
@@ -1695,6 +1724,7 @@ async function expireToolCall(turn, claimed) {
|
|
|
1695
1724
|
});
|
|
1696
1725
|
publishAgentToolCall({
|
|
1697
1726
|
runId: hooks.runId,
|
|
1727
|
+
toolCallId: call.id,
|
|
1698
1728
|
toolName: call.name,
|
|
1699
1729
|
toolType: 'action',
|
|
1700
1730
|
status: 'rejected',
|
|
@@ -2001,6 +2031,48 @@ export function streamErrorFrame(error, runId) {
|
|
|
2001
2031
|
* hooks that make the same loop body either in-process or a replay-safe durable workflow.
|
|
2002
2032
|
*/
|
|
2003
2033
|
export async function runAgentLoop(boundDeps, requested, hooks) {
|
|
2034
|
+
const startedAt = Date.now();
|
|
2035
|
+
try {
|
|
2036
|
+
return await runAgentTurn(boundDeps, requested, hooks);
|
|
2037
|
+
}
|
|
2038
|
+
catch (error) {
|
|
2039
|
+
publishRunEnded(error, requested, hooks, startedAt);
|
|
2040
|
+
throw error;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
/** Who and what the run is, for its terminal diagnostics. */
|
|
2044
|
+
function runContext(input) {
|
|
2045
|
+
return {
|
|
2046
|
+
...(input.agentName !== undefined ? { agentName: input.agentName } : {}),
|
|
2047
|
+
actorId: input.actor.id,
|
|
2048
|
+
...(input.actor.tenantRef !== undefined && input.actor.tenantRef !== null
|
|
2049
|
+
? { tenantRef: input.actor.tenantRef }
|
|
2050
|
+
: {}),
|
|
2051
|
+
...(input.parentRunId !== undefined ? { parentRunId: input.parentRunId } : {}),
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* `run.failed` / `run.cancelled` for a loop that threw. A durable control-flow signal (suspend on an
|
|
2056
|
+
* approval or a question, continue-as-new) is not an ending — the run goes on — so it publishes
|
|
2057
|
+
* nothing; a run whose abort signal fired was stopped; anything else failed, under the same code the
|
|
2058
|
+
* stream's `error` frame carries.
|
|
2059
|
+
*/
|
|
2060
|
+
function publishRunEnded(error, input, hooks, startedAt) {
|
|
2061
|
+
if (!isReplayIntegrityError(error) && hooks.isControlFlowError?.(error) === true)
|
|
2062
|
+
return;
|
|
2063
|
+
const base = {
|
|
2064
|
+
runId: hooks.runId,
|
|
2065
|
+
threadId: input.threadId,
|
|
2066
|
+
durationMs: Date.now() - startedAt,
|
|
2067
|
+
...runContext(input),
|
|
2068
|
+
};
|
|
2069
|
+
if (hooks.abortSignal?.aborted === true) {
|
|
2070
|
+
publishAgentRunCancelled(base);
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
publishAgentRunFailed({ ...base, code: streamErrorCode(error) });
|
|
2074
|
+
}
|
|
2075
|
+
async function runAgentTurn(boundDeps, requested, hooks) {
|
|
2004
2076
|
// The persona, FIRST and only when the run names one by id: its definition is read from config
|
|
2005
2077
|
// once and frozen in this checkpoint, so a run resumed after the persona was edited or removed
|
|
2006
2078
|
// keeps the prompt and allow-list it started with. A run that names none spends no position here
|
|
@@ -2134,7 +2206,8 @@ export async function runAgentLoop(boundDeps, requested, hooks) {
|
|
|
2134
2206
|
.allSpecs()
|
|
2135
2207
|
.some((spec) => spec.genui !== undefined && spec.genui.telemetry !== false);
|
|
2136
2208
|
const genuiFrames = genuiOn ? observeGenuiFrames(await hooks.openSink()) : undefined;
|
|
2137
|
-
const
|
|
2209
|
+
const firstText = observeFirstText(genuiFrames?.writer ?? (await hooks.openSink()));
|
|
2210
|
+
const writer = firstText.writer;
|
|
2138
2211
|
const genuiTurn = new GenuiTurnTelemetry();
|
|
2139
2212
|
let lastText = '';
|
|
2140
2213
|
let steps = 0;
|
|
@@ -2144,6 +2217,7 @@ export async function runAgentLoop(boundDeps, requested, hooks) {
|
|
|
2144
2217
|
// priced). If NO step had a cost, the run's `cost_usd` stays `null` — never a fabricated `0`.
|
|
2145
2218
|
let totalCost = 0;
|
|
2146
2219
|
let hasCost = false;
|
|
2220
|
+
let lastModelId;
|
|
2147
2221
|
let structured;
|
|
2148
2222
|
publishAgentRunStarted({
|
|
2149
2223
|
runId: hooks.runId,
|
|
@@ -2437,6 +2511,7 @@ export async function runAgentLoop(boundDeps, requested, hooks) {
|
|
|
2437
2511
|
}
|
|
2438
2512
|
// provider-reported model wins over the configured fallback, so cost can't misattribute
|
|
2439
2513
|
const resolvedModelId = turn.modelId ?? deps.modelId ?? 'unknown';
|
|
2514
|
+
lastModelId = resolvedModelId;
|
|
2440
2515
|
// Provider-reported spend wins; else an estimate from the (once-per-run cached) price list; else
|
|
2441
2516
|
// `null` — stamped onto the persisted assistant message's `usage.costUsd` below.
|
|
2442
2517
|
// `resolveModelPrice` e não `priceByModel.get`: o provider responde com o snapshot datado
|
|
@@ -2834,12 +2909,18 @@ export async function runAgentLoop(boundDeps, requested, hooks) {
|
|
|
2834
2909
|
...(hasCost ? { costUsd: totalCost } : {}),
|
|
2835
2910
|
}));
|
|
2836
2911
|
await writer.end();
|
|
2912
|
+
const firstTextAt = firstText.firstTextAt();
|
|
2837
2913
|
publishAgentRunFinished({
|
|
2838
2914
|
runId: hooks.runId,
|
|
2839
2915
|
threadId: input.threadId,
|
|
2840
2916
|
steps,
|
|
2841
2917
|
inputTokens: totalInput,
|
|
2842
2918
|
outputTokens: totalOutput,
|
|
2919
|
+
durationMs: Date.now() - turnStartedAt,
|
|
2920
|
+
...(firstTextAt !== undefined ? { ttftMs: firstTextAt - turnStartedAt } : {}),
|
|
2921
|
+
...(hasCost ? { costUsd: totalCost } : {}),
|
|
2922
|
+
...(lastModelId !== undefined ? { modelId: lastModelId } : {}),
|
|
2923
|
+
...runContext(input),
|
|
2843
2924
|
});
|
|
2844
2925
|
return { text: lastText, ...(structured !== undefined ? { object: structured } : {}) };
|
|
2845
2926
|
}
|