Skip to content

Instantly share code, notes, and snippets.

@cameroncking
Created February 12, 2026 06:50
Show Gist options
  • Select an option

  • Save cameroncking/848fa78054993762cda96e8e24048162 to your computer and use it in GitHub Desktop.

Select an option

Save cameroncking/848fa78054993762cda96e8e24048162 to your computer and use it in GitHub Desktop.
Easily debug OpenCode system prompts
// .opencode/plugins/log-system-prompts.js
// log system prompts to .opencode/system-prompts.jsonl
//
// This makes it easier to directly investigate how OpenCode constructs
// system prompts and what environment data is being provided to the model.
// This does not include tool call schema information.
//
import fs from "fs/promises"
import path from "path"
export const LogSystemPrompts = async ({ worktree, client }) => {
const outPath = path.join(worktree, ".opencode", "system-prompts.jsonl")
// We don't get message metadata in `experimental.chat.system.transform`, so we
// capture the latest system array per session and then log it in `chat.params`.
/** @type {Map<string, { at: number, system: string[] }>} */
const lastSystemBySession = new Map()
async function append(line) {
try {
await fs.appendFile(outPath, line + "\n", "utf8")
} catch (err) {
// Avoid crashing the whole session if logging fails.
try {
const message = err instanceof Error ? err.message : String(err)
await client.app.log({
body: {
service: "log-system-prompts",
level: "error",
message: `Failed to append to ${outPath}: ${message}`,
},
})
} catch {
// ignore
}
}
}
return {
"experimental.chat.system.transform": async (input, output) => {
const sessionID = input?.sessionID ?? ""
if (!sessionID) return
const system = Array.isArray(output?.system) ? output.system.map(String) : []
lastSystemBySession.set(sessionID, { at: Date.now(), system })
},
"chat.params": async (input, output) => {
const sessionID = input?.sessionID ?? ""
if (!sessionID) return
const sys = lastSystemBySession.get(sessionID)
// In case hooks fire in an unexpected order, still log what we can.
const system = sys?.system ?? []
const systemAgeMs = sys ? Date.now() - sys.at : null
const payload = {
at: new Date().toISOString(),
outPath,
sessionID,
agent: input?.agent?.name ?? input?.agent?.mode ?? null,
model: {
providerID: input?.model?.providerID ?? null,
modelID: input?.model?.id ?? input?.model?.modelID ?? null,
},
provider: {
id: input?.provider?.id ?? null,
name: input?.provider?.name ?? null,
},
message: {
id: input?.message?.id ?? null,
},
system,
systemAgeMs,
// OpenAI OAuth (Codex) uses `options.instructions` (not a system message).
requestInstructions:
output?.options && typeof output.options.instructions === "string" ? output.options.instructions : null,
}
await append(JSON.stringify(payload))
},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment