@dudousxd/nestjs-agent 1.34.0 → 1.35.1

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.d.cts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
2
- import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-QIuTS-5c.cjs';
3
- export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-QIuTS-5c.cjs';
2
+ import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-CF2fcJDx.cjs';
3
+ export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-CF2fcJDx.cjs';
4
4
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
5
- import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposal } from '@dudousxd/nestjs-agent-core';
5
+ import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
6
6
  export * from '@dudousxd/nestjs-agent-core';
7
7
  export { FunctionalToolDefinition } from '@dudousxd/nestjs-agent-core';
8
8
  import { A2uiOptions } from '@dudousxd/nestjs-agent-core/a2ui';
9
9
  import { Request, Response } from 'express';
10
- import { A as AgentService, a as ActionProposalService } from './index-DIFUEKPr.cjs';
11
- export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-DIFUEKPr.cjs';
10
+ import { A as AgentService, a as ActionProposalService } from './index-NF93YDF4.cjs';
11
+ export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-NF93YDF4.cjs';
12
12
  import { AgentGenui } from './genui/index.cjs';
13
13
  import { StandardSchemaV1 } from '@standard-schema/spec';
14
14
  import { DiscoveryService, MetadataScanner } from '@nestjs/core';
@@ -354,10 +354,15 @@ interface AgentOptions {
354
354
  * per edge, by the author, and never by the model: the same worker is worth waiting for in one
355
355
  * orchestrator and worth backgrounding in another, and only the person wiring the edge knows
356
356
  * which side of that the user is sitting on.
357
+ *
358
+ * `roles` / `ability` gate who may delegate along the edge (the delegate tool's own), e.g.
359
+ * `{ agent: Helper, roles: ['personal_agent'] }` to let a personal agent's turn delegate.
357
360
  */
358
361
  handoff?: (Type | {
359
362
  agent: Type;
360
363
  detached?: boolean;
364
+ roles?: string[];
365
+ ability?: string;
361
366
  })[];
362
367
  /**
363
368
  * How much of the thread this agent's turns carry, overriding `AgentModule.forRoot({ history })`.
@@ -994,6 +999,8 @@ declare class ActionProposalController {
994
999
 
995
1000
  /** Called with a proposal the worker just settled (executed, or failed executing). */
996
1001
  type ActionProposalSettledListener = (proposal: ActionProposal) => void | Promise<void>;
1002
+ /** Called with a proposal outcome the worker just wrote to its thread. */
1003
+ type ActionProposalAdmittedListener = (outcome: ActionProposalOutcome) => void | Promise<void>;
997
1004
  declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestroy {
998
1005
  private readonly store;
999
1006
  private readonly options;
@@ -1001,6 +1008,16 @@ declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestr
1001
1008
  private worker;
1002
1009
  private readonly logger;
1003
1010
  private readonly settledListeners;
1011
+ private readonly admittedListeners;
1012
+ /**
1013
+ * Run `listener` once a settled proposal's outcome is written to its thread by this process's
1014
+ * worker (the thread was free) — what a module uses to CONTINUE a conversation once an action it
1015
+ * proposed ran (a Poppy connect: the next turn goes on with what was asked). Next to
1016
+ * `actionProposalWorker.onAdmitted`; a listener that throws is logged and does not stop the
1017
+ * others. Returns the unsubscribe.
1018
+ */
1019
+ onAdmitted(listener: ActionProposalAdmittedListener): () => void;
1020
+ private admitted;
1004
1021
  /**
1005
1022
  * Run `listener` after every proposal this process's worker settles — how a module relays an
1006
1023
  * outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
@@ -1014,4 +1031,4 @@ declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestr
1014
1031
  onModuleDestroy(): Promise<void>;
1015
1032
  }
1016
1033
 
1017
- export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatQueueService, ConfigController, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, QueueController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ToolsController, agUiAdapter, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
1034
+ export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, type ActionProposalAdmittedListener, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatQueueService, ConfigController, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, QueueController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ToolsController, agUiAdapter, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
2
- import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-wNWaoUN8.js';
3
- export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-wNWaoUN8.js';
2
+ import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-CzXsKVb1.js';
3
+ export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-CzXsKVb1.js';
4
4
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
5
- import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposal } from '@dudousxd/nestjs-agent-core';
5
+ import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
6
6
  export * from '@dudousxd/nestjs-agent-core';
7
7
  export { FunctionalToolDefinition } from '@dudousxd/nestjs-agent-core';
8
8
  import { A2uiOptions } from '@dudousxd/nestjs-agent-core/a2ui';
9
9
  import { Request, Response } from 'express';
10
- import { A as AgentService, a as ActionProposalService } from './index-DFKUTFfZ.js';
11
- export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-DFKUTFfZ.js';
10
+ import { A as AgentService, a as ActionProposalService } from './index-DpS9P7so.js';
11
+ export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-DpS9P7so.js';
12
12
  import { AgentGenui } from './genui/index.js';
13
13
  import { StandardSchemaV1 } from '@standard-schema/spec';
14
14
  import { DiscoveryService, MetadataScanner } from '@nestjs/core';
@@ -354,10 +354,15 @@ interface AgentOptions {
354
354
  * per edge, by the author, and never by the model: the same worker is worth waiting for in one
355
355
  * orchestrator and worth backgrounding in another, and only the person wiring the edge knows
356
356
  * which side of that the user is sitting on.
357
+ *
358
+ * `roles` / `ability` gate who may delegate along the edge (the delegate tool's own), e.g.
359
+ * `{ agent: Helper, roles: ['personal_agent'] }` to let a personal agent's turn delegate.
357
360
  */
358
361
  handoff?: (Type | {
359
362
  agent: Type;
360
363
  detached?: boolean;
364
+ roles?: string[];
365
+ ability?: string;
361
366
  })[];
362
367
  /**
363
368
  * How much of the thread this agent's turns carry, overriding `AgentModule.forRoot({ history })`.
@@ -994,6 +999,8 @@ declare class ActionProposalController {
994
999
 
995
1000
  /** Called with a proposal the worker just settled (executed, or failed executing). */
996
1001
  type ActionProposalSettledListener = (proposal: ActionProposal) => void | Promise<void>;
1002
+ /** Called with a proposal outcome the worker just wrote to its thread. */
1003
+ type ActionProposalAdmittedListener = (outcome: ActionProposalOutcome) => void | Promise<void>;
997
1004
  declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestroy {
998
1005
  private readonly store;
999
1006
  private readonly options;
@@ -1001,6 +1008,16 @@ declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestr
1001
1008
  private worker;
1002
1009
  private readonly logger;
1003
1010
  private readonly settledListeners;
1011
+ private readonly admittedListeners;
1012
+ /**
1013
+ * Run `listener` once a settled proposal's outcome is written to its thread by this process's
1014
+ * worker (the thread was free) — what a module uses to CONTINUE a conversation once an action it
1015
+ * proposed ran (a Poppy connect: the next turn goes on with what was asked). Next to
1016
+ * `actionProposalWorker.onAdmitted`; a listener that throws is logged and does not stop the
1017
+ * others. Returns the unsubscribe.
1018
+ */
1019
+ onAdmitted(listener: ActionProposalAdmittedListener): () => void;
1020
+ private admitted;
1004
1021
  /**
1005
1022
  * Run `listener` after every proposal this process's worker settles — how a module relays an
1006
1023
  * outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
@@ -1014,4 +1031,4 @@ declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestr
1014
1031
  onModuleDestroy(): Promise<void>;
1015
1032
  }
1016
1033
 
1017
- export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatQueueService, ConfigController, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, QueueController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ToolsController, agUiAdapter, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
1034
+ export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, type ActionProposalAdmittedListener, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatQueueService, ConfigController, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, QueueController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ToolsController, agUiAdapter, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var init_kit = __esm({
69
69
  });
70
70
 
71
71
  // src/agent.module.ts
72
- import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER14, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_DURABLE_RUNNER, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL3, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG3, AGENT_OPTIONS as AGENT_OPTIONS10, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK3, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE7, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, ClosedRolesPolicy, DefaultRolesPolicy, InMemoryAgentStore, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
72
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER14, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_DURABLE_RUNNER, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL3, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG3, AGENT_OPTIONS as AGENT_OPTIONS10, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK3, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE7, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, ClosedRolesPolicy, DefaultRolesPolicy, InMemoryAgentStore, ToolRegistry as ToolRegistry3, personalAgentGate, personalAgentScopes } from "@dudousxd/nestjs-agent-core";
73
73
  import { Global, Logger as Logger8, Module as Module2 } from "@nestjs/common";
74
74
  import { DiscoveryModule, ModulesContainer, RouterModule } from "@nestjs/core";
75
75
 
@@ -4893,9 +4893,19 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
4893
4893
  this.logger.warn(`Agent "${meta.name}" hands off to ${target.name}, which is not an @Agent \u2014 skipped.`);
4894
4894
  continue;
4895
4895
  }
4896
- edges.push(detached ? {
4896
+ const roles = typeof entry === "function" ? void 0 : entry.roles;
4897
+ const ability = typeof entry === "function" ? void 0 : entry.ability;
4898
+ edges.push(detached || roles !== void 0 || ability !== void 0 ? {
4897
4899
  agent: targetMeta.name,
4898
- detached: true
4900
+ ...detached ? {
4901
+ detached: true
4902
+ } : {},
4903
+ ...roles !== void 0 ? {
4904
+ roles
4905
+ } : {},
4906
+ ...ability !== void 0 ? {
4907
+ ability
4908
+ } : {}
4899
4909
  } : targetMeta.name);
4900
4910
  }
4901
4911
  return edges;
@@ -5107,7 +5117,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
5107
5117
  let delegates = 0;
5108
5118
  for (const definition of this.agents.list()) {
5109
5119
  for (const edge of definition.delegatesTo ?? []) {
5110
- const { agent: target, detached } = normalizeDelegation2(edge);
5120
+ const { agent: target, detached, roles, ability } = normalizeDelegation2(edge);
5111
5121
  const targetDefinition = this.agents.get(target);
5112
5122
  if (targetDefinition === void 0) {
5113
5123
  throw new Error(`Agent "${definition.name}" hands off to "${target}", which is not a registered @Agent. Declare it as an @Agent provider or fix the reference.`);
@@ -5129,6 +5139,12 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
5129
5139
  ...detached ? {
5130
5140
  detached: true
5131
5141
  } : {},
5142
+ ...roles !== void 0 ? {
5143
+ roles
5144
+ } : {},
5145
+ ...ability !== void 0 ? {
5146
+ ability
5147
+ } : {},
5132
5148
  description,
5133
5149
  inputSchema: z.object({
5134
5150
  task: z.string()
@@ -5541,6 +5557,35 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
5541
5557
  worker;
5542
5558
  logger = new Logger6(_ActionProposalWorkerService.name);
5543
5559
  settledListeners = /* @__PURE__ */ new Set();
5560
+ admittedListeners = /* @__PURE__ */ new Set();
5561
+ /**
5562
+ * Run `listener` once a settled proposal's outcome is written to its thread by this process's
5563
+ * worker (the thread was free) — what a module uses to CONTINUE a conversation once an action it
5564
+ * proposed ran (a Poppy connect: the next turn goes on with what was asked). Next to
5565
+ * `actionProposalWorker.onAdmitted`; a listener that throws is logged and does not stop the
5566
+ * others. Returns the unsubscribe.
5567
+ */
5568
+ onAdmitted(listener) {
5569
+ this.admittedListeners.add(listener);
5570
+ return () => {
5571
+ this.admittedListeners.delete(listener);
5572
+ };
5573
+ }
5574
+ async admitted(outcome) {
5575
+ const configured = this.options.actionProposalWorker?.onAdmitted;
5576
+ for (const listener of [
5577
+ ...configured ? [
5578
+ configured
5579
+ ] : [],
5580
+ ...this.admittedListeners
5581
+ ]) {
5582
+ try {
5583
+ await listener(outcome);
5584
+ } catch (error) {
5585
+ this.logger.error(error);
5586
+ }
5587
+ }
5588
+ }
5544
5589
  /**
5545
5590
  * Run `listener` after every proposal this process's worker settles — how a module relays an
5546
5591
  * outcome somewhere the turn's stream no longer reaches (a text channel's conversation). Next to
@@ -5584,6 +5629,7 @@ var ActionProposalWorkerService = class _ActionProposalWorkerService {
5584
5629
  workerId: randomUUID(),
5585
5630
  ...this.options.actionProposalWorker,
5586
5631
  onSettled: /* @__PURE__ */ __name((proposal) => this.settled(proposal), "onSettled"),
5632
+ onAdmitted: /* @__PURE__ */ __name((outcome) => this.admitted(outcome), "onAdmitted"),
5587
5633
  executor: new ActionProposalExecutor({
5588
5634
  resolver,
5589
5635
  resolveExecution: /* @__PURE__ */ __name(async (proposal, actor) => {
@@ -6402,6 +6448,13 @@ function forwardingPolicy(wrapper) {
6402
6448
  throw new Error("AgentModule: the AGENT_ROLES_POLICY bound by another module is not ready yet");
6403
6449
  }
6404
6450
  return policy.can(actor, tool);
6451
+ },
6452
+ canOffer(actor, tool) {
6453
+ const policy = wrapper.instance;
6454
+ if (policy === void 0 || policy === null) {
6455
+ throw new Error("AgentModule: the AGENT_ROLES_POLICY bound by another module is not ready yet");
6456
+ }
6457
+ return policy.canOffer ? policy.canOffer(actor, tool) : policy.can(actor, tool);
6405
6458
  }
6406
6459
  };
6407
6460
  }
@@ -6443,7 +6496,14 @@ function sharedProviders(durable, engine) {
6443
6496
  // drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
6444
6497
  // host configured none — which is what keeps the turn's checkpoint sequence unchanged.
6445
6498
  provide: AGENT_SKILLS3,
6446
- useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
6499
+ // Personal agents resolve no skill scope (`personalAgentScopes`): nothing of the app's to load.
6500
+ useFactory: /* @__PURE__ */ __name((options, declared) => {
6501
+ const skills = resolveSkillsConfig(options.skills, declared);
6502
+ return skills === void 0 ? void 0 : {
6503
+ ...skills,
6504
+ scopes: personalAgentScopes(skills.scopes)
6505
+ };
6506
+ }, "useFactory"),
6447
6507
  inject: [
6448
6508
  AGENT_OPTIONS10,
6449
6509
  AGENT_SKILL_SOURCES2
@@ -6453,7 +6513,12 @@ function sharedProviders(durable, engine) {
6453
6513
  // One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
6454
6514
  // shown what the model was shown, and two resolutions would eventually disagree about that.
6455
6515
  provide: AGENT_MEMORY3,
6456
- useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
6516
+ // Personal agents resolve no memory scope (`personalAgentScopes`): under a signed-in Poppy
6517
+ // conversation the actor is the account, and it must neither read nor write its memories.
6518
+ useFactory: /* @__PURE__ */ __name((options) => options.memory === void 0 ? void 0 : {
6519
+ ...options.memory,
6520
+ scopes: personalAgentScopes(options.memory.scopes)
6521
+ }, "useFactory"),
6457
6522
  inject: [
6458
6523
  AGENT_OPTIONS10
6459
6524
  ]
@@ -6467,7 +6532,10 @@ function sharedProviders(durable, engine) {
6467
6532
  },
6468
6533
  {
6469
6534
  provide: AGENT_ROLES_POLICY2,
6470
- useFactory: /* @__PURE__ */ __name((options, modules) => resolveRolesPolicy(options, modules), "useFactory"),
6535
+ // Personal agents (a Poppy conversation, a Poppy session's MCP token) reach only the tools
6536
+ // written for them, and run only those of the scopes their user granted. A no-op for every
6537
+ // other actor.
6538
+ useFactory: /* @__PURE__ */ __name((options, modules) => personalAgentGate(resolveRolesPolicy(options, modules)), "useFactory"),
6471
6539
  inject: [
6472
6540
  AGENT_OPTIONS10,
6473
6541
  ModulesContainer