## Summary - Add `fusion-plugin-omp-runtime` so Fusion agents can run through operator-installed **Oh My Pi (`omp`)** over the [Agent Client Protocol](https://omp.sh/docs/acp) (`omp acp`). - Wire staged/bundled install, Settings → Authentication card (enable + binary path), model discovery (`omp models` → `omp-cli/*`), and MCP eligibility for runtime id `omp`. - Forward Fusion `systemPrompt` via ACP `session/new` `_meta.systemPromptOverride`. ## How operators use it 1. Install/auth `omp` (credentials under `~/.omp`). 2. Enable **Oh My Pi — via omp ACP** in Settings → Authentication (optional binary path). 3. Set agent **Runtime Source → OMP Runtime** (`runtimeHint: "omp"`), or pick an `omp-cli/*` model when enabled. ## Known v1 gaps - No Grok-style Fusion `fn_*` loopback tool bridge yet (operator MCP is forwarded; in-process custom tools are not). - Model is fixed at spawn (`omp --model … acp`); no mid-session Fusion model switch. ## Test plan - [x] `pnpm --filter @fusion-plugin-examples/omp-runtime test` (unit + live ACP when `omp` is on PATH) - [x] Auth routes: `POST /api/auth/omp-cli`, `GET /api/providers/omp-cli/status` - [x] Engine `runtimeSupportsMcp("omp")` - [ ] Manual: enable card in dashboard, select OMP runtime on an agent, run a short chat turn <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Oh My Pi (OMP) CLI support as an ACP-backed runtime and model provider, including model discovery and probing. * Added dashboard auth/status controls to enable OMP, check readiness, and configure the local binary path (with validation). * Exposed OMP custom `fn_*` tools via an MCP loopback bridge, plus optional filesystem capabilities and stricter tool permission gating. * **Documentation** * Added/expanded OMP runtime contract and integration docs (including the ACP session/handshake flow). * **Tests** * Added Vitest coverage for settings wiring, provider status, model discovery, runtime sessions, permissions, MCP bridging, and live connectivity. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
105 lines
3.6 KiB
TypeScript
105 lines
3.6 KiB
TypeScript
import { definePlugin } from "@fusion/plugin-sdk";
|
|
import type { FusionPlugin } from "@fusion/plugin-sdk";
|
|
import { killAllProcesses } from "./acp/index.js";
|
|
import { probeOmpBinary } from "./probe.js";
|
|
import { discoverOmpProviderModels } from "./provider.js";
|
|
import { OmpRuntimeAdapter } from "./runtime-adapter.js";
|
|
|
|
/*
|
|
FNXC:OmpAcp 2026-07-11-23:35:
|
|
OMP Runtime plugin — drive Oh My Pi (`omp`) as a Fusion agent runtime over the
|
|
Agent Client Protocol. Transport is `omp acp` (JSON-RPC/stdio). Mirrors the
|
|
landed Grok ACP runtime pattern (vendored ACP client under ./acp/) with
|
|
OMP-specific binary/args/auth (agent auth reuses ~/.omp).
|
|
|
|
This shells out to an operator-installed `omp` binary on PATH — Fusion does not
|
|
download or bundle it. Upstream: https://omp.sh/docs/acp
|
|
https://github.com/can1357/oh-my-pi
|
|
*/
|
|
|
|
// Reap OMP ACP agent subprocesses on hard process exit (registry SIGKILL is
|
|
// authoritative). Scoped to ACP-tracked agent children only — never port 4040.
|
|
process.on("exit", killAllProcesses);
|
|
|
|
const plugin: FusionPlugin = definePlugin({
|
|
manifest: {
|
|
id: "fusion-plugin-omp-runtime",
|
|
name: "OMP Runtime Plugin",
|
|
version: "0.1.0",
|
|
description: "Oh My Pi (omp) runtime support for Fusion via ACP (omp acp)",
|
|
author: "Fusion Team",
|
|
homepage: "https://omp.sh/docs/acp",
|
|
runtime: {
|
|
runtimeId: "omp",
|
|
name: "OMP Runtime",
|
|
version: "0.1.0",
|
|
description: "Drives the local `omp acp` Agent Client Protocol server",
|
|
},
|
|
},
|
|
state: "installed",
|
|
hooks: {
|
|
onLoad: (ctx) => {
|
|
ctx.logger.info(
|
|
"OMP Runtime Plugin loaded — transport=ACP (omp acp); probe uses omp --version",
|
|
);
|
|
},
|
|
},
|
|
runtime: {
|
|
metadata: {
|
|
runtimeId: "omp",
|
|
name: "OMP Runtime",
|
|
version: "0.1.0",
|
|
description: "Drives the local `omp acp` Agent Client Protocol server",
|
|
},
|
|
factory: async () => new OmpRuntimeAdapter(),
|
|
},
|
|
cliProviders: [
|
|
{
|
|
providerId: "omp-cli",
|
|
displayName: "Oh My Pi (omp)",
|
|
binaryName: "omp",
|
|
providerType: "cli",
|
|
statusRoute: "/providers/omp-cli/status",
|
|
authRoute: "/auth/omp-cli",
|
|
actions: [
|
|
{ actionId: "enable", label: "Enable", actionType: "enable", method: "POST", route: "/auth/omp-cli" },
|
|
{ actionId: "disable", label: "Disable", actionType: "disable", method: "POST", route: "/auth/omp-cli" },
|
|
{ actionId: "test", label: "Test", actionType: "test", method: "GET", route: "/providers/omp-cli/status" },
|
|
],
|
|
probe: async () => {
|
|
const status = await probeOmpBinary();
|
|
return {
|
|
available: status.available,
|
|
authenticated: status.authenticated,
|
|
binaryPath: status.binaryPath,
|
|
binaryName: status.binaryName,
|
|
version: status.version,
|
|
reason: status.reason,
|
|
};
|
|
},
|
|
discoverModels: discoverOmpProviderModels,
|
|
runtime: {
|
|
runtimeId: "omp",
|
|
createAdapter: async () => new OmpRuntimeAdapter(),
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
export default plugin;
|
|
export { probeOmpBinary } from "./probe.js";
|
|
export { discoverOmpProviderModels } from "./provider.js";
|
|
export { OmpRuntimeAdapter } from "./runtime-adapter.js";
|
|
export type { OmpBinaryStatus } from "./types.js";
|
|
export {
|
|
buildOmpAcpArgs,
|
|
buildOmpAcpRuntimeSettings,
|
|
OMP_ACP_ENV_ALLOWLIST,
|
|
modelForCli,
|
|
normalizeOmpCliModel,
|
|
resolveOmpAcpAuthPreferMethods,
|
|
} from "./acp-settings.js";
|
|
export { startFusionToolBridge, toolsToMcpToolDefs, FUSION_OMP_TOOL_BRIDGE_URL } from "./tool-bridge.js";
|
|
export { toAcpMcpServers } from "./mcp-forwarding.js";
|
|
export { buildOmpFusionToolRules } from "./runtime-adapter.js";
|