@ebowwa/coder 0.7.65 → 0.7.66

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/index.js CHANGED
@@ -5126,11 +5126,69 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
5126
5126
  firstToken = false;
5127
5127
  }
5128
5128
  }
5129
+ if (choice?.delta?.tool_calls && Array.isArray(choice.delta.tool_calls)) {
5130
+ for (const toolCallDelta of choice.delta.tool_calls) {
5131
+ const index = toolCallDelta.index ?? 0;
5132
+ const toolCallId = toolCallDelta.id;
5133
+ if (toolCallId) {
5134
+ if (currentToolUseBlock) {
5135
+ try {
5136
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
5137
+ } catch {
5138
+ currentToolUseBlock.input = {};
5139
+ }
5140
+ currentContent.push(currentToolUseBlock);
5141
+ callbacks.onToolUse?.({
5142
+ id: currentToolUseBlock.id,
5143
+ name: currentToolUseBlock.name,
5144
+ input: currentToolUseBlock.input
5145
+ });
5146
+ }
5147
+ currentToolUseBlock = {
5148
+ type: "tool_use",
5149
+ id: toolCallId,
5150
+ name: toolCallDelta.function?.name || "",
5151
+ input: {}
5152
+ };
5153
+ toolUseInput = "";
5154
+ if (firstToken) {
5155
+ ttft = Date.now() - startTime;
5156
+ firstToken = false;
5157
+ }
5158
+ }
5159
+ if (toolCallDelta.function?.arguments && currentToolUseBlock) {
5160
+ toolUseInput += toolCallDelta.function.arguments;
5161
+ }
5162
+ }
5163
+ }
5129
5164
  if (choice?.finish_reason) {
5130
5165
  if (currentTextBlock) {
5131
5166
  currentContent.push(currentTextBlock);
5132
5167
  currentTextBlock = null;
5133
5168
  }
5169
+ if (currentToolUseBlock) {
5170
+ try {
5171
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
5172
+ } catch {
5173
+ currentToolUseBlock.input = {};
5174
+ }
5175
+ currentContent.push(currentToolUseBlock);
5176
+ callbacks.onToolUse?.({
5177
+ id: currentToolUseBlock.id,
5178
+ name: currentToolUseBlock.name,
5179
+ input: currentToolUseBlock.input
5180
+ });
5181
+ currentToolUseBlock = null;
5182
+ toolUseInput = "";
5183
+ }
5184
+ let stopReason = "end_turn";
5185
+ if (choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call") {
5186
+ stopReason = "tool_use";
5187
+ } else if (choice.finish_reason === "length") {
5188
+ stopReason = "max_tokens";
5189
+ } else if (choice.finish_reason === "stop") {
5190
+ stopReason = "end_turn";
5191
+ }
5134
5192
  if (!message) {
5135
5193
  message = {
5136
5194
  id: `msg-${Date.now()}`,
@@ -5138,12 +5196,12 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
5138
5196
  role: "assistant",
5139
5197
  content: currentContent,
5140
5198
  model,
5141
- stop_reason: choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn",
5199
+ stop_reason: stopReason,
5142
5200
  stop_sequence: null,
5143
5201
  usage: { input_tokens: 0, output_tokens: 0 }
5144
5202
  };
5145
5203
  } else {
5146
- message.stop_reason = choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn";
5204
+ message.stop_reason = stopReason;
5147
5205
  }
5148
5206
  }
5149
5207
  }
@@ -33333,13 +33391,20 @@ var init_input_handler = __esm(() => {
33333
33391
  isShiftDown(event) {
33334
33392
  return event.code === "down" || event.code === "Down";
33335
33393
  },
33394
+ isSpace(event) {
33395
+ return event.code === " " || event.code === "Space";
33396
+ },
33336
33397
  isPrintable(event) {
33337
33398
  if (event.is_special)
33338
33399
  return false;
33339
33400
  const code = event.code;
33401
+ if (code === " " || code === "Space")
33402
+ return true;
33340
33403
  return code.length === 1 && !event.ctrl;
33341
33404
  },
33342
33405
  getChar(event) {
33406
+ if (event.code === "Space")
33407
+ return " ";
33343
33408
  return event.code;
33344
33409
  }
33345
33410
  };
@@ -2238,13 +2238,20 @@ var init_input_handler = __esm(() => {
2238
2238
  isShiftDown(event) {
2239
2239
  return event.code === "down" || event.code === "Down";
2240
2240
  },
2241
+ isSpace(event) {
2242
+ return event.code === " " || event.code === "Space";
2243
+ },
2241
2244
  isPrintable(event) {
2242
2245
  if (event.is_special)
2243
2246
  return false;
2244
2247
  const code = event.code;
2248
+ if (code === " " || code === "Space")
2249
+ return true;
2245
2250
  return code.length === 1 && !event.ctrl;
2246
2251
  },
2247
2252
  getChar(event) {
2253
+ if (event.code === "Space")
2254
+ return " ";
2248
2255
  return event.code;
2249
2256
  }
2250
2257
  };
@@ -7621,11 +7628,69 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
7621
7628
  firstToken = false;
7622
7629
  }
7623
7630
  }
7631
+ if (choice?.delta?.tool_calls && Array.isArray(choice.delta.tool_calls)) {
7632
+ for (const toolCallDelta of choice.delta.tool_calls) {
7633
+ const index = toolCallDelta.index ?? 0;
7634
+ const toolCallId = toolCallDelta.id;
7635
+ if (toolCallId) {
7636
+ if (currentToolUseBlock) {
7637
+ try {
7638
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
7639
+ } catch {
7640
+ currentToolUseBlock.input = {};
7641
+ }
7642
+ currentContent.push(currentToolUseBlock);
7643
+ callbacks.onToolUse?.({
7644
+ id: currentToolUseBlock.id,
7645
+ name: currentToolUseBlock.name,
7646
+ input: currentToolUseBlock.input
7647
+ });
7648
+ }
7649
+ currentToolUseBlock = {
7650
+ type: "tool_use",
7651
+ id: toolCallId,
7652
+ name: toolCallDelta.function?.name || "",
7653
+ input: {}
7654
+ };
7655
+ toolUseInput = "";
7656
+ if (firstToken) {
7657
+ ttft = Date.now() - startTime;
7658
+ firstToken = false;
7659
+ }
7660
+ }
7661
+ if (toolCallDelta.function?.arguments && currentToolUseBlock) {
7662
+ toolUseInput += toolCallDelta.function.arguments;
7663
+ }
7664
+ }
7665
+ }
7624
7666
  if (choice?.finish_reason) {
7625
7667
  if (currentTextBlock) {
7626
7668
  currentContent.push(currentTextBlock);
7627
7669
  currentTextBlock = null;
7628
7670
  }
7671
+ if (currentToolUseBlock) {
7672
+ try {
7673
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
7674
+ } catch {
7675
+ currentToolUseBlock.input = {};
7676
+ }
7677
+ currentContent.push(currentToolUseBlock);
7678
+ callbacks.onToolUse?.({
7679
+ id: currentToolUseBlock.id,
7680
+ name: currentToolUseBlock.name,
7681
+ input: currentToolUseBlock.input
7682
+ });
7683
+ currentToolUseBlock = null;
7684
+ toolUseInput = "";
7685
+ }
7686
+ let stopReason = "end_turn";
7687
+ if (choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call") {
7688
+ stopReason = "tool_use";
7689
+ } else if (choice.finish_reason === "length") {
7690
+ stopReason = "max_tokens";
7691
+ } else if (choice.finish_reason === "stop") {
7692
+ stopReason = "end_turn";
7693
+ }
7629
7694
  if (!message) {
7630
7695
  message = {
7631
7696
  id: `msg-${Date.now()}`,
@@ -7633,12 +7698,12 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
7633
7698
  role: "assistant",
7634
7699
  content: currentContent,
7635
7700
  model,
7636
- stop_reason: choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn",
7701
+ stop_reason: stopReason,
7637
7702
  stop_sequence: null,
7638
7703
  usage: { input_tokens: 0, output_tokens: 0 }
7639
7704
  };
7640
7705
  } else {
7641
- message.stop_reason = choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn";
7706
+ message.stop_reason = stopReason;
7642
7707
  }
7643
7708
  }
7644
7709
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/coder",
3
- "version": "0.7.65",
3
+ "version": "0.7.66",
4
4
  "description": "AI-powered terminal coding assistant",
5
5
  "author": "ebowwa",
6
6
  "license": "MIT",
@@ -442,7 +442,22 @@ async function executeStreamAttempt(
442
442
  // OpenAI/Z.AI compatible format (for GLM-5, etc.)
443
443
  default: {
444
444
  if (event.choices && Array.isArray(event.choices)) {
445
- const choice = event.choices[0] as { delta?: { content?: string }; finish_reason?: string } | undefined;
445
+ const choice = event.choices[0] as {
446
+ delta?: {
447
+ content?: string;
448
+ tool_calls?: Array<{
449
+ id?: string;
450
+ index?: number;
451
+ function?: {
452
+ name?: string;
453
+ arguments?: string;
454
+ };
455
+ }>;
456
+ };
457
+ finish_reason?: string;
458
+ } | undefined;
459
+
460
+ // Handle text content
446
461
  if (choice?.delta?.content) {
447
462
  const text = choice.delta.content;
448
463
  if (currentTextBlock) {
@@ -456,11 +471,87 @@ async function executeStreamAttempt(
456
471
  firstToken = false;
457
472
  }
458
473
  }
474
+
475
+ // Handle tool calls (OpenAI format)
476
+ if (choice?.delta?.tool_calls && Array.isArray(choice.delta.tool_calls)) {
477
+ for (const toolCallDelta of choice.delta.tool_calls) {
478
+ const index = toolCallDelta.index ?? 0;
479
+ const toolCallId = toolCallDelta.id;
480
+
481
+ // Start a new tool call if we got an ID
482
+ if (toolCallId) {
483
+ // Finalize any existing tool use block at this index
484
+ if (currentToolUseBlock) {
485
+ try {
486
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
487
+ } catch {
488
+ currentToolUseBlock.input = {};
489
+ }
490
+ currentContent.push(currentToolUseBlock);
491
+ callbacks.onToolUse?.({
492
+ id: currentToolUseBlock.id,
493
+ name: currentToolUseBlock.name,
494
+ input: currentToolUseBlock.input,
495
+ });
496
+ }
497
+
498
+ // Start new tool use block
499
+ currentToolUseBlock = {
500
+ type: "tool_use",
501
+ id: toolCallId,
502
+ name: toolCallDelta.function?.name || "",
503
+ input: {},
504
+ };
505
+ toolUseInput = "";
506
+
507
+ if (firstToken) {
508
+ ttft = Date.now() - startTime;
509
+ firstToken = false;
510
+ }
511
+ }
512
+
513
+ // Accumulate arguments for current tool call
514
+ if (toolCallDelta.function?.arguments && currentToolUseBlock) {
515
+ toolUseInput += toolCallDelta.function.arguments;
516
+ }
517
+ }
518
+ }
519
+
520
+ // Handle finish reason
459
521
  if (choice?.finish_reason) {
522
+ // Finalize any pending text block
460
523
  if (currentTextBlock) {
461
524
  currentContent.push(currentTextBlock);
462
525
  currentTextBlock = null;
463
526
  }
527
+
528
+ // Finalize any pending tool use block
529
+ if (currentToolUseBlock) {
530
+ try {
531
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
532
+ } catch {
533
+ currentToolUseBlock.input = {};
534
+ }
535
+ currentContent.push(currentToolUseBlock);
536
+ callbacks.onToolUse?.({
537
+ id: currentToolUseBlock.id,
538
+ name: currentToolUseBlock.name,
539
+ input: currentToolUseBlock.input,
540
+ });
541
+ currentToolUseBlock = null;
542
+ toolUseInput = "";
543
+ }
544
+
545
+ // Map finish reasons
546
+ let stopReason: StopReason = "end_turn";
547
+ if (choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call") {
548
+ stopReason = "tool_use";
549
+ } else if (choice.finish_reason === "length") {
550
+ stopReason = "max_tokens";
551
+ } else if (choice.finish_reason === "stop") {
552
+ stopReason = "end_turn";
553
+ }
554
+
464
555
  if (!message) {
465
556
  message = {
466
557
  id: `msg-${Date.now()}`,
@@ -468,12 +559,12 @@ async function executeStreamAttempt(
468
559
  role: "assistant",
469
560
  content: currentContent,
470
561
  model: model,
471
- stop_reason: (choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn") as StopReason,
562
+ stop_reason: stopReason,
472
563
  stop_sequence: null,
473
564
  usage: { input_tokens: 0, output_tokens: 0 },
474
565
  };
475
566
  } else {
476
- message.stop_reason = (choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn") as StopReason;
567
+ message.stop_reason = stopReason;
477
568
  }
478
569
  }
479
570
  }
@@ -200,16 +200,25 @@ export const KeyEvents = {
200
200
  return event.code === "down" || event.code === "Down";
201
201
  },
202
202
 
203
+ /** Check if event is Space key */
204
+ isSpace(event: NativeKeyEvent): boolean {
205
+ return event.code === " " || event.code === "Space";
206
+ },
207
+
203
208
  /** Check if event is a printable character */
204
209
  isPrintable(event: NativeKeyEvent): boolean {
205
210
  if (event.is_special) return false;
206
211
  const code = event.code;
212
+ // Space is printable (normalized to "Space" but should work in text input)
213
+ if (code === " " || code === "Space") return true;
207
214
  // Single character that is not a control character
208
215
  return code.length === 1 && !event.ctrl;
209
216
  },
210
217
 
211
218
  /** Get the character from the event */
212
219
  getChar(event: NativeKeyEvent): string {
220
+ // Handle normalized space
221
+ if (event.code === "Space") return " ";
213
222
  return event.code;
214
223
  },
215
224
  };