@cognipeer/agent-sdk 0.13.0 → 0.14.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/dist/index.cjs +300 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.mjs +299 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2026,27 +2026,71 @@ function convertMessageListToSections(messageList) {
|
|
|
2026
2026
|
}
|
|
2027
2027
|
return sections.length > 0 ? sections : void 0;
|
|
2028
2028
|
}
|
|
2029
|
-
function
|
|
2029
|
+
function readTraceContinuation(value) {
|
|
2030
|
+
if (!value || typeof value !== "object") return void 0;
|
|
2031
|
+
const raw = value;
|
|
2032
|
+
if (raw.v !== 1 || typeof raw.sessionId !== "string" || raw.sessionId.length === 0) return void 0;
|
|
2033
|
+
const nextSequence = Number(raw.nextSequence);
|
|
2034
|
+
const startedAt = Number(raw.startedAt);
|
|
2035
|
+
const part = Number(raw.part);
|
|
2036
|
+
if (!Number.isInteger(nextSequence) || nextSequence < 1) return void 0;
|
|
2037
|
+
if (!Number.isFinite(startedAt) || !Number.isInteger(part) || part < 1) return void 0;
|
|
2038
|
+
const summary = raw.summary && typeof raw.summary === "object" ? { ...createEmptySummary(), ...raw.summary } : createEmptySummary();
|
|
2039
|
+
summary.eventCounts = { ...raw.summary?.eventCounts ?? {} };
|
|
2040
|
+
return {
|
|
2041
|
+
v: 1,
|
|
2042
|
+
sessionId: raw.sessionId,
|
|
2043
|
+
traceId: typeof raw.traceId === "string" ? raw.traceId : void 0,
|
|
2044
|
+
rootSpanId: typeof raw.rootSpanId === "string" ? raw.rootSpanId : void 0,
|
|
2045
|
+
threadId: typeof raw.threadId === "string" ? raw.threadId : void 0,
|
|
2046
|
+
startedAt,
|
|
2047
|
+
nextSequence,
|
|
2048
|
+
part,
|
|
2049
|
+
summary,
|
|
2050
|
+
errors: Array.isArray(raw.errors) ? raw.errors : []
|
|
2051
|
+
};
|
|
2052
|
+
}
|
|
2053
|
+
function traceContinuationOf(session) {
|
|
2054
|
+
return {
|
|
2055
|
+
v: 1,
|
|
2056
|
+
sessionId: session.sessionId,
|
|
2057
|
+
traceId: session.traceId,
|
|
2058
|
+
rootSpanId: session.rootSpanId,
|
|
2059
|
+
threadId: session.threadId,
|
|
2060
|
+
startedAt: session.startedAt,
|
|
2061
|
+
nextSequence: (session.sequenceOffset ?? 0) + session.events.length + 1,
|
|
2062
|
+
part: session.part ?? 1,
|
|
2063
|
+
summary: JSON.parse(JSON.stringify(session.summary)),
|
|
2064
|
+
// Sink failures belong to the part that hit them; carrying them on would
|
|
2065
|
+
// mark every later part `partial`.
|
|
2066
|
+
errors: session.errors.filter((error) => error.type !== "sink")
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
function createTraceSession(opts, continuation) {
|
|
2030
2070
|
const cfg = withDefaults(opts.tracing);
|
|
2031
2071
|
if (!cfg.enabled) return void 0;
|
|
2032
2072
|
const providedSessionId = opts.tracing?.sessionId?.trim();
|
|
2033
|
-
const sessionId = providedSessionId || generateSessionId();
|
|
2034
|
-
const traceId = generateTraceId();
|
|
2035
|
-
const rootSpanId = generateSpanId();
|
|
2073
|
+
const sessionId = continuation?.sessionId || providedSessionId || generateSessionId();
|
|
2074
|
+
const traceId = continuation?.traceId || generateTraceId();
|
|
2075
|
+
const rootSpanId = continuation?.rootSpanId || generateSpanId();
|
|
2036
2076
|
const runtime = {
|
|
2037
2077
|
sessionId,
|
|
2038
2078
|
traceId,
|
|
2039
2079
|
rootSpanId,
|
|
2040
|
-
threadId: opts.tracing?.threadId,
|
|
2080
|
+
threadId: continuation?.threadId ?? opts.tracing?.threadId,
|
|
2041
2081
|
configAgentName: opts.tracing?.agentName?.trim() || void 0,
|
|
2042
2082
|
configMetadata: opts.tracing?.metadata && Object.keys(opts.tracing.metadata).length > 0 ? opts.tracing.metadata : void 0,
|
|
2043
|
-
startedAt: Date.now(),
|
|
2083
|
+
startedAt: continuation?.startedAt ?? Date.now(),
|
|
2044
2084
|
resolvedConfig: cfg,
|
|
2045
2085
|
events: [],
|
|
2046
|
-
summary: createEmptySummary(),
|
|
2086
|
+
summary: continuation ? continuation.summary : createEmptySummary(),
|
|
2047
2087
|
status: "in_progress",
|
|
2048
|
-
errors: [],
|
|
2049
|
-
|
|
2088
|
+
errors: continuation ? [...continuation.errors] : [],
|
|
2089
|
+
// A continued session was announced by its first part; announcing it
|
|
2090
|
+
// again would reset a streaming receiver's copy.
|
|
2091
|
+
sessionStarted: Boolean(continuation),
|
|
2092
|
+
sequenceOffset: continuation ? continuation.nextSequence - 1 : 0,
|
|
2093
|
+
part: continuation ? continuation.part + 1 : 1
|
|
2050
2094
|
};
|
|
2051
2095
|
if (cfg.sink.type === "file") {
|
|
2052
2096
|
const baseDir = cfg.sink.baseDir;
|
|
@@ -2106,7 +2150,7 @@ async function startStreamingSession(session, agentRuntime) {
|
|
|
2106
2150
|
}
|
|
2107
2151
|
function recordTraceEvent(session, event) {
|
|
2108
2152
|
if (!session) return void 0;
|
|
2109
|
-
const sequence = session.events.length + 1;
|
|
2153
|
+
const sequence = (session.sequenceOffset ?? 0) + session.events.length + 1;
|
|
2110
2154
|
const id = generateEventId(sequence);
|
|
2111
2155
|
const timestampIso = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
2112
2156
|
const status = event.status ?? "success";
|
|
@@ -2296,7 +2340,8 @@ async function finalizeTraceSession(session, params = {}) {
|
|
|
2296
2340
|
summary: session.summary,
|
|
2297
2341
|
events: session.events,
|
|
2298
2342
|
status: status2,
|
|
2299
|
-
errors: session.errors
|
|
2343
|
+
errors: session.errors,
|
|
2344
|
+
...(session.part ?? 1) > 1 ? { continuation: { part: session.part, firstSequence: (session.sequenceOffset ?? 0) + 1 } } : {}
|
|
2300
2345
|
});
|
|
2301
2346
|
const payloadForSink = buildPayload(initialStatus);
|
|
2302
2347
|
let sinkFailed = false;
|
|
@@ -2353,7 +2398,17 @@ async function finalizeTraceSession(session, params = {}) {
|
|
|
2353
2398
|
if (sink.type === "file" && session.fileSessionDir) {
|
|
2354
2399
|
try {
|
|
2355
2400
|
const filePath = path__default.default.join(session.fileSessionDir, "trace.session.json");
|
|
2356
|
-
|
|
2401
|
+
let filePayload = finalPayload;
|
|
2402
|
+
if (finalPayload.continuation) {
|
|
2403
|
+
try {
|
|
2404
|
+
const previous = JSON.parse(await fs__default.default.promises.readFile(filePath, "utf8"));
|
|
2405
|
+
const earlier = (previous.events ?? []).filter((event) => event.sequence < finalPayload.continuation.firstSequence);
|
|
2406
|
+
filePayload = { ...finalPayload, events: [...earlier, ...finalPayload.events] };
|
|
2407
|
+
delete filePayload.continuation;
|
|
2408
|
+
} catch {
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
await fs__default.default.promises.writeFile(filePath, JSON.stringify(filePayload, null, 2), "utf8");
|
|
2357
2412
|
} catch (err) {
|
|
2358
2413
|
sinkFailed = true;
|
|
2359
2414
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4792,6 +4847,207 @@ ${append}`;
|
|
|
4792
4847
|
};
|
|
4793
4848
|
}
|
|
4794
4849
|
|
|
4850
|
+
// src/utils/traceDecisions.ts
|
|
4851
|
+
var TRACED_KEY = "__outcomeTraced";
|
|
4852
|
+
function waitedMs(from, to) {
|
|
4853
|
+
if (!from || !to) return void 0;
|
|
4854
|
+
const ms = Date.parse(to) - Date.parse(from);
|
|
4855
|
+
return Number.isFinite(ms) && ms >= 0 ? ms : void 0;
|
|
4856
|
+
}
|
|
4857
|
+
function sameJson(a, b) {
|
|
4858
|
+
try {
|
|
4859
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
4860
|
+
} catch {
|
|
4861
|
+
return false;
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
function recordApprovalRequested(session, entry) {
|
|
4865
|
+
if (!session) return;
|
|
4866
|
+
const logData = session.resolvedConfig.logData;
|
|
4867
|
+
const sections = [
|
|
4868
|
+
{
|
|
4869
|
+
kind: "metadata",
|
|
4870
|
+
label: "Approval",
|
|
4871
|
+
data: {
|
|
4872
|
+
approvalId: entry.id,
|
|
4873
|
+
toolCallId: entry.toolCallId,
|
|
4874
|
+
status: "pending",
|
|
4875
|
+
requestedAt: entry.requestedAt,
|
|
4876
|
+
...entry.metadata?.prompt !== void 0 ? { prompt: entry.metadata.prompt } : {}
|
|
4877
|
+
}
|
|
4878
|
+
}
|
|
4879
|
+
];
|
|
4880
|
+
if (logData) {
|
|
4881
|
+
sections.push({ kind: "tool_call", label: "Arguments to approve", tool: entry.toolName, arguments: sanitizeTracePayload(entry.args) });
|
|
4882
|
+
}
|
|
4883
|
+
recordTraceEvent(session, {
|
|
4884
|
+
type: "tool_approval",
|
|
4885
|
+
label: `Approval requested \xB7 ${entry.toolName}`,
|
|
4886
|
+
timestamp: entry.requestedAt,
|
|
4887
|
+
status: "pending",
|
|
4888
|
+
actor: { scope: "agent", name: entry.toolName, role: "approval_request" },
|
|
4889
|
+
sections
|
|
4890
|
+
});
|
|
4891
|
+
}
|
|
4892
|
+
function recordHumanDecisions(session, state) {
|
|
4893
|
+
if (!session) return;
|
|
4894
|
+
const logData = session.resolvedConfig.logData;
|
|
4895
|
+
for (const entry of state.pendingApprovals ?? []) {
|
|
4896
|
+
if (!entry.decidedAt || entry.metadata?.[TRACED_KEY]) continue;
|
|
4897
|
+
if (entry.status !== "approved" && entry.status !== "rejected") continue;
|
|
4898
|
+
const approved = entry.status === "approved";
|
|
4899
|
+
const edited = approved && entry.approvedArgs !== void 0 && !sameJson(entry.approvedArgs, entry.args);
|
|
4900
|
+
const sections = [
|
|
4901
|
+
{
|
|
4902
|
+
kind: "metadata",
|
|
4903
|
+
label: "Decision",
|
|
4904
|
+
data: {
|
|
4905
|
+
approvalId: entry.id,
|
|
4906
|
+
toolCallId: entry.toolCallId,
|
|
4907
|
+
decision: entry.status,
|
|
4908
|
+
...entry.decidedBy ? { decidedBy: entry.decidedBy } : {},
|
|
4909
|
+
...entry.comment ? { comment: entry.comment } : {},
|
|
4910
|
+
requestedAt: entry.requestedAt,
|
|
4911
|
+
decidedAt: entry.decidedAt,
|
|
4912
|
+
...waitedMs(entry.requestedAt, entry.decidedAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.decidedAt) } : {},
|
|
4913
|
+
...edited ? { argumentsEdited: true } : {}
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
];
|
|
4917
|
+
if (logData) {
|
|
4918
|
+
sections.push({ kind: "tool_call", label: "Requested arguments", tool: entry.toolName, arguments: sanitizeTracePayload(entry.args) });
|
|
4919
|
+
if (edited) {
|
|
4920
|
+
sections.push({ kind: "tool_call", label: "Approved arguments", tool: entry.toolName, arguments: sanitizeTracePayload(entry.approvedArgs) });
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
recordTraceEvent(session, {
|
|
4924
|
+
type: "tool_approval",
|
|
4925
|
+
label: `${approved ? "Approved" : "Rejected"} \xB7 ${entry.toolName}`,
|
|
4926
|
+
timestamp: entry.decidedAt,
|
|
4927
|
+
durationMs: waitedMs(entry.requestedAt, entry.decidedAt),
|
|
4928
|
+
status: "success",
|
|
4929
|
+
actor: { scope: "human", name: entry.decidedBy || "reviewer", role: "approver" },
|
|
4930
|
+
sections
|
|
4931
|
+
});
|
|
4932
|
+
entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
|
|
4933
|
+
}
|
|
4934
|
+
for (const entry of state.pendingUserQuestions ?? []) {
|
|
4935
|
+
if (!entry.answeredAt || entry.metadata?.[TRACED_KEY]) continue;
|
|
4936
|
+
if (entry.status !== "answered" && entry.status !== "cancelled") continue;
|
|
4937
|
+
const clientTool = readClientTool(entry);
|
|
4938
|
+
if (clientTool) {
|
|
4939
|
+
recordClientToolResult(session, entry, clientTool, state.toolHistory);
|
|
4940
|
+
entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
|
|
4941
|
+
continue;
|
|
4942
|
+
}
|
|
4943
|
+
const cancelled = entry.status === "cancelled";
|
|
4944
|
+
const data = {
|
|
4945
|
+
questionId: entry.id,
|
|
4946
|
+
toolCallId: entry.toolCallId,
|
|
4947
|
+
status: entry.status,
|
|
4948
|
+
...entry.answeredBy ? { answeredBy: entry.answeredBy } : {},
|
|
4949
|
+
...entry.notes ? { notes: entry.notes } : {},
|
|
4950
|
+
requestedAt: entry.requestedAt,
|
|
4951
|
+
answeredAt: entry.answeredAt,
|
|
4952
|
+
...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
|
|
4953
|
+
};
|
|
4954
|
+
const sections = [{ kind: "metadata", label: "Answer", data }];
|
|
4955
|
+
if (logData) {
|
|
4956
|
+
sections.push({
|
|
4957
|
+
kind: "metadata",
|
|
4958
|
+
label: "Questions and answers",
|
|
4959
|
+
data: {
|
|
4960
|
+
items: (entry.questions ?? []).map((item) => ({
|
|
4961
|
+
question: item.question,
|
|
4962
|
+
...item.header ? { header: item.header } : {},
|
|
4963
|
+
answer: sanitizeTracePayload(entry.answers?.[item.question] ?? (item.header ? entry.answers?.[item.header] : void 0) ?? null)
|
|
4964
|
+
}))
|
|
4965
|
+
}
|
|
4966
|
+
});
|
|
4967
|
+
}
|
|
4968
|
+
recordTraceEvent(session, {
|
|
4969
|
+
type: "user_question",
|
|
4970
|
+
label: cancelled ? "Question cancelled" : "Answer from user",
|
|
4971
|
+
timestamp: entry.answeredAt,
|
|
4972
|
+
durationMs: waitedMs(entry.requestedAt, entry.answeredAt),
|
|
4973
|
+
status: cancelled ? "skipped" : "success",
|
|
4974
|
+
actor: { scope: "human", name: entry.answeredBy || "user", role: "user" },
|
|
4975
|
+
sections
|
|
4976
|
+
});
|
|
4977
|
+
entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
|
|
4978
|
+
}
|
|
4979
|
+
}
|
|
4980
|
+
function recordClientToolRequested(session, entry) {
|
|
4981
|
+
if (!session) return;
|
|
4982
|
+
const clientTool = readClientTool(entry);
|
|
4983
|
+
if (!clientTool) return;
|
|
4984
|
+
const sections = [
|
|
4985
|
+
{
|
|
4986
|
+
kind: "metadata",
|
|
4987
|
+
label: "Client tool",
|
|
4988
|
+
data: { questionId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt }
|
|
4989
|
+
}
|
|
4990
|
+
];
|
|
4991
|
+
if (session.resolvedConfig.logData) {
|
|
4992
|
+
sections.push({ kind: "tool_call", label: "Arguments", tool: clientTool.name, arguments: sanitizeTracePayload(clientTool.args) });
|
|
4993
|
+
}
|
|
4994
|
+
recordTraceEvent(session, {
|
|
4995
|
+
type: "tool_call",
|
|
4996
|
+
label: `Tool Execution - ${clientTool.name} (client)`,
|
|
4997
|
+
timestamp: entry.requestedAt,
|
|
4998
|
+
status: "pending",
|
|
4999
|
+
actor: { scope: "client", name: clientTool.name, role: "tool" },
|
|
5000
|
+
sections
|
|
5001
|
+
});
|
|
5002
|
+
}
|
|
5003
|
+
function readClientTool(entry) {
|
|
5004
|
+
const meta = entry.metadata?.clientTool;
|
|
5005
|
+
if (!meta || typeof meta !== "object" || typeof meta.name !== "string") return void 0;
|
|
5006
|
+
return { name: meta.name, args: meta.args };
|
|
5007
|
+
}
|
|
5008
|
+
function recordClientToolResult(session, entry, clientTool, toolHistory) {
|
|
5009
|
+
const step = [...toolHistory ?? []].reverse().find((item) => item?.tool_call_id === entry.toolCallId);
|
|
5010
|
+
const failed = step?.status === "error" || entry.status === "cancelled";
|
|
5011
|
+
const sections = [
|
|
5012
|
+
{
|
|
5013
|
+
kind: "metadata",
|
|
5014
|
+
label: "Client tool",
|
|
5015
|
+
data: {
|
|
5016
|
+
questionId: entry.id,
|
|
5017
|
+
toolCallId: entry.toolCallId,
|
|
5018
|
+
status: failed ? "error" : "answered",
|
|
5019
|
+
...entry.answeredBy ? { answeredBy: entry.answeredBy } : {},
|
|
5020
|
+
requestedAt: entry.requestedAt,
|
|
5021
|
+
answeredAt: entry.answeredAt,
|
|
5022
|
+
...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
|
|
5023
|
+
}
|
|
5024
|
+
}
|
|
5025
|
+
];
|
|
5026
|
+
if (session.resolvedConfig.logData) {
|
|
5027
|
+
sections.push({ kind: "tool_call", label: "Arguments", tool: clientTool.name, arguments: sanitizeTracePayload(clientTool.args) });
|
|
5028
|
+
if (step) {
|
|
5029
|
+
const output = step.rawOutput ?? step.output;
|
|
5030
|
+
sections.push({
|
|
5031
|
+
kind: "tool_result",
|
|
5032
|
+
label: "Result from client",
|
|
5033
|
+
tool: clientTool.name,
|
|
5034
|
+
output: sanitizeTracePayload(output),
|
|
5035
|
+
summary: typeof step.output === "string" ? step.output.slice(0, 2e3) : void 0
|
|
5036
|
+
});
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
const ranMs = typeof step?.durationMs === "number" ? step.durationMs : void 0;
|
|
5040
|
+
recordTraceEvent(session, {
|
|
5041
|
+
type: "tool_call",
|
|
5042
|
+
label: `Tool Execution - ${clientTool.name} (client)`,
|
|
5043
|
+
timestamp: entry.answeredAt,
|
|
5044
|
+
durationMs: waitedMs(entry.requestedAt, entry.answeredAt) ?? ranMs,
|
|
5045
|
+
status: failed ? "error" : "success",
|
|
5046
|
+
actor: { scope: "client", name: clientTool.name, role: "tool" },
|
|
5047
|
+
sections
|
|
5048
|
+
});
|
|
5049
|
+
}
|
|
5050
|
+
|
|
4795
5051
|
// src/utils/traceSections.ts
|
|
4796
5052
|
init_content();
|
|
4797
5053
|
function truncate(text, max = 500) {
|
|
@@ -5260,6 +5516,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
5260
5516
|
};
|
|
5261
5517
|
pendingApprovals.push(approvalEntry);
|
|
5262
5518
|
pendingByCallId.set(toolCallId, approvalEntry);
|
|
5519
|
+
recordApprovalRequested(traceSession, approvalEntry);
|
|
5263
5520
|
onEvent?.({ type: "tool_approval", status: "pending", id: approvalEntry.id, toolName: approvalEntry.toolName, toolCallId: approvalEntry.toolCallId, args });
|
|
5264
5521
|
if (host?.has("notification")) {
|
|
5265
5522
|
await host.runObservers("notification", {
|
|
@@ -5523,6 +5780,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
5523
5780
|
if (!pendingApproval) {
|
|
5524
5781
|
throw new Error(`Tool ${toolName} requested approval but no pending approval entry was recorded.`);
|
|
5525
5782
|
}
|
|
5783
|
+
recordApprovalRequested(traceSession, pendingApproval);
|
|
5526
5784
|
awaitingApproval = true;
|
|
5527
5785
|
return {
|
|
5528
5786
|
status: "awaiting_approval",
|
|
@@ -5539,6 +5797,7 @@ function createToolsNode(initialTools, opts) {
|
|
|
5539
5797
|
if (!pendingQuestion) {
|
|
5540
5798
|
throw new Error(`Tool ${toolName} requested a user question but no pending question entry was recorded.`);
|
|
5541
5799
|
}
|
|
5800
|
+
recordClientToolRequested(traceSession, pendingQuestion);
|
|
5542
5801
|
awaitingUserQuestion = true;
|
|
5543
5802
|
if (host?.has("notification")) {
|
|
5544
5803
|
await host.runObservers("notification", {
|
|
@@ -6635,16 +6894,20 @@ function createAskUserQuestionTool(stateRef, config) {
|
|
|
6635
6894
|
});
|
|
6636
6895
|
recordTraceEvent(ctx.__traceSession, {
|
|
6637
6896
|
type: "user_question",
|
|
6638
|
-
label: "
|
|
6897
|
+
label: "Question to user",
|
|
6898
|
+
timestamp: entry.requestedAt,
|
|
6639
6899
|
actor: { scope: "agent", name: "ask_user_question", role: "user_interaction" },
|
|
6640
|
-
status: "
|
|
6900
|
+
status: "pending",
|
|
6641
6901
|
sections: [
|
|
6642
6902
|
{
|
|
6643
6903
|
kind: "metadata",
|
|
6644
6904
|
label: "Pending Question",
|
|
6645
6905
|
data: {
|
|
6646
6906
|
id: entry.id,
|
|
6907
|
+
questionId: entry.id,
|
|
6647
6908
|
toolCallId: entry.toolCallId,
|
|
6909
|
+
status: "pending",
|
|
6910
|
+
requestedAt: entry.requestedAt,
|
|
6648
6911
|
questions: entry.questions,
|
|
6649
6912
|
allowFreeText
|
|
6650
6913
|
}
|
|
@@ -7863,15 +8126,17 @@ function createAgent(opts) {
|
|
|
7863
8126
|
}
|
|
7864
8127
|
const traceSession = state.ctx?.__traceSession;
|
|
7865
8128
|
if (traceSession) {
|
|
8129
|
+
const iterationNumber = (traceSession.summary.eventCounts.agent_iteration ?? 0) + 1;
|
|
7866
8130
|
const iterEvent = recordTraceEvent(traceSession, {
|
|
7867
8131
|
type: "agent_iteration",
|
|
7868
|
-
label: `Iteration ${
|
|
8132
|
+
label: `Iteration ${iterationNumber}`,
|
|
7869
8133
|
actor: { scope: "agent", name: opts.name || "agent", role: "orchestrator" },
|
|
7870
8134
|
parentSpanId: traceSession.rootSpanId
|
|
7871
8135
|
});
|
|
7872
8136
|
if (iterEvent) {
|
|
7873
8137
|
traceSession.currentIterationSpanId = iterEvent.spanId;
|
|
7874
8138
|
}
|
|
8139
|
+
recordHumanDecisions(traceSession, state);
|
|
7875
8140
|
}
|
|
7876
8141
|
if (cancelIfRequested("loop")) break;
|
|
7877
8142
|
const skippingAgent = resumeStage === "tools";
|
|
@@ -8152,7 +8417,7 @@ function createAgent(opts) {
|
|
|
8152
8417
|
}
|
|
8153
8418
|
emit({ type: "progress", ...progress });
|
|
8154
8419
|
};
|
|
8155
|
-
const traceSession = createTraceSession(opts);
|
|
8420
|
+
const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation));
|
|
8156
8421
|
const ctx = {
|
|
8157
8422
|
...input.ctx || {},
|
|
8158
8423
|
__onEvent: onEvent,
|
|
@@ -8160,6 +8425,7 @@ function createAgent(opts) {
|
|
|
8160
8425
|
__onStream: onStream,
|
|
8161
8426
|
__streaming: streamEnabled
|
|
8162
8427
|
};
|
|
8428
|
+
delete ctx.__traceContinuation;
|
|
8163
8429
|
if (traceSession) ctx.__traceSession = traceSession;
|
|
8164
8430
|
delete ctx.__plugins;
|
|
8165
8431
|
delete ctx.__applySystemPromptContribution;
|
|
@@ -8308,10 +8574,17 @@ function createAgent(opts) {
|
|
|
8308
8574
|
}
|
|
8309
8575
|
}
|
|
8310
8576
|
}
|
|
8577
|
+
const pausedForHuman = statusFor(res) === "paused";
|
|
8578
|
+
const midTurn = pausedForHuman || Boolean(res.ctx?.__needsSummarization);
|
|
8311
8579
|
await finalizeTraceSession(traceSession, {
|
|
8312
8580
|
agentRuntime: res.agent || runtime,
|
|
8313
|
-
status: "success"
|
|
8581
|
+
status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success"
|
|
8314
8582
|
});
|
|
8583
|
+
if (traceSession && midTurn) {
|
|
8584
|
+
res.ctx = { ...res.ctx || {}, __traceContinuation: traceContinuationOf(traceSession) };
|
|
8585
|
+
} else if (res.ctx && "__traceContinuation" in res.ctx) {
|
|
8586
|
+
delete res.ctx.__traceContinuation;
|
|
8587
|
+
}
|
|
8315
8588
|
const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
|
|
8316
8589
|
const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
|
|
8317
8590
|
const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
|
|
@@ -11215,6 +11488,14 @@ ${pluginAppend}`;
|
|
|
11215
11488
|
} else if (lastResult.state) {
|
|
11216
11489
|
lastResult = { ...lastResult, state: { ...lastResult.state, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, messages: rawMessages } };
|
|
11217
11490
|
}
|
|
11491
|
+
if (lastResult.state) {
|
|
11492
|
+
const endCtx = lastResult.state.ctx;
|
|
11493
|
+
if (endCtx?.__traceContinuation && !(endCtx.__awaitingApproval || endCtx.__awaitingUserQuestion || endCtx.__paused)) {
|
|
11494
|
+
const strippedCtx = { ...endCtx };
|
|
11495
|
+
delete strippedCtx.__traceContinuation;
|
|
11496
|
+
lastResult = { ...lastResult, state: { ...lastResult.state, ctx: strippedCtx } };
|
|
11497
|
+
}
|
|
11498
|
+
}
|
|
11218
11499
|
if (skillsEnabled && lastResult.state) {
|
|
11219
11500
|
const persisted = skillStateFromRegistry(toolSet.skillRegistryRef);
|
|
11220
11501
|
if (persisted) {
|
|
@@ -19539,6 +19820,7 @@ exports.prepareStrictToolMenu = prepareStrictToolMenu;
|
|
|
19539
19820
|
exports.promptInjectionGuard = promptInjectionGuard;
|
|
19540
19821
|
exports.rateLimit = rateLimit;
|
|
19541
19822
|
exports.readMemoryFacts = readMemoryFacts;
|
|
19823
|
+
exports.readTraceContinuation = readTraceContinuation;
|
|
19542
19824
|
exports.redactText = redactText;
|
|
19543
19825
|
exports.regexGuardrail = regexGuardrail;
|
|
19544
19826
|
exports.regexRule = regexRule;
|
|
@@ -19575,6 +19857,7 @@ exports.toStrictCompatible = toStrictCompatible;
|
|
|
19575
19857
|
exports.toStrictToolSchema = toStrictToolSchema;
|
|
19576
19858
|
exports.tokenize = tokenize;
|
|
19577
19859
|
exports.toolPolicy = toolPolicy;
|
|
19860
|
+
exports.traceContinuationOf = traceContinuationOf;
|
|
19578
19861
|
exports.traceSessionToOtlp = traceSessionToOtlp;
|
|
19579
19862
|
exports.validateReasoningConfig = validateReasoningConfig;
|
|
19580
19863
|
exports.validateToolArgs = validateToolArgs;
|