graphlit-client 1.0.20250610006 → 1.0.20250610007
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/client.js +63 -1
- package/dist/streaming/providers.js +40 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
@@ -1713,7 +1713,69 @@ class Graphlit {
|
|
1713
1713
|
continue;
|
1714
1714
|
}
|
1715
1715
|
try {
|
1716
|
-
|
1716
|
+
let args;
|
1717
|
+
try {
|
1718
|
+
args = JSON.parse(toolCall.arguments);
|
1719
|
+
}
|
1720
|
+
catch (parseError) {
|
1721
|
+
console.error(`Failed to parse tool arguments for ${toolCall.name}:`);
|
1722
|
+
console.error(`Arguments (${toolCall.arguments.length} chars):`, toolCall.arguments);
|
1723
|
+
console.error(`Parse error:`, parseError);
|
1724
|
+
// Check for common truncation patterns
|
1725
|
+
const lastChars = toolCall.arguments.slice(-20);
|
1726
|
+
let isTruncated = false;
|
1727
|
+
if (!toolCall.arguments.includes('}') || !lastChars.includes('}')) {
|
1728
|
+
console.error(`Possible truncation detected - arguments don't end with '}': ...${lastChars}`);
|
1729
|
+
isTruncated = true;
|
1730
|
+
}
|
1731
|
+
// Try to fix truncated JSON by adding missing closing braces
|
1732
|
+
if (isTruncated) {
|
1733
|
+
let fixedJson = toolCall.arguments;
|
1734
|
+
// Count open braces vs close braces to determine how many we need
|
1735
|
+
const openBraces = (fixedJson.match(/\{/g) || []).length;
|
1736
|
+
const closeBraces = (fixedJson.match(/\}/g) || []).length;
|
1737
|
+
const missingBraces = openBraces - closeBraces;
|
1738
|
+
if (missingBraces > 0) {
|
1739
|
+
// Add missing closing quote if the string ends with an unfinished string
|
1740
|
+
if (fixedJson.endsWith('"') === false && fixedJson.includes('"')) {
|
1741
|
+
const lastQuoteIndex = fixedJson.lastIndexOf('"');
|
1742
|
+
const afterLastQuote = fixedJson.slice(lastQuoteIndex + 1);
|
1743
|
+
if (!afterLastQuote.includes('"')) {
|
1744
|
+
fixedJson += '"';
|
1745
|
+
}
|
1746
|
+
}
|
1747
|
+
// Add missing closing braces
|
1748
|
+
fixedJson += '}'.repeat(missingBraces);
|
1749
|
+
console.log(`Attempting to fix truncated JSON by adding ${missingBraces} closing brace(s):`);
|
1750
|
+
console.log(fixedJson);
|
1751
|
+
try {
|
1752
|
+
args = JSON.parse(fixedJson);
|
1753
|
+
console.log(`✅ Successfully fixed truncated JSON for ${toolCall.name}`);
|
1754
|
+
}
|
1755
|
+
catch (fixError) {
|
1756
|
+
console.error(`❌ Failed to fix truncated JSON: ${fixError}`);
|
1757
|
+
// Fall through to error handling below
|
1758
|
+
}
|
1759
|
+
}
|
1760
|
+
}
|
1761
|
+
// If we couldn't parse or fix the JSON, log details and continue
|
1762
|
+
if (!args) {
|
1763
|
+
// Log position mentioned in error if available
|
1764
|
+
const errorMsg = parseError instanceof Error ? parseError.message : '';
|
1765
|
+
const posMatch = errorMsg.match(/position (\d+)/);
|
1766
|
+
if (posMatch) {
|
1767
|
+
const pos = parseInt(posMatch[1]);
|
1768
|
+
const context = toolCall.arguments.slice(Math.max(0, pos - 20), pos + 20);
|
1769
|
+
console.error(`Error context around position ${pos}: ...${context}...`);
|
1770
|
+
}
|
1771
|
+
// Update UI with error - use StreamEvent error type
|
1772
|
+
uiAdapter.handleEvent({
|
1773
|
+
type: "error",
|
1774
|
+
error: `Tool ${toolCall.name} failed: Invalid JSON arguments: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`,
|
1775
|
+
});
|
1776
|
+
continue;
|
1777
|
+
}
|
1778
|
+
}
|
1717
1779
|
// Update UI
|
1718
1780
|
uiAdapter.handleEvent({
|
1719
1781
|
type: "tool_call_start",
|
@@ -1,4 +1,16 @@
|
|
1
1
|
import { getModelName } from "../model-mapping.js";
|
2
|
+
/**
|
3
|
+
* Helper to check if a string is valid JSON
|
4
|
+
*/
|
5
|
+
function isValidJSON(str) {
|
6
|
+
try {
|
7
|
+
JSON.parse(str);
|
8
|
+
return true;
|
9
|
+
}
|
10
|
+
catch {
|
11
|
+
return false;
|
12
|
+
}
|
13
|
+
}
|
2
14
|
/**
|
3
15
|
* Stream with OpenAI SDK
|
4
16
|
*/
|
@@ -115,7 +127,7 @@ onEvent, onComplete) {
|
|
115
127
|
stream: true,
|
116
128
|
temperature: specification.anthropic?.temperature,
|
117
129
|
//top_p: specification.anthropic?.probability,
|
118
|
-
max_tokens: specification.anthropic?.completionTokenLimit ||
|
130
|
+
max_tokens: specification.anthropic?.completionTokenLimit || 8192, // required
|
119
131
|
};
|
120
132
|
if (systemPrompt) {
|
121
133
|
streamConfig.system = systemPrompt;
|
@@ -160,6 +172,11 @@ onEvent, onComplete) {
|
|
160
172
|
const currentTool = toolCalls[toolCalls.length - 1];
|
161
173
|
if (currentTool) {
|
162
174
|
currentTool.arguments += chunk.delta.partial_json;
|
175
|
+
// Debug logging for partial JSON accumulation
|
176
|
+
if (process.env.DEBUG_STREAMING) {
|
177
|
+
console.log(`[Anthropic] Tool ${currentTool.name} - Partial JSON chunk: "${chunk.delta.partial_json}"`);
|
178
|
+
console.log(`[Anthropic] Tool ${currentTool.name} - Total accumulated: ${currentTool.arguments.length} chars`);
|
179
|
+
}
|
163
180
|
onEvent({
|
164
181
|
type: "tool_call_delta",
|
165
182
|
toolCallId: currentTool.id,
|
@@ -172,6 +189,28 @@ onEvent, onComplete) {
|
|
172
189
|
// Tool call complete
|
173
190
|
const currentTool = toolCalls[toolCalls.length - 1];
|
174
191
|
if (currentTool) {
|
192
|
+
// Log the final JSON for debugging
|
193
|
+
if (process.env.DEBUG_STREAMING ||
|
194
|
+
!isValidJSON(currentTool.arguments)) {
|
195
|
+
console.log(`[Anthropic] Tool ${currentTool.name} complete with arguments (${currentTool.arguments.length} chars):`);
|
196
|
+
console.log(currentTool.arguments);
|
197
|
+
// Check if JSON appears truncated
|
198
|
+
const lastChars = currentTool.arguments.slice(-10);
|
199
|
+
if (!lastChars.includes("}") &&
|
200
|
+
currentTool.arguments.length > 100) {
|
201
|
+
console.warn(`[Anthropic] WARNING: JSON may be truncated - doesn't end with '}': ...${lastChars}`);
|
202
|
+
}
|
203
|
+
// Validate JSON
|
204
|
+
try {
|
205
|
+
JSON.parse(currentTool.arguments);
|
206
|
+
if (process.env.DEBUG_STREAMING) {
|
207
|
+
console.log(`[Anthropic] ✅ Valid JSON for ${currentTool.name}`);
|
208
|
+
}
|
209
|
+
}
|
210
|
+
catch (e) {
|
211
|
+
console.error(`[Anthropic] ❌ Invalid JSON for ${currentTool.name}: ${e}`);
|
212
|
+
}
|
213
|
+
}
|
175
214
|
onEvent({
|
176
215
|
type: "tool_call_complete",
|
177
216
|
toolCall: {
|