Extending TAI
TAI is designed to be extended with custom tools, channels, and providers.
Adding a new tool (code)
- Create
packages/core/src/tools/<name>.tsimplementing theToolinterface:
import type { Tool } from "./interface.js";
export function createMyTool(config: any): Tool {
return {
name: "my_tool",
description: "Does something useful",
parameters: {
type: "object",
properties: {
input: { type: "string", description: "The input" },
},
required: ["input"],
},
execute: async (args) => {
return `Result: ${args.input}`;
},
};
}
-
Add config type in
packages/core/src/config.tsunderAgentConfig.tools -
Wire it up in
packages/core/src/factories.tsin thecreateTools()function -
Export from
packages/core/src/index.ts
Adding a custom tool (config-only)
No code needed — add an entry under custom_tools in config.yaml:
custom_tools:
hello:
description: "Say hello to someone"
parameters:
name: { type: "string", description: "Name to greet" }
command: "echo Hello {{name}}"
timeout_ms: 5000
Custom tools are rebuilt on every runtime reload, so adding one makes it available immediately.
Adding a new channel
- Create
packages/core/src/channels/<name>.tsimplementingChannel:
import type { Channel } from "./interface.js";
export class MyChannel implements Channel {
async start(): Promise<void> { /* ... */ }
async stop(): Promise<void> { /* ... */ }
}
-
Add config type in
packages/core/src/config.tsunderAgentConfig.channels -
Wire it up in
packages/cli/src/index.tsin therunServe()function -
Export from
packages/core/src/index.ts -
Sessions are keyed per-user: use
findOrCreateSession(db, "channelname:userId", model, provider)
Adding a new provider
- Create
packages/core/src/providers/<name>.tsimplementingAIProvider:
import type { AIProvider, ChatParams, Message } from "./interface.js";
export class MyProvider implements AIProvider {
async chat(params: ChatParams): Promise<Message> {
// Call your LLM API
}
}
-
Add config type in
packages/core/src/config.tsunderAgentConfig.providers -
Add provider creation in
packages/core/src/factories.tsin thecreateProvider()function -
Export from
packages/core/src/index.ts
Conventions
- Tool descriptions: 1-2 sentences max (for local model compatibility)
- ESM imports: Use relative
.jsextensions within packages - Cross-package imports: Use
@agent/*workspace specifiers - Config defaults: Use
DEFAULT_CONFIGinconfig.tsas the single source of truth - All configurable values go in
config.yaml/AgentConfig - Node.js built-ins: Prefer
node:prefixed imports