-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathaiClient.ts
More file actions
62 lines (55 loc) · 1.5 KB
/
Copy pathaiClient.ts
File metadata and controls
62 lines (55 loc) · 1.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { buildApiUrl } from "./_base";
import type { HspAiAction } from "../ai/intentActions";
export type AiChatApiResponse = {
ok: boolean;
provider?: string;
mode?: string;
output_text?: string;
error?: string;
actions?: HspAiAction[];
meta?: Record<string, unknown>;
};
export type AiChatRequestContext = {
route?: string;
locale?: string;
walletConnected?: boolean;
};
export async function postAiChat(
input: string,
context?: AiChatRequestContext,
): Promise<AiChatApiResponse> {
const res = await fetch(buildApiUrl("/api/ai"), {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
input,
mode: "chat",
context,
}),
});
let body: AiChatApiResponse;
try {
body = (await res.json()) as AiChatApiResponse;
} catch {
return {
ok: false,
error: res.ok ? "Invalid response from AI service." : `AI request failed (${res.status}).`,
};
}
if (!res.ok && body.ok !== false) {
return { ok: false, error: `AI request failed (${res.status}).` };
}
return body;
}
/** Apply the first navigational action from an AI response. */
export function applyFirstNavigateAction(
router: { push: (href: string) => void },
actions?: HspAiAction[],
): boolean {
if (!actions?.length) return false;
const nav = actions.find((a): a is Extract<HspAiAction, { type: "navigate" }> => a.type === "navigate");
if (!nav?.path) return false;
router.push(nav.path);
return true;
}