@dudousxd/nestjs-agent-core 0.45.0 → 0.45.2
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 +173 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +171 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -256,6 +256,8 @@ __export(src_exports, {
|
|
|
256
256
|
toActionProposalView: () => toActionProposalView,
|
|
257
257
|
toolCallApprovalFromRow: () => toolCallApprovalFromRow,
|
|
258
258
|
toolCallContext: () => toolCallContext,
|
|
259
|
+
toolCallUpdateForProposal: () => toolCallUpdateForProposal,
|
|
260
|
+
toolCallUpdateForTransition: () => toolCallUpdateForTransition,
|
|
259
261
|
traceLlmTurn: () => traceLlmTurn,
|
|
260
262
|
traceToolExecution: () => traceToolExecution,
|
|
261
263
|
transitionActionProposalClaim: () => transitionActionProposalClaim,
|
|
@@ -5964,7 +5966,7 @@ function traceToolExecution(runId, call, run) {
|
|
|
5964
5966
|
}
|
|
5965
5967
|
__name(traceToolExecution, "traceToolExecution");
|
|
5966
5968
|
function toModelMessages(messages) {
|
|
5967
|
-
return messages.map((message) => ({
|
|
5969
|
+
return withoutBlankAssistantMessages(messages.map((message) => ({
|
|
5968
5970
|
role: message.role,
|
|
5969
5971
|
content: message.content,
|
|
5970
5972
|
...message.toolCalls !== void 0 ? {
|
|
@@ -5976,9 +5978,17 @@ function toModelMessages(messages) {
|
|
|
5976
5978
|
...message.attachments !== void 0 ? {
|
|
5977
5979
|
attachments: message.attachments
|
|
5978
5980
|
} : {}
|
|
5979
|
-
}));
|
|
5981
|
+
})));
|
|
5980
5982
|
}
|
|
5981
5983
|
__name(toModelMessages, "toModelMessages");
|
|
5984
|
+
function isBlankAssistantMessage(message) {
|
|
5985
|
+
return message.role === "assistant" && message.content.trim().length === 0 && (message.toolCalls?.length ?? 0) === 0 && (message.toolResults?.length ?? 0) === 0;
|
|
5986
|
+
}
|
|
5987
|
+
__name(isBlankAssistantMessage, "isBlankAssistantMessage");
|
|
5988
|
+
function withoutBlankAssistantMessages(messages) {
|
|
5989
|
+
return messages.some(isBlankAssistantMessage) ? messages.filter((message) => !isBlankAssistantMessage(message)) : messages;
|
|
5990
|
+
}
|
|
5991
|
+
__name(withoutBlankAssistantMessages, "withoutBlankAssistantMessages");
|
|
5982
5992
|
function historyContext(input) {
|
|
5983
5993
|
return {
|
|
5984
5994
|
threadId: input.threadId,
|
|
@@ -6010,7 +6020,7 @@ async function loadSelectedHistory(deps, input, hooks) {
|
|
|
6010
6020
|
});
|
|
6011
6021
|
return {
|
|
6012
6022
|
...recorded,
|
|
6013
|
-
messages: settleDanglingToolCalls(recorded.messages)
|
|
6023
|
+
messages: settleDanglingToolCalls(withoutBlankAssistantMessages(recorded.messages))
|
|
6014
6024
|
};
|
|
6015
6025
|
}
|
|
6016
6026
|
__name(loadSelectedHistory, "loadSelectedHistory");
|
|
@@ -7778,13 +7788,18 @@ ${block}`;
|
|
|
7778
7788
|
runId: hooks.runId,
|
|
7779
7789
|
step: i,
|
|
7780
7790
|
count
|
|
7781
|
-
}, () => generateFollowUps(
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7791
|
+
}, () => generateFollowUps(
|
|
7792
|
+
deps.model,
|
|
7793
|
+
// A blank answer is left off: an empty assistant message gets the call refused.
|
|
7794
|
+
turn.text.trim().length > 0 ? [
|
|
7795
|
+
...modelMessages,
|
|
7796
|
+
{
|
|
7797
|
+
role: "assistant",
|
|
7798
|
+
content: turn.text
|
|
7799
|
+
}
|
|
7800
|
+
] : modelMessages,
|
|
7801
|
+
count
|
|
7802
|
+
), (result2) => ({
|
|
7788
7803
|
followUps: result2.followUps.length,
|
|
7789
7804
|
inputTokens: result2.usage.inputTokens,
|
|
7790
7805
|
outputTokens: result2.usage.outputTokens,
|
|
@@ -7852,7 +7867,8 @@ ${block}`;
|
|
|
7852
7867
|
...synthetic.map((entry) => entry.call)
|
|
7853
7868
|
];
|
|
7854
7869
|
const syntheticResults = synthetic.map((entry) => entry.result);
|
|
7855
|
-
const
|
|
7870
|
+
const blankStep = turn.text.trim().length === 0 && messageCalls.length === 0 && syntheticResults.length === 0 && (turn.ui === void 0 || turn.ui.length === 0) && turn.reasoning === void 0 && followUps === void 0;
|
|
7871
|
+
const assistant = await hooks.step(`persist:assistant:${i}`, () => blankStep ? Promise.resolve(null) : deps.store.appendMessage({
|
|
7856
7872
|
threadId: input.threadId,
|
|
7857
7873
|
role: "assistant",
|
|
7858
7874
|
content: turn.text,
|
|
@@ -7898,6 +7914,23 @@ ${block}`;
|
|
|
7898
7914
|
toolResults: syntheticResults
|
|
7899
7915
|
} : {}
|
|
7900
7916
|
};
|
|
7917
|
+
const finishFinalStep = /* @__PURE__ */ __name(() => hooks.step(`stream:step-finish:${i}`, async () => {
|
|
7918
|
+
await writer.write(encodeStreamEvent({
|
|
7919
|
+
kind: "step-finish",
|
|
7920
|
+
usage: turn.usage,
|
|
7921
|
+
costUsd,
|
|
7922
|
+
...turn.reasoningMs !== void 0 ? {
|
|
7923
|
+
reasoningMs: turn.reasoningMs
|
|
7924
|
+
} : {},
|
|
7925
|
+
...stepModel !== void 0 ? {
|
|
7926
|
+
model: stepModel
|
|
7927
|
+
} : {}
|
|
7928
|
+
}));
|
|
7929
|
+
}), "finishFinalStep");
|
|
7930
|
+
if (assistant === null) {
|
|
7931
|
+
await finishFinalStep();
|
|
7932
|
+
break;
|
|
7933
|
+
}
|
|
7901
7934
|
modelMessages.push(assistantMessage);
|
|
7902
7935
|
for (const entry of synthetic) {
|
|
7903
7936
|
const { call, result: result2 } = entry;
|
|
@@ -7931,19 +7964,7 @@ ${block}`;
|
|
|
7931
7964
|
});
|
|
7932
7965
|
}
|
|
7933
7966
|
if (isFinalTurn) {
|
|
7934
|
-
await
|
|
7935
|
-
await writer.write(encodeStreamEvent({
|
|
7936
|
-
kind: "step-finish",
|
|
7937
|
-
usage: turn.usage,
|
|
7938
|
-
costUsd,
|
|
7939
|
-
...turn.reasoningMs !== void 0 ? {
|
|
7940
|
-
reasoningMs: turn.reasoningMs
|
|
7941
|
-
} : {},
|
|
7942
|
-
...stepModel !== void 0 ? {
|
|
7943
|
-
model: stepModel
|
|
7944
|
-
} : {}
|
|
7945
|
-
}));
|
|
7946
|
-
});
|
|
7967
|
+
await finishFinalStep();
|
|
7947
7968
|
break;
|
|
7948
7969
|
}
|
|
7949
7970
|
await haltIfCancelled(hooks, cancellable, `cancel:tools:${i}`);
|
|
@@ -8054,13 +8075,15 @@ ${toolText}`;
|
|
|
8054
8075
|
return;
|
|
8055
8076
|
}
|
|
8056
8077
|
const agent = input.agentName ?? "default";
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8078
|
+
if (lastText.trim().length > 0) {
|
|
8079
|
+
await deps.store.appendMessage({
|
|
8080
|
+
threadId: delivery.threadId,
|
|
8081
|
+
role: "assistant",
|
|
8082
|
+
content: lastText,
|
|
8083
|
+
agentName: agent,
|
|
8084
|
+
runId: hooks.runId
|
|
8085
|
+
});
|
|
8086
|
+
}
|
|
8064
8087
|
await deps.store.updateToolCall({
|
|
8065
8088
|
toolCallId: delivery.toolCallId,
|
|
8066
8089
|
status: "executed",
|
|
@@ -8096,6 +8119,98 @@ ${toolText}`;
|
|
|
8096
8119
|
}
|
|
8097
8120
|
__name(runAgentLoop, "runAgentLoop");
|
|
8098
8121
|
|
|
8122
|
+
// src/action-proposal-tool-call.ts
|
|
8123
|
+
function toolCallUpdateForProposal(proposal) {
|
|
8124
|
+
const audit = proposal.decisionAudit;
|
|
8125
|
+
const toolCallId = proposal.originToolCallId;
|
|
8126
|
+
const decidedBy = {
|
|
8127
|
+
...audit?.actorRef !== void 0 ? {
|
|
8128
|
+
executedByRef: audit.actorRef
|
|
8129
|
+
} : {},
|
|
8130
|
+
...audit?.via !== void 0 ? {
|
|
8131
|
+
decidedVia: audit.via
|
|
8132
|
+
} : {}
|
|
8133
|
+
};
|
|
8134
|
+
switch (proposal.decision) {
|
|
8135
|
+
case "rejected":
|
|
8136
|
+
return {
|
|
8137
|
+
toolCallId,
|
|
8138
|
+
status: "rejected",
|
|
8139
|
+
...decidedBy,
|
|
8140
|
+
...audit?.reason !== void 0 ? {
|
|
8141
|
+
error: storableText2(audit.reason)
|
|
8142
|
+
} : {}
|
|
8143
|
+
};
|
|
8144
|
+
case "expired":
|
|
8145
|
+
return {
|
|
8146
|
+
toolCallId,
|
|
8147
|
+
status: "expired",
|
|
8148
|
+
...audit?.via !== void 0 ? {
|
|
8149
|
+
decidedVia: audit.via
|
|
8150
|
+
} : {}
|
|
8151
|
+
};
|
|
8152
|
+
case "superseded":
|
|
8153
|
+
return {
|
|
8154
|
+
toolCallId,
|
|
8155
|
+
status: "expired",
|
|
8156
|
+
decidedVia: audit?.via ?? "supersession",
|
|
8157
|
+
error: proposal.supersededBy !== void 0 ? `superseded by proposal ${proposal.supersededBy}` : "superseded by a newer proposal"
|
|
8158
|
+
};
|
|
8159
|
+
case "approved": {
|
|
8160
|
+
const execution = proposal.execution;
|
|
8161
|
+
const remember = audit?.remember !== void 0 ? {
|
|
8162
|
+
remember: audit.remember
|
|
8163
|
+
} : {};
|
|
8164
|
+
if (execution?.status === "succeeded") {
|
|
8165
|
+
return {
|
|
8166
|
+
toolCallId,
|
|
8167
|
+
status: "executed",
|
|
8168
|
+
...storableOutput(execution.result) ? {
|
|
8169
|
+
output: execution.result
|
|
8170
|
+
} : {},
|
|
8171
|
+
...decidedBy,
|
|
8172
|
+
...remember
|
|
8173
|
+
};
|
|
8174
|
+
}
|
|
8175
|
+
if (execution?.status === "failed") {
|
|
8176
|
+
return {
|
|
8177
|
+
toolCallId,
|
|
8178
|
+
status: "failed",
|
|
8179
|
+
error: storableText2(execution.error ?? "the approved action failed"),
|
|
8180
|
+
...decidedBy,
|
|
8181
|
+
...remember
|
|
8182
|
+
};
|
|
8183
|
+
}
|
|
8184
|
+
return null;
|
|
8185
|
+
}
|
|
8186
|
+
default:
|
|
8187
|
+
return null;
|
|
8188
|
+
}
|
|
8189
|
+
}
|
|
8190
|
+
__name(toolCallUpdateForProposal, "toolCallUpdateForProposal");
|
|
8191
|
+
function toolCallUpdateForTransition(previous, next) {
|
|
8192
|
+
const update = toolCallUpdateForProposal(next);
|
|
8193
|
+
if (update === null) return null;
|
|
8194
|
+
const before = previous === void 0 ? null : toolCallUpdateForProposal(previous);
|
|
8195
|
+
return before?.status === update.status ? null : update;
|
|
8196
|
+
}
|
|
8197
|
+
__name(toolCallUpdateForTransition, "toolCallUpdateForTransition");
|
|
8198
|
+
function storableOutput(result2) {
|
|
8199
|
+
if (result2 === void 0) return false;
|
|
8200
|
+
let json;
|
|
8201
|
+
try {
|
|
8202
|
+
json = JSON.stringify(result2);
|
|
8203
|
+
} catch {
|
|
8204
|
+
return false;
|
|
8205
|
+
}
|
|
8206
|
+
return json !== void 0 && !/\\u0000|\\ud[89ab][0-9a-f]{2}(?!\\ud[c-f])|(?<!\\ud[89ab][0-9a-f]{2})\\ud[c-f][0-9a-f]{2}/i.test(json);
|
|
8207
|
+
}
|
|
8208
|
+
__name(storableOutput, "storableOutput");
|
|
8209
|
+
function storableText2(text) {
|
|
8210
|
+
return text.replaceAll("\0", "");
|
|
8211
|
+
}
|
|
8212
|
+
__name(storableText2, "storableText");
|
|
8213
|
+
|
|
8099
8214
|
// src/in-memory-action-proposal-store.ts
|
|
8100
8215
|
var import_node_crypto2 = require("crypto");
|
|
8101
8216
|
var InMemoryActionProposalStore = class {
|
|
@@ -8142,9 +8257,19 @@ var InMemoryActionProposalStore = class {
|
|
|
8142
8257
|
status: "not_found"
|
|
8143
8258
|
};
|
|
8144
8259
|
const result2 = transition(row2, this.clock());
|
|
8145
|
-
if (result2.proposal)
|
|
8260
|
+
if (result2.proposal) {
|
|
8261
|
+
this.rows.set(id, snapshotActionProposal(result2.proposal));
|
|
8262
|
+
this.proposalChanged(row2, result2.proposal);
|
|
8263
|
+
}
|
|
8146
8264
|
return result2;
|
|
8147
8265
|
}
|
|
8266
|
+
/**
|
|
8267
|
+
* Called after every proposal transition, with the row before and after — synchronously, so no
|
|
8268
|
+
* reader sees one without the other. {@link InMemoryAgentStore} settles the proposal's tool-call
|
|
8269
|
+
* record here (see `toolCallUpdateForTransition`).
|
|
8270
|
+
*/
|
|
8271
|
+
proposalChanged(_previous, _next) {
|
|
8272
|
+
}
|
|
8148
8273
|
async decideActionProposal(scope, id, command) {
|
|
8149
8274
|
return this.mutate(scope, id, (row2, now) => transitionActionProposalDecision(row2, command, now));
|
|
8150
8275
|
}
|
|
@@ -8225,7 +8350,11 @@ var InMemoryActionProposalStore = class {
|
|
|
8225
8350
|
if (result2.proposal) replacements.push(result2.proposal);
|
|
8226
8351
|
}
|
|
8227
8352
|
this.rows.set(proposal.id, proposal);
|
|
8228
|
-
for (const row2 of replacements)
|
|
8353
|
+
for (const row2 of replacements) {
|
|
8354
|
+
const previous = this.rows.get(row2.id);
|
|
8355
|
+
this.rows.set(row2.id, row2);
|
|
8356
|
+
if (previous) this.proposalChanged(previous, row2);
|
|
8357
|
+
}
|
|
8229
8358
|
return {
|
|
8230
8359
|
status: "created",
|
|
8231
8360
|
proposal: snapshotActionProposal(proposal)
|
|
@@ -8946,6 +9075,15 @@ var InMemoryAgentStore = class extends InMemoryActionProposalStore {
|
|
|
8946
9075
|
return settled;
|
|
8947
9076
|
}
|
|
8948
9077
|
async updateToolCall(input) {
|
|
9078
|
+
this.applyToolCallUpdate(input);
|
|
9079
|
+
}
|
|
9080
|
+
/** An independent proposal moved: its `proposed` tool-call record follows it. */
|
|
9081
|
+
proposalChanged(previous, next) {
|
|
9082
|
+
const update = toolCallUpdateForTransition(previous, next);
|
|
9083
|
+
if (update === null || this.toolCalls.get(update.toolCallId)?.proposalId !== next.id) return;
|
|
9084
|
+
this.applyToolCallUpdate(update);
|
|
9085
|
+
}
|
|
9086
|
+
applyToolCallUpdate(input) {
|
|
8949
9087
|
const row2 = this.toolCalls.get(input.toolCallId);
|
|
8950
9088
|
if (row2 === void 0) {
|
|
8951
9089
|
return;
|
|
@@ -10488,6 +10626,8 @@ __name(createFunctionalTool, "createFunctionalTool");
|
|
|
10488
10626
|
toActionProposalView,
|
|
10489
10627
|
toolCallApprovalFromRow,
|
|
10490
10628
|
toolCallContext,
|
|
10629
|
+
toolCallUpdateForProposal,
|
|
10630
|
+
toolCallUpdateForTransition,
|
|
10491
10631
|
traceLlmTurn,
|
|
10492
10632
|
traceToolExecution,
|
|
10493
10633
|
transitionActionProposalClaim,
|