feat(iteration): implement sdk v1 miniapp runtime loop

This commit is contained in:
2026-08-05 18:30:29 +08:00
parent 486280bec0
commit d2a2fd0aff
37 changed files with 2135 additions and 60 deletions
@@ -0,0 +1,22 @@
import { describe, expect, it } from "vitest";
import { MiniAppToolStateMachine } from "@/runtime/coordination/miniapp-tool-state";
describe("MiniAppToolStateMachine", () => {
it("moves a call through claim and submitted result, while rejecting duplicate terminal writes", () => {
const machine = new MiniAppToolStateMachine();
machine.receive({ call_id: "call-1", tool_id: "task.create", inventory_revision: "catalog-1", app_scope: "task-dashboard", instance_id: "task:1", conversation_id: "c", input: {}, created_at: "2026-08-04T00:00:00.000Z" });
expect(machine.route("call-1", "task:1", "2026-08-04T00:00:01.000Z")).toMatchObject({ disposition: "accepted", record: { status: "waiting_for_app" } });
expect(machine.start("call-1", "task:1", "2026-08-04T00:00:02.000Z")).toMatchObject({ disposition: "accepted", record: { status: "running" } });
expect(machine.submit("call-1", "task:1", { task_id: "t1" }, "2026-08-04T00:00:03.000Z")).toMatchObject({ disposition: "accepted", record: { status: "submitted" } });
expect(machine.submit("call-1", "task:1", { task_id: "t2" }, "2026-08-04T00:00:04.000Z")).toMatchObject({ disposition: "invalid_transition", record: { status: "submitted" } });
expect(machine.complete("call-1", "2026-08-04T00:00:05.000Z")).toMatchObject({ disposition: "accepted", record: { status: "completed" } });
});
it("cancels only the instance that owns a pending call", () => {
const machine = new MiniAppToolStateMachine();
machine.receive({ call_id: "call-2", tool_id: "task.create", inventory_revision: "catalog-1", app_scope: "task-dashboard", instance_id: "task:1", conversation_id: "c", input: {}, created_at: "2026-08-04T00:00:00.000Z" });
machine.route("call-2", "task:1", "2026-08-04T00:00:01.000Z");
expect(machine.cancel("call-2", "task:2", "app_closed", "2026-08-04T00:00:02.000Z")).toEqual(expect.objectContaining({ disposition: "invalid_scope" }));
expect(machine.cancel("call-2", "task:1", "app_closed", "2026-08-04T00:00:02.000Z")).toMatchObject({ disposition: "accepted", record: { status: "cancelled", cancel_reason: "app_closed" } });
});
});