refactor: migrate server provisioning to Cloud Orchestrator service

- Remove Queue-based server provisioning (moved to cloud-orchestrator)
- Add manage_server tool with Service Binding to Cloud Orchestrator
- Add CDN cache hit rate estimation based on tech_stack
- Always display bandwidth info (show "포함 범위 내" when no overage)
- Add language auto-detection (ko, ja, zh, en)
- Update system prompt to always call tools fresh
- Add Server System documentation to CLAUDE.md

BREAKING: Server provisioning now requires cloud-orchestrator service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-26 12:26:21 +09:00
parent 5413605347
commit 87c92e1ed1
27 changed files with 695 additions and 4584 deletions

View File

@@ -1,117 +0,0 @@
#!/usr/bin/env npx tsx
/**
* Telegram Bot CLI Chat Client
* - Worker의 /api/test 엔드포인트를 통해 직접 대화
* - 사용법: npm run chat
* 또는: npm run chat "메시지"
*/
import * as readline from 'readline';
import * as fs from 'fs';
import * as path from 'path';
// .env 파일 로드
const envPath = path.join(process.cwd(), '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf-8');
for (const line of envContent.split('\n')) {
const [key, ...valueParts] = line.split('=');
if (key && valueParts.length > 0) {
process.env[key.trim()] = valueParts.join('=').trim();
}
}
}
const WORKER_URL = process.env.WORKER_URL || 'https://telegram-summary-bot.kappa-d8e.workers.dev';
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
const USER_ID = process.env.TELEGRAM_USER_ID || '821596605';
interface TestResponse {
input: string;
response: string;
user_id: string;
error?: string;
}
async function sendMessage(text: string): Promise<string> {
if (!WEBHOOK_SECRET) {
return '❌ WEBHOOK_SECRET 환경변수가 필요합니다.\n export WEBHOOK_SECRET="your-secret"';
}
try {
const response = await fetch(`${WORKER_URL}/api/test`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
text,
user_id: USER_ID,
secret: WEBHOOK_SECRET,
}),
});
const data = await response.json() as TestResponse;
if (data.error) {
return `❌ Error: ${data.error}`;
}
return data.response;
} catch (error) {
return `❌ Request failed: ${error}`;
}
}
async function interactiveMode() {
console.log('🤖 Telegram Bot CLI');
console.log(`📡 ${WORKER_URL}`);
console.log(`👤 User: ${USER_ID}`);
console.log('─'.repeat(40));
console.log('메시지를 입력하세요. 종료: exit\n');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const prompt = () => {
rl.question('\x1b[36m>\x1b[0m ', async (input) => {
const text = input.trim();
if (text === 'exit' || text === 'quit' || text === 'q') {
console.log('👋 종료');
rl.close();
process.exit(0);
}
if (!text) {
prompt();
return;
}
console.log('\x1b[33m⏳ 처리 중...\x1b[0m');
const response = await sendMessage(text);
console.log(`\n\x1b[32m🤖\x1b[0m ${response}\n`);
prompt();
});
};
prompt();
}
async function main() {
const args = process.argv.slice(2);
if (args.length > 0) {
// 단일 메시지 모드
const text = args.join(' ');
const response = await sendMessage(text);
console.log(response);
} else {
// 대화형 모드
await interactiveMode();
}
}
main().catch(console.error);