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
2 changes: 2 additions & 0 deletions crates/agent-gui/src/lib/kbrain/historyMigration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
type HistoryMigrationFailureKind,
type HistoryMigrationFailureRecord,
knownDeterministicFailure,
LEGACY_IMPORT_MAX_BODY_BYTES,
mergeHistoryMigrationFailures,
readHistoryMigrationFailures,
writeHistoryMigrationFailures,
Expand Down Expand Up @@ -662,6 +663,7 @@ export async function migrateLegacyHistoryPage(
fingerprint: sourceFingerprint,
kind,
bytes: bodyBytes,
...(kind === "too_large" ? { limitBytes: LEGACY_IMPORT_MAX_BODY_BYTES } : {}),
message,
failedAt: Date.now(),
});
Expand Down
11 changes: 10 additions & 1 deletion crates/agent-gui/src/lib/kbrain/historyMigrationFailures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export type HistoryMigrationFailureRecord = {
kind: HistoryMigrationFailureKind;
/** Serialized request body size when known. */
bytes?: number;
/** For too_large: the import cap the failure was recorded under. */
limitBytes?: number;
message: string;
failedAt: number;
};
Expand Down Expand Up @@ -54,6 +56,12 @@ export function classifyHistoryMigrationFailure(input: {
return "transient";
}

/**
* Import cap of the bundled K-brain (maxLegacyHistoryBodyBytes). Size failures recorded
* under an older, smaller cap are retried once at startup after the backend upgrade.
*/
export const LEGACY_IMPORT_MAX_BODY_BYTES = 512 << 20;

/** Failures that will fail identically until the conversation or K-brain changes. */
export function isDeterministicHistoryMigrationFailure(kind: HistoryMigrationFailureKind) {
return kind !== "transient";
Expand Down Expand Up @@ -118,7 +126,8 @@ export function knownDeterministicFailure(
(record) =>
record.sourceId === sourceId &&
record.fingerprint === fingerprint &&
isDeterministicHistoryMigrationFailure(record.kind),
isDeterministicHistoryMigrationFailure(record.kind) &&
(record.kind !== "too_large" || record.limitBytes === LEGACY_IMPORT_MAX_BODY_BYTES),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,56 @@ test("a partial checkpoint result is cached; startup stops re-uploading it, manu
runtime.clearKBrainRuntimeConnection();
}
});

test("size failures recorded under the old 64 MiB cap are retried once after the upgrade", async () => {
const storage = memoryStorage();
globalThis.localStorage = storage;
runtime.setKBrainRuntimeConnection({
baseUrl: "http://migration-cap-upgrade.test",
token: "",
protocolVersion: "kbrain.agent.v1",
});
const scope = loader.loadModule("src/lib/kbrain/mapping.ts").kBrainStorageScope();
const source = page("old-cap");
let posts = 0;
let accept = false;
const fetch = async (_url, init) => {
if (init.method !== "POST") return new Response("{}", { status: 404 });
posts++;
if (!accept) {
return new Response(JSON.stringify({ error: "request body exceeds 512 MiB limit" }), {
status: 413,
});
}
return new Response(
JSON.stringify({
source_id: "old-cap",
backend_id: "old-cap",
status: "imported",
checkpoint: "not_found",
fingerprint: "fp",
}),
{ status: 200 },
);
};
try {
await migration.migrateLegacyHistoryPage(source, { fetch });
const [recorded] = failures.readHistoryMigrationFailures(scope, storage);
assert.equal(recorded.limitBytes, failures.LEGACY_IMPORT_MAX_BODY_BYTES);

// Under the current cap the record suppresses startup re-uploads.
await migration.migrateLegacyHistoryPage(source, { fetch });
assert.equal(posts, 1);

// A record from an older release has no cap marker: startup retries it.
const { limitBytes: _limit, ...legacyRecord } = recorded;
failures.writeHistoryMigrationFailures(scope, [legacyRecord], storage);
accept = true;
const retried = await migration.migrateLegacyHistoryPage(source, { fetch });
assert.equal(posts, 2);
assert.deepEqual(retried.failures, []);
assert.equal(failures.readHistoryMigrationFailures(scope, storage).length, 0);
} finally {
runtime.clearKBrainRuntimeConnection();
}
});
44 changes: 22 additions & 22 deletions scripts/release/kbrain.lock.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"repository": "https://github.com/Stack-Cairn/K-brain",
"sourceRevision": "068a8b0d614955c83f8d8184c8cba36adc1a2f38",
"sourceRevision": "b143a82738a80112acd47bd001e6b5d311a13125",
"protocol": "kbrain.agent.v1",
"requiredBackendFlags": [
"-parent-stdio",
Expand Down Expand Up @@ -46,65 +46,65 @@
},
"downloads": {
"aarch64-apple-darwin": {
"sourceRevision": "068a8b0d614955c83f8d8184c8cba36adc1a2f38",
"sourceRevision": "b143a82738a80112acd47bd001e6b5d311a13125",
"assets": {
"backend": "k-brain-darwin-arm64",
"computer": "k-brain-computer-darwin-arm64"
},
"sha256": {
"backend": "a30f26dad1e4da48822fc81bb12f35890dba14b10f7f9c5ea6cd9e0c27681fb0",
"computer": "e340501cd7d8424a122875fa42ce1d55645ec2cd2a98bcfa74cec70a7f1e6f9f"
"backend": "09d8543557cfbc94f48e77a288dd8bbd6156ee5475ce07b92c2acb1eaf470a79",
"computer": "5b3d6dfaafe98996369bda314d98af0325ddea352b1d42fdd4c8b9659f8b6ba6"
},
"urls": {
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-darwin-arm64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-computer-darwin-arm64"
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-darwin-arm64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-computer-darwin-arm64"
}
},
"x86_64-apple-darwin": {
"sourceRevision": "068a8b0d614955c83f8d8184c8cba36adc1a2f38",
"sourceRevision": "b143a82738a80112acd47bd001e6b5d311a13125",
"assets": {
"backend": "k-brain-darwin-x64",
"computer": "k-brain-computer-darwin-x64"
},
"sha256": {
"backend": "e9fca91e21a0f58b8be59f818802e4e24b58d761e6c2f436ffde06f97d3e357e",
"computer": "b36a3835bcb191ed940d04456774306e7cb3eaec159f43a8bdfbcd99277cb93e"
"backend": "0f6b507b50ca66c96dca42ee97d70ef2feb8ff707751c2199ea319cd850f0a1e",
"computer": "fb12a675a8f907455b64096a16533fd7e11fb49a03a800ee8f8c06b1e6758004"
},
"urls": {
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-darwin-x64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-computer-darwin-x64"
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-darwin-x64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-computer-darwin-x64"
}
},
"x86_64-unknown-linux-gnu": {
"sourceRevision": "068a8b0d614955c83f8d8184c8cba36adc1a2f38",
"sourceRevision": "b143a82738a80112acd47bd001e6b5d311a13125",
"assets": {
"backend": "k-brain-linux-x64",
"computer": "k-brain-computer-linux-x64"
},
"sha256": {
"backend": "e896bf3b9ce1ab2d873d04e579fb610933cee18cb91471f7f6e36c822e23df58",
"computer": "b7cdbc27f3b51378fbdb4a675933e4d78a9397daac4028e2c9ee9b4d852500cf"
"backend": "53b965ce9383849cb0df5c87fed922b5f265a8de13f9e252b77f25c2d51152d4",
"computer": "dea009bb25a24b85769f6f1bf244035a9db62295e7812861d8fe02e42c42660d"
},
"urls": {
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-linux-x64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-computer-linux-x64"
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-linux-x64",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-computer-linux-x64"
}
},
"x86_64-pc-windows-msvc": {
"sourceRevision": "068a8b0d614955c83f8d8184c8cba36adc1a2f38",
"sourceRevision": "b143a82738a80112acd47bd001e6b5d311a13125",
"assets": {
"backend": "k-brain-windows-x64.exe",
"computer": "k-brain-computer-windows-x64.exe"
},
"sha256": {
"backend": "3b717559a4ebc98838e4896261a5534de2881d4f6f5e2855acfbd84b37742df2",
"computer": "dcba334ce421657a26803b953518eafcbd6e978663f67922182d8bbbfb0e3edb"
"backend": "a76949d1fb168851e1901cfdca080169e86b5a7f920329b9fca9b68d3ffbaece",
"computer": "5b4c502197459613b5a135dc844a0f1d63008b2d925aa0b0e264f94fb735d0bc"
},
"urls": {
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-windows-x64.exe",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.10/k-brain-computer-windows-x64.exe"
"backend": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-windows-x64.exe",
"computer": "https://github.com/Stack-Cairn/K-brain/releases/download/v0.107.11/k-brain-computer-windows-x64.exe"
}
}
},
"releaseTag": "v0.107.10"
"releaseTag": "v0.107.11"
}
Loading