fix(omp): expose injected Paseo tools directly (#2418)
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ Pi import discovery reads Pi's persisted JSONL session files because Pi RPC does
|
|||||||
|
|
||||||
OMP is a first-class built-in provider, disabled by default. Its launch contract, typed runtime, agent/session behavior, history, permissions, imports, and test fake live under `providers/omp/`; only the provider-neutral JSONL child-process transport is shared with Pi. It launches `omp --mode rpc-ui`, uses OMP's `get_available_commands` RPC for slash-command discovery, bridges OMP `rpc-ui` approval dialogs into Paseo permissions, and imports terminal-started sessions from `~/.omp/agent/sessions` when enabled.
|
OMP is a first-class built-in provider, disabled by default. Its launch contract, typed runtime, agent/session behavior, history, permissions, imports, and test fake live under `providers/omp/`; only the provider-neutral JSONL child-process transport is shared with Pi. It launches `omp --mode rpc-ui`, uses OMP's `get_available_commands` RPC for slash-command discovery, bridges OMP `rpc-ui` approval dialogs into Paseo permissions, and imports terminal-started sessions from `~/.omp/agent/sessions` when enabled.
|
||||||
|
|
||||||
OMP supports native Paseo host tools. The adapter registers the caller-scoped Paseo tool catalog directly with OMP, so `create_agent`, `send_agent_prompt`, `wait_for_agent`, and related tools do not need the internal MCP fallback. OMP's provider-managed task subagents are surfaced as Paseo subagents through `child_session` imports; the parent keeps the subagents track while the child runtime stays owned by OMP. Custom OMP profiles should extend `omp`; other Pi-compatible forks can still extend `pi`, override `command`, and set `params.sessionDir` to their JSONL session directory.
|
OMP supports native Paseo host tools. The adapter registers the full caller-scoped Paseo tool catalog directly with OMP, matching providers such as Claude that expose the full catalog through MCP. Serialize every OMP host definition with `loadMode: "essential"` so `create_agent`, `send_agent_prompt`, `wait_for_agent`, and related tools remain direct calls; omitting the field makes OMP mount non-built-in names under `xd://` instead. OMP's provider-managed task subagents are surfaced as Paseo subagents through `child_session` imports; the parent keeps the subagents track while the child runtime stays owned by OMP. Custom OMP profiles should extend `omp`; other Pi-compatible forks can still extend `pi`, override `command`, and set `params.sessionDir` to their JSONL session directory.
|
||||||
|
|
||||||
Pi RPC extension UI dialog requests (`select`, `input`, `editor`, `confirm`) are bridged into Paseo question permissions and answered with `extension_ui_response`. Pi extensions such as `ask_user` may chain dialogs: for example, a `select` can be followed by an optional-comment `input`. When an `ask_user` tool call declares `allowComment: true`, Paseo presents the selection and optional comment as one question permission, answers Pi's initial `select` immediately, then auto-answers the follow-up optional `input` with the comment the user already supplied (or an empty string). Preserve placeholders and optional/skip semantics for standalone optional inputs so the app can still distinguish "skip this optional input" from "cancel the whole dialog." Fire-and-forget extension UI requests such as notifications are intentionally ignored by the provider adapter unless Paseo grows first-class UI for them.
|
Pi RPC extension UI dialog requests (`select`, `input`, `editor`, `confirm`) are bridged into Paseo question permissions and answered with `extension_ui_response`. Pi extensions such as `ask_user` may chain dialogs: for example, a `select` can be followed by an optional-comment `input`. When an `ask_user` tool call declares `allowComment: true`, Paseo presents the selection and optional comment as one question permission, answers Pi's initial `select` immediately, then auto-answers the follow-up optional `input` with the comment the user already supplied (or an empty string). Preserve placeholders and optional/skip semantics for standalone optional inputs so the app can still distinguish "skip this optional input" from "cancel the whole dialog." Fire-and-forget extension UI requests such as notifications are intentionally ignored by the provider adapter unless Paseo grows first-class UI for them.
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class OmpHostToolHarness {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("OMP host tools", () => {
|
describe("OMP host tools", () => {
|
||||||
test("serializes the caller-scoped Paseo catalog for set_host_tools", () => {
|
test("marks every caller-scoped Paseo tool essential for direct invocation", () => {
|
||||||
const catalog = createCatalog([
|
const catalog = createCatalog([
|
||||||
{
|
{
|
||||||
name: "create_agent",
|
name: "create_agent",
|
||||||
@@ -137,6 +137,11 @@ describe("OMP host tools", () => {
|
|||||||
inputSchema: { initialPrompt: z.string().describe("Prompt for the new agent.") },
|
inputSchema: { initialPrompt: z.string().describe("Prompt for the new agent.") },
|
||||||
handler: async () => ({ content: [] }),
|
handler: async () => ({ content: [] }),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "browser_list_tabs",
|
||||||
|
description: "List browser tabs.",
|
||||||
|
handler: async () => ({ content: [] }),
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(serializeOmpHostTools(catalog)).toEqual([
|
expect(serializeOmpHostTools(catalog)).toEqual([
|
||||||
@@ -144,8 +149,15 @@ describe("OMP host tools", () => {
|
|||||||
name: "create_agent",
|
name: "create_agent",
|
||||||
label: "Create agent",
|
label: "Create agent",
|
||||||
description: "Create a Paseo agent.",
|
description: "Create a Paseo agent.",
|
||||||
|
loadMode: "essential",
|
||||||
parameters: expect.objectContaining({ type: "object", required: ["initialPrompt"] }),
|
parameters: expect.objectContaining({ type: "object", required: ["initialPrompt"] }),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "browser_list_tabs",
|
||||||
|
description: "List browser tabs.",
|
||||||
|
loadMode: "essential",
|
||||||
|
parameters: expect.objectContaining({ type: "object" }),
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export function serializeOmpHostTools(catalog: PaseoToolCatalog): OmpRpcHostTool
|
|||||||
const definition: OmpRpcHostToolDefinition = {
|
const definition: OmpRpcHostToolDefinition = {
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
description: tool.description,
|
description: tool.description,
|
||||||
|
loadMode: "essential",
|
||||||
parameters: serializePaseoToolInputParameters(tool),
|
parameters: serializePaseoToolInputParameters(tool),
|
||||||
};
|
};
|
||||||
if (tool.title) {
|
if (tool.title) {
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ export const OmpRpcHostToolDefinitionSchema = z
|
|||||||
name: z.string(),
|
name: z.string(),
|
||||||
label: z.string().optional(),
|
label: z.string().optional(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
|
loadMode: z.enum(["essential", "discoverable"]).optional(),
|
||||||
parameters: z.record(z.string(), z.unknown()),
|
parameters: z.record(z.string(), z.unknown()),
|
||||||
hidden: z.boolean().optional(),
|
hidden: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user