diff --git a/package-lock.json b/package-lock.json index 58108b9..e216737 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@farhoodliquor/paperclip-adapter-opencode-k8s", - "version": "0.1.13", + "version": "0.1.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@farhoodliquor/paperclip-adapter-opencode-k8s", - "version": "0.1.13", + "version": "0.1.14", "license": "MIT", "dependencies": { "@kubernetes/client-node": "^1.0.0" @@ -18,7 +18,7 @@ "vitest": "^4.1.4" }, "peerDependencies": { - "@paperclipai/adapter-utils": ">=0.3.0" + "@paperclipai/adapter-utils": ">=0.3.1" } }, "node_modules/@emnapi/core": { diff --git a/package.json b/package.json index d6bd603..eb4afd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@farhoodliquor/paperclip-adapter-opencode-k8s", - "version": "0.1.13", + "version": "0.1.14", "description": "Paperclip adapter plugin that runs OpenCode agents as Kubernetes Jobs", "license": "MIT", "type": "module", @@ -26,7 +26,7 @@ "@kubernetes/client-node": "^1.0.0" }, "peerDependencies": { - "@paperclipai/adapter-utils": ">=0.3.0" + "@paperclipai/adapter-utils": ">=0.3.1" }, "devDependencies": { "@paperclipai/adapter-utils": "^2026.411.0-canary.8", diff --git a/src/server/execute.ts b/src/server/execute.ts index 7569c9e..1b5f6e2 100644 --- a/src/server/execute.ts +++ b/src/server/execute.ts @@ -1,12 +1,6 @@ import type { AdapterExecutionContext, AdapterExecutionResult } from "@paperclipai/adapter-utils"; +import { inferOpenAiCompatibleBiller, redactHomePathUserSegments } from "@paperclipai/adapter-utils"; import { asString, asNumber, asBoolean, parseObject } from "@paperclipai/adapter-utils/server-utils"; - -function inferOpenAiCompatibleBiller(env: Record, _fallback: string | null): string | null { - if (env.OPENROUTER_API_KEY) return "openrouter"; - if (env.OPENAI_BASE_URL?.includes("openrouter")) return "openrouter"; - if (env.OPENAI_API_KEY) return "openai"; - return null; -} import { parseOpenCodeJsonl, isOpenCodeUnknownSessionError, @@ -137,7 +131,7 @@ async function streamPodLogs( const writable = new Writable({ write(chunk: Buffer, _encoding, callback) { - const text = chunk.toString("utf-8"); + const text = redactHomePathUserSegments(chunk.toString("utf-8")); chunks.push(text); void onLog("stdout", text).then(() => callback(), callback); }, @@ -398,13 +392,7 @@ export async function execute(ctx: AdapterExecutionContext): Promise = {}; - for (const key of ["OPENAI_API_KEY", "OPENAI_BASE_URL", "OPENROUTER_API_KEY"]) { - const val = process.env[key]; - if (val) billerEnv[key] = val; - } - const biller = inferOpenAiCompatibleBiller(billerEnv, null) ?? provider ?? "unknown"; + const biller = inferOpenAiCompatibleBiller(process.env, null) ?? provider ?? "unknown"; const parsedError = typeof parsed.errorMessage === "string" ? parsed.errorMessage.trim() : ""; const rawExitCode = exitCode; diff --git a/src/server/index.ts b/src/server/index.ts index 11c84d7..db63166 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,4 +1,5 @@ import type { ServerAdapterModule } from "@paperclipai/adapter-utils"; +import { getAdapterSessionManagement } from "@paperclipai/adapter-utils"; import { type, models, agentConfigurationDoc } from "../index.js"; import { execute } from "./execute.js"; import { testEnvironment } from "./test.js"; @@ -15,6 +16,16 @@ export function createServerAdapter(): ServerAdapterModule { supportsLocalAgentJwt: true, agentConfigurationDoc, getConfigSchema, + sessionManagement: getAdapterSessionManagement("opencode_local") ?? { + supportsSessionResume: true, + nativeContextManagement: "unknown", + defaultSessionCompaction: { + enabled: true, + maxSessionRuns: 20, + maxRawInputTokens: 500_000, + maxSessionAgeHours: 24, + }, + }, }; } diff --git a/src/server/job-manifest.ts b/src/server/job-manifest.ts index 0276b1b..dfe2ec5 100644 --- a/src/server/job-manifest.ts +++ b/src/server/job-manifest.ts @@ -8,39 +8,10 @@ import { parseObject, buildPaperclipEnv, renderTemplate, + joinPromptSections, + stringifyPaperclipWakePayload, + renderPaperclipWakePrompt, } from "@paperclipai/adapter-utils/server-utils"; - -function joinPromptSections(sections: string[], separator = "\n\n"): string { - return sections.filter((s) => s.trim().length > 0).join(separator); -} - -function stringifyPaperclipWakePayload(wake: unknown): string | null { - if (!wake || typeof wake !== "object") return null; - try { - const json = JSON.stringify(wake); - return json === "{}" ? null : json; - } catch { - return null; - } -} - -function renderPaperclipWakePrompt(wake: unknown, _opts?: { resumedSession?: boolean }): string { - if (!wake || typeof wake !== "object") return ""; - const w = wake as Record; - const reason = typeof w.reason === "string" ? w.reason.trim() : ""; - const comments = Array.isArray(w.comments) ? w.comments : []; - if (!reason && comments.length === 0) return ""; - const parts: string[] = []; - if (reason) parts.push(`Wake reason: ${reason}`); - for (const c of comments) { - if (typeof c === "object" && c !== null) { - const comment = c as Record; - const body = typeof comment.body === "string" ? comment.body.trim() : ""; - if (body) parts.push(`Comment: ${body}`); - } - } - return parts.join("\n\n"); -} import type { SelfPodInfo } from "./k8s-client.js"; export interface JobBuildInput {