@dudousxd/nestjs-agent-core 0.4.0 → 0.6.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 +106 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +208 -2
- package/dist/index.d.ts +208 -2
- package/dist/index.js +101 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var AGENT_DEPS_FACTORY = Symbol.for("@dudousxd/nestjs-agent:deps-factory");
|
|
|
21
21
|
var AGENT_PROMPT_CONTRIBUTORS = Symbol.for("@dudousxd/nestjs-agent:prompt-contributors");
|
|
22
22
|
var AGENT_ACTOR_DIRECTORY = Symbol.for("@dudousxd/nestjs-agent:actor-directory");
|
|
23
23
|
var AGENT_ATTACHMENT_STAGING = Symbol.for("@dudousxd/nestjs-agent:attachment-staging");
|
|
24
|
+
var AGENT_APPROVAL_PORT = Symbol.for("@dudousxd/nestjs-agent:approval-port");
|
|
24
25
|
|
|
25
26
|
// src/spi/token-stream-sink.ts
|
|
26
27
|
var AgentStreamError = class extends Error {
|
|
@@ -324,6 +325,9 @@ var DefaultRolesPolicy = class {
|
|
|
324
325
|
}
|
|
325
326
|
};
|
|
326
327
|
|
|
328
|
+
// src/agent-loop.ts
|
|
329
|
+
import { createHash } from "node:crypto";
|
|
330
|
+
|
|
327
331
|
// src/diagnostics.ts
|
|
328
332
|
import { emit } from "@dudousxd/nestjs-diagnostics";
|
|
329
333
|
function publishAgentRunStarted(payload) {
|
|
@@ -358,6 +362,20 @@ function publishAgentRetrieved(payload) {
|
|
|
358
362
|
emit("agent", "retrieved", payload);
|
|
359
363
|
}
|
|
360
364
|
__name(publishAgentRetrieved, "publishAgentRetrieved");
|
|
365
|
+
var AGENT_DIAGNOSTIC_EVENTS = [
|
|
366
|
+
"run.started",
|
|
367
|
+
"message",
|
|
368
|
+
"tool-call",
|
|
369
|
+
"quota.exceeded",
|
|
370
|
+
"run.finished",
|
|
371
|
+
"run.failed",
|
|
372
|
+
"delegated",
|
|
373
|
+
"retrieved"
|
|
374
|
+
];
|
|
375
|
+
function agentDiagnosticKey(event) {
|
|
376
|
+
return `agent:${event}`;
|
|
377
|
+
}
|
|
378
|
+
__name(agentDiagnosticKey, "agentDiagnosticKey");
|
|
361
379
|
|
|
362
380
|
// src/agent-loop.ts
|
|
363
381
|
function resolveCostUsd(usage, reportedCostUsd, price) {
|
|
@@ -436,7 +454,7 @@ var ToolTimeoutError = class ToolTimeoutError2 extends Error {
|
|
|
436
454
|
this.name = "ToolTimeoutError";
|
|
437
455
|
}
|
|
438
456
|
};
|
|
439
|
-
function
|
|
457
|
+
function withToolTimeout(work, ms, toolName) {
|
|
440
458
|
return new Promise((resolve, reject) => {
|
|
441
459
|
const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);
|
|
442
460
|
work.then((value) => {
|
|
@@ -448,7 +466,7 @@ function withTimeout(work, ms, toolName) {
|
|
|
448
466
|
});
|
|
449
467
|
});
|
|
450
468
|
}
|
|
451
|
-
__name(
|
|
469
|
+
__name(withToolTimeout, "withToolTimeout");
|
|
452
470
|
function parseFollowUps(text, count) {
|
|
453
471
|
const source = text.match(/\[[\s\S]*\]/)?.[0] ?? text;
|
|
454
472
|
try {
|
|
@@ -553,6 +571,19 @@ async function runAgentLoop(deps, input, hooks) {
|
|
|
553
571
|
agentName: input.agentName
|
|
554
572
|
} : {}
|
|
555
573
|
});
|
|
574
|
+
const startedAt = await hooks.step("run:started-at", () => Promise.resolve(Date.now()));
|
|
575
|
+
await hooks.step("persist:run:start", async () => {
|
|
576
|
+
const promptHash = createHash("sha256").update(system).digest("hex");
|
|
577
|
+
await deps.store.recordRunStart?.({
|
|
578
|
+
runId: hooks.runId,
|
|
579
|
+
threadId: input.threadId,
|
|
580
|
+
actorRef: input.actor.id,
|
|
581
|
+
...input.agentName !== void 0 ? {
|
|
582
|
+
agentName: input.agentName
|
|
583
|
+
} : {},
|
|
584
|
+
promptHash
|
|
585
|
+
});
|
|
586
|
+
});
|
|
556
587
|
let injectedPassages;
|
|
557
588
|
if (deps.retriever !== void 0) {
|
|
558
589
|
const retriever = deps.retriever;
|
|
@@ -586,13 +617,25 @@ ${buildContextBlock(passages)}`;
|
|
|
586
617
|
kind: "step-start"
|
|
587
618
|
}));
|
|
588
619
|
});
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
620
|
+
let turn;
|
|
621
|
+
if (hooks.dispatchLlm) {
|
|
622
|
+
turn = await hooks.dispatchLlm(i, {
|
|
623
|
+
...input.agentName !== void 0 ? {
|
|
624
|
+
agentName: input.agentName
|
|
625
|
+
} : {},
|
|
626
|
+
system,
|
|
627
|
+
messages: modelMessages,
|
|
628
|
+
actor: input.actor
|
|
629
|
+
});
|
|
630
|
+
} else {
|
|
631
|
+
const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
|
|
632
|
+
turn = await hooks.step(`llm:${i}`, () => deps.model.runTurn({
|
|
633
|
+
system,
|
|
634
|
+
messages: modelMessages,
|
|
635
|
+
tools,
|
|
636
|
+
sink: writer
|
|
637
|
+
}));
|
|
638
|
+
}
|
|
596
639
|
const resolvedModelId = turn.modelId ?? deps.modelId ?? "unknown";
|
|
597
640
|
const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));
|
|
598
641
|
const toolCallsWithKind = turn.toolCalls.map((call) => ({
|
|
@@ -767,6 +810,7 @@ ${buildContextBlock(passages)}`;
|
|
|
767
810
|
});
|
|
768
811
|
continue;
|
|
769
812
|
}
|
|
813
|
+
let deciderRef = input.actor.id;
|
|
770
814
|
if (toolType === "action") {
|
|
771
815
|
await hooks.step(`persist:toolcall:${call.id}`, () => deps.store.recordToolCall({
|
|
772
816
|
toolCallId: call.id,
|
|
@@ -777,10 +821,12 @@ ${buildContextBlock(passages)}`;
|
|
|
777
821
|
status: "pending_approval"
|
|
778
822
|
}));
|
|
779
823
|
const decision = await hooks.awaitApproval(call, ctx);
|
|
824
|
+
deciderRef = decision.executedByRef ?? input.actor.id;
|
|
780
825
|
if (!decision.approved) {
|
|
781
826
|
await hooks.step(`persist:toolreject:${call.id}`, () => deps.store.updateToolCall({
|
|
782
827
|
toolCallId: call.id,
|
|
783
828
|
status: "rejected",
|
|
829
|
+
executedByRef: deciderRef,
|
|
784
830
|
...decision.reason !== void 0 ? {
|
|
785
831
|
error: decision.reason
|
|
786
832
|
} : {}
|
|
@@ -812,18 +858,43 @@ ${buildContextBlock(passages)}`;
|
|
|
812
858
|
status: "auto_executed"
|
|
813
859
|
}));
|
|
814
860
|
}
|
|
815
|
-
const
|
|
861
|
+
const startedAt2 = Date.now();
|
|
816
862
|
try {
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
863
|
+
let output;
|
|
864
|
+
if (hooks.dispatchTool) {
|
|
865
|
+
const stepCtx = {
|
|
866
|
+
actor: input.actor,
|
|
867
|
+
threadId: input.threadId,
|
|
868
|
+
runId: hooks.runId,
|
|
869
|
+
requestId: hooks.runId,
|
|
870
|
+
...input.agentName !== void 0 ? {
|
|
871
|
+
agentName: input.agentName
|
|
872
|
+
} : {},
|
|
873
|
+
...input.pageContext !== void 0 ? {
|
|
874
|
+
pageContext: input.pageContext
|
|
875
|
+
} : {}
|
|
876
|
+
};
|
|
877
|
+
const envelope = {
|
|
878
|
+
toolName: call.name,
|
|
879
|
+
input: call.input,
|
|
880
|
+
ctx: stepCtx,
|
|
881
|
+
...deps.toolTimeoutMs !== void 0 ? {
|
|
882
|
+
timeoutMs: deps.toolTimeoutMs
|
|
883
|
+
} : {}
|
|
884
|
+
};
|
|
885
|
+
output = await hooks.dispatchTool(call, envelope);
|
|
886
|
+
} else {
|
|
887
|
+
const invocation = hooks.step(`tool:${call.id}`, () => deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy));
|
|
888
|
+
output = deps.toolTimeoutMs !== void 0 ? await withToolTimeout(invocation, deps.toolTimeoutMs, call.name) : await invocation;
|
|
889
|
+
}
|
|
890
|
+
const executionMs = Date.now() - startedAt2;
|
|
820
891
|
await hooks.step(`persist:toolexec:${call.id}`, () => deps.store.updateToolCall({
|
|
821
892
|
toolCallId: call.id,
|
|
822
893
|
status: "executed",
|
|
823
894
|
output,
|
|
824
895
|
executionMs,
|
|
825
896
|
...toolType === "action" ? {
|
|
826
|
-
executedByRef:
|
|
897
|
+
executedByRef: deciderRef
|
|
827
898
|
} : {}
|
|
828
899
|
}));
|
|
829
900
|
results.push({
|
|
@@ -839,7 +910,10 @@ ${buildContextBlock(passages)}`;
|
|
|
839
910
|
durationMs: executionMs
|
|
840
911
|
});
|
|
841
912
|
} catch (error) {
|
|
842
|
-
|
|
913
|
+
if (hooks.isControlFlowError?.(error) === true) {
|
|
914
|
+
throw error;
|
|
915
|
+
}
|
|
916
|
+
const executionMs = Date.now() - startedAt2;
|
|
843
917
|
const message = error instanceof Error ? error.message : String(error);
|
|
844
918
|
await hooks.step(`persist:toolfail:${call.id}`, () => deps.store.updateToolCall({
|
|
845
919
|
toolCallId: call.id,
|
|
@@ -887,6 +961,13 @@ ${buildContextBlock(passages)}`;
|
|
|
887
961
|
if (thread !== null && (thread.title === "" || thread.title === "New chat")) {
|
|
888
962
|
await hooks.step("persist:title", () => deps.store.setTitle(input.threadId, deriveTitle(input.userText)));
|
|
889
963
|
}
|
|
964
|
+
await hooks.step("persist:run:end", async () => {
|
|
965
|
+
await deps.store.recordRunEnd?.({
|
|
966
|
+
runId: hooks.runId,
|
|
967
|
+
status: "completed",
|
|
968
|
+
durationMs: Date.now() - startedAt
|
|
969
|
+
});
|
|
970
|
+
});
|
|
890
971
|
await writer.end();
|
|
891
972
|
publishAgentRunFinished({
|
|
892
973
|
runId: hooks.runId,
|
|
@@ -903,8 +984,10 @@ __name(runAgentLoop, "runAgentLoop");
|
|
|
903
984
|
export {
|
|
904
985
|
AGENT_ACTOR_DIRECTORY,
|
|
905
986
|
AGENT_ACTOR_RESOLVER,
|
|
987
|
+
AGENT_APPROVAL_PORT,
|
|
906
988
|
AGENT_ATTACHMENT_STAGING,
|
|
907
989
|
AGENT_DEPS_FACTORY,
|
|
990
|
+
AGENT_DIAGNOSTIC_EVENTS,
|
|
908
991
|
AGENT_DURABLE_RUNNER,
|
|
909
992
|
AGENT_EMBEDDING_PROVIDER,
|
|
910
993
|
AGENT_GOVERNANCE_QUERIES,
|
|
@@ -928,6 +1011,7 @@ export {
|
|
|
928
1011
|
ToolInputInvalidError,
|
|
929
1012
|
ToolNotFoundError,
|
|
930
1013
|
ToolRegistry,
|
|
1014
|
+
agentDiagnosticKey,
|
|
931
1015
|
bucketByActor,
|
|
932
1016
|
bucketByModel,
|
|
933
1017
|
bucketByThread,
|
|
@@ -946,6 +1030,7 @@ export {
|
|
|
946
1030
|
publishAgentRunStarted,
|
|
947
1031
|
publishAgentToolCall,
|
|
948
1032
|
runAgentLoop,
|
|
949
|
-
seedModelPrices
|
|
1033
|
+
seedModelPrices,
|
|
1034
|
+
withToolTimeout
|
|
950
1035
|
};
|
|
951
1036
|
//# sourceMappingURL=index.js.map
|