@codemation/core 0.8.1 → 0.10.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/CHANGELOG.md +386 -0
- package/dist/{EngineRuntimeRegistration.types-BP6tsaNP.d.ts → EngineRuntimeRegistration.types-D1fyApMI.d.ts} +2 -2
- package/dist/{EngineWorkflowRunnerService-DzOCa1BW.d.cts → EngineRuntimeRegistration.types-pB3FnzqR.d.cts} +17 -17
- package/dist/{InMemoryRunDataFactory-1iz7_SnO.d.cts → InMemoryRunDataFactory-Xw7v4-sj.d.cts} +31 -29
- package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs +47 -0
- package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs.map +1 -0
- package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js +41 -0
- package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js.map +1 -0
- package/dist/{RunIntentService-BqhmdoA1.d.ts → RunIntentService-BE9CAkbf.d.ts} +966 -471
- package/dist/{RunIntentService-S-1lW-gS.d.cts → RunIntentService-siBSjaaY.d.cts} +859 -493
- package/dist/bootstrap/index.cjs +5 -2
- package/dist/bootstrap/index.d.cts +212 -135
- package/dist/bootstrap/index.d.ts +4 -4
- package/dist/bootstrap/index.js +3 -3
- package/dist/{bootstrap-Bx1u4cbS.cjs → bootstrap-Cm5ruQxx.cjs} +253 -2
- package/dist/bootstrap-Cm5ruQxx.cjs.map +1 -0
- package/dist/{bootstrap-BoknFKnw.js → bootstrap-D3r505ko.js} +236 -3
- package/dist/bootstrap-D3r505ko.js.map +1 -0
- package/dist/{index-CVs9rVhl.d.ts → index-DeLl1Tne.d.ts} +632 -230
- package/dist/index.cjs +323 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +544 -91
- package/dist/index.d.ts +3 -3
- package/dist/index.js +299 -166
- package/dist/index.js.map +1 -1
- package/dist/{runtime-DUW6tIJ1.js → runtime-BGNbRnqs.js} +934 -75
- package/dist/runtime-BGNbRnqs.js.map +1 -0
- package/dist/{runtime-Dvo2ru5A.cjs → runtime-DKXJwTNv.cjs} +1028 -73
- package/dist/runtime-DKXJwTNv.cjs.map +1 -0
- package/dist/testing.cjs +4 -4
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +3 -3
- package/package.json +7 -2
- package/src/ai/AiHost.ts +42 -14
- package/src/authoring/DefinedCollectionRegistry.ts +17 -0
- package/src/authoring/defineCollection.types.ts +181 -0
- package/src/authoring/definePollingTrigger.types.ts +396 -0
- package/src/authoring/definePollingTriggerInternals.ts +74 -0
- package/src/authoring/index.ts +19 -0
- package/src/bootstrap/index.ts +9 -0
- package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +8 -0
- package/src/browser.ts +1 -0
- package/src/contracts/CodemationTelemetryAttributeNames.ts +6 -0
- package/src/contracts/NoOpNodeExecutionTelemetry.ts +2 -11
- package/src/contracts/NoOpTelemetrySpanScope.ts +46 -10
- package/src/contracts/assertionTypes.ts +63 -0
- package/src/contracts/baseTypes.ts +12 -0
- package/src/contracts/collectionTypes.ts +44 -0
- package/src/contracts/credentialTypes.ts +23 -1
- package/src/contracts/executionPersistenceContracts.ts +30 -0
- package/src/contracts/index.ts +4 -0
- package/src/contracts/runTypes.ts +37 -1
- package/src/contracts/runtimeTypes.ts +42 -0
- package/src/contracts/telemetryTypes.ts +8 -0
- package/src/contracts/testTriggerTypes.ts +66 -0
- package/src/contracts/workflowTypes.ts +36 -7
- package/src/contracts.ts +59 -0
- package/src/events/ConnectionInvocationEventPublisher.ts +46 -0
- package/src/events/index.ts +1 -0
- package/src/events/runEvents.ts +74 -0
- package/src/execution/ChildExecutionScopeFactory.ts +55 -0
- package/src/execution/DefaultExecutionContextFactory.ts +6 -0
- package/src/execution/ExecutionTelemetryCostTrackingDecoratorFactory.ts +18 -0
- package/src/execution/NodeExecutor.ts +10 -2
- package/src/execution/NodeInstanceFactory.ts +13 -1
- package/src/execution/NodeInstantiationError.ts +16 -0
- package/src/execution/NodeRunStateWriter.ts +7 -0
- package/src/execution/NodeRunStateWriterFactory.ts +7 -0
- package/src/execution/WorkflowRunExecutionContextFactory.ts +3 -0
- package/src/execution/index.ts +2 -0
- package/src/index.ts +8 -0
- package/src/orchestration/AbortControllerFactory.ts +9 -0
- package/src/orchestration/NodeExecutionRequestHandlerService.ts +1 -0
- package/src/orchestration/RunContinuationService.ts +3 -0
- package/src/orchestration/RunStartService.ts +122 -3
- package/src/orchestration/TestSuiteOrchestrator.ts +350 -0
- package/src/orchestration/TestSuiteRunIdFactory.ts +11 -0
- package/src/orchestration/TriggerRuntimeService.ts +34 -7
- package/src/orchestration/index.ts +9 -0
- package/src/runtime/EngineFactory.ts +12 -0
- package/src/triggers/polling/PollingTriggerDedupWindow.ts +23 -0
- package/src/triggers/polling/PollingTriggerLogger.ts +18 -0
- package/src/triggers/polling/PollingTriggerRuntime.ts +122 -0
- package/src/triggers/polling/index.ts +5 -0
- package/src/types/index.ts +12 -9
- package/src/workflow/definition/NodeIterationIdFactory.ts +26 -0
- package/src/workflow/dsl/NodeIdSlugifier.ts +18 -0
- package/src/workflow/dsl/WorkflowBuilder.ts +71 -3
- package/src/workflow/dsl/WorkflowDefinitionError.ts +15 -0
- package/src/workflow/index.ts +3 -0
- package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs +0 -262
- package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs.map +0 -1
- package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js +0 -238
- package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js.map +0 -1
- package/dist/bootstrap-BoknFKnw.js.map +0 -1
- package/dist/bootstrap-Bx1u4cbS.cjs.map +0 -1
- package/dist/runtime-DUW6tIJ1.js.map +0 -1
- package/dist/runtime-Dvo2ru5A.cjs.map +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { JsonValue, NodeId } from "./workflowTypes";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One assertion emitted by an assertion-emitting node (a node whose config sets
|
|
5
|
+
* `emitsAssertions: true`). Each emitted item on `main` carries one of these as `item.json`.
|
|
6
|
+
*
|
|
7
|
+
* Pass/fail is derived from `score >= (passThreshold ?? 0.5)` — see {@link deriveAssertionPassed}.
|
|
8
|
+
* The `errored` marker is for cases where the assertion code itself threw (distinct from
|
|
9
|
+
* "the assertion was evaluated and the score was low") and is treated as a hard fail in rollups
|
|
10
|
+
* regardless of `score`.
|
|
11
|
+
*/
|
|
12
|
+
export interface AssertionResult {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
/** 0..1 score. Source of truth for pass/fail (compared against `passThreshold`). */
|
|
15
|
+
readonly score: number;
|
|
16
|
+
/** 0..1 threshold for "passed". When omitted, consumers default to 0.5. */
|
|
17
|
+
readonly passThreshold?: number;
|
|
18
|
+
/** True when evaluating the assertion threw — treated as fail regardless of `score`. */
|
|
19
|
+
readonly errored?: true;
|
|
20
|
+
/** What the assertion expected. Free-form JSON; UIs render with a JSON viewer. */
|
|
21
|
+
readonly expected?: JsonValue;
|
|
22
|
+
/** What the workflow actually produced. */
|
|
23
|
+
readonly actual?: JsonValue;
|
|
24
|
+
/** Short human-readable explanation, especially for fails / errors. */
|
|
25
|
+
readonly message?: string;
|
|
26
|
+
/** Bag of supplemental fields (e.g. judge prompt, judge raw response, comparison method). */
|
|
27
|
+
readonly details?: Readonly<Record<string, JsonValue>>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Default {@link AssertionResult.passThreshold} when authors omit it. Boolean-style assertions
|
|
32
|
+
* (assertEqual / contains / etc.) emit `score: 1` or `score: 0` so this default works for them;
|
|
33
|
+
* AI-judge assertions are expected to set their own threshold.
|
|
34
|
+
*/
|
|
35
|
+
export const DEFAULT_ASSERTION_PASS_THRESHOLD = 0.5;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Derive whether an assertion result is considered "passing" using the score-based contract:
|
|
39
|
+
* `errored` always fails, otherwise `score >= (passThreshold ?? 0.5)`. This is the canonical
|
|
40
|
+
* derivation — UI and rollup code should call it rather than inlining the comparison so future
|
|
41
|
+
* tweaks (e.g. NaN handling) land in one place.
|
|
42
|
+
*/
|
|
43
|
+
export function deriveAssertionPassed(result: {
|
|
44
|
+
readonly score: number;
|
|
45
|
+
readonly passThreshold?: number;
|
|
46
|
+
readonly errored?: true;
|
|
47
|
+
}): boolean {
|
|
48
|
+
if (result.errored === true) return false;
|
|
49
|
+
const threshold = result.passThreshold ?? DEFAULT_ASSERTION_PASS_THRESHOLD;
|
|
50
|
+
return result.score >= threshold;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Provenance for a persisted {@link AssertionResult}: which node produced it and where in the
|
|
55
|
+
* per-item iteration tree it landed. Filled in by the host-side persister, not the node itself.
|
|
56
|
+
*/
|
|
57
|
+
export interface AssertionResultProvenance {
|
|
58
|
+
readonly nodeId: NodeId;
|
|
59
|
+
/** Per-item iteration id when the emitting node ran inside a per-item loop. */
|
|
60
|
+
readonly iterationId?: string;
|
|
61
|
+
/** Item index (0-based) within the activation that produced this assertion. */
|
|
62
|
+
readonly itemIndex?: number;
|
|
63
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal base types that have no dependencies on other contracts.
|
|
3
|
+
* Used by credentialTypes, workflowTypes, and other contract layers
|
|
4
|
+
* to avoid circular dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type WorkflowId = string;
|
|
8
|
+
export type NodeId = string;
|
|
9
|
+
export type OutputPortKey = string;
|
|
10
|
+
export type InputPortKey = string;
|
|
11
|
+
export type PersistedTokenId = string;
|
|
12
|
+
export type NodeConnectionName = string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a typed store for a single collection.
|
|
3
|
+
* All rows include auto-managed id, created_at, and updated_at fields.
|
|
4
|
+
*/
|
|
5
|
+
export interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
|
|
6
|
+
/**
|
|
7
|
+
* Insert a new row. id, created_at, and updated_at are auto-populated.
|
|
8
|
+
*/
|
|
9
|
+
insert(row: TRow): Promise<TRow & { id: string; created_at: Date; updated_at: Date }>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get a single row by id.
|
|
13
|
+
*/
|
|
14
|
+
get(id: string): Promise<(TRow & { id: string; created_at: Date; updated_at: Date }) | null>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Find a single row matching the provided filter.
|
|
18
|
+
*/
|
|
19
|
+
findOne(filter: Partial<TRow>): Promise<(TRow & { id: string; created_at: Date; updated_at: Date }) | null>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* List rows with optional pagination and filtering.
|
|
23
|
+
*/
|
|
24
|
+
list(opts?: {
|
|
25
|
+
limit?: number;
|
|
26
|
+
offset?: number;
|
|
27
|
+
where?: Partial<TRow>;
|
|
28
|
+
}): Promise<{ rows: ReadonlyArray<TRow & { id: string; created_at: Date; updated_at: Date }>; total: number }>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Update a row by id with partial data.
|
|
32
|
+
*/
|
|
33
|
+
update(id: string, patch: Partial<TRow>): Promise<TRow & { id: string; created_at: Date; updated_at: Date }>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Delete a row by id. Hard delete only (no soft delete).
|
|
37
|
+
*/
|
|
38
|
+
delete(id: string): Promise<{ deleted: boolean }>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Runtime collections context: keyed by collection name.
|
|
43
|
+
*/
|
|
44
|
+
export type CollectionsContext = Readonly<Record<string, CollectionStore>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NodeId, WorkflowId } from "./
|
|
1
|
+
import type { NodeId, WorkflowId } from "./baseTypes";
|
|
2
2
|
|
|
3
3
|
export type CredentialTypeId = string;
|
|
4
4
|
export type CredentialInstanceId = string;
|
|
@@ -91,6 +91,28 @@ export type CredentialOAuth2AuthDefinition = Readonly<
|
|
|
91
91
|
clientIdFieldKey?: string;
|
|
92
92
|
clientSecretFieldKey?: string;
|
|
93
93
|
}
|
|
94
|
+
| {
|
|
95
|
+
kind: "oauth2";
|
|
96
|
+
/**
|
|
97
|
+
* Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.
|
|
98
|
+
* Not used for any registry lookup — URLs come from {@link authorizeUrl} / {@link tokenUrl}.
|
|
99
|
+
*/
|
|
100
|
+
providerId: string;
|
|
101
|
+
/**
|
|
102
|
+
* Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime
|
|
103
|
+
* substitutes from the credential's resolved public config (URL-encoded).
|
|
104
|
+
* Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`
|
|
105
|
+
*/
|
|
106
|
+
authorizeUrl: string;
|
|
107
|
+
/** Token endpoint. Same templating rules as {@link authorizeUrl}. */
|
|
108
|
+
tokenUrl: string;
|
|
109
|
+
/** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */
|
|
110
|
+
userInfoUrl?: string;
|
|
111
|
+
scopes: ReadonlyArray<string>;
|
|
112
|
+
scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
|
|
113
|
+
clientIdFieldKey?: string;
|
|
114
|
+
clientSecretFieldKey?: string;
|
|
115
|
+
}
|
|
94
116
|
>;
|
|
95
117
|
|
|
96
118
|
export type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;
|
|
@@ -148,6 +148,30 @@ export interface WorkflowRunDetailDto {
|
|
|
148
148
|
readonly mutableState?: PersistedMutableRunState;
|
|
149
149
|
readonly slotStates: ReadonlyArray<SlotExecutionStateDto>;
|
|
150
150
|
readonly executionInstances: ReadonlyArray<ExecutionInstanceDto>;
|
|
151
|
+
readonly iterations?: ReadonlyArray<RunIterationDto>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Per-item iteration projected from connection invocations and node activations.
|
|
156
|
+
*
|
|
157
|
+
* One iteration = one item processed by an agent within an activation. Multiple invocations
|
|
158
|
+
* (LLM rounds, tool calls) belonging to the same iteration share the iterationId.
|
|
159
|
+
*/
|
|
160
|
+
export interface RunIterationDto {
|
|
161
|
+
readonly iterationId: string;
|
|
162
|
+
readonly agentNodeId: NodeId;
|
|
163
|
+
readonly activationId: NodeActivationId;
|
|
164
|
+
readonly itemIndex: number;
|
|
165
|
+
readonly itemSummary?: string;
|
|
166
|
+
readonly status: NodeExecutionStatus;
|
|
167
|
+
readonly startedAt?: string;
|
|
168
|
+
readonly finishedAt?: string;
|
|
169
|
+
readonly invocationIds: ReadonlyArray<string>;
|
|
170
|
+
readonly parentInvocationId?: string;
|
|
171
|
+
/** Estimated cost rolled up from telemetry cost metric points, keyed by ISO currency code (e.g. "USD"). Values are minor units (cents-of-cents per the metric's `cost.currency_scale`). */
|
|
172
|
+
readonly estimatedCostMinorByCurrency?: Readonly<Record<string, number>>;
|
|
173
|
+
/** Currency scale (denominator) per currency, when present on the metric points. Joined with `estimatedCostMinorByCurrency` to format human-readable amounts. */
|
|
174
|
+
readonly estimatedCostCurrencyScaleByCurrency?: Readonly<Record<string, number>>;
|
|
151
175
|
}
|
|
152
176
|
|
|
153
177
|
export interface SlotExecutionStateDto {
|
|
@@ -178,6 +202,12 @@ export interface ExecutionInstanceDto {
|
|
|
178
202
|
readonly inputJson?: JsonValue;
|
|
179
203
|
readonly outputJson?: JsonValue;
|
|
180
204
|
readonly error?: Readonly<NodeExecutionError>;
|
|
205
|
+
/** Per-item iteration that produced this instance. Set on connectionInvocation rows produced inside per-item runnable loops. */
|
|
206
|
+
readonly iterationId?: string;
|
|
207
|
+
/** Item index (0-based) of the iteration. */
|
|
208
|
+
readonly itemIndex?: number;
|
|
209
|
+
/** Parent invocation id when this instance was emitted by a sub-agent triggered by an outer LLM/tool call. */
|
|
210
|
+
readonly parentInvocationId?: string;
|
|
181
211
|
}
|
|
182
212
|
|
|
183
213
|
export interface WorkflowDetailSelectionState {
|
package/src/contracts/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export * from "./baseTypes";
|
|
2
|
+
export * from "./assertionTypes";
|
|
3
|
+
export * from "./collectionTypes";
|
|
1
4
|
export * from "./credentialTypes";
|
|
2
5
|
export * from "./emitPorts";
|
|
3
6
|
export * from "./executionPersistenceContracts";
|
|
@@ -6,6 +9,7 @@ export * from "./params";
|
|
|
6
9
|
export * from "./itemExpr";
|
|
7
10
|
export * from "./runtimeTypes";
|
|
8
11
|
export * from "./telemetryTypes";
|
|
12
|
+
export * from "./testTriggerTypes";
|
|
9
13
|
export * from "./runFinishedAtFactory";
|
|
10
14
|
export * from "./runTypes";
|
|
11
15
|
export * from "./webhookTypes";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TypeToken } from "../di";
|
|
2
|
-
import type { RunEventBus } from "../events/runEvents";
|
|
2
|
+
import type { RunEventBus, TestCaseRunStatus } from "../events/runEvents";
|
|
3
3
|
import type {
|
|
4
4
|
Edge,
|
|
5
5
|
InputPortKey,
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
JsonValue,
|
|
8
8
|
NodeActivationId,
|
|
9
9
|
NodeId,
|
|
10
|
+
NodeIterationId,
|
|
10
11
|
NodeKind,
|
|
11
12
|
NodeOutputs,
|
|
12
13
|
OutputPortKey,
|
|
@@ -19,6 +20,23 @@ import type {
|
|
|
19
20
|
WorkflowNodeConnection,
|
|
20
21
|
} from "./workflowTypes";
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Test-suite linkage for a run. When set, this run was started by a TestSuiteOrchestrator
|
|
25
|
+
* as one test case inside a TestSuiteRun. The `IsTestRun` node and host-side persisters key
|
|
26
|
+
* off the presence of this field. Subworkflow runs inherit it from their parent run.
|
|
27
|
+
*/
|
|
28
|
+
export interface RunTestContext {
|
|
29
|
+
readonly testSuiteRunId: string;
|
|
30
|
+
readonly testCaseIndex: number;
|
|
31
|
+
/**
|
|
32
|
+
* Optional human-friendly label for this test case (e.g. an email subject when fixtures
|
|
33
|
+
* are loaded from a mailbox). Resolved per item by `TestTrigger.caseLabel(item)` if set,
|
|
34
|
+
* persisted on `Run.test_case_label` so the Tests-tab tree-table can show "RFQ for batch 14"
|
|
35
|
+
* instead of "run_1777755971399_bbb86beac1396".
|
|
36
|
+
*/
|
|
37
|
+
readonly testCaseLabel?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
export interface RunExecutionOptions {
|
|
23
41
|
/** Run-intent override: force the inline scheduler and bypass node-level offload decisions. */
|
|
24
42
|
localOnly?: boolean;
|
|
@@ -35,6 +53,8 @@ export interface RunExecutionOptions {
|
|
|
35
53
|
maxNodeActivations?: number;
|
|
36
54
|
/** Effective cap after engine policy merge (subworkflow nesting). */
|
|
37
55
|
maxSubworkflowDepth?: number;
|
|
56
|
+
/** Present iff started by a TestSuiteOrchestrator; propagates to subworkflow runs via {@link ParentExecutionRef.testContext}. */
|
|
57
|
+
testContext?: RunTestContext;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/** Engine-owned counters persisted with the run (worker-safe). */
|
|
@@ -154,6 +174,12 @@ export interface ConnectionInvocationRecord {
|
|
|
154
174
|
readonly startedAt?: string;
|
|
155
175
|
readonly finishedAt?: string;
|
|
156
176
|
readonly updatedAt: string;
|
|
177
|
+
/** Per-item iteration id minted by the engine when this invocation occurred inside a runnable node's per-item loop. */
|
|
178
|
+
readonly iterationId?: NodeIterationId;
|
|
179
|
+
/** Item index (0-based) of the iteration that produced this invocation. */
|
|
180
|
+
readonly itemIndex?: number;
|
|
181
|
+
/** When set, this invocation was produced inside a sub-agent triggered by the named parent invocation. */
|
|
182
|
+
readonly parentInvocationId?: ConnectionInvocationId;
|
|
157
183
|
}
|
|
158
184
|
|
|
159
185
|
/** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
|
|
@@ -169,6 +195,9 @@ export type ConnectionInvocationAppendArgs = Readonly<{
|
|
|
169
195
|
queuedAt?: string;
|
|
170
196
|
startedAt?: string;
|
|
171
197
|
finishedAt?: string;
|
|
198
|
+
iterationId?: NodeIterationId;
|
|
199
|
+
itemIndex?: number;
|
|
200
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
172
201
|
}>;
|
|
173
202
|
|
|
174
203
|
export interface RunCurrentState {
|
|
@@ -210,6 +239,13 @@ export interface RunSummary {
|
|
|
210
239
|
workflowId: WorkflowId;
|
|
211
240
|
startedAt: string;
|
|
212
241
|
status: RunStatus;
|
|
242
|
+
/**
|
|
243
|
+
* Test-case status for runs dispatched as part of a TestSuiteRun. Carries the
|
|
244
|
+
* assertion-rollup-corrected outcome the test orchestrator persists onto the row, so the
|
|
245
|
+
* executions list can show "failed" for a run whose workflow completed cleanly but whose
|
|
246
|
+
* assertions caught regressions. Absent for non-test runs and legacy rows.
|
|
247
|
+
*/
|
|
248
|
+
testCaseStatus?: TestCaseRunStatus;
|
|
213
249
|
/** ISO timestamp when the run finished (derived from node snapshots or store `updatedAt`); omit while running/pending. */
|
|
214
250
|
finishedAt?: string;
|
|
215
251
|
parent?: ParentExecutionRef;
|
|
@@ -2,14 +2,17 @@ import type { ReadableStream as BinaryReadableStream } from "node:stream/web";
|
|
|
2
2
|
import type { TypeToken } from "../di";
|
|
3
3
|
import type { RunEventBus } from "../events/runEvents";
|
|
4
4
|
import type { CredentialSessionService } from "./credentialTypes";
|
|
5
|
+
import type { CollectionsContext } from "./collectionTypes";
|
|
5
6
|
import type { ExecutionTelemetry, ExecutionTelemetryFactory, NodeExecutionTelemetry } from "./telemetryTypes";
|
|
6
7
|
import type {
|
|
7
8
|
ConnectionInvocationAppendArgs,
|
|
9
|
+
ConnectionInvocationId,
|
|
8
10
|
NodeInputsByPort,
|
|
9
11
|
PersistedWorkflowSnapshot,
|
|
10
12
|
PersistedWorkflowTokenRegistryLike,
|
|
11
13
|
RunExecutionOptions,
|
|
12
14
|
RunResult,
|
|
15
|
+
RunTestContext,
|
|
13
16
|
WorkflowExecutionRepository,
|
|
14
17
|
} from "./runTypes";
|
|
15
18
|
import type { WorkflowActivationPolicy } from "./workflowActivationPolicy";
|
|
@@ -25,6 +28,7 @@ import type {
|
|
|
25
28
|
NodeActivationId,
|
|
26
29
|
NodeConfigBase,
|
|
27
30
|
NodeId,
|
|
31
|
+
NodeIterationId,
|
|
28
32
|
NodeOutputs,
|
|
29
33
|
RunnableNodeConfig,
|
|
30
34
|
OutputPortKey,
|
|
@@ -154,6 +158,21 @@ export interface ExecutionContext {
|
|
|
154
158
|
telemetry: ExecutionTelemetry;
|
|
155
159
|
binary: ExecutionBinaryService;
|
|
156
160
|
getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
|
|
161
|
+
/** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
|
|
162
|
+
iterationId?: NodeIterationId;
|
|
163
|
+
/** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
|
|
164
|
+
itemIndex?: number;
|
|
165
|
+
/** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
|
|
166
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
167
|
+
/**
|
|
168
|
+
* Present iff the run was started by a TestSuiteOrchestrator. The {@link IsTestRunNode}
|
|
169
|
+
* branches on this; assertion-emitting nodes use it to decide whether to record results.
|
|
170
|
+
*/
|
|
171
|
+
testContext?: RunTestContext;
|
|
172
|
+
/**
|
|
173
|
+
* Collections registered in the codemation config, keyed by collection name.
|
|
174
|
+
*/
|
|
175
|
+
readonly collections?: CollectionsContext;
|
|
157
176
|
}
|
|
158
177
|
|
|
159
178
|
export interface ExecutionContextFactory {
|
|
@@ -169,6 +188,7 @@ export interface ExecutionContextFactory {
|
|
|
169
188
|
nodeState?: NodeExecutionStatePublisher;
|
|
170
189
|
telemetry?: ExecutionTelemetry;
|
|
171
190
|
getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
|
|
191
|
+
testContext?: RunTestContext;
|
|
172
192
|
}): ExecutionContext;
|
|
173
193
|
}
|
|
174
194
|
|
|
@@ -180,6 +200,24 @@ export interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfi
|
|
|
180
200
|
binary: NodeBinaryAttachmentService;
|
|
181
201
|
}
|
|
182
202
|
|
|
203
|
+
export interface PollingTriggerHandle {
|
|
204
|
+
/**
|
|
205
|
+
* Start the polling loop. The runtime registers its own cleanup handle so callers do not need to
|
|
206
|
+
* call {@link TriggerSetupContext.registerCleanup} for the loop.
|
|
207
|
+
* @returns The state returned by the first cycle (or `undefined` when the overlap guard fired).
|
|
208
|
+
*/
|
|
209
|
+
start<TState, TItem>(args: {
|
|
210
|
+
intervalMs: number;
|
|
211
|
+
seedState?: TState;
|
|
212
|
+
runCycle: (cycleCtx: {
|
|
213
|
+
previousState: TState | undefined;
|
|
214
|
+
signal: AbortSignal;
|
|
215
|
+
}) => Promise<{ items: Items<TItem>; nextState: TState }>;
|
|
216
|
+
}): Promise<TState | undefined>;
|
|
217
|
+
/** Convenience dedup-window helper. */
|
|
218
|
+
readonly dedup: import("../triggers/polling/PollingTriggerDedupWindow").PollingTriggerDedupWindow;
|
|
219
|
+
}
|
|
220
|
+
|
|
183
221
|
export interface TriggerSetupContext<
|
|
184
222
|
TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>,
|
|
185
223
|
TSetupState extends JsonValue | undefined = TriggerNodeSetupState<TConfig>,
|
|
@@ -189,6 +227,8 @@ export interface TriggerSetupContext<
|
|
|
189
227
|
previousState: TSetupState;
|
|
190
228
|
registerCleanup(cleanup: TriggerCleanupHandle): void;
|
|
191
229
|
emit(items: Items): Promise<void>;
|
|
230
|
+
/** Generic polling-trigger surface. Pre-binds trigger id, emit, and registerCleanup. */
|
|
231
|
+
readonly polling: PollingTriggerHandle;
|
|
192
232
|
}
|
|
193
233
|
|
|
194
234
|
export interface TriggerTestItemsContext<
|
|
@@ -431,4 +471,6 @@ export interface EngineDeps {
|
|
|
431
471
|
workflowPolicyRuntimeDefaults?: WorkflowPolicyRuntimeDefaults;
|
|
432
472
|
/** When set, logs inactive-workflow skips at boot and trigger start/stop on activation changes. */
|
|
433
473
|
triggerRuntimeDiagnostics?: TriggerRuntimeDiagnostics;
|
|
474
|
+
/** When set, the polling-trigger runtime uses this logger for cycle info/debug/error. */
|
|
475
|
+
pollingTriggerLogger?: import("../triggers/polling/PollingTriggerLogger").PollingTriggerLogger;
|
|
434
476
|
}
|
|
@@ -73,6 +73,14 @@ export interface TelemetrySpanScope extends TelemetryScope {
|
|
|
73
73
|
readonly traceId: string;
|
|
74
74
|
readonly spanId: string;
|
|
75
75
|
end(args?: TelemetrySpanEnd): Promise<void> | void;
|
|
76
|
+
/**
|
|
77
|
+
* Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
|
|
78
|
+
* Children created via the returned telemetry's `startChildSpan` get this span as their parent.
|
|
79
|
+
*
|
|
80
|
+
* Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
|
|
81
|
+
* span instead of the orchestrator's node-level span.
|
|
82
|
+
*/
|
|
83
|
+
asNodeTelemetry(args: Readonly<{ nodeId: NodeId; activationId: NodeActivationId }>): NodeExecutionTelemetry;
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
export interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Item, NodeId, WorkflowId } from "./workflowTypes";
|
|
2
|
+
import type { TriggerNodeConfig } from "./workflowTypes";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Identifier minted by the host (or in-memory test runner) for one execution of a test suite.
|
|
6
|
+
* One TestSuiteRun produces N child workflow runs, one per item yielded by `generateItems`.
|
|
7
|
+
*/
|
|
8
|
+
export type TestSuiteRunId = string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Setup context passed to a {@link TestTriggerNodeConfig.generateItems} callback. Distinct from
|
|
12
|
+
* {@link import("./runtimeTypes").TriggerSetupContext} on purpose: test triggers are not
|
|
13
|
+
* activated by the live trigger lifecycle (webhooks, cron, polling) and never call `emit` —
|
|
14
|
+
* the orchestrator pulls from the iterable they return and dispatches one run per item.
|
|
15
|
+
*/
|
|
16
|
+
export interface TestTriggerSetupContext<
|
|
17
|
+
TConfig extends TestTriggerNodeConfig<unknown> = TestTriggerNodeConfig<unknown>,
|
|
18
|
+
> {
|
|
19
|
+
readonly workflowId: WorkflowId;
|
|
20
|
+
readonly nodeId: NodeId;
|
|
21
|
+
readonly config: TConfig;
|
|
22
|
+
readonly testSuiteRunId: TestSuiteRunId;
|
|
23
|
+
/**
|
|
24
|
+
* Resolves a credential session for a slot declared on this trigger's
|
|
25
|
+
* {@link import("./workflowTypes").NodeConfigBase.getCredentialRequirements}. Same contract as
|
|
26
|
+
* {@link import("./runtimeTypes").ExecutionContext.getCredential}.
|
|
27
|
+
*/
|
|
28
|
+
getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
|
|
29
|
+
/** AbortSignal raised when the suite is cancelled — long-running pulls should bail out. */
|
|
30
|
+
readonly signal: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A trigger config that emits **test cases**. Each item yielded by {@link generateItems}
|
|
35
|
+
* becomes one workflow run (with `executionOptions.testContext` set), so 10 yielded items
|
|
36
|
+
* → 10 runs marked under the same TestSuiteRun.
|
|
37
|
+
*
|
|
38
|
+
* The trigger is otherwise a normal {@link TriggerNodeConfig} (so the canvas treats it like
|
|
39
|
+
* any other trigger), but its `triggerKind` is `"test"` so the live activation policy skips it.
|
|
40
|
+
*/
|
|
41
|
+
export interface TestTriggerNodeConfig<TOutputJson = unknown> extends TriggerNodeConfig<TOutputJson, undefined> {
|
|
42
|
+
readonly triggerKind: "test";
|
|
43
|
+
/**
|
|
44
|
+
* Author-supplied async iterable of items, evaluated lazily. Implementations may fetch from
|
|
45
|
+
* credentialed APIs, read fixture files, or yield hard-coded items. The orchestrator iterates
|
|
46
|
+
* and dispatches one run per item, with concurrency capped by {@link concurrency} (default 4).
|
|
47
|
+
*/
|
|
48
|
+
generateItems(ctx: TestTriggerSetupContext<TestTriggerNodeConfig<TOutputJson>>): AsyncIterable<Item<TOutputJson>>;
|
|
49
|
+
/** Per-suite-run cap on simultaneously-executing test cases. Default: 4. */
|
|
50
|
+
readonly concurrency?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Free-form description of where the test cases come from — surfaced in the node properties
|
|
53
|
+
* panel and the suite-detail header so authors revisiting the workflow six months later
|
|
54
|
+
* remember which mailbox / folder / fixture file the cases originate from.
|
|
55
|
+
*
|
|
56
|
+
* Example: `"All emails in the Gmail label \"test/triage-fixtures\" — 14 messages as of 2026-05-03."`
|
|
57
|
+
*/
|
|
58
|
+
readonly description?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Resolves a human-readable label for one yielded test case (e.g. email subject). The
|
|
61
|
+
* orchestrator calls this once per yielded item, persists the result on the run, and the
|
|
62
|
+
* Tests-tab UI uses it to render the case row instead of the opaque runId. Return
|
|
63
|
+
* `undefined` to fall back to "Case #N".
|
|
64
|
+
*/
|
|
65
|
+
caseLabel?(item: Item<TOutputJson>): string | undefined;
|
|
66
|
+
}
|
|
@@ -3,13 +3,18 @@ import type { ZodType } from "zod";
|
|
|
3
3
|
import type { TypeToken } from "../di";
|
|
4
4
|
import type { CredentialRequirement } from "./credentialTypes";
|
|
5
5
|
import type { RetryPolicySpec } from "./retryPolicySpec.types";
|
|
6
|
+
import type { InputPortKey, NodeConnectionName, NodeId, OutputPortKey, WorkflowId } from "./baseTypes";
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
InputPortKey,
|
|
10
|
+
NodeConnectionName,
|
|
11
|
+
NodeId,
|
|
12
|
+
OutputPortKey,
|
|
13
|
+
PersistedTokenId,
|
|
14
|
+
WorkflowId,
|
|
15
|
+
} from "./baseTypes";
|
|
6
16
|
|
|
7
|
-
export type WorkflowId = string;
|
|
8
|
-
export type NodeId = string;
|
|
9
17
|
export type NodeIdRef<TJson = unknown> = NodeId & Readonly<{ __codemationNodeJson?: TJson }>;
|
|
10
|
-
export type OutputPortKey = string;
|
|
11
|
-
export type InputPortKey = string;
|
|
12
|
-
export type PersistedTokenId = string;
|
|
13
18
|
|
|
14
19
|
export type NodeKind = "trigger" | "node";
|
|
15
20
|
export type JsonPrimitive = string | number | boolean | null;
|
|
@@ -26,8 +31,6 @@ export interface Edge {
|
|
|
26
31
|
to: { nodeId: NodeId; input: InputPortKey };
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
export type NodeConnectionName = string;
|
|
30
|
-
|
|
31
34
|
/**
|
|
32
35
|
* Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}
|
|
33
36
|
* but are not traversed by the main execution graph. Parents are commonly executable nodes, but may
|
|
@@ -91,6 +94,14 @@ export interface NodeConfigBase {
|
|
|
91
94
|
readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
|
|
92
95
|
readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
|
|
93
96
|
getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
|
|
97
|
+
/**
|
|
98
|
+
* Marker: this node emits {@link import("./assertionTypes").AssertionResult}-shaped items on its
|
|
99
|
+
* `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for
|
|
100
|
+
* `nodeCompleted` events from nodes with this flag set, and persist their output items as
|
|
101
|
+
* TestAssertion records (only when the run carries a `testContext`). Set on assertion node
|
|
102
|
+
* configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).
|
|
103
|
+
*/
|
|
104
|
+
readonly emitsAssertions?: true;
|
|
94
105
|
}
|
|
95
106
|
|
|
96
107
|
export declare const runnableNodeInputType: unique symbol;
|
|
@@ -127,6 +138,12 @@ export interface TriggerNodeConfig<
|
|
|
127
138
|
readonly kind: "trigger";
|
|
128
139
|
readonly [triggerNodeOutputType]?: TOutputJson;
|
|
129
140
|
readonly [triggerNodeSetupStateType]?: TSetupState;
|
|
141
|
+
/**
|
|
142
|
+
* Distinguishes triggers driven by the live activation policy (webhooks, cron, polling) from
|
|
143
|
+
* triggers driven only by the {@link TestSuiteOrchestrator}. `WorkflowActivation` skips
|
|
144
|
+
* `"test"` triggers; the orchestrator skips `"live"` triggers. Defaults to `"live"` when omitted.
|
|
145
|
+
*/
|
|
146
|
+
readonly triggerKind?: "live" | "test";
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
export type RunnableNodeInputJson<TConfig extends RunnableNodeConfig<any, any>> =
|
|
@@ -194,6 +211,12 @@ export type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
|
|
|
194
211
|
|
|
195
212
|
export type RunId = string;
|
|
196
213
|
export type NodeActivationId = string;
|
|
214
|
+
/**
|
|
215
|
+
* One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
|
|
216
|
+
* per-item connection invocations and telemetry. Undefined when the executing node is a batch
|
|
217
|
+
* node or trigger that does not iterate items.
|
|
218
|
+
*/
|
|
219
|
+
export type NodeIterationId = string;
|
|
197
220
|
|
|
198
221
|
export interface ParentExecutionRef {
|
|
199
222
|
runId: RunId;
|
|
@@ -205,6 +228,12 @@ export interface ParentExecutionRef {
|
|
|
205
228
|
engineMaxNodeActivations?: number;
|
|
206
229
|
/** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
|
|
207
230
|
engineMaxSubworkflowDepth?: number;
|
|
231
|
+
/**
|
|
232
|
+
* Test-suite linkage inherited by the child subworkflow run. Set by whichever node
|
|
233
|
+
* spawns the subworkflow when its own `ctx.testContext` is present, so assertions
|
|
234
|
+
* emitted inside a subworkflow land under the correct parent test case.
|
|
235
|
+
*/
|
|
236
|
+
testContext?: import("./runTypes").RunTestContext;
|
|
208
237
|
}
|
|
209
238
|
|
|
210
239
|
export interface RunDataSnapshot {
|
package/src/contracts.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Pure-type-only re-exports. Use this for type-only consumers that should not drag in runtime DSL or factory code.
|
|
2
|
+
// This subpath prevents unnecessary compile-graph bloat for packages that only need types like NodeId, Items, etc.
|
|
3
|
+
|
|
4
|
+
export type * from "./contracts/baseTypes";
|
|
5
|
+
export type * from "./contracts/assertionTypes";
|
|
6
|
+
// assertionTypes also exports a runtime helper for deriving pass/fail from a score+threshold.
|
|
7
|
+
// We keep the type-only re-export above and surface the helper explicitly here so UI consumers
|
|
8
|
+
// (next-host) don't need to re-implement the comparison.
|
|
9
|
+
export { deriveAssertionPassed, DEFAULT_ASSERTION_PASS_THRESHOLD } from "./contracts/assertionTypes";
|
|
10
|
+
export type * from "./contracts/params";
|
|
11
|
+
export type * from "./contracts/retryPolicySpec.types";
|
|
12
|
+
export type * from "./contracts/CostCatalogContract";
|
|
13
|
+
export type * from "./contracts/executionPersistenceContracts";
|
|
14
|
+
export type * from "./contracts/runtimeTypes";
|
|
15
|
+
export type * from "./contracts/telemetryTypes";
|
|
16
|
+
export type * from "./contracts/testTriggerTypes";
|
|
17
|
+
export type * from "./contracts/runTypes";
|
|
18
|
+
export type * from "./contracts/webhookTypes";
|
|
19
|
+
export type * from "./contracts/workflowTypes";
|
|
20
|
+
|
|
21
|
+
// credentialTypes mixes types (Credential* interfaces) with runtime (CredentialUnboundError class).
|
|
22
|
+
// Export type-only subset for pure type consumers.
|
|
23
|
+
export type {
|
|
24
|
+
CredentialTypeId,
|
|
25
|
+
CredentialInstanceId,
|
|
26
|
+
CredentialMaterialSourceKind,
|
|
27
|
+
CredentialSetupStatus,
|
|
28
|
+
CredentialHealthStatus,
|
|
29
|
+
CredentialFieldSchema,
|
|
30
|
+
CredentialRequirement,
|
|
31
|
+
CredentialBindingKey,
|
|
32
|
+
CredentialBinding,
|
|
33
|
+
CredentialHealth,
|
|
34
|
+
OAuth2ProviderFromPublicConfig,
|
|
35
|
+
CredentialOAuth2ScopesFromPublicConfig,
|
|
36
|
+
CredentialOAuth2AuthDefinition,
|
|
37
|
+
CredentialAuthDefinition,
|
|
38
|
+
CredentialAdvancedSectionPresentation,
|
|
39
|
+
CredentialTypeDefinition,
|
|
40
|
+
CredentialJsonRecord,
|
|
41
|
+
CredentialInstanceRecord,
|
|
42
|
+
CredentialSessionFactoryArgs,
|
|
43
|
+
CredentialSessionFactory,
|
|
44
|
+
CredentialHealthTester,
|
|
45
|
+
CredentialType,
|
|
46
|
+
AnyCredentialType,
|
|
47
|
+
CredentialSessionService,
|
|
48
|
+
CredentialTypeRegistry,
|
|
49
|
+
} from "./contracts/credentialTypes";
|
|
50
|
+
|
|
51
|
+
// CostTrackingTelemetryContract mixes types with const runtime values (metric/attribute names).
|
|
52
|
+
// Export type-only subset for pure type consumers.
|
|
53
|
+
export type {
|
|
54
|
+
CostTrackingComponent,
|
|
55
|
+
CostTrackingUsageRecord,
|
|
56
|
+
CostTrackingPriceQuote,
|
|
57
|
+
CostTrackingTelemetry,
|
|
58
|
+
CostTrackingTelemetryFactory,
|
|
59
|
+
} from "./contracts/CostTrackingTelemetryContract";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ConnectionInvocationRecord } from "../contracts/runTypes";
|
|
2
|
+
import type { ParentExecutionRef } from "../types";
|
|
3
|
+
import type { RunEventBus } from "./runEvents";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Publishes per-invocation lifecycle records onto the run {@link RunEventBus}.
|
|
7
|
+
*
|
|
8
|
+
* Surgical, per-invocation events let the UI update the right-side inspector
|
|
9
|
+
* timeline as each LLM round / tool call transitions through `running` → `completed`
|
|
10
|
+
* (or `failed`) without depending on a coarse `runSaved` poll.
|
|
11
|
+
*/
|
|
12
|
+
export class ConnectionInvocationEventPublisher {
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly eventBus: RunEventBus | undefined,
|
|
15
|
+
private readonly parent: ParentExecutionRef | undefined,
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
async publish(record: ConnectionInvocationRecord): Promise<void> {
|
|
19
|
+
if (!this.eventBus) return;
|
|
20
|
+
const kind = this.kindFor(record);
|
|
21
|
+
if (!kind) return;
|
|
22
|
+
await this.eventBus.publish({
|
|
23
|
+
kind,
|
|
24
|
+
runId: record.runId,
|
|
25
|
+
workflowId: record.workflowId,
|
|
26
|
+
parent: this.parent,
|
|
27
|
+
at: record.updatedAt,
|
|
28
|
+
record,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private kindFor(
|
|
33
|
+
record: ConnectionInvocationRecord,
|
|
34
|
+
): "connectionInvocationStarted" | "connectionInvocationCompleted" | "connectionInvocationFailed" | undefined {
|
|
35
|
+
if (record.status === "running" || record.status === "queued") {
|
|
36
|
+
return "connectionInvocationStarted";
|
|
37
|
+
}
|
|
38
|
+
if (record.status === "completed") {
|
|
39
|
+
return "connectionInvocationCompleted";
|
|
40
|
+
}
|
|
41
|
+
if (record.status === "failed") {
|
|
42
|
+
return "connectionInvocationFailed";
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|