@dudousxd/nestjs-agent 1.19.2 → 1.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.
package/README.md CHANGED
@@ -156,6 +156,8 @@ per-message cap — so a client never repeats them.
156
156
  it leaves media with nothing pointing at it. Two optional methods make that findable — `list` on
157
157
  your `AttachmentStagingStore` (you stored the bytes, so only you can enumerate them) and
158
158
  `referencedMediaIds` on your `AgentStore` (only it can see which media a live message carries).
159
+ A message waiting in a thread's queue — sent while a turn ran, or into a paused queue — counts as
160
+ live: its files are kept until it runs, is removed, or has its attachments edited away.
159
161
 
160
162
  ```ts
161
163
  // a job the host runs; nothing here is reachable over HTTP
@@ -1,4 +1,4 @@
1
- import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason, Actor } from '@dudousxd/nestjs-agent-core';
1
+ import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason, Actor } from '@dudousxd/nestjs-agent-core';
2
2
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
4
4
 
@@ -24,6 +24,8 @@ interface AgentDeps {
24
24
  maxAgentAppearances?: number;
25
25
  /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */
26
26
  toolAllowList?: string[];
27
+ /** The agent's personas (`@Agent({ personas })`) — read by the loop only for a run that names one. */
28
+ personas?: Persona[];
27
29
  /** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */
28
30
  toolTimeoutMs?: number;
29
31
  /**
@@ -534,7 +536,36 @@ declare class AgentDepsFactory {
534
536
  */
535
537
  defaultAgentName(): string;
536
538
  private effectiveTools;
539
+ /**
540
+ * The agent a name stands for: itself when it is a registered agent (or unknown — the bare
541
+ * assistant), else the agent whose persona took the name over (`Persona.aliases`) and that persona.
542
+ */
543
+ resolveAgent(name: string): {
544
+ agentName: string;
545
+ persona?: string;
546
+ };
547
+ /** `agentName`'s personas as a picker reads them. Empty when it declares none. */
548
+ personaCatalog(agentName: string): PersonaCatalogEntry[];
549
+ /** The persona `agentName` runs under when nothing names one. Undefined → none. */
550
+ defaultPersona(agentName: string): string | undefined;
551
+ /**
552
+ * The persona a turn of `agentName` runs under, most specific first: the one the send names
553
+ * (refused with `400 persona_not_found` when the agent does not declare it), else the thread's
554
+ * pinned one when this agent declares it, else the agent's default. Undefined → none.
555
+ */
556
+ resolvePersona(args: {
557
+ agentName: string;
558
+ requested?: string;
559
+ threadPersona?: string | null;
560
+ }): string | undefined;
537
561
  forAgent(agentName?: string): AgentDeps;
562
+ /**
563
+ * A persona baked into an agent's deps — how a run journaled under an agent name that a persona
564
+ * has since taken over (`Persona.aliases`) is served. That run names no persona of its own (it
565
+ * predates them, and its input cannot change), so the persona applies the way the old agent's own
566
+ * config did: as config, re-read on every replay, with no checkpoint of its own.
567
+ */
568
+ private withPersona;
538
569
  /**
539
570
  * The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
540
571
  * own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
@@ -591,13 +622,14 @@ declare class ChatQueueService {
591
622
  private readonly quotaProvider?;
592
623
  private readonly options?;
593
624
  private readonly staging?;
625
+ private readonly deps?;
594
626
  private readonly logger;
595
627
  /**
596
628
  * Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
597
629
  * alive whatever the runner says — it simply has not registered the run yet.
598
630
  */
599
631
  private readonly starting;
600
- constructor(store: AgentStore, sink: TokenStreamSink, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota"> | undefined, staging?: AttachmentStagingStore | undefined);
632
+ constructor(store: AgentStore, sink: TokenStreamSink, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota"> | undefined, staging?: AttachmentStagingStore | undefined, deps?: AgentDepsFactory | undefined);
601
633
  /** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
602
634
  get supported(): boolean;
603
635
  /** The bound store as a queue store, or a 501 naming what is missing. */
@@ -673,6 +705,13 @@ declare class ChatQueueService {
673
705
  * waited. An attachment the staging store no longer resolves keeps its stored url.
674
706
  */
675
707
  private inputFor;
708
+ /**
709
+ * The agent and persona a queued message starts as. A message carries the persona its send
710
+ * resolved; one that carries none — queued before personas existed, or by a host that sets none —
711
+ * resolves it now, exactly as a send would: an agent name a persona took over, then the thread's
712
+ * pinned persona, then the agent's default. Never refused here: nobody is waiting on a 400.
713
+ */
714
+ private targetFor;
676
715
  private freshAttachments;
677
716
  }
678
717
 
@@ -1,4 +1,4 @@
1
- import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason, Actor } from '@dudousxd/nestjs-agent-core';
1
+ import { ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, QuotaProvider, QuotaQuery, QuotaReport, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason, Actor } from '@dudousxd/nestjs-agent-core';
2
2
  import { StandardSchemaV1 } from '@standard-schema/spec';
3
3
  import { Provider, FactoryProvider, Type, CanActivate, ModuleMetadata, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
4
4
 
@@ -24,6 +24,8 @@ interface AgentDeps {
24
24
  maxAgentAppearances?: number;
25
25
  /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */
26
26
  toolAllowList?: string[];
27
+ /** The agent's personas (`@Agent({ personas })`) — read by the loop only for a run that names one. */
28
+ personas?: Persona[];
27
29
  /** Per-tool execution timeout in ms (from module options). Undefined → no timeout. */
28
30
  toolTimeoutMs?: number;
29
31
  /**
@@ -534,7 +536,36 @@ declare class AgentDepsFactory {
534
536
  */
535
537
  defaultAgentName(): string;
536
538
  private effectiveTools;
539
+ /**
540
+ * The agent a name stands for: itself when it is a registered agent (or unknown — the bare
541
+ * assistant), else the agent whose persona took the name over (`Persona.aliases`) and that persona.
542
+ */
543
+ resolveAgent(name: string): {
544
+ agentName: string;
545
+ persona?: string;
546
+ };
547
+ /** `agentName`'s personas as a picker reads them. Empty when it declares none. */
548
+ personaCatalog(agentName: string): PersonaCatalogEntry[];
549
+ /** The persona `agentName` runs under when nothing names one. Undefined → none. */
550
+ defaultPersona(agentName: string): string | undefined;
551
+ /**
552
+ * The persona a turn of `agentName` runs under, most specific first: the one the send names
553
+ * (refused with `400 persona_not_found` when the agent does not declare it), else the thread's
554
+ * pinned one when this agent declares it, else the agent's default. Undefined → none.
555
+ */
556
+ resolvePersona(args: {
557
+ agentName: string;
558
+ requested?: string;
559
+ threadPersona?: string | null;
560
+ }): string | undefined;
537
561
  forAgent(agentName?: string): AgentDeps;
562
+ /**
563
+ * A persona baked into an agent's deps — how a run journaled under an agent name that a persona
564
+ * has since taken over (`Persona.aliases`) is served. That run names no persona of its own (it
565
+ * predates them, and its input cannot change), so the persona applies the way the old agent's own
566
+ * config did: as config, re-read on every replay, with no checkpoint of its own.
567
+ */
568
+ private withPersona;
538
569
  /**
539
570
  * The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
540
571
  * own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
@@ -591,13 +622,14 @@ declare class ChatQueueService {
591
622
  private readonly quotaProvider?;
592
623
  private readonly options?;
593
624
  private readonly staging?;
625
+ private readonly deps?;
594
626
  private readonly logger;
595
627
  /**
596
628
  * Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
597
629
  * alive whatever the runner says — it simply has not registered the run yet.
598
630
  */
599
631
  private readonly starting;
600
- constructor(store: AgentStore, sink: TokenStreamSink, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota"> | undefined, staging?: AttachmentStagingStore | undefined);
632
+ constructor(store: AgentStore, sink: TokenStreamSink, quotaProvider?: QuotaProvider | undefined, options?: Pick<AgentModuleOptions, "quota"> | undefined, staging?: AttachmentStagingStore | undefined, deps?: AgentDepsFactory | undefined);
601
633
  /** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
602
634
  get supported(): boolean;
603
635
  /** The bound store as a queue store, or a 501 naming what is missing. */
@@ -673,6 +705,13 @@ declare class ChatQueueService {
673
705
  * waited. An attachment the staging store no longer resolves keeps its stored url.
674
706
  */
675
707
  private inputFor;
708
+ /**
709
+ * The agent and persona a queued message starts as. A message carries the persona its send
710
+ * resolved; one that carries none — queued before personas existed, or by a host that sets none —
711
+ * resolves it now, exactly as a send would: an agent name a persona took over, then the thread's
712
+ * pinned persona, then the agent's default. Never refused here: nobody is waiting on a 400.
713
+ */
714
+ private targetFor;
676
715
  private freshAttachments;
677
716
  }
678
717