import { describe, expect, it } from "vitest"; import { decodeConversationItem, parseEnvelopeJSON } from "@/runtime/protocol/lineup-v1"; import { InteractionKernel } from "@/runtime/coordination/interaction-kernel"; function envelope(overrides: Record = {}): string { return JSON.stringify({ v: 1, id: "evt_kernel_001", type: "lineup.v1.text", conversation_id: "conversation_kernel_test", sender: { kind: "agent", id: "agent_test" }, payload: { markdown: "# Hello\n\n**trusted**" }, ...overrides, }); } describe("InteractionKernel", () => { it("accepts a valid typed envelope and projects its trusted markdown item", () => { const kernel = new InteractionKernel(); const result = kernel.ingest({ raw: envelope(), source: "sync", transport_id: "41" }); expect(result.disposition).toBe("accepted"); expect(result.items).toEqual([expect.objectContaining({ kind: "markdown", id: "evt_kernel_001", markdown: "# Hello\n\n**trusted**", })]); expect(result.snapshot.seen_envelope_ids).toBe(1); }); it("rejects invalid protocol JSON while preserving legacy plain text as safe markdown", () => { const kernel = new InteractionKernel(); const invalidProtocol = parseEnvelopeJSON("{"); const legacyText = kernel.ingest({ raw: "{", source: "sync" }); const unknown = kernel.ingest({ raw: envelope({ id: "evt_kernel_unknown", type: "lineup.v1.unknown" }), source: "live", }); expect(invalidProtocol).toMatchObject({ ok: false, fallback: { code: "invalid_json" } }); expect(legacyText.items).toEqual([expect.objectContaining({ kind: "markdown", markdown: "{" })]); expect(unknown.items).toEqual([expect.objectContaining({ kind: "fallback", reason: "unsupported_type", id: "evt_kernel_unknown" })]); }); it("deduplicates one envelope id across sync and live transport sources", () => { const kernel = new InteractionKernel(); const first = kernel.ingest({ raw: envelope(), source: "sync" }); const duplicate = kernel.ingest({ raw: envelope(), source: "live" }); expect(first.disposition).toBe("accepted"); expect(duplicate).toMatchObject({ disposition: "duplicate", items: [] }); expect(duplicate.snapshot.seen_envelope_ids).toBe(1); }); it("projects the latest agent status by actor and retains a bounded dedupe set", () => { const kernel = new InteractionKernel(2); const thinking = kernel.ingest({ raw: envelope({ id: "evt_status_thinking", type: "lineup.v1.agent.status", payload: { status: "thinking", detail: "planning" } }), source: "sync", received_at: "2026-08-03T00:00:00.000Z", }); kernel.ingest({ raw: envelope({ id: "evt_other", payload: { markdown: "one" } }), source: "sync" }); kernel.ingest({ raw: envelope({ id: "evt_newer", payload: { markdown: "two" } }), source: "sync" }); expect(thinking.snapshot.agent_presence).toEqual([expect.objectContaining({ status: "thinking", detail: "planning", envelope_id: "evt_status_thinking", updated_at: "2026-08-03T00:00:00.000Z", })]); // The first id has expired from the bounded set and is accepted again. expect(kernel.ingest({ raw: envelope({ id: "evt_status_thinking" }), source: "live" }).disposition).toBe("accepted"); }); it("projects tool calls by call_id and applies a result only after submission", () => { const kernel = new InteractionKernel(); const call = kernel.ingest({ raw: envelope({ id: "evt_tool_call", type: "lineup.v1.tool.call", payload: { call_id: "call_kernel_001", tool: "choice", title: "Choose", prompt: "One", data: { action_group: { mode: "single-choice", actions: [{ id: "alpha", label: "Alpha" }] } } }, }), source: "sync", received_at: "2026-08-03T08:00:00.000Z", }); const duplicateCallID = kernel.ingest({ raw: envelope({ id: "evt_tool_call_duplicate_id", type: "lineup.v1.tool.call", payload: { call_id: "call_kernel_001", tool: "choice", title: "Ignored", prompt: "Ignored", data: { action_group: { mode: "button", actions: [{ id: "beta", label: "Beta" }] } } }, }), source: "live", }); const earlyResult = kernel.ingest({ raw: envelope({ id: "evt_tool_result_early", type: "lineup.v1.tool.result", payload: { call_id: "call_kernel_001", status: "completed", result: {} } }), source: "live", }); expect(call.snapshot.tool_calls).toEqual([expect.objectContaining({ call_id: "call_kernel_001", status: "pending" })]); expect(duplicateCallID.snapshot.tool_calls).toEqual([ expect.objectContaining({ request: expect.objectContaining({ title: "Choose" }) }), ]); expect(earlyResult.snapshot.tool_calls).toEqual([expect.objectContaining({ status: "pending" })]); expect(kernel.submitToolCall("call_kernel_001", "2026-08-03T08:01:00.000Z")).toMatchObject({ disposition: "accepted" }); const completed = kernel.ingest({ raw: envelope({ id: "evt_tool_result_completed", type: "lineup.v1.tool.result", payload: { call_id: "call_kernel_001", status: "completed", result: { selected: "alpha" } } }), source: "live", }); expect(completed.snapshot.tool_calls).toEqual([ expect.objectContaining({ call_id: "call_kernel_001", status: "completed", result: { selected: "alpha" } }), ]); }); it("keeps malformed tool payloads on the safe fallback path", () => { const kernel = new InteractionKernel(); const invalidCall = kernel.ingest({ raw: envelope({ id: "evt_invalid_tool_call", type: "lineup.v1.tool.call", payload: { call_id: "call_bad", tool: "shell", data: {} } }), source: "sync", }); const invalidResult = kernel.ingest({ raw: envelope({ id: "evt_invalid_tool_result", type: "lineup.v1.tool.result", payload: { call_id: "call_bad", status: "submitted", result: {} } }), source: "sync", }); expect(invalidCall.items).toEqual([expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })]); expect(invalidResult.items).toEqual([expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })]); }); it("accepts only a bounded, uniquely identified ActionGroup for choice calls", () => { const kernel = new InteractionKernel(); const accepted = kernel.ingest({ raw: envelope({ id: "evt_choice_group", type: "lineup.v1.tool.call", payload: { call_id: "call_choice_group", tool: "choice", title: "Pick deployment targets", prompt: "You may select multiple targets.", data: { action_group: { mode: "multi-choice", actions: [{ id: "staging", label: "Staging" }, { id: "production", label: "Production", description: "Requires approval" }] } }, }, }), source: "sync", }); const duplicateActionID = kernel.ingest({ raw: envelope({ id: "evt_choice_invalid_group", type: "lineup.v1.tool.call", payload: { call_id: "call_bad_group", tool: "choice", title: "Bad", prompt: "Bad", data: { action_group: { mode: "multi-choice", actions: [{ id: "same", label: "One" }, { id: "same", label: "Two" }] } } }, }), source: "sync", }); expect(accepted.items).toEqual([expect.objectContaining({ kind: "tool-call", call: expect.objectContaining({ action_group: { mode: "multi-choice", actions: [{ id: "staging", label: "Staging" }, { id: "production", label: "Production", description: "Requires approval" }] } }), })]); expect(duplicateActionID.items).toEqual([expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })]); }); it("accepts trusted confirm and input schemas while rejecting unsafe form fields", () => { const kernel = new InteractionKernel(); const confirm = kernel.ingest({ raw: envelope({ id: "evt_confirm", type: "lineup.v1.tool.call", payload: { call_id: "call_confirm", tool: "confirm", title: "Continue?", prompt: "This can be cancelled.", data: { confirm: { approve_label: "Continue", cancel_label: "Stop" } } } }), source: "sync", }); const form = kernel.ingest({ raw: envelope({ id: "evt_input", type: "lineup.v1.tool.call", payload: { call_id: "call_input", tool: "input", title: "Release", prompt: "Version and notes", data: { form: { fields: [{ id: "version", label: "Version", type: "text", required: true, pattern: "^v\\d+\\.\\d+\\.\\d+$" }, { id: "notes", label: "Notes", type: "textarea", max_length: 200 }], submit_label: "Create", cancel_label: "Cancel" } } } }), source: "sync", }); const invalid = kernel.ingest({ raw: envelope({ id: "evt_input_invalid", type: "lineup.v1.tool.call", payload: { call_id: "call_input_invalid", tool: "input", title: "Bad", prompt: "Bad", data: { form: { fields: [{ id: "bad", label: "Bad", type: "file" }] } } } }), source: "sync", }); expect(confirm.items).toEqual([expect.objectContaining({ kind: "tool-call", call: expect.objectContaining({ confirm: { approve_label: "Continue", cancel_label: "Stop" } }) })]); expect(form.items).toEqual([expect.objectContaining({ kind: "tool-call", call: expect.objectContaining({ form: expect.objectContaining({ fields: expect.arrayContaining([expect.objectContaining({ id: "version", required: true })]) }) }) })]); expect(invalid.items).toEqual([expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })]); }); it("aggregates structured task progress by operation_id and exposes a local cancellation request", () => { const kernel = new InteractionKernel(); const first = kernel.ingest({ raw: envelope({ id: "evt_task_first", type: "lineup.v1.agent.progress", payload: { operation_id: "task_kernel_001", title: "Build report", percent: 15, status: "running", cancellable: true } }), source: "sync", }); const update = kernel.ingest({ raw: envelope({ id: "evt_task_update", type: "lineup.v1.agent.progress", payload: { operation_id: "task_kernel_001", title: "Build report", percent: 65, status: "running", cancellable: true } }), source: "live", }); expect(first.snapshot.tasks).toEqual([expect.objectContaining({ operation_id: "task_kernel_001", percent: 15 })]); expect(update.snapshot.tasks).toEqual([expect.objectContaining({ operation_id: "task_kernel_001", percent: 65 })]); expect(kernel.requestTaskCancel("task_kernel_001", "2026-08-03T09:05:00.000Z")).toMatchObject({ disposition: "accepted" }); expect(kernel.snapshot().tasks).toEqual([expect.objectContaining({ cancel_requested_at: "2026-08-03T09:05:00.000Z" })]); }); it("admits only app identity and state for a Surface open, never an Agent-provided bundle", () => { const safe = decodeConversationItem(envelope({ id: "evt_surface_safe", type: "lineup.v1.ui.open", payload: { instance_id: "task:001", app: { app_id: "lineup.task-dashboard", version: "0.1.0" }, state: { title: "Build" } }, })); const injectedBundle = decodeConversationItem(envelope({ id: "evt_surface_bundle", type: "lineup.v1.ui.open", payload: { instance_id: "task:002", app: { app_id: "lineup.task-dashboard", version: "0.1.0" }, bundle_url: "https://example.invalid/app.js" }, })); const extraAppField = decodeConversationItem(envelope({ id: "evt_surface_extra_app", type: "lineup.v1.ui.open", payload: { instance_id: "task:003", app: { app_id: "lineup.task-dashboard", version: "0.1.0", source: "injected" } }, })); expect(safe).toEqual(expect.objectContaining({ kind: "surface", id: "evt_surface_safe" })); expect(injectedBundle).toEqual(expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })); expect(extraAppField).toEqual(expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })); }); it("requires a bounded reason, expiry and exact payload shape for app calls", () => { const valid = decodeConversationItem(envelope({ id: "evt_capability_valid", type: "lineup.v1.app.call", payload: { call_id: "cap_001", capability: "app.open_url", reason: "打开文档", expires_at: "2026-08-04T00:00:00.000Z", arguments: { url: "https://example.com" } }, })); const missingExpiry = decodeConversationItem(envelope({ id: "evt_capability_invalid", type: "lineup.v1.app.call", payload: { call_id: "cap_002", capability: "app.open_url", reason: "打开文档", arguments: { url: "https://example.com" } }, })); expect(valid).toEqual(expect.objectContaining({ kind: "app-call" })); expect(missingExpiry).toEqual(expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })); }); it("admits artifact offers as data but rejects undeclared control fields", () => { const safe = decodeConversationItem(envelope({ id: "evt_artifact_safe", type: "lineup.v1.artifact.offer", payload: { artifact_id: "report_001", name: "report.pdf", mime_type: "application/pdf", size_bytes: 42, integrity: "verified", created_at: "2026-08-03T00:00:00.000Z" }, })); const injected = decodeConversationItem(envelope({ id: "evt_artifact_injected", type: "lineup.v1.artifact.offer", payload: { artifact_id: "report_002", name: "report.pdf", mime_type: "application/pdf", size_bytes: 42, integrity: "verified", created_at: "2026-08-03T00:00:00.000Z", url: "https://bad.example" }, })); expect(safe).toEqual(expect.objectContaining({ kind: "artifact-offer" })); const content = decodeConversationItem(envelope({ id: "evt_artifact_content", type: "lineup.v1.artifact.offer", payload: { artifact_id: "report_003", name: "report.txt", mime_type: "text/plain", size_bytes: 5, integrity: "verified", created_at: "2026-08-03T00:00:00.000Z", local_ref: "artifact-cache-003", content_base64: "aGVsbG8=" }, })); expect(content).toEqual(expect.objectContaining({ kind: "artifact-offer" })); expect(injected).toEqual(expect.objectContaining({ kind: "fallback", reason: "invalid_payload" })); }); });