Use the dedicated TJWATER_AGENT_URL and Responses stream protocol. Keep running turns active while users steer or queue follow-ups and edit pending delivery. Refresh the model catalog before generation and preserve approval mode selection. Integrate scoped investigation messaging/presentation, geographic place selection, current Agent composer styles and supporting workbench contracts. Validation: 77 focused Vitest checks, 21 browser cases, lint, typecheck and production build. Preserve direct Server/Agent routing and project authentication.
46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
import type {
|
|
AgentApiClient,
|
|
AgentChatSessionSummary,
|
|
AgentModelOption,
|
|
AgentModelsResponse
|
|
} from "./client";
|
|
import { parseUiRegistry, type UIRegistry } from "../ui-envelope";
|
|
import { parseFrontendActionRegistry, type FrontendActionRegistry } from "../frontend-action";
|
|
|
|
export const agentBootstrapKey = ["agent", "bootstrap"] as const;
|
|
export const agentSessionsKey = ["agent", "sessions"] as const;
|
|
|
|
export type AgentBootstrapData = {
|
|
registry: UIRegistry | null;
|
|
frontendActionRegistry?: FrontendActionRegistry | null;
|
|
models: AgentModelOption[];
|
|
defaultModel: string;
|
|
};
|
|
|
|
export function resolveAgentModelSelection(catalog: AgentModelsResponse, current = ""): string {
|
|
if (catalog.models.some((model) => model.id === current)) return current;
|
|
if (catalog.models.some((model) => model.id === catalog.defaultModel)) return catalog.defaultModel;
|
|
return catalog.models[0]?.id ?? "";
|
|
}
|
|
|
|
export async function fetchAgentBootstrap(client: AgentApiClient): Promise<AgentBootstrapData> {
|
|
const [rawRegistry, rawFrontendActionRegistry, modelsResponse] = await Promise.all([
|
|
client.getUiRegistry(),
|
|
typeof client.getFrontendActionRegistry === "function" ? client.getFrontendActionRegistry() : Promise.resolve(undefined),
|
|
client.getModels()
|
|
]);
|
|
|
|
return {
|
|
registry: parseUiRegistry(rawRegistry),
|
|
...(rawFrontendActionRegistry === undefined ? {} : { frontendActionRegistry: parseFrontendActionRegistry(rawFrontendActionRegistry) }),
|
|
models: modelsResponse.models,
|
|
defaultModel: modelsResponse.defaultModel
|
|
};
|
|
}
|
|
|
|
export async function fetchAgentSessions(client: AgentApiClient): Promise<AgentChatSessionSummary[]> {
|
|
const sessions = await client.listSessions({ purpose: "ordinary_chat" });
|
|
// Keep the product boundary even while an older Agent service is rolling forward.
|
|
return sessions.filter((session) => session.purpose === "ordinary_chat");
|
|
}
|