From 9981585df9abcd45ff7403565d1fae70a29e97c8 Mon Sep 17 00:00:00 2001 From: ship Date: Thu, 27 Aug 2026 22:59:34 +0800 Subject: [PATCH] =?UTF-8?q?ship=201.4.60=EF=BC=9AArcrun@98b45409740b?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- arcrun-cypher-executor/worker.mjs | 131 ++++++++++++++++++++++++++++-- arcrun-kbdb/worker.mjs | 102 ++++++++++++++--------- manifest.json | 38 ++++----- 4 files changed, 206 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 0fae951..071db79 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Served via jsDelivr; fetched automatically during install — you never need to - `arcrun-wait/` — **arcrun-wait**(首裝) - `daemon/` — 桌面 App(Mac/Windows)安裝檔 -Built from `Arcrun@f87260b1234f` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.59,built 2026-08-27)。 +Built from `Arcrun@98b45409740b` by `installer/scripts/ship.mjs`(arcrun-rag repo,release 1.4.60,built 2026-08-27)。 ⚠️ 這份檔案由出貨管線每次自動重寫(`installer/scripts/render-bundles-readme.mjs`)—— 不要手動改這裡列的零件清單——它是算出來的:公庫=Arcrun 這一版編了什麼, diff --git a/arcrun-cypher-executor/worker.mjs b/arcrun-cypher-executor/worker.mjs index 5181faa..8d5220f 100644 --- a/arcrun-cypher-executor/worker.mjs +++ b/arcrun-cypher-executor/worker.mjs @@ -12978,7 +12978,87 @@ var PORTAL_TEMPLATE_SEEDS = [ // cypher-executor/src/routes/portal.ts init_credentials(); + +// cypher-executor/src/lib/ai-response.ts +function pickChatContent(o) { + const choices = o.choices; + if (!Array.isArray(choices) || choices.length === 0) return void 0; + const first = choices[0]; + if (!first || typeof first !== "object") return void 0; + const msg = first.message; + if (!msg || typeof msg !== "object") return void 0; + const content = msg.content; + return typeof content === "string" && content.length > 0 ? content : void 0; +} +function pickResponseValue(out) { + if (out === null || out === void 0) return void 0; + if (typeof out === "string") return out; + if (typeof out !== "object") return out; + const o = out; + const chat = pickChatContent(o); + if (chat !== void 0) return chat; + if ("response" in o) return o.response; + const result = o.result; + if (result && typeof result === "object") { + const r = result; + const rc = pickChatContent(r); + if (rc !== void 0) return rc; + if ("response" in r) return r.response; + } + return void 0; +} +function normalizeAiText(out) { + const v = pickResponseValue(out); + if (v === null || v === void 0) return { text: "", kind: "empty" }; + if (typeof v === "string") return { text: v.trim(), kind: v.trim() ? "string" : "empty" }; + if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") { + return { text: String(v), kind: "scalar" }; + } + if (typeof v === "object") { + try { + const s = JSON.stringify(v); + if (typeof s !== "string") { + return { text: "", kind: "unrenderable", reason: "JSON.stringify \u56DE undefined" }; + } + return { text: s, kind: "json" }; + } catch (e) { + return { + text: "", + kind: "unrenderable", + reason: e instanceof Error ? e.message : "\u7121\u6CD5\u5E8F\u5217\u5316" + }; + } + } + return { text: "", kind: "unrenderable", reason: `\u672A\u9810\u671F\u7684\u578B\u5225 ${typeof v}` }; +} +function parseExpectShape(raw2, hasPrompt) { + const s = String(raw2 ?? "").trim(); + if (s === "json_object" || s === "text") return s; + return hasPrompt ? "json_object" : "text"; +} +function hasJsonObject(text) { + const start = text.indexOf("{"); + const end = text.lastIndexOf("}"); + if (start < 0 || end <= start) return { ok: false, reason: "\u6574\u6BB5\u56DE\u61C9\u88E1\u627E\u4E0D\u5230 JSON \u7269\u4EF6\uFF08\u6C92\u6709\u6210\u5C0D\u7684\u5927\u62EC\u865F\uFF09" }; + try { + const parsed = JSON.parse(text.slice(start, end + 1)); + if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { + return { ok: false, reason: "\u5927\u62EC\u865F\u88E1\u7684\u5167\u5BB9\u4E0D\u662F JSON \u7269\u4EF6" }; + } + return { ok: true }; + } catch (e) { + return { ok: false, reason: `JSON \u89E3\u6790\u5931\u6557\uFF1A${e instanceof Error ? e.message : "\u672A\u77E5\u932F\u8AA4"}` }; + } +} +function snippetForError(text, max = 120) { + const one = text.replace(/\s+/g, " ").trim(); + if (!one) return "\uFF08\u7A7A\u7684\uFF09"; + return one.length <= max ? one : one.slice(0, max) + "\u2026"; +} + +// cypher-executor/src/routes/portal.ts var portalRouter = new Hono2(); +var EXTRACT_MODEL = "@cf/meta/llama-4-scout-17b-16e-instruct"; var SESSION_PREFIX2 = "portal_sess:"; var LOCKFAIL_PREFIX = "portal_lockfail:"; var LOCK_LIMIT = 5; @@ -13983,6 +14063,7 @@ portalRouter.post( const pageName = String(body?.page_name ?? "").trim(); const srcText = String(body?.text ?? ""); const daemonPrompt = String(body?.prompt ?? "").trim(); + const expectShape = parseExpectShape(body?.expect, Boolean(daemonPrompt)); if (!daemonPrompt && (!pageName || !srcText.trim())) return c.json({ error: "page_name \u8207 text \u5FC5\u586B" }, 400); if (!c.env.AI) { @@ -14003,15 +14084,44 @@ portalRouter.post( \u539F\u7A3F\uFF1A ${srcText}`; try { - const out = await c.env.AI.run("@cf/meta/llama-4-scout-17b-16e-instruct", { + const out = await c.env.AI.run(EXTRACT_MODEL, { messages: [{ role: "user", content: prompt }], max_tokens: daemonPrompt ? 8192 : 2048, - temperature: 0.2 + temperature: 0.2, + // 🔴 Arcrun#134(2026-08-27):呼叫端說它要一個 JSON 物件 ⇒ **就用模型保證得了的方式去要**。 + // 不加這個的實測(youlin 真檔《火星座標_短片劇本_v1》打 6 次):**3 次壞在 + // 模型把字串的收尾引號打成全形 `”`** ⇒ 字串沒收掉 ⇒ 後面那個換行變成 JSON 裡的 + // 裸控制字元 ⇒ daemon 與雲端都解析不了。那是第二顆骰子,和 `[object Object]` + // 不同源但同一種傷害:**同一份檔、同一個請求,成敗看運氣**。 + // `response_format: json_object` 走的是受限解碼,語法由平台保證 ⇒ 骰子拿掉。 + // 只在呼叫端宣告要 JSON 時才加:legacy(要 markdown 卡)那條路一個字都沒動。 + ...expectShape === "json_object" ? { response_format: { type: "json_object" } } : {} + // 🔴 **不准把回傳值宣告成 `{ response?: string }`**。 + // 那個型別斷言正是本票的病根——binding 把純 JSON 回應解析成 JS 物件交回來, + // 而斷言讓編譯器相信它是字串 ⇒ `String(物件)` = '[object Object]' ⇒ 整張卡沒了。 + // 一律 `unknown`,由 normalizeAiText 認形狀(見 lib/ai-response.ts 檔頭實測)。 }); - const raw2 = String(out?.response ?? "").trim(); + const norm = normalizeAiText(out); + if (norm.kind === "unrenderable") { + return c.json({ error: `\u96F2\u7AEF\u8403\u53D6\uFF1AWorkers AI \u7684\u56DE\u61C9\u9084\u539F\u4E0D\u56DE\u6587\u5B57\uFF08${norm.reason ?? "\u672A\u77E5\u539F\u56E0"}\uFF09` }, 502); + } + const raw2 = norm.text; if (!raw2) return c.json({ error: "Workers AI \u6C92\u6709\u56DE\u50B3\u5167\u5BB9" }, 502); if (daemonPrompt) { - return c.json({ success: true, output: raw2 }); + if (expectShape === "json_object") { + const check = hasJsonObject(raw2); + if (!check.ok) { + return c.json( + { + error: `\u96F2\u7AEF\u8403\u53D6\uFF1A\u6A21\u578B\u6C92\u6709\u7167\u5951\u7D04\u56DE JSON \u7269\u4EF6\uFF08${check.reason}\uFF09\u3002\u9019\u4E00\u6BB5\u662F\u5728\u4F60\u7684\u77E5\u8B58\u5EAB\u96F2\u7AEF\u8DD1\u7684\uFF08Workers AI ${EXTRACT_MODEL}\uFF09\uFF0C\u4E0D\u662F\u5728\u4F60\u7684\u96FB\u8166\u4E0A\u3002\u6A21\u578B\u5BE6\u969B\u56DE\u7684\u524D 120 \u5B57\uFF1A${snippetForError(raw2)}`, + code: "ai_output_not_json_object", + output_kind: norm.kind + }, + 502 + ); + } + } + return c.json({ success: true, output: raw2, output_kind: norm.kind }); } const marker = `# ${pageName}`; const idx = raw2.lastIndexOf(marker); @@ -17099,7 +17209,7 @@ async function tripletCensus(env, tenant2) { if (owned !== 0) return { owned, any: null }; return { owned, any: await tripletCount(env, null) }; } -async function fuzzyFindNode(env, tenant2, searchTerm) { +async function fuzzyFindNode(env, tenant2, searchTerm, libraries) { try { const res = await kbdbFetch(env, `/records/by-template/triplet?${ownerQuery(tenant2)}`); if (!res.ok) return null; @@ -17109,6 +17219,8 @@ async function fuzzyFindNode(env, tenant2, searchTerm) { for (const r of body.records) { const v = r?.values; if (!v || typeof v !== "object") continue; + const lib = recordLibrary(v); + if (lib !== null && !canReadLibrary(libraries, lib)) continue; if (typeof v.subject === "string" && v.subject.trim()) nodeNames.add(v.subject.trim()); if (typeof v.object === "string" && v.object.trim()) nodeNames.add(v.object.trim()); } @@ -17170,10 +17282,11 @@ portalDataRouter.get( return c.json({ success: true, entry }); }) ); -async function fetchNeighborsFromKbdb(env, tenant2, node, depth) { +async function fetchNeighborsFromKbdb(env, tenant2, node, depth, libraries) { const qs = new URLSearchParams(); qs.set("depth", String(depth)); qs.set("template", "triplet"); + if (!libraries.includes("*")) qs.set("library", libraries.join(",")); const res = await kbdbFetch(env, `/graph/neighbors/${encodeURIComponent(node)}?${qs.toString()}&${ownerQuery(tenant2)}`); const body = await res.json().catch(() => null); return { ok: res.ok, status: res.status, body }; @@ -17197,16 +17310,16 @@ portalDataRouter.get( let first = null; try { for (const name of tryNames) { - const r = await fetchNeighborsFromKbdb(c.env, tenant2, name, depth); + const r = await fetchNeighborsFromKbdb(c.env, tenant2, name, depth, libraries); if (!first) first = r; if (!r.ok) break; const mapped = mapGraphNeighborsResponse(r.body); if (mapped.count > 0) return c.json(mapped); } if (first?.ok) { - const fallbackName = await fuzzyFindNode(c.env, tenant2, rawName); + const fallbackName = await fuzzyFindNode(c.env, tenant2, rawName, libraries); if (fallbackName && !tryNames.includes(fallbackName)) { - const r = await fetchNeighborsFromKbdb(c.env, tenant2, fallbackName, depth); + const r = await fetchNeighborsFromKbdb(c.env, tenant2, fallbackName, depth, libraries); if (r.ok) { const mapped = mapGraphNeighborsResponse(r.body); if (mapped.count > 0) return c.json(mapped); diff --git a/arcrun-kbdb/worker.mjs b/arcrun-kbdb/worker.mjs index eb2ac5b..aefe7da 100644 --- a/arcrun-kbdb/worker.mjs +++ b/arcrun-kbdb/worker.mjs @@ -2127,6 +2127,11 @@ function libraryOf(expr) { var ENTRY_LIBRARY_EXPR = "json_extract(metadata_json, '$.library')"; var ENTRY_LIBRARY = libraryOf(ENTRY_LIBRARY_EXPR); var ENTRY_UNLABELLED = `(${ENTRY_LIBRARY_EXPR} IS NULL OR ${ENTRY_LIBRARY_EXPR} = '')`; +function parseLibraryList(raw2) { + if (!raw2) return void 0; + const libs = raw2.split(",").map((s) => s.trim()).filter(Boolean); + return libs.length > 0 ? libs : void 0; +} // kbdb/src/actions/entry-crud.ts function uid(prefix) { @@ -3198,11 +3203,7 @@ function fireAndForget(c, p) { else void p.catch(() => { }); } -function parseLibraryParam(raw2) { - if (!raw2) return void 0; - const libs = raw2.split(",").map((s) => s.trim()).filter(Boolean); - return libs.length > 0 ? libs : void 0; -} +var parseLibraryParam = parseLibraryList; entryRoutes.post("/", async (c) => { const body = await c.req.json().catch(() => null); if (!body || !body.entry_type) return c.json({ success: false, error: "entry_type required" }, 400); @@ -4550,7 +4551,15 @@ mapRoutes.get("/:library", async (c) => { }); // kbdb/src/actions/graph-query.ts -async function findTripletEdgesByNode(db, templateIdOrName, fields, nodeValue, owner_id) { +var D1_MAX_BOUND_PARAMS = 90; +function chunkForD1(items, fixedParams) { + const size = Math.max(1, D1_MAX_BOUND_PARAMS - fixedParams); + if (items.length <= size) return [items]; + const out = []; + for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size)); + return out; +} +async function findTripletEdgesByNode(db, templateIdOrName, fields, nodeValue, owner_id, libraries) { if (!nodeValue || fields.length === 0) return []; const tpl = await getTemplate(db, templateIdOrName); if (!tpl) return []; @@ -4560,42 +4569,58 @@ async function findTripletEdgesByNode(db, templateIdOrName, fields, nodeValue, o const valueIds = (valueRows.results ?? []).map((r) => r.id); if (valueIds.length === 0) return []; const fieldIds = fields.map((f) => fieldEntryId(tpl.id, f)); - const dstPh = valueIds.map(() => "?").join(","); const relPh = fieldIds.map(() => "?").join(","); - const relSql = owner_id ? `SELECT DISTINCT src_id AS record_id FROM entries - WHERE dst_id IN (${dstPh}) AND rel_id IN (${relPh}) AND owner_id = ?` : `SELECT DISTINCT src_id AS record_id FROM entries - WHERE dst_id IN (${dstPh}) AND rel_id IN (${relPh})`; - const relParams = owner_id ? [...valueIds, ...fieldIds, owner_id] : [...valueIds, ...fieldIds]; - const relRows = await db.prepare(relSql).bind(...relParams).all(); - const recordIds = (relRows.results ?? []).map((r) => r.record_id); + const recordIdSet = /* @__PURE__ */ new Set(); + for (const idsChunk of chunkForD1(valueIds, fieldIds.length + (owner_id ? 1 : 0))) { + const dstPh = idsChunk.map(() => "?").join(","); + const relSql = owner_id ? `SELECT DISTINCT src_id AS record_id FROM entries + WHERE dst_id IN (${dstPh}) AND rel_id IN (${relPh}) AND owner_id = ?` : `SELECT DISTINCT src_id AS record_id FROM entries + WHERE dst_id IN (${dstPh}) AND rel_id IN (${relPh})`; + const relParams = owner_id ? [...idsChunk, ...fieldIds, owner_id] : [...idsChunk, ...fieldIds]; + const relRows = await db.prepare(relSql).bind(...relParams).all(); + for (const r of relRows.results ?? []) recordIdSet.add(r.record_id); + } + const recordIds = [...recordIdSet]; if (recordIds.length === 0) return []; - const recPh = recordIds.map(() => "?").join(","); - const pivotSql = ` - SELECT b.src_id AS record_id, - MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS subject, - MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS predicate, - MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS object, - MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS status - FROM entries b - LEFT JOIN entries r ON r.src_id = b.src_id AND r.rel_id != 'sys_belongs' - LEFT JOIN entries v ON v.id = r.dst_id - WHERE b.rel_id = 'sys_belongs' AND b.src_id IN (${recPh}) - GROUP BY b.src_id`; - const pivotParams = [ - fieldEntryId(tpl.id, "subject"), - fieldEntryId(tpl.id, "predicate"), - fieldEntryId(tpl.id, "object"), - fieldEntryId(tpl.id, "status"), - ...recordIds - ]; - const pivotRows = await db.prepare(pivotSql).bind(...pivotParams).all(); - return pivotRows.results ?? []; + const libFilter = libraries && libraries.length > 0 ? libraries : null; + const libAgg = "MAX(CASE WHEN r.rel_id = ? THEN v.content END)"; + const pivotFixed = 5 + (libFilter ? 1 + libFilter.length : 0); + const rows = []; + for (const recChunk of chunkForD1(recordIds, pivotFixed)) { + const recPh = recChunk.map(() => "?").join(","); + const pivotSql = ` + SELECT b.src_id AS record_id, + MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS subject, + MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS predicate, + MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS object, + MAX(CASE WHEN r.rel_id = ? THEN v.content END) AS status, + ${libAgg} AS library + FROM entries b + LEFT JOIN entries r ON r.src_id = b.src_id AND r.rel_id != 'sys_belongs' + LEFT JOIN entries v ON v.id = r.dst_id + WHERE b.rel_id = 'sys_belongs' AND b.src_id IN (${recPh}) + GROUP BY b.src_id${libFilter ? ` + HAVING ${libraryOf(libAgg)} IN (${libFilter.map(() => "?").join(",")})` : ""}`; + const pivotParams = [ + fieldEntryId(tpl.id, "subject"), + fieldEntryId(tpl.id, "predicate"), + fieldEntryId(tpl.id, "object"), + fieldEntryId(tpl.id, "status"), + fieldEntryId(tpl.id, "library"), + ...recChunk, + ...libFilter ? [fieldEntryId(tpl.id, "library"), ...libFilter] : [] + ]; + const pivotRows = await db.prepare(pivotSql).bind(...pivotParams).all(); + rows.push(...pivotRows.results ?? []); + } + return rows; } async function graphNeighbors(db, start, opts = {}) { const depth = Math.max(1, Math.min(Math.floor(opts.depth ?? 1) || 1, 10)); const template = opts.template ?? "triplet"; const directed = !!opts.directed; const owner_id = opts.owner_id; + const libraries = opts.library && opts.library.length > 0 ? opts.library : void 0; const visited = /* @__PURE__ */ new Set([start]); let frontier = [start]; const neighbors = []; @@ -4603,7 +4628,7 @@ async function graphNeighbors(db, start, opts = {}) { if (frontier.length === 0) break; const next = []; for (const cur of frontier) { - const outgoing = await findTripletEdgesByNode(db, template, ["subject"], cur, owner_id); + const outgoing = await findTripletEdgesByNode(db, template, ["subject"], cur, owner_id, libraries); for (const e of outgoing) { if (e.status === "deprecated") continue; const nb = e.object; @@ -4613,7 +4638,7 @@ async function graphNeighbors(db, start, opts = {}) { next.push(nb); } if (!directed) { - const incoming = await findTripletEdgesByNode(db, template, ["object"], cur, owner_id); + const incoming = await findTripletEdgesByNode(db, template, ["object"], cur, owner_id, libraries); for (const e of incoming) { if (e.status === "deprecated") continue; const nb = e.subject; @@ -4626,7 +4651,7 @@ async function graphNeighbors(db, start, opts = {}) { } frontier = next; } - return { success: true, start, depth, directed, neighbors, count: neighbors.length }; + return { success: true, start, depth, directed, libraries: libraries ?? null, neighbors, count: neighbors.length }; } // kbdb/src/routes/graph.ts @@ -4639,8 +4664,9 @@ graphRoutes.get("/neighbors/:node", async (c) => { const directed = c.req.query("directed") === "true"; const template = c.req.query("template") || void 0; const owner_id = c.req.query("owner_id") || void 0; + const library = parseLibraryList(c.req.query("library")); try { - const result = await graphNeighbors(c.env.DB, node, { depth, template, directed, owner_id }); + const result = await graphNeighbors(c.env.DB, node, { depth, template, directed, owner_id, library }); const edges = result.neighbors.map((n) => ({ subject: n.from, predicate: n.predicate, diff --git a/manifest.json b/manifest.json index b04ad78..62292a1 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "schema": 2, "built": "2026-08-27", - "source": "Arcrun@f87260b1234f", + "source": "Arcrun@98b45409740b", "core": [ { "name": "arcrun-array-ops", @@ -198,7 +198,7 @@ "name": "arcrun-cypher-executor", "main_module": "worker.mjs", "main_file": "arcrun-cypher-executor/worker.mjs", - "js_bytes": 696639, + "js_bytes": 702374, "modules": [], "compat_date": "2025-02-19", "compat_flags": [ @@ -239,10 +239,10 @@ "stripped": { "services": 13 }, - "source_commit": "f87260b1234f0c108c378caf474d7af78cdd6cb9", - "source_content_sha256": "2390294711ed529125559e505ed8f575093798480606253b31021b6faca4c758", - "sha256": "2390294711ed529125559e505ed8f575093798480606253b31021b6faca4c758", - "bytes": 696639 + "source_commit": "98b45409740bdb4976f8744f09255c98be8fc10c", + "source_content_sha256": "b5cb49e2d2c263adea38418289d61fac470d1d121391d4805928e5a6cbb6c012", + "sha256": "b5cb49e2d2c263adea38418289d61fac470d1d121391d4805928e5a6cbb6c012", + "bytes": 702374 }, { "name": "arcrun-date-ops", @@ -396,7 +396,7 @@ "name": "arcrun-kbdb", "main_module": "worker.mjs", "main_file": "arcrun-kbdb/worker.mjs", - "js_bytes": 194366, + "js_bytes": 195715, "modules": [], "compat_date": "2025-02-19", "compat_flags": [ @@ -416,10 +416,10 @@ "ENVIRONMENT": "production" } }, - "source_commit": "f87260b1234f0c108c378caf474d7af78cdd6cb9", - "source_content_sha256": "97140b9d10337c0f995b5bd5a4a3403ff06403afb6a51394b3ede013293c5bf6", - "sha256": "97140b9d10337c0f995b5bd5a4a3403ff06403afb6a51394b3ede013293c5bf6", - "bytes": 194366 + "source_commit": "98b45409740bdb4976f8744f09255c98be8fc10c", + "source_content_sha256": "fc1b12b56c7b3f8d68021349c72b5301afbb93333bf25887595b0fedc0e2232d", + "sha256": "fc1b12b56c7b3f8d68021349c72b5301afbb93333bf25887595b0fedc0e2232d", + "bytes": 195715 }, { "name": "arcrun-mcp", @@ -698,12 +698,12 @@ "bytes": 67697 } ], - "release": "1.4.59", + "release": "1.4.60", "built_for": "oauth-installer-lazy-load", "notes": [ "rag_takedown_direct 用了 __CARDS_PREFIX__,但安裝器的代換表沒有它 ⇒ 這個佔位符會原封不動被推進使用者的工作流。" ], - "fingerprint": "6d5575253074f913fa548e13da8ce6c9cda4d9598a8bd5971642ab66ea43bf80", + "fingerprint": "731204104f2d9354af6b5e236dcfdf71f366b0ec56d103fb5bf242b99718d4bf", "library": [ { "name": "arcrun-array-ops", @@ -888,7 +888,7 @@ "name": "arcrun-cypher-executor", "main_module": "worker.mjs", "main_file": "arcrun-cypher-executor/worker.mjs", - "js_bytes": 696639, + "js_bytes": 702374, "modules": [], "compat_date": "2025-02-19", "compat_flags": [ @@ -929,8 +929,8 @@ "stripped": { "services": 13 }, - "source_commit": "f87260b1234f0c108c378caf474d7af78cdd6cb9", - "source_content_sha256": "2390294711ed529125559e505ed8f575093798480606253b31021b6faca4c758", + "source_commit": "98b45409740bdb4976f8744f09255c98be8fc10c", + "source_content_sha256": "b5cb49e2d2c263adea38418289d61fac470d1d121391d4805928e5a6cbb6c012", "first_install": true }, { @@ -1075,7 +1075,7 @@ "name": "arcrun-kbdb", "main_module": "worker.mjs", "main_file": "arcrun-kbdb/worker.mjs", - "js_bytes": 194366, + "js_bytes": 195715, "modules": [], "compat_date": "2025-02-19", "compat_flags": [ @@ -1095,8 +1095,8 @@ "ENVIRONMENT": "production" } }, - "source_commit": "f87260b1234f0c108c378caf474d7af78cdd6cb9", - "source_content_sha256": "97140b9d10337c0f995b5bd5a4a3403ff06403afb6a51394b3ede013293c5bf6", + "source_commit": "98b45409740bdb4976f8744f09255c98be8fc10c", + "source_content_sha256": "fc1b12b56c7b3f8d68021349c72b5301afbb93333bf25887595b0fedc0e2232d", "first_install": true }, {