@dudousxd/nestjs-agent-core 0.18.0 → 0.20.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.
@@ -323,6 +323,25 @@ interface AgentApprovalRequest {
323
323
  /** Why this call needs a person, in words for that person. */
324
324
  reason?: string;
325
325
  }
326
+ /**
327
+ * How an approval settled — the other half of {@link AgentApprovalRequest}, under the same `id`.
328
+ * Metadata again: the call's own outcome still arrives as `tool-output` (approved and ran),
329
+ * `tool-output-error` (approved and failed) or `tool-output-denied` (rejected or expired).
330
+ */
331
+ interface AgentApprovalSettlement {
332
+ id: string;
333
+ status: 'approved' | 'rejected' | 'expired';
334
+ /** Repeated from the request, for a call approved without one being streamed (a remembered approval). */
335
+ approver?: string;
336
+ /** Opaque ref of who decided. Absent on an expiry. */
337
+ decidedBy?: string;
338
+ /** The surface the decision came through: `'web'`, `'slack'`, `'remembered'`, … */
339
+ decidedVia?: string;
340
+ /** The approval also covers later calls of this tool in this thread. */
341
+ remember?: boolean;
342
+ /** What the person said when declining. */
343
+ reason?: string;
344
+ }
326
345
  type AgentStreamEvent = {
327
346
  kind: 'step-start';
328
347
  }
@@ -414,6 +433,14 @@ type AgentStreamEvent = {
414
433
  | ({
415
434
  kind: 'approval-requested';
416
435
  } & AgentApprovalRequest)
436
+ /**
437
+ * A parked action call was decided (or lapsed). Optional, like `approval-requested`: it adds WHO
438
+ * decided, THROUGH WHAT and whether the approval is REMEMBERED; the outcome itself rides the
439
+ * call's own output frame. See {@link AgentApprovalSettlement}.
440
+ */
441
+ | ({
442
+ kind: 'approval-settled';
443
+ } & AgentApprovalSettlement)
417
444
  /**
418
445
  * Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool
419
446
  * call. See {@link AgentUiComponent}.
@@ -454,6 +481,94 @@ declare function encodeStreamEvent(event: AgentStreamEvent): Uint8Array;
454
481
  */
455
482
  declare function decodeStreamEvent(line: string): AgentStreamEvent | null;
456
483
 
484
+ /**
485
+ * How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,
486
+ * beside the tool's input schema, because whoever changes the input is the one who has to re-word
487
+ * the sentence that mentions it — and a client that shipped its own name-to-sentence map would go
488
+ * stale the moment a tool was renamed. A tool name is an identifier, never copy.
489
+ *
490
+ * `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:
491
+ * `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one
492
+ * declaration covers every call the tool will ever receive and replays identically from history.
493
+ * A placeholder with nothing behind it collapses along with the space before it.
494
+ */
495
+ interface ToolPresentation {
496
+ /** Noun phrase, for counts and headings: "Database query", "Knowledge base". */
497
+ label: string;
498
+ /** Present progressive, while the call is in flight: "Reading {bucket}". */
499
+ running: string;
500
+ /** Settled, once the output is in: "Read {bucket}". */
501
+ done: string;
502
+ /** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */
503
+ icon?: string;
504
+ /** One line naming what the tool reaches, for when the activity line is opened. */
505
+ detail?: string;
506
+ /** `destructive` earns the warning treatment on an approval prompt. */
507
+ tone?: ToolPresentationTone;
508
+ /** What a person is being asked to allow when an `action` call parks for approval. */
509
+ confirm?: ToolConfirmation;
510
+ /** How the call's OUTPUT reads as content. */
511
+ result?: ToolResultView;
512
+ }
513
+ type ToolPresentationTone = 'neutral' | 'destructive';
514
+ interface ToolConfirmation {
515
+ /** "Delete {count} files?" */
516
+ title: string;
517
+ /** The button: "Delete". */
518
+ verb: string;
519
+ /** A sentence under the title, when the title alone does not say what changes. */
520
+ detail?: string;
521
+ }
522
+ /** A value read out of a tool's output by dotted path, with the words to put next to it. */
523
+ interface ToolResultField {
524
+ path: string;
525
+ label: string;
526
+ unit?: string;
527
+ }
528
+ /**
529
+ * How a tool's output reads as content. Every variant names dotted paths into the output rather
530
+ * than shapes, so a renderer never has to recognise which tool it is drawing: it receives
531
+ * `{ view, output }` and draws it.
532
+ */
533
+ type ToolResultView =
534
+ /** A row of labelled readings — one result, several facets. */
535
+ {
536
+ kind: 'metrics';
537
+ fields: ToolResultField[];
538
+ }
539
+ /** `rows` is a path to an array; each column's `path` is read WITHIN a row. */
540
+ | {
541
+ kind: 'table';
542
+ columns: ToolResultField[];
543
+ rows: string;
544
+ empty?: string;
545
+ }
546
+ /** `lines` is a path to an array of strings, drawn as a log tail. */
547
+ | {
548
+ kind: 'log';
549
+ lines: string;
550
+ }
551
+ /** One sentence, templated over the output. */
552
+ | {
553
+ kind: 'note';
554
+ text: string;
555
+ }
556
+ /** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */
557
+ | {
558
+ kind: 'elsewhere';
559
+ };
560
+ /**
561
+ * One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,
562
+ * with how each is spoken about. `presentation` is absent for a tool that declared none — a client
563
+ * then narrates it generically rather than falling back to its name.
564
+ */
565
+ interface ToolCatalogEntry {
566
+ /** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */
567
+ name: string;
568
+ kind: ToolKind;
569
+ presentation?: ToolPresentation;
570
+ }
571
+
457
572
  /**
458
573
  * Transient tool-error classification + the retry loop that wraps a tool's own invocation. A
459
574
  * classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means
@@ -573,6 +688,11 @@ interface ToolSpec {
573
688
  name: string;
574
689
  kind: ToolKind;
575
690
  description: string;
691
+ /**
692
+ * How a person-facing surface talks about this tool (see {@link ToolPresentation}). Never shown
693
+ * to the model; served to clients by `GET <base>/tools`.
694
+ */
695
+ presentation?: ToolPresentation;
576
696
  /**
577
697
  * Input schema as a [Standard Schema](https://standardschema.dev) — validation-agnostic, so
578
698
  * Zod, Valibot, or ArkType all work. The loop validates input via `~standard.validate` before
@@ -645,6 +765,12 @@ interface ToolResult {
645
765
  * tool's outcome on; this flag is what everything else reads.
646
766
  */
647
767
  denied?: true;
768
+ /**
769
+ * The approval request lapsed before anyone decided, so the tool never ran. Always set together
770
+ * with {@link denied}: an expiry IS a refusal to every consumer that only knows that much, and this
771
+ * flag is for the ones that tell "nobody answered" from "someone said no".
772
+ */
773
+ expired?: true;
648
774
  id: string;
649
775
  name: string;
650
776
  output: unknown;
@@ -724,6 +850,22 @@ interface Decision {
724
850
  * (the chat flow).
725
851
  */
726
852
  executedByRef?: string;
853
+ /**
854
+ * Approve later calls of the SAME tool in the SAME thread without asking again. Read only on an
855
+ * approval; the loop answers it through {@link import('./spi/agent-store.js').AgentStore.rememberedApprovals}.
856
+ */
857
+ remember?: boolean;
858
+ /**
859
+ * The surface the decision came through — `'web'`, `'slack'`, `'console'`, anything the caller
860
+ * names. Provenance only: persisted with the call, never authorized against.
861
+ */
862
+ decidedVia?: string;
863
+ /**
864
+ * Nobody decided before the request lapsed. Set by the RUNNER when the approval wait times out
865
+ * (see `AgentLoopHooks.awaitApproval`'s `timeoutMs`), never by a person — the HTTP surface does not
866
+ * accept it. Read as a denial the model is told expired.
867
+ */
868
+ expired?: true;
727
869
  }
728
870
  type MessageRole = 'user' | 'assistant' | 'system';
729
871
  /**
@@ -951,13 +1093,44 @@ interface StoredMessage {
951
1093
  * props for each `id` — a reloaded thread replays them as `data-ui` parts.
952
1094
  */
953
1095
  ui?: AgentUiComponent[];
1096
+ /**
1097
+ * The approval record of every call on this message that was put to a person under an
1098
+ * {@link import('./spi/approval-policy.js').ApprovalPolicy} — who had to decide, until when, and how
1099
+ * it settled. Read off the tool-call rows by the store; absent when no call on the message asked
1100
+ * for one, or on a store that does not record approvals.
1101
+ */
1102
+ approvals?: ToolCallApproval[];
954
1103
  createdAt: string;
955
1104
  }
1105
+ /**
1106
+ * How one approval stands. `pending` → still parked; `approved` → someone said yes (or a remembered
1107
+ * approval did); `rejected` → someone said no; `expired` → nobody answered before `expiresAt`.
1108
+ */
1109
+ type ToolCallApprovalStatus = 'pending' | 'approved' | 'rejected' | 'expired';
1110
+ /** The persisted approval metadata of one action tool call. See {@link StoredMessage.approvals}. */
1111
+ interface ToolCallApproval {
1112
+ toolCallId: string;
1113
+ /** Who may decide: `'requester'` (the thread's own actor) or a role name. */
1114
+ approver: string;
1115
+ /** ISO-8601 instant the request lapses; absent → it never does. */
1116
+ expiresAt?: string;
1117
+ status: ToolCallApprovalStatus;
1118
+ /** The decision asked for later calls of this tool in this thread to be approved automatically. */
1119
+ remember?: boolean;
1120
+ /** Opaque ref of who decided. Absent while pending and on an expiry. */
1121
+ decidedBy?: string;
1122
+ /** The surface the decision came through (`'web'`, `'slack'`, `'remembered'`, …). */
1123
+ decidedVia?: string;
1124
+ /** What the person said when declining. */
1125
+ reason?: string;
1126
+ }
956
1127
  interface ThreadDetail extends ThreadSummary {
957
1128
  messages: StoredMessage[];
958
1129
  activeStreamId?: string;
959
1130
  }
960
- type ToolCallStatus = 'auto_executed' | 'pending_approval' | 'executed' | 'rejected' | 'failed';
1131
+ type ToolCallStatus = 'auto_executed' | 'pending_approval' | 'executed' | 'rejected' | 'failed'
1132
+ /** An approval request lapsed before anyone decided; the tool never ran. */
1133
+ | 'expired';
961
1134
  /**
962
1135
  * Serializable input for a dispatched model-turn step. Carries only data — the serving worker
963
1136
  * re-resolves the model/sink/registry from its own DI via AGENT_DEPS_FACTORY.forAgent(agentName).
@@ -1212,4 +1385,4 @@ interface ToolHandler<I = unknown> {
1212
1385
  canUse?(actor: Actor): boolean | Promise<boolean>;
1213
1386
  }
1214
1387
 
1215
- export { type HistoryPolicyContext as $, type Actor as A, type AgentApprovalRequest as B, type AgentCatalogEntry as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentHistoryWindow as F, type AgentStreamEvent as G, type HumanReply as H, type InputProcessor as I, type AskToolInput as J, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as K, type LlmStepEnvelope as L, type ModelMessage as M, DEFAULT_INTAKE_PREAMBLE as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as V, type ElicitationOption as W, type ElicitationOutcome as X, type ElicitationQuestion as Y, type ElicitationReply as Z, type ElicitationResult as _, type ToolDefinition as a, type HistorySelection as a0, type HistorySummary as a1, type IncrementalGating as a2, type InvokeWithTransientRetryOptions as a3, MAX_ASK_QUESTIONS as a4, type MessageRole as a5, OutputRejectedError as a6, type OutputVerdict as a7, ProcessorFailedError as a8, type PromptContext as a9, type QuotaView as aa, type ToolKind as ab, type ToolStepCtx as ac, type ToolTransientRetryNumbers as ad, type ToolTransientRetryOptions as ae, askInputSchema as af, askToolDefinition as ag, decodeStreamEvent as ah, encodeStreamEvent as ai, invokeWithTransientRetry as aj, isTransientToolError as ak, normalizeElicitationReply as al, renderElicitationAnswers as am, resolveElicitation as an, resolveToolTransientRetryNumbers as ao, settleElicitation as ap, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type HistoryPolicy as l, type ProcessedPrompt as m, type ModelAnswer as n, type PageContext as o, type AgentDefinition as p, type AgentDelegation as q, type AiToolCtx as r, type PromptBuilder as s, type PromptContributor as t, type ToolTransientRetrySetting as u, type AgentIntake as v, type Decision as w, type ToolStepEnvelope as x, ASK_TOOL_DESCRIPTION as y, ASK_TOOL_NAME as z };
1388
+ export { type ElicitationQuestion as $, type Actor as A, ASK_TOOL_DESCRIPTION as B, ASK_TOOL_NAME as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentApprovalRequest as F, type AgentApprovalSettlement as G, type HumanReply as H, type InputProcessor as I, type AgentCatalogEntry as J, type AgentHistoryWindow as K, type LlmStepEnvelope as L, type ModelMessage as M, type AgentStreamEvent as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, type AskToolInput as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as V, DEFAULT_INTAKE_PREAMBLE as W, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as X, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as Y, type ElicitationOption as Z, type ElicitationOutcome as _, type ToolDefinition as a, type ElicitationReply as a0, type ElicitationResult as a1, type HistoryPolicyContext as a2, type HistorySelection as a3, type HistorySummary as a4, type IncrementalGating as a5, type InvokeWithTransientRetryOptions as a6, MAX_ASK_QUESTIONS as a7, type MessageRole as a8, OutputRejectedError as a9, type OutputVerdict as aa, ProcessorFailedError as ab, type PromptContext as ac, type QuotaView as ad, type ToolCallApprovalStatus as ae, type ToolCatalogEntry as af, type ToolConfirmation as ag, type ToolPresentation as ah, type ToolPresentationTone as ai, type ToolResultField as aj, type ToolResultView as ak, type ToolStepCtx as al, type ToolTransientRetryNumbers as am, type ToolTransientRetryOptions as an, askInputSchema as ao, askToolDefinition as ap, decodeStreamEvent as aq, encodeStreamEvent as ar, invokeWithTransientRetry as as, isTransientToolError as at, normalizeElicitationReply as au, renderElicitationAnswers as av, resolveElicitation as aw, resolveToolTransientRetryNumbers as ax, settleElicitation as ay, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type ToolKind as l, type ToolCallApproval as m, type HistoryPolicy as n, type ProcessedPrompt as o, type ModelAnswer as p, type PageContext as q, type AgentDefinition as r, type AgentDelegation as s, type AiToolCtx as t, type PromptBuilder as u, type PromptContributor as v, type ToolTransientRetrySetting as w, type AgentIntake as x, type Decision as y, type ToolStepEnvelope as z };
@@ -323,6 +323,25 @@ interface AgentApprovalRequest {
323
323
  /** Why this call needs a person, in words for that person. */
324
324
  reason?: string;
325
325
  }
326
+ /**
327
+ * How an approval settled — the other half of {@link AgentApprovalRequest}, under the same `id`.
328
+ * Metadata again: the call's own outcome still arrives as `tool-output` (approved and ran),
329
+ * `tool-output-error` (approved and failed) or `tool-output-denied` (rejected or expired).
330
+ */
331
+ interface AgentApprovalSettlement {
332
+ id: string;
333
+ status: 'approved' | 'rejected' | 'expired';
334
+ /** Repeated from the request, for a call approved without one being streamed (a remembered approval). */
335
+ approver?: string;
336
+ /** Opaque ref of who decided. Absent on an expiry. */
337
+ decidedBy?: string;
338
+ /** The surface the decision came through: `'web'`, `'slack'`, `'remembered'`, … */
339
+ decidedVia?: string;
340
+ /** The approval also covers later calls of this tool in this thread. */
341
+ remember?: boolean;
342
+ /** What the person said when declining. */
343
+ reason?: string;
344
+ }
326
345
  type AgentStreamEvent = {
327
346
  kind: 'step-start';
328
347
  }
@@ -414,6 +433,14 @@ type AgentStreamEvent = {
414
433
  | ({
415
434
  kind: 'approval-requested';
416
435
  } & AgentApprovalRequest)
436
+ /**
437
+ * A parked action call was decided (or lapsed). Optional, like `approval-requested`: it adds WHO
438
+ * decided, THROUGH WHAT and whether the approval is REMEMBERED; the outcome itself rides the
439
+ * call's own output frame. See {@link AgentApprovalSettlement}.
440
+ */
441
+ | ({
442
+ kind: 'approval-settled';
443
+ } & AgentApprovalSettlement)
417
444
  /**
418
445
  * Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool
419
446
  * call. See {@link AgentUiComponent}.
@@ -454,6 +481,94 @@ declare function encodeStreamEvent(event: AgentStreamEvent): Uint8Array;
454
481
  */
455
482
  declare function decodeStreamEvent(line: string): AgentStreamEvent | null;
456
483
 
484
+ /**
485
+ * How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,
486
+ * beside the tool's input schema, because whoever changes the input is the one who has to re-word
487
+ * the sentence that mentions it — and a client that shipped its own name-to-sentence map would go
488
+ * stale the moment a tool was renamed. A tool name is an identifier, never copy.
489
+ *
490
+ * `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:
491
+ * `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one
492
+ * declaration covers every call the tool will ever receive and replays identically from history.
493
+ * A placeholder with nothing behind it collapses along with the space before it.
494
+ */
495
+ interface ToolPresentation {
496
+ /** Noun phrase, for counts and headings: "Database query", "Knowledge base". */
497
+ label: string;
498
+ /** Present progressive, while the call is in flight: "Reading {bucket}". */
499
+ running: string;
500
+ /** Settled, once the output is in: "Read {bucket}". */
501
+ done: string;
502
+ /** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */
503
+ icon?: string;
504
+ /** One line naming what the tool reaches, for when the activity line is opened. */
505
+ detail?: string;
506
+ /** `destructive` earns the warning treatment on an approval prompt. */
507
+ tone?: ToolPresentationTone;
508
+ /** What a person is being asked to allow when an `action` call parks for approval. */
509
+ confirm?: ToolConfirmation;
510
+ /** How the call's OUTPUT reads as content. */
511
+ result?: ToolResultView;
512
+ }
513
+ type ToolPresentationTone = 'neutral' | 'destructive';
514
+ interface ToolConfirmation {
515
+ /** "Delete {count} files?" */
516
+ title: string;
517
+ /** The button: "Delete". */
518
+ verb: string;
519
+ /** A sentence under the title, when the title alone does not say what changes. */
520
+ detail?: string;
521
+ }
522
+ /** A value read out of a tool's output by dotted path, with the words to put next to it. */
523
+ interface ToolResultField {
524
+ path: string;
525
+ label: string;
526
+ unit?: string;
527
+ }
528
+ /**
529
+ * How a tool's output reads as content. Every variant names dotted paths into the output rather
530
+ * than shapes, so a renderer never has to recognise which tool it is drawing: it receives
531
+ * `{ view, output }` and draws it.
532
+ */
533
+ type ToolResultView =
534
+ /** A row of labelled readings — one result, several facets. */
535
+ {
536
+ kind: 'metrics';
537
+ fields: ToolResultField[];
538
+ }
539
+ /** `rows` is a path to an array; each column's `path` is read WITHIN a row. */
540
+ | {
541
+ kind: 'table';
542
+ columns: ToolResultField[];
543
+ rows: string;
544
+ empty?: string;
545
+ }
546
+ /** `lines` is a path to an array of strings, drawn as a log tail. */
547
+ | {
548
+ kind: 'log';
549
+ lines: string;
550
+ }
551
+ /** One sentence, templated over the output. */
552
+ | {
553
+ kind: 'note';
554
+ text: string;
555
+ }
556
+ /** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */
557
+ | {
558
+ kind: 'elsewhere';
559
+ };
560
+ /**
561
+ * One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,
562
+ * with how each is spoken about. `presentation` is absent for a tool that declared none — a client
563
+ * then narrates it generically rather than falling back to its name.
564
+ */
565
+ interface ToolCatalogEntry {
566
+ /** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */
567
+ name: string;
568
+ kind: ToolKind;
569
+ presentation?: ToolPresentation;
570
+ }
571
+
457
572
  /**
458
573
  * Transient tool-error classification + the retry loop that wraps a tool's own invocation. A
459
574
  * classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means
@@ -573,6 +688,11 @@ interface ToolSpec {
573
688
  name: string;
574
689
  kind: ToolKind;
575
690
  description: string;
691
+ /**
692
+ * How a person-facing surface talks about this tool (see {@link ToolPresentation}). Never shown
693
+ * to the model; served to clients by `GET <base>/tools`.
694
+ */
695
+ presentation?: ToolPresentation;
576
696
  /**
577
697
  * Input schema as a [Standard Schema](https://standardschema.dev) — validation-agnostic, so
578
698
  * Zod, Valibot, or ArkType all work. The loop validates input via `~standard.validate` before
@@ -645,6 +765,12 @@ interface ToolResult {
645
765
  * tool's outcome on; this flag is what everything else reads.
646
766
  */
647
767
  denied?: true;
768
+ /**
769
+ * The approval request lapsed before anyone decided, so the tool never ran. Always set together
770
+ * with {@link denied}: an expiry IS a refusal to every consumer that only knows that much, and this
771
+ * flag is for the ones that tell "nobody answered" from "someone said no".
772
+ */
773
+ expired?: true;
648
774
  id: string;
649
775
  name: string;
650
776
  output: unknown;
@@ -724,6 +850,22 @@ interface Decision {
724
850
  * (the chat flow).
725
851
  */
726
852
  executedByRef?: string;
853
+ /**
854
+ * Approve later calls of the SAME tool in the SAME thread without asking again. Read only on an
855
+ * approval; the loop answers it through {@link import('./spi/agent-store.js').AgentStore.rememberedApprovals}.
856
+ */
857
+ remember?: boolean;
858
+ /**
859
+ * The surface the decision came through — `'web'`, `'slack'`, `'console'`, anything the caller
860
+ * names. Provenance only: persisted with the call, never authorized against.
861
+ */
862
+ decidedVia?: string;
863
+ /**
864
+ * Nobody decided before the request lapsed. Set by the RUNNER when the approval wait times out
865
+ * (see `AgentLoopHooks.awaitApproval`'s `timeoutMs`), never by a person — the HTTP surface does not
866
+ * accept it. Read as a denial the model is told expired.
867
+ */
868
+ expired?: true;
727
869
  }
728
870
  type MessageRole = 'user' | 'assistant' | 'system';
729
871
  /**
@@ -951,13 +1093,44 @@ interface StoredMessage {
951
1093
  * props for each `id` — a reloaded thread replays them as `data-ui` parts.
952
1094
  */
953
1095
  ui?: AgentUiComponent[];
1096
+ /**
1097
+ * The approval record of every call on this message that was put to a person under an
1098
+ * {@link import('./spi/approval-policy.js').ApprovalPolicy} — who had to decide, until when, and how
1099
+ * it settled. Read off the tool-call rows by the store; absent when no call on the message asked
1100
+ * for one, or on a store that does not record approvals.
1101
+ */
1102
+ approvals?: ToolCallApproval[];
954
1103
  createdAt: string;
955
1104
  }
1105
+ /**
1106
+ * How one approval stands. `pending` → still parked; `approved` → someone said yes (or a remembered
1107
+ * approval did); `rejected` → someone said no; `expired` → nobody answered before `expiresAt`.
1108
+ */
1109
+ type ToolCallApprovalStatus = 'pending' | 'approved' | 'rejected' | 'expired';
1110
+ /** The persisted approval metadata of one action tool call. See {@link StoredMessage.approvals}. */
1111
+ interface ToolCallApproval {
1112
+ toolCallId: string;
1113
+ /** Who may decide: `'requester'` (the thread's own actor) or a role name. */
1114
+ approver: string;
1115
+ /** ISO-8601 instant the request lapses; absent → it never does. */
1116
+ expiresAt?: string;
1117
+ status: ToolCallApprovalStatus;
1118
+ /** The decision asked for later calls of this tool in this thread to be approved automatically. */
1119
+ remember?: boolean;
1120
+ /** Opaque ref of who decided. Absent while pending and on an expiry. */
1121
+ decidedBy?: string;
1122
+ /** The surface the decision came through (`'web'`, `'slack'`, `'remembered'`, …). */
1123
+ decidedVia?: string;
1124
+ /** What the person said when declining. */
1125
+ reason?: string;
1126
+ }
956
1127
  interface ThreadDetail extends ThreadSummary {
957
1128
  messages: StoredMessage[];
958
1129
  activeStreamId?: string;
959
1130
  }
960
- type ToolCallStatus = 'auto_executed' | 'pending_approval' | 'executed' | 'rejected' | 'failed';
1131
+ type ToolCallStatus = 'auto_executed' | 'pending_approval' | 'executed' | 'rejected' | 'failed'
1132
+ /** An approval request lapsed before anyone decided; the tool never ran. */
1133
+ | 'expired';
961
1134
  /**
962
1135
  * Serializable input for a dispatched model-turn step. Carries only data — the serving worker
963
1136
  * re-resolves the model/sink/registry from its own DI via AGENT_DEPS_FACTORY.forAgent(agentName).
@@ -1212,4 +1385,4 @@ interface ToolHandler<I = unknown> {
1212
1385
  canUse?(actor: Actor): boolean | Promise<boolean>;
1213
1386
  }
1214
1387
 
1215
- export { type HistoryPolicyContext as $, type Actor as A, type AgentApprovalRequest as B, type AgentCatalogEntry as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentHistoryWindow as F, type AgentStreamEvent as G, type HumanReply as H, type InputProcessor as I, type AskToolInput as J, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as K, type LlmStepEnvelope as L, type ModelMessage as M, DEFAULT_INTAKE_PREAMBLE as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as V, type ElicitationOption as W, type ElicitationOutcome as X, type ElicitationQuestion as Y, type ElicitationReply as Z, type ElicitationResult as _, type ToolDefinition as a, type HistorySelection as a0, type HistorySummary as a1, type IncrementalGating as a2, type InvokeWithTransientRetryOptions as a3, MAX_ASK_QUESTIONS as a4, type MessageRole as a5, OutputRejectedError as a6, type OutputVerdict as a7, ProcessorFailedError as a8, type PromptContext as a9, type QuotaView as aa, type ToolKind as ab, type ToolStepCtx as ac, type ToolTransientRetryNumbers as ad, type ToolTransientRetryOptions as ae, askInputSchema as af, askToolDefinition as ag, decodeStreamEvent as ah, encodeStreamEvent as ai, invokeWithTransientRetry as aj, isTransientToolError as ak, normalizeElicitationReply as al, renderElicitationAnswers as am, resolveElicitation as an, resolveToolTransientRetryNumbers as ao, settleElicitation as ap, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type HistoryPolicy as l, type ProcessedPrompt as m, type ModelAnswer as n, type PageContext as o, type AgentDefinition as p, type AgentDelegation as q, type AiToolCtx as r, type PromptBuilder as s, type PromptContributor as t, type ToolTransientRetrySetting as u, type AgentIntake as v, type Decision as w, type ToolStepEnvelope as x, ASK_TOOL_DESCRIPTION as y, ASK_TOOL_NAME as z };
1388
+ export { type ElicitationQuestion as $, type Actor as A, ASK_TOOL_DESCRIPTION as B, ASK_TOOL_NAME as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentApprovalRequest as F, type AgentApprovalSettlement as G, type HumanReply as H, type InputProcessor as I, type AgentCatalogEntry as J, type AgentHistoryWindow as K, type LlmStepEnvelope as L, type ModelMessage as M, type AgentStreamEvent as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, type AskToolInput as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as V, DEFAULT_INTAKE_PREAMBLE as W, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as X, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as Y, type ElicitationOption as Z, type ElicitationOutcome as _, type ToolDefinition as a, type ElicitationReply as a0, type ElicitationResult as a1, type HistoryPolicyContext as a2, type HistorySelection as a3, type HistorySummary as a4, type IncrementalGating as a5, type InvokeWithTransientRetryOptions as a6, MAX_ASK_QUESTIONS as a7, type MessageRole as a8, OutputRejectedError as a9, type OutputVerdict as aa, ProcessorFailedError as ab, type PromptContext as ac, type QuotaView as ad, type ToolCallApprovalStatus as ae, type ToolCatalogEntry as af, type ToolConfirmation as ag, type ToolPresentation as ah, type ToolPresentationTone as ai, type ToolResultField as aj, type ToolResultView as ak, type ToolStepCtx as al, type ToolTransientRetryNumbers as am, type ToolTransientRetryOptions as an, askInputSchema as ao, askToolDefinition as ap, decodeStreamEvent as aq, encodeStreamEvent as ar, invokeWithTransientRetry as as, isTransientToolError as at, normalizeElicitationReply as au, renderElicitationAnswers as av, resolveElicitation as aw, resolveToolTransientRetryNumbers as ax, settleElicitation as ay, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type ToolKind as l, type ToolCallApproval as m, type HistoryPolicy as n, type ProcessedPrompt as o, type ModelAnswer as p, type PageContext as q, type AgentDefinition as r, type AgentDelegation as s, type AiToolCtx as t, type PromptBuilder as u, type PromptContributor as v, type ToolTransientRetrySetting as w, type AgentIntake as x, type Decision as y, type ToolStepEnvelope as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-core",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/DavideCarvalho/nestjs-agent.git",