contract-identity.test.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { expect, test } from "bun:test"
  2. import { Schema } from "effect"
  3. import { AgentV2 } from "@opencode-ai/core/agent"
  4. import { Location as CoreLocation } from "@opencode-ai/core/location"
  5. import { ModelV2 } from "@opencode-ai/core/model"
  6. import { SessionV2 } from "@opencode-ai/core/session"
  7. import { SessionInput as CoreSessionInput } from "@opencode-ai/core/session/input"
  8. import { SessionMessage as CoreSessionMessage } from "@opencode-ai/core/session/message"
  9. import { Prompt as CorePrompt } from "@opencode-ai/core/session/prompt"
  10. import { Agent } from "@opencode-ai/schema/agent"
  11. import { Location } from "@opencode-ai/schema/location"
  12. import { Model } from "@opencode-ai/schema/model"
  13. import { Project } from "@opencode-ai/schema/project"
  14. import { Provider } from "@opencode-ai/schema/provider"
  15. import { Prompt } from "@opencode-ai/schema/prompt"
  16. import { Session } from "@opencode-ai/schema/session"
  17. import { SessionInput } from "@opencode-ai/schema/session-input"
  18. import { SessionMessage } from "@opencode-ai/schema/session-message"
  19. import { Workspace } from "@opencode-ai/schema/workspace"
  20. import { Api } from "@opencode-ai/server/api"
  21. import { compile, emitPromise } from "@opencode-ai/httpapi-codegen"
  22. import { HttpApi } from "effect/unstable/httpapi"
  23. import { SessionGroup } from "../src/contract"
  24. test("Core and Server reuse the authoritative Schema and Protocol values", () => {
  25. expect(AgentV2.ID).toBe(Agent.ID)
  26. expect(CoreLocation.Ref).toBe(Location.Ref)
  27. expect(ModelV2.Ref).toBe(Model.Ref)
  28. expect(SessionV2.Info).toBe(Session.Info)
  29. expect(CoreSessionInput.Admitted).toBe(SessionInput.Admitted)
  30. expect(CoreSessionMessage.Message).toBe(SessionMessage.Message)
  31. expect(CorePrompt).toBe(Prompt)
  32. expect(Api.groups["server.session"].identifier).toBe("server.session")
  33. expect(SessionGroup.identifier).toBe(Api.groups["server.session"].identifier)
  34. expect(Session.ID.create()).toStartWith("ses_")
  35. expect(Project.ID.global).toBe("global")
  36. expect(Provider.ID.anthropic).toBe("anthropic")
  37. expect(Workspace.ID.create()).toStartWith("wrk_")
  38. })
  39. test("client and Server Session contracts generate identically", () => {
  40. const options = { groupNames: { "server.session": "sessions" } }
  41. const server = compile(HttpApi.make("server").add(Api.groups["server.session"]), options)
  42. const client = compile(HttpApi.make("client").add(SessionGroup), options)
  43. expect(emitPromise(client)).toEqual(emitPromise(server))
  44. })
  45. test("shared DTO schemas construct and decode plain objects", () => {
  46. const made = Prompt.make({ text: "hello" })
  47. const decoded = Schema.decodeUnknownSync(Prompt)({ text: "hello" })
  48. const content = Schema.decodeUnknownSync(SessionMessage.AssistantText)({ type: "text", id: "part_1", text: "hi" })
  49. expect(Object.getPrototypeOf(made)).toBe(Object.prototype)
  50. expect(Object.getPrototypeOf(decoded)).toBe(Object.prototype)
  51. expect(Object.getPrototypeOf(content)).toBe(Object.prototype)
  52. expect(Prompt.ast.annotations?.identifier).toBe("Prompt")
  53. expect(SessionMessage.AssistantText.ast.annotations?.identifier).toBe("Session.Message.Assistant.Text")
  54. expect(CoreSessionMessage.AssistantText).toBe(SessionMessage.AssistantText)
  55. })