@buoy-gg/agent-core 7.0.35 → 7.0.38
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/README.md +21 -14
- package/lib/commonjs/blocks/receipts.js +57 -1
- package/lib/commonjs/blocks/receipts.js.map +1 -1
- package/lib/commonjs/blocks/types.js +23 -2
- package/lib/commonjs/blocks/types.js.map +1 -1
- package/lib/commonjs/blocks/uiTool.js +423 -10
- package/lib/commonjs/blocks/uiTool.js.map +1 -1
- package/lib/commonjs/catalog/catalog.g.js +213 -48
- package/lib/commonjs/catalog/catalog.g.js.map +1 -1
- package/lib/commonjs/catalog/catalog.source.json +226 -48
- package/lib/commonjs/catalog/catalog.types.g.js +44 -0
- package/lib/commonjs/catalog/catalog.types.g.js.map +1 -0
- package/lib/commonjs/catalog/normalizeParams.js +333 -0
- package/lib/commonjs/catalog/normalizeParams.js.map +1 -0
- package/lib/commonjs/catalog/signature.js +68 -0
- package/lib/commonjs/catalog/signature.js.map +1 -0
- package/lib/commonjs/catalog/snapshotReads.js +13 -6
- package/lib/commonjs/catalog/snapshotReads.js.map +1 -1
- package/lib/commonjs/catalog/toProviderTools.js +44 -6
- package/lib/commonjs/catalog/toProviderTools.js.map +1 -1
- package/lib/commonjs/context/buildContextPack.js +367 -19
- package/lib/commonjs/context/buildContextPack.js.map +1 -1
- package/lib/commonjs/effects/digest.js +34 -0
- package/lib/commonjs/effects/digest.js.map +1 -0
- package/lib/commonjs/effects/ledger.js +98 -2
- package/lib/commonjs/effects/ledger.js.map +1 -1
- package/lib/commonjs/engine/askGate.js +287 -0
- package/lib/commonjs/engine/askGate.js.map +1 -0
- package/lib/commonjs/engine/effectFor.js +82 -1
- package/lib/commonjs/engine/effectFor.js.map +1 -1
- package/lib/commonjs/engine/evidence.js +113 -0
- package/lib/commonjs/engine/evidence.js.map +1 -0
- package/lib/commonjs/engine/historyBudget.js +363 -0
- package/lib/commonjs/engine/historyBudget.js.map +1 -0
- package/lib/commonjs/engine/retrieve.js +214 -0
- package/lib/commonjs/engine/retrieve.js.map +1 -0
- package/lib/commonjs/engine/runAgentTurn.js +1231 -120
- package/lib/commonjs/engine/runAgentTurn.js.map +1 -1
- package/lib/commonjs/engine/systemPrompt.js +103 -9
- package/lib/commonjs/engine/systemPrompt.js.map +1 -1
- package/lib/commonjs/engine/textToolCalls.js +276 -0
- package/lib/commonjs/engine/textToolCalls.js.map +1 -0
- package/lib/commonjs/engine/tokenCalibration.js +81 -0
- package/lib/commonjs/engine/tokenCalibration.js.map +1 -0
- package/lib/commonjs/engine/verify.js +300 -0
- package/lib/commonjs/engine/verify.js.map +1 -0
- package/lib/commonjs/index.js +74 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/policy/labels.js +19 -3
- package/lib/commonjs/policy/labels.js.map +1 -1
- package/lib/commonjs/policy/policy.js +6 -1
- package/lib/commonjs/policy/policy.js.map +1 -1
- package/lib/commonjs/policy/redact.js +42 -5
- package/lib/commonjs/policy/redact.js.map +1 -1
- package/lib/commonjs/providers/anthropic.js +340 -208
- package/lib/commonjs/providers/anthropic.js.map +1 -1
- package/lib/commonjs/providers/openai.js +237 -103
- package/lib/commonjs/providers/openai.js.map +1 -1
- package/lib/commonjs/providers/problem.js +98 -0
- package/lib/commonjs/providers/problem.js.map +1 -0
- package/lib/commonjs/providers/sse.js +170 -34
- package/lib/commonjs/providers/sse.js.map +1 -1
- package/lib/commonjs/providers/streamTimer.js +123 -0
- package/lib/commonjs/providers/streamTimer.js.map +1 -0
- package/lib/commonjs/providers/transport.js +123 -0
- package/lib/commonjs/providers/transport.js.map +1 -0
- package/lib/commonjs/providers/xhrStream.js +212 -0
- package/lib/commonjs/providers/xhrStream.js.map +1 -0
- package/lib/commonjs/session.js +242 -58
- package/lib/commonjs/session.js.map +1 -1
- package/lib/module/blocks/receipts.js +57 -1
- package/lib/module/blocks/receipts.js.map +1 -1
- package/lib/module/blocks/types.js +23 -2
- package/lib/module/blocks/types.js.map +1 -1
- package/lib/module/blocks/uiTool.js +421 -10
- package/lib/module/blocks/uiTool.js.map +1 -1
- package/lib/module/catalog/catalog.g.js +213 -48
- package/lib/module/catalog/catalog.g.js.map +1 -1
- package/lib/module/catalog/catalog.source.json +226 -48
- package/lib/module/catalog/catalog.types.g.js +40 -0
- package/lib/module/catalog/catalog.types.g.js.map +1 -0
- package/lib/module/catalog/normalizeParams.js +327 -0
- package/lib/module/catalog/normalizeParams.js.map +1 -0
- package/lib/module/catalog/signature.js +63 -0
- package/lib/module/catalog/signature.js.map +1 -0
- package/lib/module/catalog/snapshotReads.js +13 -6
- package/lib/module/catalog/snapshotReads.js.map +1 -1
- package/lib/module/catalog/toProviderTools.js +44 -6
- package/lib/module/catalog/toProviderTools.js.map +1 -1
- package/lib/module/context/buildContextPack.js +366 -19
- package/lib/module/context/buildContextPack.js.map +1 -1
- package/lib/module/effects/digest.js +29 -0
- package/lib/module/effects/digest.js.map +1 -0
- package/lib/module/effects/ledger.js +98 -2
- package/lib/module/effects/ledger.js.map +1 -1
- package/lib/module/engine/askGate.js +280 -0
- package/lib/module/engine/askGate.js.map +1 -0
- package/lib/module/engine/effectFor.js +83 -1
- package/lib/module/engine/effectFor.js.map +1 -1
- package/lib/module/engine/evidence.js +107 -0
- package/lib/module/engine/evidence.js.map +1 -0
- package/lib/module/engine/historyBudget.js +355 -0
- package/lib/module/engine/historyBudget.js.map +1 -0
- package/lib/module/engine/retrieve.js +210 -0
- package/lib/module/engine/retrieve.js.map +1 -0
- package/lib/module/engine/runAgentTurn.js +1227 -121
- package/lib/module/engine/runAgentTurn.js.map +1 -1
- package/lib/module/engine/systemPrompt.js +101 -9
- package/lib/module/engine/systemPrompt.js.map +1 -1
- package/lib/module/engine/textToolCalls.js +270 -0
- package/lib/module/engine/textToolCalls.js.map +1 -0
- package/lib/module/engine/tokenCalibration.js +75 -0
- package/lib/module/engine/tokenCalibration.js.map +1 -0
- package/lib/module/engine/verify.js +292 -0
- package/lib/module/engine/verify.js.map +1 -0
- package/lib/module/index.js +7 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/policy/labels.js +19 -3
- package/lib/module/policy/labels.js.map +1 -1
- package/lib/module/policy/policy.js +6 -1
- package/lib/module/policy/policy.js.map +1 -1
- package/lib/module/policy/redact.js +42 -5
- package/lib/module/policy/redact.js.map +1 -1
- package/lib/module/providers/anthropic.js +341 -209
- package/lib/module/providers/anthropic.js.map +1 -1
- package/lib/module/providers/openai.js +238 -104
- package/lib/module/providers/openai.js.map +1 -1
- package/lib/module/providers/problem.js +92 -0
- package/lib/module/providers/problem.js.map +1 -0
- package/lib/module/providers/sse.js +166 -34
- package/lib/module/providers/sse.js.map +1 -1
- package/lib/module/providers/streamTimer.js +118 -0
- package/lib/module/providers/streamTimer.js.map +1 -0
- package/lib/module/providers/transport.js +119 -0
- package/lib/module/providers/transport.js.map +1 -0
- package/lib/module/providers/xhrStream.js +207 -0
- package/lib/module/providers/xhrStream.js.map +1 -0
- package/lib/module/session.js +226 -60
- package/lib/module/session.js.map +1 -1
- package/lib/typescript/blocks/receipts.d.ts +5 -0
- package/lib/typescript/blocks/receipts.d.ts.map +1 -1
- package/lib/typescript/blocks/types.d.ts +23 -2
- package/lib/typescript/blocks/types.d.ts.map +1 -1
- package/lib/typescript/blocks/uiTool.d.ts +11 -2
- package/lib/typescript/blocks/uiTool.d.ts.map +1 -1
- package/lib/typescript/catalog/catalog.g.d.ts +2 -2
- package/lib/typescript/catalog/catalog.g.d.ts.map +1 -1
- package/lib/typescript/catalog/catalog.types.g.d.ts +40 -0
- package/lib/typescript/catalog/catalog.types.g.d.ts.map +1 -0
- package/lib/typescript/catalog/normalizeParams.d.ts +43 -0
- package/lib/typescript/catalog/normalizeParams.d.ts.map +1 -0
- package/lib/typescript/catalog/signature.d.ts +29 -0
- package/lib/typescript/catalog/signature.d.ts.map +1 -0
- package/lib/typescript/catalog/snapshotReads.d.ts.map +1 -1
- package/lib/typescript/catalog/toProviderTools.d.ts +28 -15
- package/lib/typescript/catalog/toProviderTools.d.ts.map +1 -1
- package/lib/typescript/context/buildContextPack.d.ts +24 -2
- package/lib/typescript/context/buildContextPack.d.ts.map +1 -1
- package/lib/typescript/effects/digest.d.ts +10 -0
- package/lib/typescript/effects/digest.d.ts.map +1 -0
- package/lib/typescript/effects/ledger.d.ts +73 -0
- package/lib/typescript/effects/ledger.d.ts.map +1 -1
- package/lib/typescript/engine/askGate.d.ts +29 -0
- package/lib/typescript/engine/askGate.d.ts.map +1 -0
- package/lib/typescript/engine/effectFor.d.ts +6 -1
- package/lib/typescript/engine/effectFor.d.ts.map +1 -1
- package/lib/typescript/engine/evidence.d.ts +67 -0
- package/lib/typescript/engine/evidence.d.ts.map +1 -0
- package/lib/typescript/engine/historyBudget.d.ts +115 -0
- package/lib/typescript/engine/historyBudget.d.ts.map +1 -0
- package/lib/typescript/engine/retrieve.d.ts +32 -0
- package/lib/typescript/engine/retrieve.d.ts.map +1 -0
- package/lib/typescript/engine/runAgentTurn.d.ts +179 -3
- package/lib/typescript/engine/runAgentTurn.d.ts.map +1 -1
- package/lib/typescript/engine/systemPrompt.d.ts +80 -0
- package/lib/typescript/engine/systemPrompt.d.ts.map +1 -1
- package/lib/typescript/engine/textToolCalls.d.ts +58 -0
- package/lib/typescript/engine/textToolCalls.d.ts.map +1 -0
- package/lib/typescript/engine/tokenCalibration.d.ts +46 -0
- package/lib/typescript/engine/tokenCalibration.d.ts.map +1 -0
- package/lib/typescript/engine/verify.d.ts +67 -0
- package/lib/typescript/engine/verify.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +7 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/policy/labels.d.ts.map +1 -1
- package/lib/typescript/policy/policy.d.ts.map +1 -1
- package/lib/typescript/policy/redact.d.ts.map +1 -1
- package/lib/typescript/providers/anthropic.d.ts.map +1 -1
- package/lib/typescript/providers/openai.d.ts +0 -16
- package/lib/typescript/providers/openai.d.ts.map +1 -1
- package/lib/typescript/providers/problem.d.ts +50 -0
- package/lib/typescript/providers/problem.d.ts.map +1 -0
- package/lib/typescript/providers/sse.d.ts +86 -2
- package/lib/typescript/providers/sse.d.ts.map +1 -1
- package/lib/typescript/providers/streamTimer.d.ts +59 -0
- package/lib/typescript/providers/streamTimer.d.ts.map +1 -0
- package/lib/typescript/providers/transport.d.ts +48 -0
- package/lib/typescript/providers/transport.d.ts.map +1 -0
- package/lib/typescript/providers/types.d.ts +105 -3
- package/lib/typescript/providers/types.d.ts.map +1 -1
- package/lib/typescript/providers/xhrStream.d.ts +45 -0
- package/lib/typescript/providers/xhrStream.d.ts.map +1 -0
- package/lib/typescript/session.d.ts +55 -4
- package/lib/typescript/session.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +6 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +10 -10
- package/LICENSE +0 -58
|
@@ -16,8 +16,23 @@
|
|
|
16
16
|
* That is strictly stronger than the MCP server's `z.record(z.unknown())`,
|
|
17
17
|
* which validates nothing.
|
|
18
18
|
*/
|
|
19
|
+
import { paramsLine } from "./signature";
|
|
19
20
|
|
|
20
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Provider-agnostic tool definition; the adapters reshape it per protocol.
|
|
23
|
+
*
|
|
24
|
+
* The description comes in three forms because the two protocols cap it
|
|
25
|
+
* differently. Anthropic takes `description` whole. OpenAI (and Azure, and
|
|
26
|
+
* every OpenAI-compatible gateway) caps a function description at 1024
|
|
27
|
+
* chars, and the catalog renders the summary first and the `Actions:` list
|
|
28
|
+
* LAST — so trimming `description` to fit dropped every action line for 23
|
|
29
|
+
* of 24 tools (the 24th kept one line of sixteen), and a model on that
|
|
30
|
+
* protocol saw a summary cut mid-sentence plus a bare `action` enum. Hence
|
|
31
|
+
* the split: `summaryDescription` is the part that fits the cap,
|
|
32
|
+
* `actionsBlock` goes into the `action` property's description, which
|
|
33
|
+
* nothing caps. `description` stays their concatenation
|
|
34
|
+
* so the Anthropic request is byte-identical to what it was.
|
|
35
|
+
*/
|
|
21
36
|
|
|
22
37
|
/**
|
|
23
38
|
* Both Anthropic and OpenAI cap tool names at `[a-zA-Z0-9_-]`, so Buoy's
|
|
@@ -47,7 +62,14 @@ function actionLine(a, isRelease) {
|
|
|
47
62
|
bits.push(`[UNAVAILABLE in this build: ${a.release}]`);
|
|
48
63
|
}
|
|
49
64
|
if (a.requires?.length) bits.push(`[needs: ${a.requires.join(", ")}]`);
|
|
50
|
-
|
|
65
|
+
// The field names, from the SAME schema `validateParams` enforces. Without
|
|
66
|
+
// them the model reconstructs parameter names from prose and invents one on
|
|
67
|
+
// ~18% of param-carrying calls (measured across three agents); five of the
|
|
68
|
+
// commonest misses are patched up by `normalizeParams`, the rest just fail.
|
|
69
|
+
// `buoy_ui` already ships its signatures for exactly this reason — see the
|
|
70
|
+
// note above `signature()` in catalog/signature.ts.
|
|
71
|
+
const sig = paramsLine(a.params);
|
|
72
|
+
return sig ? `${bits.join(" ")}\n ${sig}` : bits.join(" ");
|
|
51
73
|
}
|
|
52
74
|
export function toProviderTools(catalog, opts = {}) {
|
|
53
75
|
const {
|
|
@@ -60,12 +82,18 @@ export function toProviderTools(catalog, opts = {}) {
|
|
|
60
82
|
for (const tool of catalog) {
|
|
61
83
|
if (availableToolIds && !availableToolIds.includes(tool.toolId)) continue;
|
|
62
84
|
const live = availableActions?.[tool.toolId];
|
|
63
|
-
|
|
85
|
+
// An engine-served action needs no adapter to advertise it — the engine
|
|
86
|
+
// is the adapter — so it rides with the tool whenever the tool is here.
|
|
87
|
+
let actions = live ? tool.actions.filter(a => live.includes(a.action) || a.servedBy === "engine") : tool.actions;
|
|
64
88
|
if (isRelease && hideUnavailable) {
|
|
65
89
|
actions = actions.filter(a => a.release === "works");
|
|
66
90
|
}
|
|
67
91
|
if (actions.length === 0) continue;
|
|
68
|
-
|
|
92
|
+
|
|
93
|
+
// The summary ALONE is what has to fit OpenAI's 1024-char cap (it does for
|
|
94
|
+
// 23 of 24 tools); the availability caveat rides with the actions block,
|
|
95
|
+
// which nothing caps. Concatenated they are the same bytes as before.
|
|
96
|
+
const summaryDescription = tool.summary;
|
|
69
97
|
// These prose lines look like the expensive part of the catalog and are
|
|
70
98
|
// the CHEAPEST part of it. Measured against a real tokenizer (fal ->
|
|
71
99
|
// gpt-4o-mini): the whole catalog is 79,601 chars but only 7,902 tokens
|
|
@@ -74,10 +102,20 @@ export function toProviderTools(catalog, opts = {}) {
|
|
|
74
102
|
// sent 48% fewer characters and cost MORE tokens (7,986), since dotted
|
|
75
103
|
// camelCase identifiers tokenize at ~5 chars/token. Do not "shrink" this
|
|
76
104
|
// by counting characters; measure tokens or leave it alone.
|
|
77
|
-
"Actions:", ...actions.map(a => `- ${actionLine(a, isRelease)}`)].
|
|
105
|
+
const actionsBlock = [tool.unavailableWhen ? `Unavailable when: ${tool.unavailableWhen}` : "", "Actions:", ...actions.map(a => `- ${actionLine(a, isRelease)}`)].join("\n");
|
|
106
|
+
// No blank line between the two: the single-list render this replaced
|
|
107
|
+
// filtered its "" separator out, and this string is the prefix Anthropic
|
|
108
|
+
// caches — it must not move by a byte.
|
|
109
|
+
const desc = [summaryDescription, actionsBlock].filter(Boolean).join("\n");
|
|
110
|
+
const inputExamples = actions.flatMap(a => a.inputExamples ?? []);
|
|
78
111
|
tools.push({
|
|
79
112
|
name: toProviderToolName(tool.toolId),
|
|
113
|
+
...(inputExamples.length ? {
|
|
114
|
+
inputExamples
|
|
115
|
+
} : {}),
|
|
80
116
|
description: desc,
|
|
117
|
+
summaryDescription,
|
|
118
|
+
actionsBlock,
|
|
81
119
|
inputSchema: {
|
|
82
120
|
type: "object",
|
|
83
121
|
properties: {
|
|
@@ -88,7 +126,7 @@ export function toProviderTools(catalog, opts = {}) {
|
|
|
88
126
|
},
|
|
89
127
|
params: {
|
|
90
128
|
type: "object",
|
|
91
|
-
description: "Arguments for the action.
|
|
129
|
+
description: "Arguments for the action. Each action's `params:` line in this tool's description lists its exact fields — `*` marks a required one. Send EXACTLY those names; a field that is not listed is rejected."
|
|
92
130
|
}
|
|
93
131
|
},
|
|
94
132
|
required: ["action"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["MAX_TOOL_NAME","toProviderToolName","toolId","replace","slice","fromProviderToolName","name","catalog","find","t","actionLine","a","isRelease","bits","action","summary","effect","push","release","requires","length","join","toProviderTools","opts","availableToolIds","availableActions","hideUnavailable","tools","tool","includes","live","actions","filter","
|
|
1
|
+
{"version":3,"names":["paramsLine","MAX_TOOL_NAME","toProviderToolName","toolId","replace","slice","fromProviderToolName","name","catalog","find","t","actionLine","a","isRelease","bits","action","summary","effect","push","release","requires","length","join","sig","params","toProviderTools","opts","availableToolIds","availableActions","hideUnavailable","tools","tool","includes","live","actions","filter","servedBy","summaryDescription","actionsBlock","unavailableWhen","map","desc","Boolean","inputExamples","flatMap","description","inputSchema","type","properties","enum","required","additionalProperties"],"sourceRoot":"../../../src","sources":["catalog/toProviderTools.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -10,6 +10,21 @@
|
|
|
10
10
|
* ~5.7KB (~1.5K tokens) covering routes, env, query keys, redux slices,
|
|
11
11
|
* zustand stores, jotai atoms, storage keys and API hosts.
|
|
12
12
|
*
|
|
13
|
+
* TWO HALVES, READ ON TWO SCHEDULES.
|
|
14
|
+
*
|
|
15
|
+
* The STABLE half (routes, slices, stores, atoms, storage keys, env names) is
|
|
16
|
+
* read once when the chat opens and rendered inside the cached system block.
|
|
17
|
+
* It changes rarely, and when it does the cache re-warms once.
|
|
18
|
+
*
|
|
19
|
+
* The LIVE half — the current route, which queries are MOUNTED right now, the
|
|
20
|
+
* last few requests — is read again before EVERY turn and rendered as a
|
|
21
|
+
* separate, uncached block. This exists because of one failure: asked to
|
|
22
|
+
* "rename the Pokémon I'm looking at", the model went to an empty zustand cart
|
|
23
|
+
* because the once-at-open digest had been built before any query was cached,
|
|
24
|
+
* so React Query never appeared in its prompt at all. A query with
|
|
25
|
+
* `observers > 0` IS what the screen is rendering; that fact has to be in
|
|
26
|
+
* front of the model at the moment it decides which tool to reach for.
|
|
27
|
+
*
|
|
13
28
|
* What this does NOT do, and why:
|
|
14
29
|
* - No `getSnapshot('query')`. It returns the full dehydrated cache — 8.3KB for
|
|
15
30
|
* ten queries in that same measurement, growing with every cached payload.
|
|
@@ -27,6 +42,7 @@ import { projectSnapshot, SNAPSHOT_ACTION } from "../catalog/snapshotReads";
|
|
|
27
42
|
/** Per-probe budget. A slow tool must not hold up the first message. */
|
|
28
43
|
const PROBE_TIMEOUT_MS = 2500;
|
|
29
44
|
const list = value => Array.isArray(value) ? value : Array.isArray(value?.items) ? value.items : [];
|
|
45
|
+
const rec = value => value && typeof value === "object" ? value : {};
|
|
30
46
|
const names = (value, keys, cap = 40) => list(value).slice(0, cap).map(item => {
|
|
31
47
|
if (!item || typeof item !== "object") return item;
|
|
32
48
|
const rec = item;
|
|
@@ -35,7 +51,61 @@ const names = (value, keys, cap = 40) => list(value).slice(0, cap).map(item => {
|
|
|
35
51
|
}
|
|
36
52
|
return rec.id ?? rec.name ?? rec.key;
|
|
37
53
|
});
|
|
38
|
-
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Budgets for the store sketches above. These ride in EVERY prompt, so they are
|
|
57
|
+
* caps first and features second: a wide store must cost a bounded number of
|
|
58
|
+
* characters, not however many lists it happens to hold.
|
|
59
|
+
*/
|
|
60
|
+
const DIGEST_STORE_CAP = 30;
|
|
61
|
+
const DIGEST_STORE_KEYS = 24;
|
|
62
|
+
const DIGEST_LISTS_PER_STORE = 8;
|
|
63
|
+
const DIGEST_ITEM_CHARS = 240;
|
|
64
|
+
/**
|
|
65
|
+
* TOTAL characters of item sketches across ALL stores — the cap that actually
|
|
66
|
+
* bounds the prompt. The per-store limits above bound one store; thirty stores
|
|
67
|
+
* each spending their full allowance is 60,000 characters of digest, in a
|
|
68
|
+
* block that rides in every turn. Per-item and per-store budgets are not an
|
|
69
|
+
* output budget, so this is the one that has to hold.
|
|
70
|
+
*
|
|
71
|
+
* Measured: the example app's single bag store costs ~490 tokens (+2% of the
|
|
72
|
+
* rendered prompt). This allows roughly six of those before it starts cutting.
|
|
73
|
+
*/
|
|
74
|
+
const DIGEST_SHAPES_TOTAL_CHARS = 12_000;
|
|
75
|
+
|
|
76
|
+
/** Truncate visibly — a silently cut type sketch reads as a complete one. */
|
|
77
|
+
const clampText = (s, max) => s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The top-level `name: type` pairs of a `shapeOf` sketch, split on commas that
|
|
81
|
+
* are not inside a nested `{...}` or `[...]`.
|
|
82
|
+
*
|
|
83
|
+
* Only used to drop the store's ACTION FUNCTIONS from `keys`. A zustand store
|
|
84
|
+
* keeps its actions alongside its state, so `Object.keys()` on the Poké Mart
|
|
85
|
+
* bag returns ten of `addLine`, `setQty`, `removeLine`, `clearLines`… for six
|
|
86
|
+
* real fields. Those are not state, cannot be written, and cannot be sent over
|
|
87
|
+
* the wire — putting them in front of the model as things the store "has" is
|
|
88
|
+
* an invitation to try. The catalog documents `keys` as plain `Object.keys()`,
|
|
89
|
+
* so the adapter's contract stays as it is and the filtering happens here.
|
|
90
|
+
*/
|
|
91
|
+
function topLevelFields(sketch) {
|
|
92
|
+
const out = new Map();
|
|
93
|
+
if (typeof sketch !== "string" || !sketch.startsWith("{")) return out;
|
|
94
|
+
let depth = 0;
|
|
95
|
+
let part = "";
|
|
96
|
+
const take = () => {
|
|
97
|
+
const i = part.indexOf(":");
|
|
98
|
+
if (i > 0) out.set(part.slice(0, i).trim(), part.slice(i + 1).trim());
|
|
99
|
+
part = "";
|
|
100
|
+
};
|
|
101
|
+
for (const ch of sketch.slice(1, -1)) {
|
|
102
|
+
if (ch === "{" || ch === "[" || ch === "(") depth++;else if (ch === "}" || ch === "]" || ch === ")") depth--;
|
|
103
|
+
if (ch === "," && depth === 0) take();else part += ch;
|
|
104
|
+
}
|
|
105
|
+
take();
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
const STABLE_PROBES = [{
|
|
39
109
|
// `getSitemap` was never an action — the sitemap lives in the adapter's
|
|
40
110
|
// snapshot, so this probe could only ever have been filtered out or
|
|
41
111
|
// thrown. Same for env below.
|
|
@@ -44,11 +114,6 @@ const PROBES = [{
|
|
|
44
114
|
action: SNAPSHOT_ACTION,
|
|
45
115
|
// projectSnapshot already flattened the nested route tree to paths.
|
|
46
116
|
shape: v => list(v?.routes).slice(0, 60)
|
|
47
|
-
}, {
|
|
48
|
-
key: "queryKeys",
|
|
49
|
-
toolId: "query",
|
|
50
|
-
action: "listQueries",
|
|
51
|
-
shape: v => names(v, ["queryHash", "queryKey", "key"], 40)
|
|
52
117
|
}, {
|
|
53
118
|
key: "reduxSlices",
|
|
54
119
|
toolId: "redux",
|
|
@@ -63,22 +128,76 @@ const PROBES = [{
|
|
|
63
128
|
// actually a hydrated store's saved copy — write the key directly and the
|
|
64
129
|
// screen does not change, then the store overwrites you. `listStores`
|
|
65
130
|
// already reports `persistName`; nothing else surfaces it.
|
|
131
|
+
//
|
|
132
|
+
// IT ALSO CARRIES THE ITEM SHAPE OF EVERY LIST IN THE STORE, and for a
|
|
133
|
+
// long time it did not. `listStores` returns `keys` and `shape`
|
|
134
|
+
// (zustandSyncAdapter.ts) — computed by shared/sync/valueShape.ts, which
|
|
135
|
+
// exists FOR this — and this probe threw both away, so the only bag-line
|
|
136
|
+
// shape anywhere in the prompt was a six-field one appearing incidentally
|
|
137
|
+
// inside a React Query cache key, while the store's line has nine. Models
|
|
138
|
+
// copied the shape they were shown and invented names for the rest
|
|
139
|
+
// (`price` for `unitPrice`, `imageUrl` for `image`). Both a weak and a
|
|
140
|
+
// strong model did it identically, which is what makes it ours and not
|
|
141
|
+
// theirs.
|
|
142
|
+
//
|
|
143
|
+
// `unknownLists` is the honest half. An EMPTY list has no observable item
|
|
144
|
+
// shape — not unread, unknowable — and saying so is what stops a guess
|
|
145
|
+
// going in unremarked, because the typed-edit guard builds its template
|
|
146
|
+
// from `list[0]` and has nothing to check against either.
|
|
66
147
|
key: "zustandStores",
|
|
67
148
|
toolId: "zustand",
|
|
68
149
|
action: "listStores",
|
|
69
150
|
// Structured, not a display string: `session` reads `persistsTo` back out
|
|
70
151
|
// to build the owner map the engine uses at dispatch time, and the digest
|
|
71
152
|
// is JSON-stringified into the prompt anyway, so the model loses nothing.
|
|
72
|
-
shape: v =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
153
|
+
shape: v => {
|
|
154
|
+
// Spent across every store, not per store — see DIGEST_SHAPES_TOTAL_CHARS.
|
|
155
|
+
let spent = 0;
|
|
156
|
+
return list(v?.stores ?? v).slice(0, DIGEST_STORE_CAP).map(raw => {
|
|
157
|
+
const s = raw ?? {};
|
|
158
|
+
const name = typeof s.name === "string" ? s.name : s.id;
|
|
159
|
+
const lists = list(s.shape?.lists).map(rec);
|
|
160
|
+
const known = {};
|
|
161
|
+
const unknown = [];
|
|
162
|
+
for (const l of lists.slice(0, DIGEST_LISTS_PER_STORE)) {
|
|
163
|
+
const path = typeof l.path === "string" ? l.path : undefined;
|
|
164
|
+
if (!path) continue;
|
|
165
|
+
// One level of item fields is what a write needs; `lines[].addonIds`
|
|
166
|
+
// is already covered by its parent's item sketch.
|
|
167
|
+
if (path.includes("[].")) continue;
|
|
168
|
+
if (typeof l.item !== "string") {
|
|
169
|
+
// An empty list is cheap to report and the most important thing
|
|
170
|
+
// here, so it is never what gets cut.
|
|
171
|
+
unknown.push(path);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const item = clampText(l.item, DIGEST_ITEM_CHARS);
|
|
175
|
+
if (spent + item.length > DIGEST_SHAPES_TOTAL_CHARS) continue;
|
|
176
|
+
spent += item.length;
|
|
177
|
+
known[path] = item;
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
name,
|
|
181
|
+
...(typeof s.persistName === "string" ? {
|
|
182
|
+
persistsTo: s.persistName
|
|
183
|
+
} : {}),
|
|
184
|
+
...(() => {
|
|
185
|
+
if (!Array.isArray(s.keys) || !s.keys.length) return {};
|
|
186
|
+
const fields = topLevelFields(s.shape?.shape);
|
|
187
|
+
const stateKeys = s.keys.filter(k => fields.get(String(k)) !== "function");
|
|
188
|
+
return stateKeys.length ? {
|
|
189
|
+
keys: stateKeys.slice(0, DIGEST_STORE_KEYS)
|
|
190
|
+
} : {};
|
|
191
|
+
})(),
|
|
192
|
+
...(Object.keys(known).length ? {
|
|
193
|
+
listItemShapes: known
|
|
194
|
+
} : {}),
|
|
195
|
+
...(unknown.length ? {
|
|
196
|
+
unknownLists: unknown
|
|
197
|
+
} : {})
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
}
|
|
82
201
|
}, {
|
|
83
202
|
key: "jotaiAtoms",
|
|
84
203
|
toolId: "jotai",
|
|
@@ -101,16 +220,152 @@ const PROBES = [{
|
|
|
101
220
|
return env && typeof env === "object" ? Object.keys(env).slice(0, 40) : undefined;
|
|
102
221
|
}
|
|
103
222
|
}];
|
|
223
|
+
|
|
224
|
+
/** Most-recent queries carried per turn. Mounted ones are sorted first. */
|
|
225
|
+
const LIVE_QUERY_CAP = 25;
|
|
226
|
+
/**
|
|
227
|
+
* How many queries to ASK the adapter for, before we cap to LIVE_QUERY_CAP.
|
|
228
|
+
*
|
|
229
|
+
* The adapter sorts by `dataUpdatedAt` and slices to `limit`
|
|
230
|
+
* (reactQuerySyncAdapter.ts) — so asking it for 25 and sorting mounted-first
|
|
231
|
+
* afterwards sorts a list the screen's own query may already have fallen out
|
|
232
|
+
* of. A detail screen whose query settled a minute ago sits behind every
|
|
233
|
+
* background refetch since; on an app with more than 25 live queries it was
|
|
234
|
+
* simply absent from the prompt, and `likelyScreen` then had nothing to mark.
|
|
235
|
+
* Our demo app never has enough queries to reach the cap, which is why this
|
|
236
|
+
* survived: it is a bug that only appears on apps bigger than the example.
|
|
237
|
+
*
|
|
238
|
+
* The real fix is in the adapter, which now sorts mounted-first before it
|
|
239
|
+
* applies `limit`. This modest over-fetch is defence in depth for the readers
|
|
240
|
+
* that do NOT — an older device on a published version, or a desktop mirror
|
|
241
|
+
* replaying its own payload — where prioritising here is the only chance left.
|
|
242
|
+
* 2x, not more: this rides in every turn and an unbounded scan is how a cheap
|
|
243
|
+
* call stops being cheap.
|
|
244
|
+
*/
|
|
245
|
+
const LIVE_QUERY_SCAN = LIVE_QUERY_CAP * 2;
|
|
246
|
+
/** Recent requests carried per turn — enough to find the call that fed the screen. */
|
|
247
|
+
const LIVE_REQUEST_CAP = 8;
|
|
248
|
+
const LIVE_PROBES = [{
|
|
249
|
+
// `{path, params}` — the params matter as much as the path: "mewtwo" in
|
|
250
|
+
// `params.id` is what ties `/pokemon/[id]` to the `["pokemon-detail",
|
|
251
|
+
// "mewtwo", ...]` query below.
|
|
252
|
+
key: "currentRoute",
|
|
253
|
+
toolId: "route-events",
|
|
254
|
+
action: "getCurrentRoute",
|
|
255
|
+
shape: v => {
|
|
256
|
+
const r = rec(v);
|
|
257
|
+
if (typeof r.path !== "string") return undefined;
|
|
258
|
+
return r.params && Object.keys(rec(r.params)).length ? {
|
|
259
|
+
path: r.path,
|
|
260
|
+
params: r.params
|
|
261
|
+
} : {
|
|
262
|
+
path: r.path
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}, {
|
|
266
|
+
// `observers > 0` is the one field that says "a component on screen is
|
|
267
|
+
// rendering this right now". Everything else about a query is secondary
|
|
268
|
+
// to that when the question is "what am I looking at".
|
|
269
|
+
key: "queries",
|
|
270
|
+
toolId: "query",
|
|
271
|
+
action: "listQueries",
|
|
272
|
+
params: {
|
|
273
|
+
limit: LIVE_QUERY_SCAN
|
|
274
|
+
},
|
|
275
|
+
shape: v => {
|
|
276
|
+
const rows = list(v?.queries ?? v).map(rec);
|
|
277
|
+
const shaped = rows.map(q => {
|
|
278
|
+
const observers = typeof q.observers === "number" ? q.observers : 0;
|
|
279
|
+
return {
|
|
280
|
+
key: q.queryKey ?? q.queryHash,
|
|
281
|
+
status: q.status,
|
|
282
|
+
...(observers > 0 ? {
|
|
283
|
+
onScreen: true,
|
|
284
|
+
observers
|
|
285
|
+
} : {})
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
// PRIORITISE, THEN CAP — in that order. The adapter has already dropped
|
|
289
|
+
// everything past LIVE_QUERY_SCAN by recency; this keeps the mounted
|
|
290
|
+
// ones out of the next cut, which is the whole point of the sort.
|
|
291
|
+
shaped.sort((a, b) => Number(Boolean(b.onScreen)) - Number(Boolean(a.onScreen)));
|
|
292
|
+
return shaped.slice(0, LIVE_QUERY_CAP);
|
|
293
|
+
}
|
|
294
|
+
}, {
|
|
295
|
+
// Whether anything is being recorded AT ALL. Network only captures while
|
|
296
|
+
// something holds a subscription, so the request list below can be empty
|
|
297
|
+
// or stale for a reason that has nothing to do with the app. Put in front
|
|
298
|
+
// of the model on the first turn, it was costing several turns to
|
|
299
|
+
// discover ("The network recorder wasn't running when you asked…").
|
|
300
|
+
key: "networkCapture",
|
|
301
|
+
toolId: "network",
|
|
302
|
+
action: "getCaptureStatus",
|
|
303
|
+
shape: v => {
|
|
304
|
+
const s = rec(v);
|
|
305
|
+
if (typeof s.capturing !== "boolean") return undefined;
|
|
306
|
+
return {
|
|
307
|
+
recording: s.capturing,
|
|
308
|
+
...(s.interceptorLive === false ? {
|
|
309
|
+
interceptorLive: false
|
|
310
|
+
} : {}),
|
|
311
|
+
captured: typeof s.eventCount === "number" ? s.eventCount : undefined
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}, {
|
|
315
|
+
// Newest FIRST, as the adapter stores them (the projection keeps that
|
|
316
|
+
// order; it once took the oldest N by mistake). Carries the request `id` so a
|
|
317
|
+
// network override seeded from the real response is one call away
|
|
318
|
+
// (`upsertOverrideRule({ fromRequestId })`), and `overridden` so the model
|
|
319
|
+
// never presents mocked data as live.
|
|
320
|
+
key: "recentRequests",
|
|
321
|
+
toolId: "network",
|
|
322
|
+
action: SNAPSHOT_ACTION,
|
|
323
|
+
params: {
|
|
324
|
+
limit: LIVE_REQUEST_CAP
|
|
325
|
+
},
|
|
326
|
+
shape: v => list(v?.requests).map(raw => {
|
|
327
|
+
const e = rec(raw);
|
|
328
|
+
return {
|
|
329
|
+
id: e.id,
|
|
330
|
+
method: e.method,
|
|
331
|
+
url: e.url,
|
|
332
|
+
status: e.status,
|
|
333
|
+
...(e.overridden ? {
|
|
334
|
+
overridden: true
|
|
335
|
+
} : {})
|
|
336
|
+
};
|
|
337
|
+
})
|
|
338
|
+
}, {
|
|
339
|
+
// An armed override rule explains a response that disagrees with the
|
|
340
|
+
// server. Without this the model would tell the user the API is broken.
|
|
341
|
+
key: "networkOverrides",
|
|
342
|
+
toolId: "network",
|
|
343
|
+
action: "listOverrideRules",
|
|
344
|
+
shape: v => {
|
|
345
|
+
const state = rec(v);
|
|
346
|
+
const rules = list(state.rules).map(rec).filter(r => r.enabled !== false).slice(0, 10).map(r => ({
|
|
347
|
+
id: r.id,
|
|
348
|
+
urlPattern: r.urlPattern,
|
|
349
|
+
kind: r.kind,
|
|
350
|
+
status: r.status
|
|
351
|
+
}));
|
|
352
|
+
if (!rules.length) return undefined;
|
|
353
|
+
return {
|
|
354
|
+
enabled: state.enabled === true,
|
|
355
|
+
rules
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}];
|
|
104
359
|
async function withTimeout(p, ms) {
|
|
105
360
|
return await Promise.race([p.catch(() => undefined), new Promise(resolve => setTimeout(() => resolve(undefined), ms))]);
|
|
106
361
|
}
|
|
107
|
-
|
|
362
|
+
async function runProbes(probes, {
|
|
108
363
|
dispatch,
|
|
109
364
|
readSnapshot,
|
|
110
365
|
availableToolIds,
|
|
111
366
|
availableActions
|
|
112
367
|
}) {
|
|
113
|
-
const runnable =
|
|
368
|
+
const runnable = probes.filter(p => {
|
|
114
369
|
if (!availableToolIds.includes(p.toolId)) return false;
|
|
115
370
|
const actions = availableActions?.[p.toolId];
|
|
116
371
|
return !actions || actions.includes(p.action);
|
|
@@ -119,7 +374,7 @@ export async function buildContextDigest({
|
|
|
119
374
|
// All at once — these are independent reads and the first message should not
|
|
120
375
|
// wait on the slowest one twice over.
|
|
121
376
|
const settled = await Promise.all(runnable.map(async probe => {
|
|
122
|
-
const read = probe.action === SNAPSHOT_ACTION ? readSnapshot ? Promise.resolve(readSnapshot(probe.toolId)).then(payload => projectSnapshot(probe.toolId, payload)) : Promise.resolve(undefined) : Promise.resolve(dispatch(probe.toolId, probe.action, probe.params));
|
|
377
|
+
const read = probe.action === SNAPSHOT_ACTION ? readSnapshot ? Promise.resolve(readSnapshot(probe.toolId)).then(payload => projectSnapshot(probe.toolId, payload, probe.params ?? {})) : Promise.resolve(undefined) : Promise.resolve(dispatch(probe.toolId, probe.action, probe.params));
|
|
123
378
|
const value = await withTimeout(read, PROBE_TIMEOUT_MS);
|
|
124
379
|
if (value === undefined) return [probe.key, undefined];
|
|
125
380
|
try {
|
|
@@ -135,4 +390,96 @@ export async function buildContextDigest({
|
|
|
135
390
|
}
|
|
136
391
|
return digest;
|
|
137
392
|
}
|
|
393
|
+
|
|
394
|
+
/** The stable half: read once at open, rendered inside the cached prompt. */
|
|
395
|
+
export function buildContextDigest(input) {
|
|
396
|
+
return runProbes(STABLE_PROBES, input);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/** Lowercased string tokens from a query key array (or a hash string). */
|
|
400
|
+
function keyTokens(key) {
|
|
401
|
+
const parts = Array.isArray(key) ? key : typeof key === "string" ? (() => {
|
|
402
|
+
try {
|
|
403
|
+
const p = JSON.parse(key);
|
|
404
|
+
return Array.isArray(p) ? p : [key];
|
|
405
|
+
} catch {
|
|
406
|
+
return [key];
|
|
407
|
+
}
|
|
408
|
+
})() : [key];
|
|
409
|
+
return parts.flatMap(p => p === null || p === undefined ? [] : splitTokens(String(typeof p === "object" ? JSON.stringify(p) : p)));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* The one tokeniser. Keys and route params MUST be split identically — that
|
|
414
|
+
* they were not is exactly how the scoring came to work only on bare words.
|
|
415
|
+
*/
|
|
416
|
+
function splitTokens(value) {
|
|
417
|
+
return value.toLowerCase().split(/[^a-z0-9]+/i).filter(Boolean);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Tie the mounted queries to the FOCUSED route.
|
|
422
|
+
*
|
|
423
|
+
* `observers > 0` means "mounted somewhere in the nav stack", NOT "on the
|
|
424
|
+
* visible screen" — a stack navigator keeps the screen beneath the current one
|
|
425
|
+
* mounted, so its query still reports an observer. That is the exact bug behind
|
|
426
|
+
* "it edited a query that isn't the screen I'm on": on /pokemon/charmander both
|
|
427
|
+
* the pokemon-detail query and a still-mounted /shop/item/charmander query look
|
|
428
|
+
* on-screen. So score each on-screen query against the focused route's param
|
|
429
|
+
* VALUES (weighted) and path segments, and mark the single clear winner
|
|
430
|
+
* `likelyScreen: true`. A tie marks none — the prompt then tells the model to
|
|
431
|
+
* reason from currentRoute rather than guess.
|
|
432
|
+
*/
|
|
433
|
+
function annotateLikelyScreen(live) {
|
|
434
|
+
const route = live.currentRoute;
|
|
435
|
+
const queries = live.queries;
|
|
436
|
+
if (!route?.path || !Array.isArray(queries)) return;
|
|
437
|
+
|
|
438
|
+
// Tokenised the SAME way the keys are. They were not, and `tokens.has(value)`
|
|
439
|
+
// could therefore never match a param containing anything but letters and
|
|
440
|
+
// digits — every UUID, slug, date, email and composite id silently scored
|
|
441
|
+
// zero, and only the demo app's bare `mewtwo` / `25` ever matched. A param
|
|
442
|
+
// counts as present when every one of its tokens is in the key, so
|
|
443
|
+
// "double-cheese-burger" matches ["menu-item","double-cheese-burger"] and
|
|
444
|
+
// does not match ["menu","burger"].
|
|
445
|
+
const paramTokens = Object.values(route.params ?? {}).map(v => splitTokens(String(v))).filter(t => t.length > 0);
|
|
446
|
+
const pathSegs = splitTokens(route.path);
|
|
447
|
+
let best = -1;
|
|
448
|
+
let bestIdx = -1;
|
|
449
|
+
let tie = false;
|
|
450
|
+
queries.forEach((q, i) => {
|
|
451
|
+
if (!q.onScreen) return;
|
|
452
|
+
const tokens = new Set(keyTokens(q.key));
|
|
453
|
+
// A param value present in the key is the strong signal (this is THIS id);
|
|
454
|
+
// a shared path segment breaks ties between two screens showing that id.
|
|
455
|
+
const paramHits = paramTokens.filter(parts => parts.every(t => tokens.has(t))).length;
|
|
456
|
+
const pathHits = pathSegs.filter(s => tokens.has(s) || [...tokens].some(t => t.includes(s) || s.includes(t))).length;
|
|
457
|
+
const score = paramHits * 3 + pathHits;
|
|
458
|
+
if (score <= 0) return;
|
|
459
|
+
if (score > best) {
|
|
460
|
+
best = score;
|
|
461
|
+
bestIdx = i;
|
|
462
|
+
tie = false;
|
|
463
|
+
} else if (score === best) {
|
|
464
|
+
tie = true;
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
if (bestIdx >= 0 && !tie) {
|
|
468
|
+
queries[bestIdx].likelyScreen = true;
|
|
469
|
+
// float it to the very top so a capped list always shows it
|
|
470
|
+
const [winner] = queries.splice(bestIdx, 1);
|
|
471
|
+
queries.unshift(winner);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* The live half: read before every turn. Current route, mounted queries,
|
|
477
|
+
* recent requests, armed overrides. Rendered as the uncached "RIGHT NOW"
|
|
478
|
+
* block — see `buildLiveBlock` in systemPrompt.ts.
|
|
479
|
+
*/
|
|
480
|
+
export async function buildLiveContext(input) {
|
|
481
|
+
const live = await runProbes(LIVE_PROBES, input);
|
|
482
|
+
annotateLikelyScreen(live);
|
|
483
|
+
return live;
|
|
484
|
+
}
|
|
138
485
|
//# sourceMappingURL=buildContextPack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["projectSnapshot","SNAPSHOT_ACTION","PROBE_TIMEOUT_MS","list","value","Array","isArray","items","names","keys","cap","slice","map","item","rec","k","undefined","id","name","key","PROBES","toolId","action","shape","v","routes","params","includeValues","Object","state","stores","raw","s","persistName","persistsTo","env","withTimeout","p","ms","Promise","race","catch","resolve","setTimeout","buildContextDigest","dispatch","readSnapshot","availableToolIds","availableActions","runnable","filter","includes","actions","settled","all","probe","read","then","payload","digest","empty","length"],"sourceRoot":"../../../src","sources":["context/buildContextPack.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["projectSnapshot","SNAPSHOT_ACTION","PROBE_TIMEOUT_MS","list","value","Array","isArray","items","rec","names","keys","cap","slice","map","item","k","undefined","id","name","key","DIGEST_STORE_CAP","DIGEST_STORE_KEYS","DIGEST_LISTS_PER_STORE","DIGEST_ITEM_CHARS","DIGEST_SHAPES_TOTAL_CHARS","clampText","s","max","length","topLevelFields","sketch","out","Map","startsWith","depth","part","take","i","indexOf","set","trim","ch","STABLE_PROBES","toolId","action","shape","v","routes","params","includeValues","Object","state","spent","stores","raw","lists","known","unknown","l","path","includes","push","persistName","persistsTo","fields","stateKeys","filter","get","String","listItemShapes","unknownLists","env","LIVE_QUERY_CAP","LIVE_QUERY_SCAN","LIVE_REQUEST_CAP","LIVE_PROBES","r","limit","rows","queries","shaped","q","observers","queryKey","queryHash","status","onScreen","sort","a","b","Number","Boolean","capturing","recording","interceptorLive","captured","eventCount","requests","e","method","url","overridden","rules","enabled","urlPattern","kind","withTimeout","p","ms","Promise","race","catch","resolve","setTimeout","runProbes","probes","dispatch","readSnapshot","availableToolIds","availableActions","runnable","actions","settled","all","probe","read","then","payload","digest","empty","buildContextDigest","input","keyTokens","parts","JSON","parse","flatMap","splitTokens","stringify","toLowerCase","split","annotateLikelyScreen","live","route","currentRoute","paramTokens","values","t","pathSegs","best","bestIdx","tie","forEach","tokens","Set","paramHits","every","has","pathHits","some","score","likelyScreen","winner","splice","unshift","buildLiveContext"],"sourceRoot":"../../../src","sources":["context/buildContextPack.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A short, stable fingerprint of any JSON-able value. Not cryptographic —
|
|
5
|
+
* it only has to answer "is this the same as what I saw?" — and deliberately
|
|
6
|
+
* lossy so the thing persisted beside an unanswered approval or a ledger
|
|
7
|
+
* entry is a hash of a store's state, never the state itself.
|
|
8
|
+
*/
|
|
9
|
+
export function digestOf(value) {
|
|
10
|
+
let json;
|
|
11
|
+
try {
|
|
12
|
+
json = JSON.stringify(value) ?? "";
|
|
13
|
+
} catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
let h = 5381;
|
|
17
|
+
for (let i = 0; i < json.length; i++) h = (h << 5) + h + json.charCodeAt(i) | 0;
|
|
18
|
+
return `${(h >>> 0).toString(16)}:${json.length}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Byte-ish size of a value once serialised; Infinity when it cannot be. */
|
|
22
|
+
export function jsonLength(value) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(value)?.length ?? 0;
|
|
25
|
+
} catch {
|
|
26
|
+
return Number.POSITIVE_INFINITY;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["digestOf","value","json","JSON","stringify","undefined","h","i","length","charCodeAt","toString","jsonLength","Number","POSITIVE_INFINITY"],"sourceRoot":"../../../src","sources":["effects/digest.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,QAAQA,CAACC,KAAc,EAAsB;EAC3D,IAAIC,IAAY;EAChB,IAAI;IACFA,IAAI,GAAGC,IAAI,CAACC,SAAS,CAACH,KAAK,CAAC,IAAI,EAAE;EACpC,CAAC,CAAC,MAAM;IACN,OAAOI,SAAS;EAClB;EACA,IAAIC,CAAC,GAAG,IAAI;EACZ,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGL,IAAI,CAACM,MAAM,EAAED,CAAC,EAAE,EAAED,CAAC,GAAI,CAACA,CAAC,IAAI,CAAC,IAAIA,CAAC,GAAGJ,IAAI,CAACO,UAAU,CAACF,CAAC,CAAC,GAAI,CAAC;EACjF,OAAO,GAAG,CAACD,CAAC,KAAK,CAAC,EAAEI,QAAQ,CAAC,EAAE,CAAC,IAAIR,IAAI,CAACM,MAAM,EAAE;AACnD;;AAEA;AACA,OAAO,SAASG,UAAUA,CAACV,KAAc,EAAU;EACjD,IAAI;IACF,OAAOE,IAAI,CAACC,SAAS,CAACH,KAAK,CAAC,EAAEO,MAAM,IAAI,CAAC;EAC3C,CAAC,CAAC,MAAM;IACN,OAAOI,MAAM,CAACC,iBAAiB;EACjC;AACF","ignoreList":[]}
|