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:
2026-10-19 18:46:58 +08:00
parent f5c3cde2c2
commit 6a49d2209e
164 changed files with 12286 additions and 2368 deletions
+39
View File
@@ -0,0 +1,39 @@
import { describe, expect, it } from "bun:test";
import express from "express";
import { registerTaskAgentBridge } from "../../src/routes/task-agent-bridge.js";
import { registerTaskPublicationBridge } from "../../src/routes/task-publication-bridge.js";
import { removeRuntimeSessionContext, setRuntimeSessionContext } from "../../src/runtime/sessionContext.js";
import { TASK_AGENT, TASK_READER_AGENT } from "../../src/runtime/task-agent-policy.js";
describe("task reader bridge", () => {
it("uses parent identity only for reads, revokes on run end and forbids child publication", async () => {
const id = "bridge-task-parent";
setRuntimeSessionContext({ sessionId: id, clientSessionId: id, actorKey: "a", projectKey: "p",
projectId: "project-1", taskId: "task-1", traceId: "test", purpose: "task_execution" });
let active = true;
const app = express(); app.use(express.json());
const reader = registerTaskAgentBridge(app, { internalToken: "TEST_ONLY", hasActiveRun: () => active,
getSession: async (sessionId) => ({ id: sessionId, parentID: sessionId === id ? undefined : id,
agent: sessionId === id ? TASK_AGENT : TASK_READER_AGENT, location: { directory: "/workspace" } }),
});
registerTaskPublicationBridge(app, { internalToken: "TEST_ONLY" });
const server = app.listen(0, "127.0.0.1");
await new Promise<void>((resolve) => server.once("listening", resolve));
const base = `http://127.0.0.1:${(server.address() as { port: number }).port}`;
const post = (path: string, token = "TEST_ONLY") => fetch(`${base}/internal/operational-task/${path}`, {
method: "POST", headers: { "Content-Type": "application/json", "x-agent-internal-token": token }, body: JSON.stringify({ session_id: "child" }),
});
try {
expect(await (await post("agent-policy")).json()).toEqual({ role: "reader" });
expect((await post("agent-policy", "wrong")).status).toBe(403);
expect((await reader("child"))?.runtimeSessionId).toBe(id);
for (const kind of ["artifacts", "presentation"]) expect((await post(kind)).status).toBe(403);
active = false;
expect(await reader("child")).toBeNull();
expect(await (await post("agent-policy")).json()).toEqual({ role: "denied" });
} finally {
removeRuntimeSessionContext(id);
await new Promise<void>((resolve) => server.close(() => resolve()));
}
});
});