Recipes
这页整理了一些基于公开 Ageniti API 的常见集成模式。
面向 CLI 的内部工具
当终端命令是主要入口时,适合这种模式。
import { createAgenitiApp, defineAction, s } from "@ageniti/core";
const searchTasks = defineAction({
name: "search_tasks",
description: "Search tasks by status.",
input: s.object({
status: s.enum(["open", "blocked", "done"]),
}),
run(input, ctx) {
return ctx.services.tasks.search(input);
},
});
const app = createAgenitiApp({
name: "ops-tools",
actions: [searchTasks],
services: { tasks },
});
await app.createCli().main();这种模式的优点:
- 单一命令入口
- 参数自动有 JSON Schema
- 对 shell 包装层和测试来说,返回结构稳定
复用现有 React 按钮逻辑
当应用已经有 UI handler,而你想把同一能力复用给 agent-facing 场景时,适合这种模式。
const { useAction } = app.createReactAdapter();
const runSearchTasks = useAction(searchTasks);
async function onClick() {
const result = await runSearchTasks({ status: "open" });
if (result.ok) {
setTasks(result.data.items);
}
}推荐做法:
- 确认流程放在 UI 层
- 权限上下文通过
invokeOptions传入 - 后续其他 surface 继续复用同一个 action
用 JSON Runner 做自动化调用
适合脚本、队列、cron job 或测试 harness。
const runner = app.createJsonRunner();
const result = await runner.invoke({
action: "search_tasks",
input: { status: "open" },
metadata: { source: "nightly-job" },
});如果你只是想把 Ageniti 套在自己的 transport 外层,这通常是最直接的做法。
仓库示例:
ageniti/examples/task-app.js
给 Agent 平台暴露 MCP Tools
当宿主系统已经使用 MCP 风格 JSON-RPC 时,适合这种模式。
const handle = app.createMcpHandler();
const list = await handle({
jsonrpc: "2.0",
id: 1,
method: "tools/list",
});
const call = await handle({
jsonrpc: "2.0",
id: 2,
method: "tools/call",
params: {
name: "search_tasks",
arguments: { status: "open" },
},
});如果宿主不是内存内 handler,而是要求 stdio 方式,可以使用:
await app.createCli().run(["mcp", "--stdio"]);仓库示例:
ageniti/examples/mcp-host.js
OpenAI 与 AI SDK Tool Adapter
当宿主应用本身已经会消费 OpenAI 兼容 schema 或 AI SDK tool object 时,适合这种模式。
const openaiTools = app.createOpenAITools();
const responsesTools = app.createOpenAIResponsesTools();
const aiSdkTools = app.createAISDKTools({ returnEnvelope: true });建议:
- destructive action 默认不要放出去
- 高风险工具再叠加显式 filter
- 当调用方需要日志或 artifacts 时,使用
returnEnvelope: true
OpenAI Responses 宿主接入
当你的宿主应用已经在调用 OpenAI Responses API,只是需要从 app SDK 拿到一组稳定 tool 时,适合这种模式。
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const tools = app.createOpenAIResponsesTools();
const response = await client.responses.create({
model: "gpt-4.1",
input: "Find the blocked tasks and summarize the owners.",
tools,
});这个模式的价值在于:
- 宿主自己决定模型和 prompt
- Ageniti 负责应用能力 contract
- tool schema 和 runtime 语义保持一致
仓库示例:
ageniti/examples/openai-responses-host.js
Vercel AI SDK Route Handler
当 Next.js 或其他服务端宿主已经在用 AI SDK,而你想把 shared runtime 直接接成 executable tool 时,适合这种模式。
import { generateText } from "ai";
const tools = app.createAISDKTools({ returnEnvelope: true });
const result = await generateText({
model,
prompt: "Create a high-priority follow-up task for the open incident.",
tools,
});推荐做法:
- auth 放在宿主层,通过 runtime option 注入
- 需要 logs 或 artifacts 时返回 envelope
- 非受信任宿主默认继续过滤高风险工具
仓库示例:
ageniti/examples/ai-sdk-route.js
HTTP Gateway Wrapper
当你希望自己的后端统一掌控 transport、auth 和部署,而 Ageniti 只负责 action 执行时,适合这种模式。
const handle = app.createHttpHandler();
const response = await handle({
method: "POST",
url: "/ageniti/actions/create_task/invoke",
body: {
input: {
title: "Write the release review summary",
priority: "high",
},
auth: {
permissions: ["task:create"],
},
},
});推荐做法:
- 调用方身份和鉴权收口在 gateway 层
- 只把应用级 permission context 传进 Ageniti
- HTTP payload 尽量贴近 runtime envelope,方便调试
仓库示例:
ageniti/examples/http-gateway.js
限制 Surface 暴露范围
可以通过 action 元数据把高风险操作限制在受信任入口上。
const deleteTask = defineAction({
name: "delete_task",
description: "Delete a task by id.",
sideEffects: "destructive",
supportedSurfaces: ["cli", "react", "dev"],
input: s.object({
taskId: s.string(),
}),
run(input, ctx) {
return ctx.services.tasks.remove(input.taskId);
},
});这样 action 仍可用于受信任的操作员路径,但不会进入 MCP 和 LLM tool 暴露面。
在 CI 中检查 Manifest 与 Lint
适合在发布前把 contract 显式化。
const manifest = app.manifest();
const lint = app.lint();
if (!lint.ok) {
process.exitCode = 1;
}你可以在测试里对 manifest 做 snapshot,也可以把它作为内部 contract artifact 提供给其他工具链使用。