← Public packages
@kody/agent-mail
AgentMail inboxes for agents: create/list inboxes, messages, threads, and Svix webhook ingress.
src/core.ts
75 lines · 2.3 KB · TypeScriptconst agentmailApiKey = '{{secret:agentmailApiKey|scope=user}}'
const agentmailApiBase = 'https://api.agentmail.to'
export function clean(value: unknown) {
return String(value ?? '').trim()
}
export function requireConfirmOrDryRun(input: {
confirm?: boolean
dryRun?: boolean
}, action: string) {
if (input.dryRun === true) return 'dryRun' as const
if (input.confirm === true) return 'confirm' as const
throw new Error(
`Pass confirm: true to ${action}, or dryRun: true to preview`,
)
}
export async function parseJsonResponse(response: Response, label = 'AgentMail API') {
const text = await response.text()
let body: unknown = null
try {
body = text ? JSON.parse(text) : null
} catch {
body = { raw: text }
}
if (!response.ok) {
throw new Error(
label + ' HTTP ' + response.status + ': ' + JSON.stringify(body).slice(0, 800),
)
}
return body
}
export type AgentMailRequestInput = {
method?: string
path: string
query?: Record<string, unknown>
body?: unknown
headers?: Record<string, string>
label?: string
}
/**
* Make one authenticated AgentMail REST request with agentmailApiKey.
* Prefer the typed exports over calling this directly.
*/
export async function agentMailRequest(input: AgentMailRequestInput) {
const path = clean(input.path)
if (!path.startsWith('/')) throw new Error('path must start with /')
const url = new URL(path, agentmailApiBase)
for (const [key, value] of Object.entries(input.query || {})) {
if (value === undefined || value === null || value === '') continue
url.searchParams.set(key, String(value))
}
const method = clean(input.method || 'GET').toUpperCase() || 'GET'
const headers: Record<string, string> = {
Authorization: 'Bearer ' + agentmailApiKey,
Accept: 'application/json',
...(input.headers || {}),
}
let body: string | undefined
if (input.body !== undefined && method !== 'GET' && method !== 'HEAD') {
headers['Content-Type'] = 'application/json'
body = JSON.stringify(input.body)
}
const response = await fetch(url, { method, headers, body })
return await parseJsonResponse(response, input.label || 'AgentMail API')
}
export function encodePathSegment(value: unknown, label: string) {
const id = clean(value)
if (!id) throw new Error(label + ' is required')
return encodeURIComponent(id)
}