@dudousxd/nestjs-agent-core 0.3.3 → 0.5.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 +120 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +245 -4
- package/dist/index.d.ts +245 -4
- package/dist/index.js +116 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -21,7 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
AGENT_ACTOR_DIRECTORY: () => AGENT_ACTOR_DIRECTORY,
|
|
24
25
|
AGENT_ACTOR_RESOLVER: () => AGENT_ACTOR_RESOLVER,
|
|
26
|
+
AGENT_ATTACHMENT_STAGING: () => AGENT_ATTACHMENT_STAGING,
|
|
25
27
|
AGENT_DEPS_FACTORY: () => AGENT_DEPS_FACTORY,
|
|
26
28
|
AGENT_DURABLE_RUNNER: () => AGENT_DURABLE_RUNNER,
|
|
27
29
|
AGENT_EMBEDDING_PROVIDER: () => AGENT_EMBEDDING_PROVIDER,
|
|
@@ -64,7 +66,8 @@ __export(index_exports, {
|
|
|
64
66
|
publishAgentRunStarted: () => publishAgentRunStarted,
|
|
65
67
|
publishAgentToolCall: () => publishAgentToolCall,
|
|
66
68
|
runAgentLoop: () => runAgentLoop,
|
|
67
|
-
seedModelPrices: () => seedModelPrices
|
|
69
|
+
seedModelPrices: () => seedModelPrices,
|
|
70
|
+
withToolTimeout: () => withToolTimeout
|
|
68
71
|
});
|
|
69
72
|
module.exports = __toCommonJS(index_exports);
|
|
70
73
|
|
|
@@ -86,6 +89,8 @@ var AGENT_RETRIEVER = Symbol.for("@dudousxd/nestjs-agent:retriever");
|
|
|
86
89
|
var AGENT_EMBEDDING_PROVIDER = Symbol.for("@dudousxd/nestjs-agent:embedding-provider");
|
|
87
90
|
var AGENT_DEPS_FACTORY = Symbol.for("@dudousxd/nestjs-agent:deps-factory");
|
|
88
91
|
var AGENT_PROMPT_CONTRIBUTORS = Symbol.for("@dudousxd/nestjs-agent:prompt-contributors");
|
|
92
|
+
var AGENT_ACTOR_DIRECTORY = Symbol.for("@dudousxd/nestjs-agent:actor-directory");
|
|
93
|
+
var AGENT_ATTACHMENT_STAGING = Symbol.for("@dudousxd/nestjs-agent:attachment-staging");
|
|
89
94
|
|
|
90
95
|
// src/spi/token-stream-sink.ts
|
|
91
96
|
var AgentStreamError = class extends Error {
|
|
@@ -425,6 +430,13 @@ function publishAgentRetrieved(payload) {
|
|
|
425
430
|
__name(publishAgentRetrieved, "publishAgentRetrieved");
|
|
426
431
|
|
|
427
432
|
// src/agent-loop.ts
|
|
433
|
+
function resolveCostUsd(usage, reportedCostUsd, price) {
|
|
434
|
+
if (reportedCostUsd !== void 0) {
|
|
435
|
+
return reportedCostUsd;
|
|
436
|
+
}
|
|
437
|
+
return price === void 0 ? null : estimateCost(usage, price);
|
|
438
|
+
}
|
|
439
|
+
__name(resolveCostUsd, "resolveCostUsd");
|
|
428
440
|
function buildContextBlock(passages) {
|
|
429
441
|
const items = passages.map((passage, index) => {
|
|
430
442
|
const label = passage.source !== void 0 ? ` (${passage.source})` : "";
|
|
@@ -494,7 +506,7 @@ var ToolTimeoutError = class ToolTimeoutError2 extends Error {
|
|
|
494
506
|
this.name = "ToolTimeoutError";
|
|
495
507
|
}
|
|
496
508
|
};
|
|
497
|
-
function
|
|
509
|
+
function withToolTimeout(work, ms, toolName) {
|
|
498
510
|
return new Promise((resolve, reject) => {
|
|
499
511
|
const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);
|
|
500
512
|
work.then((value) => {
|
|
@@ -506,7 +518,7 @@ function withTimeout(work, ms, toolName) {
|
|
|
506
518
|
});
|
|
507
519
|
});
|
|
508
520
|
}
|
|
509
|
-
__name(
|
|
521
|
+
__name(withToolTimeout, "withToolTimeout");
|
|
510
522
|
function parseFollowUps(text, count) {
|
|
511
523
|
const source = text.match(/\[[\s\S]*\]/)?.[0] ?? text;
|
|
512
524
|
try {
|
|
@@ -611,6 +623,17 @@ async function runAgentLoop(deps, input, hooks) {
|
|
|
611
623
|
agentName: input.agentName
|
|
612
624
|
} : {}
|
|
613
625
|
});
|
|
626
|
+
const startedAt = await hooks.step("run:started-at", () => Promise.resolve(Date.now()));
|
|
627
|
+
await hooks.step("persist:run:start", async () => {
|
|
628
|
+
await deps.store.recordRunStart?.({
|
|
629
|
+
runId: hooks.runId,
|
|
630
|
+
threadId: input.threadId,
|
|
631
|
+
actorRef: input.actor.id,
|
|
632
|
+
...input.agentName !== void 0 ? {
|
|
633
|
+
agentName: input.agentName
|
|
634
|
+
} : {}
|
|
635
|
+
});
|
|
636
|
+
});
|
|
614
637
|
let injectedPassages;
|
|
615
638
|
if (deps.retriever !== void 0) {
|
|
616
639
|
const retriever = deps.retriever;
|
|
@@ -629,24 +652,50 @@ ${buildContextBlock(passages)}`;
|
|
|
629
652
|
count: passages.length
|
|
630
653
|
});
|
|
631
654
|
}
|
|
655
|
+
let prices = [];
|
|
656
|
+
if (deps.pricingStore !== void 0) {
|
|
657
|
+
const pricingStore = deps.pricingStore;
|
|
658
|
+
prices = await hooks.step("pricing:list", () => pricingStore.listCurrentPrices());
|
|
659
|
+
}
|
|
660
|
+
const priceByModel = new Map(prices.map((price) => [
|
|
661
|
+
price.modelId,
|
|
662
|
+
price
|
|
663
|
+
]));
|
|
632
664
|
for (let i = 0; i < maxSteps; i += 1) {
|
|
633
665
|
await hooks.step(`stream:step-start:${i}`, async () => {
|
|
634
666
|
await writer.write(encodeStreamEvent({
|
|
635
667
|
kind: "step-start"
|
|
636
668
|
}));
|
|
637
669
|
});
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
670
|
+
let turn;
|
|
671
|
+
if (hooks.dispatchLlm) {
|
|
672
|
+
turn = await hooks.dispatchLlm(i, {
|
|
673
|
+
...input.agentName !== void 0 ? {
|
|
674
|
+
agentName: input.agentName
|
|
675
|
+
} : {},
|
|
676
|
+
system,
|
|
677
|
+
messages: modelMessages,
|
|
678
|
+
actor: input.actor
|
|
679
|
+
});
|
|
680
|
+
} else {
|
|
681
|
+
const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
|
|
682
|
+
turn = await hooks.step(`llm:${i}`, () => deps.model.runTurn({
|
|
683
|
+
system,
|
|
684
|
+
messages: modelMessages,
|
|
685
|
+
tools,
|
|
686
|
+
sink: writer
|
|
687
|
+
}));
|
|
688
|
+
}
|
|
689
|
+
const resolvedModelId = turn.modelId ?? deps.modelId ?? "unknown";
|
|
690
|
+
const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));
|
|
691
|
+
const toolCallsWithKind = turn.toolCalls.map((call) => ({
|
|
692
|
+
...call,
|
|
693
|
+
kind: deps.registry.spec(call.name)?.kind ?? "read"
|
|
644
694
|
}));
|
|
645
695
|
await hooks.step(`persist:usage:${i}`, () => deps.store.recordUsage({
|
|
646
696
|
threadId: input.threadId,
|
|
647
697
|
actorRef: input.actor.id,
|
|
648
|
-
|
|
649
|
-
modelId: turn.modelId ?? deps.modelId ?? "unknown",
|
|
698
|
+
modelId: resolvedModelId,
|
|
650
699
|
purpose: "chat",
|
|
651
700
|
usage: turn.usage,
|
|
652
701
|
// persist the provider's actual cost when reported; the read-model prefers it over pricing
|
|
@@ -694,12 +743,15 @@ ${buildContextBlock(passages)}`;
|
|
|
694
743
|
threadId: input.threadId,
|
|
695
744
|
role: "assistant",
|
|
696
745
|
content: turn.text,
|
|
697
|
-
usage:
|
|
746
|
+
usage: {
|
|
747
|
+
...turn.usage,
|
|
748
|
+
costUsd
|
|
749
|
+
},
|
|
698
750
|
...input.agentName !== void 0 ? {
|
|
699
751
|
agentName: input.agentName
|
|
700
752
|
} : {},
|
|
701
|
-
...
|
|
702
|
-
toolCalls:
|
|
753
|
+
...toolCallsWithKind.length > 0 ? {
|
|
754
|
+
toolCalls: toolCallsWithKind
|
|
703
755
|
} : {},
|
|
704
756
|
...followUps !== void 0 ? {
|
|
705
757
|
followUps
|
|
@@ -708,8 +760,8 @@ ${buildContextBlock(passages)}`;
|
|
|
708
760
|
const assistantMessage = {
|
|
709
761
|
role: "assistant",
|
|
710
762
|
content: turn.text,
|
|
711
|
-
...
|
|
712
|
-
toolCalls:
|
|
763
|
+
...toolCallsWithKind.length > 0 ? {
|
|
764
|
+
toolCalls: toolCallsWithKind
|
|
713
765
|
} : {}
|
|
714
766
|
};
|
|
715
767
|
modelMessages.push(assistantMessage);
|
|
@@ -739,15 +791,17 @@ ${buildContextBlock(passages)}`;
|
|
|
739
791
|
if (isFinalTurn) {
|
|
740
792
|
await hooks.step(`stream:step-finish:${i}`, async () => {
|
|
741
793
|
await writer.write(encodeStreamEvent({
|
|
742
|
-
kind: "step-finish"
|
|
794
|
+
kind: "step-finish",
|
|
795
|
+
usage: turn.usage,
|
|
796
|
+
costUsd
|
|
743
797
|
}));
|
|
744
798
|
});
|
|
745
799
|
break;
|
|
746
800
|
}
|
|
747
801
|
const results = [];
|
|
748
|
-
for (const call of
|
|
802
|
+
for (const call of toolCallsWithKind) {
|
|
749
803
|
const spec = deps.registry.spec(call.name);
|
|
750
|
-
const toolType =
|
|
804
|
+
const toolType = call.kind ?? "read";
|
|
751
805
|
const ctx = {
|
|
752
806
|
actor: input.actor,
|
|
753
807
|
threadId: input.threadId,
|
|
@@ -851,11 +905,36 @@ ${buildContextBlock(passages)}`;
|
|
|
851
905
|
status: "auto_executed"
|
|
852
906
|
}));
|
|
853
907
|
}
|
|
854
|
-
const
|
|
908
|
+
const startedAt2 = Date.now();
|
|
855
909
|
try {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
910
|
+
let output;
|
|
911
|
+
if (hooks.dispatchTool) {
|
|
912
|
+
const stepCtx = {
|
|
913
|
+
actor: input.actor,
|
|
914
|
+
threadId: input.threadId,
|
|
915
|
+
runId: hooks.runId,
|
|
916
|
+
requestId: hooks.runId,
|
|
917
|
+
...input.agentName !== void 0 ? {
|
|
918
|
+
agentName: input.agentName
|
|
919
|
+
} : {},
|
|
920
|
+
...input.pageContext !== void 0 ? {
|
|
921
|
+
pageContext: input.pageContext
|
|
922
|
+
} : {}
|
|
923
|
+
};
|
|
924
|
+
const envelope = {
|
|
925
|
+
toolName: call.name,
|
|
926
|
+
input: call.input,
|
|
927
|
+
ctx: stepCtx,
|
|
928
|
+
...deps.toolTimeoutMs !== void 0 ? {
|
|
929
|
+
timeoutMs: deps.toolTimeoutMs
|
|
930
|
+
} : {}
|
|
931
|
+
};
|
|
932
|
+
output = await hooks.dispatchTool(call, envelope);
|
|
933
|
+
} else {
|
|
934
|
+
const invocation = hooks.step(`tool:${call.id}`, () => deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy));
|
|
935
|
+
output = deps.toolTimeoutMs !== void 0 ? await withToolTimeout(invocation, deps.toolTimeoutMs, call.name) : await invocation;
|
|
936
|
+
}
|
|
937
|
+
const executionMs = Date.now() - startedAt2;
|
|
859
938
|
await hooks.step(`persist:toolexec:${call.id}`, () => deps.store.updateToolCall({
|
|
860
939
|
toolCallId: call.id,
|
|
861
940
|
status: "executed",
|
|
@@ -878,7 +957,10 @@ ${buildContextBlock(passages)}`;
|
|
|
878
957
|
durationMs: executionMs
|
|
879
958
|
});
|
|
880
959
|
} catch (error) {
|
|
881
|
-
|
|
960
|
+
if (hooks.isControlFlowError?.(error) === true) {
|
|
961
|
+
throw error;
|
|
962
|
+
}
|
|
963
|
+
const executionMs = Date.now() - startedAt2;
|
|
882
964
|
const message = error instanceof Error ? error.message : String(error);
|
|
883
965
|
await hooks.step(`persist:toolfail:${call.id}`, () => deps.store.updateToolCall({
|
|
884
966
|
toolCallId: call.id,
|
|
@@ -917,13 +999,22 @@ ${buildContextBlock(passages)}`;
|
|
|
917
999
|
});
|
|
918
1000
|
await hooks.step(`stream:step-finish:${i}`, async () => {
|
|
919
1001
|
await writer.write(encodeStreamEvent({
|
|
920
|
-
kind: "step-finish"
|
|
1002
|
+
kind: "step-finish",
|
|
1003
|
+
usage: turn.usage,
|
|
1004
|
+
costUsd
|
|
921
1005
|
}));
|
|
922
1006
|
});
|
|
923
1007
|
}
|
|
924
1008
|
if (thread !== null && (thread.title === "" || thread.title === "New chat")) {
|
|
925
1009
|
await hooks.step("persist:title", () => deps.store.setTitle(input.threadId, deriveTitle(input.userText)));
|
|
926
1010
|
}
|
|
1011
|
+
await hooks.step("persist:run:end", async () => {
|
|
1012
|
+
await deps.store.recordRunEnd?.({
|
|
1013
|
+
runId: hooks.runId,
|
|
1014
|
+
status: "completed",
|
|
1015
|
+
durationMs: Date.now() - startedAt
|
|
1016
|
+
});
|
|
1017
|
+
});
|
|
927
1018
|
await writer.end();
|
|
928
1019
|
publishAgentRunFinished({
|
|
929
1020
|
runId: hooks.runId,
|
|
@@ -939,7 +1030,9 @@ ${buildContextBlock(passages)}`;
|
|
|
939
1030
|
__name(runAgentLoop, "runAgentLoop");
|
|
940
1031
|
// Annotate the CommonJS export names for ESM import in node:
|
|
941
1032
|
0 && (module.exports = {
|
|
1033
|
+
AGENT_ACTOR_DIRECTORY,
|
|
942
1034
|
AGENT_ACTOR_RESOLVER,
|
|
1035
|
+
AGENT_ATTACHMENT_STAGING,
|
|
943
1036
|
AGENT_DEPS_FACTORY,
|
|
944
1037
|
AGENT_DURABLE_RUNNER,
|
|
945
1038
|
AGENT_EMBEDDING_PROVIDER,
|
|
@@ -982,6 +1075,7 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
982
1075
|
publishAgentRunStarted,
|
|
983
1076
|
publishAgentToolCall,
|
|
984
1077
|
runAgentLoop,
|
|
985
|
-
seedModelPrices
|
|
1078
|
+
seedModelPrices,
|
|
1079
|
+
withToolTimeout
|
|
986
1080
|
});
|
|
987
1081
|
//# sourceMappingURL=index.cjs.map
|