feat(agent): unify MCP tools and adopt Responses delivery
Move project and host queries into native MCP with host-owned OAuth/context, while retaining memory, skills, actions and publication plugins. Add nearby-model queries and explicit chat/task/learning model defaults. Adopt Responses HTTP/SSE and native steer/queue inbox delivery, preserving scoped session ownership, pending input edits and investigation communication. Disable local-provider discovery: Server /health allowed native vLLM to probe /v1/models on port 8000. A native before/after regression prevents recurrence. Validation: 170 focused Bun tests; service/plugin typechecks; native discovery, provider-discovery and input-inbox smoke checks; no paid model inference.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { Plugin, Rpc } from "@opencode/plugin";
|
||||
import { z } from "zod";
|
||||
|
||||
// Loaded only by the opt-in isolated smoke script, never by the Agent service.
|
||||
export default Plugin.define({
|
||||
id: "tjwater.mcp-fixture",
|
||||
async setup(ctx) {
|
||||
await ctx.websearch.transform((editor) => {
|
||||
editor.add({ id: "fixture-search", name: "Isolated search fixture", execute: async ({ query }) => [
|
||||
{ url: "https://example.test/search-result", title: "Fixture result", content: query, time: {} },
|
||||
] });
|
||||
});
|
||||
// Materialize the native session toolbox, then stop before any model call.
|
||||
await ctx.session.hook("context", () => { throw new Error("MCP fixture stops before model request"); });
|
||||
const evaluated: string[] = [];
|
||||
await ctx.permission.hook("evaluate", (event) => { evaluated.push(event.action); });
|
||||
await ctx.rpc.register(Rpc.define({
|
||||
id: "tjwater.mcp-fixture", events: {}, methods: {
|
||||
call: { input: z.object({ session_id: z.string(), tool: z.enum(["mcp_stdio_echo", "mcp_http_write", "mcp_tjwater_session_search", "mcp_tjwater_todoread", "mcp_tjwater_run_simulation", "websearch"]), value: z.string().optional(), arguments: z.record(z.string(), z.unknown()).optional() }), output: z.object({ content: z.unknown(), evaluated: z.array(z.string()), error: z.string().optional() }) },
|
||||
},
|
||||
}), {
|
||||
call: async (input, context) => {
|
||||
const tool = (await ctx.tool.list()).find((tool) => tool.id === input.tool);
|
||||
if (!tool) throw new Error("fixture tool missing");
|
||||
try {
|
||||
const result = await tool.execute(input.arguments ?? { value: input.value }, { sessionID: input.session_id as never, id: "call-mcp-fixture" as never, messageID: "msg-mcp-fixture" as never, agent: "instruction" as never, signal: context.signal, progress: async () => {} });
|
||||
return { content: result.content ?? [], evaluated };
|
||||
} catch (error) { return { content: [], evaluated, error: String(error) }; }
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
// Loaded only by the opt-in isolated task-agent smoke test, never by the service.
|
||||
import { Plugin, Rpc } from "@opencode/plugin";
|
||||
import * as Schema from "effect/Schema";
|
||||
import { z } from "zod";
|
||||
|
||||
export default Plugin.define({ id: "test.task-agent-probe", async setup(ctx) {
|
||||
await ctx.rpc.register(Rpc.define({ id: "test.task-agent-probe", methods: {
|
||||
subagent_input: { input: z.object({}), output: z.array(z.string()) },
|
||||
}, events: {} }), { subagent_input: async () => {
|
||||
const tool = (await ctx.tool.list()).find((item) => item.id === "subagent");
|
||||
if (!tool) throw new Error("native subagent tool missing");
|
||||
const input = Schema.isSchema(tool.input) ? Schema.toJsonSchemaDocument(tool.input).schema : tool.input;
|
||||
return Object.keys((input as { properties?: Record<string, unknown> }).properties ?? {});
|
||||
} });
|
||||
} });
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "tjwater-task-agent-probe-plugin",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": "./index.ts"
|
||||
}
|
||||
Reference in New Issue
Block a user