@dudousxd/nestjs-agent-core 0.15.1 → 0.15.3

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 CHANGED
@@ -56,6 +56,7 @@ __export(index_exports, {
56
56
  DEFAULT_MAX_FACT_CHARS: () => DEFAULT_MAX_FACT_CHARS,
57
57
  DEFAULT_MAX_MEMORIES: () => DEFAULT_MAX_MEMORIES,
58
58
  DEFAULT_MAX_SKILLS: () => DEFAULT_MAX_SKILLS,
59
+ DEFAULT_REFUSAL_REASON: () => DEFAULT_REFUSAL_REASON,
59
60
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION: () => DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
60
61
  DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS: () => DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
61
62
  DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS: () => DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
@@ -154,6 +155,7 @@ __export(index_exports, {
154
155
  skillInputSchema: () => skillInputSchema,
155
156
  skillToolDefinition: () => skillToolDefinition,
156
157
  skillWriteVerdict: () => skillWriteVerdict,
158
+ stampToolKinds: () => stampToolKinds,
157
159
  staticSkillProvider: () => staticSkillProvider,
158
160
  summarizeWithModel: () => summarizeWithModel,
159
161
  tenantScope: () => tenantScope,
@@ -2615,6 +2617,16 @@ async function structureAnswer(schema, deps, input, hooks, messages, step) {
2615
2617
  throw new StructuredOutputError(issues, text, maxAttempts);
2616
2618
  }
2617
2619
  __name(structureAnswer, "structureAnswer");
2620
+ function stampToolKinds(result, deps) {
2621
+ return {
2622
+ ...result,
2623
+ toolCalls: result.toolCalls.map((call) => call.kind === void 0 ? {
2624
+ ...call,
2625
+ kind: declaredKind(deps, call.name)
2626
+ } : call)
2627
+ };
2628
+ }
2629
+ __name(stampToolKinds, "stampToolKinds");
2618
2630
  function declaredKind(deps, name) {
2619
2631
  if (deps.ask === true && name === ASK_TOOL_NAME) {
2620
2632
  return "ask";
@@ -2815,7 +2827,7 @@ async function claimToolCall(turn, call) {
2815
2827
  const { deps, input, hooks, messageId } = turn;
2816
2828
  const persisted = await hooks.step(`persist:toolcall:${call.id}`, async () => {
2817
2829
  const spec = deps.registry.spec(call.name);
2818
- const kind = declaredKind(deps, call.name);
2830
+ const kind = call.kind ?? declaredKind(deps, call.name);
2819
2831
  const awaitsHuman = kind === "action" || kind === "ask";
2820
2832
  await deps.store.recordToolCall({
2821
2833
  toolCallId: call.id,
@@ -3235,15 +3247,58 @@ async function runClaimedToolCall(turn, claimed) {
3235
3247
  name: call.name,
3236
3248
  output: {
3237
3249
  rejected: true,
3238
- reason: decision.reason ?? "rejected by user"
3250
+ reason: decision.reason ?? DEFAULT_REFUSAL_REASON
3239
3251
  },
3240
- error: "rejected"
3252
+ denied: true,
3253
+ // What the MODEL is told. It used to be the bare word `rejected`, which names no actor and
3254
+ // reads exactly like a tool that blew up — so the answer that followed would speculate about
3255
+ // causes ("the key may not exist", "there may be permission restrictions") and offer to try
3256
+ // again. A person's decision is not a fault to diagnose, so this says who decided, that
3257
+ // nothing ran, and what not to do next.
3258
+ error: refusalNarrative(decision.reason)
3241
3259
  };
3242
3260
  }
3243
3261
  }
3244
3262
  return recordToolOutcome(turn, claimed, await invokeClaimedTool(turn, claimed), deciderRef);
3245
3263
  }
3246
3264
  __name(runClaimedToolCall, "runClaimedToolCall");
3265
+ function outputFrame(result) {
3266
+ if (result.denied === true) {
3267
+ const reason = refusalReason(result);
3268
+ return {
3269
+ kind: "tool-output-denied",
3270
+ id: result.id,
3271
+ ...reason !== void 0 ? {
3272
+ reason
3273
+ } : {}
3274
+ };
3275
+ }
3276
+ return result.error !== void 0 ? {
3277
+ kind: "tool-output-error",
3278
+ id: result.id,
3279
+ error: result.error
3280
+ } : {
3281
+ kind: "tool-output",
3282
+ id: result.id,
3283
+ output: result.output
3284
+ };
3285
+ }
3286
+ __name(outputFrame, "outputFrame");
3287
+ function refusalReason(result) {
3288
+ const { output } = result;
3289
+ if (output !== null && typeof output === "object" && "reason" in output) {
3290
+ const reason = output.reason;
3291
+ return typeof reason === "string" && reason !== DEFAULT_REFUSAL_REASON ? reason : void 0;
3292
+ }
3293
+ return void 0;
3294
+ }
3295
+ __name(refusalReason, "refusalReason");
3296
+ var DEFAULT_REFUSAL_REASON = "rejected by user";
3297
+ function refusalNarrative(reason) {
3298
+ const base = "The person was asked to approve this action and declined it. Nothing ran and nothing changed. This is their decision, not an error, a missing record or a permissions problem \u2014 do not explain it as one, do not guess at causes, and do not run this action again or reach for another way to do the same thing. Acknowledge the decision and ask what they would like instead.";
3299
+ return reason === void 0 ? base : `${base} They said: ${reason}`;
3300
+ }
3301
+ __name(refusalNarrative, "refusalNarrative");
3247
3302
  async function invokeClaimedToolsTogether(turn, parallel, claimed) {
3248
3303
  const settled = await parallel(claimed.map((entry) => () => invokeClaimedTool(turn, entry)));
3249
3304
  for (const outcome of settled) {
@@ -3479,12 +3534,12 @@ ${block}`;
3479
3534
  writer
3480
3535
  }) : void 0;
3481
3536
  const buffer = gateMode === "whole" ? createFrameBuffer() : void 0;
3482
- const result = await traceLlmTurn(hooks.runId, i, () => deps.model.runTurn({
3537
+ const result = stampToolKinds(await traceLlmTurn(hooks.runId, i, () => deps.model.runTurn({
3483
3538
  system: prompt.system,
3484
3539
  messages: prompt.messages,
3485
3540
  tools,
3486
3541
  sink: incremental?.writer ?? buffer?.writer ?? writer
3487
- }));
3542
+ })), deps);
3488
3543
  if (incremental !== void 0) {
3489
3544
  await incremental.settled();
3490
3545
  const refusal = incremental.rejection();
@@ -3543,7 +3598,7 @@ ${block}`;
3543
3598
  const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));
3544
3599
  const toolCallsWithKind = turn.toolCalls.map((call) => ({
3545
3600
  ...call,
3546
- kind: declaredKind(deps, call.name)
3601
+ kind: call.kind ?? declaredKind(deps, call.name)
3547
3602
  }));
3548
3603
  await hooks.step(`persist:usage:${i}`, () => deps.store.recordUsage({
3549
3604
  threadId: input.threadId,
@@ -3775,15 +3830,7 @@ ${block}`;
3775
3830
  await hooks.step(`stream:tool-outputs:${i}`, async () => {
3776
3831
  await deps.store.setMessageToolResults(assistant.id, settledResults);
3777
3832
  for (const result of results) {
3778
- await writer.write(encodeStreamEvent(result.error !== void 0 ? {
3779
- kind: "tool-output-error",
3780
- id: result.id,
3781
- error: result.error
3782
- } : {
3783
- kind: "tool-output",
3784
- id: result.id,
3785
- output: result.output
3786
- }));
3833
+ await writer.write(encodeStreamEvent(outputFrame(result)));
3787
3834
  }
3788
3835
  });
3789
3836
  await hooks.step(`stream:step-finish:${i}`, async () => {
@@ -3882,6 +3929,7 @@ __name(runAgentLoop, "runAgentLoop");
3882
3929
  DEFAULT_MAX_FACT_CHARS,
3883
3930
  DEFAULT_MAX_MEMORIES,
3884
3931
  DEFAULT_MAX_SKILLS,
3932
+ DEFAULT_REFUSAL_REASON,
3885
3933
  DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,
3886
3934
  DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,
3887
3935
  DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,
@@ -3980,6 +4028,7 @@ __name(runAgentLoop, "runAgentLoop");
3980
4028
  skillInputSchema,
3981
4029
  skillToolDefinition,
3982
4030
  skillWriteVerdict,
4031
+ stampToolKinds,
3983
4032
  staticSkillProvider,
3984
4033
  summarizeWithModel,
3985
4034
  tenantScope,