-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_shared.ts
More file actions
75 lines (67 loc) · 1.91 KB
/
Copy path_shared.ts
File metadata and controls
75 lines (67 loc) · 1.91 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
63
64
65
66
67
68
69
70
71
72
73
74
75
import { HospitableError } from "../hospitable/client.js";
import { writeAuditLog as realWriteAuditLog } from "../db.js";
import type { TenantContext } from "../auth.js";
type AuditLogger = (
tenantIdHash: string | null,
tool: string,
result: "ok" | "error",
errorMessage?: string
) => Promise<void>;
let auditLogger: AuditLogger = realWriteAuditLog;
/** Test hook: replace the audit logger. Returns a restore function. */
export function setAuditLogger(fn: AuditLogger): () => void {
const prev = auditLogger;
auditLogger = fn;
return () => {
auditLogger = prev;
};
}
export interface ToolResult {
[key: string]: unknown;
content: Array<{ type: "text"; text: string }>;
isError?: boolean;
}
export function jsonResponse(data: unknown): ToolResult {
return {
content: [{ type: "text", text: JSON.stringify(data) }],
};
}
export function textResponse(text: string): ToolResult {
return { content: [{ type: "text", text }] };
}
export function formatToolError(err: unknown): ToolResult {
if (err instanceof HospitableError) {
return {
content: [
{
type: "text",
text: `Hospitable API error ${err.status}: ${err.message}${err.body ? `\n${err.body}` : ""}`,
},
],
isError: true,
};
}
const msg = err instanceof Error ? err.message : String(err);
return {
content: [{ type: "text", text: msg }],
isError: true,
};
}
export async function runTool(
ctx: TenantContext,
toolName: string,
fn: () => Promise<unknown>
): Promise<ToolResult> {
try {
const data = await fn();
void auditLogger(ctx.tenantIdHash, toolName, "ok");
if (data === undefined || data === null) {
return textResponse("OK");
}
return jsonResponse(data);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
void auditLogger(ctx.tenantIdHash, toolName, "error", msg);
return formatToolError(err);
}
}