Wrap a new backend endpoint in the TypeScript SDK (packages/sdk), or record it as skipped. Use when `just coverage` fails, or after adding an endpoint to a Rust service.
日本語の概要は準備中です。原文の説明を表示しています。
Build a new AI tool end-to-end — Rust implementation, toolset wiring, infra, schema generation, and frontend UI.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
This skill walks through building a new AI tool from scratch. Before writing any code, read the design guide at crates/ai_toolset/TOOL_DESIGN.md and the framework docs/examples in crates/ai_toolset/src/lib.rs.
IMPORTANT: Never modify the crates/ai_toolset/ crate. It is the framework — you build tools that use it.
Decide which domain crate the tool belongs in. Tools live at crates/<crate>/src/inbound/toolset/.
Study an existing tool for patterns:
crates/documents/src/inbound/toolset/ — tools: read_content.rs, read_metadata.rs, create_document.rscrates/email/src/inbound/toolset/ — tools: send_email.rs, get_thread.rs, update_thread_labels.rscrates/soup/src/inbound/toolset/ — tool: list_entities.rscrates/call/src/inbound/toolset/ — call-related toolsEach tool is a struct that derives JsonSchema and Deserialize, with #[schemars(title = "...", description = "...")] on the struct and #[schemars(description = "...")] on each field. The struct implements AsyncTool<Context> from the ai_toolset crate.
Create a new file for your tool (e.g. my_tool.rs), add it as a mod in the toolset's mod.rs, and wire it into the toolset's AsyncToolSet::new().add_tool::<...>() chain.
If your tool needs dependencies (DB connections, service clients) that aren't already in an existing context, define a new context struct in the toolset's mod.rs. See crates/documents/src/inbound/toolset/mod.rs for the DocumentToolContext pattern.
The context must be Clone and derivable from the parent ToolServiceContext via FromRef.
If the tool's dependencies are already available in an existing context (e.g. it only needs Arc<ToolScribe>), you can use that context directly — no new struct needed.
all_tools in the ai_tools crateEdit crates/ai_tools/src/lib.rs:
.add_tool::<YourTool, YourContext>() or .add_subtoolset::<YourToolContext>(your_toolset()) to the all_tools() functionEdit crates/ai_tools/src/tool_context.rs:
Tool* naming pattern)ToolServiceContext structFromRef<ToolServiceContext> for your context if needed (or derive it — the struct uses #[derive(FromRef)])Edit crates/ai_tools/src/build_context.rs:
env_var! or maybe_env_var! blocksbuild_tool_service_context_from_envToolServiceContextEdit infra/packages/shared/src/ai_tools.ts:
envVars array in getAiToolsInfra()Run from the repository root:
cargo fmt
cargo clippy -p ai_tools
cargo test -p <your_domain_crate>
Fix any warnings or errors before proceeding.
Run from apps/web/:
bun gen-tools
This builds crates/ai_tools/src/bin/gen_tool_schemas.rs, generates crates/ai_tools/schemas/tools.json, and transpiles the schemas into TypeScript at apps/web/src/lib/service-clients/service-cognition/generated/tools/.
Run from apps/web/:
bun check
This runs tsc --noEmit and will report type errors — specifically, the toolHandlers map in apps/web/src/lib/core/component/AI/component/tool/handler.tsx will be missing your new tool name. The errors tell you exactly what to implement.
The tool UI components live at apps/web/src/lib/core/component/AI/component/tool/. Study existing renderers:
Search.tsx — search results renderingReadContent.tsx / ReadMetadata.tsx — document tool UISendEmail.tsx — email tool UIListEntities.tsx — list displayProperties.tsx — property get/set toolsListCallRecords.tsx / ReadCallRecord.tsx — call toolsBaseTool.tsx — shared base componentEach tool needs a handler object implementing ToolHandler (from ToolRenderer.tsx) with at minimum a render component. Use createToolRenderer to create it.
apps/web/src/lib/core/component/AI/component/tool/YourTool.tsxcreateToolRendererapps/web/src/lib/core/component/AI/component/tool/handler.tsx:
toolHandlers map with the key matching your tool's schema titleEvery tool renderer must show results. Use the expandable dropdown pattern from Search.tsx / ListEntities.tsx:
BaseTool (from BaseTool.tsx) as the wrapper. It accepts a response prop for expandable content.const [isExpanded, setIsExpanded] = createSignal(false) to track open/closed state.ctx.response?.data (typed from the generated schema).CaretRight toggle button (@icon/regular/caret-right.svg?component-solid) that rotates 90deg when expanded.BaseTool's response prop, gated on isExpanded().For tools that return text/string results (not entity lists), render the response string in a <pre> or similar block inside the response prop. The key point: the response data must always be surfaced in the UI via the dropdown — never silently swallowed.
Run from apps/web/:
bun format
bun check
Fix any remaining type or formatting errors.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Wrap a new backend endpoint in the TypeScript SDK (packages/sdk), or record it as skipped. Use when `just coverage` fails, or after adding an endpoint to a Rust service.
日本語の概要は準備中です。原文の説明を表示しています。
Add or change an in-app feature tour (a view's guided flyover) in the web app. Use when adding a tour to a view, adding or editing tour steps, pointing a step at a new control, or when a step's target needs something opened first.
日本語の概要は準備中です。原文の説明を表示しています。
Enforce hexagonal architecture in the Rust backend. Use before modifying crates/ or Rust services, especially inbound axum/tool/listener adapters, domain services/ports, outbound adapters, authorization, permissions, database access, or external clients.
日本語の概要は準備中です。原文の説明を表示しています。
Enforce hexagonal architecture in the Rust backend. Use before modifying crates or Rust services, especially inbound axum/tool/listener adapters, domain services/ports, outbound adapters, authorization, permissions, database access, or external clients.
日本語の概要は準備中です。原文の説明を表示しています。
Use when adding collaborative markdown, notes, or descriptions to a feature with collab surfaces. Covers parent entities, service entry points, authorization, content storage, and lifecycle.
日本語の概要は準備中です。原文の説明を表示しています。
Use when building a feature on reusable database storage or UI, such as CRM, or deciding whether it needs a Macro database entity. Covers shared storage, a host-independent database UI and API contract, ownership, authorization, and the _entities naming convention.
日本語の概要は準備中です。原文の説明を表示しています。