graphlit-client 1.0.20250610007 → 1.0.20250610008

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 CHANGED
@@ -1730,14 +1730,24 @@ class Graphlit {
1730
1730
  }
1731
1731
  // Try to fix truncated JSON by adding missing closing braces
1732
1732
  if (isTruncated) {
1733
- let fixedJson = toolCall.arguments;
1733
+ let fixedJson = toolCall.arguments.trim();
1734
1734
  // Count open braces vs close braces to determine how many we need
1735
1735
  const openBraces = (fixedJson.match(/\{/g) || []).length;
1736
1736
  const closeBraces = (fixedJson.match(/\}/g) || []).length;
1737
1737
  const missingBraces = openBraces - closeBraces;
1738
1738
  if (missingBraces > 0) {
1739
+ // Check if we're mid-value (ends with number or boolean)
1740
+ if (fixedJson.match(/:\s*\d+$/) || fixedJson.match(/:\s*(true|false)$/)) {
1741
+ // Complete the current property and close
1742
+ fixedJson += ', "content": ""'; // Add empty content field
1743
+ }
1744
+ // Check if we're after a value but missing comma
1745
+ else if (fixedJson.match(/"\s*:\s*[^,}\s]+$/)) {
1746
+ // We have a complete value but no comma, add empty content
1747
+ fixedJson += ', "content": ""';
1748
+ }
1739
1749
  // Add missing closing quote if the string ends with an unfinished string
1740
- if (fixedJson.endsWith('"') === false && fixedJson.includes('"')) {
1750
+ else if (fixedJson.endsWith('"') === false && fixedJson.includes('"')) {
1741
1751
  const lastQuoteIndex = fixedJson.lastIndexOf('"');
1742
1752
  const afterLastQuote = fixedJson.slice(lastQuoteIndex + 1);
1743
1753
  if (!afterLastQuote.includes('"')) {
@@ -141,8 +141,14 @@ onEvent, onComplete) {
141
141
  }));
142
142
  }
143
143
  const stream = await anthropicClient.messages.create(streamConfig);
144
+ let activeContentBlock = false;
144
145
  for await (const chunk of stream) {
146
+ // Debug log all chunk types
147
+ if (process.env.DEBUG_STREAMING) {
148
+ console.log(`[Anthropic] Received chunk type: ${chunk.type}`);
149
+ }
145
150
  if (chunk.type === "content_block_start") {
151
+ activeContentBlock = true;
146
152
  if (chunk.content_block.type === "tool_use") {
147
153
  const toolCall = {
148
154
  id: chunk.content_block.id,
@@ -186,6 +192,7 @@ onEvent, onComplete) {
186
192
  }
187
193
  }
188
194
  else if (chunk.type === "content_block_stop") {
195
+ activeContentBlock = false;
189
196
  // Tool call complete
190
197
  const currentTool = toolCalls[toolCalls.length - 1];
191
198
  if (currentTool) {
@@ -221,8 +228,45 @@ onEvent, onComplete) {
221
228
  });
222
229
  }
223
230
  }
231
+ else if (chunk.type === "message_stop" && activeContentBlock) {
232
+ // Handle Anthropic bug: message_stop without content_block_stop
233
+ console.warn(`[Anthropic] Received message_stop without content_block_stop - handling as implicit block stop`);
234
+ activeContentBlock = false;
235
+ // Emit synthetic content_block_stop for the current tool
236
+ const currentTool = toolCalls[toolCalls.length - 1];
237
+ if (currentTool) {
238
+ // Log the incomplete tool
239
+ console.warn(`[Anthropic] Synthetic content_block_stop for incomplete tool ${currentTool.name} (${currentTool.arguments.length} chars)`);
240
+ // Only emit tool_call_complete if we have valid JSON
241
+ if (isValidJSON(currentTool.arguments)) {
242
+ onEvent({
243
+ type: "tool_call_complete",
244
+ toolCall: {
245
+ id: currentTool.id,
246
+ name: currentTool.name,
247
+ arguments: currentTool.arguments,
248
+ },
249
+ });
250
+ }
251
+ else {
252
+ console.error(`[Anthropic] Tool ${currentTool.name} has incomplete JSON, skipping tool_call_complete event`);
253
+ }
254
+ }
255
+ }
224
256
  }
225
- onComplete(fullMessage, toolCalls);
257
+ // Final check: filter out any remaining incomplete tool calls
258
+ const validToolCalls = toolCalls.filter((tc, idx) => {
259
+ if (!isValidJSON(tc.arguments)) {
260
+ console.warn(`[Anthropic] Filtering out incomplete tool call ${idx} (${tc.name}) with INVALID JSON (${tc.arguments.length} chars)`);
261
+ return false;
262
+ }
263
+ return true;
264
+ });
265
+ if (toolCalls.length !== validToolCalls.length) {
266
+ console.log(`[Anthropic] Filtered out ${toolCalls.length - validToolCalls.length} incomplete tool calls`);
267
+ console.log(`[Anthropic] Successfully processed ${validToolCalls.length} valid tool calls`);
268
+ }
269
+ onComplete(fullMessage, validToolCalls);
226
270
  }
227
271
  catch (error) {
228
272
  onEvent({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20250610007",
3
+ "version": "1.0.20250610008",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "main": "dist/client.js",
6
6
  "types": "dist/client.d.ts",