@xyne/workflow-sdk 3.2.33 → 3.2.35
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/agents/agent-step.d.ts +8 -8
- package/dist/agents/agent-step.d.ts.map +1 -1
- package/dist/agents/agent-step.js +11 -127
- package/dist/agents/agent-step.js.map +1 -1
- package/dist/agents/contract.d.ts +225 -0
- package/dist/agents/contract.d.ts.map +1 -0
- package/dist/agents/contract.js +196 -0
- package/dist/agents/contract.js.map +1 -0
- package/dist/agents/host-agent-step.d.ts +222 -0
- package/dist/agents/host-agent-step.d.ts.map +1 -0
- package/dist/agents/host-agent-step.js +352 -0
- package/dist/agents/host-agent-step.js.map +1 -0
- package/dist/agents/host.d.ts +9 -0
- package/dist/agents/host.d.ts.map +1 -0
- package/dist/agents/host.js +20 -0
- package/dist/agents/host.js.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +9 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/provider.d.ts +227 -0
- package/dist/agents/provider.d.ts.map +1 -0
- package/dist/agents/provider.js +72 -0
- package/dist/agents/provider.js.map +1 -0
- package/dist/agents/types.d.ts +2 -21
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/engine/workflow-executor.d.ts.map +1 -1
- package/dist/engine/workflow-executor.js +25 -7
- package/dist/engine/workflow-executor.js.map +1 -1
- package/dist/persistence/in-memory-adapter.d.ts +6 -1
- package/dist/persistence/in-memory-adapter.d.ts.map +1 -1
- package/dist/persistence/in-memory-adapter.js +3 -1
- package/dist/persistence/in-memory-adapter.js.map +1 -1
- package/dist/persistence/types.d.ts +16 -1
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/runtime/workflow-runtime.d.ts.map +1 -1
- package/dist/runtime/workflow-runtime.js +6 -0
- package/dist/runtime/workflow-runtime.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent provider port — the seam between a workflow's agent step and whoever
|
|
3
|
+
* actually runs the agent.
|
|
4
|
+
*
|
|
5
|
+
* The SDK ships one agent implementation ({@link AgentStep}, which drives an
|
|
6
|
+
* LLM directly through a pi-mono runtime). That works when the SDK owns the
|
|
7
|
+
* agent: the step config carries the system prompt, the tool list and the turn
|
|
8
|
+
* budget, and the SDK drives the loop.
|
|
9
|
+
*
|
|
10
|
+
* It does not work when the *host* already owns agent lifecycle. In xyne-spaces
|
|
11
|
+
* agents live in claw; in xyne-search they live in an `agents` table. In both
|
|
12
|
+
* cases the prompt, tools, MCP connections and model are the host's to resolve
|
|
13
|
+
* — a workflow step should name an agent and hand it a task, not re-specify it.
|
|
14
|
+
*
|
|
15
|
+
* A provider is that: the host's agent platform, behind a port. It resolves
|
|
16
|
+
* config into a run and reports back; the step keeps the workflow contract
|
|
17
|
+
* (output shape, JSON repair, citations, artifacts). See ./host-agent-step.ts.
|
|
18
|
+
*
|
|
19
|
+
* Two transports, because hosts genuinely have both:
|
|
20
|
+
*
|
|
21
|
+
* - {@link SyncAgentCapability} streams the run. The step holds a worker slot
|
|
22
|
+
* for its duration and forwards progress to the execution viewer. Right for
|
|
23
|
+
* a workflow someone is watching.
|
|
24
|
+
* - {@link AsyncAgentCapability} dispatches the run and parks the step. The
|
|
25
|
+
* worker slot is released and the execution resumes on callback. Right for
|
|
26
|
+
* headless automations, and for agents that run for a long time.
|
|
27
|
+
*
|
|
28
|
+
* A provider may implement either or both. Where it implements both, the choice
|
|
29
|
+
* is per-invocation — the same agent, watched or not — so it belongs in step
|
|
30
|
+
* config, not in the provider's identity.
|
|
31
|
+
*
|
|
32
|
+
* Deliberately free of pi-mono imports.
|
|
33
|
+
*/
|
|
34
|
+
import type { z } from 'zod';
|
|
35
|
+
import type { Attachment } from '../common/attachment.js';
|
|
36
|
+
import type { StepExecutionContext } from '../steps/base-step.js';
|
|
37
|
+
import type { ResumePayload } from '../common/resume-payload.js';
|
|
38
|
+
import type { ResponseDefect, ToolCallRecord } from './contract.js';
|
|
39
|
+
/**
|
|
40
|
+
* One selectable agent, as shown in the step's agent picker.
|
|
41
|
+
*
|
|
42
|
+
* Returned by {@link BaseAgentProvider.listAgents} and served over the host's
|
|
43
|
+
* agents route — never baked into the config JSON Schema, which is generated
|
|
44
|
+
* once per process and has no tenant context.
|
|
45
|
+
*/
|
|
46
|
+
export interface AgentDescriptor {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
avatarUrl?: string;
|
|
51
|
+
}
|
|
52
|
+
/** What the step hands a provider for one invocation. */
|
|
53
|
+
export interface AgentRunInput {
|
|
54
|
+
/** The instruction for this run, with workflow refs already resolved. */
|
|
55
|
+
task: string;
|
|
56
|
+
/** Input documents the agent should have access to. */
|
|
57
|
+
attachments: Attachment[];
|
|
58
|
+
/** True when the step expects a JSON object back rather than free text. */
|
|
59
|
+
expectJson: boolean;
|
|
60
|
+
/** The JSON Schema the response should match. Present only when `expectJson`. */
|
|
61
|
+
outputSchema?: Record<string, unknown>;
|
|
62
|
+
/** True when every data point in the response must carry a source citation. */
|
|
63
|
+
cite: boolean;
|
|
64
|
+
/** Aborted when the step's wall-clock budget expires or the execution is cancelled. */
|
|
65
|
+
signal: AbortSignal;
|
|
66
|
+
/**
|
|
67
|
+
* Set when re-prompting after an unusable response. Providers should feed
|
|
68
|
+
* the defect back to the agent rather than starting a fresh conversation.
|
|
69
|
+
*/
|
|
70
|
+
repair?: {
|
|
71
|
+
attempt: number;
|
|
72
|
+
} & ResponseDefect;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* What a streaming run reports back.
|
|
76
|
+
*
|
|
77
|
+
* A provider translates its own transport (SSE frames, a websocket, an
|
|
78
|
+
* in-process iterator) into these. Failures are thrown, not yielded — a
|
|
79
|
+
* provider that ends without a `done` event is treated as a failed run.
|
|
80
|
+
*/
|
|
81
|
+
export type AgentRunEvent = {
|
|
82
|
+
type: 'text';
|
|
83
|
+
text: string;
|
|
84
|
+
} | {
|
|
85
|
+
type: 'thinking';
|
|
86
|
+
text?: string;
|
|
87
|
+
} | {
|
|
88
|
+
type: 'tool_start';
|
|
89
|
+
toolCallId: string;
|
|
90
|
+
tool: string;
|
|
91
|
+
args: Record<string, unknown>;
|
|
92
|
+
} | {
|
|
93
|
+
type: 'tool_end';
|
|
94
|
+
toolCallId: string;
|
|
95
|
+
tool: string;
|
|
96
|
+
result: unknown;
|
|
97
|
+
}
|
|
98
|
+
/** A file the agent produced. The step stores it; the provider only yields bytes. */
|
|
99
|
+
| {
|
|
100
|
+
type: 'artifact';
|
|
101
|
+
name: string;
|
|
102
|
+
mimeType: string;
|
|
103
|
+
bytes: Uint8Array;
|
|
104
|
+
} | {
|
|
105
|
+
type: 'done';
|
|
106
|
+
result: AgentRunResult;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* The outcome of one agent invocation.
|
|
110
|
+
*
|
|
111
|
+
* Note there are no attachments here: artifacts arrive as events and are
|
|
112
|
+
* persisted by the step through `ctx.storage`, so storage policy stays in the
|
|
113
|
+
* SDK rather than being re-implemented by every provider.
|
|
114
|
+
*/
|
|
115
|
+
export interface AgentRunResult {
|
|
116
|
+
/** The agent's response text, unparsed — the step shapes it per `outputType`. */
|
|
117
|
+
text: string;
|
|
118
|
+
toolCalls: ToolCallRecord[];
|
|
119
|
+
turnCount: number;
|
|
120
|
+
usage: {
|
|
121
|
+
inputTokens: number;
|
|
122
|
+
outputTokens: number;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Artifacts the provider resolved itself.
|
|
126
|
+
*
|
|
127
|
+
* Streaming providers should leave this unset and yield `artifact` events
|
|
128
|
+
* instead, so the step persists the bytes through `ctx.storage` and storage
|
|
129
|
+
* policy stays in one place. Dispatching providers have no byte stream to
|
|
130
|
+
* intercept — their artifacts arrive as references in the callback payload —
|
|
131
|
+
* so they map them to {@link Attachment} themselves.
|
|
132
|
+
*/
|
|
133
|
+
attachments?: Attachment[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* What a parked step remembers about its dispatched run, written under
|
|
137
|
+
* `data.agent` on the step record and handed back to {@link
|
|
138
|
+
* AsyncAgentCapability.collect}.
|
|
139
|
+
*
|
|
140
|
+
* `provider` is stamped so a provider swap between dispatch and callback is
|
|
141
|
+
* caught rather than silently mis-resolved. `externalRef` is the correlation
|
|
142
|
+
* key: the SDK does not persist the one passed to `ctx.pause`, so this is the
|
|
143
|
+
* durable copy a host's callback route matches against. `attempt` carries the
|
|
144
|
+
* repair budget across the pause boundary, since the async repair loop is
|
|
145
|
+
* re-entry rather than iteration.
|
|
146
|
+
*/
|
|
147
|
+
export interface AgentDispatchRecord {
|
|
148
|
+
provider: string;
|
|
149
|
+
attempt: number;
|
|
150
|
+
externalRef: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A host's agent platform, behind a port.
|
|
154
|
+
*
|
|
155
|
+
* `TConfig` is the provider's own slice of step config — typically just the
|
|
156
|
+
* agent reference, since everything else about the agent is the host's to
|
|
157
|
+
* resolve. The step merges it with the shared contract fields.
|
|
158
|
+
*
|
|
159
|
+
* `TCtx` is the host's authorization context, used only by {@link listAgents},
|
|
160
|
+
* which is called from a request route rather than from step execution.
|
|
161
|
+
*/
|
|
162
|
+
export declare abstract class BaseAgentProvider<TConfig extends z.ZodTypeAny = z.ZodTypeAny, TCtx = unknown> {
|
|
163
|
+
/** Human-readable provider name. Also stamped on paused step records so a
|
|
164
|
+
* provider swap mid-flight is caught rather than silently mis-resolved. */
|
|
165
|
+
abstract readonly name: string;
|
|
166
|
+
/** The provider's config fields, merged into the step's config schema. */
|
|
167
|
+
abstract readonly configSchema: TConfig;
|
|
168
|
+
/**
|
|
169
|
+
* List the agents this caller may run. Backs the step's agent picker.
|
|
170
|
+
*
|
|
171
|
+
* Omit when the provider's config names an agent some other way (a free-text
|
|
172
|
+
* id, a fixed single agent); the picker then falls back to a plain field.
|
|
173
|
+
*/
|
|
174
|
+
listAgents?(ctx: TCtx): Promise<AgentDescriptor[]>;
|
|
175
|
+
/**
|
|
176
|
+
* Customize the JSON Schema generated from {@link configSchema} — the same
|
|
177
|
+
* hook steps have, scoped to the provider's own fields.
|
|
178
|
+
*
|
|
179
|
+
* Note this runs once per process with no tenant context, so it can inject
|
|
180
|
+
* static metadata (formats, enums over process-global lists) but never a
|
|
181
|
+
* per-workspace list. That is what {@link listAgents} is for.
|
|
182
|
+
*/
|
|
183
|
+
decorateConfigSchema?(jsonSchema: Record<string, unknown>): Record<string, unknown>;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Stream the run and report progress as it happens.
|
|
187
|
+
*
|
|
188
|
+
* The step consumes the iterable to completion, so a provider holding an open
|
|
189
|
+
* connection must release it from the generator's `finally` — the step may stop
|
|
190
|
+
* consuming early (timeout, abort, workflow cancellation).
|
|
191
|
+
*/
|
|
192
|
+
export interface SyncAgentCapability<TConfig extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
193
|
+
run(config: z.infer<TConfig>, input: AgentRunInput, ctx: StepExecutionContext): AsyncIterable<AgentRunEvent>;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Dispatch the run and let the step park until the host calls back.
|
|
197
|
+
*
|
|
198
|
+
* `dispatch` returns a correlation reference the host's callback route carries;
|
|
199
|
+
* the step persists it and pauses. `collect` runs on resume and turns the
|
|
200
|
+
* parked record plus the callback payload into a result.
|
|
201
|
+
*/
|
|
202
|
+
export interface AsyncAgentCapability<TConfig extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
203
|
+
dispatch(config: z.infer<TConfig>, input: AgentRunInput, ctx: StepExecutionContext): Promise<{
|
|
204
|
+
externalRef: string;
|
|
205
|
+
}>;
|
|
206
|
+
/**
|
|
207
|
+
* Turn the host's callback into a result.
|
|
208
|
+
*
|
|
209
|
+
* `payload` is what the host passed to `runtime.resume()` — a dispatching
|
|
210
|
+
* provider typically reads its own envelope out of `payload.data`. `record`
|
|
211
|
+
* is what this provider stored when it dispatched, so a provider that needs
|
|
212
|
+
* its own correlation reference has it without going near the step row.
|
|
213
|
+
*/
|
|
214
|
+
collect(payload: ResumePayload, record: AgentDispatchRecord, config: z.infer<TConfig>, ctx: StepExecutionContext): Promise<AgentRunResult>;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Resolve which transport an invocation should take.
|
|
218
|
+
*
|
|
219
|
+
* A provider implementing exactly one capability decides it; one implementing
|
|
220
|
+
* both defers to step config, where the author chose per invocation.
|
|
221
|
+
*/
|
|
222
|
+
export declare function resolveAgentMode<TConfig extends z.ZodTypeAny, TCtx>(provider: BaseAgentProvider<TConfig, TCtx>, mode: unknown): 'sync' | 'async';
|
|
223
|
+
/** A provider paired with at least one transport. */
|
|
224
|
+
export type AgentProvider<TConfig extends z.ZodTypeAny = z.ZodTypeAny, TCtx = unknown> = BaseAgentProvider<TConfig, TCtx> & (SyncAgentCapability<TConfig> | AsyncAgentCapability<TConfig>);
|
|
225
|
+
export declare function supportsSync<TConfig extends z.ZodTypeAny, TCtx>(provider: BaseAgentProvider<TConfig, TCtx>): provider is BaseAgentProvider<TConfig, TCtx> & SyncAgentCapability<TConfig>;
|
|
226
|
+
export declare function supportsAsync<TConfig extends z.ZodTypeAny, TCtx>(provider: BaseAgentProvider<TConfig, TCtx>): provider is BaseAgentProvider<TConfig, TCtx> & AsyncAgentCapability<TConfig>;
|
|
227
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/agents/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent provider port — the seam between a workflow's agent step and whoever
|
|
3
|
+
* actually runs the agent.
|
|
4
|
+
*
|
|
5
|
+
* The SDK ships one agent implementation ({@link AgentStep}, which drives an
|
|
6
|
+
* LLM directly through a pi-mono runtime). That works when the SDK owns the
|
|
7
|
+
* agent: the step config carries the system prompt, the tool list and the turn
|
|
8
|
+
* budget, and the SDK drives the loop.
|
|
9
|
+
*
|
|
10
|
+
* It does not work when the *host* already owns agent lifecycle. In xyne-spaces
|
|
11
|
+
* agents live in claw; in xyne-search they live in an `agents` table. In both
|
|
12
|
+
* cases the prompt, tools, MCP connections and model are the host's to resolve
|
|
13
|
+
* — a workflow step should name an agent and hand it a task, not re-specify it.
|
|
14
|
+
*
|
|
15
|
+
* A provider is that: the host's agent platform, behind a port. It resolves
|
|
16
|
+
* config into a run and reports back; the step keeps the workflow contract
|
|
17
|
+
* (output shape, JSON repair, citations, artifacts). See ./host-agent-step.ts.
|
|
18
|
+
*
|
|
19
|
+
* Two transports, because hosts genuinely have both:
|
|
20
|
+
*
|
|
21
|
+
* - {@link SyncAgentCapability} streams the run. The step holds a worker slot
|
|
22
|
+
* for its duration and forwards progress to the execution viewer. Right for
|
|
23
|
+
* a workflow someone is watching.
|
|
24
|
+
* - {@link AsyncAgentCapability} dispatches the run and parks the step. The
|
|
25
|
+
* worker slot is released and the execution resumes on callback. Right for
|
|
26
|
+
* headless automations, and for agents that run for a long time.
|
|
27
|
+
*
|
|
28
|
+
* A provider may implement either or both. Where it implements both, the choice
|
|
29
|
+
* is per-invocation — the same agent, watched or not — so it belongs in step
|
|
30
|
+
* config, not in the provider's identity.
|
|
31
|
+
*
|
|
32
|
+
* Deliberately free of pi-mono imports.
|
|
33
|
+
*/
|
|
34
|
+
// ─── Provider ───
|
|
35
|
+
/**
|
|
36
|
+
* A host's agent platform, behind a port.
|
|
37
|
+
*
|
|
38
|
+
* `TConfig` is the provider's own slice of step config — typically just the
|
|
39
|
+
* agent reference, since everything else about the agent is the host's to
|
|
40
|
+
* resolve. The step merges it with the shared contract fields.
|
|
41
|
+
*
|
|
42
|
+
* `TCtx` is the host's authorization context, used only by {@link listAgents},
|
|
43
|
+
* which is called from a request route rather than from step execution.
|
|
44
|
+
*/
|
|
45
|
+
export class BaseAgentProvider {
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve which transport an invocation should take.
|
|
49
|
+
*
|
|
50
|
+
* A provider implementing exactly one capability decides it; one implementing
|
|
51
|
+
* both defers to step config, where the author chose per invocation.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveAgentMode(provider, mode) {
|
|
54
|
+
const sync = supportsSync(provider);
|
|
55
|
+
const async = supportsAsync(provider);
|
|
56
|
+
if (sync && async)
|
|
57
|
+
return mode === 'async' ? 'async' : 'sync';
|
|
58
|
+
if (async)
|
|
59
|
+
return 'async';
|
|
60
|
+
if (sync)
|
|
61
|
+
return 'sync';
|
|
62
|
+
throw new Error(`Agent provider "${provider.name}" implements neither SyncAgentCapability nor AsyncAgentCapability`);
|
|
63
|
+
}
|
|
64
|
+
// ─── Capability Detection ───
|
|
65
|
+
export function supportsSync(provider) {
|
|
66
|
+
return typeof provider.run === 'function';
|
|
67
|
+
}
|
|
68
|
+
export function supportsAsync(provider) {
|
|
69
|
+
return typeof provider.dispatch === 'function'
|
|
70
|
+
&& typeof provider.collect === 'function';
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/agents/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA8GH,mBAAmB;AAEnB;;;;;;;;;GASG;AACH,MAAM,OAAgB,iBAAiB;CA4BtC;AAiDD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA0C,EAC1C,IAAa;IAEb,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,IAAI,IAAI,KAAK;QAAE,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9D,IAAI,KAAK;QAAE,OAAO,OAAO,CAAC;IAC1B,IAAI,IAAI;QAAE,OAAO,MAAM,CAAC;IACxB,MAAM,IAAI,KAAK,CACb,mBAAmB,QAAQ,CAAC,IAAI,mEAAmE,CACpG,CAAC;AACJ,CAAC;AASD,+BAA+B;AAE/B,MAAM,UAAU,YAAY,CAC1B,QAA0C;IAE1C,OAAO,OAAQ,QAA8B,CAAC,GAAG,KAAK,UAAU,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAA0C;IAE1C,OAAO,OAAQ,QAAmC,CAAC,QAAQ,KAAK,UAAU;WACrE,OAAQ,QAAkC,CAAC,OAAO,KAAK,UAAU,CAAC;AACzE,CAAC"}
|
package/dist/agents/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Only usable when pi-mono peer dependencies are installed.
|
|
10
10
|
*/
|
|
11
|
-
import type {
|
|
11
|
+
import type { ToolCallRecord } from './contract.js';
|
|
12
12
|
export type { AgentEvent, AgentTool, AgentToolResult, AgentToolUpdateCallback, AgentContext, AgentMessage, AgentLoopConfig, BeforeToolCallResult, AfterToolCallResult, BeforeToolCallContext, AfterToolCallContext, ThinkingLevel, } from '@earendil-works/pi-agent-core';
|
|
13
13
|
export type { AgentSessionEvent } from '@earendil-works/pi-coding-agent';
|
|
14
14
|
export type { Message, UserMessage, AssistantMessage, ToolResultMessage, TextContent, ThinkingContent, ImageContent, ToolCall, Tool, Usage, Model, Context, StopReason, } from '@earendil-works/pi-ai';
|
|
@@ -73,24 +73,5 @@ export interface AgentPauseState {
|
|
|
73
73
|
outputTokens: number;
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
export interface ToolCallRecord {
|
|
78
|
-
name: string;
|
|
79
|
-
args: Record<string, unknown>;
|
|
80
|
-
result: unknown;
|
|
81
|
-
durationMs: number;
|
|
82
|
-
}
|
|
83
|
-
/** Final output written to workflow context after agent execution. */
|
|
84
|
-
export interface AgentResult extends Record<string, unknown> {
|
|
85
|
-
/** Free text (outputType 'string') or a parsed JSON object (outputType 'json'). */
|
|
86
|
-
response: string | Record<string, unknown>;
|
|
87
|
-
toolCalls: ToolCallRecord[];
|
|
88
|
-
turnCount: number;
|
|
89
|
-
usage: {
|
|
90
|
-
inputTokens: number;
|
|
91
|
-
outputTokens: number;
|
|
92
|
-
};
|
|
93
|
-
/** Files the agent generated in the sandbox, persisted as artifacts. */
|
|
94
|
-
attachments: Attachment[];
|
|
95
|
-
}
|
|
76
|
+
export type { ToolCallRecord, AgentResult } from './contract.js';
|
|
96
77
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-executor.d.ts","sourceRoot":"","sources":["../../src/engine/workflow-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAU7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAI3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAYvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAoD,MAAM,wBAAwB,CAAC;AAI5G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA+C1D,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,+GAA+G;IAC/G,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,qFAAqF;IACrF,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAgB,CAC3B,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAWjE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAZ3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAgC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA6B;gBAInC,WAAW,EAAE,kBAAkB,CAAC,OAAO,CAAC,EACxC,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC,EACrD,OAAO,CAAC,EAAE,eAAe,GAAG;QAAE,MAAM,CAAC,EAAE,cAAc,CAAA;KAAE;IAUzD,6DAA6D;IAC7D,OAAO,CAAC,SAAS;IAMjB;;;;;;OAMG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-executor.d.ts","sourceRoot":"","sources":["../../src/engine/workflow-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -152,6 +152,7 @@ export class WorkflowExecutor {
|
|
|
152
152
|
await this.persistence.updateExecutionStatus(executionId, 'SKIPPED');
|
|
153
153
|
await this.persistence.persistState(executionId, {
|
|
154
154
|
context: JSON.stringify(context),
|
|
155
|
+
attributes: context.workflow.attributes,
|
|
155
156
|
});
|
|
156
157
|
this.log.info(`runExecution: filter mismatch for ${executionId} — SKIPPED`);
|
|
157
158
|
return;
|
|
@@ -188,6 +189,7 @@ export class WorkflowExecutor {
|
|
|
188
189
|
status: gateRows[0].status,
|
|
189
190
|
executorType: gateRows[0].executorType,
|
|
190
191
|
data: JSON.stringify(data),
|
|
192
|
+
attributes: context.workflow.attributes,
|
|
191
193
|
});
|
|
192
194
|
}
|
|
193
195
|
}
|
|
@@ -203,6 +205,7 @@ export class WorkflowExecutor {
|
|
|
203
205
|
await this.persistence.updateExecutionStatus(executionId, 'RUNNING');
|
|
204
206
|
await this.persistence.persistState(executionId, {
|
|
205
207
|
context: JSON.stringify(context),
|
|
208
|
+
attributes: context.workflow.attributes,
|
|
206
209
|
});
|
|
207
210
|
this.log.info(`run ${isResume ? 'RESUMED' : 'STARTED'} execId=${executionId} workflow=${workflow.id}`);
|
|
208
211
|
await this.runWorkflow(executionId, context, config.steps, {
|
|
@@ -224,6 +227,7 @@ export class WorkflowExecutor {
|
|
|
224
227
|
workflowId,
|
|
225
228
|
status: 'PENDING',
|
|
226
229
|
context: JSON.stringify(context),
|
|
230
|
+
attributes: context.workflow.attributes,
|
|
227
231
|
});
|
|
228
232
|
await this.runExecution(executionId);
|
|
229
233
|
return executionId;
|
|
@@ -319,6 +323,7 @@ export class WorkflowExecutor {
|
|
|
319
323
|
status: 'PENDING',
|
|
320
324
|
context: JSON.stringify(newContext),
|
|
321
325
|
sourceExecutionId,
|
|
326
|
+
attributes: newContext.workflow.attributes,
|
|
322
327
|
});
|
|
323
328
|
// Persist prior steps as COMPLETED on the new execution so the memoized
|
|
324
329
|
// walk skips them (records are the cursor — there is no positional skip).
|
|
@@ -333,6 +338,7 @@ export class WorkflowExecutor {
|
|
|
333
338
|
? 'conditional'
|
|
334
339
|
: 'deterministic',
|
|
335
340
|
data: JSON.stringify(entry),
|
|
341
|
+
attributes: newContext.workflow.attributes,
|
|
336
342
|
});
|
|
337
343
|
}
|
|
338
344
|
this.log.info(`rerun created exec=${newExecutionId} from=${sourceExecutionId} step=${fromStepId}`);
|
|
@@ -347,6 +353,7 @@ export class WorkflowExecutor {
|
|
|
347
353
|
await this.persistence.persistState(executionId, {
|
|
348
354
|
context: JSON.stringify(context),
|
|
349
355
|
currentStepIndex: steps.length,
|
|
356
|
+
attributes: context.workflow.attributes,
|
|
350
357
|
});
|
|
351
358
|
this.emitEvent(executionId, { event: 'execution_completed', data: { status: 'COMPLETED' } });
|
|
352
359
|
this.log.info(`run ${executionId} COMPLETED`);
|
|
@@ -366,6 +373,7 @@ export class WorkflowExecutor {
|
|
|
366
373
|
await this.persistence.persistState(executionId, {
|
|
367
374
|
context: JSON.stringify(context),
|
|
368
375
|
...(pauseCategory === 'review' ? { pauseType: 'review' } : { pauseType: 'step' }),
|
|
376
|
+
attributes: context.workflow.attributes,
|
|
369
377
|
});
|
|
370
378
|
await this.persistence.updateExecutionStatus(executionId, 'EXTERNAL_WAIT');
|
|
371
379
|
this.log.info(`run ${executionId} PAUSED`);
|
|
@@ -376,6 +384,7 @@ export class WorkflowExecutor {
|
|
|
376
384
|
context.__meta = { ...context.__meta, error: errMsg };
|
|
377
385
|
await this.persistence.persistState(executionId, {
|
|
378
386
|
context: JSON.stringify(context),
|
|
387
|
+
attributes: context.workflow.attributes,
|
|
379
388
|
});
|
|
380
389
|
this.emitEvent(executionId, { event: 'execution_failed', data: { error: errMsg } });
|
|
381
390
|
this.log.error(`run ${executionId} FAILED: ${errMsg}`);
|
|
@@ -430,7 +439,7 @@ export class WorkflowExecutor {
|
|
|
430
439
|
// approve → restore output, mark COMPLETED, advance.
|
|
431
440
|
if (rec.data)
|
|
432
441
|
context.steps[step.id] = entryFromData(rec.data, step.type);
|
|
433
|
-
await this.persistStep(executionId, key, 'COMPLETED', executorType, context.steps[step.id], memo);
|
|
442
|
+
await this.persistStep(executionId, key, 'COMPLETED', executorType, context.steps[step.id], memo, context.workflow.attributes);
|
|
434
443
|
this.emitEvent(executionId, {
|
|
435
444
|
event: 'step_completed',
|
|
436
445
|
data: { stepName: step.id, nodePath: key, output: (context.steps[step.id]?.output ?? {}) },
|
|
@@ -479,7 +488,11 @@ export class WorkflowExecutor {
|
|
|
479
488
|
// re-entering its branches; completed branch steps memo-skip.)
|
|
480
489
|
const resuming = resumeData !== undefined;
|
|
481
490
|
if (!resuming) {
|
|
482
|
-
await this.persistence.upsertStep(executionId, key, {
|
|
491
|
+
await this.persistence.upsertStep(executionId, key, {
|
|
492
|
+
status: 'RUNNING',
|
|
493
|
+
executorType,
|
|
494
|
+
attributes: context.workflow.attributes,
|
|
495
|
+
});
|
|
483
496
|
this.emitEvent(executionId, {
|
|
484
497
|
event: 'step_started',
|
|
485
498
|
data: { stepName: step.id, stepType: step.type, nodePath: key },
|
|
@@ -502,7 +515,7 @@ export class WorkflowExecutor {
|
|
|
502
515
|
? { ...ctxEntry }
|
|
503
516
|
: { type: step.type, output: {} };
|
|
504
517
|
const merged = pe.statePatch ? { ...base, ...pe.statePatch } : base;
|
|
505
|
-
await this.persistStep(executionId, key, 'EXTERNAL_WAIT', executorType, merged, memo);
|
|
518
|
+
await this.persistStep(executionId, key, 'EXTERNAL_WAIT', executorType, merged, memo, context.workflow.attributes);
|
|
506
519
|
this.emitEvent(executionId, {
|
|
507
520
|
event: 'execution_paused',
|
|
508
521
|
data: {
|
|
@@ -527,6 +540,7 @@ export class WorkflowExecutor {
|
|
|
527
540
|
status: 'FAILED',
|
|
528
541
|
executorType,
|
|
529
542
|
data: JSON.stringify({ ...(ctxEntry ?? {}), error: errMsg }),
|
|
543
|
+
attributes: context.workflow.attributes,
|
|
530
544
|
});
|
|
531
545
|
memo.set(key, { status: 'FAILED', data: { ...(ctxEntry ?? {}), error: errMsg } });
|
|
532
546
|
this.emitEvent(executionId, { event: 'step_failed', data: { stepName: step.id, nodePath: key, error: errMsg } });
|
|
@@ -537,6 +551,7 @@ export class WorkflowExecutor {
|
|
|
537
551
|
status: 'FAILED',
|
|
538
552
|
executorType,
|
|
539
553
|
data: JSON.stringify({ ...(ctxEntry ?? {}), error: errMsg }),
|
|
554
|
+
attributes: context.workflow.attributes,
|
|
540
555
|
});
|
|
541
556
|
this.emitEvent(executionId, { event: 'step_failed', data: { stepName: step.id, nodePath: key, error: errMsg } });
|
|
542
557
|
throw err;
|
|
@@ -547,14 +562,14 @@ export class WorkflowExecutor {
|
|
|
547
562
|
if (!resuming && step.onComplete === 'review') {
|
|
548
563
|
const reviewPauseState = buildReviewPauseState(step.id, ctxEntry);
|
|
549
564
|
const data = { ...(ctxEntry ?? { type: step.type, output: {} }), pauseState: reviewPauseState };
|
|
550
|
-
await this.persistStep(executionId, key, 'REVIEW_WAIT', executorType, data, memo);
|
|
565
|
+
await this.persistStep(executionId, key, 'REVIEW_WAIT', executorType, data, memo, context.workflow.attributes);
|
|
551
566
|
this.emitEvent(executionId, {
|
|
552
567
|
event: 'execution_paused',
|
|
553
568
|
data: { stepName: step.id, nodePath: key, pauseState: reviewPauseState },
|
|
554
569
|
});
|
|
555
570
|
throw reviewPause(step.id);
|
|
556
571
|
}
|
|
557
|
-
await this.persistStep(executionId, key, 'COMPLETED', executorType, ctxEntry, memo);
|
|
572
|
+
await this.persistStep(executionId, key, 'COMPLETED', executorType, ctxEntry, memo, context.workflow.attributes);
|
|
558
573
|
this.emitEvent(executionId, {
|
|
559
574
|
event: 'step_completed',
|
|
560
575
|
data: { stepName: step.id, nodePath: key, output: (ctxEntry?.output ?? {}) },
|
|
@@ -562,12 +577,15 @@ export class WorkflowExecutor {
|
|
|
562
577
|
}
|
|
563
578
|
}
|
|
564
579
|
/** Persist a step record + mirror it into the in-memory memo for this run. */
|
|
565
|
-
async persistStep(executionId, key, status, executorType, entry, memo
|
|
580
|
+
async persistStep(executionId, key, status, executorType, entry, memo,
|
|
581
|
+
/** The tenant this run acts as — see PersistenceAdapter.createExecution. */
|
|
582
|
+
attributes) {
|
|
566
583
|
const data = entry ? { ...entry } : { output: null };
|
|
567
584
|
await this.persistence.upsertStep(executionId, key, {
|
|
568
585
|
status,
|
|
569
586
|
executorType,
|
|
570
587
|
data: JSON.stringify(data),
|
|
588
|
+
attributes,
|
|
571
589
|
});
|
|
572
590
|
memo.set(key, { status, data });
|
|
573
591
|
}
|
|
@@ -740,7 +758,7 @@ export class WorkflowExecutor {
|
|
|
740
758
|
// state and the activity timeline use — so historical + live align with
|
|
741
759
|
// no client-side remapping.
|
|
742
760
|
this.persistence
|
|
743
|
-
.appendStepEvent(callCtx.executionId, callCtx.stepId, normalized)
|
|
761
|
+
.appendStepEvent(callCtx.executionId, callCtx.stepId, normalized, context.workflow.attributes)
|
|
744
762
|
.catch((err) => {
|
|
745
763
|
this.log.warn(`Failed to persist step event: ${err instanceof Error ? err.message : String(err)}`);
|
|
746
764
|
});
|