Wave D: native AgentEvent wire + client session rewrite (SDK purged)
Server: ui-stream.ts is verbatim pi AgentEvent passthrough (SSE data lines + [DONE]); only app-level events are the loop-level error and turn-settled terminal; onError carries raw provider text (owner ruling). Client: useChat + the AI-SDK transport replaced by components/session-core.ts (SessionModel: 409 identity-retry, optimistic c_ appends, absorbed() adoption, needsContinuation, shared consume for POST + reattach) and the session.ts hook; the golden-master grouping canon moved client-side into core/view.ts (projectView); scanners read the native record (phaseAt3Lh, danglingQuestionOf, graph toolParts, plan-blocks, runner, extraction). Coverage: the native message is the unit (fork 3) with the call+result inseparability bond rule; view-line-less messages (markers, error results) are invisible to coverage and never checkpointed. Deletes: chat-transport, projection, ui-message, their tests (ported to tests/session-core.test.ts), and the ai + @ai-sdk/react dependencies — the Vercel SDK is fully out of the tree. Wire pins in chat-flow rewritten onto the AgentEvent dialect (eventsOf parser). Gates: tsc clean, 994/994 tests, eslint clean, build green; live smoke on PORT=3004 (verbatim wire → native record).
This commit is contained in:
@@ -16,8 +16,7 @@
|
||||
*/
|
||||
|
||||
import type { PlanBlockData, PlanTree } from "./contracts.ts";
|
||||
import { derivePlanStatuses } from "./contracts.ts";
|
||||
import type { UIMessage } from "ai";
|
||||
import { derivePlanStatusesLh } from "./contracts.ts";
|
||||
import type { LhMessage } from "./native-messages.ts";
|
||||
import { newPlanBlockMessage } from "./native-messages.ts";
|
||||
import type { ToolResultMessage } from "@earendil-works/pi-ai";
|
||||
@@ -32,9 +31,11 @@ export interface PlanBlockPart {
|
||||
}
|
||||
|
||||
/** The snapshot payload (unchanged since wave 4): statuses derived AT
|
||||
* EMISSION time from the transcript — the block never re-derives. */
|
||||
function snapshot(tree: PlanTree, messages: readonly UIMessage[]): PlanBlockData {
|
||||
const statuses = derivePlanStatuses(tree, messages);
|
||||
* EMISSION time from the transcript — the block never re-derives. Wave D:
|
||||
* the derivation reads the NATIVE transcript (quiz CALLS only — results
|
||||
* feed nothing, contracts/plan.ts derivePlanStatusesLh). */
|
||||
function snapshot(tree: PlanTree, messages: readonly LhMessage[]): PlanBlockData {
|
||||
const statuses = derivePlanStatusesLh(tree, messages);
|
||||
return {
|
||||
kind: "full",
|
||||
at: new Date().toISOString(),
|
||||
@@ -68,14 +69,14 @@ export function emittedPlanBlockCalls(messages: readonly LhMessage[]): Set<strin
|
||||
* once; a later turn's rewrite gets its own block — the golden-master
|
||||
* rule the UIMessage-era attach had) that the record hasn't already
|
||||
* emitted. `tree` is the record's current tree (the plan tool saved it
|
||||
* during the turn); `transcript` is the full PROJECTED transcript the
|
||||
* status derivation reads.
|
||||
* during the turn); `transcript` is the full NATIVE transcript the status
|
||||
* derivation reads.
|
||||
*/
|
||||
export function planBlocksFor(
|
||||
record: readonly LhMessage[],
|
||||
newMessages: readonly LhMessage[],
|
||||
tree: PlanTree | null | undefined,
|
||||
transcript: readonly UIMessage[],
|
||||
transcript: readonly LhMessage[],
|
||||
): LhMessage[] {
|
||||
if (!tree || tree.nodes.length === 0) return [];
|
||||
const emitted = emittedPlanBlockCalls(record);
|
||||
|
||||
Reference in New Issue
Block a user