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:
@@ -1,6 +1,7 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
import { type ProductCredential } from "./server-auth-client.js";
|
||||
import { getRuntimeSessionContext } from "../runtime/sessionContext.js";
|
||||
|
||||
export type CredentialRefreshReason =
|
||||
| "access_token_expired"
|
||||
@@ -245,7 +246,10 @@ export const credentialRefreshCoordinator = new CredentialRefreshCoordinator(45_
|
||||
export const bindSessionCredential = (sessionId: string, credential: ProductCredential | null) => {
|
||||
if (credential) { credentialVault.set(sessionId, { ...credential }); credentialFailures.delete(sessionId); }
|
||||
};
|
||||
const credentialReleaseListeners = new Set<(id: string) => void>();
|
||||
export const onSessionCredentialReleased = (listener: (id: string) => void) => { credentialReleaseListeners.add(listener); return () => credentialReleaseListeners.delete(listener); };
|
||||
export const releaseSessionCredential = (sessionId: string) => {
|
||||
for (const listener of credentialReleaseListeners) listener(sessionId);
|
||||
credentialRefreshCoordinator.cancelSession(sessionId);
|
||||
credentialRefreshCoordinator.disableBackground(sessionId);
|
||||
credentialVault.delete(sessionId);
|
||||
@@ -264,6 +268,9 @@ export const requestWithSessionCredential = async (
|
||||
sessionId: string, execute: (credential: ProductCredential) => Promise<Response>,
|
||||
) => {
|
||||
const credential = credentialVault.get(sessionId);
|
||||
if (!credential && getRuntimeSessionContext(sessionId)?.projectKey.startsWith("personal-")) {
|
||||
throw Object.assign(new Error("个人会话未关联项目,请选择项目会话后访问业务数据"), { status: 403, code: "PROJECT_CONTEXT_REQUIRED" });
|
||||
}
|
||||
if (!credential) throw Object.assign(new Error("task access requires a current product credential"), { status: 401 });
|
||||
if (credentialFailures.has(sessionId)) throw Object.assign(new CredentialRefreshError("credential renewal failed"), { status: 401 });
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user