/** * スモークテスト: LLM接続 → エージェントループの動作確認 * 実行: npx tsx test-smoke.ts */ import { OpenAICompatClient } from './src/llm/openai-compat.js'; import { executeMovement, Movement } from './src/engine/agent-loop.js'; import { ToolContext } from './src/engine/tools.js'; import { mkdirSync } from 'fs'; import { join } from 'path'; const BASE_URL = process.env['OLLAMA_BASE_URL'] ?? 'http://192.168.1.148:11434/v1'; const MODEL = process.env['OLLAMA_MODEL'] ?? 'qwen3:8b'; async function testLLMConnection() { console.log('=== Test 1: LLM接続確認 ==='); const client = new OpenAICompatClient(BASE_URL, MODEL); for await (const event of client.chat([ { role: 'user', content: 'Say "hello" in one word.' } ])) { if (event.type === 'text') process.stdout.write(event.text); if (event.type === 'error') console.error('\nError:', event.error); if (event.type === 'done') console.log('\n[done]', event.usage ?? ''); } } async function testToolUse() { console.log('\n=== Test 2: ツール呼び出し確認 ==='); const client = new OpenAICompatClient(BASE_URL, MODEL); // テスト用ワークスペース作成 const workspace = '/tmp/agent-test-workspace'; mkdirSync(join(workspace, 'input'), { recursive: true }); mkdirSync(join(workspace, 'output'), { recursive: true }); // テスト用入力ファイル作成 const { writeFileSync } = await import('fs'); writeFileSync(join(workspace, 'input', 'sample.txt'), 'これはテストファイルです。\n行1\n行2\n行3\n'); const movement: Movement = { name: 'test', edit: true, persona: 'テスター', instruction: 'input/sample.txt を読み込んで内容を確認し、output/result.txt に「確認完了」と書き込んでください。', allowedTools: ['Read', 'Write', 'Bash', 'Glob'], rules: [ { condition: '作業が完了した', next: 'COMPLETE' }, ], }; const ctx: ToolContext = { workspacePath: workspace, editAllowed: true }; console.log(`Workspace: ${workspace}`); console.log(`Model: ${MODEL}`); console.log('Running agent loop...\n'); const result = await executeMovement( movement, 'テストタスク: ファイルの読み書き確認', client, ctx, { onToolUse: (name, input) => console.log(` [tool] ${name}(${JSON.stringify(input).slice(0, 100)})`), onText: (text) => process.stdout.write(text), }, 10, // max 10 iterations ); console.log('\n\n--- Result ---'); console.log('next:', result.next); console.log('tools used:', result.toolsUsed); console.log('output length:', result.output.length); // output/result.txt が存在するか確認 try { const { readFileSync } = await import('fs'); const output = readFileSync(join(workspace, 'output', 'result.txt'), 'utf-8'); console.log('output/result.txt:', output); } catch { console.log('output/result.txt: (not created)'); } } async function main() { try { await testLLMConnection(); await testToolUse(); console.log('\n=== All tests passed ==='); } catch (err) { console.error('Test failed:', err); process.exit(1); } } main();