root-wiring
Understand and modify the wiring of main.go (root) — how tools, sub-agents, plugins and toolsets are assembled into the lead agent. Use when adding a sub-agent, swapping a plugin, changing the toolset list, or debugging why a feature isn't reaching the agent. Mention triggers - root binary, main.go, wiring, lead agent, agenttool, NewMultiLoader, plugins.
- License 许可
- MIT
- 所属仓库
- blouargant/omnis
- 最近更新
- 2026-11-10
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- root-wiring
- description
- Understand and modify the wiring of main.go (root) — how tools, sub-agents, plugins and toolsets are assembled into the lead agent. Use when adding a sub-agent, swapping a plugin, changing the toolset list, or debugging why a feature isn't reaching the agent. Mention triggers - root binary, main.go, wiring, lead agent, agenttool, NewMultiLoader, plugins.
03 SKILL.md 正文
main.go (root) wiring
This is the only file in the project that assembles components. It contains no logic of its own — every change here is "I want component X to be part of the running agent".
Mental model
┌──────────────┐
│ agentkit.NewModel(ctx) ← reads OMNIS_PROVIDER
└──────┬───────┘
│ llm
▼
┌────────────────────────────────────────────────────────┐
│ leadTools = []tool.Tool{ │
│ fstools.New()..., // file/bash/grep/glob │
│ store.Tools()..., // todo │
│ g.Tools()..., // tasks │
│ worktree.Tools(repo)..., // git worktrees │
│ q.Tool(), // bash_background │
│ leadMailbox.Tools()..., // teammate comms │
│ agenttool.New(investigator), // sub-agent as tool │
│ agenttool.New(summariser), // sub-agent as tool │
│ } │
│ │
│ toolsets = [skills.Toolset, mcp.Toolsets...] │
└────────────────────────────────────────────────────────┘
│
▼
agentkit.New({Tools, Toolsets}) ──► lead
│
▼
adkagent.NewMultiLoader(lead, investigator, summariser)
│
▼
full.NewLauncher().Execute(ctx, cfg, args)
Common changes
Add a new tool
leadTools = append(leadTools, mypkg.New()...)
Place it before the lead's agentkit.New(...) call.
Add a sub-agent
Important: do NOT pass sub-agents to
SubAgentsin the lead'sagentkit.AgentConfig. WhenSubAgentsis non-empty, ADK injects atransfer_to_agentfunction into the lead. That function permanently hands off control — the lead never resumes after the call. Useagenttool.Newinstead: it wraps the sub-agent as a regular tool that returns its output to the caller. In the root agent, also wrap the AgentTool withnewNonConcurrentToolso duplicate calls to the same sub-agent in one model turn fail fast instead of blocking the turn.
critic, err := agentkit.New(agentkit.AgentConfig{
Name: "critic",
Description: "Pokes holes in a proposed plan.",
Model: llm,
Instruction: "You are an adversarial reviewer. ...", // role, not domain
})
if err != nil { return err }
// Register as a tool so control always returns to the leader.
wrappedCritic, ok := agenttool.New(critic, &agenttool.Config{}).(runnableTool)
if !ok { return fmt.Errorf("agenttool for critic is not runnable") }
leadTools = append(leadTools, newNonConcurrentTool(wrappedCritic))
// Add to the multi-loader so the launcher can address it:
loader, err := adkagent.NewMultiLoader(lead, investigator, summariser, critic)
Add a plugin
if p, err := mypkg.NewPlugin("mine"); err == nil {
plugins = append(plugins, p)
}
Convention: never return err from a plugin constructor inside run()
— treat plugin failure as best-effort (log via the events plugin if
needed). Permission plugin is the exception (it's safety-critical).
Add an MCP server
Don't touch this file. Edit config/mcp_config.json instead — it's
already loaded via mcpcfg.Load("config/mcp_config.json").
Add a skill
Don't touch this file. Drop a skills/<name>/SKILL.md — the
skills.Toolset(ctx, "skills") call already discovers it.
Things to leave alone
- The
SystemPrompt/ leadInstructiontext. They are intentionally domain-neutral. If you want to change agent behaviour by domain, do it via a skill, not here. - The investigator / summariser sub-agents. They are the harness's generic "roles". Add new sub-agents alongside; don't repurpose these.
- The mailbox backend choice (
teammates.ChooseBackend()readsREDIS_URL). Don't hard-code a backend.
Order matters
agentkit.NewModel— fails fast on missing API key.- Toolsets (skills, MCP) — loaded best-effort; failures are logged.
- Mailbox backend —
defer be.Close()must come before the lead is built so it survives the function. - Sub-agents — built before the lead, then added to
leadToolsviaagenttool.New. - Lead — built last, with the full
leadToolsslice. NewMultiLoader(lead, ...subAgents)— must list every agent addressable by the launcher.- Plugins — assembled into
runner.PluginConfig. full.NewLauncher().Execute(ctx, cfg, args)— the only blocking call.
Verify after a change
PATH=$HOME/.local/go/bin:$PATH go build ./... && \
PATH=$HOME/.local/go/bin:$PATH go vet ./... && echo OK
PATH=$HOME/.local/go/bin:$PATH go run . console
> what tools and skills do you have?
The agent should enumerate every tool/skill you wired.
04 同仓库更多 Skills
skill-creator
Create or update a skill playbook (SKILL.md) for the agent. Use when the user wants to create a new skill, add a skill, define a new agent capability, update an existing skill, edit a skill, refine a skill playbook, or specialise the agent for a new domain.
review
Review a body of work (source code, configuration, documents, infra manifests, …) for correctness, clarity, and obvious risks. Use this skill whenever the user asks for a review, audit or critique.
Fallback PDF text extractor using pdftotext (poppler). Use ONLY when the preferred `liteparse` skill is unavailable or for a quick plain-text dump of a simple text PDF — for the best PDF parsing (scanned, multi-column, layout-heavy, or non-PDF formats) prefer the `liteparse` skill.
pandoc
This skill should be used when converting documents between formats (Markdown, DOCX, PDF, HTML, LaTeX, etc.) using pandoc. Use for format conversion, document generation, and preparing markdown for Google Docs or other word processors.
liteparse
Preferred local parser for extracting text from PDFs, images, and scanned/layout-heavy documents (OCR, screenshots, complex PDFs) — far better than pdftotext. Use this FIRST for any PDF, image, or OCR text-extraction or conversion task. NOTE for Office documents (DOCX, PPTX, XLSX, ODT) — for plain text extraction prefer the `pandoc` skill, which needs no LibreOffice; only use LiteParse for Office docs when you need its layout/OCR/screenshot output. The `pdf` skill (pdftotext) is only a fallback for when LiteParse cannot be installed.
linux-admin
Safely make a change to a Linux workstation — install/remove packages, manage systemd services and timers, edit and validate configuration files, manage users/permissions and networking. Detect the distro and package manager, determine whether the target is package-managed or hand-maintained, preview or simulate every change, back up configs before editing, and prefer the package manager and drop-in overrides so the host stays consistent and secure. Use whenever a change to the local Linux host is required (install, remove, enable, disable, start, stop, edit a config, add a user, change permissions or networking).