Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

185 lines
5.8 KiB
TypeScript

/**
* Test fixture run as a child process by the smithers-runtime suite: executes a
* workflow through `runWorkflowWithSmithers` and prints a prefixed result line the
* parent parses. Exercises the real Smithers execution adapter.
*/
import { writeFile } from 'node:fs/promises';
import {
runWorkflowWithSmithers,
type SmithersExecutionPlan,
type SmithersWorkflowRunOptions,
} from '../../src/services/smithers-runtime';
import type { WorkflowDefinition, WorkflowExecution, WorkflowNode } from '../../src/types/index';
const RESULT_PREFIX = 'SMITHERS_RUNTIME_CASE_RESULT ';
type RunNode = SmithersWorkflowRunOptions['runNode'];
type NodeInput = Parameters<RunNode>[1];
interface RunDataEntry {
data: { main: Array<Array<{ json: Record<string, unknown> }>> };
}
function node(name: string, extra: Partial<WorkflowNode> = {}): WorkflowNode {
return { name, type: 'test.node', typeVersion: 1, position: [0, 0], parameters: {}, ...extra };
}
function pendingExecution(workflowId: string): WorkflowExecution {
return {
id: `exec-${workflowId}`,
finished: false,
mode: 'manual',
startedAt: new Date().toISOString(),
workflowId,
status: 'running',
};
}
function run(
id: string,
nodes: WorkflowNode[],
plan: SmithersExecutionPlan,
runNode: RunNode
): Promise<WorkflowExecution> {
const uid = `${id}-${Math.random().toString(36).slice(2, 10)}`;
const workflow: WorkflowDefinition = { id: uid, name: uid, nodes, connections: {} };
return runWorkflowWithSmithers({
workflow,
executionId: `run-${uid}`,
pending: pendingExecution(uid),
mode: 'manual',
triggerData: {},
plan,
runNode,
});
}
async function fanoutCase(): Promise<Record<string, unknown>> {
const calls: string[] = [];
const inputs = new Map<string, NodeInput>();
const nodes = [node('trigger'), node('A'), node('B'), node('C')];
const plan: SmithersExecutionPlan = {
enabledNodes: nodes,
startNodes: ['trigger'],
incoming: {
A: [{ source: 'trigger', sourceOutputIndex: 0, destinationInputIndex: 0 }],
B: [{ source: 'trigger', sourceOutputIndex: 0, destinationInputIndex: 0 }],
C: [
{ source: 'A', sourceOutputIndex: 0, destinationInputIndex: 0 },
{ source: 'B', sourceOutputIndex: 0, destinationInputIndex: 1 },
],
},
};
const result = await run('wf-fanout', nodes, plan, async (n, inputData) => {
calls.push(n.name);
inputs.set(n.name, inputData);
await new Promise((resolve) => setTimeout(resolve, 5));
return [[{ json: { node: n.name } }]];
});
const cInput = inputs.get('C');
return {
status: result.status,
finished: result.finished,
calls: [...calls].sort(),
lastNodeExecuted: result.data?.resultData?.lastNodeExecuted,
cInput0: cInput?.[0]?.[0]?.json,
cInput1: cInput?.[1]?.[0]?.json,
engine: result.data?.resultData?.engine,
};
}
async function retryCase(): Promise<Record<string, unknown>> {
let attempts = 0;
const nodes = [
node('trigger'),
node('R', { retryOnFail: true, maxTries: 3, waitBetweenTries: 1 }),
];
const plan: SmithersExecutionPlan = {
enabledNodes: nodes,
startNodes: ['trigger'],
incoming: { R: [{ source: 'trigger', sourceOutputIndex: 0, destinationInputIndex: 0 }] },
};
const result = await run('wf-retry', nodes, plan, async (n) => {
if (n.name === 'R') {
attempts += 1;
if (attempts < 2) throw new Error('transient');
}
return [[{ json: { node: n.name } }]];
});
return {
attempts,
status: result.status,
retries: result.data?.resultData?.engine?.retries,
};
}
async function continueCase(): Promise<Record<string, unknown>> {
const nodes = [node('trigger'), node('F', { continueOnFail: true })];
const plan: SmithersExecutionPlan = {
enabledNodes: nodes,
startNodes: ['trigger'],
incoming: { F: [{ source: 'trigger', sourceOutputIndex: 0, destinationInputIndex: 0 }] },
};
const result = await run('wf-continue', nodes, plan, async (n) => {
if (n.name === 'F') throw new Error('boom');
return [[{ json: { node: n.name } }]];
});
const fRun = result.data?.resultData?.runData?.F as RunDataEntry[] | undefined;
return {
status: result.status,
errorItem: fRun?.[0]?.data.main[0][0].json.error,
};
}
async function failCase(): Promise<Record<string, unknown>> {
const nodes = [node('trigger'), node('X')];
const plan: SmithersExecutionPlan = {
enabledNodes: nodes,
startNodes: ['trigger'],
incoming: { X: [{ source: 'trigger', sourceOutputIndex: 0, destinationInputIndex: 0 }] },
};
try {
await run('wf-fail', nodes, plan, async (n) => {
if (n.name === 'X') throw new Error('fatal');
return [[{ json: { node: n.name } }]];
});
} catch (error) {
return {
threw: true,
message: error instanceof Error ? error.message : String(error),
};
}
return { threw: false };
}
const cases: Record<string, () => Promise<Record<string, unknown>>> = {
fanout: fanoutCase,
retry: retryCase,
continue: continueCase,
fail: failCase,
};
const caseName = process.argv[2];
const selected = caseName ? cases[caseName] : undefined;
async function writeResult(result: Record<string, unknown>): Promise<void> {
const serialized = JSON.stringify(result);
const outputPath = process.env.SMITHERS_RUNTIME_CASE_OUTPUT;
if (outputPath) await writeFile(outputPath, serialized, 'utf8');
process.stdout.write(`${RESULT_PREFIX}${serialized}\n`);
}
if (!selected) {
process.stderr.write(`Unknown Smithers runtime case: ${caseName ?? '<missing>'}\n`);
process.exitCode = 2;
} else {
try {
const result = await selected();
await writeResult(result);
} catch (error) {
process.stderr.write(error instanceof Error ? (error.stack ?? error.message) : String(error));
process.stderr.write('\n');
process.exitCode = 1;
}
}