Skip to content

Conversation

@TonyMarkham
Copy link

Summary

This PR implements JSON Schema as the canonical source of truth for OpenCode's type definitions, addressing #6879.

72+ JSON Schema files now define all major type domains, with Zod validators auto-generated from them.

What's Included

Domain Schemas Key Types
Model 8 files ModelInfo, ModelCost, ModelCapabilities, ModelLimits
Provider 6 files ProviderInfo, ProviderOptions, ProviderSource
Auth 4 files Auth, ApiAuth, OAuth, WellKnownAuth
Session 10 files SessionInfo, SessionTime, SessionSummary, FileDiff
Message 20 files Message, UserMessage, AssistantMessage, all Part types, Error types
Tool 9 files ToolState, ToolPart, PermissionRequest, PermissionReply
Agent 2 files AgentInfo, AgentModel
Event 13 files Event, GlobalEvent, SessionStatus, all event types

Implementation

  1. Custom code generator (script/generate-from-schemas.ts)

    • Validates schemas with AJV
    • Generates Zod validators + TypeScript types
    • Handles cross-file $ref correctly (existing tools don't)
    • Integrated with bun run generate workflow
  2. Refactored source files to use generated validators:

    • provider.ts, message-v2.ts, permission/next.ts
    • agent/agent.ts, session/status.ts, server/server.ts
  3. Documentation in schema/README.md

Results

  • ✅ All 87 schemas validate
  • ✅ All 544 tests pass
  • ✅ TypeScript compilation passes
  • ✅ Build succeeds (11 platforms)
  • ✅ Runtime behavior unchanged

Benefits for External Clients

# Rust
typify schema/modelInfo.schema.json

# Python
datamodel-codegen --input schema/ --output opencode_types/

# C#
NJsonSchema.CodeGeneration schema/modelInfo.schema.json

Technical Notes

  • Generated files are gitignored (build artifacts)
  • Zod 4.x compatible
  • z.union()z.discriminatedUnion() where schema has discriminator (behavioral equivalence)

Closes #6879

@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2026

The following comment was made by an LLM, it may be inaccurate:

Search Results

I've completed a comprehensive search for duplicate or related PRs using multiple relevant keywords. Here's what I found:

✅ No Duplicate PRs Detected

The search returned only the current PR (6987) itself when looking for JSON Schema and type definition related content. The other results shown are unrelated PRs covering different features (telemetry, TUI configuration, IDE integration, etc.).

Key searches performed:

  • "JSON Schema type definitions" - Only returned current PR
  • "schema validation Zod validators" - No relevant results
  • "code generator schema" - Only returned current PR
  • "issue 6879" (the issue this PR closes) - No results

Conclusion: This appears to be a novel feature addition with no competing or overlapping PRs in the repository. You're safe to proceed with this PR.

- Create custom Zod validator generator with cross-file $ref support
- Add validation for 21 JSON Schema files using AJV
- Integrate schema generation into root script/generate.ts
- Configure TypeScript with @generated/* path alias
- Add schema/README.md documentation
- Generated validators output to packages/opencode/generated/ (gitignored)
- modelInfo: add missing fields (family, release_date, variants), fix 'limits' -> 'limit'
- modelCapabilities: add missing 'interleaved' field with union type
- providerInfo: add missing required fields (env, options)
- providerOptions: add additionalProperties:true, replace 'custom' with 'fetch'
- openaiOptions: fix metadata type to accept any (was string)
- Update comments for composition/API schemas
…SON Schema

- Import modelInfoSchema and providerInfoSchema from @generated/validators
- Delete ~84 lines of inline Zod definitions for Model and Info
- Maintain backwards compatibility (same export names)
- All 544 tests pass, typecheck passes, build succeeds

Part of JSON Schema as source of truth initiative (Session 2)
- Add working code generation examples for Rust (typify, schemafy),
  Python (datamodel-code-generator), and C# (NJsonSchema)
- Replace 'Coming soon' placeholders

Part of JSON Schema as source of truth initiative (Session 3)
- Create oauth.schema.json (OAuth with refresh/access tokens)
- Create apiAuth.schema.json (API key authentication)
- Create wellKnownAuth.schema.json (key + token pair)
- Create auth.schema.json (discriminated union of all auth types)
- Enhance generator to support JSON Schema const keyword (generates z.literal())
- All schemas validated and 544 tests pass

Part of JSON Schema as source of truth initiative
…rom JSON Schema

- Import authSchema, oauthSchema, apiAuthSchema, wellKnownAuthSchema from @generated/validators
- Delete ~33 lines of inline Zod definitions for Auth.Oauth, Auth.Api, Auth.WellKnown, Auth.Info
- Maintain backwards compatibility (same export names)
- All 544 tests pass, typecheck passes, build succeeds

Completes auth schema refactoring (Step 4.4) - JSON Schema is now single source of truth
- Create 10 session-related schemas (sessionInfo, sessionTime, sessionSummary,
  sessionShare, sessionRevert, sessionList, fileDiff, permissionAction,
  permissionRule, permissionRuleset)
- Add pattern constraint support to generator for ID prefix validation
- Refactor session/index.ts, permission/next.ts, snapshot/index.ts to use
  generated validators
- All tests pass (544), typecheck passes, build succeeds

Part of JSON Schema as source of truth initiative
- Create 17 new JSON Schema files for tool execution and permission types:
  - Tool states: toolStatePending, toolStateRunning, toolStateCompleted, toolStateError, toolState
  - Tool part: toolPart
  - File parts: filePart, filePartSource, fileSource, symbolSource, resourceSource, filePartSourceText
  - LSP types: lspPosition, lspRange
  - Permissions: permissionRequest, permissionReply, permissionToolContext

- Refactor TypeScript to use generated validators:
  - message-v2.ts: tool state and file part types now import from @generated/validators
  - permission/next.ts: Request and Reply now import from @generated/validators

- Enhance generator (generate-from-schemas.ts):
  - Add discriminatedUnion detection for oneOf with const discriminator
  - Add integer support (type: integer -> z.number().int())

All 544 tests pass, typecheck passes, build succeeds on 11 platforms.

Part of JSON Schema as source of truth initiative
- Create 20 JSON Schema files for message parts, messages, and errors
- Refactor message-v2.ts to use generated validators from @generated/validators
- Part types: textPart, reasoningPart, snapshotPart, patchPart, agentPart,
  compactionPart, subtaskPart, stepStartPart, stepFinishPart, retryPart, part
- Message types: userMessage, assistantMessage, message
- Error types: apiError, providerAuthError, unknownError, outputLengthError,
  abortedError, messageError
- All 544 tests pass, typecheck passes, build succeeds

Part of JSON Schema as source of truth initiative
- Create agentInfo.schema.json (13 fields matching Agent.Info)
- Create agentModel.schema.json (model selection nested object)
- Update generator to support minimum/maximum constraints
- Refactor agent.ts to use generated validators

Part of JSON Schema as source of truth initiative
- Add 13 event schemas: message events (updated, removed, part.updated, part.removed),
  session events (created, updated, deleted, status), permission events (asked, replied)
- Add sessionStatus schema for idle/retry/busy union type
- Add event.schema.json discriminated union aggregating all event types
- Add globalEvent.schema.json for SSE endpoint wrapper
- Refactor status.ts to use generated sessionStatusSchema
- Refactor server.ts to use generated eventSchema and globalEventSchema
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: JSON Schema as Source of Truth for API Contracts

2 participants