cc-libs/.plans/opencode-fake-provider-direct-plan.md
2026-06-12 00:20:57 +02:00

3.8 KiB

Plan: Direct Fake Provider Integration

Goal

Prove that a real opencode serve process can run with a deterministic fake provider/model and answer HTTP API requests without calling an external LLM.

This plan deliberately stops before CraftOS, the WebSocket bridge, or /programs/ai.lua. It validates only the opencode-side fixture that the full integration test will reuse.

Desired Boundary

Real:

  • opencode serve
  • opencode config validation and loading
  • opencode session/message HTTP endpoints
  • opencode model/provider selection
  • opencode agent/title/summary plumbing as far as it is triggered by simple messages

Fake:

  • The provider/model response behavior only

Proposed Test Fixture

Create a test-only temporary opencode workspace during the test. Do not modify the project .opencode/opencode.json for this.

Files generated under a temp directory:

  • opencode.json
  • fake-provider.ts or fake-provider.js
  • fake-responses.json

Example response mapping:

[
  { "match": "reply with exactly: pong", "reply": "pong" },
  { "match": "fresh start", "reply": "new reply" },
  { "match": "continue please", "reply": "plain reply" }
]

The fake provider should return the first response whose match appears in the final model prompt. Unknown prompts should return a deterministic fallback such as ok or unhandled fake prompt, not fail immediately, because opencode may issue title/summary/internal prompts.

Config Shape To Validate

Use the published schema as the source of truth before finalizing fields.

Candidate config:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "traptest/fake",
  "small_model": "traptest/fake",
  "enabled_providers": ["traptest"],
  "plugin": ["./fake-provider.ts"],
  "provider": {
    "traptest": {
      "name": "Trap Test",
      "models": {
        "fake": {
          "id": "fake",
          "name": "Trap Test Fake Model",
          "limit": { "context": 100000, "output": 10000 },
          "cost": { "input": 0, "output": 0 },
          "status": "active"
        }
      }
    }
  },
  "agent": {
    "build": { "model": "traptest/fake" },
    "title": { "model": "traptest/fake" },
    "summary": { "model": "traptest/fake" }
  }
}

Open question: the exact plugin provider hook shape must be verified against opencode's runtime/plugin API. Do not guess this implementation from the config schema alone.

Test Implementation

Add a Node integration test, likely under:

  • tools/mcp-bridge/test-integration/opencode-fake-provider.test.ts

Test steps:

  1. Create a temp directory.
  2. Write the test opencode.json.
  3. Write fake-responses.json.
  4. Write the fake provider plugin.
  5. Start opencode serve on 127.0.0.1 with a random free port.
  6. Wait for readiness by polling an HTTP endpoint such as GET /session.
  7. Call opencode HTTP directly:
    • POST /session
    • POST /session/:id/message with reply with exactly: pong
    • POST /session/:id/message with fresh start
  8. Assert the responses contain pong and new reply.
  9. Stop the opencode process and clean up the temp directory.

Useful Assertions

  • opencode serve starts successfully with the generated config.
  • POST /session returns a usable session ID.
  • POST /session/:id/message returns text from the fake mapping.
  • Unknown/internal prompts do not break the test fixture.
  • No external provider credentials are required.

Result To Capture For Plan 2

After this plan is run, record:

  • Exact working fake provider plugin API shape.
  • Exact command/env used to start opencode serve reliably.
  • Confirmed readiness endpoint and polling logic.
  • Whether title/summary/internal model calls happen during simple message requests.
  • Any required config fields not listed above.

Plan 2 should be updated with these facts before implementation.