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,72 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdir, mkdtemp, rm } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { parseAgentModelConfig } from "../../src/chat/modelConfig.js";
|
||||
import { serviceOpencodeConfig } from "../../src/runtime/opencode2-config.js";
|
||||
import { startOpencode2 } from "../../src/runtime/opencode2-server.js";
|
||||
|
||||
// No inference or live business requests: redirect every local discovery probe
|
||||
// to a fixture that behaves like TJWater Server (/health exists, /v1/models does not).
|
||||
const root = await mkdtemp(join(tmpdir(), "tjwater-provider-discovery-"));
|
||||
const originalDirectory = process.cwd();
|
||||
const requests: string[] = [];
|
||||
const localProviders = ["vllm", "lmstudio", "ollama"];
|
||||
const fixture = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch(request) {
|
||||
const path = new URL(request.url).pathname;
|
||||
requests.push(path);
|
||||
if (path === "/health") return Response.json({ status: "ok" });
|
||||
if (path === "/api/v1/models" || path === "/api/tags") return Response.json({ models: [] });
|
||||
return new Response(null, { status: 404 });
|
||||
} });
|
||||
|
||||
try {
|
||||
const models = parseAgentModelConfig({
|
||||
defaults: { chat: "fixture/fake", task: "fixture/fake", learning_gate: "fixture/fake" },
|
||||
providers: Object.fromEntries(["fixture", ...localProviders].map((id) => [id, {
|
||||
name: id, api_url: `http://127.0.0.1:${fixture.port}/v1`, models: { fake: {} },
|
||||
}])),
|
||||
});
|
||||
const generated = serviceOpencodeConfig({}, models);
|
||||
// Keep the service's actual discovery filters, without loading unrelated
|
||||
// TJWater query/action plugins in this isolated provider-only test.
|
||||
const filters = generated.plugins.filter((plugin) => typeof plugin === "string" && plugin.startsWith("-opencode.provider."));
|
||||
process.chdir(root);
|
||||
for (const fixed of [false, true]) {
|
||||
const location = join(root, fixed ? "fixed" : "baseline");
|
||||
await mkdir(location, { recursive: true });
|
||||
const start = requests.length;
|
||||
const runtime = await startOpencode2({
|
||||
command: process.env.OPENCODE_COMMAND ?? "opencode2", hostname: "127.0.0.1", port: 0, timeout: 30_000,
|
||||
config: { model: generated.model, providers: generated.providers, plugins: ["*", ...(fixed ? filters : [])] },
|
||||
env: {
|
||||
OPENCODE_DB: join(location, "native.db"), OPENCODE_CONFIG_DIR: join(location, "config"),
|
||||
XDG_DATA_HOME: join(location, "data"), XDG_CONFIG_HOME: join(location, "config"),
|
||||
XDG_CACHE_HOME: join(location, "cache"), XDG_STATE_HOME: join(location, "state"),
|
||||
},
|
||||
});
|
||||
try {
|
||||
const catalog = await runtime.client.model.list({ location: { directory: location } });
|
||||
await Bun.sleep(1500);
|
||||
const observed = requests.slice(start);
|
||||
console.log(fixed ? "Fixed discovery requests:" : "Baseline discovery requests:", JSON.stringify(observed));
|
||||
if (fixed) {
|
||||
assert.deepEqual(observed, [], "native local-provider discovery still makes unsolicited HTTP requests");
|
||||
for (const providerID of ["fixture", ...localProviders]) {
|
||||
assert.ok(catalog.data.some((model) => model.providerID === providerID && model.id === "fake" && model.enabled),
|
||||
`configured model unavailable: ${providerID}/fake`);
|
||||
}
|
||||
} else {
|
||||
assert.ok(observed.includes("/health"), "baseline did not perform the vLLM health probe");
|
||||
assert.ok(observed.includes("/v1/models"), "baseline did not reproduce the unwanted model request");
|
||||
assert.ok(observed.includes("/api/v1/models"), "baseline did not probe LM Studio");
|
||||
assert.ok(observed.includes("/api/tags"), "baseline did not probe Ollama");
|
||||
}
|
||||
} finally { runtime.close(); await runtime.exited; }
|
||||
}
|
||||
console.log("Native provider discovery regression passed; configured local models retained, no inference.");
|
||||
} finally {
|
||||
process.chdir(originalDirectory);
|
||||
fixture.stop(true);
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
Reference in New Issue
Block a user