|
| 1 | +// Pure HTTP client functions + types for the DeepAgent Review dialog. Split out from the .tsx so it |
| 2 | +// carries NO UI imports (Kobalte/solid-web run client-only code at module eval, which crashes a |
| 3 | +// server-side unit test). The route contract test imports THIS module; the component re-exports these |
| 4 | +// for back-compat. Keep this file free of any solid-js/UI imports. |
| 5 | + |
| 6 | +export type KnowledgeItem = { |
| 7 | + id: string |
| 8 | + type: "knowledge" | "strategy" | "methodology" | "memory" | "skill" | "failure_dossier" |
| 9 | + summary: string |
| 10 | + evidence_strength: "strong" | "medium" | "weak" | "none" |
| 11 | + evidence_refs: string[] |
| 12 | + approval_status: "pending" | "approved" | "rejected" |
| 13 | +} |
| 14 | + |
| 15 | +type RawSdkClient = { |
| 16 | + client: { |
| 17 | + request<TData>(options: { |
| 18 | + method: string |
| 19 | + url: string |
| 20 | + body?: unknown |
| 21 | + headers?: Record<string, string> |
| 22 | + }): Promise<{ data?: TData }> |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +export type ReviewClient = RawSdkClient |
| 27 | + |
| 28 | +export const listPending = async (client: ReviewClient): Promise<KnowledgeItem[]> => { |
| 29 | + const response = await client.client.request<{ items: KnowledgeItem[] }>({ |
| 30 | + method: "GET", |
| 31 | + url: "/deepagent/knowledge/pending", |
| 32 | + }) |
| 33 | + return response.data?.items ?? [] |
| 34 | +} |
| 35 | + |
| 36 | +export const setStatus = async ( |
| 37 | + client: ReviewClient, |
| 38 | + action: "approve" | "reject-ids", |
| 39 | + ids: string[], |
| 40 | +): Promise<void> => { |
| 41 | + await client.client.request<{ updated: string[] }>({ |
| 42 | + method: "POST", |
| 43 | + url: `/deepagent/knowledge/${action}`, |
| 44 | + body: { ids }, |
| 45 | + headers: { "Content-Type": "application/json" }, |
| 46 | + }) |
| 47 | +} |
| 48 | + |
| 49 | +// V3.8.1 §G environment-fact use-gate. Provisional user-global environment facts surface here so the |
| 50 | +// user decides, per project, whether to adopt them (§G.5). Credentials never appear — only secret_ref |
| 51 | +// pointers. `degraded` marks a fact whose last connection attempt failed (§G.6). |
| 52 | +export type EnvFactBody = { |
| 53 | + host?: string |
| 54 | + port?: number |
| 55 | + container?: string |
| 56 | + purpose?: string |
| 57 | + secret_refs?: string[] |
| 58 | + last_confirmed_at: string |
| 59 | + notes?: string |
| 60 | +} |
| 61 | +export type EnvFactItem = { |
| 62 | + fact_id: string |
| 63 | + version: number |
| 64 | + description: string |
| 65 | + body: EnvFactBody | null |
| 66 | + degraded: boolean |
| 67 | +} |
| 68 | +export type EnvFactList = { adopted: EnvFactItem[]; pending: EnvFactItem[] } |
| 69 | + |
| 70 | +export const listEnvFacts = async (client: ReviewClient): Promise<EnvFactList> => { |
| 71 | + const response = await client.client.request<EnvFactList>({ method: "GET", url: "/deepagent/env-facts" }) |
| 72 | + return { adopted: response.data?.adopted ?? [], pending: response.data?.pending ?? [] } |
| 73 | +} |
| 74 | + |
| 75 | +export const decideEnvFact = async ( |
| 76 | + client: ReviewClient, |
| 77 | + factId: string, |
| 78 | + decision: "adopt" | "reject", |
| 79 | +): Promise<void> => { |
| 80 | + await client.client.request<{ ok: boolean }>({ |
| 81 | + method: "POST", |
| 82 | + url: "/deepagent/env-facts/decide", |
| 83 | + body: { factId, decision }, |
| 84 | + headers: { "Content-Type": "application/json" }, |
| 85 | + }) |
| 86 | +} |
| 87 | + |
| 88 | +// §G.5 modify: edit a fact then adopt it. mode=global corrects the shared fact for every project; |
| 89 | +// mode=project writes a project-local override, leaving the global fact untouched for others. |
| 90 | +export type EnvFactModifyInput = { |
| 91 | + factId: string |
| 92 | + description: string |
| 93 | + body: EnvFactBody |
| 94 | + domain?: string | null |
| 95 | + mode: "global" | "project" |
| 96 | +} |
| 97 | +export const modifyEnvFact = async (client: ReviewClient, input: EnvFactModifyInput): Promise<void> => { |
| 98 | + await client.client.request<{ ok: boolean; factId: string }>({ |
| 99 | + method: "POST", |
| 100 | + url: "/deepagent/env-facts/modify", |
| 101 | + body: input, |
| 102 | + headers: { "Content-Type": "application/json" }, |
| 103 | + }) |
| 104 | +} |
0 commit comments