Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 25 additions & 30 deletions VENDORED.md

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/CHAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ it — one switch feeding both the wake and the relaunch path. The
workbench itself has no host run and no occurrences to name; only invited
agents deploy as sections.

`onBodyFailure: "continue"` — authored in the section shape itself — is
`onBodyFailure: "tolerate"` — authored in the section shape itself — is
the failure edge: a turn that ends `failed` records the failed occurrence
and leaves the section subscribed, so one bad turn kills neither the agent
nor the room. The runtime names an occurrence's child run `turn__<n>`,
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@
"@intx/agent": "workspace:*",
"@intx/authz": "0.3.0",
"@intx/crypto": "0.3.0",
"@intx/db": "0.3.0",
"@intx/db": "workspace:*",
"@intx/harness": "0.3.0",
"@intx/hub-agent": "0.3.0",
"@intx/hub-api": "0.3.0",
"@intx/hub-api": "workspace:*",
"@intx/hub-common": "0.3.0",
"@intx/hub-sessions": "0.3.0",
"@intx/hub-sessions": "workspace:*",
"@intx/inference": "workspace:*",
"@intx/inference-catalog": "0.3.0",
"@intx/log": "0.3.0",
Expand All @@ -107,9 +107,9 @@
"@intx/storage-isogit": "0.3.0",
"@intx/tool-packaging": "0.3.0",
"@intx/types": "workspace:*",
"@intx/workflow": "0.3.0",
"@intx/workflow-deploy": "0.3.0",
"@intx/workflow-host": "0.3.0",
"@intx/workflow": "workspace:*",
"@intx/workflow-deploy": "workspace:*",
"@intx/workflow-host": "workspace:*",
"better-auth": "1.6.29",
"hono": "4.13.3",
"@intx/mailbox": "workspace:*"
Expand Down
4 changes: 2 additions & 2 deletions packages/agent-runtime/src/definition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe("buildAgentRuntimeWorkflow — section mode", () => {
const section =
buildAgentRuntimeWorkflow(sectionConfig).steps[AGENT_RUNTIME_SECTION_ID];

expect(section).toMatchObject({ onBodyFailure: "continue" });
expect(section).toMatchObject({ onBodyFailure: "tolerate" });
});

test("the section's failure policy survives the live→inert projection", () => {
Expand All @@ -162,7 +162,7 @@ describe("buildAgentRuntimeWorkflow — section mode", () => {

expect(section).toMatchObject({
kind: "onTrigger",
onBodyFailure: "continue",
onBodyFailure: "tolerate",
});
});

Expand Down
8 changes: 4 additions & 4 deletions packages/agent-runtime/src/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
// whose body is one agent step, so every message becomes an occurrence
// with its own child run id and event log.
//
// Section mode authors `onBodyFailure: "continue"`, the failure edge
// Section mode authors `onBodyFailure: "tolerate"`, the failure edge
// that keeps a section subscribed after a failed turn: a conversation
// whose agent threw on one message must still answer the next, and the
// primitive's default (`"end"`) retires the whole run instead. The
// vendored surface carries the field through the live→inert projection,
// primitive's default (`"end"`) retires the whole run instead.
// `@intx/workflow` carries the field through the live→inert projection,
// so the policy reaches the hub's frozen projection rather than being
// silently dropped before deploy.
import { buildSingleStepAgentDefinition } from "@intx/workflow-deploy";
Expand Down Expand Up @@ -106,7 +106,7 @@ function buildSectionWorkflow(
[AGENT_RUNTIME_SECTION_ID]: onTrigger({
on: { type: "mail" as const, to: config.triggerAddress },
body,
onBodyFailure: "continue",
onBodyFailure: "tolerate",
}),
};
return config.credentialBindings.length > 0
Expand Down
2 changes: 1 addition & 1 deletion packages/chat/src/standalone-launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { CHAT_TURN_TIMEOUT_MS } from "./turn-claims";
* That child id is what a reply's `run_id` carries, which is the whole
* reason a reply is traceable.
*
* `onBodyFailure: "continue"` — authored in the section shape itself
* `onBodyFailure: "tolerate"` — authored in the section shape itself
* (`@corbits/agent-runtime`) — is the failure edge: a turn that throws
* records a failed occurrence and leaves the section subscribed, so one
* bad turn kills neither the agent nor the conversation.
Expand Down
4 changes: 2 additions & 2 deletions packages/chat/test/platform-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1097,12 +1097,12 @@ describe("createHubChatPlatform", () => {

// CL-6329: a room agent deploys as an `onTrigger` section, so every
// message it is asked to answer is an occurrence with its own child
// run — and `onBodyFailure: "continue"` keeps the section subscribed
// run — and `onBodyFailure: "tolerate"` keeps the section subscribed
// after a turn that threw.
const rendered = deployedDefinition(assetService.populatedTrees);
expect(Object.keys(rendered.steps)).toEqual([AGENT_RUNTIME_SECTION_ID]);
expect(rendered.steps[AGENT_RUNTIME_SECTION_ID]).toMatchObject({
onBodyFailure: "continue",
onBodyFailure: "tolerate",
});
});

Expand Down
2 changes: 1 addition & 1 deletion packages/folded-runs/test/definition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function sectionProjection(overrides: Partial<Record<string, unknown>> = {}) {
kind: "onTrigger",
id: "turn",
on: { type: "mail", to: "agent@example.com" },
onBodyFailure: "continue",
onBodyFailure: "tolerate",
body: {
inline: {
id: "wfd_2_body",
Expand Down
8 changes: 4 additions & 4 deletions scripts/checks/kill-dates.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
# package's VENDORED-FROM delta line in the same change.
apps/sidecar | sawyer | 2026-09-19
vendor/intx/agent | sawyer | 2026-10-26 | d0d56d9f452b78f4b541ad8f4e89f975e8069446bb98f2c8097b90de4b020243
vendor/intx/db | sawyer | 2026-09-19 | 3ab08b9122f3ab84d60e1f2d5b7af88c3eb673f9120ce6dedf3d2600d4a6cad4
vendor/intx/db | sawyer | 2026-09-19 | 0a4cdb9a8a6ff19d5d4713cbc4f5cc9257aad839b1fa393b2026e6d5afd828b9
vendor/intx/hub-api | sawyer | 2026-09-19 | f93a383cb5d6acdf50a461b43e4c8991dbdf7e13d34a4e5598e556eaee66308b
vendor/intx/hub-sessions | sawyer | 2026-09-19 | df5f1d275e197668851c53f58c51182d8bc455f3585e2ed65784d3687a856001
vendor/intx/hub-sessions | sawyer | 2026-09-19 | e3344253ed6f2b0998599f9f8712d4e9b0757895b31a3e7df6a245c2bb76af3c
vendor/intx/inference | sawyer | 2026-10-26 | 77fec29b078e8d03e686747c70e6b62ac1fd1434db0fb2c1e12e84b6dc71465f
vendor/intx/mail-memory | sawyer | 2026-10-26 | 9f3601a7fb22e2d1c63daa976f3afccbd79af2187c155a0080c0d60c82450b92
vendor/intx/mailbox | sawyer | 2026-10-26 | d36d7ffcc32018571276e4922a8c2714b7ee0bb5deb80b01e73859245975d4c6
vendor/intx/mime | sawyer | 2026-10-26 | d02e5f8f1429eac7c27d3a37eec31111f8a1053c91fbfae77ac58a0d63c823ed
vendor/intx/types | sawyer | 2026-10-26 | ec1de14b859007b4db137da1533d4ce79d11024ad69c8b36938017319d6d8e86
vendor/intx/workflow | sawyer | 2026-09-19 | 34628e7bbd0587f131a07e3a206141983881106963a20ab607e68aeed1135593
vendor/intx/workflow-deploy | sawyer | 2026-09-19 | 95711adf282180852b0daec1cac39d00a4dc24aff15f9a515e07eb3d2ca749f9
vendor/intx/workflow | sawyer | 2026-09-19 | 4b51b9bd6a124cfaa0c916e2b26c04ac9170618bb092f0c8e1c312263fc84fdf
vendor/intx/workflow-deploy | sawyer | 2026-10-26 | 960a2ae408223649fe8be0e3b9d63f2b0cca25259bc0ae06761bca521bb738e5
vendor/intx/workflow-host | sawyer | 2026-09-19 | 48ae3e34c6f14b99a3a940ede98b119e52dfe7410a86f644d3b78cf6e7d44f4d

packages/folded-runs | sawyer | 2026-11-01
Expand Down
4 changes: 2 additions & 2 deletions scripts/e2e/cl-6324-launch-proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ async function main(): Promise<void> {
);
expectStatus("send the mid-turn message", sent, 201);
// The section deployment takes the same kill mid-occurrence, so the
// restart has to prove `onBodyFailure: "continue"` too: a section
// restart has to prove `onBodyFailure: "tolerate"` too: a section
// that retired on the dead body would never answer again.
const sectionSent = await api(
hub.baseUrl,
Expand Down Expand Up @@ -1221,7 +1221,7 @@ async function main(): Promise<void> {

// The section deployment rode the same kill. Boot restore replays its
// pin from the sidecar data dir exactly as it does the folded run's,
// and `onBodyFailure: "continue"` is what keeps the section subscribed
// and `onBodyFailure: "tolerate"` is what keeps the section subscribed
// when the killed occurrence died mid-body: a section that retired on
// that failure would never produce a second occurrence at all.
//
Expand Down
2 changes: 1 addition & 1 deletion scripts/e2e/cl-6329-turn-swap-proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// 2. Three rapid messages serialize into ordered turns rather than
// racing: occurrences 0,1,2 in arrival order.
// 3. A turn killed mid-occurrence leaves BOTH the room and the section
// alive: `onBodyFailure: "continue"` keeps the section subscribed,
// alive: `onBodyFailure: "tolerate"` keeps the section subscribed,
// the failed turn is visible rather than silent, and the next
// message is still answered.
//
Expand Down
2 changes: 1 addition & 1 deletion vendor/intx/db/VENDORED-FROM
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Source: https://github.com/faremeter/interchange (packages/db)
Commit: a8bc06ae38661c5e0ed91ded8559bf09f502213d (origin/main, 2026-08-27)
License: LGPL-2.1-only (see vendor/intx/LICENSE)
Local modifications: exports map repointed from the upstream intx-src condition to direct TypeScript source resolution (types/default -> ./src/...); dist references removed. CL-6324: workflow_definition_version gains a wire_projection jsonb column (migration 0086_workflow_definition_version_wire_projection.sql -- renumbered from 0085 when upstream a8bc06ae took that slot for 0085_add_approval_run_idx.sql, and from 0084 before that; the journal keeps our original `when` values, which still sort after upstream's 0085), schema/workflow-definitions.ts declares it, and workflow-definition-store.ts adds loadFrozenWireProjection (exported from src/index.ts) to read it back beside the approved wire hash. CL-6452: workflow_definition gains an origin column (migration 0087_workflow_definition_origin.sql, renumbered from 0086; declared in schema/workflow-definitions.ts) marking the per-run record a folded run's deploy mints for itself, so launch and refresh resolve the hub-authored definition instead of the newest same-named row. Workbench applies these files by sorted filename through scripts/db-setup.ts (replay-from-scratch with a filename ledger); the drizzle journal exists for drizzle-kit only.
Local modifications: exports map repointed from the upstream intx-src condition to direct TypeScript source resolution (types/default -> ./src/...); dist references removed. CL-6324: workflow_definition_version gains a wire_projection jsonb column (migration 0086_workflow_definition_version_wire_projection.sql -- renumbered from 0085 when upstream a8bc06ae took that slot for 0085_add_approval_run_idx.sql, and from 0084 before that; the journal keeps our original `when` values, which still sort after upstream's 0085), schema/workflow-definitions.ts declares it, and workflow-definition-store.ts adds loadFrozenWireProjection (exported from src/index.ts) to read it back beside the approved wire hash. CL-6452: workflow_definition gains an origin column (migration 0087_workflow_definition_origin.sql, renumbered from 0086; declared in schema/workflow-definitions.ts) marking the per-run record a folded run's deploy mints for itself, so launch and refresh resolve the hub-authored definition instead of the newest same-named row. Migration 0088_workflow_definition_version_tolerate_body_failure.sql rewrites the retired `onBodyFailure: "continue"` literal (our pre-a8bc06ae vendored @intx/workflow delta) to upstream b977ade6's `"tolerate"` inside stored wire projections. Workbench applies these files by sorted filename through scripts/db-setup.ts (replay-from-scratch with a filename ledger); the drizzle journal exists for drizzle-kit only.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- WORKBENCH DELTA (see VENDORED.md): upstream b977ade6 named the opt-in
-- onTrigger body-failure policy "tolerate"; workbench's earlier vendored
-- delta had called the same policy "continue". A frozen inert projection
-- is stored verbatim, so rewrite the retired literal in place. Postgres
-- renders jsonb text canonically (`"key": "value"`), so the textual
-- replace matches exactly this key/value pair at any nesting depth.
UPDATE "workflow_definition_version"
SET "wire_projection" = replace("wire_projection"::text, '"onBodyFailure": "continue"', '"onBodyFailure": "tolerate"')::jsonb
WHERE "wire_projection"::text LIKE '%"onBodyFailure": "continue"%';
7 changes: 7 additions & 0 deletions vendor/intx/db/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,13 @@
"when": 1787810000000,
"tag": "0087_workflow_definition_origin",
"breakpoints": true
},
{
"idx": 88,
"version": "7",
"when": 1787900000000,
"tag": "0088_workflow_definition_version_tolerate_body_failure",
"breakpoints": true
}
]
}
12 changes: 4 additions & 8 deletions vendor/intx/db/src/migrations-journal.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
// WORKBENCH DELTA (see VENDORED.md): our two migrations ride behind
// upstream's in the drizzle-kit journal. Renumbering them at each re-pin
// is a hand edit, so pin the invariants drizzle-kit relies on: one journal
// entry per SQL file, in filename order, with non-decreasing `when`.
// entry per SQL file, in filename order. (`idx`/`when` are not asserted:
// upstream's own journal has an idx gap and non-monotonic timestamps.)
import { expect, test } from "bun:test";
import { readdirSync, readFileSync } from "node:fs";
import path from "node:path";

const MIGRATIONS_DIR = path.resolve(import.meta.dir, "..", "migrations");

test("every migration file has a journal entry in filename order with non-decreasing `when`", () => {
test("every migration file has a journal entry in filename order", () => {
const files = readdirSync(MIGRATIONS_DIR)
.filter((file) => file.endsWith(".sql"))
.sort()
.map((file) => file.slice(0, -".sql".length));
const journal = JSON.parse(
readFileSync(path.join(MIGRATIONS_DIR, "meta", "_journal.json"), "utf8"),
) as { entries: { idx: number; when: number; tag: string }[] };
) as { entries: { tag: string }[] };

expect(journal.entries.map((entry) => entry.tag)).toEqual(files);
journal.entries.forEach((entry, i) => {
expect(entry.idx).toBe(i);
expect(entry.tag.startsWith(String(i).padStart(4, "0"))).toBe(true);
if (i > 0) expect(entry.when).toBeGreaterThanOrEqual(journal.entries[i - 1]!.when);
});
});
77 changes: 77 additions & 0 deletions vendor/intx/db/src/tolerate-migration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// WORKBENCH DELTA (see VENDORED.md): migration 0088 rewrites the retired
// `onBodyFailure: "continue"` literal to upstream's `"tolerate"` inside
// frozen wire projections. Exercised against a scratch table carrying the
// column the statement touches. DB-gated: skipped when DATABASE_URL is unset.
import { afterAll, describe, expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { userInfo } from "node:os";
import path from "node:path";
import postgres from "postgres";

const databaseUrl = process.env["DATABASE_URL"] ?? "";
const describeIfDb = databaseUrl === "" ? describe.skip : describe;

const MIGRATION = path.resolve(
import.meta.dir,
"..",
"migrations",
"0088_workflow_definition_version_tolerate_body_failure.sql",
);

describeIfDb("0088 rewrites onBodyFailure continue -> tolerate", () => {
const schema = `tolerate_test_${Date.now().toString(36)}`;
const parsed = new URL(databaseUrl);
const sql = postgres({
host: parsed.hostname,
port: Number(parsed.port || 5432),
user: decodeURIComponent(parsed.username) || userInfo().username,
password: decodeURIComponent(parsed.password),
database: parsed.pathname.slice(1),
max: 1,
onnotice: () => undefined,
connection: { search_path: `"${schema}"` },
});
afterAll(async () => {
await sql.unsafe(`DROP SCHEMA IF EXISTS "${schema}" CASCADE`);
await sql.end();
});

test("rewrites the literal at any depth and leaves other rows untouched", async () => {
await sql.unsafe(`CREATE SCHEMA "${schema}"`);
await sql.unsafe(
`CREATE TABLE "workflow_definition_version" (id text PRIMARY KEY, wire_projection jsonb)`,
);
const nested = {
steps: {
section: {
kind: "onTrigger",
onBodyFailure: "continue",
body: {
inline: {
steps: { inner: { kind: "onTrigger", onBodyFailure: "continue" } },
},
},
},
},
};
const untouched = { steps: { s: { kind: "onTrigger", onBodyFailure: "end" } } };
await sql`INSERT INTO "workflow_definition_version" VALUES
('a', ${sql.json(nested)}), ('b', ${sql.json(untouched)}), ('c', NULL)`;

for (const statement of readFileSync(MIGRATION, "utf8")
.split("--> statement-breakpoint")
.map((s) => s.trim())
.filter((s) => s.length > 0)) {
await sql.unsafe(statement);
}

const rows = await sql<{ id: string; wire_projection: unknown }[]>`
SELECT id, wire_projection FROM "workflow_definition_version" ORDER BY id`;
expect(JSON.stringify(rows[0]!.wire_projection)).not.toContain("continue");
expect(rows[0]!.wire_projection).toEqual(
JSON.parse(JSON.stringify(nested).replaceAll('"continue"', '"tolerate"')),
);
expect(rows[1]!.wire_projection).toEqual(untouched);
expect(rows[2]!.wire_projection).toBeNull();
});
});
2 changes: 1 addition & 1 deletion vendor/intx/hub-sessions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@intx/tool-packaging": "0.3.0",
"@intx/types": "0.3.0",
"@intx/workflow": "workspace:*",
"@intx/workflow-deploy": "workspace:*",
"@intx/workflow-deploy": "0.3.0",
"arktype": "catalog:",
"drizzle-orm": "catalog:",
"isomorphic-git": "catalog:",
Expand Down
Loading
Loading