@boboddy/sdk 0.0.16-alpha → 0.1.0-alpha
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/client.js +0 -75
- package/dist/definitions/advancement-policies/define-advancement-policy.d.ts +218 -0
- package/dist/definitions/advancement-policies/index.d.ts +1 -0
- package/dist/definitions/advancement-policies/index.js +95 -0
- package/dist/definitions/pipelines/define-pipeline.d.ts +112 -0
- package/dist/definitions/pipelines/index.d.ts +1 -0
- package/dist/definitions/pipelines/index.js +141 -0
- package/dist/{define-step.d.ts → definitions/steps/define-step.d.ts} +16 -3
- package/dist/definitions/steps/index.d.ts +2 -0
- package/dist/{define-step.js → definitions/steps/index.js} +1368 -80
- package/dist/{step-definitions-client.d.ts → definitions/steps/step-definitions-client.d.ts} +2 -2
- package/dist/generated/index.d.ts +2 -2
- package/dist/generated/sdk.gen.d.ts +1 -23
- package/dist/generated/types.gen.d.ts +0 -1351
- package/dist/index.d.ts +2 -1
- package/dist/index.js +261 -168
- package/dist/opencode-mcp.js +94 -88
- package/package.json +27 -14
- package/dist/step-definitions-client.js +0 -1372
package/dist/client.js
CHANGED
|
@@ -890,66 +890,6 @@ class Projects extends HeyApiClient {
|
|
|
890
890
|
}
|
|
891
891
|
}
|
|
892
892
|
|
|
893
|
-
class RuntimeSessions extends HeyApiClient {
|
|
894
|
-
listRuntimeSessions(options) {
|
|
895
|
-
return (options.client ?? this.client).get({ url: "/api/projects/{projectId}/runtime-sessions", ...options });
|
|
896
|
-
}
|
|
897
|
-
createRuntimeSession(options) {
|
|
898
|
-
return (options.client ?? this.client).post({
|
|
899
|
-
url: "/api/projects/{projectId}/runtime-sessions",
|
|
900
|
-
...options,
|
|
901
|
-
headers: {
|
|
902
|
-
"Content-Type": "application/json",
|
|
903
|
-
...options.headers
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
getRuntimeSession(options) {
|
|
908
|
-
return (options.client ?? this.client).get({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}", ...options });
|
|
909
|
-
}
|
|
910
|
-
stopRuntimeSession(options) {
|
|
911
|
-
return (options.client ?? this.client).post({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/stop", ...options });
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
class RuntimeServices extends HeyApiClient {
|
|
916
|
-
createRuntimeService(options) {
|
|
917
|
-
return (options.client ?? this.client).post({
|
|
918
|
-
url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/services",
|
|
919
|
-
...options,
|
|
920
|
-
headers: {
|
|
921
|
-
"Content-Type": "application/json",
|
|
922
|
-
...options.headers
|
|
923
|
-
}
|
|
924
|
-
});
|
|
925
|
-
}
|
|
926
|
-
getRuntimeService(options) {
|
|
927
|
-
return (options.client ?? this.client).get({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/services/{runtimeServiceId}", ...options });
|
|
928
|
-
}
|
|
929
|
-
startRuntimeService(options) {
|
|
930
|
-
return (options.client ?? this.client).post({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/services/{runtimeServiceId}/start", ...options });
|
|
931
|
-
}
|
|
932
|
-
stopRuntimeService(options) {
|
|
933
|
-
return (options.client ?? this.client).post({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/services/{runtimeServiceId}/stop", ...options });
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
class RuntimeCommands extends HeyApiClient {
|
|
938
|
-
createRuntimeCommand(options) {
|
|
939
|
-
return (options.client ?? this.client).post({
|
|
940
|
-
url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/commands",
|
|
941
|
-
...options,
|
|
942
|
-
headers: {
|
|
943
|
-
"Content-Type": "application/json",
|
|
944
|
-
...options.headers
|
|
945
|
-
}
|
|
946
|
-
});
|
|
947
|
-
}
|
|
948
|
-
runRuntimeCommand(options) {
|
|
949
|
-
return (options.client ?? this.client).post({ url: "/api/projects/{projectId}/runtime-sessions/{runtimeSessionId}/commands/{runtimeCommandId}/run", ...options });
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
|
|
953
893
|
class StepDefinitions extends HeyApiClient {
|
|
954
894
|
listStepDefinitions(options) {
|
|
955
895
|
return (options.client ?? this.client).get({ url: "/api/step-definitions", ...options });
|
|
@@ -1284,18 +1224,6 @@ class BoboddyClient extends HeyApiClient {
|
|
|
1284
1224
|
get projects() {
|
|
1285
1225
|
return this._projects ??= new Projects({ client: this.client });
|
|
1286
1226
|
}
|
|
1287
|
-
_runtimeSessions;
|
|
1288
|
-
get runtimeSessions() {
|
|
1289
|
-
return this._runtimeSessions ??= new RuntimeSessions({ client: this.client });
|
|
1290
|
-
}
|
|
1291
|
-
_runtimeServices;
|
|
1292
|
-
get runtimeServices() {
|
|
1293
|
-
return this._runtimeServices ??= new RuntimeServices({ client: this.client });
|
|
1294
|
-
}
|
|
1295
|
-
_runtimeCommands;
|
|
1296
|
-
get runtimeCommands() {
|
|
1297
|
-
return this._runtimeCommands ??= new RuntimeCommands({ client: this.client });
|
|
1298
|
-
}
|
|
1299
1227
|
_stepDefinitions;
|
|
1300
1228
|
get stepDefinitions() {
|
|
1301
1229
|
return this._stepDefinitions ??= new StepDefinitions({ client: this.client });
|
|
@@ -1406,9 +1334,6 @@ export {
|
|
|
1406
1334
|
StepExecutions,
|
|
1407
1335
|
StepDefinitions,
|
|
1408
1336
|
StepDefinitionTemplates,
|
|
1409
|
-
RuntimeSessions,
|
|
1410
|
-
RuntimeServices,
|
|
1411
|
-
RuntimeCommands,
|
|
1412
1337
|
Projects,
|
|
1413
1338
|
ProjectContext,
|
|
1414
1339
|
PipelineExecutions,
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comparison operators supported by json-rules-engine.
|
|
3
|
+
* These map directly to the operator names the runtime evaluates against signal values.
|
|
4
|
+
*/
|
|
5
|
+
export type ConditionOperator = "equal" | "notEqual" | "lessThan" | "lessThanInclusive" | "greaterThan" | "greaterThanInclusive" | "in" | "notIn" | "contains" | "doesNotContain";
|
|
6
|
+
/** All possible outcomes a step can resolve to after policy evaluation. */
|
|
7
|
+
export type AdvancementEventType = "continue" | "block" | "needs_review" | "complete";
|
|
8
|
+
/**
|
|
9
|
+
* The outcome emitted when a rule fires (or when no rules match and
|
|
10
|
+
* `defaultOutcome` is used).
|
|
11
|
+
*
|
|
12
|
+
* Shorthand — use when no extra params are needed:
|
|
13
|
+
* "continue"
|
|
14
|
+
*
|
|
15
|
+
* Object form — use when the outcome carries additional context the runtime
|
|
16
|
+
* or downstream steps should receive:
|
|
17
|
+
* { outcome: "needs_review", outcomeJson: { reason: "low confidence" } }
|
|
18
|
+
*/
|
|
19
|
+
export type AdvancementOutcome = AdvancementEventType | {
|
|
20
|
+
outcome: AdvancementEventType;
|
|
21
|
+
outcomeJson?: Record<string, unknown> | null;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A leaf condition that checks a single signal value against a given operator
|
|
25
|
+
* and value. Used directly inside `Rule.all()` / `Rule.any()`, or implicitly
|
|
26
|
+
* by `Rule.when()`.
|
|
27
|
+
*
|
|
28
|
+
* `TSignalKeys` is constrained to the declaring step's signal keys, so the
|
|
29
|
+
* `signal` field is validated at compile time.
|
|
30
|
+
*/
|
|
31
|
+
export type SignalCondition<TSignalKeys extends string = string> = {
|
|
32
|
+
readonly _tag: "signal";
|
|
33
|
+
signal: TSignalKeys;
|
|
34
|
+
operator: ConditionOperator;
|
|
35
|
+
value: unknown;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* A condition group where ALL nested conditions must match.
|
|
39
|
+
* Created by calling `Rule.all()` without an outcome argument.
|
|
40
|
+
* Can itself be nested inside another `Rule.all()` or `Rule.any()`.
|
|
41
|
+
*/
|
|
42
|
+
export type AllCondition<TSignalKeys extends string = string> = {
|
|
43
|
+
readonly _tag: "all";
|
|
44
|
+
conditions: RuleCondition<TSignalKeys>[];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A condition group where ANY nested condition must match.
|
|
48
|
+
* Created by calling `Rule.any()` without an outcome argument.
|
|
49
|
+
* Can itself be nested inside another `Rule.all()` or `Rule.any()`.
|
|
50
|
+
*/
|
|
51
|
+
export type AnyCondition<TSignalKeys extends string = string> = {
|
|
52
|
+
readonly _tag: "any";
|
|
53
|
+
conditions: RuleCondition<TSignalKeys>[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Anything that can appear inside `Rule.all()` or `Rule.any()` — either a leaf
|
|
57
|
+
* signal condition or a nested all/any group.
|
|
58
|
+
*/
|
|
59
|
+
export type RuleCondition<TSignalKeys extends string = string> = SignalCondition<TSignalKeys> | AllCondition<TSignalKeys> | AnyCondition<TSignalKeys>;
|
|
60
|
+
/**
|
|
61
|
+
* A complete advancement rule: one or more conditions evaluated in `all` or
|
|
62
|
+
* `any` mode, plus the outcome emitted when the rule fires.
|
|
63
|
+
*
|
|
64
|
+
* Rules are created via the `Rule` namespace — `Rule.when()`, `Rule.all()`,
|
|
65
|
+
* `Rule.any()`. They are not constructed directly.
|
|
66
|
+
*/
|
|
67
|
+
export type Rule<TSignalKeys extends string = string> = {
|
|
68
|
+
readonly _tag: "rule";
|
|
69
|
+
mode: "all" | "any";
|
|
70
|
+
conditions: RuleCondition<TSignalKeys>[];
|
|
71
|
+
outcome: AdvancementOutcome;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Creates a leaf signal condition for use inside `Rule.all()` or `Rule.any()`.
|
|
75
|
+
* Not a rule itself — no outcome is attached.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* Rule.all([
|
|
79
|
+
* Rule.signal("score", "greaterThanInclusive", 80),
|
|
80
|
+
* Rule.signal("flagged", "equal", false),
|
|
81
|
+
* ], "continue")
|
|
82
|
+
*/
|
|
83
|
+
declare function signal<TSignalKeys extends string>(signal: TSignalKeys, operator: ConditionOperator, value: unknown): SignalCondition<TSignalKeys>;
|
|
84
|
+
/**
|
|
85
|
+
* When called with only `conditions`: returns a nested `AllCondition` group
|
|
86
|
+
* for use inside another `Rule.all()` or `Rule.any()`.
|
|
87
|
+
*
|
|
88
|
+
* When called with `conditions` and `outcome`: returns a top-level `Rule` that
|
|
89
|
+
* fires when ALL conditions match.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* // Top-level rule
|
|
93
|
+
* Rule.all([Rule.signal("passed", "equal", true)], "continue")
|
|
94
|
+
*
|
|
95
|
+
* // Nested inside Rule.any
|
|
96
|
+
* Rule.any([
|
|
97
|
+
* Rule.all([
|
|
98
|
+
* Rule.signal("score", "greaterThan", 90),
|
|
99
|
+
* Rule.signal("flagged", "equal", false),
|
|
100
|
+
* ]),
|
|
101
|
+
* Rule.signal("override", "equal", true),
|
|
102
|
+
* ], "continue")
|
|
103
|
+
*/
|
|
104
|
+
declare function all<TSignalKeys extends string>(conditions: RuleCondition<TSignalKeys>[]): AllCondition<TSignalKeys>;
|
|
105
|
+
declare function all<TSignalKeys extends string>(conditions: RuleCondition<TSignalKeys>[], outcome: AdvancementOutcome): Rule<TSignalKeys>;
|
|
106
|
+
/**
|
|
107
|
+
* When called with only `conditions`: returns a nested `AnyCondition` group
|
|
108
|
+
* for use inside another `Rule.all()` or `Rule.any()`.
|
|
109
|
+
*
|
|
110
|
+
* When called with `conditions` and `outcome`: returns a top-level `Rule` that
|
|
111
|
+
* fires when ANY condition matches.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // Top-level rule
|
|
115
|
+
* Rule.any([
|
|
116
|
+
* Rule.signal("score", "greaterThan", 90),
|
|
117
|
+
* Rule.signal("override", "equal", true),
|
|
118
|
+
* ], "continue")
|
|
119
|
+
*
|
|
120
|
+
* // Nested inside Rule.all
|
|
121
|
+
* Rule.all([
|
|
122
|
+
* Rule.signal("score", "greaterThanInclusive", 80),
|
|
123
|
+
* Rule.any([
|
|
124
|
+
* Rule.signal("reviewerApproved", "equal", true),
|
|
125
|
+
* Rule.signal("autoApproved", "equal", true),
|
|
126
|
+
* ]),
|
|
127
|
+
* ], "continue")
|
|
128
|
+
*/
|
|
129
|
+
declare function any<TSignalKeys extends string>(conditions: RuleCondition<TSignalKeys>[]): AnyCondition<TSignalKeys>;
|
|
130
|
+
declare function any<TSignalKeys extends string>(conditions: RuleCondition<TSignalKeys>[], outcome: AdvancementOutcome): Rule<TSignalKeys>;
|
|
131
|
+
/**
|
|
132
|
+
* Shorthand for a single-condition rule. Equivalent to
|
|
133
|
+
* `Rule.all([Rule.signal(signal, operator, value)], outcome)`.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* Rule.when("passed", "equal", true, "continue")
|
|
137
|
+
* Rule.when("score", "greaterThanInclusive", 80, { outcome: "continue", outcomeJson: { via: "score" } })
|
|
138
|
+
*/
|
|
139
|
+
declare function when<TSignalKeys extends string>(signal: TSignalKeys, operator: ConditionOperator, value: unknown, outcome: AdvancementOutcome): Rule<TSignalKeys>;
|
|
140
|
+
/**
|
|
141
|
+
* All factories for building advancement rules.
|
|
142
|
+
*
|
|
143
|
+
* - `Rule.signal` — leaf condition (used inside `all` / `any`)
|
|
144
|
+
* - `Rule.all` — all conditions must match; nestable
|
|
145
|
+
* - `Rule.any` — any condition must match; nestable
|
|
146
|
+
* - `Rule.when` — shorthand for a single-signal rule
|
|
147
|
+
*/
|
|
148
|
+
export declare const Rule: {
|
|
149
|
+
readonly signal: typeof signal;
|
|
150
|
+
readonly all: typeof all;
|
|
151
|
+
readonly any: typeof any;
|
|
152
|
+
readonly when: typeof when;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Controls when and how a pipeline step advances.
|
|
156
|
+
*
|
|
157
|
+
* Rules are evaluated in order; the first match wins. If no rule fires,
|
|
158
|
+
* the step resolves to `defaultOutcome`.
|
|
159
|
+
*
|
|
160
|
+
* `TSignalKeys` is inferred from the step's declared signals, which constrains
|
|
161
|
+
* all `Rule.signal()` / `Rule.when()` calls to only valid signal keys.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* {
|
|
165
|
+
* defaultOutcome: "block",
|
|
166
|
+
* rules: [
|
|
167
|
+
* Rule.when("passed", "equal", true, "continue"),
|
|
168
|
+
* Rule.all([
|
|
169
|
+
* Rule.signal("score", "greaterThanInclusive", 80),
|
|
170
|
+
* Rule.any([
|
|
171
|
+
* Rule.signal("reviewerApproved", "equal", true),
|
|
172
|
+
* Rule.signal("autoApproved", "equal", true),
|
|
173
|
+
* ]),
|
|
174
|
+
* ], "continue"),
|
|
175
|
+
* ],
|
|
176
|
+
* }
|
|
177
|
+
*/
|
|
178
|
+
export type AdvancementPolicy<TSignalKeys extends string = string> = {
|
|
179
|
+
/**
|
|
180
|
+
* The outcome emitted when no rule matches.
|
|
181
|
+
* "continue" — step advances automatically.
|
|
182
|
+
* "block" — step waits for human intervention.
|
|
183
|
+
*/
|
|
184
|
+
defaultOutcome: AdvancementOutcome;
|
|
185
|
+
/**
|
|
186
|
+
* Ordered list of rules evaluated against the step's signal values.
|
|
187
|
+
* First match wins; unmatched falls through to `defaultOutcome`.
|
|
188
|
+
*/
|
|
189
|
+
rules?: Rule<TSignalKeys>[];
|
|
190
|
+
};
|
|
191
|
+
type SerializedLeafCondition = {
|
|
192
|
+
fact: string;
|
|
193
|
+
operator: string;
|
|
194
|
+
value: unknown;
|
|
195
|
+
};
|
|
196
|
+
type SerializedConditionGroup = {
|
|
197
|
+
all?: SerializedCondition[];
|
|
198
|
+
any?: SerializedCondition[];
|
|
199
|
+
};
|
|
200
|
+
type SerializedCondition = SerializedLeafCondition | SerializedConditionGroup;
|
|
201
|
+
type SerializedRule = {
|
|
202
|
+
conditions: SerializedConditionGroup;
|
|
203
|
+
event: {
|
|
204
|
+
type: string;
|
|
205
|
+
params?: Record<string, unknown>;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
/** Serialized shape expected by the boboddy runtime API. */
|
|
209
|
+
export type SerializedAdvancementPolicy = {
|
|
210
|
+
rulesJson: {
|
|
211
|
+
rules: SerializedRule[];
|
|
212
|
+
};
|
|
213
|
+
defaultEventType: AdvancementEventType;
|
|
214
|
+
defaultEventParamsJson: Record<string, unknown> | null;
|
|
215
|
+
allowedEventTypes: AdvancementEventType[];
|
|
216
|
+
};
|
|
217
|
+
export declare function serializeAdvancementPolicy(policy: AdvancementPolicy | undefined): SerializedAdvancementPolicy;
|
|
218
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./define-advancement-policy";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __returnValue = (v) => v;
|
|
3
|
+
function __exportSetter(name, newValue) {
|
|
4
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
5
|
+
}
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
set: __exportSetter.bind(all, name)
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/definitions/advancement-policies/define-advancement-policy.ts
|
|
17
|
+
function signal(signal2, operator, value) {
|
|
18
|
+
return { _tag: "signal", signal: signal2, operator, value };
|
|
19
|
+
}
|
|
20
|
+
function all(conditions, outcome) {
|
|
21
|
+
if (outcome === undefined) {
|
|
22
|
+
return { _tag: "all", conditions };
|
|
23
|
+
}
|
|
24
|
+
return { _tag: "rule", mode: "all", conditions, outcome };
|
|
25
|
+
}
|
|
26
|
+
function any(conditions, outcome) {
|
|
27
|
+
if (outcome === undefined) {
|
|
28
|
+
return { _tag: "any", conditions };
|
|
29
|
+
}
|
|
30
|
+
return { _tag: "rule", mode: "any", conditions, outcome };
|
|
31
|
+
}
|
|
32
|
+
function when(signal2, operator, value, outcome) {
|
|
33
|
+
return {
|
|
34
|
+
_tag: "rule",
|
|
35
|
+
mode: "all",
|
|
36
|
+
conditions: [{ _tag: "signal", signal: signal2, operator, value }],
|
|
37
|
+
outcome
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
var Rule = { signal, all, any, when };
|
|
41
|
+
function resolveOutcome(outcome) {
|
|
42
|
+
if (typeof outcome === "string") {
|
|
43
|
+
return { type: outcome, params: null };
|
|
44
|
+
}
|
|
45
|
+
return { type: outcome.outcome, params: outcome.outcomeJson ?? null };
|
|
46
|
+
}
|
|
47
|
+
function serializeCondition(condition) {
|
|
48
|
+
if (condition._tag === "signal") {
|
|
49
|
+
return {
|
|
50
|
+
fact: condition.signal,
|
|
51
|
+
operator: condition.operator,
|
|
52
|
+
value: condition.value
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (condition._tag === "all") {
|
|
56
|
+
return { all: condition.conditions.map(serializeCondition) };
|
|
57
|
+
}
|
|
58
|
+
return { any: condition.conditions.map(serializeCondition) };
|
|
59
|
+
}
|
|
60
|
+
function serializeRule(rule) {
|
|
61
|
+
const resolved = resolveOutcome(rule.outcome);
|
|
62
|
+
return {
|
|
63
|
+
conditions: { [rule.mode]: rule.conditions.map(serializeCondition) },
|
|
64
|
+
event: {
|
|
65
|
+
type: resolved.type,
|
|
66
|
+
...resolved.params ? { params: resolved.params } : {}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function serializeAdvancementPolicy(policy) {
|
|
71
|
+
if (!policy) {
|
|
72
|
+
return {
|
|
73
|
+
rulesJson: { rules: [] },
|
|
74
|
+
defaultEventType: "continue",
|
|
75
|
+
defaultEventParamsJson: null,
|
|
76
|
+
allowedEventTypes: ["continue"]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const defaultResolved = resolveOutcome(policy.defaultOutcome);
|
|
80
|
+
const outcomeSet = new Set([defaultResolved.type]);
|
|
81
|
+
const serializedRules = (policy.rules ?? []).map((rule) => {
|
|
82
|
+
outcomeSet.add(resolveOutcome(rule.outcome).type);
|
|
83
|
+
return serializeRule(rule);
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
rulesJson: { rules: serializedRules },
|
|
87
|
+
defaultEventType: defaultResolved.type,
|
|
88
|
+
defaultEventParamsJson: defaultResolved.params,
|
|
89
|
+
allowedEventTypes: [...outcomeSet]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
serializeAdvancementPolicy,
|
|
94
|
+
Rule
|
|
95
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { DotPaths, TypedStepDefinitionSpec } from "../steps/define-step";
|
|
3
|
+
import { type AdvancementPolicy, type SerializedAdvancementPolicy } from "../advancement-policies/define-advancement-policy";
|
|
4
|
+
export type { AdvancementPolicy } from "../advancement-policies/define-advancement-policy";
|
|
5
|
+
export { Rule } from "../advancement-policies/define-advancement-policy";
|
|
6
|
+
type AnyTypedStep = TypedStepDefinitionSpec<any, any, any>;
|
|
7
|
+
export type PipelineInputBinding = {
|
|
8
|
+
source: "pipeline_input";
|
|
9
|
+
path: string;
|
|
10
|
+
};
|
|
11
|
+
export type StepSignalBinding = {
|
|
12
|
+
source: "step_signal";
|
|
13
|
+
step: AnyTypedStep;
|
|
14
|
+
signalKey: string;
|
|
15
|
+
};
|
|
16
|
+
export type StepOutputBinding = {
|
|
17
|
+
source: "step_output";
|
|
18
|
+
step: AnyTypedStep;
|
|
19
|
+
};
|
|
20
|
+
export type AnyBinding = PipelineInputBinding | StepSignalBinding | StepOutputBinding;
|
|
21
|
+
/**
|
|
22
|
+
* Binds a step input field to a field of the pipeline's top-level input.
|
|
23
|
+
* The `path` is validated against the pipeline input schema at compile time.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fromPipelineInput<T extends ZodType>(_schema: T, path: DotPaths<T["_output"]>): PipelineInputBinding;
|
|
26
|
+
/**
|
|
27
|
+
* Binds a step input field to a named signal from a prior step.
|
|
28
|
+
* `signalKey` is validated against the prior step's declared signal keys.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fromSignal<TStep extends AnyTypedStep>(step: TStep, signalKey: TStep["__signalKeys"]): StepSignalBinding;
|
|
31
|
+
/**
|
|
32
|
+
* Binds a step input field to the entire agent output of a prior step.
|
|
33
|
+
* Use this when your consumer handles the full output object directly.
|
|
34
|
+
* For a stable contract, prefer fromSignal() instead.
|
|
35
|
+
*/
|
|
36
|
+
export declare function stepOutput(step: AnyTypedStep): StepOutputBinding;
|
|
37
|
+
export type PipelineStepConfig<TStep extends AnyTypedStep = AnyTypedStep> = {
|
|
38
|
+
step: TStep;
|
|
39
|
+
/** Maps each step input field to an input source. Extra keys are ignored at runtime. */
|
|
40
|
+
input?: Partial<{
|
|
41
|
+
[K in keyof NonNullable<TStep["__inputType"]> & string]: AnyBinding;
|
|
42
|
+
}>;
|
|
43
|
+
timeout?: number | null;
|
|
44
|
+
/**
|
|
45
|
+
* Controls when and how this step advances in the pipeline.
|
|
46
|
+
* Signal keys in `whenSignal()` rules are type-checked against this step's declared signals.
|
|
47
|
+
* Defaults to `{ defaultOutcome: "continue" }` when omitted.
|
|
48
|
+
*/
|
|
49
|
+
advancement?: AdvancementPolicy<TStep["__signalKeys"]>;
|
|
50
|
+
};
|
|
51
|
+
type SerializedBinding = {
|
|
52
|
+
source: "pipeline_input";
|
|
53
|
+
path: string;
|
|
54
|
+
} | {
|
|
55
|
+
source: "step_signal";
|
|
56
|
+
stepKey: string;
|
|
57
|
+
signalKey: string;
|
|
58
|
+
} | {
|
|
59
|
+
source: "step_output";
|
|
60
|
+
stepKey: string;
|
|
61
|
+
};
|
|
62
|
+
export type PipelineDefinitionSpec = {
|
|
63
|
+
key: string;
|
|
64
|
+
name: string;
|
|
65
|
+
description: string | null;
|
|
66
|
+
version: number;
|
|
67
|
+
status: "draft" | "active" | "archived";
|
|
68
|
+
steps: Array<{
|
|
69
|
+
stepKey: string;
|
|
70
|
+
stepName: string;
|
|
71
|
+
stepDescription: string | null;
|
|
72
|
+
position: number;
|
|
73
|
+
inputBindingsJson: Record<string, SerializedBinding>;
|
|
74
|
+
timeoutSeconds: number | null;
|
|
75
|
+
advancementPolicyDefinition: SerializedAdvancementPolicy;
|
|
76
|
+
}>;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Untyped input shape used for documentation and as the internal implementation
|
|
80
|
+
* target. Call sites use the generic overload below which provides per-step
|
|
81
|
+
* signal key validation.
|
|
82
|
+
*/
|
|
83
|
+
export type DefinePipelineInput = {
|
|
84
|
+
key: string;
|
|
85
|
+
name: string;
|
|
86
|
+
description?: string | null;
|
|
87
|
+
version?: number;
|
|
88
|
+
status?: "draft" | "active";
|
|
89
|
+
steps: Array<PipelineStepConfig>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Defines a pipeline from an ordered list of step configs.
|
|
93
|
+
*
|
|
94
|
+
* Each step's `advancement` policy is typed against that step's declared signal
|
|
95
|
+
* keys — passing an unknown signal key to `whenSignal()` is a compile-time error.
|
|
96
|
+
*
|
|
97
|
+
* TypeScript achieves per-element signal key checking by constraining `TSteps`
|
|
98
|
+
* to a tuple of step instances (`AnyTypedStep[]`), not step configs. Each element
|
|
99
|
+
* of `steps` is then typed as `PipelineStepConfig<TSteps[K]>`, giving TypeScript
|
|
100
|
+
* a direct inference site: `step: TSteps[K]` matches the concrete step instance,
|
|
101
|
+
* which carries the signal key union via `__signalKeys`.
|
|
102
|
+
*/
|
|
103
|
+
export declare function definePipeline<const TSteps extends ReadonlyArray<AnyTypedStep>>(config: {
|
|
104
|
+
key: string;
|
|
105
|
+
name: string;
|
|
106
|
+
description?: string | null;
|
|
107
|
+
version?: number;
|
|
108
|
+
status?: "draft" | "active";
|
|
109
|
+
steps: {
|
|
110
|
+
[K in keyof TSteps]: PipelineStepConfig<TSteps[K]>;
|
|
111
|
+
};
|
|
112
|
+
}): PipelineDefinitionSpec;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./define-pipeline";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __returnValue = (v) => v;
|
|
3
|
+
function __exportSetter(name, newValue) {
|
|
4
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
5
|
+
}
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
set: __exportSetter.bind(all, name)
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/definitions/advancement-policies/define-advancement-policy.ts
|
|
17
|
+
function signal(signal2, operator, value) {
|
|
18
|
+
return { _tag: "signal", signal: signal2, operator, value };
|
|
19
|
+
}
|
|
20
|
+
function all(conditions, outcome) {
|
|
21
|
+
if (outcome === undefined) {
|
|
22
|
+
return { _tag: "all", conditions };
|
|
23
|
+
}
|
|
24
|
+
return { _tag: "rule", mode: "all", conditions, outcome };
|
|
25
|
+
}
|
|
26
|
+
function any(conditions, outcome) {
|
|
27
|
+
if (outcome === undefined) {
|
|
28
|
+
return { _tag: "any", conditions };
|
|
29
|
+
}
|
|
30
|
+
return { _tag: "rule", mode: "any", conditions, outcome };
|
|
31
|
+
}
|
|
32
|
+
function when(signal2, operator, value, outcome) {
|
|
33
|
+
return {
|
|
34
|
+
_tag: "rule",
|
|
35
|
+
mode: "all",
|
|
36
|
+
conditions: [{ _tag: "signal", signal: signal2, operator, value }],
|
|
37
|
+
outcome
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
var Rule = { signal, all, any, when };
|
|
41
|
+
function resolveOutcome(outcome) {
|
|
42
|
+
if (typeof outcome === "string") {
|
|
43
|
+
return { type: outcome, params: null };
|
|
44
|
+
}
|
|
45
|
+
return { type: outcome.outcome, params: outcome.outcomeJson ?? null };
|
|
46
|
+
}
|
|
47
|
+
function serializeCondition(condition) {
|
|
48
|
+
if (condition._tag === "signal") {
|
|
49
|
+
return {
|
|
50
|
+
fact: condition.signal,
|
|
51
|
+
operator: condition.operator,
|
|
52
|
+
value: condition.value
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (condition._tag === "all") {
|
|
56
|
+
return { all: condition.conditions.map(serializeCondition) };
|
|
57
|
+
}
|
|
58
|
+
return { any: condition.conditions.map(serializeCondition) };
|
|
59
|
+
}
|
|
60
|
+
function serializeRule(rule) {
|
|
61
|
+
const resolved = resolveOutcome(rule.outcome);
|
|
62
|
+
return {
|
|
63
|
+
conditions: { [rule.mode]: rule.conditions.map(serializeCondition) },
|
|
64
|
+
event: {
|
|
65
|
+
type: resolved.type,
|
|
66
|
+
...resolved.params ? { params: resolved.params } : {}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function serializeAdvancementPolicy(policy) {
|
|
71
|
+
if (!policy) {
|
|
72
|
+
return {
|
|
73
|
+
rulesJson: { rules: [] },
|
|
74
|
+
defaultEventType: "continue",
|
|
75
|
+
defaultEventParamsJson: null,
|
|
76
|
+
allowedEventTypes: ["continue"]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const defaultResolved = resolveOutcome(policy.defaultOutcome);
|
|
80
|
+
const outcomeSet = new Set([defaultResolved.type]);
|
|
81
|
+
const serializedRules = (policy.rules ?? []).map((rule) => {
|
|
82
|
+
outcomeSet.add(resolveOutcome(rule.outcome).type);
|
|
83
|
+
return serializeRule(rule);
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
rulesJson: { rules: serializedRules },
|
|
87
|
+
defaultEventType: defaultResolved.type,
|
|
88
|
+
defaultEventParamsJson: defaultResolved.params,
|
|
89
|
+
allowedEventTypes: [...outcomeSet]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/definitions/pipelines/define-pipeline.ts
|
|
94
|
+
function fromPipelineInput(_schema, path) {
|
|
95
|
+
return { source: "pipeline_input", path };
|
|
96
|
+
}
|
|
97
|
+
function fromSignal(step, signalKey) {
|
|
98
|
+
return { source: "step_signal", step, signalKey };
|
|
99
|
+
}
|
|
100
|
+
function stepOutput(step) {
|
|
101
|
+
return { source: "step_output", step };
|
|
102
|
+
}
|
|
103
|
+
function serializeBinding(binding) {
|
|
104
|
+
if (binding.source === "pipeline_input") {
|
|
105
|
+
return { source: "pipeline_input", path: binding.path };
|
|
106
|
+
}
|
|
107
|
+
if (binding.source === "step_signal") {
|
|
108
|
+
return {
|
|
109
|
+
source: "step_signal",
|
|
110
|
+
stepKey: binding.step.key,
|
|
111
|
+
signalKey: binding.signalKey
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return { source: "step_output", stepKey: binding.step.key };
|
|
115
|
+
}
|
|
116
|
+
function definePipeline(config) {
|
|
117
|
+
const steps = config.steps;
|
|
118
|
+
return {
|
|
119
|
+
key: config.key,
|
|
120
|
+
name: config.name,
|
|
121
|
+
description: config.description ?? null,
|
|
122
|
+
version: config.version ?? 1,
|
|
123
|
+
status: config.status ?? "active",
|
|
124
|
+
steps: steps.map((stepConfig, index) => ({
|
|
125
|
+
stepKey: stepConfig.step.key,
|
|
126
|
+
stepName: stepConfig.step.name,
|
|
127
|
+
stepDescription: stepConfig.step.description,
|
|
128
|
+
position: index + 1,
|
|
129
|
+
inputBindingsJson: Object.fromEntries(Object.entries(stepConfig.input ?? {}).filter((entry) => entry[1] !== undefined).map(([key, binding]) => [key, serializeBinding(binding)])),
|
|
130
|
+
timeoutSeconds: stepConfig.timeout ?? null,
|
|
131
|
+
advancementPolicyDefinition: serializeAdvancementPolicy(stepConfig.advancement)
|
|
132
|
+
}))
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export {
|
|
136
|
+
stepOutput,
|
|
137
|
+
fromSignal,
|
|
138
|
+
fromPipelineInput,
|
|
139
|
+
definePipeline,
|
|
140
|
+
Rule
|
|
141
|
+
};
|