import type { DriverTarget } from "@skaile/workspaces/plugin-registry"; import type { ModelEntry } from "../models.js"; import { type AgentConfig, AgentDriver, type DriverInfo } from "../types.js"; /** * Credential and routing env vars forwarded to the omp child process. * * omp is model-agnostic — it selects a provider from whichever of these it * finds. Forwarding only `ANTHROPIC_API_KEY`, as this allowlist used to, * silently reduced every non-Anthropic workspace to a fallback: the child had * no credential for the provider it was configured for and no way to say so. * It also omitted `ANTHROPIC_BASE_URL`, so an Anthropic-compatible gateway was * bypassed and traffic went to Anthropic's own API instead. * * The list mirrors the "Environment Variables" section of `omp --help`, which * is the authoritative statement of what the child actually reads. Widening it * is deliberate: these names *are* the provider credentials, so a host that * sets one in the runner's environment is asking for the agent to use it. Vars * outside this list — anything a platform provisions under its own naming — * still do not reach the child. * * @docLink packages/bridge/concepts#omp-env-whitelist */ export declare const OMP_PROVIDER_ENV_KEYS: readonly ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "ANTHROPIC_CUSTOM_HEADERS", "ANTHROPIC_FOUNDRY_API_KEY", "FOUNDRY_BASE_URL", "CLAUDE_CODE_USE_FOUNDRY", "CLAUDE_CODE_CLIENT_CERT", "CLAUDE_CODE_CLIENT_KEY", "NODE_EXTRA_CA_CERTS", "OPENAI_API_KEY", "OPENAI_BASE_URL", "GEMINI_API_KEY", "COPILOT_GITHUB_TOKEN", "AZURE_OPENAI_API_KEY", "GROQ_API_KEY", "CEREBRAS_API_KEY", "XAI_API_KEY", "MISTRAL_API_KEY", "ZAI_API_KEY", "MINIMAX_API_KEY", "DEEPSEEK_API_KEY", "OPENROUTER_API_KEY", "KILO_API_KEY", "AI_GATEWAY_API_KEY", "OPENCODE_API_KEY", "CURSOR_ACCESS_TOKEN", "CLINE_API_KEY", "WAFER_SERVERLESS_API_KEY", "YOLO_AUTO_API_KEY", "ABLITERATION_API_KEY", "UMANS_AI_CODING_PLAN_API_KEY", "UMANS_WEBSEARCH_PROVIDER", "AWS_PROFILE", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_REGION", "AWS_DEFAULT_REGION", "GOOGLE_CLOUD_PROJECT", "GOOGLE_CLOUD_LOCATION", "GOOGLE_APPLICATION_CREDENTIALS", "EXA_API_KEY", "BRAVE_API_KEY", "PERPLEXITY_API_KEY", "PERPLEXITY_COOKIES", "TAVILY_API_KEY", "TINYFISH_API_KEY", "FIRECRAWL_API_KEY", "ANTHROPIC_SEARCH_API_KEY", "ANTHROPIC_SEARCH_BASE_URL", "OMP_PROFILE"]; /** * Build the explicit env allowlist forwarded to the omp child process. * * The runner's full environment is never inherited — only * {@link OMP_BASE_ENV_KEYS} (process essentials), * {@link OMP_PROVIDER_ENV_KEYS} (provider credentials and routing), and the * `PI_*` prefix (omp's own app config the host operator may have set). * * Test seams (`OMP_BRIDGE_*`, `FAKE_OMP_*`) are passed through so the * subprocess harness in `tests/omp-driver.test.ts` can drive a fake-omp * script via env-driven mode flags. * * @docLink packages/bridge/concepts#omp-env-whitelist */ export declare function buildOmpChildEnv(parent: NodeJS.ProcessEnv): Record; /** * omp's built-in tools, as reported by `omp --help` ("Available Tools"). * * `computer` is the one entry omp does not enable by default; everything else * is on unless `--tools` narrows the set. Used to turn a manifest *deny* list * into the *allow* list omp's CLI actually accepts. */ export declare const OMP_BUILTIN_TOOLS: readonly ["read", "bash", "edit", "write", "grep", "glob", "lsp", "python", "notebook", "browser", "computer", "task", "todo", "web_search", "ask"]; /** omp's default-enabled toolset — every built-in except `computer`. */ export declare const OMP_DEFAULT_TOOLS: readonly string[]; /** * Resolve `AgentConfig.tools` into the omp CLI flags that enforce it. * * omp expresses tool restriction as a positive `--tools a,b,c` list (or * `--no-tools`) — there is no deny flag — so a manifest deny list is applied by * subtracting from {@link OMP_DEFAULT_TOOLS}. * * Returns `[]` when the manifest declares no restriction, which leaves omp on * its full default toolset exactly as before. That default toolset is the bulk * of every request's fixed token prefix, so this is the lever an agent * definition needs in order to shrink it. * * Pure — exported for direct testing. * * @since 1.5.0 */ export declare function buildOmpToolArgs(tools: AgentConfig["tools"]): string[]; /** * Agent driver for the oh-my-pi (omp) coding agent. * * Spawns `omp --mode rpc` as a child process and communicates via newline-delimited * JSON-RPC over stdin/stdout. Model-agnostic: supports any LLM provider. * * @see https://github.com/can1357/oh-my-pi * * @remarks * **Session persistence** — omp writes JSONL session files to `/.omp/sessions/` * (via `--session-dir`). After each turn (`agent_end`), sends a `get_state` RPC to * capture the native session ID and emits a `session_info` event so the forge layer * can persist it. On the next spawn, callers pass `resumeSessionId` to restore omp's * native context. * * **stderrBuffer** — collects the last 20 lines of stderr so they can be appended to * crash error messages for diagnostics without blocking the stdout readline loop. * * **systemPrompt injection** — omp does not accept a system prompt string directly. * The driver writes `AgentConfig.systemPrompt` to `/.omp/system.md` and passes * the path via `--append-system-prompt` before spawning. * * **agentDir** — maps to the `PI_CODING_AGENT_DIR` environment variable. omp reads the * GitAgent directory at this path natively (agent.yaml, SOUL.md, RULES.md, knowledge/). * * @docLink packages/bridge/drivers#omp-driver */ export declare class OmpDriver extends AgentDriver { readonly driverInfo: DriverInfo; private readonly log; private proc; private rl; private reqId; private config; private ready; private startPromise; private stderrBuffer; private prevText; /** OMP session ID captured via `get_state` after each turn. */ private _ompSessionId?; /** Per-turn settlement handlers; non-null only while a prompt is in flight. */ private turnResolve; private turnReject; get runtimeSessionId(): string | undefined; getModel(): string | undefined; /** * @param config - Driver configuration. omp-relevant fields: * - `cwd` — working directory; omp session files are stored under `/.omp/sessions/`. * - `model` / `provider` — forwarded as `--model [provider/]model`. * - `systemPrompt` — written to `/.omp/system.md` and appended via `--append-system-prompt`. * - `agentDir` — sets `PI_CODING_AGENT_DIR`; omp reads agent identity from this directory. * - `sshKeyPath` — injected as `GIT_SSH_COMMAND` for authenticated git operations. * - `resumeSessionId` — omp session UUID to restore via `--session `. */ constructor(config: AgentConfig); start(): Promise; private _start; private extractMessageText; private handleEvent; /** * Resolve the in-flight prompt turn (on `agent_end`). Idempotent — a turn * settles at most once, so a stray second `agent_end` is harmless. */ private resolveTurn; /** * Reject the in-flight prompt turn (process crash/error). Settling here keeps * `prompt()` from hanging forever when the child dies before `agent_end`. */ private rejectTurn; /** * Query OMP for the current session ID via `get_state` RPC. * Emits a `session_info` event on success so the forge layer can persist the ID. * Failures are silently swallowed — session tracking is best-effort. */ private captureSessionId; private nextId; private send; /** * Sends a prompt to the omp process via JSON-RPC and resolves when the turn * completes (after the `agent_end` event), honoring the `AgentDriver.prompt` * contract so driver-agnostic callers can await turn completion uniformly. * * The driver emits `agent-event` payloads as omp streams responses on stdout. * If the child process errors or exits before `agent_end`, the returned promise * rejects rather than hanging. * * @param message - Plain-text user prompt. * @throws {Error} When the omp process is not running, its stdin is closed, or * the child crashes/exits before the turn completes. */ prompt(message: string): Promise; /** * Sends an in-band abort RPC to the omp process, requesting it to stop the * current turn without terminating the child process. * * @remarks This is a best-effort signal — omp may not honour the abort * immediately. The process remains alive after `abort()`. */ abort(): Promise; /** `true` when the omp child process is alive and has not been killed. */ get isRunning(): boolean; /** * Sends SIGTERM to the omp child process and performs cleanup. * * The driver instance must not be reused after `kill()`. Create a new * `OmpDriver` to start a fresh session. */ kill(): void; resetSession(): Promise; private classifyProcessError; private classifyErrorMessage; listModels(): Promise; private cleanup; } /** * `DriverTarget` wrapper for the omp driver. Registered into the plugin * registry by `registerBuiltinDrivers()`. */ export declare const ompDriverTarget: DriverTarget; //# sourceMappingURL=omp.d.ts.map