@ebowwa/coder 0.7.65 → 0.7.68

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.
@@ -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
  };
@@ -7371,6 +7378,69 @@ function convertToolsToOpenAIFormat(tools) {
7371
7378
  }
7372
7379
  }));
7373
7380
  }
7381
+ function convertMessagesToOpenAIFormat(messages) {
7382
+ const result = [];
7383
+ for (const msg of messages) {
7384
+ if (msg.role === "assistant") {
7385
+ const toolCalls = [];
7386
+ const textParts = [];
7387
+ for (const block of msg.content) {
7388
+ if (block.type === "text") {
7389
+ textParts.push(block.text);
7390
+ } else if (block.type === "tool_use") {
7391
+ toolCalls.push({
7392
+ id: block.id,
7393
+ type: "function",
7394
+ function: {
7395
+ name: block.name,
7396
+ arguments: JSON.stringify(block.input)
7397
+ }
7398
+ });
7399
+ } else if (block.type === "thinking" || block.type === "redacted_thinking") {}
7400
+ }
7401
+ const openAIMsg = {
7402
+ role: "assistant",
7403
+ content: textParts.join(`
7404
+ `) || null
7405
+ };
7406
+ if (toolCalls.length > 0) {
7407
+ openAIMsg.tool_calls = toolCalls;
7408
+ }
7409
+ result.push(openAIMsg);
7410
+ } else if (msg.role === "user") {
7411
+ const textParts = [];
7412
+ const toolResults = [];
7413
+ for (const block of msg.content) {
7414
+ if (block.type === "text") {
7415
+ textParts.push(block.text);
7416
+ } else if (block.type === "tool_result") {
7417
+ const contentStr = typeof block.content === "string" ? block.content : block.content.map((c) => c.type === "text" ? c.text : JSON.stringify(c)).join(`
7418
+ `);
7419
+ toolResults.push({
7420
+ tool_use_id: block.tool_use_id,
7421
+ content: contentStr,
7422
+ is_error: block.is_error
7423
+ });
7424
+ }
7425
+ }
7426
+ if (textParts.length > 0) {
7427
+ result.push({
7428
+ role: "user",
7429
+ content: textParts.join(`
7430
+ `)
7431
+ });
7432
+ }
7433
+ for (const tr of toolResults) {
7434
+ result.push({
7435
+ role: "tool",
7436
+ tool_call_id: tr.tool_use_id,
7437
+ content: tr.content
7438
+ });
7439
+ }
7440
+ }
7441
+ }
7442
+ return result;
7443
+ }
7374
7444
  function calculateCost2(model, usage) {
7375
7445
  return calculateCost(model, usage);
7376
7446
  }
@@ -7621,11 +7691,69 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
7621
7691
  firstToken = false;
7622
7692
  }
7623
7693
  }
7694
+ if (choice?.delta?.tool_calls && Array.isArray(choice.delta.tool_calls)) {
7695
+ for (const toolCallDelta of choice.delta.tool_calls) {
7696
+ const index = toolCallDelta.index ?? 0;
7697
+ const toolCallId = toolCallDelta.id;
7698
+ if (toolCallId) {
7699
+ if (currentToolUseBlock) {
7700
+ try {
7701
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
7702
+ } catch {
7703
+ currentToolUseBlock.input = {};
7704
+ }
7705
+ currentContent.push(currentToolUseBlock);
7706
+ callbacks.onToolUse?.({
7707
+ id: currentToolUseBlock.id,
7708
+ name: currentToolUseBlock.name,
7709
+ input: currentToolUseBlock.input
7710
+ });
7711
+ }
7712
+ currentToolUseBlock = {
7713
+ type: "tool_use",
7714
+ id: toolCallId,
7715
+ name: toolCallDelta.function?.name || "",
7716
+ input: {}
7717
+ };
7718
+ toolUseInput = "";
7719
+ if (firstToken) {
7720
+ ttft = Date.now() - startTime;
7721
+ firstToken = false;
7722
+ }
7723
+ }
7724
+ if (toolCallDelta.function?.arguments && currentToolUseBlock) {
7725
+ toolUseInput += toolCallDelta.function.arguments;
7726
+ }
7727
+ }
7728
+ }
7624
7729
  if (choice?.finish_reason) {
7625
7730
  if (currentTextBlock) {
7626
7731
  currentContent.push(currentTextBlock);
7627
7732
  currentTextBlock = null;
7628
7733
  }
7734
+ if (currentToolUseBlock) {
7735
+ try {
7736
+ currentToolUseBlock.input = JSON.parse(toolUseInput);
7737
+ } catch {
7738
+ currentToolUseBlock.input = {};
7739
+ }
7740
+ currentContent.push(currentToolUseBlock);
7741
+ callbacks.onToolUse?.({
7742
+ id: currentToolUseBlock.id,
7743
+ name: currentToolUseBlock.name,
7744
+ input: currentToolUseBlock.input
7745
+ });
7746
+ currentToolUseBlock = null;
7747
+ toolUseInput = "";
7748
+ }
7749
+ let stopReason = "end_turn";
7750
+ if (choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call") {
7751
+ stopReason = "tool_use";
7752
+ } else if (choice.finish_reason === "length") {
7753
+ stopReason = "max_tokens";
7754
+ } else if (choice.finish_reason === "stop") {
7755
+ stopReason = "end_turn";
7756
+ }
7629
7757
  if (!message) {
7630
7758
  message = {
7631
7759
  id: `msg-${Date.now()}`,
@@ -7633,12 +7761,12 @@ async function executeStreamAttempt(request, headers, apiEndpoint, signal, model
7633
7761
  role: "assistant",
7634
7762
  content: currentContent,
7635
7763
  model,
7636
- stop_reason: choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn",
7764
+ stop_reason: stopReason,
7637
7765
  stop_sequence: null,
7638
7766
  usage: { input_tokens: 0, output_tokens: 0 }
7639
7767
  };
7640
7768
  } else {
7641
- message.stop_reason = choice.finish_reason === "stop" ? "end_turn" : choice.finish_reason === "length" ? "max_tokens" : "end_turn";
7769
+ message.stop_reason = stopReason;
7642
7770
  }
7643
7771
  }
7644
7772
  }
@@ -7706,20 +7834,6 @@ async function createMessageStream(messages, options) {
7706
7834
  signal
7707
7835
  } = options;
7708
7836
  const startTime = Date.now();
7709
- const cachedMessages = buildCachedMessages(messages, cacheConfig);
7710
- const cachedSystemPrompt = buildSystemPrompt(systemPrompt, cacheConfig);
7711
- const request = {
7712
- model,
7713
- max_tokens: maxTokens,
7714
- messages: cachedMessages.map((m) => ({
7715
- role: m.role,
7716
- content: m.content
7717
- })),
7718
- stream: true
7719
- };
7720
- if (cachedSystemPrompt) {
7721
- request.system = cachedSystemPrompt;
7722
- }
7723
7837
  const providerInfo = resolveProvider(model);
7724
7838
  let apiEndpoint;
7725
7839
  let headers;
@@ -7749,6 +7863,37 @@ async function createMessageStream(messages, options) {
7749
7863
  "anthropic-version": "2023-06-01"
7750
7864
  };
7751
7865
  }
7866
+ const cachedMessages = buildCachedMessages(messages, cacheConfig);
7867
+ const cachedSystemPrompt = buildSystemPrompt(systemPrompt, cacheConfig);
7868
+ let requestMessages;
7869
+ if (apiFormat === "openai") {
7870
+ const openAIMessages = convertMessagesToOpenAIFormat(cachedMessages);
7871
+ if (cachedSystemPrompt) {
7872
+ const systemText = typeof cachedSystemPrompt === "string" ? cachedSystemPrompt : cachedSystemPrompt.map((b) => b.text).join(`
7873
+
7874
+ `);
7875
+ requestMessages = [
7876
+ { role: "system", content: systemText },
7877
+ ...openAIMessages
7878
+ ];
7879
+ } else {
7880
+ requestMessages = openAIMessages;
7881
+ }
7882
+ } else {
7883
+ requestMessages = cachedMessages.map((m) => ({
7884
+ role: m.role,
7885
+ content: m.content
7886
+ }));
7887
+ }
7888
+ const request = {
7889
+ model,
7890
+ max_tokens: maxTokens,
7891
+ messages: requestMessages,
7892
+ stream: true
7893
+ };
7894
+ if (cachedSystemPrompt && apiFormat === "anthropic") {
7895
+ request.system = cachedSystemPrompt;
7896
+ }
7752
7897
  if (tools && tools.length > 0) {
7753
7898
  if (apiFormat === "openai") {
7754
7899
  request.tools = convertToolsToOpenAIFormat(tools);
@@ -11184,6 +11329,84 @@ var init_spinner_frames = __esm(() => {
11184
11329
  ];
11185
11330
  });
11186
11331
 
11332
+ // packages/src/interfaces/ui/terminal/cli/interactive/scroll-handler.ts
11333
+ function handleScrollEvent(event, currentOffset, totalMessages, config = {}) {
11334
+ const { pageScrollAmount, lineScrollAmount } = { ...DEFAULT_SCROLL_CONFIG, ...config };
11335
+ const maxScroll = Math.max(0, Math.max(totalMessages - 1, 10));
11336
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11337
+ console.error("[ScrollHandler] Event:", {
11338
+ code: event.code,
11339
+ shift: event.shift,
11340
+ ctrl: event.ctrl,
11341
+ alt: event.alt,
11342
+ is_special: event.is_special
11343
+ });
11344
+ }
11345
+ if (KeyEvents.isPageUp(event)) {
11346
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11347
+ console.error("[ScrollHandler] PageUp detected, scrolling up");
11348
+ }
11349
+ return { handled: true, newOffset: Math.min(currentOffset + pageScrollAmount, maxScroll) };
11350
+ }
11351
+ if (KeyEvents.isPageDown(event)) {
11352
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11353
+ console.error("[ScrollHandler] PageDown detected, scrolling down");
11354
+ }
11355
+ return { handled: true, newOffset: Math.max(0, currentOffset - pageScrollAmount) };
11356
+ }
11357
+ if (KeyEvents.isHome(event)) {
11358
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11359
+ console.error("[ScrollHandler] Home detected, resetting to bottom");
11360
+ }
11361
+ return { handled: true, newOffset: 0 };
11362
+ }
11363
+ if (KeyEvents.isUp(event) && event.alt) {
11364
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11365
+ console.error("[ScrollHandler] Alt+Up detected, scrolling up");
11366
+ }
11367
+ return { handled: true, newOffset: Math.min(currentOffset + lineScrollAmount, maxScroll) };
11368
+ }
11369
+ if (KeyEvents.isDown(event) && event.alt) {
11370
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11371
+ console.error("[ScrollHandler] Alt+Down detected, scrolling down");
11372
+ }
11373
+ return { handled: true, newOffset: Math.max(0, currentOffset - lineScrollAmount) };
11374
+ }
11375
+ if (KeyEvents.isUp(event) && event.ctrl) {
11376
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11377
+ console.error("[ScrollHandler] Ctrl+Up detected, scrolling up");
11378
+ }
11379
+ return { handled: true, newOffset: Math.min(currentOffset + lineScrollAmount, maxScroll) };
11380
+ }
11381
+ if (KeyEvents.isDown(event) && event.ctrl) {
11382
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11383
+ console.error("[ScrollHandler] Ctrl+Down detected, scrolling down");
11384
+ }
11385
+ return { handled: true, newOffset: Math.max(0, currentOffset - lineScrollAmount) };
11386
+ }
11387
+ if (KeyEvents.isUp(event) && event.shift) {
11388
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11389
+ console.error("[ScrollHandler] Shift+Up detected, scrolling up");
11390
+ }
11391
+ return { handled: true, newOffset: Math.min(currentOffset + lineScrollAmount, maxScroll) };
11392
+ }
11393
+ if (KeyEvents.isDown(event) && event.shift) {
11394
+ if (process.env.CODER_DEBUG_SCROLL === "1") {
11395
+ console.error("[ScrollHandler] Shift+Down detected, scrolling down");
11396
+ }
11397
+ return { handled: true, newOffset: Math.max(0, currentOffset - lineScrollAmount) };
11398
+ }
11399
+ return { handled: false, newOffset: currentOffset };
11400
+ }
11401
+ var DEFAULT_SCROLL_CONFIG;
11402
+ var init_scroll_handler = __esm(() => {
11403
+ init_input_handler();
11404
+ DEFAULT_SCROLL_CONFIG = {
11405
+ pageScrollAmount: 3,
11406
+ lineScrollAmount: 1
11407
+ };
11408
+ });
11409
+
11187
11410
  // packages/src/interfaces/ui/terminal/cli/interactive/interactive-runner.ts
11188
11411
  import process3 from "process";
11189
11412
  function createInitialState() {
@@ -11334,6 +11557,23 @@ class InteractiveRunner {
11334
11557
  this.state = { ...this.state, inputValue: "", cursorPos: 0 };
11335
11558
  return true;
11336
11559
  }
11560
+ if (process3.env.CODER_DEBUG_SCROLL === "1") {
11561
+ console.error("[InteractiveRunner] Key event:", {
11562
+ code: event.code,
11563
+ shift: event.shift,
11564
+ ctrl: event.ctrl,
11565
+ alt: event.alt,
11566
+ is_special: event.is_special
11567
+ });
11568
+ }
11569
+ const scrollResult = handleScrollEvent(event, this.state.scrollOffset, this.messageStore.messages.length);
11570
+ if (process3.env.CODER_DEBUG_SCROLL === "1") {
11571
+ console.error("[InteractiveRunner] Scroll result:", scrollResult);
11572
+ }
11573
+ if (scrollResult.handled) {
11574
+ this.state = { ...this.state, scrollOffset: scrollResult.newOffset };
11575
+ return true;
11576
+ }
11337
11577
  if (KeyEvents.isUp(event)) {
11338
11578
  return this._handleHistoryUp();
11339
11579
  }
@@ -11631,18 +11871,19 @@ class InteractiveRunner {
11631
11871
  })) : [];
11632
11872
  return {
11633
11873
  messages: renderMessages,
11634
- inputValue,
11635
- cursorPos,
11636
- statusText,
11637
- isLoading,
11638
- streamingText,
11874
+ input_value: inputValue,
11875
+ cursor_pos: cursorPos,
11876
+ status_text: statusText,
11877
+ is_loading: isLoading,
11878
+ streaming_text: streamingText,
11639
11879
  model: this.props.model,
11640
- showHelp: helpMode,
11641
- helpText,
11642
- searchMode: sessionSelectMode,
11643
- searchQuery: "",
11644
- searchResults,
11645
- searchSelected: 0
11880
+ show_help: helpMode,
11881
+ help_text: helpText,
11882
+ search_mode: sessionSelectMode,
11883
+ search_query: "",
11884
+ search_results: searchResults,
11885
+ search_selected: 0,
11886
+ scroll_offset: this.state.scrollOffset
11646
11887
  };
11647
11888
  }
11648
11889
  _getHelpText(section) {
@@ -11744,6 +11985,7 @@ var init_interactive_runner = __esm(() => {
11744
11985
  init_native();
11745
11986
  init_spinner_frames();
11746
11987
  init_input_handler();
11988
+ init_scroll_handler();
11747
11989
  init_types();
11748
11990
  });
11749
11991
 
@@ -34260,3 +34502,6 @@ if (checkPtyWrapper2()) {
34260
34502
  process5.exit(1);
34261
34503
  });
34262
34504
  }
34505
+
34506
+ //# debugId=7897AF5E6C87CE9064756E2164756E21
34507
+ //# sourceMappingURL=bootstrap.js.map
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/coder",
3
- "version": "0.7.65",
3
+ "version": "0.7.68",
4
4
  "description": "AI-powered terminal coding assistant",
5
5
  "author": "ebowwa",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "scripts": {
26
26
  "build": "bun run build:native && bun run build:ts && bun run link",
27
- "build:ts": "bun build ./packages/src/index.ts ./packages/src/interfaces/ui/terminal/cli/bootstrap.ts --outdir ./dist --target bun --external @ebowwa/coder-native && cp -r native dist/ && mkdir -p dist/interfaces/ui/terminal && cp -r native dist/interfaces/ui/terminal/ && mv dist/interfaces/ui/terminal/cli/bootstrap.js dist/interfaces/ui/terminal/cli/index.js",
27
+ "build:ts": "bun build ./packages/src/index.ts ./packages/src/interfaces/ui/terminal/cli/bootstrap.ts --outdir ./dist --target bun --external @ebowwa/coder-native --sourcemap && cp -r native dist/ && mkdir -p dist/interfaces/ui/terminal && cp -r native dist/interfaces/ui/terminal/ && mv dist/interfaces/ui/terminal/cli/bootstrap.js dist/interfaces/ui/terminal/cli/index.js",
28
28
  "build:native": "cd packages/rust && cargo build --release --target-dir ./target && cd ../.. && bun run build:napi-artifacts",
29
29
  "build:napi-artifacts": "napi build --platform --release --target-dir packages/rust/target --manifest-path packages/rust/Cargo.toml --output-dir native --js-package-name @ebowwa/coder-native --const-enum --strip --dts index.d.ts",
30
30
  "link": "bun link || npm link",