Integrations
The cleanest way to integrate Chidori with external systems is as an event-driven agent: one file, one agent(event, chidori) function, one HTTP port. Every external system that can POST JSON becomes a source of events.
The pattern
chidori serve agents/integrations.ts --port 8080import type { Chidori } from "chidori";
export async function agent(event, chidori: Chidori) {
if (event.path === "/github") return handleGithub(event, chidori);
if (event.path === "/slack") return handleSlack(event, chidori);
if (event.path === "/alert") return handleAlert(event, chidori);
return { status: 404, body: { error: "Unknown path: " + event.path } };
}Then point each external system at the matching URL — one agent, many integrations.
GitHub webhooks
GitHub sends a JSON body and a x-github-event header identifying the event type.
async function handleGithub(event, chidori: Chidori) {
const ghEvent = event.headers["x-github-event"] ?? "";
const body = event.body;
if (ghEvent === "pull_request" && body.action === "opened") {
return reviewPr(body.pull_request, chidori);
}
if (ghEvent === "issues" && body.action === "opened") {
return triageIssue(body.issue, chidori);
}
return { status: 200, body: { ignored: ghEvent } };
}
async function reviewPr(pr, chidori: Chidori) {
const diff = await chidori.http(pr.diff_url, {
headers: { Accept: "application/vnd.github.v3.diff" },
});
const review = await chidori.prompt(
"Review this pull request. Flag correctness, security, and style issues.\n\n" +
"Title: " + pr.title + "\n\nDiff:\n" + diff.body,
{ maxTokens: 1000 },
);
await chidori.http(pr.comments_url, {
method: "POST",
headers: { Authorization: "Bearer " + chidori.env("GITHUB_TOKEN") },
body: { body: review },
});
return { status: 200, body: { reviewed: pr.number } };
}
async function triageIssue(issue, chidori: Chidori) {
const classification = await chidori.prompt(
"Classify this issue as 'bug', 'feature', 'question', or 'duplicate'. " +
"Respond with just the word.\n\nTitle: " + issue.title +
"\n\nBody:\n" + (issue.body ?? ""),
{ maxTokens: 20 },
);
await chidori.http(issue.url + "/labels", {
method: "POST",
headers: { Authorization: "Bearer " + chidori.env("GITHUB_TOKEN") },
body: { labels: [classification.trim().toLowerCase()] },
});
return { status: 200, body: { triaged: issue.number, label: classification } };
}Register the webhook in GitHub under Settings → Webhooks, pointing at https://your-host/github.
Slack slash commands
Slack POSTs a form-encoded body; Chidori parses it into event.body as an object:
async function handleSlack(event, chidori: Chidori) {
const body = event.body;
const command = body.command ?? "";
const text = body.text ?? "";
if (command === "/summarize") {
return summarizeThread(body.channel_id, body.thread_ts, chidori);
}
if (command === "/explain") {
return { status: 200, body: { text: await chidori.prompt("Explain like I'm 5:\n" + text) } };
}
return { status: 200, body: { text: "Unknown command: " + command } };
}Alert responders
Chidori is a natural fit for on-call copilots — an alert comes in, the agent fetches related metrics, proposes a diagnosis, and pages a human only if it can't self-resolve.
async function handleAlert(event, chidori: Chidori) {
const alert = event.body;
const severity = alert.severity ?? "unknown";
const service = alert.service ?? "unknown";
// Pull related metrics and recent deploys in parallel
const context = await chidori.parallel([
() => chidori.tool("prometheus_query", { query: `rate(errors{service="${service}"}[5m])` }),
() => chidori.tool("recent_deploys", { service, hours: 2 }),
() => chidori.tool("recent_alerts", { service, hours: 6 }),
]);
const diagnosis = await chidori.prompt(
await chidori.template("prompts/alert.jinja", {
alert,
metrics: context[0],
deploys: context[1],
related: context[2],
}),
{ maxTokens: 500 },
);
if (severity === "critical") {
await chidori.tool("page_oncall", { service, diagnosis });
}
return { status: 200, body: { diagnosis, severity } };
}Secrets
Never inline secrets. Read them with chidori.env() and pass them through to chidori.http():
await chidori.http("https://api.example.com/...", {
method: "POST",
headers: { Authorization: "Bearer " + chidori.env("API_TOKEN") },
body: payload,
});Debugging failed integrations
Because every integration run is a session under chidori serve, any production failure is a replayable checkpoint. Grab the checkpoint, run it locally, edit the offending call's cached result in the debugger to branch the history, and iterate — zero additional LLM spend.
