import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { PiOAuthCompleteRequest, PiOAuthCompleteResult, PiOAuthStartRequest, PiOAuthStartResult, PiProvidersResponse, PiUpstream, PiUpstreamCreate, PiUpstreamList, PiUpstreamModels, PiUpstreamTestRequest, PiUpstreamTestResult, PiUpstreamUpdate, } from "@umt/contracts"; import { apiData, TTL_MINUTE } from "~/lib/api.ts"; import { qk } from "~/lib/query-keys.ts"; // Agent 上游(W7-A 的 /pi/*):能力表、上游 CRUD、测试、模型表、订阅登录。 // 写操作后刷新上游列表与全局设置(默认上游存在 settings.pi.defaultUpstreamId)。 export const piKeys = { all: ["pi"] as const, providers: (withModels: boolean) => ["pi", "providers", withModels] as const, upstreams: ["pi", "upstreams"] as const, models: (id: string) => ["pi", "models", id] as const, }; /** 能力表;withModels = 带静态模型表(约 370 KB,只在新建向导里要) */ export function usePiProviders(withModels = false, enabled = true) { return useQuery({ queryKey: piKeys.providers(withModels), enabled, staleTime: 30 * TTL_MINUTE, queryFn: ({ signal }) => apiData("/pi/providers", { params: withModels ? {} : { models: "false" }, signal }), }); } export function usePiUpstreams() { return useQuery({ queryKey: piKeys.upstreams, queryFn: ({ signal }) => apiData("/pi/upstreams", { signal }), }); } export function usePiUpstreamModels(id: string | null) { return useQuery({ queryKey: piKeys.models(id ?? ""), enabled: !!id, staleTime: 5 * TTL_MINUTE, queryFn: ({ signal }) => apiData("/pi/upstreams/{id}/models", { pathParams: { id: id ?? "" }, signal }), }); } function useInvalidatePi() { const qc = useQueryClient(); return () => { qc.invalidateQueries({ queryKey: piKeys.upstreams }); qc.invalidateQueries({ queryKey: qk.settings }); }; } export function useCreatePiUpstream() { const inv = useInvalidatePi(); return useMutation({ mutationFn: (body: PiUpstreamCreate) => apiData("/pi/upstreams", { method: "POST", body }), onSuccess: inv, }); } export function useUpdatePiUpstream() { const inv = useInvalidatePi(); return useMutation({ mutationFn: ({ id, body }: { id: string; body: PiUpstreamUpdate }) => apiData("/pi/upstreams/{id}", { method: "PATCH", pathParams: { id }, body }), onSuccess: inv, }); } export function useRemovePiUpstream() { const inv = useInvalidatePi(); return useMutation({ mutationFn: (id: string) => apiData("/pi/upstreams/{id}", { method: "DELETE", pathParams: { id } }), onSuccess: inv, }); } export function useTestPiUpstream() { const inv = useInvalidatePi(); return useMutation({ mutationFn: ({ id, body }: { id: string; body: PiUpstreamTestRequest }) => apiData("/pi/upstreams/{id}/test", { method: "POST", pathParams: { id }, body }), onSettled: inv, }); } export function useStartPiOAuth() { return useMutation({ mutationFn: ({ id, body }: { id: string; body: PiOAuthStartRequest }) => apiData("/pi/upstreams/{id}/oauth/start", { method: "POST", pathParams: { id }, body }), }); } /** 完成 / 轮询一次登录(device 模式前端反复调用直到终态) */ export function completePiOAuth(id: string, body: PiOAuthCompleteRequest, signal?: AbortSignal) { return apiData("/pi/upstreams/{id}/oauth/complete", { method: "POST", pathParams: { id }, body, signal, }); } export function useLogoutPiOAuth() { const inv = useInvalidatePi(); return useMutation({ mutationFn: (id: string) => apiData("/pi/upstreams/{id}/oauth/logout", { method: "POST", pathParams: { id }, body: {} }), onSuccess: inv, }); } export { useInvalidatePi };