@konneal/engine 0.2.152 → 0.2.153
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.
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
handleMemories,
|
|
5
5
|
scoreFaithfulness,
|
|
6
6
|
scoreJudge
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-I6HU3EM6.js";
|
|
8
8
|
import "../../chunk-ECOYO7EX.js";
|
|
9
9
|
import {
|
|
10
10
|
TOOLS_REGISTRY,
|
|
@@ -1107,7 +1107,7 @@ async function callToolOnce(env, ctx, _req, tier, key, name, args, t0) {
|
|
|
1107
1107
|
const r = await runTool({ ...env, DB: env.DB }, { name, args }, "mcp");
|
|
1108
1108
|
payload = r ? { tool: r.name, query: r.query, result: r.output } : { error: { message: `tool ${name} returned nothing for the given arguments` } };
|
|
1109
1109
|
} else {
|
|
1110
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
1110
|
+
const res = name === "ask" ? await (await import("../../ask-UIIE5LD2.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-GAU5SEZI.js")).handleSearch(env, ctx, inner, tier, key);
|
|
1111
1111
|
payload = await res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
1112
1112
|
}
|
|
1113
1113
|
telemetry(env, ctx, tier, `mcp:${name}`, null, !payload?.error, JSON.stringify(payload).length, await sha256Hex(`${name}:${JSON.stringify(args ?? {})}`), void 0, void 0, { durationMs: Date.now() - t0 });
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# The agent-mode stream-first architecture (the designed next build)
|
|
2
|
+
|
|
3
|
+
## The demand (owner directive, 2026-10-15): SOTA agent bots 2026 —
|
|
4
|
+
users see EVERY call as it runs. The current shape: the ask handler
|
|
5
|
+
computes the ENTIRE pipeline (understanding → retrieval → register →
|
|
6
|
+
nameplate vision → the agent loop) BEFORE the SSE response opens —
|
|
7
|
+
the user waits minutes in silence, then receives the buffered steps +
|
|
8
|
+
the answer tokens.
|
|
9
|
+
|
|
10
|
+
## The target shape
|
|
11
|
+
1. The SSE opens at the top of the streamed branch (right after the
|
|
12
|
+
cache check): the controller is captured; `live.send(ev)` works from
|
|
13
|
+
that moment.
|
|
14
|
+
2. The pipeline runs ONCE, inside the streamed branch, emitting live:
|
|
15
|
+
- mark() sends `{type:"agent", step}` immediately (no agentSteps
|
|
16
|
+
buffer + flush).
|
|
17
|
+
- The vision/question-understanding/certificate-lookup steps each
|
|
18
|
+
send their start (and result) events — the owner's step order.
|
|
19
|
+
- The short-circuits (register count/latest, verdict) send their
|
|
20
|
+
events (citations/tokens/blocks/done) through the same channel.
|
|
21
|
+
- The generation streams tokens as today (the 0.2.148 head-buffer +
|
|
22
|
+
narration restart ride along).
|
|
23
|
+
3. The JSON lane becomes a CLIENT of the same stream: run the stream,
|
|
24
|
+
aggregate {answer, citations, blocks, quota, context} from the
|
|
25
|
+
events, return json. ONE pipeline body, two delivery modes — no
|
|
26
|
+
duplication. (The done event gains the contextOut fields — additive.)
|
|
27
|
+
|
|
28
|
+
## The mechanical plan
|
|
29
|
+
- The block (understanding → the generation, ~610-1905 in ask.ts)
|
|
30
|
+
moves into the streamed branch inside start().
|
|
31
|
+
- The exits convert: the 3 err()s → the graceful token + done; the
|
|
32
|
+
json returns inside the streamed branch → the aggregator return;
|
|
33
|
+
sseResponse(...) → live.send per event + close.
|
|
34
|
+
- The json lane below the branch → the aggregator (~40 lines).
|
|
35
|
+
- The event-shape additions are additive (context in done; the error
|
|
36
|
+
token convention).
|
|
37
|
+
|
|
38
|
+
## The safe path
|
|
39
|
+
1. The engine PR: merge safely (no deploy).
|
|
40
|
+
2. Publish → the ai scratch worktree pins 0.2.15x → `npm run dev:public`
|
|
41
|
+
(the LOCAL worker, remote bindings) → the probes: the streamed
|
|
42
|
+
Chomsky refusal, the photo flow's step order, a JSON MPE ask, the
|
|
43
|
+
long question.
|
|
44
|
+
3. Only after the probes: the ai pin bump PR → auto-deploy → the
|
|
45
|
+
production probes.
|
|
46
|
+
|
|
47
|
+
## WHAT LANDED (0.2.151, probes green)
|
|
48
|
+
|
|
49
|
+
One pipeline body, TWO DELIVERIES — but the delivery is chosen by the
|
|
50
|
+
CHANNEL PARAMETER, not the request's stream preference:
|
|
51
|
+
`pipeline(channel, qq)` where channel is the live SSE writer or null.
|
|
52
|
+
The dispatch: `if (liveResponse) { void pipeline(live, q); return
|
|
53
|
+
liveResponse; } return await pipeline(null, q);`.
|
|
54
|
+
|
|
55
|
+
Laws the build adds to the serving doctrine:
|
|
56
|
+
|
|
57
|
+
1. **THE CHANNEL DECIDES THE LANE.** Inside the pipeline, every lane
|
|
58
|
+
branch keys off `live` (the channel) — never off `wantsStream` (the
|
|
59
|
+
request preference). The two are coupled by the hoist/dispatch, but
|
|
60
|
+
the channel is the authority: a preference-guarded branch is reachable
|
|
61
|
+
with a null channel (the first probe build 500'd every json ask in
|
|
62
|
+
exactly that else).
|
|
63
|
+
2. **THE HOIST PRECEDES EVERY STEP.** The SSE opens before the vision
|
|
64
|
+
step, the understanding, the register bridge — each mark() streams at
|
|
65
|
+
the moment it runs (the owner's step order), never replayed from a
|
|
66
|
+
buffer. The agentSteps buffer survives only for the json lane's
|
|
67
|
+
single response.
|
|
68
|
+
3. **ONE READER, ONE LOOKUP (the photo flow).** The nameplate bridge
|
|
69
|
+
(vision → extract → certificates.search) is the reader on a cert-photo
|
|
70
|
+
turn; the agent loop stands down there (`!nameplate?.manufacturer`).
|
|
71
|
+
The loop's image-bearing probe remains the reader on every OTHER
|
|
72
|
+
image turn. The user watches: Reading the nameplate photograph →
|
|
73
|
+
Nameplate read: … → certificates.search — … → the answer.
|
|
74
|
+
4. **THE CFA BUDGET.** A ~1400-line closure drops TypeScript's flow
|
|
75
|
+
narrowing mid-function (values see `string | null` inside their own
|
|
76
|
+
guards). The 24 carried sites are guard-backed `!` assertions — the
|
|
77
|
+
guards are the runtime proof; a reduced repro for the narrowing loss
|
|
78
|
+
is a follow-up.
|
|
79
|
+
|
|
80
|
+
Probes (local --remote dev against production bindings): JSON MPE ask
|
|
81
|
+
(7-10 citations, table block), streamed Chomsky refusal (pinned
|
|
82
|
+
sentence, no follow_up chips), streamed knowledge (read → citations →
|
|
83
|
+
tokens → quota → done), text cert question (the loop streams), the
|
|
84
|
+
photo flow in the owner's order.
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.153",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|