call-ai 0.7.0-dev-preview-8 → 0.7.0-dev-preview-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +65 -9
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -35,10 +35,26 @@ function callAI(prompt, options = {}) {
|
|
|
35
35
|
// Make the fetch request and handle errors before creating the generator
|
|
36
36
|
console.log(`[callAI:${PACKAGE_VERSION}] Making fetch request to: ${endpoint}`);
|
|
37
37
|
console.log(`[callAI:${PACKAGE_VERSION}] With model: ${model}`);
|
|
38
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Request headers:`, JSON.stringify(requestOptions.headers));
|
|
38
39
|
let response;
|
|
39
40
|
try {
|
|
40
41
|
response = await fetch(endpoint, requestOptions);
|
|
41
42
|
console.log(`[callAI:${PACKAGE_VERSION}] Fetch completed with status:`, response.status, response.statusText);
|
|
43
|
+
// Log all headers
|
|
44
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Response headers:`);
|
|
45
|
+
response.headers.forEach((value, name) => {
|
|
46
|
+
console.log(`[callAI:${PACKAGE_VERSION}] ${name}: ${value}`);
|
|
47
|
+
});
|
|
48
|
+
// Clone response for diagnostic purposes only
|
|
49
|
+
const diagnosticResponse = response.clone();
|
|
50
|
+
try {
|
|
51
|
+
// Try to get the response as text for debugging
|
|
52
|
+
const responseText = await diagnosticResponse.text();
|
|
53
|
+
console.log(`[callAI:${PACKAGE_VERSION}] First 500 chars of response body:`, responseText.substring(0, 500) + (responseText.length > 500 ? '...' : ''));
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Could not read response body for diagnostics:`, e);
|
|
57
|
+
}
|
|
42
58
|
}
|
|
43
59
|
catch (fetchError) {
|
|
44
60
|
console.error(`[callAI:${PACKAGE_VERSION}] Network error during fetch:`, fetchError);
|
|
@@ -47,6 +63,7 @@ function callAI(prompt, options = {}) {
|
|
|
47
63
|
// Explicitly check for HTTP error status and log extensively
|
|
48
64
|
console.log(`[callAI:${PACKAGE_VERSION}] Response.ok =`, response.ok);
|
|
49
65
|
console.log(`[callAI:${PACKAGE_VERSION}] Response.status =`, response.status);
|
|
66
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Response.type =`, response.type);
|
|
50
67
|
// Enhanced error handling with more debugging - MUST check !response.ok
|
|
51
68
|
if (!response.ok) {
|
|
52
69
|
console.log(`[callAI:${PACKAGE_VERSION}] Detected error response with status:`, response.status);
|
|
@@ -462,8 +479,16 @@ async function extractClaudeResponse(response) {
|
|
|
462
479
|
/**
|
|
463
480
|
* Generator factory function for streaming API calls
|
|
464
481
|
* This is called after the fetch is made and response is validated
|
|
482
|
+
*
|
|
483
|
+
* Note: Even though we checked response.ok before creating this generator,
|
|
484
|
+
* we need to be prepared for errors that may occur during streaming. Some APIs
|
|
485
|
+
* return a 200 OK initially but then deliver error information in the stream.
|
|
465
486
|
*/
|
|
466
487
|
async function* createStreamingGenerator(response, options, schemaStrategy, model) {
|
|
488
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Starting streaming generator with model: ${model}`);
|
|
489
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Response status:`, response.status);
|
|
490
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Response type:`, response.type);
|
|
491
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Response Content-Type:`, response.headers.get('content-type'));
|
|
467
492
|
try {
|
|
468
493
|
// Handle streaming response
|
|
469
494
|
if (!response.body) {
|
|
@@ -477,16 +502,26 @@ async function* createStreamingGenerator(response, options, schemaStrategy, mode
|
|
|
477
502
|
while (true) {
|
|
478
503
|
const { done, value } = await reader.read();
|
|
479
504
|
if (done) {
|
|
505
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Stream done=true after ${chunkCount} chunks`);
|
|
480
506
|
if (options.debug) {
|
|
481
507
|
console.log(`[callAI-streaming:complete v${PACKAGE_VERSION}] Stream finished after ${chunkCount} chunks`);
|
|
482
508
|
}
|
|
483
509
|
break;
|
|
484
510
|
}
|
|
511
|
+
// Increment chunk counter before processing
|
|
512
|
+
chunkCount++;
|
|
485
513
|
const chunk = decoder.decode(value);
|
|
514
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Raw chunk #${chunkCount} (${chunk.length} bytes):`, chunk.length > 200 ? chunk.substring(0, 200) + '...' : chunk);
|
|
486
515
|
const lines = chunk.split("\n").filter((line) => line.trim() !== "");
|
|
516
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Chunk #${chunkCount} contains ${lines.length} non-empty lines`);
|
|
487
517
|
for (const line of lines) {
|
|
518
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Processing line:`, line.length > 100 ? line.substring(0, 100) + '...' : line);
|
|
488
519
|
if (line.startsWith("data: ")) {
|
|
489
|
-
|
|
520
|
+
let data = line.slice(6);
|
|
521
|
+
if (data === "[DONE]") {
|
|
522
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Received [DONE] marker`);
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
490
525
|
if (options.debug) {
|
|
491
526
|
console.log(`[callAI:raw] ${line}`);
|
|
492
527
|
}
|
|
@@ -498,17 +533,38 @@ async function* createStreamingGenerator(response, options, schemaStrategy, mode
|
|
|
498
533
|
try {
|
|
499
534
|
const jsonLine = line.replace("data: ", "");
|
|
500
535
|
if (!jsonLine.trim()) {
|
|
536
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Empty JSON line after data: prefix`);
|
|
501
537
|
continue;
|
|
502
538
|
}
|
|
503
|
-
|
|
539
|
+
console.log(`[callAI:${PACKAGE_VERSION}] JSON line (first 100 chars):`, jsonLine.length > 100 ? jsonLine.substring(0, 100) + '...' : jsonLine);
|
|
504
540
|
// Parse the JSON chunk
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
541
|
+
let json;
|
|
542
|
+
try {
|
|
543
|
+
json = JSON.parse(jsonLine);
|
|
544
|
+
console.log(`[callAI:${PACKAGE_VERSION}] Parsed JSON:`, JSON.stringify(json).length > 100 ?
|
|
545
|
+
JSON.stringify(json).substring(0, 100) + '...' :
|
|
546
|
+
JSON.stringify(json));
|
|
547
|
+
}
|
|
548
|
+
catch (parseError) {
|
|
549
|
+
console.error(`[callAI:${PACKAGE_VERSION}] JSON parse error:`, parseError);
|
|
550
|
+
console.error(`[callAI:${PACKAGE_VERSION}] Failed to parse:`, jsonLine);
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
// Enhanced error detection - check for BOTH error and json.error
|
|
554
|
+
// Some APIs return 200 OK but then deliver errors in the stream
|
|
555
|
+
if (json.error || (typeof json === 'object' && 'error' in json)) {
|
|
556
|
+
console.error(`[callAI:${PACKAGE_VERSION}] Detected error in streaming response:`, json);
|
|
557
|
+
// Create a detailed error object similar to our HTTP error handling
|
|
558
|
+
const errorMessage = json.error?.message ||
|
|
559
|
+
json.error?.toString() ||
|
|
560
|
+
JSON.stringify(json.error || json);
|
|
561
|
+
const detailedError = new Error(`API streaming error: ${errorMessage}`);
|
|
562
|
+
// Add error metadata
|
|
563
|
+
detailedError.status = json.error?.status || 400;
|
|
564
|
+
detailedError.statusText = json.error?.type || 'Bad Request';
|
|
565
|
+
detailedError.details = JSON.stringify(json.error || json);
|
|
566
|
+
console.error(`[callAI:${PACKAGE_VERSION}] Throwing stream error:`, detailedError);
|
|
567
|
+
throw detailedError;
|
|
512
568
|
}
|
|
513
569
|
// Handle tool use response - Claude with schema cases
|
|
514
570
|
const isClaudeWithSchema = /claude/i.test(model) && schemaStrategy.strategy === "tool_mode";
|
package/package.json
CHANGED