@dudousxd/nestjs-agent 0.4.0 → 0.5.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,11 +1,60 @@
1
- import { AgentStore, AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';
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-BM_RB6br.cjs';
3
+ import { A as AgentDepsFactory, a as AgentModuleOptions } from '../agent-deps.factory-DGM0IVtA.cjs';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
 
7
7
  /**
8
- * The agent turn AS a durable workflow. Each model/tool call is a checkpointed `ctx.step`, HITL is
8
+ * Serializable input for the dispatched `llm` step: a {@link LlmStepEnvelope} plus the sink routing
9
+ * only the durable runner knows (`sinkRunId`/`childSink`) — core's `AgentLoopHooks.dispatchLlm` stays
10
+ * sink-topology-agnostic, so the workflow adds these two fields when it builds the envelope.
11
+ */
12
+ interface DispatchedLlmInput extends LlmStepEnvelope {
13
+ /**
14
+ * The dispatching workflow's own `ctx.runId` — the run this step's outcome accrues to for
15
+ * reliability metrics (`bumpRunRetries`). Carried even though the handler cannot bump retries
16
+ * today: the durable handler boundary (`runStepHandler`) hands a `@Step` method only
17
+ * `(input, StepLogger)` — the wire task's `attempt` is not exposed — so there is no clean way to
18
+ * detect a retry from inside the handler. Kept on the envelope so the bump can be wired without a
19
+ * wire-contract change once the durable runtime exposes the attempt.
20
+ */
21
+ runId: string;
22
+ /** The stream target: `input.sinkRunId ?? ctx.runId` of the dispatching workflow. */
23
+ sinkRunId: string;
24
+ /** True for a sub-agent run — wrap the writer with {@link childSinkWriter} (no end/fail). */
25
+ childSink: boolean;
26
+ }
27
+ /**
28
+ * The two long steps `AgentRunWorkflow` dispatches as routed remote steps when
29
+ * `dispatchedSteps: true` (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of running them
30
+ * in-process under `ctx.localStep`. Both re-resolve their deps from THIS worker's own DI via
31
+ * `AGENT_DEPS_FACTORY.forAgent` — a step can be served by any worker in the fleet, not just the one
32
+ * that started the run. Always provided by `AgentDurableModule` regardless of `dispatchedSteps`, so
33
+ * the worker group is never orphaned.
34
+ */
35
+ declare class AgentRunSteps {
36
+ private readonly factory;
37
+ constructor(factory: AgentDepsFactory);
38
+ /**
39
+ * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
40
+ * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
41
+ * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
42
+ * across however many turns/retries it takes.
43
+ */
44
+ llm(input: DispatchedLlmInput): Promise<ModelTurnResult>;
45
+ /**
46
+ * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).
47
+ * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch
48
+ * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.
49
+ */
50
+ tool(input: ToolStepEnvelope): Promise<unknown>;
51
+ }
52
+
53
+ /**
54
+ * The agent turn AS a durable workflow. Each model/tool call is a checkpointed `ctx.localStep` — the
55
+ * in-process primitive, NOT the always-dispatched `ctx.step`: the loop's deps (model provider, store,
56
+ * sink) live in THIS workflow worker's DI, and the step names are dynamic checkpoint identities
57
+ * (`llm:0`, `persist:toolcall:<id>`), not routable worker groups. HITL is
9
58
  * `ctx.waitForSignal`, and sub-agent delegation is `ctx.child(AgentRunWorkflow)` — a replay-safe,
10
59
  * observable child run (it shows up as a node in the durable dashboard). A child streams into its
11
60
  * top-level ancestor's sink (`sinkRunId`) so the human watching the parent sees it and can approve
@@ -14,7 +63,9 @@ import { DynamicModule } from '@nestjs/common';
14
63
  declare class AgentRunWorkflow {
15
64
  private readonly factory;
16
65
  private readonly store;
17
- constructor(factory: AgentDepsFactory, store: AgentStore);
66
+ private readonly steps;
67
+ private readonly dispatchedSteps;
68
+ constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps, dispatchedSteps: boolean);
18
69
  run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{
19
70
  text: string;
20
71
  }>;
@@ -40,6 +91,10 @@ declare class DurableAgentRunner implements AgentRunner {
40
91
  * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)
41
92
  * and exposes the durable runner via `AGENT_DURABLE_RUNNER`, which AgentModule binds to
42
93
  * `AGENT_RUNNER`. Forgetting this import makes AgentModule throw a clear error at boot.
94
+ *
95
+ * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves
96
+ * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar
97
+ * can't see ahead of time.
43
98
  */
44
99
  declare class AgentDurableModule {
45
100
  /**
@@ -63,4 +118,14 @@ declare class AgentDurableModule {
63
118
  */
64
119
  declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
65
120
 
66
- export { AgentDurableModule, AgentRunWorkflow, DurableAgentRunner, agentDurable };
121
+ /**
122
+ * DI flag mirroring `AgentModuleOptions.dispatchedSteps`: whether `AgentRunWorkflow` dispatches its
123
+ * `llm`/`tool` steps as routed remote steps (`AgentRunSteps`) instead of in-process `ctx.localStep`s.
124
+ * `AgentDurableModule` binds it from `AGENT_OPTIONS` (defaulting to `false`); `AgentRunWorkflow`
125
+ * injects it. Kept in its own file — `AgentDurableModule` provides `AgentRunWorkflow` and
126
+ * `AgentRunWorkflow` injects this token, so declaring it in either of those two files would make them
127
+ * import each other.
128
+ */
129
+ declare const AGENT_DISPATCHED_STEPS: unique symbol;
130
+
131
+ export { AGENT_DISPATCHED_STEPS, AgentDurableModule, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, DurableAgentRunner, agentDurable };
@@ -1,11 +1,60 @@
1
- import { AgentStore, AgentRunInput, AgentRunner, Decision } from '@dudousxd/nestjs-agent-core';
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-BM_RB6br.js';
3
+ import { A as AgentDepsFactory, a as AgentModuleOptions } from '../agent-deps.factory-DGM0IVtA.js';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
 
7
7
  /**
8
- * The agent turn AS a durable workflow. Each model/tool call is a checkpointed `ctx.step`, HITL is
8
+ * Serializable input for the dispatched `llm` step: a {@link LlmStepEnvelope} plus the sink routing
9
+ * only the durable runner knows (`sinkRunId`/`childSink`) — core's `AgentLoopHooks.dispatchLlm` stays
10
+ * sink-topology-agnostic, so the workflow adds these two fields when it builds the envelope.
11
+ */
12
+ interface DispatchedLlmInput extends LlmStepEnvelope {
13
+ /**
14
+ * The dispatching workflow's own `ctx.runId` — the run this step's outcome accrues to for
15
+ * reliability metrics (`bumpRunRetries`). Carried even though the handler cannot bump retries
16
+ * today: the durable handler boundary (`runStepHandler`) hands a `@Step` method only
17
+ * `(input, StepLogger)` — the wire task's `attempt` is not exposed — so there is no clean way to
18
+ * detect a retry from inside the handler. Kept on the envelope so the bump can be wired without a
19
+ * wire-contract change once the durable runtime exposes the attempt.
20
+ */
21
+ runId: string;
22
+ /** The stream target: `input.sinkRunId ?? ctx.runId` of the dispatching workflow. */
23
+ sinkRunId: string;
24
+ /** True for a sub-agent run — wrap the writer with {@link childSinkWriter} (no end/fail). */
25
+ childSink: boolean;
26
+ }
27
+ /**
28
+ * The two long steps `AgentRunWorkflow` dispatches as routed remote steps when
29
+ * `dispatchedSteps: true` (`AgentRunSteps.llm` / `AgentRunSteps.tool`) instead of running them
30
+ * in-process under `ctx.localStep`. Both re-resolve their deps from THIS worker's own DI via
31
+ * `AGENT_DEPS_FACTORY.forAgent` — a step can be served by any worker in the fleet, not just the one
32
+ * that started the run. Always provided by `AgentDurableModule` regardless of `dispatchedSteps`, so
33
+ * the worker group is never orphaned.
34
+ */
35
+ declare class AgentRunSteps {
36
+ private readonly factory;
37
+ constructor(factory: AgentDepsFactory);
38
+ /**
39
+ * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
40
+ * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
41
+ * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
42
+ * across however many turns/retries it takes.
43
+ */
44
+ llm(input: DispatchedLlmInput): Promise<ModelTurnResult>;
45
+ /**
46
+ * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).
47
+ * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch
48
+ * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.
49
+ */
50
+ tool(input: ToolStepEnvelope): Promise<unknown>;
51
+ }
52
+
53
+ /**
54
+ * The agent turn AS a durable workflow. Each model/tool call is a checkpointed `ctx.localStep` — the
55
+ * in-process primitive, NOT the always-dispatched `ctx.step`: the loop's deps (model provider, store,
56
+ * sink) live in THIS workflow worker's DI, and the step names are dynamic checkpoint identities
57
+ * (`llm:0`, `persist:toolcall:<id>`), not routable worker groups. HITL is
9
58
  * `ctx.waitForSignal`, and sub-agent delegation is `ctx.child(AgentRunWorkflow)` — a replay-safe,
10
59
  * observable child run (it shows up as a node in the durable dashboard). A child streams into its
11
60
  * top-level ancestor's sink (`sinkRunId`) so the human watching the parent sees it and can approve
@@ -14,7 +63,9 @@ import { DynamicModule } from '@nestjs/common';
14
63
  declare class AgentRunWorkflow {
15
64
  private readonly factory;
16
65
  private readonly store;
17
- constructor(factory: AgentDepsFactory, store: AgentStore);
66
+ private readonly steps;
67
+ private readonly dispatchedSteps;
68
+ constructor(factory: AgentDepsFactory, store: AgentStore, steps: AgentRunSteps, dispatchedSteps: boolean);
18
69
  run(ctx: WorkflowCtx, input: AgentRunInput): Promise<{
19
70
  text: string;
20
71
  }>;
@@ -40,6 +91,10 @@ declare class DurableAgentRunner implements AgentRunner {
40
91
  * configured `DurableModule`. It registers the `agent.run` workflow (discovered by DurableModule)
41
92
  * and exposes the durable runner via `AGENT_DURABLE_RUNNER`, which AgentModule binds to
42
93
  * `AGENT_RUNNER`. Forgetting this import makes AgentModule throw a clear error at boot.
94
+ *
95
+ * Always provides `AgentRunSteps` regardless of `dispatchedSteps` — the worker group it serves
96
+ * (`AgentRunSteps.llm`/`.tool`) must never be orphaned by a config flag the durable step registrar
97
+ * can't see ahead of time.
43
98
  */
44
99
  declare class AgentDurableModule {
45
100
  /**
@@ -63,4 +118,14 @@ declare class AgentDurableModule {
63
118
  */
64
119
  declare function agentDurable(options: AgentModuleOptions): DynamicModule[];
65
120
 
66
- export { AgentDurableModule, AgentRunWorkflow, DurableAgentRunner, agentDurable };
121
+ /**
122
+ * DI flag mirroring `AgentModuleOptions.dispatchedSteps`: whether `AgentRunWorkflow` dispatches its
123
+ * `llm`/`tool` steps as routed remote steps (`AgentRunSteps`) instead of in-process `ctx.localStep`s.
124
+ * `AgentDurableModule` binds it from `AGENT_OPTIONS` (defaulting to `false`); `AgentRunWorkflow`
125
+ * injects it. Kept in its own file — `AgentDurableModule` provides `AgentRunWorkflow` and
126
+ * `AgentRunWorkflow` injects this token, so declaring it in either of those two files would make them
127
+ * import each other.
128
+ */
129
+ declare const AGENT_DISPATCHED_STEPS: unique symbol;
130
+
131
+ export { AGENT_DISPATCHED_STEPS, AgentDurableModule, AgentRunSteps, AgentRunWorkflow, type DispatchedLlmInput, DurableAgentRunner, agentDurable };