mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 14:16:43 +00:00
- reorganize bin/ into auth/, glmt/, management/, utils/ - add budget calculator and locale enforcer - enhance test coverage with unit/integration separation
231 lines
9.0 KiB
JavaScript
Executable File
231 lines
9.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
'use strict';
|
|
|
|
const https = require('https');
|
|
|
|
const API_KEY = process.env.Z_AI_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN;
|
|
const MODEL = 'GLM-4.6';
|
|
|
|
if (!API_KEY || API_KEY === 'your-api-key-here') {
|
|
console.error('[ERROR] Z.AI API key not found');
|
|
console.error('[INFO] Set Z_AI_API_KEY or ANTHROPIC_AUTH_TOKEN environment variable');
|
|
console.error('[INFO] Example: export Z_AI_API_KEY=your-key-here');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Test request with reasoning
|
|
const requestBody = JSON.stringify({
|
|
model: MODEL,
|
|
messages: [
|
|
{
|
|
role: 'user',
|
|
content: 'Solve this math problem step by step: What is 27 * 453? Show your reasoning process.'
|
|
}
|
|
],
|
|
stream: true,
|
|
reasoning: true,
|
|
reasoning_effort: 'medium',
|
|
max_tokens: 4096,
|
|
do_sample: true
|
|
});
|
|
|
|
const options = {
|
|
hostname: 'api.z.ai',
|
|
port: 443,
|
|
path: '/api/coding/paas/v4/chat/completions',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${API_KEY}`,
|
|
'Content-Length': Buffer.byteLength(requestBody),
|
|
'User-Agent': 'CCS-GLMT-StreamingTest/1.0'
|
|
}
|
|
};
|
|
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('Z.AI STREAMING BEHAVIOR TEST');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('[TEST] Initiating streaming request to Z.AI');
|
|
console.log('[TEST] Model:', MODEL);
|
|
console.log('[TEST] Stream: true');
|
|
console.log('[TEST] Reasoning: true');
|
|
console.log('[TEST] Reasoning Effort: medium');
|
|
console.log('[TEST] API Key:', API_KEY.substring(0, 10) + '...');
|
|
console.log('');
|
|
|
|
const startTime = Date.now();
|
|
let firstByteTime = null;
|
|
|
|
const req = https.request(options, (res) => {
|
|
console.log('[HTTP] Status:', res.statusCode);
|
|
console.log('[HTTP] Content-Type:', res.headers['content-type']);
|
|
console.log('');
|
|
|
|
if (res.statusCode !== 200) {
|
|
let errorBody = '';
|
|
res.on('data', chunk => errorBody += chunk);
|
|
res.on('end', () => {
|
|
console.error('[ERROR] Request failed:', res.statusCode, res.statusMessage);
|
|
console.error('[ERROR] Response:', errorBody);
|
|
process.exit(1);
|
|
});
|
|
return;
|
|
}
|
|
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('SSE EVENTS (analyzing streaming behavior)');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('');
|
|
|
|
let buffer = '';
|
|
let eventCount = 0;
|
|
let reasoningEventCount = 0;
|
|
let reasoningInDelta = false;
|
|
let reasoningInMessage = false;
|
|
let totalReasoningChunks = [];
|
|
let textEventCount = 0;
|
|
|
|
res.on('data', (chunk) => {
|
|
if (!firstByteTime) {
|
|
firstByteTime = Date.now();
|
|
console.log('[TIMING] Time to first byte:', firstByteTime - startTime, 'ms');
|
|
console.log('');
|
|
}
|
|
|
|
buffer += chunk.toString();
|
|
const lines = buffer.split('\n');
|
|
|
|
// Keep incomplete line in buffer
|
|
buffer = lines.pop() || '';
|
|
|
|
lines.forEach(line => {
|
|
if (line.startsWith('data: ')) {
|
|
eventCount++;
|
|
const data = line.substring(6);
|
|
|
|
if (data === '[DONE]') {
|
|
console.log(`[EVENT ${eventCount}] [DONE]`);
|
|
console.log('');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const parsed = JSON.parse(data);
|
|
const choice = parsed.choices?.[0];
|
|
const delta = choice?.delta;
|
|
const message = choice?.message;
|
|
|
|
// Check for reasoning_content in delta
|
|
if (delta?.reasoning_content) {
|
|
reasoningInDelta = true;
|
|
reasoningEventCount++;
|
|
totalReasoningChunks.push(delta.reasoning_content);
|
|
|
|
console.log(`[EVENT ${eventCount}] *** REASONING IN DELTA ***`);
|
|
console.log(' Delta keys:', Object.keys(delta).join(', '));
|
|
console.log(' Reasoning chunk length:', delta.reasoning_content.length);
|
|
console.log(' Reasoning chunk preview:', JSON.stringify(delta.reasoning_content.substring(0, 80)));
|
|
console.log('');
|
|
}
|
|
|
|
// Check for reasoning_content in message (complete)
|
|
if (message?.reasoning_content) {
|
|
reasoningInMessage = true;
|
|
console.log(`[EVENT ${eventCount}] *** REASONING IN MESSAGE (COMPLETE) ***`);
|
|
console.log(' Message keys:', Object.keys(message).join(', '));
|
|
console.log(' Reasoning total length:', message.reasoning_content.length);
|
|
console.log(' Reasoning preview:', message.reasoning_content.substring(0, 100).replace(/\n/g, ' '));
|
|
console.log('');
|
|
}
|
|
|
|
// Check for text content in delta
|
|
if (delta?.content) {
|
|
textEventCount++;
|
|
if (textEventCount <= 3 || eventCount % 10 === 0) {
|
|
console.log(`[EVENT ${eventCount}] Text delta`);
|
|
console.log(' Content:', JSON.stringify(delta.content));
|
|
console.log('');
|
|
}
|
|
}
|
|
|
|
// Show finish_reason
|
|
if (choice?.finish_reason) {
|
|
console.log(`[EVENT ${eventCount}] Finish reason: ${choice.finish_reason}`);
|
|
console.log('');
|
|
}
|
|
|
|
// Show usage stats
|
|
if (parsed.usage) {
|
|
console.log(`[EVENT ${eventCount}] Usage:`, JSON.stringify(parsed.usage));
|
|
console.log('');
|
|
}
|
|
|
|
} catch (e) {
|
|
console.log(`[EVENT ${eventCount}] [PARSE ERROR]`, e.message);
|
|
console.log(' Raw:', data.substring(0, 100));
|
|
console.log('');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
res.on('end', () => {
|
|
const totalTime = Date.now() - startTime;
|
|
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('TEST RESULTS');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('');
|
|
console.log('[TIMING]');
|
|
console.log(' Time to first byte:', firstByteTime - startTime, 'ms');
|
|
console.log(' Total duration:', totalTime, 'ms');
|
|
console.log('');
|
|
console.log('[EVENTS]');
|
|
console.log(' Total events:', eventCount);
|
|
console.log(' Text content events:', textEventCount);
|
|
console.log(' Reasoning events:', reasoningEventCount);
|
|
console.log('');
|
|
console.log('[REASONING BEHAVIOR]');
|
|
console.log(' Reasoning in delta (incremental):', reasoningInDelta);
|
|
console.log(' Reasoning in message (complete):', reasoningInMessage);
|
|
if (totalReasoningChunks.length > 0) {
|
|
const totalReasoningLength = totalReasoningChunks.join('').length;
|
|
console.log(' Total reasoning chunks:', totalReasoningChunks.length);
|
|
console.log(' Total reasoning length:', totalReasoningLength);
|
|
}
|
|
console.log('');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
console.log('SCENARIO DETERMINATION');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
|
|
if (reasoningInDelta) {
|
|
console.log('');
|
|
console.log('[✓] SCENARIO A: Incremental Streaming');
|
|
console.log(' reasoning_content appears in delta objects');
|
|
console.log(' Multiple events contain reasoning chunks');
|
|
console.log(' RECOMMENDATION: Proceed with full streaming implementation');
|
|
} else if (reasoningInMessage) {
|
|
console.log('');
|
|
console.log('[!] SCENARIO B: Complete at End');
|
|
console.log(' reasoning_content only in final message object');
|
|
console.log(' No intermediate reasoning chunks');
|
|
console.log(' RECOMMENDATION: Hybrid streaming (text streams, reasoning buffered)');
|
|
} else {
|
|
console.log('');
|
|
console.log('[X] SCENARIO C: No Streaming Support');
|
|
console.log(' No reasoning_content in streaming mode');
|
|
console.log(' RECOMMENDATION: Keep buffered mode only');
|
|
}
|
|
console.log('');
|
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
});
|
|
});
|
|
|
|
req.on('error', (error) => {
|
|
console.error('[ERROR]', error.message);
|
|
process.exit(1);
|
|
});
|
|
|
|
req.write(requestBody);
|
|
req.end();
|