内置工具开发_builtin-tool
以下为本文档的中文说明
LobeHub内置工具包构建指南,专门用于开发和集成LobeHub平台中可被代理调用的工具。该技能定义了内置工具的五大核心组件:Manifest与类型定义(为LLM提供工具规范和系统提示)、ExecutionRuntime执行运行时(负责服务器端和桌面端的实际调用)、Executor执行器(客户端侧的交互逻辑)、Inspector检查器(用于调试和验证工具行为)、以及Render渲染器(负责工具输出在界面中的呈现)。此外还涵盖流式处理、干预机制、Portal集成和工具注册表等高级功能。使用场景主要包括:为LobeHub平台添加新的Agent可调用工具、开发工具包的各面层组件、配置工具的Manifest和类型系统、实现工具的流式响应处理、以及将工具注册到工具注册表中供代理发现和使用。核心原则强调"五面一体"的架构设计——每个工具由五个独立但协同的组件构成,分别服务于LLM、运行时、客户端、调试和UI渲染等不同层面。这种分层架构确保了工具的灵活性、可测试性和可维护性。
Builtin Tool Authoring Guide
A builtin tool is a package the agent runtime can call. It shipsfive faces:
| Face | Lives in | Audience |
|---|---|---|
| Manifest + types | src/{manifest,types,systemRole}.ts | The LLM (tool spec + system prompt) |
| ExecutionRuntime | src/ExecutionRuntime/ | Server / desktop / any runtime caller |
| Executor | src/client/executor/ | Frontend (wraps stores/services) |
| Client UI | src/client/{Inspector,Render,…}/ | Chat UI |
| Registry wiring | packages/builtin-tools/src/*.ts+src/store/tool/slices/builtin/executors/index.ts | Framework |
Read These First
| Question | Doc |
|---|---|
| Where do files live? What does each face do? Wiring? | architecture.md |
| How do I name the tool, design APIs, write the manifest, executor, ExecutionRuntime? | tool-design.md |
| How do I build Inspector / Render / Placeholder / Streaming / Intervention / Portal? | ui/ |
When to Use This Skill
- Creating a new
packages/builtin-tool-<name>/package - Adding a new API method to an existing builtin tool
- Building or restyling any of the 6 client surfaces for a tool
- Wiring a tool into the central registries
- Debugging “tool not found / API not found / render not showing / placeholder stuck” errors
Top-Level Design Principles
lobe-<domain>identifier is permanent.It’s stored in message history. Renames need@deprecatedaliases (seepackages/builtin-tools/src/inspectors.ts:88-89). Get it right the first time.- ApiName is an
as constobject, not a TS enum. It doubles as the runtime listBaseExecutoriterates over. - Three result fields, three audiences:
content: string→ the LLM reads itstate: Record<…>→ the UI’spluginState;result-domain only, never echo all params backerror: { type, message, body? }→ both LLM and UI;typeis a stable code
- Split execution from frontend wiring.
src/ExecutionRuntime/— pure runtime, no React, no Zustand, accepts services via constructor.The default place for new logic.src/client/executor/—BaseExecutorsubclass that callsExecutionRuntime(or stores/services directly when frontend-only).
- UI defaults to “do nothing”.Inspector is required (the header strip). Render/Placeholder/Streaming/Intervention/Portal are addedonly when there’s something specific to show— empty registries are fine.
- Style with
createStaticStyles + cssVar.*(zero-runtime). Fall back tocreateStyles + tokenonly when you genuinely need runtime values. Use@lobehub/uicomponents, not raw antd. - i18n keys live in
src/locales/default/plugin.ts.Inspector titles must come fromt('builtins.<identifier>.apiName.<api>')so something renders while args stream.
Package Layout (preferred, post-2026 convention)
packages/builtin-tool-<name>/ ├── package.json └── src/ ├── index.ts # exports manifest + types + systemRole + Identifier (no React, no stores) ├── manifest.ts # BuiltinToolManifest with JSON Schema for every API ├── types.ts # ApiName const + Params/State interfaces per API ├── systemRole.ts # System prompt teaching the model when/how to use the APIs ├── ExecutionRuntime/ # ✅ Default home for runtime logic (server- or anywhere-callable) │ └── index.ts └── client/ ├── index.ts # Re-exports for the registries ├── executor/ # ✅ Frontend executor — extends BaseExecutor, often delegates to ExecutionRuntime │ └── index.ts ├── Inspector/ # required — header chip per API ├── Render/ # optional — rich result card ├── Placeholder/ # optional — skeleton during streaming/execution ├── Streaming/ # optional — live output renderer (e.g. RunCommand, WriteFile) ├── Intervention/ # optional — approval / edit-before-run UI ├── Portal/ # optional — full-screen detail view └── components/ # shared subcomponents used by the surfaces aboveOlder packages(builtin-tool-task,builtin-tool-calculator, etc.) still havesrc/executor/as a sibling ofsrc/client/. That’s grandfathered;don’t relocate without a deliberate refactor. New packages and new APIs added to existing packages should follow the layout above.
package.jsonexports map:
"exports":{".":"./src/index.ts","./client":"./src/client/index.ts","./executor":"./src/client/executor/index.ts","./executionRuntime":"./src/ExecutionRuntime/index.ts"}Authoring Checklist
Before opening the PR:
- Identifier follows
lobe-<domain>and isstable(lives in message history). - Every
<Name>ApiNamevalue has: a manifestapi[]entry, an executor method, an Inspector, an i18napiName.*key. Paramsinterfaces match the JSON Schema;Stateinterfaces match what the executor returns and what the UI surfaces read.- System prompt disambiguates confusable APIs and points to batch variants.
- Runtime logic lives in
ExecutionRuntime/; theclient/executor/only wires stores/services and delegates. - Executor returns
{ success, content, state, error? }via a singletoResult()funnel —contentalways non-empty (default toerror.message). - Inspector handles
isArgumentsStreaming,isLoading,partialArgs, missingpluginState. - Render returns
nulluntil it has data; only created for APIs with rich results. - Placeholder added if the API has a perceivable execution lag (search, list, crawl).
- Streaming added for APIs that emit incremental output (run command, write file, code execution).
- Intervention added if
humanInterventionis set in the manifest. - All registry files updated (see architecture.md → Registry wiring).
- i18n keys in
src/locales/default/plugin.tsplus dev seeds inen-US/zh-CN. bunx vitest run --silent='passed-only' 'packages/builtin-tool-<name>'passes.bun run type-checkpasses.
Reference Tools
Pick the closest neighbor and copy:
| If your tool is… | Read first |
|---|---|
| Pure-compute, no UI state | packages/builtin-tool-calculator/—ExecutionRuntimereuses executor (mathjs/nerdamer work everywhere) |
| CRUD over a domain entity | packages/builtin-tool-task/— full Inspector + Render set, batch variants |
| Heavy UI (Inspector/Render/Placeho | |
| lder/Portal) | packages/builtin-tool-web-browsing/— search-style result UI, Portal for detail view |
| Desktop / filesystem with all surfaces (incl. Streaming + Intervention) | packages/builtin-tool-local-system/—ExecutionRuntimeinjects anILocalSystemService, executor calls it |
| Server-side pure (no client executor) | packages/builtin-tool-web-browsing/— onlyExecutionRuntimeis exported; the chat client doesn’t run it |
| Needs human approval before running | packages/builtin-tool-local-system/src/client/Intervention/— per-API approval components |