96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
/**
|
|
* スモークテスト: 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://10.0.0.10: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();
|