122 lines
3.8 KiB
Markdown
122 lines
3.8 KiB
Markdown
# 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:
|
|
|
|
```json
|
|
[
|
|
{ "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:
|
|
|
|
```json
|
|
{
|
|
"$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.
|