@dudousxd/nestjs-agent 0.8.2 → 0.10.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.
@@ -1,6 +1,6 @@
1
1
  import { LlmStepEnvelope, ModelTurnResult, ToolStepEnvelope, AgentStore, AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';
2
2
  import { WorkflowCtx } from '@dudousxd/nestjs-durable-core';
3
- import { A as AgentDepsFactory, a as AgentModuleOptions } from '../agent-deps.factory-BlC9tumI.cjs';
3
+ import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-D7GdhqdK.cjs';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
 
@@ -56,9 +56,14 @@ declare class AgentRunSteps {
56
56
  */
57
57
  llm(input: DispatchedLlmInput): Promise<ModelTurnResult>;
58
58
  /**
59
- * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).
60
- * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch
61
- * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.
59
+ * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
60
+ * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
61
+ * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
62
+ * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
63
+ * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
64
+ * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
65
+ * bounds engine liveness (retryable) rather than the tool's own business outcome — and per
66
+ * ATTEMPT, so a retried invocation gets its own fresh timeout window.
62
67
  */
63
68
  tool(input: DispatchedToolInput): Promise<unknown>;
64
69
  }
@@ -80,7 +85,7 @@ declare class AgentRunWorkflow {
80
85
  private readonly store;
81
86
  private readonly steps;
82
87
  private readonly dispatchedSteps;
83
- constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps, dispatchedSteps: boolean);
88
+ constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps | undefined, dispatchedSteps: boolean);
84
89
  run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{
85
90
  text: string;
86
91
  }>;
@@ -101,6 +106,31 @@ declare class DurableAgentRunner implements AgentRunner {
101
106
  cancel(_runId: string): Promise<void>;
102
107
  }
103
108
 
109
+ /**
110
+ * `AgentDurableModule.forRoot()` options. `surface` mirrors `AgentModuleOptions.surface` — it has
111
+ * to be its OWN option here (not read off the shared `AGENT_OPTIONS` provider) because Nest builds
112
+ * a module's provider LIST at static/decoration time, before any DI value (including
113
+ * `AGENT_OPTIONS`) exists to read; there is no way to make a `providers` array conditional on an
114
+ * injected value. Keep both in sync — `agentDurable()` (`./agent-durable.js`) does this
115
+ * automatically for the one-call setup; importing `AgentModule`/`AgentDurableModule` separately
116
+ * means passing `surface` to both by hand.
117
+ */
118
+ interface AgentDurableModuleOptions {
119
+ /**
120
+ * Omit (or `'engine'`/`'both'`) for today's full wiring, unconditionally — identical to importing
121
+ * the bare `AgentDurableModule` class (registers `agent.run` AND `AgentRunSteps.llm`/`.tool`).
122
+ *
123
+ * `'http'` registers the `agent.run` WORKFLOW (so `WorkflowService.start(AgentRunWorkflow, …)`
124
+ * still works — `engine.start` requires local registration to validate/persist a new run, even
125
+ * on an enqueue-only pod) but does NOT provide `AgentRunSteps` — the fix for the flip incident
126
+ * this option exists for: an API pod that also registered the dispatched-step handlers
127
+ * subscribed their queues and ran LLM/tool work meant for the worker fleet. Pair `surface: 'http'`
128
+ * with the durable `DurableModule.forRoot({ drive: false })` enqueue-only config so this pod also
129
+ * never DRIVES (polls/executes) the run it just registered — registration alone only satisfies
130
+ * `start()`'s bookkeeping, it doesn't make this pod execute anything on its own.
131
+ */
132
+ surface?: AgentSurface;
133
+ }
104
134
  /**
105
135
  * Opt-in durable runner. Import this alongside `AgentModule.forRoot({ durable: true })` and a
106
136
  * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)
@@ -109,15 +139,20 @@ declare class DurableAgentRunner implements AgentRunner {
109
139
  *
110
140
  * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves
111
141
  * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar
112
- * can't see ahead of time.
142
+ * can't see ahead of time. This is the FULL ('both'/'engine'-equivalent) wiring: bare-importing this
143
+ * class (no `forRoot()` call) always gets it, unconditionally — `forRoot({ surface: 'http' })` is
144
+ * the only form that diverges (see `AgentDurableHttpModule` above).
113
145
  */
114
146
  declare class AgentDurableModule {
115
147
  /**
116
- * The dynamic form used by the `agentDurable` helper. The module needs no configuration of its
117
- * own (its providers come from the decorator above), so this just yields the module reference —
118
- * importing `AgentDurableModule` directly stays equivalent.
148
+ * `surface: 'http'` returns the reduced `AgentDurableHttpModule` wiring (no `AgentRunSteps`);
149
+ * everything else (omitted, `'engine'`, `'both'`) returns this module's own full wiring — the
150
+ * class's `@Module` providers above merge in regardless of which DynamicModule shape a caller
151
+ * imports (Nest merges a class's static provider list with whatever a self-referencing
152
+ * `DynamicModule` adds), which is exactly why the reduced case has to be a DIFFERENT module class
153
+ * rather than a conditional subset of this one's own decorator.
119
154
  */
120
- static forRoot(): DynamicModule;
155
+ static forRoot(options?: AgentDurableModuleOptions): DynamicModule;
121
156
  }
122
157
 
123
158
  /**
@@ -129,7 +164,10 @@ declare class AgentDurableModule {
129
164
  *
130
165
  * It wires `AgentModule.forRoot({ ...options, durable: true })` together with `AgentDurableModule`,
131
166
  * the equivalent of importing both by hand. A configured `DurableModule` is still required. The
132
- * durable runner has no configuration of its own, so `options` is exactly the agent options.
167
+ * durable runner has no configuration of its own beyond the agent options, so `options` is exactly
168
+ * `AgentModuleOptions` — including `surface`, which this helper threads to BOTH calls so a consumer
169
+ * sets it in exactly one place (see `AgentModuleOptions.surface` / `AgentDurableModuleOptions.surface`
170
+ * for why each needs its own copy of the value rather than one reading it off the other via DI).
133
171
  */
134
172
  declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
135
173
 
@@ -143,4 +181,4 @@ declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
143
181
  */
144
182
  declare const AGENT_DISPATCHED_STEPS: unique symbol;
145
183
 
146
- export { AGENT_DISPATCHED_STEPS, AgentDurableModule, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, type DispatchedToolInput, DurableAgentRunner, agentDurable };
184
+ export { AGENT_DISPATCHED_STEPS, AgentDurableModule, type AgentDurableModuleOptions, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, type DispatchedToolInput, DurableAgentRunner, agentDurable };
@@ -1,6 +1,6 @@
1
1
  import { LlmStepEnvelope, ModelTurnResult, ToolStepEnvelope, AgentStore, AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';
2
2
  import { WorkflowCtx } from '@dudousxd/nestjs-durable-core';
3
- import { A as AgentDepsFactory, a as AgentModuleOptions } from '../agent-deps.factory-BlC9tumI.js';
3
+ import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-D7GdhqdK.js';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
 
@@ -56,9 +56,14 @@ declare class AgentRunSteps {
56
56
  */
57
57
  llm(input: DispatchedLlmInput): Promise<ModelTurnResult>;
58
58
  /**
59
- * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).
60
- * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch
61
- * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.
59
+ * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
60
+ * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
61
+ * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
62
+ * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
63
+ * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
64
+ * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
65
+ * bounds engine liveness (retryable) rather than the tool's own business outcome — and per
66
+ * ATTEMPT, so a retried invocation gets its own fresh timeout window.
62
67
  */
63
68
  tool(input: DispatchedToolInput): Promise<unknown>;
64
69
  }
@@ -80,7 +85,7 @@ declare class AgentRunWorkflow {
80
85
  private readonly store;
81
86
  private readonly steps;
82
87
  private readonly dispatchedSteps;
83
- constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps, dispatchedSteps: boolean);
88
+ constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps | undefined, dispatchedSteps: boolean);
84
89
  run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{
85
90
  text: string;
86
91
  }>;
@@ -101,6 +106,31 @@ declare class DurableAgentRunner implements AgentRunner {
101
106
  cancel(_runId: string): Promise<void>;
102
107
  }
103
108
 
109
+ /**
110
+ * `AgentDurableModule.forRoot()` options. `surface` mirrors `AgentModuleOptions.surface` — it has
111
+ * to be its OWN option here (not read off the shared `AGENT_OPTIONS` provider) because Nest builds
112
+ * a module's provider LIST at static/decoration time, before any DI value (including
113
+ * `AGENT_OPTIONS`) exists to read; there is no way to make a `providers` array conditional on an
114
+ * injected value. Keep both in sync — `agentDurable()` (`./agent-durable.js`) does this
115
+ * automatically for the one-call setup; importing `AgentModule`/`AgentDurableModule` separately
116
+ * means passing `surface` to both by hand.
117
+ */
118
+ interface AgentDurableModuleOptions {
119
+ /**
120
+ * Omit (or `'engine'`/`'both'`) for today's full wiring, unconditionally — identical to importing
121
+ * the bare `AgentDurableModule` class (registers `agent.run` AND `AgentRunSteps.llm`/`.tool`).
122
+ *
123
+ * `'http'` registers the `agent.run` WORKFLOW (so `WorkflowService.start(AgentRunWorkflow, …)`
124
+ * still works — `engine.start` requires local registration to validate/persist a new run, even
125
+ * on an enqueue-only pod) but does NOT provide `AgentRunSteps` — the fix for the flip incident
126
+ * this option exists for: an API pod that also registered the dispatched-step handlers
127
+ * subscribed their queues and ran LLM/tool work meant for the worker fleet. Pair `surface: 'http'`
128
+ * with the durable `DurableModule.forRoot({ drive: false })` enqueue-only config so this pod also
129
+ * never DRIVES (polls/executes) the run it just registered — registration alone only satisfies
130
+ * `start()`'s bookkeeping, it doesn't make this pod execute anything on its own.
131
+ */
132
+ surface?: AgentSurface;
133
+ }
104
134
  /**
105
135
  * Opt-in durable runner. Import this alongside `AgentModule.forRoot({ durable: true })` and a
106
136
  * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)
@@ -109,15 +139,20 @@ declare class DurableAgentRunner implements AgentRunner {
109
139
  *
110
140
  * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves
111
141
  * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar
112
- * can't see ahead of time.
142
+ * can't see ahead of time. This is the FULL ('both'/'engine'-equivalent) wiring: bare-importing this
143
+ * class (no `forRoot()` call) always gets it, unconditionally — `forRoot({ surface: 'http' })` is
144
+ * the only form that diverges (see `AgentDurableHttpModule` above).
113
145
  */
114
146
  declare class AgentDurableModule {
115
147
  /**
116
- * The dynamic form used by the `agentDurable` helper. The module needs no configuration of its
117
- * own (its providers come from the decorator above), so this just yields the module reference —
118
- * importing `AgentDurableModule` directly stays equivalent.
148
+ * `surface: 'http'` returns the reduced `AgentDurableHttpModule` wiring (no `AgentRunSteps`);
149
+ * everything else (omitted, `'engine'`, `'both'`) returns this module's own full wiring — the
150
+ * class's `@Module` providers above merge in regardless of which DynamicModule shape a caller
151
+ * imports (Nest merges a class's static provider list with whatever a self-referencing
152
+ * `DynamicModule` adds), which is exactly why the reduced case has to be a DIFFERENT module class
153
+ * rather than a conditional subset of this one's own decorator.
119
154
  */
120
- static forRoot(): DynamicModule;
155
+ static forRoot(options?: AgentDurableModuleOptions): DynamicModule;
121
156
  }
122
157
 
123
158
  /**
@@ -129,7 +164,10 @@ declare class AgentDurableModule {
129
164
  *
130
165
  * It wires `AgentModule.forRoot({ ...options, durable: true })` together with `AgentDurableModule`,
131
166
  * the equivalent of importing both by hand. A configured `DurableModule` is still required. The
132
- * durable runner has no configuration of its own, so `options` is exactly the agent options.
167
+ * durable runner has no configuration of its own beyond the agent options, so `options` is exactly
168
+ * `AgentModuleOptions` — including `surface`, which this helper threads to BOTH calls so a consumer
169
+ * sets it in exactly one place (see `AgentModuleOptions.surface` / `AgentDurableModuleOptions.surface`
170
+ * for why each needs its own copy of the value rather than one reading it off the other via DI).
133
171
  */
134
172
  declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
135
173
 
@@ -143,4 +181,4 @@ declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
143
181
  */
144
182
  declare const AGENT_DISPATCHED_STEPS: unique symbol;
145
183
 
146
- export { AGENT_DISPATCHED_STEPS, AgentDurableModule, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, type DispatchedToolInput, DurableAgentRunner, agentDurable };
184
+ export { AGENT_DISPATCHED_STEPS, AgentDurableModule, type AgentDurableModuleOptions, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, type DispatchedToolInput, DurableAgentRunner, agentDurable };