Documentation Index
Fetch the complete documentation index at: https://docs.ixo.world/llms.txt
Use this file to discover all available pages before exploring further.
The finished plugin in one snippet
This is what you are about to build — everyOraclePlugin hook wired against Open-Meteo. The canonical source: apps/qiforge-example/src/plugins/weather/weather.plugin.ts.
Prerequisites
- A working
main.tscallingcreateOracleApp— see Create your oracle. - The oracle scaffolded by the CLI (
qiforge init) — see the CLI reference. - Files live under
src/plugins/weather/— same layout as the reference apps/qiforge-example/src/plugins/weather/.
Step-by-step
Create the skeleton with a manifest and config schema
File: That’s a valid plugin — it loads, validates
weather.plugin.tsWEATHER_DEFAULT_UNITS, and contributes nothing yet. Everything below adds one hook at a time.Write the upstream client
File: Keep it tiny — this guide is about the plugin contract, not weather APIs.
weather-client.ts. Open-Meteo doesn’t need auth.Add a boot-time tool with getTools
File: Wire it on the plugin:The handler still receives a full
weather-tools.ts.getTools(ctx) is called once per agent build. Use it when the tool’s behaviour depends only on plugin config — not on per-request data.RuntimeContext at call time — ctx.user, ctx.session, ctx.abortSignal are all live.Add a request-time tool with getRequestTools
When a tool depends on per-request data (e.g. the user’s timezone), register it via Boot-time and request-time outputs are merged — both tools end up in the agent’s tool list.
getRequestTools(rtCtx) instead:Add a sub-agent with getSubAgents
File:
weather-sub-agent.ts.Sub-agents have their own prompt and tool list, and the runtime exposes each as a single tool to the main agent (call_weather_planner_agent). Use them for compound tasks that benefit from focused context.forwardTools: true surfaces the sub-agent’s inner tool calls in the parent chat’s UI events so users see the chain.Add a middleware with getMiddlewares
File: Plugin middleware runs after the framework’s always-on middleware (tool validation, retry, page context, safety guardrail), in topological dependency order across plugins.
weather-middleware.ts.Middleware runs around every LLM call. Hooks come from LangChain’s createMiddleware.Add an HTTP route with getNestModules + getAuthExcludedRoutes
File: Register it from the plugin and opt the route out of UCAN auth:
weather.module.ts.To expose a public GET /weather/now?city=X, ship a NestJS module:Expose shared state with getSharedState
Other plugins can now read the last weather query for the current session:Your tool/sub-agent handlers write into
this.lastBySession after every successful lookup (see step 3). Consumers read it as rtCtx.shared.lastWeatherQuery.Register the plugin in main.ts
Verify every hook works end-to-end
Boot the app (
Full manual walkthrough: apps/qiforge-example/WEATHER-PLUGIN.md.
pnpm dev) and exercise each hook.| Hook | How to verify |
|---|---|
getNestModules + getAuthExcludedRoutes | curl 'http://localhost:5678/weather/now?city=Berlin' returns JSON without a UCAN header. |
manifest.visibility: 'on-demand' | Chat what's the weather in Berlin? — the agent calls list_capabilities and/or load_capability before any weather tool. |
getTools | After weather is loaded, chat what's the temperature in Tokyo? — get_current_weather fires. |
getRequestTools | Chat forecast for São Paulo this week with an x-timezone header — get_weather_forecast fires; handler reads rtCtx.user.timezone. |
getSubAgents + forwardTools | Chat should I bring a jacket to Berlin tomorrow? — main agent calls call_weather_planner_agent, which chains get_weather_forecast then recommend_outfit. Both inner calls show in the UI. |
getMiddlewares | Server logs show model call started / model call complete (Xms) for every weather turn. |
getSharedState | Inside another plugin’s tool: rtCtx.shared.lastWeatherQuery returns the latest record for this session. |
configSchema | Set WEATHER_DEFAULT_UNITS=kelvin and boot — fails with a Zod error pointing at the weather plugin. |
Where to read next
Test your plugin
Tier A direct-invoke and Tier B agent-loop tests.
Plugin recipes
Per-hook deep dives (tool, sub-agent, middleware, HTTP, state).
Plugin API reference
Every hook signature, exhaustively.
Plugin anatomy
How the runtime turns a class into a registered plugin.