mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-31 11:00:34 +00:00
## Summary - Recommend and pin OpenCode **2.0.29** (`@opencode/client`, `@opencode/plugin`); the technical minimum stays **2.0.27** since 2.0.28/2.0.29 keep Effect 4.0.1. - Add 2.0.29 as a reviewed contract profile beside 2.0.27; 2.0.28 and future/custom labels keep authenticated negotiation. - Test fixture only: the recurring Missions host declares the `credential` domain that the 2.0.29 Promise adapter reads eagerly (the managed owner spreads `ctx`, dropping the Proxy fallback). No product code change. - Two new isolated fixtures for upstream behavior changes: bounded output-length continuation, and rejected Promise tools / native denial. - Compatibility docs, CONTRIBUTING, AGENTS and architecture guide updated. ## Upstream review - OpenAPI: same 118 paths; additive schema changes (config `policies`, provider/model `compatibility`, `encoding`). - Private LocationServiceMap/Form/Permission/queue contracts used by the pending snapshot: unchanged. - Effect stays 4.0.1. ## Validation (Windows, isolated CLIs/databases, never the shared daemon) - 2.0.29: plugin runtime, automation, pruning/history/proxy, Missions contract/family control/full journey, session environment, fork, aside, prompt skills, Git degraded/init, provider usage/accounts, temporary workspaces, blank-session cleanup, output-limit continuation, Promise tool failure, system settings discovery, native upgrade 2.0.15→2.0.29. - 2.0.27 (minimum): plugin runtime, automation, pruning, Missions contract/family, session environment, fork, aside, prompt skills, blank cleanup. - Server: 2235 passed / 7 skipped / 0 failed. UI: 1524 passed. Tauri crate 268/268, updater handoff 1/1, UI updater flow 13/13 (dev base includes #786). ## Known, not caused by this change `scripts/test-permission-receipts-native.mjs` times out identically on 2.0.27 with the previous pins; tracked separately.
34 lines
2.1 KiB
JavaScript
34 lines
2.1 KiB
JavaScript
// Real isolated runtime and loopback provider; exercise the native bounded continuation policy.
|
|
import assert from "node:assert/strict"
|
|
import { mkdir, writeFile } from "node:fs/promises"
|
|
import path from "node:path"
|
|
import { withProductRuntime } from "./native-product-fixture.mjs"
|
|
|
|
await withProductRuntime(process.argv[2], async ({ root }) => {
|
|
const plugin = path.join(root, "output-limit-fixture")
|
|
await mkdir(plugin)
|
|
await writeFile(path.join(plugin, "index.ts"), `export default { id: "output-limit-fixture", async setup(ctx) {
|
|
await ctx.session.hook("http.response", async event => {
|
|
if (event.kind !== "primary") return
|
|
const text = await event.response.text()
|
|
event.response = new Response(text.replaceAll('"finish_reason":"stop"', '"finish_reason":"length"'), {
|
|
status: event.response.status, headers: { "content-type": "text/event-stream" },
|
|
})
|
|
})
|
|
} }`)
|
|
return { plugins: [plugin] }
|
|
}, async ({ client, root }) => {
|
|
const session = await client.session.create({ location: { directory: root } })
|
|
await client.session.prompt({ sessionID: session.id, text: "Return only the synthetic fixture answer." })
|
|
await client.session.wait({ sessionID: session.id })
|
|
const messages = (await client.message.list({ sessionID: session.id, order: "asc", limit: 100 })).data
|
|
const assistants = messages.filter(message => message.type === "assistant")
|
|
assert.equal(assistants.length, 3, "Native continuation must stop after two output-limit continuations")
|
|
assert(assistants.every(message => message.finish === "length"))
|
|
assert.equal(messages.filter(message => message.type === "user").length, 1, "The user prompt must not be replayed")
|
|
const idle = messages.filter(message => message.type === "idle").at(-1)
|
|
assert.equal(idle?.outcome, "failed", "Exhausted continuation must become a durable native failure")
|
|
const state = (await client.session.active())[session.id]
|
|
assert.equal(state, undefined, "Output-limit failure must not leave the session active")
|
|
console.log("PASS: native length recovery is bounded, preserves a single user prompt and settles failed/idle")
|
|
})
|