@dudousxd/nestjs-agent-core 0.5.0 → 0.7.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.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,10 @@ var DefaultRolesPolicy = class {
324
325
  }
325
326
  };
326
327
 
328
+ // src/agent-loop.ts
329
+ import { createHash } from "node:crypto";
330
+ import { trace } from "@dudousxd/nestjs-diagnostics";
331
+
327
332
  // src/diagnostics.ts
328
333
  import { emit } from "@dudousxd/nestjs-diagnostics";
329
334
  function publishAgentRunStarted(payload) {
@@ -358,6 +363,26 @@ function publishAgentRetrieved(payload) {
358
363
  emit("agent", "retrieved", payload);
359
364
  }
360
365
  __name(publishAgentRetrieved, "publishAgentRetrieved");
366
+ var AGENT_SPAN_EVENTS = [
367
+ "llm.turn",
368
+ "tool.execution",
369
+ "retrieval",
370
+ "follow-ups"
371
+ ];
372
+ var AGENT_DIAGNOSTIC_EVENTS = [
373
+ "run.started",
374
+ "message",
375
+ "tool-call",
376
+ "quota.exceeded",
377
+ "run.finished",
378
+ "run.failed",
379
+ "delegated",
380
+ "retrieved"
381
+ ];
382
+ function agentDiagnosticKey(event) {
383
+ return `agent:${event}`;
384
+ }
385
+ __name(agentDiagnosticKey, "agentDiagnosticKey");
361
386
 
362
387
  // src/agent-loop.ts
363
388
  function resolveCostUsd(usage, reportedCostUsd, price) {
@@ -485,6 +510,39 @@ async function generateFollowUps(model, messages, count) {
485
510
  };
486
511
  }
487
512
  __name(generateFollowUps, "generateFollowUps");
513
+ async function spanned(event, runId, payload, run, summarize) {
514
+ let value;
515
+ await trace("agent", event, async () => {
516
+ value = await run();
517
+ return summarize(value);
518
+ }, payload, {
519
+ traceId: runId
520
+ });
521
+ return value;
522
+ }
523
+ __name(spanned, "spanned");
524
+ function traceLlmTurn(runId, step, run) {
525
+ return spanned("llm.turn", runId, {
526
+ runId,
527
+ step
528
+ }, run, (turn) => ({
529
+ ...turn.modelId !== void 0 ? {
530
+ modelId: turn.modelId
531
+ } : {},
532
+ inputTokens: turn.usage.inputTokens,
533
+ outputTokens: turn.usage.outputTokens,
534
+ textLength: turn.text.length,
535
+ toolCalls: turn.toolCalls.length
536
+ }));
537
+ }
538
+ __name(traceLlmTurn, "traceLlmTurn");
539
+ function traceToolExecution(runId, call, run) {
540
+ return spanned("tool.execution", runId, {
541
+ runId,
542
+ ...call
543
+ }, run, () => ({}));
544
+ }
545
+ __name(traceToolExecution, "traceToolExecution");
488
546
  async function runAgentLoop(deps, input, hooks) {
489
547
  const maxSteps = deps.maxSteps ?? 8;
490
548
  let system = await resolveSystemPrompt(deps, input);
@@ -555,21 +613,30 @@ async function runAgentLoop(deps, input, hooks) {
555
613
  });
556
614
  const startedAt = await hooks.step("run:started-at", () => Promise.resolve(Date.now()));
557
615
  await hooks.step("persist:run:start", async () => {
616
+ const promptHash = createHash("sha256").update(system).digest("hex");
558
617
  await deps.store.recordRunStart?.({
559
618
  runId: hooks.runId,
560
619
  threadId: input.threadId,
561
620
  actorRef: input.actor.id,
562
621
  ...input.agentName !== void 0 ? {
563
622
  agentName: input.agentName
564
- } : {}
623
+ } : {},
624
+ promptHash
565
625
  });
566
626
  });
567
627
  let injectedPassages;
568
628
  if (deps.retriever !== void 0) {
569
629
  const retriever = deps.retriever;
570
- const passages = await hooks.step("retrieve", () => retriever.retrieve(input.userText, {
571
- topK: deps.retrievalTopK ?? 5
572
- }));
630
+ const topK = deps.retrievalTopK ?? 5;
631
+ const passages = await hooks.step("retrieve", () => spanned("retrieval", hooks.runId, {
632
+ runId: hooks.runId,
633
+ queryLength: input.userText.length,
634
+ topK
635
+ }, () => retriever.retrieve(input.userText, {
636
+ topK
637
+ }), (retrieved) => ({
638
+ count: retrieved.length
639
+ })));
573
640
  if (passages.length > 0) {
574
641
  injectedPassages = passages;
575
642
  system = `${system}
@@ -609,12 +676,12 @@ ${buildContextBlock(passages)}`;
609
676
  });
610
677
  } else {
611
678
  const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
612
- turn = await hooks.step(`llm:${i}`, () => deps.model.runTurn({
679
+ turn = await hooks.step(`llm:${i}`, () => traceLlmTurn(hooks.runId, i, () => deps.model.runTurn({
613
680
  system,
614
681
  messages: modelMessages,
615
682
  tools,
616
683
  sink: writer
617
- }));
684
+ })));
618
685
  }
619
686
  const resolvedModelId = turn.modelId ?? deps.modelId ?? "unknown";
620
687
  const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));
@@ -651,13 +718,24 @@ ${buildContextBlock(passages)}`;
651
718
  let followUps;
652
719
  if (isFinalTurn && deps.followUpsCount !== void 0 && deps.followUpsCount > 0) {
653
720
  const count = deps.followUpsCount;
654
- const generated = await hooks.step(`followups:${i}`, () => generateFollowUps(deps.model, [
721
+ const generated = await hooks.step(`followups:${i}`, () => spanned("follow-ups", hooks.runId, {
722
+ runId: hooks.runId,
723
+ step: i,
724
+ count
725
+ }, () => generateFollowUps(deps.model, [
655
726
  ...modelMessages,
656
727
  {
657
728
  role: "assistant",
658
729
  content: turn.text
659
730
  }
660
- ], count));
731
+ ], count), (result) => ({
732
+ followUps: result.followUps.length,
733
+ inputTokens: result.usage.inputTokens,
734
+ outputTokens: result.usage.outputTokens,
735
+ ...result.modelId !== void 0 ? {
736
+ modelId: result.modelId
737
+ } : {}
738
+ })));
661
739
  if (generated.followUps.length > 0) {
662
740
  followUps = generated.followUps;
663
741
  }
@@ -790,6 +868,7 @@ ${buildContextBlock(passages)}`;
790
868
  });
791
869
  continue;
792
870
  }
871
+ let deciderRef = input.actor.id;
793
872
  if (toolType === "action") {
794
873
  await hooks.step(`persist:toolcall:${call.id}`, () => deps.store.recordToolCall({
795
874
  toolCallId: call.id,
@@ -800,10 +879,12 @@ ${buildContextBlock(passages)}`;
800
879
  status: "pending_approval"
801
880
  }));
802
881
  const decision = await hooks.awaitApproval(call, ctx);
882
+ deciderRef = decision.executedByRef ?? input.actor.id;
803
883
  if (!decision.approved) {
804
884
  await hooks.step(`persist:toolreject:${call.id}`, () => deps.store.updateToolCall({
805
885
  toolCallId: call.id,
806
886
  status: "rejected",
887
+ executedByRef: deciderRef,
807
888
  ...decision.reason !== void 0 ? {
808
889
  error: decision.reason
809
890
  } : {}
@@ -861,7 +942,11 @@ ${buildContextBlock(passages)}`;
861
942
  };
862
943
  output = await hooks.dispatchTool(call, envelope);
863
944
  } else {
864
- const invocation = hooks.step(`tool:${call.id}`, () => deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy));
945
+ const invocation = hooks.step(`tool:${call.id}`, () => traceToolExecution(hooks.runId, {
946
+ toolCallId: call.id,
947
+ toolName: call.name,
948
+ toolType
949
+ }, () => deps.registry.invoke(call.name, call.input, ctx, deps.rolesPolicy)));
865
950
  output = deps.toolTimeoutMs !== void 0 ? await withToolTimeout(invocation, deps.toolTimeoutMs, call.name) : await invocation;
866
951
  }
867
952
  const executionMs = Date.now() - startedAt2;
@@ -871,7 +956,7 @@ ${buildContextBlock(passages)}`;
871
956
  output,
872
957
  executionMs,
873
958
  ...toolType === "action" ? {
874
- executedByRef: input.actor.id
959
+ executedByRef: deciderRef
875
960
  } : {}
876
961
  }));
877
962
  results.push({
@@ -961,8 +1046,10 @@ __name(runAgentLoop, "runAgentLoop");
961
1046
  export {
962
1047
  AGENT_ACTOR_DIRECTORY,
963
1048
  AGENT_ACTOR_RESOLVER,
1049
+ AGENT_APPROVAL_PORT,
964
1050
  AGENT_ATTACHMENT_STAGING,
965
1051
  AGENT_DEPS_FACTORY,
1052
+ AGENT_DIAGNOSTIC_EVENTS,
966
1053
  AGENT_DURABLE_RUNNER,
967
1054
  AGENT_EMBEDDING_PROVIDER,
968
1055
  AGENT_GOVERNANCE_QUERIES,
@@ -976,6 +1063,7 @@ export {
976
1063
  AGENT_ROLES_POLICY,
977
1064
  AGENT_RUNNER,
978
1065
  AGENT_SINK,
1066
+ AGENT_SPAN_EVENTS,
979
1067
  AGENT_STORE,
980
1068
  AGENT_TOOL_REGISTRY,
981
1069
  AgentRegistry,
@@ -986,6 +1074,7 @@ export {
986
1074
  ToolInputInvalidError,
987
1075
  ToolNotFoundError,
988
1076
  ToolRegistry,
1077
+ agentDiagnosticKey,
989
1078
  bucketByActor,
990
1079
  bucketByModel,
991
1080
  bucketByThread,
@@ -1005,6 +1094,8 @@ export {
1005
1094
  publishAgentToolCall,
1006
1095
  runAgentLoop,
1007
1096
  seedModelPrices,
1097
+ traceLlmTurn,
1098
+ traceToolExecution,
1008
1099
  withToolTimeout
1009
1100
  };
1010
1101
  //# sourceMappingURL=index.js.map