feat: initial public release (MAESTRO)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* スモークテスト: 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();
|
||||
Reference in New Issue
Block a user