@stigmer/runner-slim 3.2.1 → 3.2.2
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/main.js +32 -16
- package/package.json +6 -6
- package/workflow-bundle.js +133 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/runner-slim",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Self-contained Stigmer runner build for embedding in desktop apps — the bundle-friendly @stigmer/runner",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"jq-wasm": "^1.1.0-jq-1.8.1"
|
|
17
17
|
},
|
|
18
18
|
"optionalDependencies": {
|
|
19
|
-
"@stigmer/runner-slim-darwin-arm64": "3.2.
|
|
20
|
-
"@stigmer/runner-slim-darwin-x64": "3.2.
|
|
21
|
-
"@stigmer/runner-slim-linux-x64": "3.2.
|
|
22
|
-
"@stigmer/runner-slim-linux-arm64": "3.2.
|
|
23
|
-
"@stigmer/runner-slim-win32-x64": "3.2.
|
|
19
|
+
"@stigmer/runner-slim-darwin-arm64": "3.2.2",
|
|
20
|
+
"@stigmer/runner-slim-darwin-x64": "3.2.2",
|
|
21
|
+
"@stigmer/runner-slim-linux-x64": "3.2.2",
|
|
22
|
+
"@stigmer/runner-slim-linux-arm64": "3.2.2",
|
|
23
|
+
"@stigmer/runner-slim-win32-x64": "3.2.2"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"stigmer",
|
package/workflow-bundle.js
CHANGED
|
@@ -24214,6 +24214,7 @@ function deepClone(value) {
|
|
|
24214
24214
|
"use strict";
|
|
24215
24215
|
__webpack_require__.r(__webpack_exports__);
|
|
24216
24216
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
24217
|
+
/* harmony export */ TASK_STARTED_INPUT_SUMMARY_PATCH: () => (/* binding */ TASK_STARTED_INPUT_SUMMARY_PATCH),
|
|
24217
24218
|
/* harmony export */ executeDoTasks: () => (/* binding */ executeDoTasks)
|
|
24218
24219
|
/* harmony export */ });
|
|
24219
24220
|
/* harmony import */ var _types_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types.js */ "./dist/workflow-engine/types.js");
|
|
@@ -24253,6 +24254,37 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
24253
24254
|
|
|
24254
24255
|
|
|
24255
24256
|
|
|
24257
|
+
/**
|
|
24258
|
+
* Deterministic-version gate id for the task_started emission reorder
|
|
24259
|
+
* (input resolution moved ahead of the event so it can carry
|
|
24260
|
+
* `input_summary`). Pre-change histories replay the old order — emit
|
|
24261
|
+
* first, resolve second — via `TaskExecutionContext.isPatched`.
|
|
24262
|
+
*/
|
|
24263
|
+
const TASK_STARTED_INPUT_SUMMARY_PATCH = "task-started-input-summary";
|
|
24264
|
+
/**
|
|
24265
|
+
* Truncation budget for event I/O summaries. Deliberately far below the
|
|
24266
|
+
* 64KB snapshot cap: events are the live-stream preview source and the
|
|
24267
|
+
* proto documents them as "truncated to prevent event bloat" — the full
|
|
24268
|
+
* I/O lives on `status.tasks[]`.
|
|
24269
|
+
*/
|
|
24270
|
+
const EVENT_SUMMARY_MAX_BYTES = 8_192;
|
|
24271
|
+
/**
|
|
24272
|
+
* Projects a task I/O value into the shape an event summary Struct can
|
|
24273
|
+
* carry: truncated to the event budget, objects only (mirroring the
|
|
24274
|
+
* snapshot path's `toJsonObject` semantics — proto Struct fields cannot
|
|
24275
|
+
* carry scalars or arrays, and `status.tasks[].input/output` share the
|
|
24276
|
+
* same limitation). Oversize values come back as `truncatePayload`'s
|
|
24277
|
+
* `{_truncated, _preview}` marker object, which IS carried.
|
|
24278
|
+
*/
|
|
24279
|
+
function toEventSummary(value) {
|
|
24280
|
+
if (value === null || value === undefined)
|
|
24281
|
+
return undefined;
|
|
24282
|
+
const truncated = (0,_task_status_accumulator_js__WEBPACK_IMPORTED_MODULE_9__.truncatePayload)(value, EVENT_SUMMARY_MAX_BYTES);
|
|
24283
|
+
if (truncated === null || typeof truncated !== "object" || Array.isArray(truncated)) {
|
|
24284
|
+
return undefined;
|
|
24285
|
+
}
|
|
24286
|
+
return truncated;
|
|
24287
|
+
}
|
|
24256
24288
|
/**
|
|
24257
24289
|
* Returns the task kind string used for event emission. For call:function
|
|
24258
24290
|
* tasks, appends the specific function name (e.g., "call:function:llm")
|
|
@@ -24349,20 +24381,37 @@ async function executeDoTasks(tasks, input, state, doc, evaluateExpressions, ctx
|
|
|
24349
24381
|
const kind = eventTaskKind(entry);
|
|
24350
24382
|
effectiveCtx.taskStatusAccumulator?.taskStarted(entry.key, kind);
|
|
24351
24383
|
const attemptNumber = effectiveCtx.taskStatusAccumulator?.getAttempt(entry.key) ?? 1;
|
|
24352
|
-
|
|
24384
|
+
const emitTaskStarted = async (inputSummary) => {
|
|
24385
|
+
if (!effectiveCtx.emitEvents)
|
|
24386
|
+
return;
|
|
24353
24387
|
await effectiveCtx.emitEvents([{
|
|
24354
24388
|
type: "task_started",
|
|
24355
24389
|
taskName: entry.key,
|
|
24356
24390
|
occurredAt: new Date().toISOString(),
|
|
24357
24391
|
taskKind: kind,
|
|
24358
24392
|
attemptNumber,
|
|
24393
|
+
inputSummary,
|
|
24359
24394
|
}]);
|
|
24360
|
-
}
|
|
24395
|
+
};
|
|
24396
|
+
// Emission-order gate: carrying `input_summary` on task_started
|
|
24397
|
+
// requires resolving the input BEFORE emitting, which reorders two
|
|
24398
|
+
// local-activity commands — a non-deterministic change for in-flight
|
|
24399
|
+
// histories (a gated or waiting task can be parked across a deploy).
|
|
24400
|
+
// Pre-change histories replay the old emit-then-resolve order.
|
|
24401
|
+
const emitStartedAfterResolve = effectiveCtx.isPatched?.(TASK_STARTED_INPUT_SUMMARY_PATCH) ?? true;
|
|
24402
|
+
if (!emitStartedAfterResolve) {
|
|
24403
|
+
await emitTaskStarted();
|
|
24404
|
+
}
|
|
24405
|
+
let startedEmitted = !emitStartedAfterResolve;
|
|
24361
24406
|
const taskStartMs = Date.now();
|
|
24362
24407
|
let taskOutput;
|
|
24363
24408
|
try {
|
|
24364
24409
|
const effectiveInput = await resolveTaskInput(entry, input, state, effectiveCtx);
|
|
24365
24410
|
effectiveCtx.taskStatusAccumulator?.taskStartedWithInput(entry.key, kind, (0,_task_status_accumulator_js__WEBPACK_IMPORTED_MODULE_9__.truncatePayload)(effectiveInput));
|
|
24411
|
+
if (emitStartedAfterResolve) {
|
|
24412
|
+
await emitTaskStarted(toEventSummary(effectiveInput));
|
|
24413
|
+
startedEmitted = true;
|
|
24414
|
+
}
|
|
24366
24415
|
taskOutput = await runSingleTask(entry, effectiveInput, state, doc, effectiveCtx);
|
|
24367
24416
|
}
|
|
24368
24417
|
catch (taskErr) {
|
|
@@ -24378,6 +24427,12 @@ async function executeDoTasks(tasks, input, state, doc, evaluateExpressions, ctx
|
|
|
24378
24427
|
});
|
|
24379
24428
|
}
|
|
24380
24429
|
if (effectiveCtx.emitEvents) {
|
|
24430
|
+
// Input resolution failed before the reordered task_started could
|
|
24431
|
+
// fire — emit it now so consumers always see the started→failed pair.
|
|
24432
|
+
if (!startedEmitted) {
|
|
24433
|
+
await emitTaskStarted();
|
|
24434
|
+
startedEmitted = true;
|
|
24435
|
+
}
|
|
24381
24436
|
await effectiveCtx.emitEvents([{
|
|
24382
24437
|
type: "task_failed",
|
|
24383
24438
|
taskName: entry.key,
|
|
@@ -24419,6 +24474,10 @@ async function executeDoTasks(tasks, input, state, doc, evaluateExpressions, ctx
|
|
|
24419
24474
|
durationMs: taskDurationMs,
|
|
24420
24475
|
costMicros: costInfo.costMicros,
|
|
24421
24476
|
tokensUsed: costInfo.inputTokens + costInfo.outputTokens,
|
|
24477
|
+
// The live-stream preview source for task cards: post-promotion
|
|
24478
|
+
// output (the artifact-promoted form is what downstream sees),
|
|
24479
|
+
// truncated to the event budget. Full output rides the snapshot.
|
|
24480
|
+
outputSummary: toEventSummary(promotedOutput),
|
|
24422
24481
|
}];
|
|
24423
24482
|
for (const evt of promotionEvents) {
|
|
24424
24483
|
events.push(evt);
|
|
@@ -26217,6 +26276,69 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26217
26276
|
* Mirrors Go's custom call function dispatch in `task_builder.go`.
|
|
26218
26277
|
*/
|
|
26219
26278
|
|
|
26279
|
+
/**
|
|
26280
|
+
* Detaches deferred-code fields from a call-function config before
|
|
26281
|
+
* expression resolution and returns a restorer that puts the originals
|
|
26282
|
+
* back afterwards.
|
|
26283
|
+
*
|
|
26284
|
+
* Some config fields carry jq CODE that the activity evaluates later
|
|
26285
|
+
* against its own input — not data to interpolate at config time:
|
|
26286
|
+
*
|
|
26287
|
+
* - `transform.expression` — evaluated by `transformAction` against the
|
|
26288
|
+
* transform's `input`.
|
|
26289
|
+
* - `validate.rules[].expression` — evaluated by `validateAction` per
|
|
26290
|
+
* rule against the validated data.
|
|
26291
|
+
*
|
|
26292
|
+
* Without the detach, a `${ }`-wrapped predicate is pre-evaluated here
|
|
26293
|
+
* against the WRONG input and its non-string RESULT is substituted back
|
|
26294
|
+
* into the config; the activity then tries to evaluate that result as jq
|
|
26295
|
+
* (the `expr.includes is not a function` crash class). All other fields
|
|
26296
|
+
* — including `rules[].message` and the llm/eval prompt fields — are
|
|
26297
|
+
* data and continue to interpolate normally. The original config object
|
|
26298
|
+
* is never mutated (shared across retries).
|
|
26299
|
+
*/
|
|
26300
|
+
function detachDeferredCode(callType, config) {
|
|
26301
|
+
if (callType === "transform" && "expression" in config) {
|
|
26302
|
+
const { expression, ...rest } = config;
|
|
26303
|
+
return {
|
|
26304
|
+
config: rest,
|
|
26305
|
+
restore: (resolved) => {
|
|
26306
|
+
resolved.expression = expression;
|
|
26307
|
+
},
|
|
26308
|
+
};
|
|
26309
|
+
}
|
|
26310
|
+
if (callType === "validate" && Array.isArray(config.rules)) {
|
|
26311
|
+
const originalRules = config.rules;
|
|
26312
|
+
const strippedRules = originalRules.map((rule) => {
|
|
26313
|
+
if (isPlainObject(rule) && "expression" in rule) {
|
|
26314
|
+
const { expression: _deferred, ...rest } = rule;
|
|
26315
|
+
return rest;
|
|
26316
|
+
}
|
|
26317
|
+
return rule;
|
|
26318
|
+
});
|
|
26319
|
+
return {
|
|
26320
|
+
config: { ...config, rules: strippedRules },
|
|
26321
|
+
restore: (resolved) => {
|
|
26322
|
+
const resolvedRules = resolved.rules;
|
|
26323
|
+
if (!Array.isArray(resolvedRules))
|
|
26324
|
+
return;
|
|
26325
|
+
for (let i = 0; i < resolvedRules.length; i++) {
|
|
26326
|
+
const original = originalRules[i];
|
|
26327
|
+
const target = resolvedRules[i];
|
|
26328
|
+
if (isPlainObject(original) &&
|
|
26329
|
+
isPlainObject(target) &&
|
|
26330
|
+
"expression" in original) {
|
|
26331
|
+
target.expression = original.expression;
|
|
26332
|
+
}
|
|
26333
|
+
}
|
|
26334
|
+
},
|
|
26335
|
+
};
|
|
26336
|
+
}
|
|
26337
|
+
return { config, restore: () => { } };
|
|
26338
|
+
}
|
|
26339
|
+
function isPlainObject(value) {
|
|
26340
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26341
|
+
}
|
|
26220
26342
|
/**
|
|
26221
26343
|
* Normalizes the raw LlmCallResult from the activity into the documented
|
|
26222
26344
|
* task output contract: { text, structured, model, usage }.
|
|
@@ -26248,8 +26370,12 @@ class CallFunctionTaskBuilder {
|
|
|
26248
26370
|
build() {
|
|
26249
26371
|
return async (input, state, ctx) => {
|
|
26250
26372
|
const withConfig = this.taskDef.with ?? {};
|
|
26251
|
-
const resolved = await (0,_resolve_js__WEBPACK_IMPORTED_MODULE_0__.resolveConfigExpressions)(withConfig, input, state, ctx.evaluateExpressions);
|
|
26252
26373
|
const callType = this.taskDef.call;
|
|
26374
|
+
// Deferred-code fields (transform/validate expressions) must reach
|
|
26375
|
+
// the activity as unresolved jq strings — see detachDeferredCode.
|
|
26376
|
+
const deferred = detachDeferredCode(callType, withConfig);
|
|
26377
|
+
const resolved = await (0,_resolve_js__WEBPACK_IMPORTED_MODULE_0__.resolveConfigExpressions)(deferred.config, input, state, ctx.evaluateExpressions);
|
|
26378
|
+
deferred.restore(resolved);
|
|
26253
26379
|
if ((callType === "transform" || callType === "validate") &&
|
|
26254
26380
|
!("input" in resolved) || resolved.input === undefined) {
|
|
26255
26381
|
resolved.input = input;
|
|
@@ -28371,6 +28497,10 @@ async function runWorkflowEngine(input, options) {
|
|
|
28371
28497
|
checkPause: options?.checkPause,
|
|
28372
28498
|
emitEvents,
|
|
28373
28499
|
taskStatusAccumulator,
|
|
28500
|
+
// Deterministic version gate for engine command-order changes (the
|
|
28501
|
+
// kernel never imports Temporal APIs — it receives patched() as an
|
|
28502
|
+
// opaque callback, like every other capability on this context).
|
|
28503
|
+
isPatched: (changeId) => (0,_temporalio_workflow__WEBPACK_IMPORTED_MODULE_0__.patched)(changeId),
|
|
28374
28504
|
sleep: async (durationMs) => {
|
|
28375
28505
|
try {
|
|
28376
28506
|
await (0,_temporalio_workflow__WEBPACK_IMPORTED_MODULE_0__.sleep)(durationMs);
|