feat: add tool framework foundation (types, registry, executor, shell tool, model types, SOUL.md)

- Task 0: SOUL.md + loadSystemPrompt() in daemon
- Task 1: Tool type definitions (Tool, ToolCall, ToolResult, etc.)
- Task 2: ToolRegistry with Anthropic/OpenAI serialization
- Task 3: ToolExecutor with hooks, timeout, truncation
- Task 4: shell.exec builtin tool
- Task 8: Model types updated for tool use (ToolDefinition, ModelToolCall, etc.)
- Task 15: Model index exports for tool types
This commit is contained in:
William Valentin
2026-02-05 17:39:40 -08:00
parent 32dd3ad728
commit b00706325b
13 changed files with 691 additions and 7 deletions
+17 -4
View File
@@ -8,7 +8,7 @@ import { SessionStore, SessionManager } from '../session/index.js';
import { HookEngine } from '../hooks/index.js';
import { resolve } from 'path';
import { homedir } from 'os';
import { mkdirSync } from 'fs';
import { mkdirSync, readFileSync, existsSync } from 'fs';
export interface DaemonContext {
config: Config;
@@ -21,9 +21,22 @@ export interface DaemonContext {
modelRouter: ModelRouter;
}
const SYSTEM_PROMPT = `You are Flynn, a helpful personal AI assistant. You are direct, concise, and helpful. You can help with a variety of tasks including answering questions, providing information, and having conversations.
function loadSystemPrompt(): string {
// Try to load SOUL.md from working directory first, then from project root
const paths = [
resolve(process.cwd(), 'SOUL.md'),
resolve(import.meta.dirname, '../../SOUL.md'),
];
Keep responses focused and avoid unnecessary verbosity. Use markdown formatting when it improves readability.`;
for (const soulPath of paths) {
if (existsSync(soulPath)) {
return readFileSync(soulPath, 'utf-8');
}
}
// Fallback if SOUL.md not found
return 'You are Flynn, a helpful personal AI assistant. Be direct, concise, and helpful. Use markdown when it improves readability.';
}
function createModelRouter(config: Config): ModelRouter {
const models = config.models;
@@ -117,7 +130,7 @@ export async function startDaemon(config: Config): Promise<DaemonContext> {
// Initialize native agent with session
const agent = new NativeAgent({
modelClient: modelRouter,
systemPrompt: SYSTEM_PROMPT,
systemPrompt: loadSystemPrompt(),
session,
});