@granular-software/sdk 0.4.63 → 0.4.65
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/agent-evals.d.mts +2 -2
- package/dist/agent-evals.d.ts +2 -2
- package/dist/agent-evals.js +713 -65
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +713 -65
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +713 -65
- package/dist/{client-lk-dmdKR.d.mts → client-S-z8bri1.d.mts} +47 -1
- package/dist/{client-KqJIH7WE.d.ts → client-z6shQivt.d.ts} +47 -1
- package/dist/index.d.mts +72 -5
- package/dist/index.d.ts +72 -5
- package/dist/index.js +1058 -83
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1052 -84
- package/dist/index.mjs.map +1 -1
- package/dist/{spend-DtsHRNb5.d.mts → spend-CESUvrZC.d.mts} +239 -4
- package/dist/{spend-DtsHRNb5.d.ts → spend-CESUvrZC.d.ts} +239 -4
- package/dist/spend.d.mts +1 -1
- package/dist/spend.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6533,6 +6533,11 @@ var Session = class {
|
|
|
6533
6533
|
}
|
|
6534
6534
|
}
|
|
6535
6535
|
buildDirectedInvocationEffectContext(params, feedbackContext) {
|
|
6536
|
+
const commitUnavailable = async () => {
|
|
6537
|
+
throw new Error(
|
|
6538
|
+
"This directed browser tool invocation has no product commit transport"
|
|
6539
|
+
);
|
|
6540
|
+
};
|
|
6536
6541
|
return {
|
|
6537
6542
|
effectClientId: this.clientId,
|
|
6538
6543
|
sandboxId: params.sandboxId || "",
|
|
@@ -6545,6 +6550,10 @@ var Session = class {
|
|
|
6545
6550
|
userId: "",
|
|
6546
6551
|
subjectId: ""
|
|
6547
6552
|
},
|
|
6553
|
+
commit: {
|
|
6554
|
+
effect: commitUnavailable,
|
|
6555
|
+
transition: commitUnavailable
|
|
6556
|
+
},
|
|
6548
6557
|
...feedbackContext ? {
|
|
6549
6558
|
feedback: feedbackContext.feedback,
|
|
6550
6559
|
transientFeedback: feedbackContext.transientFeedback
|
|
@@ -12197,8 +12206,12 @@ external_exports.union([
|
|
|
12197
12206
|
external_exports.array(external_exports.string()),
|
|
12198
12207
|
external_exports.object({
|
|
12199
12208
|
values: external_exports.array(external_exports.string()),
|
|
12209
|
+
labels: external_exports.array(external_exports.string().min(1)).optional(),
|
|
12200
12210
|
message: external_exports.string().optional()
|
|
12201
|
-
}).strict()
|
|
12211
|
+
}).strict().refine(
|
|
12212
|
+
(rule) => !rule.labels || rule.labels.length === rule.values.length,
|
|
12213
|
+
{ message: "Enum labels must match enum values one-for-one" }
|
|
12214
|
+
)
|
|
12202
12215
|
]);
|
|
12203
12216
|
external_exports.union([
|
|
12204
12217
|
external_exports.boolean(),
|
|
@@ -12226,7 +12239,7 @@ var StateMachineStateSchema = external_exports.union([
|
|
|
12226
12239
|
external_exports.string(),
|
|
12227
12240
|
external_exports.object({
|
|
12228
12241
|
name: external_exports.string().min(1),
|
|
12229
|
-
label: external_exports.string().optional(),
|
|
12242
|
+
label: external_exports.string().min(1).optional(),
|
|
12230
12243
|
description: external_exports.string().optional(),
|
|
12231
12244
|
isFinal: external_exports.boolean().optional()
|
|
12232
12245
|
}).strict()
|
|
@@ -12312,6 +12325,12 @@ var StateTransitionExpectedOutcomeSchema = external_exports.union([
|
|
|
12312
12325
|
summary: external_exports.string().optional()
|
|
12313
12326
|
}).strict()
|
|
12314
12327
|
]);
|
|
12328
|
+
var StateTransitionOutcomeSchema = external_exports.object({
|
|
12329
|
+
label: external_exports.string().min(1).optional(),
|
|
12330
|
+
to: external_exports.string().min(1),
|
|
12331
|
+
primary: external_exports.boolean().optional(),
|
|
12332
|
+
disposition: external_exports.enum(["continue", "error"])
|
|
12333
|
+
}).strict();
|
|
12315
12334
|
var StateMachineTransitionSchema = external_exports.object({
|
|
12316
12335
|
name: external_exports.string().min(1),
|
|
12317
12336
|
from: external_exports.string().min(1),
|
|
@@ -12323,7 +12342,8 @@ var StateMachineTransitionSchema = external_exports.object({
|
|
|
12323
12342
|
requirements: StateTransitionRequirementsSchema.optional(),
|
|
12324
12343
|
permission: StateTransitionPermissionSchema.optional(),
|
|
12325
12344
|
risk: external_exports.enum(["low", "medium", "high"]).optional(),
|
|
12326
|
-
expectedOutcome: StateTransitionExpectedOutcomeSchema.optional()
|
|
12345
|
+
expectedOutcome: StateTransitionExpectedOutcomeSchema.optional(),
|
|
12346
|
+
outcomes: external_exports.record(external_exports.string().min(1), StateTransitionOutcomeSchema).optional()
|
|
12327
12347
|
}).strict();
|
|
12328
12348
|
external_exports.object({
|
|
12329
12349
|
name: external_exports.string().min(1),
|
|
@@ -13004,6 +13024,289 @@ var effectBehaviorsMetamodelPackage = defineMetamodelPackage({
|
|
|
13004
13024
|
}
|
|
13005
13025
|
});
|
|
13006
13026
|
|
|
13027
|
+
// src/commit.ts
|
|
13028
|
+
var MAX_PROJECTION_CHANGES = 1e3;
|
|
13029
|
+
var MAX_SAFE_SUMMARY_KEYS = 32;
|
|
13030
|
+
var MAX_SAFE_TEXT_LENGTH = 2e3;
|
|
13031
|
+
var definedTransitionMetadata = /* @__PURE__ */ new WeakMap();
|
|
13032
|
+
function getDefinedTransitionMetadata(transition) {
|
|
13033
|
+
return definedTransitionMetadata.get(transition);
|
|
13034
|
+
}
|
|
13035
|
+
function defineProjection(mapper) {
|
|
13036
|
+
return mapper;
|
|
13037
|
+
}
|
|
13038
|
+
function defineEffect(effect) {
|
|
13039
|
+
return effect;
|
|
13040
|
+
}
|
|
13041
|
+
function defineStateMachine(definition) {
|
|
13042
|
+
const stateNames = new Set(Object.keys(definition.states));
|
|
13043
|
+
for (const [transitionName, transition] of Object.entries(
|
|
13044
|
+
definition.transitions
|
|
13045
|
+
)) {
|
|
13046
|
+
if (!stateNames.has(transition.from)) {
|
|
13047
|
+
throw new Error(
|
|
13048
|
+
`Transition ${transitionName} starts at undeclared state ${transition.from}`
|
|
13049
|
+
);
|
|
13050
|
+
}
|
|
13051
|
+
if (transition.effect.commit?.kind !== "transition") {
|
|
13052
|
+
throw new Error(
|
|
13053
|
+
`Transition ${transitionName} must use a transition-commit effect`
|
|
13054
|
+
);
|
|
13055
|
+
}
|
|
13056
|
+
const outcomes = Object.entries(transition.outcomes);
|
|
13057
|
+
const primary = outcomes.filter(([, outcome]) => outcome.primary === true);
|
|
13058
|
+
if (primary.length !== 1) {
|
|
13059
|
+
throw new Error(
|
|
13060
|
+
`Transition ${transitionName} must declare exactly one primary outcome`
|
|
13061
|
+
);
|
|
13062
|
+
}
|
|
13063
|
+
for (const [outcomeKey, outcome] of outcomes) {
|
|
13064
|
+
if (outcome.to !== "$current" && !stateNames.has(outcome.to)) {
|
|
13065
|
+
throw new Error(
|
|
13066
|
+
`Transition ${transitionName} outcome ${outcomeKey} targets undeclared state ${outcome.to}`
|
|
13067
|
+
);
|
|
13068
|
+
}
|
|
13069
|
+
if (outcome.to === "$current" && outcome.disposition !== "error") {
|
|
13070
|
+
throw new Error(
|
|
13071
|
+
`Transition ${transitionName} outcome ${outcomeKey} may use $current only with error disposition`
|
|
13072
|
+
);
|
|
13073
|
+
}
|
|
13074
|
+
}
|
|
13075
|
+
}
|
|
13076
|
+
for (const [transitionName, transition] of Object.entries(
|
|
13077
|
+
definition.transitions
|
|
13078
|
+
)) {
|
|
13079
|
+
definedTransitionMetadata.set(transition, {
|
|
13080
|
+
machine: definition.name,
|
|
13081
|
+
transition: transitionName
|
|
13082
|
+
});
|
|
13083
|
+
}
|
|
13084
|
+
return definition;
|
|
13085
|
+
}
|
|
13086
|
+
function requireNonEmptyString(value, path) {
|
|
13087
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
13088
|
+
throw new Error(`${path} must be a non-empty string`);
|
|
13089
|
+
}
|
|
13090
|
+
return value.trim();
|
|
13091
|
+
}
|
|
13092
|
+
function validateObjectReference(value, path) {
|
|
13093
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
13094
|
+
throw new Error(`${path} must be an object reference`);
|
|
13095
|
+
}
|
|
13096
|
+
const reference = value;
|
|
13097
|
+
requireNonEmptyString(reference.className, `${path}.className`);
|
|
13098
|
+
requireNonEmptyString(reference.id, `${path}.id`);
|
|
13099
|
+
if (reference.path !== void 0) {
|
|
13100
|
+
requireNonEmptyString(reference.path, `${path}.path`);
|
|
13101
|
+
}
|
|
13102
|
+
}
|
|
13103
|
+
function validateScalarRecord(value, path) {
|
|
13104
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) {
|
|
13105
|
+
throw new Error(`${path} must be an object of scalar values`);
|
|
13106
|
+
}
|
|
13107
|
+
for (const [key, item] of Object.entries(value)) {
|
|
13108
|
+
if (item !== null && typeof item !== "string" && typeof item !== "number" && typeof item !== "boolean") {
|
|
13109
|
+
throw new Error(
|
|
13110
|
+
`${path}.${key} must be a string, finite number, boolean, or null`
|
|
13111
|
+
);
|
|
13112
|
+
}
|
|
13113
|
+
if (typeof item === "number" && !Number.isFinite(item)) {
|
|
13114
|
+
throw new Error(`${path}.${key} must be finite`);
|
|
13115
|
+
}
|
|
13116
|
+
}
|
|
13117
|
+
}
|
|
13118
|
+
function validateProjectedRecord(value, path) {
|
|
13119
|
+
validateObjectReference(value, path);
|
|
13120
|
+
const record = value;
|
|
13121
|
+
if (record.label !== void 0) {
|
|
13122
|
+
if (typeof record.label !== "string") {
|
|
13123
|
+
throw new Error(`${path}.label must be a string`);
|
|
13124
|
+
}
|
|
13125
|
+
if (record.label.length > MAX_SAFE_TEXT_LENGTH) {
|
|
13126
|
+
throw new Error(
|
|
13127
|
+
`${path}.label exceeds ${MAX_SAFE_TEXT_LENGTH} characters`
|
|
13128
|
+
);
|
|
13129
|
+
}
|
|
13130
|
+
}
|
|
13131
|
+
validateScalarRecord(record.fields, `${path}.fields`);
|
|
13132
|
+
}
|
|
13133
|
+
function validateBoundedJson(value, path, depth = 0) {
|
|
13134
|
+
if (depth > 12) throw new Error(`${path} is nested too deeply`);
|
|
13135
|
+
if (value === null || typeof value === "boolean") return;
|
|
13136
|
+
if (typeof value === "number") {
|
|
13137
|
+
if (!Number.isFinite(value)) throw new Error(`${path} must be finite`);
|
|
13138
|
+
return;
|
|
13139
|
+
}
|
|
13140
|
+
if (typeof value === "string") {
|
|
13141
|
+
if (value.length > MAX_SAFE_TEXT_LENGTH) {
|
|
13142
|
+
throw new Error(`${path} exceeds ${MAX_SAFE_TEXT_LENGTH} characters`);
|
|
13143
|
+
}
|
|
13144
|
+
return;
|
|
13145
|
+
}
|
|
13146
|
+
if (Array.isArray(value)) {
|
|
13147
|
+
if (value.length > MAX_PROJECTION_CHANGES) {
|
|
13148
|
+
throw new Error(`${path} contains too many values`);
|
|
13149
|
+
}
|
|
13150
|
+
value.forEach(
|
|
13151
|
+
(item, index) => validateBoundedJson(item, `${path}[${index}]`, depth + 1)
|
|
13152
|
+
);
|
|
13153
|
+
return;
|
|
13154
|
+
}
|
|
13155
|
+
if (!value || typeof value !== "object") {
|
|
13156
|
+
throw new Error(`${path} contains an unsupported value`);
|
|
13157
|
+
}
|
|
13158
|
+
const entries = Object.entries(value);
|
|
13159
|
+
if (entries.length > 256) throw new Error(`${path} contains too many keys`);
|
|
13160
|
+
for (const [key, item] of entries) {
|
|
13161
|
+
if (/token|secret|password|authorization|cookie/i.test(key)) {
|
|
13162
|
+
throw new Error(`${path}.${key} is not allowed in a commit projection`);
|
|
13163
|
+
}
|
|
13164
|
+
validateBoundedJson(item, `${path}.${key}`, depth + 1);
|
|
13165
|
+
}
|
|
13166
|
+
}
|
|
13167
|
+
function validateProjectionResult(declaration, projection) {
|
|
13168
|
+
if (!projection || typeof projection !== "object") {
|
|
13169
|
+
throw new Error("Projection mapper must return an object");
|
|
13170
|
+
}
|
|
13171
|
+
requireNonEmptyString(
|
|
13172
|
+
projection.source?.reference,
|
|
13173
|
+
"projection.source.reference"
|
|
13174
|
+
);
|
|
13175
|
+
if (projection.source.version !== void 0) {
|
|
13176
|
+
requireNonEmptyString(
|
|
13177
|
+
projection.source.version,
|
|
13178
|
+
"projection.source.version"
|
|
13179
|
+
);
|
|
13180
|
+
}
|
|
13181
|
+
if (!Array.isArray(projection.changes)) {
|
|
13182
|
+
throw new Error("projection.changes must be an array");
|
|
13183
|
+
}
|
|
13184
|
+
if (projection.changes.length > MAX_PROJECTION_CHANGES) {
|
|
13185
|
+
throw new Error(
|
|
13186
|
+
`projection.changes exceeds the ${MAX_PROJECTION_CHANGES} change limit`
|
|
13187
|
+
);
|
|
13188
|
+
}
|
|
13189
|
+
if (projection.primaryTarget) {
|
|
13190
|
+
validateObjectReference(
|
|
13191
|
+
projection.primaryTarget,
|
|
13192
|
+
"projection.primaryTarget"
|
|
13193
|
+
);
|
|
13194
|
+
}
|
|
13195
|
+
if (projection.safeSummary) {
|
|
13196
|
+
const entries = Object.entries(projection.safeSummary);
|
|
13197
|
+
if (entries.length > MAX_SAFE_SUMMARY_KEYS) {
|
|
13198
|
+
throw new Error(
|
|
13199
|
+
`projection.safeSummary exceeds the ${MAX_SAFE_SUMMARY_KEYS} key limit`
|
|
13200
|
+
);
|
|
13201
|
+
}
|
|
13202
|
+
validateBoundedJson(projection.safeSummary, "projection.safeSummary");
|
|
13203
|
+
validateScalarRecord(projection.safeSummary, "projection.safeSummary");
|
|
13204
|
+
}
|
|
13205
|
+
projection.changes.forEach((change, index) => {
|
|
13206
|
+
const changePath = `projection.changes[${index}]`;
|
|
13207
|
+
validateBoundedJson(change, changePath);
|
|
13208
|
+
if (!change || typeof change !== "object" || Array.isArray(change)) {
|
|
13209
|
+
throw new Error(`${changePath} must be an object`);
|
|
13210
|
+
}
|
|
13211
|
+
const rawChange = change;
|
|
13212
|
+
const kind = requireNonEmptyString(rawChange.kind, `${changePath}.kind`);
|
|
13213
|
+
if (kind === "object") {
|
|
13214
|
+
const operation = requireNonEmptyString(
|
|
13215
|
+
rawChange.operation,
|
|
13216
|
+
`${changePath}.operation`
|
|
13217
|
+
);
|
|
13218
|
+
if (operation !== "created" && operation !== "updated" && operation !== "deleted") {
|
|
13219
|
+
throw new Error(
|
|
13220
|
+
`${changePath}.operation must be created, updated, or deleted`
|
|
13221
|
+
);
|
|
13222
|
+
}
|
|
13223
|
+
if (operation === "deleted") {
|
|
13224
|
+
validateObjectReference(rawChange.target, `${changePath}.target`);
|
|
13225
|
+
} else {
|
|
13226
|
+
validateProjectedRecord(rawChange.record, `${changePath}.record`);
|
|
13227
|
+
}
|
|
13228
|
+
} else if (kind === "relationship") {
|
|
13229
|
+
const operation = requireNonEmptyString(
|
|
13230
|
+
rawChange.operation,
|
|
13231
|
+
`${changePath}.operation`
|
|
13232
|
+
);
|
|
13233
|
+
if (operation !== "connected" && operation !== "disconnected") {
|
|
13234
|
+
throw new Error(
|
|
13235
|
+
`${changePath}.operation must be connected or disconnected`
|
|
13236
|
+
);
|
|
13237
|
+
}
|
|
13238
|
+
requireNonEmptyString(
|
|
13239
|
+
rawChange.relationship,
|
|
13240
|
+
`${changePath}.relationship`
|
|
13241
|
+
);
|
|
13242
|
+
validateObjectReference(rawChange.from, `${changePath}.from`);
|
|
13243
|
+
validateObjectReference(rawChange.to, `${changePath}.to`);
|
|
13244
|
+
} else if (kind === "state_observation") {
|
|
13245
|
+
if (rawChange.operation !== void 0) {
|
|
13246
|
+
throw new Error(
|
|
13247
|
+
`${changePath}.operation is not valid for an observation`
|
|
13248
|
+
);
|
|
13249
|
+
}
|
|
13250
|
+
validateObjectReference(rawChange.target, `${changePath}.target`);
|
|
13251
|
+
requireNonEmptyString(rawChange.machine, `${changePath}.machine`);
|
|
13252
|
+
requireNonEmptyString(rawChange.state, `${changePath}.state`);
|
|
13253
|
+
} else {
|
|
13254
|
+
throw new Error(`${changePath}.kind is unsupported: ${kind}`);
|
|
13255
|
+
}
|
|
13256
|
+
});
|
|
13257
|
+
const objectOperations = /* @__PURE__ */ new Map();
|
|
13258
|
+
for (const change of projection.changes) {
|
|
13259
|
+
if (change.kind !== "object") continue;
|
|
13260
|
+
const reference = change.operation === "deleted" ? change.target : change.record;
|
|
13261
|
+
const key = `${reference.className}\0${reference.id}`;
|
|
13262
|
+
const operations = objectOperations.get(key) || {
|
|
13263
|
+
deleted: false,
|
|
13264
|
+
upserted: false
|
|
13265
|
+
};
|
|
13266
|
+
if (change.operation === "deleted") operations.deleted = true;
|
|
13267
|
+
else operations.upserted = true;
|
|
13268
|
+
if (operations.deleted && operations.upserted) {
|
|
13269
|
+
throw new Error(
|
|
13270
|
+
`projection.changes cannot both delete and upsert ${reference.className}/${reference.id}; return only its canonical final state`
|
|
13271
|
+
);
|
|
13272
|
+
}
|
|
13273
|
+
objectOperations.set(key, operations);
|
|
13274
|
+
}
|
|
13275
|
+
const outcome = projection.outcome;
|
|
13276
|
+
if (declaration.kind === "transition") {
|
|
13277
|
+
if (!outcome) {
|
|
13278
|
+
throw new Error("A transition projection must return an outcome");
|
|
13279
|
+
}
|
|
13280
|
+
requireNonEmptyString(outcome.key, "projection.outcome.key");
|
|
13281
|
+
if (outcome.error) {
|
|
13282
|
+
validateBoundedJson(outcome.error, "projection.outcome.error");
|
|
13283
|
+
}
|
|
13284
|
+
} else if (projection.outcome !== void 0) {
|
|
13285
|
+
throw new Error("An effect projection cannot declare a transition outcome");
|
|
13286
|
+
}
|
|
13287
|
+
}
|
|
13288
|
+
function canonicalizeCommitValue(value) {
|
|
13289
|
+
const normalize = (current) => {
|
|
13290
|
+
if (current === null || typeof current === "boolean" || typeof current === "string") {
|
|
13291
|
+
return typeof current === "string" ? current.normalize("NFC") : current;
|
|
13292
|
+
}
|
|
13293
|
+
if (typeof current === "number") {
|
|
13294
|
+
if (!Number.isFinite(current)) {
|
|
13295
|
+
throw new Error("Cannot canonicalize a non-finite number");
|
|
13296
|
+
}
|
|
13297
|
+
return Object.is(current, -0) ? 0 : current;
|
|
13298
|
+
}
|
|
13299
|
+
if (Array.isArray(current)) return current.map(normalize);
|
|
13300
|
+
if (current && typeof current === "object") {
|
|
13301
|
+
return Object.fromEntries(
|
|
13302
|
+
Object.entries(current).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key.normalize("NFC"), normalize(item)])
|
|
13303
|
+
);
|
|
13304
|
+
}
|
|
13305
|
+
throw new Error(`Cannot canonicalize ${typeof current}`);
|
|
13306
|
+
};
|
|
13307
|
+
return JSON.stringify(normalize(value));
|
|
13308
|
+
}
|
|
13309
|
+
|
|
13007
13310
|
// src/effect-runtime.ts
|
|
13008
13311
|
function computeEffectKey(effect) {
|
|
13009
13312
|
const attachedClass = effect.className?.trim();
|
|
@@ -13068,6 +13371,45 @@ function resolveInvocationMode(context) {
|
|
|
13068
13371
|
}
|
|
13069
13372
|
return "execute";
|
|
13070
13373
|
}
|
|
13374
|
+
async function sha256Hex(value) {
|
|
13375
|
+
const digest = await globalThis.crypto.subtle.digest(
|
|
13376
|
+
"SHA-256",
|
|
13377
|
+
new TextEncoder().encode(value)
|
|
13378
|
+
);
|
|
13379
|
+
return Array.from(
|
|
13380
|
+
new Uint8Array(digest),
|
|
13381
|
+
(byte) => byte.toString(16).padStart(2, "0")
|
|
13382
|
+
).join("");
|
|
13383
|
+
}
|
|
13384
|
+
async function resolveInvocationIdempotencyKey(request) {
|
|
13385
|
+
const supplied = request.context?.idempotencyKey?.trim();
|
|
13386
|
+
if (supplied) return supplied;
|
|
13387
|
+
const invocationId = request.context?.invocationId?.trim();
|
|
13388
|
+
if (!invocationId) {
|
|
13389
|
+
throw new Error(
|
|
13390
|
+
`Committed effect ${request.effectKey} requires an invocation id`
|
|
13391
|
+
);
|
|
13392
|
+
}
|
|
13393
|
+
const digest = await sha256Hex(
|
|
13394
|
+
canonicalizeCommitValue({
|
|
13395
|
+
sandboxId: request.context?.sandboxId || "",
|
|
13396
|
+
environmentId: request.context?.environmentId || "",
|
|
13397
|
+
effectKey: request.effectKey,
|
|
13398
|
+
invocationId,
|
|
13399
|
+
input: request.input
|
|
13400
|
+
})
|
|
13401
|
+
);
|
|
13402
|
+
return `gci_${digest}`;
|
|
13403
|
+
}
|
|
13404
|
+
function createUnavailableCommitContext(message) {
|
|
13405
|
+
const unavailable = async () => {
|
|
13406
|
+
throw new Error(message);
|
|
13407
|
+
};
|
|
13408
|
+
return {
|
|
13409
|
+
effect: unavailable,
|
|
13410
|
+
transition: unavailable
|
|
13411
|
+
};
|
|
13412
|
+
}
|
|
13071
13413
|
function resolveReverseEffect(effectMap, currentEffect, request, behaviors) {
|
|
13072
13414
|
const explicitReverseHandler = request.context?.invocation?.reverseHandler?.trim();
|
|
13073
13415
|
const configuredReverseHandler = behaviors.reverse?.handler?.trim();
|
|
@@ -13120,7 +13462,7 @@ function resolveHandlerForMode(effectMap, effect, request) {
|
|
|
13120
13462
|
if (mode === "artifactOptions") {
|
|
13121
13463
|
if (!effect.artifactOptionsHandler) {
|
|
13122
13464
|
throw new Error(
|
|
13123
|
-
`Artifact
|
|
13465
|
+
`Artifact field options are not supported for ${request.effectKey}`
|
|
13124
13466
|
);
|
|
13125
13467
|
}
|
|
13126
13468
|
return {
|
|
@@ -13139,22 +13481,32 @@ function resolveHandlerForMode(effectMap, effect, request) {
|
|
|
13139
13481
|
throw new Error(`Dry run is not supported for ${request.effectKey}`);
|
|
13140
13482
|
}
|
|
13141
13483
|
if (mode === "reverse") {
|
|
13484
|
+
const sourceEffectKey = request.context?.invocation?.sourceEffectKey?.trim();
|
|
13485
|
+
if (sourceEffectKey && sourceEffectKey !== request.effectKey) {
|
|
13486
|
+
return { effect, mode, handler: effect.handler };
|
|
13487
|
+
}
|
|
13488
|
+
const namedReverseHandler = request.context?.invocation?.reverseHandler?.trim() || behaviors.reverse?.handler?.trim();
|
|
13489
|
+
if (namedReverseHandler) {
|
|
13490
|
+
const reverseEffect = resolveReverseEffect(
|
|
13491
|
+
effectMap,
|
|
13492
|
+
effect,
|
|
13493
|
+
request,
|
|
13494
|
+
behaviors
|
|
13495
|
+
);
|
|
13496
|
+
if (reverseEffect) {
|
|
13497
|
+
return {
|
|
13498
|
+
effect: reverseEffect,
|
|
13499
|
+
mode,
|
|
13500
|
+
handler: reverseEffect.handler
|
|
13501
|
+
};
|
|
13502
|
+
}
|
|
13503
|
+
throw new Error(
|
|
13504
|
+
`Reverse effect ${namedReverseHandler} is not registered for ${request.effectKey}`
|
|
13505
|
+
);
|
|
13506
|
+
}
|
|
13142
13507
|
if (effect.reverseHandler) {
|
|
13143
13508
|
return { effect, mode, handler: effect.reverseHandler };
|
|
13144
13509
|
}
|
|
13145
|
-
const reverseEffect = resolveReverseEffect(
|
|
13146
|
-
effectMap,
|
|
13147
|
-
effect,
|
|
13148
|
-
request,
|
|
13149
|
-
behaviors
|
|
13150
|
-
);
|
|
13151
|
-
if (reverseEffect) {
|
|
13152
|
-
return {
|
|
13153
|
-
effect: reverseEffect,
|
|
13154
|
-
mode,
|
|
13155
|
-
handler: reverseEffect.reverseHandler || reverseEffect.handler
|
|
13156
|
-
};
|
|
13157
|
-
}
|
|
13158
13510
|
throw new Error(
|
|
13159
13511
|
`Reverse execution is not supported for ${request.effectKey}`
|
|
13160
13512
|
);
|
|
@@ -13255,18 +13607,142 @@ async function invokeRegisteredEffect(effectMap, request, options = {}) {
|
|
|
13255
13607
|
throw new Error(`Effect handler not found: ${request.effectKey}`);
|
|
13256
13608
|
}
|
|
13257
13609
|
const resolved = resolveHandlerForMode(effectMap, effect, request);
|
|
13610
|
+
const isPreResolvedNamedReverse = resolved.mode === "reverse" && Boolean(request.context?.invocation?.sourceEffectKey?.trim()) && request.context?.invocation?.sourceEffectKey?.trim() !== request.effectKey;
|
|
13611
|
+
const resolvedEffectKey = computeEffectKey(resolved.effect);
|
|
13612
|
+
if (resolved.mode === "reverse" && resolved.effect !== effect && (effect.commit || resolved.effect.commit)) {
|
|
13613
|
+
throw new Error(
|
|
13614
|
+
`Committed named reverse effect ${resolvedEffectKey} must be reserved and dispatched using its own effect key; customer code was not invoked`
|
|
13615
|
+
);
|
|
13616
|
+
}
|
|
13617
|
+
const declaration = resolved.effect.commit;
|
|
13618
|
+
const commitTransport = options.commit;
|
|
13619
|
+
const commitRequired = Boolean(declaration) && (resolved.mode === "execute" || resolved.mode === "reverse");
|
|
13620
|
+
if (commitRequired && !commitTransport) {
|
|
13621
|
+
throw new Error(
|
|
13622
|
+
`Committed effect ${request.effectKey} has no durable commit transport; customer code was not invoked`
|
|
13623
|
+
);
|
|
13624
|
+
}
|
|
13625
|
+
if (commitRequired && declaration?.kind === "transition" && !request.context?.invocation?.transition) {
|
|
13626
|
+
throw new Error(
|
|
13627
|
+
`Transition effect ${request.effectKey} has no resolved transition context; customer code was not invoked`
|
|
13628
|
+
);
|
|
13629
|
+
}
|
|
13630
|
+
const idempotencyKey = commitRequired ? await resolveInvocationIdempotencyKey(request) : request.context?.idempotencyKey;
|
|
13631
|
+
let commitStarted = false;
|
|
13632
|
+
let commitPromise = null;
|
|
13633
|
+
const beginCommit = (requestedKind, productResult) => {
|
|
13634
|
+
if (!declaration || !commitRequired || !commitTransport) {
|
|
13635
|
+
return Promise.reject(
|
|
13636
|
+
new Error(
|
|
13637
|
+
`Effect ${request.effectKey} does not declare an active ${requestedKind} commit`
|
|
13638
|
+
)
|
|
13639
|
+
);
|
|
13640
|
+
}
|
|
13641
|
+
if (declaration.kind !== requestedKind) {
|
|
13642
|
+
return Promise.reject(
|
|
13643
|
+
new Error(
|
|
13644
|
+
`Effect ${request.effectKey} declares ${declaration.kind} commit, not ${requestedKind}`
|
|
13645
|
+
)
|
|
13646
|
+
);
|
|
13647
|
+
}
|
|
13648
|
+
if (commitStarted) {
|
|
13649
|
+
return Promise.reject(
|
|
13650
|
+
new Error(
|
|
13651
|
+
`Effect invocation ${request.context?.invocationId || request.effectKey} already emitted its commit`
|
|
13652
|
+
)
|
|
13653
|
+
);
|
|
13654
|
+
}
|
|
13655
|
+
commitStarted = true;
|
|
13656
|
+
commitPromise = (async () => {
|
|
13657
|
+
let projection;
|
|
13658
|
+
try {
|
|
13659
|
+
projection = declaration.project(productResult);
|
|
13660
|
+
validateProjectionResult(declaration, projection);
|
|
13661
|
+
} catch (error) {
|
|
13662
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13663
|
+
if (commitTransport.mappingFailed) {
|
|
13664
|
+
await commitTransport.mappingFailed({
|
|
13665
|
+
effectKey: request.effectKey,
|
|
13666
|
+
effectName: request.effectName,
|
|
13667
|
+
invocationId: request.context?.invocationId || "",
|
|
13668
|
+
idempotencyKey: idempotencyKey || "",
|
|
13669
|
+
environmentId: request.context?.environmentId || "",
|
|
13670
|
+
message
|
|
13671
|
+
});
|
|
13672
|
+
}
|
|
13673
|
+
throw new Error(
|
|
13674
|
+
`Product mutation may have succeeded, but its commit projection is invalid: ${message}`
|
|
13675
|
+
);
|
|
13676
|
+
}
|
|
13677
|
+
if (requestedKind === "transition") {
|
|
13678
|
+
const transition = request.context?.invocation?.transition;
|
|
13679
|
+
const outcome = projection.outcome;
|
|
13680
|
+
if (!transition || !outcome?.key) {
|
|
13681
|
+
throw new Error(
|
|
13682
|
+
`Transition effect ${request.effectKey} did not resolve an authored outcome`
|
|
13683
|
+
);
|
|
13684
|
+
}
|
|
13685
|
+
if (!Object.prototype.hasOwnProperty.call(
|
|
13686
|
+
transition.outcomes,
|
|
13687
|
+
outcome.key
|
|
13688
|
+
)) {
|
|
13689
|
+
throw new Error(
|
|
13690
|
+
`Transition ${transition.machine}.${transition.transition} does not declare outcome ${outcome.key}`
|
|
13691
|
+
);
|
|
13692
|
+
}
|
|
13693
|
+
}
|
|
13694
|
+
const invocationId = request.context?.invocationId || "";
|
|
13695
|
+
const environmentId = request.context?.environmentId || "";
|
|
13696
|
+
const sandboxId = request.context?.sandboxId || "";
|
|
13697
|
+
if (!invocationId || !environmentId || !sandboxId || !idempotencyKey) {
|
|
13698
|
+
throw new Error(
|
|
13699
|
+
`Committed effect ${request.effectKey} is missing its trusted invocation scope`
|
|
13700
|
+
);
|
|
13701
|
+
}
|
|
13702
|
+
const commitRequest = {
|
|
13703
|
+
kind: requestedKind,
|
|
13704
|
+
effectKey: request.effectKey,
|
|
13705
|
+
effectName: request.effectName,
|
|
13706
|
+
operationLabel: resolved.effect.label || resolved.effect.name,
|
|
13707
|
+
invocationId,
|
|
13708
|
+
idempotencyKey,
|
|
13709
|
+
sandboxId,
|
|
13710
|
+
environmentId,
|
|
13711
|
+
...request.context?.sessionId ? { sessionId: request.context.sessionId } : {},
|
|
13712
|
+
...request.context?.jobId ? { jobId: request.context.jobId } : {},
|
|
13713
|
+
...request.context?.buildId ? { buildId: request.context.buildId } : {},
|
|
13714
|
+
...request.context?.invocation?.artifactId ? { artifactId: request.context.invocation.artifactId } : {},
|
|
13715
|
+
projection,
|
|
13716
|
+
...requestedKind === "transition" && request.context?.invocation?.transition ? { transition: request.context.invocation.transition } : {}
|
|
13717
|
+
};
|
|
13718
|
+
const receipt = await commitTransport.persist(commitRequest);
|
|
13719
|
+
await options.commitAcknowledged?.(receipt);
|
|
13720
|
+
return receipt;
|
|
13721
|
+
})();
|
|
13722
|
+
return commitPromise;
|
|
13723
|
+
};
|
|
13724
|
+
const commitContext = commitRequired ? {
|
|
13725
|
+
effect: (productResult) => beginCommit("effect", productResult),
|
|
13726
|
+
transition: (productResult) => beginCommit("transition", productResult)
|
|
13727
|
+
} : createUnavailableCommitContext(
|
|
13728
|
+
`Effect ${request.effectKey} is not executing a declared product commit`
|
|
13729
|
+
);
|
|
13258
13730
|
const context = {
|
|
13259
13731
|
...request.context || {},
|
|
13732
|
+
...idempotencyKey ? { idempotencyKey } : {},
|
|
13733
|
+
commit: commitContext,
|
|
13260
13734
|
behaviors: normalizeEffectBehaviors(
|
|
13261
13735
|
request.context?.behaviors || effect.metamodels || void 0
|
|
13262
13736
|
),
|
|
13263
13737
|
invocation: {
|
|
13264
13738
|
mode: resolved.mode,
|
|
13265
|
-
|
|
13266
|
-
|
|
13739
|
+
...commitRequired && declaration ? { commitKind: declaration.kind } : {},
|
|
13740
|
+
sourceEffectKey: isPreResolvedNamedReverse ? request.context?.invocation?.sourceEffectKey || request.effectKey : request.effectKey,
|
|
13741
|
+
sourceEffectName: isPreResolvedNamedReverse ? request.context?.invocation?.sourceEffectName || request.effectName : request.effectName,
|
|
13267
13742
|
...request.context?.invocation?.reverseHandler ? { reverseHandler: request.context.invocation.reverseHandler } : {},
|
|
13268
13743
|
...request.context?.invocation?.artifactId ? { artifactId: request.context.invocation.artifactId } : {},
|
|
13269
|
-
...request.context?.invocation?.artifactOptions ? { artifactOptions: request.context.invocation.artifactOptions } : {}
|
|
13744
|
+
...request.context?.invocation?.artifactOptions ? { artifactOptions: request.context.invocation.artifactOptions } : {},
|
|
13745
|
+
...request.context?.invocation?.transition ? { transition: request.context.invocation.transition } : {}
|
|
13270
13746
|
}
|
|
13271
13747
|
};
|
|
13272
13748
|
const feedbackContext = options.feedback ? createInvocationFeedbackContext(options.feedback) : null;
|
|
@@ -13290,6 +13766,16 @@ async function invokeRegisteredEffect(effectMap, request, options = {}) {
|
|
|
13290
13766
|
handlerFailed = true;
|
|
13291
13767
|
handlerError = error;
|
|
13292
13768
|
}
|
|
13769
|
+
let commitError;
|
|
13770
|
+
let commitFailed = false;
|
|
13771
|
+
if (commitPromise) {
|
|
13772
|
+
try {
|
|
13773
|
+
await commitPromise;
|
|
13774
|
+
} catch (error) {
|
|
13775
|
+
commitFailed = true;
|
|
13776
|
+
commitError = error;
|
|
13777
|
+
}
|
|
13778
|
+
}
|
|
13293
13779
|
let feedbackError;
|
|
13294
13780
|
let feedbackFailed = false;
|
|
13295
13781
|
if (feedbackContext) {
|
|
@@ -13303,9 +13789,17 @@ async function invokeRegisteredEffect(effectMap, request, options = {}) {
|
|
|
13303
13789
|
if (handlerFailed) {
|
|
13304
13790
|
throw handlerError;
|
|
13305
13791
|
}
|
|
13792
|
+
if (commitFailed) {
|
|
13793
|
+
throw commitError;
|
|
13794
|
+
}
|
|
13306
13795
|
if (feedbackFailed) {
|
|
13307
13796
|
throw feedbackError;
|
|
13308
13797
|
}
|
|
13798
|
+
if (commitRequired && !commitStarted) {
|
|
13799
|
+
throw new Error(
|
|
13800
|
+
`Mutating effect ${request.effectKey} returned without acknowledging its product mutation`
|
|
13801
|
+
);
|
|
13802
|
+
}
|
|
13309
13803
|
return handlerResult;
|
|
13310
13804
|
}
|
|
13311
13805
|
|
|
@@ -13374,12 +13868,7 @@ function toRecordSearchResult(className, node) {
|
|
|
13374
13868
|
(field) => normalizeGraphPathSegment(field.name) === "real_id" && typeof field.value === "string" && field.value.trim()
|
|
13375
13869
|
);
|
|
13376
13870
|
const id = typeof realIdField?.value === "string" ? realIdField.value.trim() : graphPathId;
|
|
13377
|
-
const
|
|
13378
|
-
if (fields.length === 0 && rawLabel && isPlaceholderRecordLabel(rawLabel, graphPathId, path)) {
|
|
13379
|
-
return null;
|
|
13380
|
-
}
|
|
13381
|
-
const fallbackLabel = displayLabelFromFields(fields);
|
|
13382
|
-
const label = rawLabel && !isPlaceholderRecordLabel(rawLabel, id, path) ? rawLabel : fallbackLabel || rawLabel || id;
|
|
13871
|
+
const label = typeof node.label === "string" && node.label.trim() ? node.label.trim() : path || id;
|
|
13383
13872
|
return {
|
|
13384
13873
|
path,
|
|
13385
13874
|
className,
|
|
@@ -13389,30 +13878,6 @@ function toRecordSearchResult(className, node) {
|
|
|
13389
13878
|
fields
|
|
13390
13879
|
};
|
|
13391
13880
|
}
|
|
13392
|
-
function isPlaceholderRecordLabel(label, id, path) {
|
|
13393
|
-
const normalizedLabel = normalizeGraphPathSegment(label);
|
|
13394
|
-
return normalizedLabel === normalizeGraphPathSegment(id) || normalizedLabel === normalizeGraphPathSegment(path);
|
|
13395
|
-
}
|
|
13396
|
-
function displayLabelFromFields(fields) {
|
|
13397
|
-
const preferredFieldNames = [
|
|
13398
|
-
"name",
|
|
13399
|
-
"title",
|
|
13400
|
-
"label",
|
|
13401
|
-
"display_name",
|
|
13402
|
-
"file_name",
|
|
13403
|
-
"number",
|
|
13404
|
-
"code"
|
|
13405
|
-
];
|
|
13406
|
-
for (const preferred of preferredFieldNames) {
|
|
13407
|
-
const match = fields.find(
|
|
13408
|
-
(field) => normalizeGraphPathSegment(field.name) === preferred && typeof field.value === "string" && field.value.trim()
|
|
13409
|
-
);
|
|
13410
|
-
if (typeof match?.value === "string") {
|
|
13411
|
-
return match.value.trim();
|
|
13412
|
-
}
|
|
13413
|
-
}
|
|
13414
|
-
return null;
|
|
13415
|
-
}
|
|
13416
13881
|
function normalizeRecordSearchText(value) {
|
|
13417
13882
|
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, " ").replace(/\s+/g, " ").trim();
|
|
13418
13883
|
}
|
|
@@ -13622,18 +14087,24 @@ function normalizeEnumInput(enumSpec) {
|
|
|
13622
14087
|
(value) => typeof value === "string" && value.length > 0
|
|
13623
14088
|
);
|
|
13624
14089
|
if (values.length === 0) return null;
|
|
13625
|
-
|
|
14090
|
+
const labels = Array.isArray(config.labels) && config.labels.length === values.length ? config.labels : values;
|
|
14091
|
+
return {
|
|
14092
|
+
values,
|
|
14093
|
+
labels,
|
|
14094
|
+
...config.message ? { message: config.message } : {}
|
|
14095
|
+
};
|
|
13626
14096
|
}
|
|
13627
14097
|
function buildEnumFieldMutations(fieldPath, enumSpec) {
|
|
13628
14098
|
const normalized = normalizeEnumInput(enumSpec);
|
|
13629
14099
|
if (!normalized) return [];
|
|
13630
14100
|
const messageArg = normalized.message ? `, message: ${JSON.stringify(normalized.message)}` : "";
|
|
14101
|
+
const labelsArg = normalized.labels ? `, labels: ${JSON.stringify(normalized.labels)}` : "";
|
|
13631
14102
|
return [
|
|
13632
14103
|
{
|
|
13633
14104
|
label: `set enum on ${fieldPath}`,
|
|
13634
14105
|
query: `mutation { at(path: ${JSON.stringify(fieldPath)}) { set_enum(values: ${JSON.stringify(
|
|
13635
14106
|
normalized.values
|
|
13636
|
-
)}${messageArg}) { values } } }`
|
|
14107
|
+
)}${labelsArg}${messageArg}) { values labels } } }`
|
|
13637
14108
|
}
|
|
13638
14109
|
];
|
|
13639
14110
|
}
|
|
@@ -13643,7 +14114,7 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13643
14114
|
fieldRows: [
|
|
13644
14115
|
{
|
|
13645
14116
|
key: "enum",
|
|
13646
|
-
description: 'Allowed values.
|
|
14117
|
+
description: 'Allowed values. Use `{ "values": [...], "labels": [...] }` for authored display labels; otherwise each unchanged value is its display fallback.'
|
|
13647
14118
|
}
|
|
13648
14119
|
]
|
|
13649
14120
|
},
|
|
@@ -13653,6 +14124,7 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13653
14124
|
type EnumMetamodel {
|
|
13654
14125
|
model: Model!
|
|
13655
14126
|
values: [String!]!
|
|
14127
|
+
labels: [String!]!
|
|
13656
14128
|
message: String
|
|
13657
14129
|
}
|
|
13658
14130
|
|
|
@@ -13661,7 +14133,7 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13661
14133
|
}
|
|
13662
14134
|
|
|
13663
14135
|
extend type ModelMutation {
|
|
13664
|
-
set_enum(values: [String!]!, message: String): EnumMetamodel
|
|
14136
|
+
set_enum(values: [String!]!, labels: [String!], message: String): EnumMetamodel
|
|
13665
14137
|
}
|
|
13666
14138
|
`
|
|
13667
14139
|
],
|
|
@@ -13670,15 +14142,19 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13670
14142
|
EnumMetamodel: {
|
|
13671
14143
|
model: (value) => value.model,
|
|
13672
14144
|
values: (value) => value.values,
|
|
14145
|
+
labels: (value) => value.labels || [],
|
|
13673
14146
|
message: (value) => value.message || null
|
|
13674
14147
|
},
|
|
13675
14148
|
Model: {
|
|
13676
14149
|
enum_rule: async (ant) => await run(ant.enum_rule())
|
|
13677
14150
|
},
|
|
13678
14151
|
ModelMutation: {
|
|
13679
|
-
set_enum: async (ant, { values, message }) => {
|
|
13680
|
-
const
|
|
13681
|
-
|
|
14152
|
+
set_enum: async (ant, { values, labels, message }) => {
|
|
14153
|
+
const resolvedLabels = Array.isArray(labels) && labels.length === values.length ? labels : values;
|
|
14154
|
+
const model = await run(
|
|
14155
|
+
ant.set_enum(values, resolvedLabels, message)
|
|
14156
|
+
);
|
|
14157
|
+
return { model, values, labels: resolvedLabels, message };
|
|
13682
14158
|
}
|
|
13683
14159
|
}
|
|
13684
14160
|
};
|
|
@@ -13691,7 +14167,7 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13691
14167
|
},
|
|
13692
14168
|
summary: {
|
|
13693
14169
|
selections: {
|
|
13694
|
-
propertyFields: [`enum_rule { values message }`]
|
|
14170
|
+
propertyFields: [`enum_rule { values labels message }`]
|
|
13695
14171
|
},
|
|
13696
14172
|
readPropertySummary(rawProperty) {
|
|
13697
14173
|
const values = Array.isArray(rawProperty.enum_rule?.values) ? rawProperty.enum_rule.values.filter(
|
|
@@ -13699,8 +14175,15 @@ var enumMetamodelPackage = defineMetamodelPackage({
|
|
|
13699
14175
|
) : [];
|
|
13700
14176
|
if (values.length === 0) return { enumRule: null };
|
|
13701
14177
|
const message = typeof rawProperty.enum_rule?.message === "string" ? rawProperty.enum_rule.message : null;
|
|
14178
|
+
const labels = Array.isArray(rawProperty.enum_rule?.labels) ? rawProperty.enum_rule.labels.filter(
|
|
14179
|
+
(label) => typeof label === "string" && label.length > 0
|
|
14180
|
+
) : [];
|
|
13702
14181
|
return {
|
|
13703
|
-
enumRule:
|
|
14182
|
+
enumRule: {
|
|
14183
|
+
values,
|
|
14184
|
+
...labels.length === values.length ? { labels } : {},
|
|
14185
|
+
...message ? { message } : {}
|
|
14186
|
+
}
|
|
13704
14187
|
};
|
|
13705
14188
|
}
|
|
13706
14189
|
},
|
|
@@ -14357,7 +14840,8 @@ function normalizeStateMachines(values) {
|
|
|
14357
14840
|
requirements: parseJsonRecord(transition?.requirements) || parseJsonRecord(transition?.requirements_json),
|
|
14358
14841
|
permission: parseJsonValue(transition?.permission) ?? parseJsonValue(transition?.permission_json),
|
|
14359
14842
|
risk: transition?.risk === "low" || transition?.risk === "medium" || transition?.risk === "high" ? transition.risk : null,
|
|
14360
|
-
expectedOutcome: parseJsonValue(transition?.expectedOutcome) ?? parseJsonValue(transition?.expected_outcome_json)
|
|
14843
|
+
expectedOutcome: parseJsonValue(transition?.expectedOutcome) ?? parseJsonValue(transition?.expected_outcome_json),
|
|
14844
|
+
outcomes: parseJsonRecord(transition?.outcomes) || parseJsonRecord(transition?.outcomes_json)
|
|
14361
14845
|
})).filter(
|
|
14362
14846
|
(transition) => transition.name.length > 0 && transition.from.length > 0 && transition.to.length > 0
|
|
14363
14847
|
);
|
|
@@ -14450,6 +14934,11 @@ function transitionMetadataGraphqlArgs(transition) {
|
|
|
14450
14934
|
`expected_outcome_json: ${JSON.stringify(JSON.stringify(transition.expectedOutcome))}`
|
|
14451
14935
|
);
|
|
14452
14936
|
}
|
|
14937
|
+
if (transition.outcomes) {
|
|
14938
|
+
args.push(
|
|
14939
|
+
`outcomes_json: ${JSON.stringify(JSON.stringify(transition.outcomes))}`
|
|
14940
|
+
);
|
|
14941
|
+
}
|
|
14453
14942
|
return args.length > 0 ? `, ${args.join(", ")}` : "";
|
|
14454
14943
|
}
|
|
14455
14944
|
function buildStateMachineModelMutations(modelPath, machines) {
|
|
@@ -14512,7 +15001,7 @@ function buildMachineTypes(classSummary, machine) {
|
|
|
14512
15001
|
];
|
|
14513
15002
|
}
|
|
14514
15003
|
function buildMachineMethods(classSummary, machine) {
|
|
14515
|
-
const
|
|
15004
|
+
const stateName2 = stateTypeName(classSummary.name, machine.name);
|
|
14516
15005
|
const transitionName = transitionTypeName(classSummary.name, machine.name);
|
|
14517
15006
|
pathTypeName(classSummary.name, machine.name);
|
|
14518
15007
|
const docsPrefix = `${classSummary.name}.${machine.name}`;
|
|
@@ -14522,12 +15011,12 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14522
15011
|
docs: [`Get the current ${docsPrefix} state.`],
|
|
14523
15012
|
static: false,
|
|
14524
15013
|
params: [],
|
|
14525
|
-
returnType: `Promise<${
|
|
15014
|
+
returnType: `Promise<${stateName2} | null>`,
|
|
14526
15015
|
runtime: {
|
|
14527
15016
|
kind: "state_machine",
|
|
14528
15017
|
machineName: machine.name,
|
|
14529
15018
|
className: classSummary.name,
|
|
14530
|
-
stateTypeName:
|
|
15019
|
+
stateTypeName: stateName2,
|
|
14531
15020
|
transitionTypeName: transitionName,
|
|
14532
15021
|
operation: "get_current"
|
|
14533
15022
|
}
|
|
@@ -14538,13 +15027,13 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14538
15027
|
`Reach a ${docsPrefix} state through the shortest allowed transition path.`
|
|
14539
15028
|
],
|
|
14540
15029
|
static: false,
|
|
14541
|
-
params: [{ name: "target", type:
|
|
15030
|
+
params: [{ name: "target", type: stateName2 }],
|
|
14542
15031
|
returnType: `Promise<${toPascalCase2(classSummary.name)}>`,
|
|
14543
15032
|
runtime: {
|
|
14544
15033
|
kind: "state_machine",
|
|
14545
15034
|
machineName: machine.name,
|
|
14546
15035
|
className: classSummary.name,
|
|
14547
|
-
stateTypeName:
|
|
15036
|
+
stateTypeName: stateName2,
|
|
14548
15037
|
transitionTypeName: transitionName,
|
|
14549
15038
|
operation: "reach"
|
|
14550
15039
|
}
|
|
@@ -14559,7 +15048,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14559
15048
|
kind: "state_machine",
|
|
14560
15049
|
machineName: machine.name,
|
|
14561
15050
|
className: classSummary.name,
|
|
14562
|
-
stateTypeName:
|
|
15051
|
+
stateTypeName: stateName2,
|
|
14563
15052
|
transitionTypeName: transitionName,
|
|
14564
15053
|
operation: "list_transitions"
|
|
14565
15054
|
}
|
|
@@ -14569,12 +15058,12 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14569
15058
|
docs: [`List reachable states for ${docsPrefix} from the current state.`],
|
|
14570
15059
|
static: false,
|
|
14571
15060
|
params: [],
|
|
14572
|
-
returnType: `Promise<${
|
|
15061
|
+
returnType: `Promise<${stateName2}[]>`,
|
|
14573
15062
|
runtime: {
|
|
14574
15063
|
kind: "state_machine",
|
|
14575
15064
|
machineName: machine.name,
|
|
14576
15065
|
className: classSummary.name,
|
|
14577
|
-
stateTypeName:
|
|
15066
|
+
stateTypeName: stateName2,
|
|
14578
15067
|
transitionTypeName: transitionName,
|
|
14579
15068
|
operation: "list_reachable_states"
|
|
14580
15069
|
}
|
|
@@ -14589,7 +15078,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14589
15078
|
kind: "state_machine",
|
|
14590
15079
|
machineName: machine.name,
|
|
14591
15080
|
className: classSummary.name,
|
|
14592
|
-
stateTypeName:
|
|
15081
|
+
stateTypeName: stateName2,
|
|
14593
15082
|
transitionTypeName: transitionName,
|
|
14594
15083
|
operation: "is_final"
|
|
14595
15084
|
}
|
|
@@ -14600,13 +15089,13 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14600
15089
|
`List shortest transition paths from the current ${docsPrefix} state to a target state.`
|
|
14601
15090
|
],
|
|
14602
15091
|
static: false,
|
|
14603
|
-
params: [{ name: "target", type:
|
|
14604
|
-
returnType: `Promise<Array<{ states: ${
|
|
15092
|
+
params: [{ name: "target", type: stateName2 }],
|
|
15093
|
+
returnType: `Promise<Array<{ states: ${stateName2}[]; transitions: ${transitionName}[] }>>`,
|
|
14605
15094
|
runtime: {
|
|
14606
15095
|
kind: "state_machine",
|
|
14607
15096
|
machineName: machine.name,
|
|
14608
15097
|
className: classSummary.name,
|
|
14609
|
-
stateTypeName:
|
|
15098
|
+
stateTypeName: stateName2,
|
|
14610
15099
|
transitionTypeName: transitionName,
|
|
14611
15100
|
operation: "paths_to"
|
|
14612
15101
|
}
|
|
@@ -14630,7 +15119,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14630
15119
|
kind: "state_machine",
|
|
14631
15120
|
machineName: machine.name,
|
|
14632
15121
|
className: classSummary.name,
|
|
14633
|
-
stateTypeName:
|
|
15122
|
+
stateTypeName: stateName2,
|
|
14634
15123
|
transitionTypeName: transitionName,
|
|
14635
15124
|
operation: "reach",
|
|
14636
15125
|
targetState: stateNameValue,
|
|
@@ -14649,7 +15138,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14649
15138
|
kind: "state_machine",
|
|
14650
15139
|
machineName: machine.name,
|
|
14651
15140
|
className: classSummary.name,
|
|
14652
|
-
stateTypeName:
|
|
15141
|
+
stateTypeName: stateName2,
|
|
14653
15142
|
transitionTypeName: transitionName,
|
|
14654
15143
|
operation: "prepare_reach",
|
|
14655
15144
|
targetState: stateNameValue,
|
|
@@ -14662,7 +15151,7 @@ function buildMachineMethods(classSummary, machine) {
|
|
|
14662
15151
|
kind: "state_machine",
|
|
14663
15152
|
machineName: machine.name,
|
|
14664
15153
|
className: classSummary.name,
|
|
14665
|
-
stateTypeName:
|
|
15154
|
+
stateTypeName: stateName2,
|
|
14666
15155
|
transitionTypeName: transitionName,
|
|
14667
15156
|
operation: "prepare_create_reach",
|
|
14668
15157
|
targetState: stateNameValue,
|
|
@@ -14728,7 +15217,7 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14728
15217
|
name: String!
|
|
14729
15218
|
state_machine: StateMachine!
|
|
14730
15219
|
add_state(name: String!, is_final: Boolean, label: String, description: String): StateMachineMutation!
|
|
14731
|
-
add_transition(name: String!, from: String!, to: String!, label: String, description: String, action_json: String, assignee_json: String, requirements_json: String, permission_json: String, risk: String, expected_outcome_json: String): StateMachineMutation!
|
|
15220
|
+
add_transition(name: String!, from: String!, to: String!, label: String, description: String, action_json: String, assignee_json: String, requirements_json: String, permission_json: String, risk: String, expected_outcome_json: String, outcomes_json: String): StateMachineMutation!
|
|
14732
15221
|
activate_transition(name: String!): StateMachineMutation!
|
|
14733
15222
|
}
|
|
14734
15223
|
|
|
@@ -14745,6 +15234,7 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14745
15234
|
type StateMachineSnapshotMutation {
|
|
14746
15235
|
snapshot: StateMachineSnapshot!
|
|
14747
15236
|
activate_transition(name: String!): StateMachineSnapshotMutation!
|
|
15237
|
+
commit_transition(name: String!, outcome: String!, to: String!, commit_id: String!, source_version: String): StateMachineSnapshotMutation!
|
|
14748
15238
|
observe_state(state: String!, force: Boolean, source: String): StateMachineSnapshotMutation!
|
|
14749
15239
|
}
|
|
14750
15240
|
|
|
@@ -14791,6 +15281,7 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14791
15281
|
permission_json: String
|
|
14792
15282
|
risk: String
|
|
14793
15283
|
expected_outcome_json: String
|
|
15284
|
+
outcomes_json: String
|
|
14794
15285
|
}
|
|
14795
15286
|
|
|
14796
15287
|
type StateMachinePath {
|
|
@@ -14801,6 +15292,10 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14801
15292
|
type StateMachineTransitionEvent {
|
|
14802
15293
|
sequence: Int!
|
|
14803
15294
|
occurred_at: Float!
|
|
15295
|
+
commit_id: String
|
|
15296
|
+
outcome: String
|
|
15297
|
+
source_version: String
|
|
15298
|
+
projected_from_mismatch: String
|
|
14804
15299
|
transition: StateMachineTransition!
|
|
14805
15300
|
from: StateMachineState!
|
|
14806
15301
|
to: StateMachineState!
|
|
@@ -14866,7 +15361,8 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14866
15361
|
requirements_json,
|
|
14867
15362
|
permission_json,
|
|
14868
15363
|
risk,
|
|
14869
|
-
expected_outcome_json
|
|
15364
|
+
expected_outcome_json,
|
|
15365
|
+
outcomes_json
|
|
14870
15366
|
}) => {
|
|
14871
15367
|
await run(
|
|
14872
15368
|
value.target.add_state_machine_transition(
|
|
@@ -14882,7 +15378,8 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14882
15378
|
requirementsJson: requirements_json,
|
|
14883
15379
|
permissionJson: permission_json,
|
|
14884
15380
|
risk,
|
|
14885
|
-
expectedOutcomeJson: expected_outcome_json
|
|
15381
|
+
expectedOutcomeJson: expected_outcome_json,
|
|
15382
|
+
outcomesJson: outcomes_json
|
|
14886
15383
|
}
|
|
14887
15384
|
)
|
|
14888
15385
|
);
|
|
@@ -14903,6 +15400,19 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14903
15400
|
);
|
|
14904
15401
|
return value;
|
|
14905
15402
|
},
|
|
15403
|
+
commit_transition: async (value, { name, outcome, to, commit_id, source_version }) => {
|
|
15404
|
+
await run(
|
|
15405
|
+
value.target.commit_state_machine_transition(
|
|
15406
|
+
value.name,
|
|
15407
|
+
name,
|
|
15408
|
+
outcome,
|
|
15409
|
+
to,
|
|
15410
|
+
commit_id,
|
|
15411
|
+
source_version
|
|
15412
|
+
)
|
|
15413
|
+
);
|
|
15414
|
+
return value;
|
|
15415
|
+
},
|
|
14906
15416
|
observe_state: async (value, { state, force, source }) => {
|
|
14907
15417
|
await run(
|
|
14908
15418
|
value.target.observe_state_machine_state(
|
|
@@ -14932,7 +15442,8 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14932
15442
|
requirements_json: (value) => value.requirements_json || null,
|
|
14933
15443
|
permission_json: (value) => value.permission_json || null,
|
|
14934
15444
|
risk: (value) => value.risk || null,
|
|
14935
|
-
expected_outcome_json: (value) => value.expected_outcome_json || null
|
|
15445
|
+
expected_outcome_json: (value) => value.expected_outcome_json || null,
|
|
15446
|
+
outcomes_json: (value) => value.outcomes_json || null
|
|
14936
15447
|
},
|
|
14937
15448
|
StateMachinePath: {
|
|
14938
15449
|
states: (value) => value.states,
|
|
@@ -14941,6 +15452,10 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
14941
15452
|
StateMachineTransitionEvent: {
|
|
14942
15453
|
sequence: (value) => value.sequence,
|
|
14943
15454
|
occurred_at: (value) => value.occurred_at,
|
|
15455
|
+
commit_id: (value) => value.commit_id || null,
|
|
15456
|
+
outcome: (value) => value.outcome || null,
|
|
15457
|
+
source_version: (value) => value.source_version || null,
|
|
15458
|
+
projected_from_mismatch: (value) => value.projected_from_mismatch || null,
|
|
14944
15459
|
transition: (value) => value.transition,
|
|
14945
15460
|
from: (value) => value.from,
|
|
14946
15461
|
to: (value) => value.to
|
|
@@ -15014,6 +15529,7 @@ var stateMachineMetamodelPackage = defineMetamodelPackage({
|
|
|
15014
15529
|
permission_json
|
|
15015
15530
|
risk
|
|
15016
15531
|
expected_outcome_json
|
|
15532
|
+
outcomes_json
|
|
15017
15533
|
}
|
|
15018
15534
|
}`
|
|
15019
15535
|
]
|
|
@@ -15741,6 +16257,133 @@ var Environment = class _Environment {
|
|
|
15741
16257
|
getAwaitingCount: async () => this.getAwaitingRecordCount()
|
|
15742
16258
|
};
|
|
15743
16259
|
}
|
|
16260
|
+
/**
|
|
16261
|
+
* Acknowledge a declared product mutation that already happened outside a
|
|
16262
|
+
* Granular-run effect (for example, in a webhook consumer). These methods
|
|
16263
|
+
* run the declaration's pure projection mapper; they never call its handler.
|
|
16264
|
+
*/
|
|
16265
|
+
get commit() {
|
|
16266
|
+
return {
|
|
16267
|
+
effect: async (effect, productResult, options = {}) => this.persistExternalEffect(effect, productResult, options),
|
|
16268
|
+
transition: async (transition, productResult, options = {}) => this.persistExternalTransition(transition, productResult, options),
|
|
16269
|
+
get: async (commitId) => this.controlPlaneRequest(
|
|
16270
|
+
`/control/environments/${this.environmentId}/commits/${encodeURIComponent(
|
|
16271
|
+
commitId
|
|
16272
|
+
)}`
|
|
16273
|
+
),
|
|
16274
|
+
retry: async (commitId) => this.controlPlaneRequest(
|
|
16275
|
+
`/control/environments/${this.environmentId}/commits/${encodeURIComponent(
|
|
16276
|
+
commitId
|
|
16277
|
+
)}/retry`,
|
|
16278
|
+
{ method: "POST" }
|
|
16279
|
+
)
|
|
16280
|
+
};
|
|
16281
|
+
}
|
|
16282
|
+
/** Inspect or retry the agent synchronization of a product snapshot. */
|
|
16283
|
+
get observation() {
|
|
16284
|
+
return {
|
|
16285
|
+
get: async (observationId) => this.controlPlaneRequest(
|
|
16286
|
+
`/control/environments/${this.environmentId}/observations/${encodeURIComponent(
|
|
16287
|
+
observationId
|
|
16288
|
+
)}`
|
|
16289
|
+
),
|
|
16290
|
+
retry: async (observationId) => this.controlPlaneRequest(
|
|
16291
|
+
`/control/environments/${this.environmentId}/observations/${encodeURIComponent(
|
|
16292
|
+
observationId
|
|
16293
|
+
)}/retry`,
|
|
16294
|
+
{ method: "POST" }
|
|
16295
|
+
)
|
|
16296
|
+
};
|
|
16297
|
+
}
|
|
16298
|
+
async persistExternalEffect(effect, productResult, options) {
|
|
16299
|
+
const projection = effect.commit.project(productResult);
|
|
16300
|
+
validateProjectionResult(effect.commit, projection);
|
|
16301
|
+
this.requireExternalIdentity(projection.source.version, options);
|
|
16302
|
+
return this.controlPlaneRequest(
|
|
16303
|
+
`/control/environments/${this.environmentId}/external-commits`,
|
|
16304
|
+
{
|
|
16305
|
+
method: "POST",
|
|
16306
|
+
body: JSON.stringify({
|
|
16307
|
+
kind: "effect",
|
|
16308
|
+
effectKey: computeEffectKey2(effect),
|
|
16309
|
+
...options.sourceEventId?.trim() ? { sourceEventId: options.sourceEventId.trim() } : {},
|
|
16310
|
+
projection
|
|
16311
|
+
})
|
|
16312
|
+
}
|
|
16313
|
+
);
|
|
16314
|
+
}
|
|
16315
|
+
async persistExternalTransition(transition, productResult, options) {
|
|
16316
|
+
const metadata = getDefinedTransitionMetadata(transition);
|
|
16317
|
+
if (!metadata) {
|
|
16318
|
+
throw new Error(
|
|
16319
|
+
"environment.commit.transition requires a transition returned by defineStateMachine"
|
|
16320
|
+
);
|
|
16321
|
+
}
|
|
16322
|
+
const projection = transition.effect.commit.project(productResult);
|
|
16323
|
+
validateProjectionResult(transition.effect.commit, projection);
|
|
16324
|
+
this.requireExternalIdentity(projection.source.version, options);
|
|
16325
|
+
if (!Object.prototype.hasOwnProperty.call(
|
|
16326
|
+
transition.outcomes,
|
|
16327
|
+
projection.outcome.key
|
|
16328
|
+
)) {
|
|
16329
|
+
throw new Error(
|
|
16330
|
+
`Transition ${metadata.machine}.${metadata.transition} does not declare outcome ${projection.outcome.key}`
|
|
16331
|
+
);
|
|
16332
|
+
}
|
|
16333
|
+
if (!projection.primaryTarget) {
|
|
16334
|
+
throw new Error(
|
|
16335
|
+
"An external transition projection requires primaryTarget to identify the transitioned product record"
|
|
16336
|
+
);
|
|
16337
|
+
}
|
|
16338
|
+
return this.controlPlaneRequest(
|
|
16339
|
+
`/control/environments/${this.environmentId}/external-commits`,
|
|
16340
|
+
{
|
|
16341
|
+
method: "POST",
|
|
16342
|
+
body: JSON.stringify({
|
|
16343
|
+
kind: "transition",
|
|
16344
|
+
effectKey: computeEffectKey2(transition.effect),
|
|
16345
|
+
...options.sourceEventId?.trim() ? { sourceEventId: options.sourceEventId.trim() } : {},
|
|
16346
|
+
projection,
|
|
16347
|
+
transition: {
|
|
16348
|
+
className: projection.primaryTarget.className,
|
|
16349
|
+
objectId: projection.primaryTarget.id,
|
|
16350
|
+
...projection.primaryTarget.path ? { objectPath: projection.primaryTarget.path } : {},
|
|
16351
|
+
machine: metadata.machine,
|
|
16352
|
+
transition: metadata.transition,
|
|
16353
|
+
from: transition.from
|
|
16354
|
+
}
|
|
16355
|
+
})
|
|
16356
|
+
}
|
|
16357
|
+
);
|
|
16358
|
+
}
|
|
16359
|
+
requireExternalIdentity(sourceVersion, options) {
|
|
16360
|
+
if (!options.sourceEventId?.trim() && !sourceVersion?.trim()) {
|
|
16361
|
+
throw new Error(
|
|
16362
|
+
"An external commit requires sourceEventId or a source version from its projection mapper"
|
|
16363
|
+
);
|
|
16364
|
+
}
|
|
16365
|
+
}
|
|
16366
|
+
/**
|
|
16367
|
+
* Synchronize a versioned product snapshot without claiming an effect or
|
|
16368
|
+
* lifecycle transition. This records no transition history.
|
|
16369
|
+
*/
|
|
16370
|
+
async observe(mapper, productResult) {
|
|
16371
|
+
const declaration = { kind: "effect"};
|
|
16372
|
+
const projection = mapper(productResult);
|
|
16373
|
+
validateProjectionResult(declaration, projection);
|
|
16374
|
+
if (!projection.source.version?.trim()) {
|
|
16375
|
+
throw new Error(
|
|
16376
|
+
"environment.observe requires a monotonic source version or serialized adapter sequence"
|
|
16377
|
+
);
|
|
16378
|
+
}
|
|
16379
|
+
return this.controlPlaneRequest(
|
|
16380
|
+
`/control/environments/${this.environmentId}/observations`,
|
|
16381
|
+
{
|
|
16382
|
+
method: "POST",
|
|
16383
|
+
body: JSON.stringify({ projection })
|
|
16384
|
+
}
|
|
16385
|
+
);
|
|
16386
|
+
}
|
|
15744
16387
|
/**
|
|
15745
16388
|
* Mirror product-owned workflow state into Granular without making Granular
|
|
15746
16389
|
* own the customer application's state machine.
|
|
@@ -15780,8 +16423,8 @@ var Environment = class _Environment {
|
|
|
15780
16423
|
* `await env.recordState({ className: "spend_request", id, machine: "lifecycle", state: "policy_review", source: "customer_backend" })`
|
|
15781
16424
|
*/
|
|
15782
16425
|
state(target) {
|
|
15783
|
-
const observe = async (machineName,
|
|
15784
|
-
const observedState = input.observedState || input.state ||
|
|
16426
|
+
const observe = async (machineName, stateName2, input = {}) => {
|
|
16427
|
+
const observedState = input.observedState || input.state || stateName2;
|
|
15785
16428
|
if (!observedState) {
|
|
15786
16429
|
throw new Error("State observation requires a target state");
|
|
15787
16430
|
}
|
|
@@ -15807,7 +16450,7 @@ var Environment = class _Environment {
|
|
|
15807
16450
|
{
|
|
15808
16451
|
get: (_machineTarget, stateProperty) => {
|
|
15809
16452
|
if (stateProperty === "to") {
|
|
15810
|
-
return (
|
|
16453
|
+
return (stateName2, input) => observe(machineProperty, stateName2, input || {});
|
|
15811
16454
|
}
|
|
15812
16455
|
if (typeof stateProperty !== "string") return void 0;
|
|
15813
16456
|
return (input) => observe(
|
|
@@ -17147,6 +17790,14 @@ var EnvironmentSession = class extends Session {
|
|
|
17147
17790
|
}
|
|
17148
17791
|
};
|
|
17149
17792
|
}
|
|
17793
|
+
get mutations() {
|
|
17794
|
+
return {
|
|
17795
|
+
list: (options = {}) => this.sessionDataRequest(
|
|
17796
|
+
"/mutations",
|
|
17797
|
+
options
|
|
17798
|
+
)
|
|
17799
|
+
};
|
|
17800
|
+
}
|
|
17150
17801
|
get artifacts() {
|
|
17151
17802
|
return {
|
|
17152
17803
|
list: (options = {}) => {
|
|
@@ -18646,6 +19297,7 @@ var Granular = class _Granular {
|
|
|
18646
19297
|
const serialized = {
|
|
18647
19298
|
effectKey: computeEffectKey2(effect),
|
|
18648
19299
|
name: effect.name,
|
|
19300
|
+
...effect.label ? { label: effect.label } : {},
|
|
18649
19301
|
description: effect.description,
|
|
18650
19302
|
inputSchema: effect.inputSchema,
|
|
18651
19303
|
stability: effect.stability || "stable",
|
|
@@ -18669,6 +19321,9 @@ var Granular = class _Granular {
|
|
|
18669
19321
|
if (effect.metamodels !== void 0) {
|
|
18670
19322
|
serialized.metamodels = effect.metamodels;
|
|
18671
19323
|
}
|
|
19324
|
+
if (effect.commit !== void 0) {
|
|
19325
|
+
serialized.commit = { kind: effect.commit.kind };
|
|
19326
|
+
}
|
|
18672
19327
|
return serialized;
|
|
18673
19328
|
}
|
|
18674
19329
|
async publishSandboxEffectCatalog(host) {
|
|
@@ -18889,16 +19544,60 @@ var Granular = class _Granular {
|
|
|
18889
19544
|
};
|
|
18890
19545
|
wsClient.registerRpcHandler("effect.invoke", async (params) => {
|
|
18891
19546
|
const request = params;
|
|
18892
|
-
|
|
19547
|
+
let commitReceipt;
|
|
19548
|
+
const result = await invokeRegisteredEffect(
|
|
18893
19549
|
this.getSandboxEffectMap(sandboxId),
|
|
18894
19550
|
request,
|
|
18895
19551
|
{
|
|
19552
|
+
commitAcknowledged: (receipt) => {
|
|
19553
|
+
commitReceipt = receipt;
|
|
19554
|
+
},
|
|
19555
|
+
commit: {
|
|
19556
|
+
persist: (commitRequest) => this.request(
|
|
19557
|
+
`/control/environments/${encodeURIComponent(
|
|
19558
|
+
commitRequest.environmentId
|
|
19559
|
+
)}/commits`,
|
|
19560
|
+
{
|
|
19561
|
+
method: "POST",
|
|
19562
|
+
body: JSON.stringify({
|
|
19563
|
+
kind: commitRequest.kind,
|
|
19564
|
+
invocationId: commitRequest.invocationId,
|
|
19565
|
+
idempotencyKey: commitRequest.idempotencyKey,
|
|
19566
|
+
effectKey: commitRequest.effectKey,
|
|
19567
|
+
projection: commitRequest.projection
|
|
19568
|
+
})
|
|
19569
|
+
}
|
|
19570
|
+
),
|
|
19571
|
+
mappingFailed: (failure) => this.request(
|
|
19572
|
+
`/control/environments/${encodeURIComponent(
|
|
19573
|
+
failure.environmentId
|
|
19574
|
+
)}/commit-invocations/${encodeURIComponent(
|
|
19575
|
+
failure.invocationId
|
|
19576
|
+
)}`,
|
|
19577
|
+
{
|
|
19578
|
+
method: "PATCH",
|
|
19579
|
+
body: JSON.stringify({
|
|
19580
|
+
status: "mapping_failed",
|
|
19581
|
+
error: {
|
|
19582
|
+
code: "commit_projection_mapping_failed",
|
|
19583
|
+
message: failure.message,
|
|
19584
|
+
retryable: false
|
|
19585
|
+
}
|
|
19586
|
+
})
|
|
19587
|
+
}
|
|
19588
|
+
)
|
|
19589
|
+
},
|
|
18896
19590
|
feedback: {
|
|
18897
19591
|
invocationId: request.callId,
|
|
18898
19592
|
publish: (method, publishParams) => wsClient.call(method, publishParams)
|
|
18899
19593
|
}
|
|
18900
19594
|
}
|
|
18901
19595
|
);
|
|
19596
|
+
return {
|
|
19597
|
+
__granularEffectInvocationResult: true,
|
|
19598
|
+
result,
|
|
19599
|
+
...commitReceipt ? { commit: commitReceipt } : {}
|
|
19600
|
+
};
|
|
18902
19601
|
});
|
|
18903
19602
|
wsClient.on("open", () => {
|
|
18904
19603
|
void this.synchronizeEffectHost(host).catch((error) => {
|
|
@@ -19470,6 +20169,275 @@ var Granular = class _Granular {
|
|
|
19470
20169
|
}
|
|
19471
20170
|
};
|
|
19472
20171
|
|
|
20172
|
+
// src/record-snapshot-projection.ts
|
|
20173
|
+
function stableValue(value) {
|
|
20174
|
+
if (Array.isArray(value)) return value.map(stableValue);
|
|
20175
|
+
if (value && typeof value === "object") {
|
|
20176
|
+
return Object.fromEntries(
|
|
20177
|
+
Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, stableValue(item)])
|
|
20178
|
+
);
|
|
20179
|
+
}
|
|
20180
|
+
return value;
|
|
20181
|
+
}
|
|
20182
|
+
function stableJson(value) {
|
|
20183
|
+
return JSON.stringify(stableValue(value));
|
|
20184
|
+
}
|
|
20185
|
+
function recordKey(record) {
|
|
20186
|
+
return `${record.className}\0${record.id}`;
|
|
20187
|
+
}
|
|
20188
|
+
function recordReference(className, id) {
|
|
20189
|
+
return { className, id };
|
|
20190
|
+
}
|
|
20191
|
+
function changedRecordSnapshots(beforeRecords, afterRecords) {
|
|
20192
|
+
const before = new Map(
|
|
20193
|
+
beforeRecords.map((record) => [recordKey(record), record])
|
|
20194
|
+
);
|
|
20195
|
+
const after = new Map(
|
|
20196
|
+
afterRecords.map((record) => [recordKey(record), record])
|
|
20197
|
+
);
|
|
20198
|
+
const changedKeys = /* @__PURE__ */ new Set();
|
|
20199
|
+
for (const key of /* @__PURE__ */ new Set([...before.keys(), ...after.keys()])) {
|
|
20200
|
+
if (stableJson(before.get(key)) !== stableJson(after.get(key))) {
|
|
20201
|
+
changedKeys.add(key);
|
|
20202
|
+
}
|
|
20203
|
+
}
|
|
20204
|
+
return {
|
|
20205
|
+
beforeRecords: beforeRecords.filter(
|
|
20206
|
+
(record) => changedKeys.has(recordKey(record))
|
|
20207
|
+
),
|
|
20208
|
+
afterRecords: afterRecords.filter(
|
|
20209
|
+
(record) => changedKeys.has(recordKey(record))
|
|
20210
|
+
)
|
|
20211
|
+
};
|
|
20212
|
+
}
|
|
20213
|
+
function relationshipTargets(manifest) {
|
|
20214
|
+
const targets = /* @__PURE__ */ new Map();
|
|
20215
|
+
for (const volume of manifest.volumes) {
|
|
20216
|
+
for (const operation of volume.operations) {
|
|
20217
|
+
const relationship = operation.defineRelationship;
|
|
20218
|
+
if (!relationship) continue;
|
|
20219
|
+
targets.set(`${relationship.left}\0${relationship.leftSubmodel}`, {
|
|
20220
|
+
className: relationship.right
|
|
20221
|
+
});
|
|
20222
|
+
targets.set(`${relationship.right}\0${relationship.rightSubmodel}`, {
|
|
20223
|
+
className: relationship.left
|
|
20224
|
+
});
|
|
20225
|
+
}
|
|
20226
|
+
}
|
|
20227
|
+
return targets;
|
|
20228
|
+
}
|
|
20229
|
+
function stateName(value) {
|
|
20230
|
+
return typeof value === "string" ? value : value.state;
|
|
20231
|
+
}
|
|
20232
|
+
function asIds(value) {
|
|
20233
|
+
return value === void 0 ? [] : Array.isArray(value) ? value : [value];
|
|
20234
|
+
}
|
|
20235
|
+
function changedObjectProjection(before, after) {
|
|
20236
|
+
const beforeFields = before?.fields || {};
|
|
20237
|
+
const afterFields = after.fields || {};
|
|
20238
|
+
const fields = { ...afterFields };
|
|
20239
|
+
for (const fieldName of Object.keys(beforeFields)) {
|
|
20240
|
+
if (!(fieldName in afterFields)) fields[fieldName] = null;
|
|
20241
|
+
}
|
|
20242
|
+
if (before && before.label === after.label && stableJson(beforeFields) === stableJson(afterFields)) {
|
|
20243
|
+
return null;
|
|
20244
|
+
}
|
|
20245
|
+
return {
|
|
20246
|
+
kind: "object",
|
|
20247
|
+
operation: before ? "updated" : "created",
|
|
20248
|
+
record: {
|
|
20249
|
+
className: after.className,
|
|
20250
|
+
id: after.id,
|
|
20251
|
+
...after.label !== void 0 ? { label: after.label } : {},
|
|
20252
|
+
fields
|
|
20253
|
+
}
|
|
20254
|
+
};
|
|
20255
|
+
}
|
|
20256
|
+
function projectionChanges(input) {
|
|
20257
|
+
const before = new Map(
|
|
20258
|
+
input.beforeRecords.map((record) => [recordKey(record), record])
|
|
20259
|
+
);
|
|
20260
|
+
const after = new Map(
|
|
20261
|
+
input.afterRecords.map((record) => [recordKey(record), record])
|
|
20262
|
+
);
|
|
20263
|
+
const targets = relationshipTargets(input.manifest);
|
|
20264
|
+
const changes = [];
|
|
20265
|
+
for (const record of input.afterRecords) {
|
|
20266
|
+
const previous = before.get(recordKey(record));
|
|
20267
|
+
const objectChange = changedObjectProjection(previous, record);
|
|
20268
|
+
if (objectChange) changes.push(objectChange);
|
|
20269
|
+
const relationshipNames = /* @__PURE__ */ new Set([
|
|
20270
|
+
...Object.keys(previous?.relationships || {}),
|
|
20271
|
+
...Object.keys(record.relationships || {})
|
|
20272
|
+
]);
|
|
20273
|
+
for (const relationshipName of [...relationshipNames].sort()) {
|
|
20274
|
+
const target = targets.get(
|
|
20275
|
+
`${record.className}\0${relationshipName}`
|
|
20276
|
+
);
|
|
20277
|
+
if (!target) {
|
|
20278
|
+
throw new Error(
|
|
20279
|
+
`No ontology relationship target is declared for ${record.className}.${relationshipName}`
|
|
20280
|
+
);
|
|
20281
|
+
}
|
|
20282
|
+
const previousIds = new Set(
|
|
20283
|
+
asIds(previous?.relationships?.[relationshipName])
|
|
20284
|
+
);
|
|
20285
|
+
const currentIds = new Set(
|
|
20286
|
+
asIds(record.relationships?.[relationshipName])
|
|
20287
|
+
);
|
|
20288
|
+
for (const id of [...previousIds].sort()) {
|
|
20289
|
+
if (currentIds.has(id)) continue;
|
|
20290
|
+
changes.push({
|
|
20291
|
+
kind: "relationship",
|
|
20292
|
+
operation: "disconnected",
|
|
20293
|
+
relationship: relationshipName,
|
|
20294
|
+
from: recordReference(record.className, record.id),
|
|
20295
|
+
to: recordReference(target.className, id)
|
|
20296
|
+
});
|
|
20297
|
+
}
|
|
20298
|
+
for (const id of [...currentIds].sort()) {
|
|
20299
|
+
if (previousIds.has(id)) continue;
|
|
20300
|
+
changes.push({
|
|
20301
|
+
kind: "relationship",
|
|
20302
|
+
operation: "connected",
|
|
20303
|
+
relationship: relationshipName,
|
|
20304
|
+
from: recordReference(record.className, record.id),
|
|
20305
|
+
to: recordReference(target.className, id)
|
|
20306
|
+
});
|
|
20307
|
+
}
|
|
20308
|
+
}
|
|
20309
|
+
const machines = /* @__PURE__ */ new Set([
|
|
20310
|
+
...Object.keys(previous?.states || {}),
|
|
20311
|
+
...Object.keys(record.states || {})
|
|
20312
|
+
]);
|
|
20313
|
+
for (const machine of [...machines].sort()) {
|
|
20314
|
+
const next = record.states?.[machine];
|
|
20315
|
+
if (next === void 0) continue;
|
|
20316
|
+
const prior = previous?.states?.[machine];
|
|
20317
|
+
if (prior !== void 0 && stateName(prior) === stateName(next)) continue;
|
|
20318
|
+
if (input.transition && input.transition.className === record.className && input.transition.objectId === record.id && input.transition.machine === machine) {
|
|
20319
|
+
continue;
|
|
20320
|
+
}
|
|
20321
|
+
changes.push({
|
|
20322
|
+
kind: "state_observation",
|
|
20323
|
+
target: recordReference(record.className, record.id),
|
|
20324
|
+
machine,
|
|
20325
|
+
state: stateName(next)
|
|
20326
|
+
});
|
|
20327
|
+
}
|
|
20328
|
+
}
|
|
20329
|
+
for (const record of input.beforeRecords) {
|
|
20330
|
+
if (after.has(recordKey(record))) continue;
|
|
20331
|
+
changes.push({
|
|
20332
|
+
kind: "object",
|
|
20333
|
+
operation: "deleted",
|
|
20334
|
+
target: recordReference(record.className, record.id)
|
|
20335
|
+
});
|
|
20336
|
+
}
|
|
20337
|
+
return changes;
|
|
20338
|
+
}
|
|
20339
|
+
function valueAtPath(value, path) {
|
|
20340
|
+
return path.split(".").filter(Boolean).reduce((current, segment) => {
|
|
20341
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
20342
|
+
return void 0;
|
|
20343
|
+
}
|
|
20344
|
+
return current[segment];
|
|
20345
|
+
}, value);
|
|
20346
|
+
}
|
|
20347
|
+
function primaryTarget(input) {
|
|
20348
|
+
if (input.transition) {
|
|
20349
|
+
return recordReference(
|
|
20350
|
+
input.transition.className,
|
|
20351
|
+
input.transition.objectId
|
|
20352
|
+
);
|
|
20353
|
+
}
|
|
20354
|
+
const creates = input.effect.metamodels?.creates;
|
|
20355
|
+
if (creates) {
|
|
20356
|
+
const declaration = typeof creates === "string" ? { className: creates } : creates;
|
|
20357
|
+
const id = declaration.idPath ? valueAtPath(input.result, declaration.idPath) : void 0;
|
|
20358
|
+
if (typeof id === "string" && id) {
|
|
20359
|
+
return recordReference(declaration.className, id);
|
|
20360
|
+
}
|
|
20361
|
+
}
|
|
20362
|
+
if (input.effect.className && !input.effect.static) {
|
|
20363
|
+
const objectId = input.effectInput && typeof input.effectInput === "object" && !Array.isArray(input.effectInput) ? input.effectInput._objectId : void 0;
|
|
20364
|
+
if (typeof objectId === "string" && objectId) {
|
|
20365
|
+
return recordReference(input.effect.className, objectId);
|
|
20366
|
+
}
|
|
20367
|
+
}
|
|
20368
|
+
const created = input.changes.filter(
|
|
20369
|
+
(change) => change.kind === "object" && change.operation === "created"
|
|
20370
|
+
);
|
|
20371
|
+
const onlyCreated = created.length === 1 ? created[0] : void 0;
|
|
20372
|
+
return onlyCreated ? recordReference(onlyCreated.record.className, onlyCreated.record.id) : void 0;
|
|
20373
|
+
}
|
|
20374
|
+
function transitionOutcome(transition, afterRecords) {
|
|
20375
|
+
if (!transition) {
|
|
20376
|
+
throw new Error("A transition commit has no authored transition context.");
|
|
20377
|
+
}
|
|
20378
|
+
const target = afterRecords.find(
|
|
20379
|
+
(record) => record.className === transition.className && record.id === transition.objectId
|
|
20380
|
+
);
|
|
20381
|
+
const observed = target?.states?.[transition.machine];
|
|
20382
|
+
if (!observed) {
|
|
20383
|
+
throw new Error(
|
|
20384
|
+
`The product result did not expose ${transition.className}:${transition.objectId}.${transition.machine}`
|
|
20385
|
+
);
|
|
20386
|
+
}
|
|
20387
|
+
const finalState = stateName(observed);
|
|
20388
|
+
const matches = Object.entries(transition.outcomes).filter(
|
|
20389
|
+
([, outcome]) => outcome.to === finalState || outcome.to === "$current" && finalState === transition.from
|
|
20390
|
+
);
|
|
20391
|
+
if (matches.length !== 1) {
|
|
20392
|
+
throw new Error(
|
|
20393
|
+
`Product state ${finalState} maps to ${matches.length} authored outcomes for ${transition.machine}.${transition.transition}`
|
|
20394
|
+
);
|
|
20395
|
+
}
|
|
20396
|
+
const [key, declaration] = matches[0];
|
|
20397
|
+
return {
|
|
20398
|
+
key,
|
|
20399
|
+
...declaration.disposition === "error" ? {
|
|
20400
|
+
error: {
|
|
20401
|
+
code: `product_outcome_${key}`,
|
|
20402
|
+
message: declaration.label || `The product completed in ${finalState} instead of continuing.`,
|
|
20403
|
+
retryable: false
|
|
20404
|
+
}
|
|
20405
|
+
} : {}
|
|
20406
|
+
};
|
|
20407
|
+
}
|
|
20408
|
+
function projectRecordSnapshotMutation(input) {
|
|
20409
|
+
const changes = projectionChanges({
|
|
20410
|
+
manifest: input.manifest,
|
|
20411
|
+
beforeRecords: input.source.beforeRecords,
|
|
20412
|
+
afterRecords: input.source.afterRecords,
|
|
20413
|
+
transition: input.transition
|
|
20414
|
+
});
|
|
20415
|
+
const target = primaryTarget({
|
|
20416
|
+
effect: input.effect,
|
|
20417
|
+
effectInput: input.effectInput,
|
|
20418
|
+
result: input.result,
|
|
20419
|
+
changes,
|
|
20420
|
+
transition: input.transition
|
|
20421
|
+
});
|
|
20422
|
+
const base = {
|
|
20423
|
+
source: {
|
|
20424
|
+
reference: input.source.reference,
|
|
20425
|
+
...input.source.version ? { version: input.source.version } : {}
|
|
20426
|
+
},
|
|
20427
|
+
...target ? { primaryTarget: target } : {},
|
|
20428
|
+
changes,
|
|
20429
|
+
safeSummary: {
|
|
20430
|
+
effect: input.effect.name,
|
|
20431
|
+
affectedChanges: changes.length
|
|
20432
|
+
}
|
|
20433
|
+
};
|
|
20434
|
+
if (input.commitKind === "effect") return base;
|
|
20435
|
+
return {
|
|
20436
|
+
...base,
|
|
20437
|
+
outcome: transitionOutcome(input.transition, input.source.afterRecords)
|
|
20438
|
+
};
|
|
20439
|
+
}
|
|
20440
|
+
|
|
19473
20441
|
// src/agent-harness-templates/action-presentation/0.1.0/manifest.json
|
|
19474
20442
|
var manifest_default = {
|
|
19475
20443
|
id: "action-presentation",
|
|
@@ -22478,6 +23446,6 @@ function calculateOpenAITokenSpend(model, rawUsage) {
|
|
|
22478
23446
|
};
|
|
22479
23447
|
}
|
|
22480
23448
|
|
|
22481
|
-
export { Environment, EnvironmentSession, GRANULAR_FEED_DIAGNOSTIC_EVENT, Granular, OPENAI_MODEL_PRICING_USD_PER_MILLION, OntologyHandle, Session, SessionFeedController, WSClient, buildContinuationInstruction, buildContinuationInstructionFromTemplate, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentFileBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentManualActionBlock, buildGranularAgentManualActionMemorySummary, buildGranularAgentReferentBlock, buildGranularAgentRuntimeImportsBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentSystemPromptFromTemplate, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, buildOpenAISpendEventId, buildSessionTranscript, buildSessionTranscriptFromFeedItems, calculateOpenAITokenSpend, consumeGranularReasoningOnlyChunk, consumeGranularReasoningTraceChunk, createFeedPublisher, createHarnessVerifierSnapshot, emitFeedDiagnostic, emitFeedDiagnosticToDefaultSink, emptyFeedSnapshot, evaluateContinuation, evaluateValidationRule, extractPromptTokens, getCurrentClosureId, getDefaultHarnessTemplateId, getExclusivePromptTarget, getOpenAIModelPricing, hasCanonicalSessionFeedActivation, hasOpenPrompt, hashHarnessTemplateValue, invokeRegisteredEffect, isCanonicalSessionFeedDocument, isLocalApiUrl, listHarnessTemplates, mergeFeedItemsBySequence, normalizeEffectBehaviors, normalizeFeedDiagnostic, normalizeFeedDiagnosticKind, normalizeFeedPage, normalizeOpenAIUsage, normalizePrompt, normalizePromptChoiceOption, normalizePromptText, normalizePromptType, orderTransientFeedItems, projectConversationReferentFocus, projectConversationReferentSummary, projectHeapSummary, projectLoopSummary, projectSessionFileSummary, projectWorkflowFocus, projectWorkflowSummary, readSessionFeedSnapshot, recordOpenAIUsageSpend, renderContinuationInstructionFromTemplate, renderGranularAgentSystemPromptFromTemplate, resolveApiUrl, resolveAuthTokenForApiUrl, resolveHarnessTemplate, resolveJobPresentation, resolvePromptAnswer, reviewGeneratedJobCode, scorePromptChoiceMatch, stripGranularReasoningTrace, toGranularHttpBase, validateHarnessTemplateManifest, validationRuleFailureMessage };
|
|
23449
|
+
export { Environment, EnvironmentSession, GRANULAR_FEED_DIAGNOSTIC_EVENT, Granular, OPENAI_MODEL_PRICING_USD_PER_MILLION, OntologyHandle, Session, SessionFeedController, WSClient, buildContinuationInstruction, buildContinuationInstructionFromTemplate, buildGranularAgentCheckpointBlock, buildGranularAgentDomainBlock, buildGranularAgentFileBlock, buildGranularAgentHeapBlock, buildGranularAgentLoopBlock, buildGranularAgentManualActionBlock, buildGranularAgentManualActionMemorySummary, buildGranularAgentReferentBlock, buildGranularAgentRuntimeImportsBlock, buildGranularAgentSessionBlock, buildGranularAgentSystemPrompt, buildGranularAgentSystemPromptFromTemplate, buildGranularAgentToolBlock, buildGranularAgentWorkflowBlock, buildOpenAISpendEventId, buildSessionTranscript, buildSessionTranscriptFromFeedItems, calculateOpenAITokenSpend, canonicalizeCommitValue, changedRecordSnapshots, consumeGranularReasoningOnlyChunk, consumeGranularReasoningTraceChunk, createFeedPublisher, createHarnessVerifierSnapshot, defineEffect, defineProjection, defineStateMachine, emitFeedDiagnostic, emitFeedDiagnosticToDefaultSink, emptyFeedSnapshot, evaluateContinuation, evaluateValidationRule, extractPromptTokens, getCurrentClosureId, getDefaultHarnessTemplateId, getExclusivePromptTarget, getOpenAIModelPricing, hasCanonicalSessionFeedActivation, hasOpenPrompt, hashHarnessTemplateValue, invokeRegisteredEffect, isCanonicalSessionFeedDocument, isLocalApiUrl, listHarnessTemplates, mergeFeedItemsBySequence, normalizeEffectBehaviors, normalizeFeedDiagnostic, normalizeFeedDiagnosticKind, normalizeFeedPage, normalizeOpenAIUsage, normalizePrompt, normalizePromptChoiceOption, normalizePromptText, normalizePromptType, orderTransientFeedItems, projectConversationReferentFocus, projectConversationReferentSummary, projectHeapSummary, projectLoopSummary, projectRecordSnapshotMutation, projectSessionFileSummary, projectWorkflowFocus, projectWorkflowSummary, readSessionFeedSnapshot, recordOpenAIUsageSpend, renderContinuationInstructionFromTemplate, renderGranularAgentSystemPromptFromTemplate, resolveApiUrl, resolveAuthTokenForApiUrl, resolveHarnessTemplate, resolveJobPresentation, resolvePromptAnswer, reviewGeneratedJobCode, scorePromptChoiceMatch, stripGranularReasoningTrace, toGranularHttpBase, validateHarnessTemplateManifest, validateProjectionResult, validationRuleFailureMessage };
|
|
22482
23450
|
//# sourceMappingURL=index.mjs.map
|
|
22483
23451
|
//# sourceMappingURL=index.mjs.map
|