@bike4mind/cli 0.1.3 → 0.1.4

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-MKO2KCCS.js";
4
+ } from "./chunk-VVV7WLJ6.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-B3YFSFVU.js";
9
+ } from "./chunk-EVPT4ARN.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-MKO2KCCS.js";
14
+ } from "./chunk-VVV7WLJ6.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
17
17
  import { z } from "zod";
@@ -16,7 +16,7 @@ import {
16
16
  dayjsConfig_default,
17
17
  extractSnippetMeta,
18
18
  settingsMap
19
- } from "./chunk-MKO2KCCS.js";
19
+ } from "./chunk-VVV7WLJ6.js";
20
20
 
21
21
  // ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
22
22
  import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
@@ -1051,19 +1051,29 @@ var BaseBedrockBackend = class {
1051
1051
  }
1052
1052
  if (func.some((f) => f.name)) {
1053
1053
  for await (const tool of func) {
1054
- const { id, name, parameters } = tool;
1055
- const toolFn = options.tools?.find((tool2) => tool2.toolSchema.name === name)?.toolFn;
1056
- if (id && name && parameters && toolFn) {
1057
- const result = await toolFn(JSON.parse(parameters));
1054
+ const { name, parameters } = tool;
1055
+ if (name && parameters) {
1058
1056
  toolsUsed.push({ name, arguments: parameters });
1059
- await handleToolResultStreaming(name, result, async (results) => {
1060
- await callback(results, { inputTokens, outputTokens, toolsUsed });
1061
- });
1062
- this.pushToolMessages(messages, { id, name, parameters }, result);
1063
1057
  }
1064
1058
  }
1065
- await callback(["\n\n"], { inputTokens, outputTokens, toolsUsed });
1066
- await this.complete(model, messages, { ...options, thinking: { enabled: false, budget_tokens: 0 } }, callback, toolsUsed);
1059
+ if (options.executeTools !== false) {
1060
+ for await (const tool of func) {
1061
+ const { id, name, parameters } = tool;
1062
+ const toolFn = options.tools?.find((tool2) => tool2.toolSchema.name === name)?.toolFn;
1063
+ if (id && name && parameters && toolFn) {
1064
+ const result = await toolFn(JSON.parse(parameters));
1065
+ await handleToolResultStreaming(name, result, async (results) => {
1066
+ await callback(results, { inputTokens, outputTokens, toolsUsed });
1067
+ });
1068
+ this.pushToolMessages(messages, { id, name, parameters }, result);
1069
+ }
1070
+ }
1071
+ await callback(["\n\n"], { inputTokens, outputTokens, toolsUsed });
1072
+ await this.complete(model, messages, { ...options, thinking: { enabled: false, budget_tokens: 0 } }, callback, toolsUsed);
1073
+ } else {
1074
+ console.log("[BaseBedrockBackend] executeTools=false, passing tool calls to callback");
1075
+ await callback([null], { inputTokens, outputTokens, toolsUsed });
1076
+ }
1067
1077
  return;
1068
1078
  }
1069
1079
  } else {
@@ -1084,16 +1094,24 @@ var BaseBedrockBackend = class {
1084
1094
  const toolChoice = chunk?.choices.find((choice) => choice.statusEndReason === ChoiceEndReason.TOOL_USE);
1085
1095
  if (toolChoice?.tool) {
1086
1096
  const { id, name, parameters } = toolChoice.tool;
1087
- const toolFn = options.tools?.find((tool) => tool.toolSchema.name === name)?.toolFn;
1088
- if (id && name && parameters && toolFn) {
1089
- const result = await toolFn(JSON.parse(parameters));
1097
+ if (name && parameters) {
1090
1098
  toolsUsed.push({ name, arguments: parameters });
1091
- await handleToolResultStreaming(name, result, async (results) => {
1092
- await callback(results, { inputTokens, outputTokens, toolsUsed });
1093
- });
1094
- this.pushToolMessages(messages, { id, name, parameters }, result);
1095
- await callback(["\n\n"], { inputTokens, outputTokens, toolsUsed });
1096
- await this.complete(model, messages, { ...options, thinking: { enabled: false, budget_tokens: 0 } }, callback, toolsUsed);
1099
+ }
1100
+ if (options.executeTools !== false) {
1101
+ const toolFn = options.tools?.find((tool) => tool.toolSchema.name === name)?.toolFn;
1102
+ if (id && name && parameters && toolFn) {
1103
+ const result = await toolFn(JSON.parse(parameters));
1104
+ await handleToolResultStreaming(name, result, async (results) => {
1105
+ await callback(results, { inputTokens, outputTokens, toolsUsed });
1106
+ });
1107
+ this.pushToolMessages(messages, { id, name, parameters }, result);
1108
+ await callback(["\n\n"], { inputTokens, outputTokens, toolsUsed });
1109
+ await this.complete(model, messages, { ...options, thinking: { enabled: false, budget_tokens: 0 } }, callback, toolsUsed);
1110
+ return;
1111
+ }
1112
+ } else {
1113
+ console.log("[BaseBedrockBackend] executeTools=false, passing tool calls to callback");
1114
+ await callback([null], { inputTokens, outputTokens, toolsUsed });
1097
1115
  return;
1098
1116
  }
1099
1117
  }
@@ -3007,58 +3025,63 @@ var GeminiBackend = class {
3007
3025
  }
3008
3026
  if (toolCalls.length > 0 && options.tools?.length) {
3009
3027
  console.log("[DEBUG] Gemini executing tools immediately:", toolCalls.map((tc) => tc.name));
3010
- const assistantMessage = {
3011
- role: "assistant",
3012
- content: toolCalls.map((toolCall, index) => ({
3013
- type: "tool_use",
3014
- id: toolCall.id,
3015
- name: toolCall.name,
3016
- input: toolCall.parameters,
3017
- // Only first tool call gets thought_signature (Gemini 3 requirement for parallel calls)
3018
- thought_signature: index === 0 ? toolCall.thought_signature : void 0
3019
- }))
3020
- };
3021
- messages.push(assistantMessage);
3022
- for (const toolCall of toolCalls) {
3023
- const toolFn = options.tools.find((tool) => tool.toolSchema.name === toolCall.name)?.toolFn;
3024
- if (!toolFn) {
3025
- console.warn(`[WARN] Tool ${toolCall.name} not found`);
3026
- continue;
3027
- }
3028
- try {
3029
- const result2 = await toolFn(toolCall.parameters);
3030
- await handleToolResultStreaming(toolCall.name, result2, async (results) => {
3031
- await callback(results, { toolsUsed });
3032
- });
3033
- messages.push({
3034
- role: "tool",
3035
- content: [
3036
- {
3037
- type: "tool_result",
3038
- content: JSON.stringify({ result: result2 }),
3039
- tool_use_id: toolCall.id
3040
- }
3041
- ]
3042
- });
3043
- } catch (error) {
3044
- if (error instanceof PermissionDeniedError) {
3045
- throw error;
3028
+ if (options.executeTools !== false) {
3029
+ const assistantMessage = {
3030
+ role: "assistant",
3031
+ content: toolCalls.map((toolCall, index) => ({
3032
+ type: "tool_use",
3033
+ id: toolCall.id,
3034
+ name: toolCall.name,
3035
+ input: toolCall.parameters,
3036
+ // Only first tool call gets thought_signature (Gemini 3 requirement for parallel calls)
3037
+ thought_signature: index === 0 ? toolCall.thought_signature : void 0
3038
+ }))
3039
+ };
3040
+ messages.push(assistantMessage);
3041
+ for (const toolCall of toolCalls) {
3042
+ const toolFn = options.tools.find((tool) => tool.toolSchema.name === toolCall.name)?.toolFn;
3043
+ if (!toolFn) {
3044
+ console.warn(`[WARN] Tool ${toolCall.name} not found`);
3045
+ continue;
3046
+ }
3047
+ try {
3048
+ const result2 = await toolFn(toolCall.parameters);
3049
+ await handleToolResultStreaming(toolCall.name, result2, async (results) => {
3050
+ await callback(results, { toolsUsed });
3051
+ });
3052
+ messages.push({
3053
+ role: "tool",
3054
+ content: [
3055
+ {
3056
+ type: "tool_result",
3057
+ content: JSON.stringify({ result: result2 }),
3058
+ tool_use_id: toolCall.id
3059
+ }
3060
+ ]
3061
+ });
3062
+ } catch (error) {
3063
+ if (error instanceof PermissionDeniedError) {
3064
+ throw error;
3065
+ }
3066
+ console.error(`[ERROR] Error executing tool ${toolCall.name}:`, error);
3067
+ messages.push({
3068
+ role: "tool",
3069
+ content: [
3070
+ {
3071
+ type: "tool_result",
3072
+ content: JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" }),
3073
+ tool_use_id: toolCall.id
3074
+ }
3075
+ ]
3076
+ });
3046
3077
  }
3047
- console.error(`[ERROR] Error executing tool ${toolCall.name}:`, error);
3048
- messages.push({
3049
- role: "tool",
3050
- content: [
3051
- {
3052
- type: "tool_result",
3053
- content: JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" }),
3054
- tool_use_id: toolCall.id
3055
- }
3056
- ]
3057
- });
3058
3078
  }
3079
+ await callback(["\n\n"], { toolsUsed });
3080
+ await this.complete(modelName, messages, options, callback, toolsUsed);
3081
+ } else {
3082
+ console.log("[DEBUG] Gemini executeTools=false, passing tool calls to callback");
3083
+ await callback([null], { toolsUsed });
3059
3084
  }
3060
- await callback(["\n\n"], { toolsUsed });
3061
- await this.complete(modelName, messages, options, callback, toolsUsed);
3062
3085
  return;
3063
3086
  }
3064
3087
  } catch (error) {
@@ -3096,58 +3119,63 @@ var GeminiBackend = class {
3096
3119
  }
3097
3120
  if (!options.stream && toolCalls.length > 0 && options.tools?.length) {
3098
3121
  console.log("[DEBUG] Gemini executing tools (non-streaming mode):", toolCalls.map((tc) => tc.name));
3099
- const assistantMessage = {
3100
- role: "assistant",
3101
- content: toolCalls.map((toolCall, index) => ({
3102
- type: "tool_use",
3103
- id: toolCall.id,
3104
- name: toolCall.name,
3105
- input: toolCall.parameters,
3106
- // Only first tool call gets thought_signature (Gemini 3 requirement for parallel calls)
3107
- thought_signature: index === 0 ? toolCall.thought_signature : void 0
3108
- }))
3109
- };
3110
- messages.push(assistantMessage);
3111
- for (const toolCall of toolCalls) {
3112
- const toolFn = options.tools.find((tool) => tool.toolSchema.name === toolCall.name)?.toolFn;
3113
- if (!toolFn) {
3114
- console.warn(`[WARN] Tool ${toolCall.name} not found`);
3115
- continue;
3116
- }
3117
- try {
3118
- const result = await toolFn(toolCall.parameters);
3119
- await handleToolResultStreaming(toolCall.name, result, async (results) => {
3120
- await callback(results, { toolsUsed });
3121
- });
3122
- messages.push({
3123
- role: "tool",
3124
- content: [
3125
- {
3126
- type: "tool_result",
3127
- content: JSON.stringify({ result }),
3128
- tool_use_id: toolCall.id
3129
- }
3130
- ]
3131
- });
3132
- } catch (error) {
3133
- if (error instanceof PermissionDeniedError) {
3134
- throw error;
3122
+ if (options.executeTools !== false) {
3123
+ const assistantMessage = {
3124
+ role: "assistant",
3125
+ content: toolCalls.map((toolCall, index) => ({
3126
+ type: "tool_use",
3127
+ id: toolCall.id,
3128
+ name: toolCall.name,
3129
+ input: toolCall.parameters,
3130
+ // Only first tool call gets thought_signature (Gemini 3 requirement for parallel calls)
3131
+ thought_signature: index === 0 ? toolCall.thought_signature : void 0
3132
+ }))
3133
+ };
3134
+ messages.push(assistantMessage);
3135
+ for (const toolCall of toolCalls) {
3136
+ const toolFn = options.tools.find((tool) => tool.toolSchema.name === toolCall.name)?.toolFn;
3137
+ if (!toolFn) {
3138
+ console.warn(`[WARN] Tool ${toolCall.name} not found`);
3139
+ continue;
3140
+ }
3141
+ try {
3142
+ const result = await toolFn(toolCall.parameters);
3143
+ await handleToolResultStreaming(toolCall.name, result, async (results) => {
3144
+ await callback(results, { toolsUsed });
3145
+ });
3146
+ messages.push({
3147
+ role: "tool",
3148
+ content: [
3149
+ {
3150
+ type: "tool_result",
3151
+ content: JSON.stringify({ result }),
3152
+ tool_use_id: toolCall.id
3153
+ }
3154
+ ]
3155
+ });
3156
+ } catch (error) {
3157
+ if (error instanceof PermissionDeniedError) {
3158
+ throw error;
3159
+ }
3160
+ console.error(`[ERROR] Error executing tool ${toolCall.name}:`, error);
3161
+ messages.push({
3162
+ role: "tool",
3163
+ content: [
3164
+ {
3165
+ type: "tool_result",
3166
+ content: JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" }),
3167
+ tool_use_id: toolCall.id
3168
+ }
3169
+ ]
3170
+ });
3135
3171
  }
3136
- console.error(`[ERROR] Error executing tool ${toolCall.name}:`, error);
3137
- messages.push({
3138
- role: "tool",
3139
- content: [
3140
- {
3141
- type: "tool_result",
3142
- content: JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" }),
3143
- tool_use_id: toolCall.id
3144
- }
3145
- ]
3146
- });
3147
3172
  }
3173
+ await callback(["\n\n"], { toolsUsed });
3174
+ await this.complete(modelName, messages, options, callback, toolsUsed);
3175
+ } else {
3176
+ console.log("[DEBUG] Gemini executeTools=false, passing tool calls to callback");
3177
+ await callback([null], { toolsUsed });
3148
3178
  }
3149
- await callback(["\n\n"], { toolsUsed });
3150
- await this.complete(modelName, messages, options, callback, toolsUsed);
3151
3179
  }
3152
3180
  }
3153
3181
  formatMessagesIntoGeminiContent(messages) {
@@ -4584,67 +4612,83 @@ var XAIBackend = class {
4584
4612
  }
4585
4613
  if (c.message.tool_calls && c.message.tool_calls.length > 0) {
4586
4614
  for (const toolCall of c.message.tool_calls) {
4587
- if (toolCall.type !== "function") {
4615
+ if (toolCall.type !== "function")
4588
4616
  continue;
4589
- }
4590
- const toolFn = options.tools?.find((tool) => tool.toolSchema.name === toolCall.function.name)?.toolFn;
4591
- if (toolFn && toolCall.function.arguments) {
4617
+ if (toolCall.function.arguments) {
4592
4618
  toolsUsed.push({
4593
4619
  name: toolCall.function.name,
4594
4620
  arguments: toolCall.function.arguments
4595
4621
  });
4596
- try {
4597
- const parsedParams = JSON.parse(toolCall.function.arguments);
4598
- const result = await toolFn(parsedParams);
4599
- this.pushToolMessages(messages, {
4600
- id: toolCall.id,
4601
- name: toolCall.function.name,
4602
- parameters: toolCall.function.arguments
4603
- }, result.toString());
4604
- const isMcpTool = options.tools?.find((t) => t.toolSchema.name === toolCall.function.name)?._isMcpTool;
4605
- if (isMcpTool) {
4606
- await this.complete(model, messages, {
4607
- ...options,
4608
- _internal: {
4609
- toolCallCount: toolCallCount + 1
4610
- }
4611
- }, callback, toolsUsed);
4612
- } else {
4613
- await this.complete(model, messages, {
4614
- ...options,
4615
- tools: void 0,
4616
- _internal: void 0
4617
- }, callback, toolsUsed);
4618
- }
4619
- return;
4620
- } catch (error) {
4621
- if (error instanceof PermissionDeniedError) {
4622
- throw error;
4623
- }
4624
- console.warn(`Error processing ${toolCall.function.name} tool:`, error);
4625
- this.pushToolMessages(messages, {
4626
- id: toolCall.id,
4627
- name: toolCall.function.name,
4628
- parameters: toolCall.function.arguments
4629
- }, `Error: ${error instanceof Error ? error.message : "Unknown error"}`);
4630
- const isMcpToolError = options.tools?.find((t) => t.toolSchema.name === toolCall.function.name)?._isMcpTool;
4631
- if (isMcpToolError) {
4632
- await this.complete(model, messages, {
4633
- ...options,
4634
- _internal: {
4635
- toolCallCount: toolCallCount + 1
4636
- }
4637
- }, callback, toolsUsed);
4638
- } else {
4639
- await this.complete(model, messages, {
4640
- ...options,
4641
- tools: void 0,
4642
- _internal: void 0
4643
- }, callback, toolsUsed);
4622
+ }
4623
+ }
4624
+ if (options.executeTools !== false) {
4625
+ for (const toolCall of c.message.tool_calls) {
4626
+ if (toolCall.type !== "function") {
4627
+ continue;
4628
+ }
4629
+ const toolFn = options.tools?.find((tool) => tool.toolSchema.name === toolCall.function.name)?.toolFn;
4630
+ if (toolFn && toolCall.function.arguments) {
4631
+ try {
4632
+ const parsedParams = JSON.parse(toolCall.function.arguments);
4633
+ const result = await toolFn(parsedParams);
4634
+ this.pushToolMessages(messages, {
4635
+ id: toolCall.id,
4636
+ name: toolCall.function.name,
4637
+ parameters: toolCall.function.arguments
4638
+ }, result.toString());
4639
+ const isMcpTool = options.tools?.find((t) => t.toolSchema.name === toolCall.function.name)?._isMcpTool;
4640
+ if (isMcpTool) {
4641
+ await this.complete(model, messages, {
4642
+ ...options,
4643
+ _internal: {
4644
+ toolCallCount: toolCallCount + 1
4645
+ }
4646
+ }, callback, toolsUsed);
4647
+ } else {
4648
+ await this.complete(model, messages, {
4649
+ ...options,
4650
+ tools: void 0,
4651
+ _internal: void 0
4652
+ }, callback, toolsUsed);
4653
+ }
4654
+ return;
4655
+ } catch (error) {
4656
+ if (error instanceof PermissionDeniedError) {
4657
+ throw error;
4658
+ }
4659
+ console.warn(`Error processing ${toolCall.function.name} tool:`, error);
4660
+ this.pushToolMessages(messages, {
4661
+ id: toolCall.id,
4662
+ name: toolCall.function.name,
4663
+ parameters: toolCall.function.arguments
4664
+ }, `Error: ${error instanceof Error ? error.message : "Unknown error"}`);
4665
+ const isMcpToolError = options.tools?.find((t) => t.toolSchema.name === toolCall.function.name)?._isMcpTool;
4666
+ if (isMcpToolError) {
4667
+ await this.complete(model, messages, {
4668
+ ...options,
4669
+ _internal: {
4670
+ toolCallCount: toolCallCount + 1
4671
+ }
4672
+ }, callback, toolsUsed);
4673
+ } else {
4674
+ await this.complete(model, messages, {
4675
+ ...options,
4676
+ tools: void 0,
4677
+ _internal: void 0
4678
+ }, callback, toolsUsed);
4679
+ }
4680
+ return;
4644
4681
  }
4645
- return;
4646
4682
  }
4647
4683
  }
4684
+ } else {
4685
+ this.logger.debug(`[Tool Execution] executeTools=false, passing tool calls to callback`);
4686
+ await callback([null], {
4687
+ inputTokens: 0,
4688
+ outputTokens: 0,
4689
+ toolsUsed: toolsUsed.length > 0 ? toolsUsed : void 0
4690
+ });
4691
+ return;
4648
4692
  }
4649
4693
  } else {
4650
4694
  streamedText[c.index] = c.message.content || "";
@@ -4700,43 +4744,57 @@ var XAIBackend = class {
4700
4744
  }
4701
4745
  if (func.length > 0) {
4702
4746
  for await (const tool of func) {
4703
- const { id, name, parameters: parameters2 } = tool;
4704
- const toolFn = options.tools?.find((tool2) => tool2.toolSchema.name === name)?.toolFn;
4705
- if (id && name && parameters2 && toolFn) {
4706
- try {
4707
- toolsUsed.push({
4708
- name,
4709
- arguments: parameters2
4710
- });
4711
- const result = await toolFn(JSON.parse(parameters2));
4712
- this.pushToolMessages(messages, {
4713
- id,
4714
- name,
4715
- parameters: parameters2
4716
- }, result);
4717
- } catch (error) {
4718
- if (error instanceof PermissionDeniedError) {
4719
- throw error;
4720
- }
4721
- this.logger.updateMetadata({
4722
- tool: name,
4723
- parameters: parameters2
4724
- });
4725
- if (error instanceof SyntaxError && /JSON/.test(error.message)) {
4726
- this.logger.warn("JSON parse error processing tool parameters:", error);
4727
- } else {
4728
- this.logger.error("Error processing tool:", error);
4747
+ const { name, parameters: parameters2 } = tool;
4748
+ if (name && parameters2) {
4749
+ toolsUsed.push({
4750
+ name,
4751
+ arguments: parameters2
4752
+ });
4753
+ }
4754
+ }
4755
+ if (options.executeTools !== false) {
4756
+ for await (const tool of func) {
4757
+ const { id, name, parameters: parameters2 } = tool;
4758
+ const toolFn = options.tools?.find((tool2) => tool2.toolSchema.name === name)?.toolFn;
4759
+ if (id && name && parameters2 && toolFn) {
4760
+ try {
4761
+ const result = await toolFn(JSON.parse(parameters2));
4762
+ this.pushToolMessages(messages, {
4763
+ id,
4764
+ name,
4765
+ parameters: parameters2
4766
+ }, result);
4767
+ } catch (error) {
4768
+ if (error instanceof PermissionDeniedError) {
4769
+ throw error;
4770
+ }
4771
+ this.logger.updateMetadata({
4772
+ tool: name,
4773
+ parameters: parameters2
4774
+ });
4775
+ if (error instanceof SyntaxError && /JSON/.test(error.message)) {
4776
+ this.logger.warn("JSON parse error processing tool parameters:", error);
4777
+ } else {
4778
+ this.logger.error("Error processing tool:", error);
4779
+ }
4780
+ this.pushToolMessages(messages, {
4781
+ id,
4782
+ name,
4783
+ parameters: parameters2
4784
+ }, `Error: ${error instanceof Error ? error.message : "Unknown error"}`);
4785
+ continue;
4729
4786
  }
4730
- this.pushToolMessages(messages, {
4731
- id,
4732
- name,
4733
- parameters: parameters2
4734
- }, `Error: ${error instanceof Error ? error.message : "Unknown error"}`);
4735
- continue;
4736
4787
  }
4737
4788
  }
4789
+ await this.complete(model, messages, { ...options, tools: options.tools }, callback, toolsUsed);
4790
+ } else {
4791
+ this.logger.debug(`[Tool Execution] executeTools=false, passing tool calls to callback`);
4792
+ await callback([null], {
4793
+ inputTokens,
4794
+ outputTokens,
4795
+ toolsUsed: toolsUsed.length > 0 ? toolsUsed : void 0
4796
+ });
4738
4797
  }
4739
- await this.complete(model, messages, { ...options, tools: options.tools }, callback, toolsUsed);
4740
4798
  }
4741
4799
  }
4742
4800
  formatMessages(messages) {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-B3YFSFVU.js";
5
+ } from "./chunk-EVPT4ARN.js";
6
6
  import {
7
7
  GenericCreditDeductTransaction,
8
8
  ImageEditUsageTransaction,
@@ -10,7 +10,7 @@ import {
10
10
  RealtimeVoiceUsageTransaction,
11
11
  TextGenerationUsageTransaction,
12
12
  TransferCreditTransaction
13
- } from "./chunk-MKO2KCCS.js";
13
+ } from "./chunk-VVV7WLJ6.js";
14
14
 
15
15
  // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
16
16
  import { z } from "zod";
@@ -3770,6 +3770,7 @@ var AuthEvents;
3770
3770
  AuthEvents2["RESET_LAND_PASSWORD"] = "Password Reset Landed";
3771
3771
  AuthEvents2["RESET_PASSWORD_TOKEN_EXPIRED"] = "Password Reset Token Expired";
3772
3772
  AuthEvents2["CHANGE_PASSWORD"] = "Password Changed";
3773
+ AuthEvents2["FORCE_CHANGE_PASSWORD"] = "Forced Password Changed";
3773
3774
  AuthEvents2["ADMIN_RESET_PASSWORD"] = "Admin Password Reset";
3774
3775
  AuthEvents2["FAILED_LOGIN"] = "Failed Login Attempt";
3775
3776
  AuthEvents2["EMAIL_VERIFIED"] = "Email Verified";
@@ -7,11 +7,11 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-B3YFSFVU.js";
10
+ } from "./chunk-EVPT4ARN.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-MKO2KCCS.js";
14
+ } from "./chunk-VVV7WLJ6.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-KZGZGNHL.js";
6
- import "./chunk-B3YFSFVU.js";
5
+ } from "./chunk-ZT7Z4QVD.js";
6
+ import "./chunk-EVPT4ARN.js";
7
7
  import "./chunk-CC67R4RB.js";
8
- import "./chunk-MKO2KCCS.js";
8
+ import "./chunk-VVV7WLJ6.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  createFabFile,
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-XANFVWI6.js";
8
- import "./chunk-TPSQ5MIR.js";
9
- import "./chunk-KZGZGNHL.js";
7
+ } from "./chunk-43ZKBRTE.js";
8
+ import "./chunk-FNZZAMET.js";
9
+ import "./chunk-ZT7Z4QVD.js";
10
10
  import {
11
11
  BFLImageService,
12
12
  BaseStorage,
@@ -15,7 +15,7 @@ import {
15
15
  OpenAIBackend,
16
16
  OpenAIImageService,
17
17
  XAIImageService
18
- } from "./chunk-B3YFSFVU.js";
18
+ } from "./chunk-EVPT4ARN.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-CC67R4RB.js";
@@ -72,7 +72,7 @@ import {
72
72
  XAI_IMAGE_MODELS,
73
73
  b4mLLMTools,
74
74
  getMcpProviderMetadata
75
- } from "./chunk-MKO2KCCS.js";
75
+ } from "./chunk-VVV7WLJ6.js";
76
76
  import {
77
77
  __require
78
78
  } from "./chunk-PDX44BCA.js";
@@ -207,6 +207,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
207
207
  const [selectedIndex, setSelectedIndex] = useState(0);
208
208
  const [historyIndex, setHistoryIndex] = useState(-1);
209
209
  const [tempInput, setTempInput] = useState("");
210
+ const [inputKey, setInputKey] = useState(0);
210
211
  const shouldShowAutocomplete = value.startsWith("/") && !disabled;
211
212
  const query = shouldShowAutocomplete ? value.slice(1) : "";
212
213
  const filteredCommands = useMemo(() => {
@@ -253,6 +254,12 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
253
254
  if (shouldShowAutocomplete && filteredCommands.length > 0) {
254
255
  const selectedCommand = filteredCommands[selectedIndex];
255
256
  const commandText = `/${selectedCommand.name}`;
257
+ if (selectedCommand.args) {
258
+ setValue(commandText + " ");
259
+ setHistoryIndex(-1);
260
+ setInputKey((prev) => prev + 1);
261
+ return;
262
+ }
256
263
  setValue("");
257
264
  setHistoryIndex(-1);
258
265
  onSubmit(commandText);
@@ -272,6 +279,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
272
279
  return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React3.createElement(
273
280
  TextInput,
274
281
  {
282
+ key: inputKey,
275
283
  value,
276
284
  onChange: handleChange,
277
285
  onSubmit: handleSubmit,
@@ -463,6 +471,7 @@ import React9, { useState as useState2, useEffect as useEffect2 } from "react";
463
471
  import { Box as Box9, Text as Text8 } from "ink";
464
472
  import Spinner2 from "ink-spinner";
465
473
  import jwt from "jsonwebtoken";
474
+ import open from "open";
466
475
 
467
476
  // src/auth/OAuthClient.ts
468
477
  import axios from "axios";
@@ -614,6 +623,13 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
614
623
  };
615
624
  runLoginFlow();
616
625
  }, [apiUrl, configStore, onSuccess, onError]);
626
+ useEffect2(() => {
627
+ if (deviceFlow && status === "waiting") {
628
+ open(deviceFlow.verification_uri_complete).catch((err) => {
629
+ console.error("Failed to auto-open browser:", err);
630
+ });
631
+ }
632
+ }, [deviceFlow, status]);
617
633
  if (status === "initiating") {
618
634
  return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
619
635
  }
@@ -623,7 +639,7 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
623
639
  if (status === "success") {
624
640
  return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "You can now use B4M CLI with your account.")));
625
641
  }
626
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "Please visit the following URL to authorize this device:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "Enter this code when prompted:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
642
+ return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "And enter this code when prompted:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
627
643
  }
628
644
 
629
645
  // src/storage/SessionStore.ts
@@ -860,7 +876,6 @@ var ConfigStore = class {
860
876
  } else {
861
877
  rawConfig.apiConfig = {};
862
878
  }
863
- console.log("[ConfigStore] Auto-migrated API config from old environment format");
864
879
  }
865
880
  const validated = CliConfigSchema.parse(rawConfig);
866
881
  this.config = {
@@ -882,10 +897,6 @@ var ConfigStore = class {
882
897
  },
883
898
  trustedTools: validated.trustedTools || []
884
899
  };
885
- console.log("[ConfigStore] Loaded config with auth:", !!this.config.auth);
886
- if (this.config.auth) {
887
- console.log("[ConfigStore] Auth userId:", this.config.auth.userId);
888
- }
889
900
  return this.config;
890
901
  } catch (error) {
891
902
  if (error.code === "ENOENT") {
@@ -929,13 +940,8 @@ var ConfigStore = class {
929
940
  throw new Error("No configuration to save");
930
941
  }
931
942
  try {
932
- console.log("[ConfigStore] Saving config with auth:", !!this.config.auth);
933
- if (this.config.auth) {
934
- console.log("[ConfigStore] Auth userId:", this.config.auth.userId);
935
- }
936
943
  await fs2.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
937
944
  await fs2.chmod(this.configPath, 384);
938
- console.log("[ConfigStore] Config saved to:", this.configPath);
939
945
  } catch (error) {
940
946
  console.error("Failed to save config:", error);
941
947
  throw error;
@@ -6694,7 +6700,7 @@ function stripThinkingBlocks(text) {
6694
6700
  }
6695
6701
  var ServerLlmBackend = class {
6696
6702
  constructor(options) {
6697
- this.completionsEndpoint = "/api/cli/completions";
6703
+ this.completionsEndpoint = "/api/ai/v1/completions";
6698
6704
  this.apiClient = options.apiClient;
6699
6705
  this.currentModel = options.model;
6700
6706
  }
@@ -6801,8 +6807,8 @@ var ServerLlmBackend = class {
6801
6807
  });
6802
6808
  } catch (error) {
6803
6809
  if (error instanceof Error) {
6804
- if (error.message.includes("Authentication expired")) {
6805
- reject(new Error("Authentication expired. Please run `b4m login` again."));
6810
+ if (error.message.includes("Authentication expired") || error.message.includes("Authentication failed")) {
6811
+ reject(error);
6806
6812
  } else if (error.message.includes("ECONNREFUSED")) {
6807
6813
  reject(new Error("Cannot connect to Bike4Mind server. Please check your internet connection."));
6808
6814
  } else if (error.message.includes("Rate limit exceeded")) {
@@ -6904,7 +6910,6 @@ var ApiClient = class {
6904
6910
  if (!tokens) {
6905
6911
  throw new Error("Not authenticated");
6906
6912
  }
6907
- console.log("\u{1F504} Access token expired, refreshing...");
6908
6913
  const newTokens = await this.oauthClient.refreshToken(tokens.refreshToken);
6909
6914
  const expiresAt = new Date(Date.now() + newTokens.expires_in * 1e3).toISOString();
6910
6915
  await this.configStore.setAuthTokens({
@@ -6914,7 +6919,6 @@ var ApiClient = class {
6914
6919
  userId: tokens.userId
6915
6920
  // Preserve userId
6916
6921
  });
6917
- console.log("\u2705 Token refreshed successfully");
6918
6922
  originalRequest.headers.Authorization = `Bearer ${newTokens.access_token}`;
6919
6923
  return this.client(originalRequest);
6920
6924
  } catch (refreshError) {
@@ -6927,6 +6931,10 @@ var ApiClient = class {
6927
6931
  throw new Error("Authentication expired. Please run `b4m login` again.");
6928
6932
  }
6929
6933
  }
6934
+ if (error.response?.status === 401 && originalRequest._retry) {
6935
+ await this.configStore.clearAuthTokens();
6936
+ throw new Error("Authentication failed. Please run /login to authenticate.");
6937
+ }
6930
6938
  return Promise.reject(error);
6931
6939
  }
6932
6940
  );
@@ -7327,6 +7335,13 @@ Remember: Use context from previous messages to understand follow-up questions.`
7327
7335
  setStoreSession(updatedSession);
7328
7336
  await state.sessionStore.save(updatedSession);
7329
7337
  } catch (error) {
7338
+ if (error instanceof Error) {
7339
+ if (error.message.includes("Authentication failed") || error.message.includes("Authentication expired")) {
7340
+ console.log("\n\u274C Authentication failed");
7341
+ console.log("\u{1F4A1} Run /login to authenticate with your API environment.\n");
7342
+ return;
7343
+ }
7344
+ }
7330
7345
  console.error("Error processing message:", error);
7331
7346
  }
7332
7347
  };
@@ -7418,14 +7433,20 @@ Tool Permissions:
7418
7433
  return;
7419
7434
  }
7420
7435
  await state.configStore.setCustomApiUrl(url);
7436
+ await state.configStore.clearAuthTokens();
7421
7437
  console.log(`
7422
- \u2705 Connected to self-hosted instance: ${url}`);
7438
+ \u2705 API URL updated: ${url}`);
7439
+ console.log("\u{1F513} Authentication cleared");
7440
+ console.log(`\u{1F4A1} Run /login to authenticate with ${url}`);
7423
7441
  console.log("Please restart the CLI for changes to take effect.\n");
7424
7442
  break;
7425
7443
  }
7426
7444
  case "reset-api":
7427
7445
  await state.configStore.setCustomApiUrl(null);
7428
- console.log("\n\u2705 Reset to Bike4Mind main service");
7446
+ await state.configStore.clearAuthTokens();
7447
+ console.log("\n\u2705 API URL reset to Bike4Mind main service");
7448
+ console.log("\u{1F513} Authentication cleared");
7449
+ console.log("\u{1F4A1} Run /login to authenticate");
7429
7450
  console.log("Please restart the CLI for changes to take effect.\n");
7430
7451
  break;
7431
7452
  case "api-info": {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-MKO2KCCS.js";
4
+ } from "./chunk-VVV7WLJ6.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/llmMarkdownGenerator.js
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-MKO2KCCS.js";
4
+ } from "./chunk-VVV7WLJ6.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/markdownGenerator.js
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  findMostSimilarMemento,
4
4
  getRelevantMementos
5
- } from "./chunk-XANFVWI6.js";
6
- import "./chunk-B3YFSFVU.js";
5
+ } from "./chunk-43ZKBRTE.js";
6
+ import "./chunk-EVPT4ARN.js";
7
7
  import "./chunk-CC67R4RB.js";
8
- import "./chunk-MKO2KCCS.js";
8
+ import "./chunk-VVV7WLJ6.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  findMostSimilarMemento,
@@ -291,7 +291,7 @@ import {
291
291
  validateQuestMasterArtifactV2,
292
292
  validateReactArtifactV2,
293
293
  validateSvgArtifactV2
294
- } from "./chunk-MKO2KCCS.js";
294
+ } from "./chunk-VVV7WLJ6.js";
295
295
  import "./chunk-PDX44BCA.js";
296
296
  export {
297
297
  ALL_IMAGE_MODELS,
@@ -117,7 +117,7 @@ import {
117
117
  validateMermaidSyntax,
118
118
  warmUpSettingsCache,
119
119
  withRetry
120
- } from "./chunk-B3YFSFVU.js";
120
+ } from "./chunk-EVPT4ARN.js";
121
121
  import {
122
122
  Logger,
123
123
  NotificationDeduplicator,
@@ -126,7 +126,7 @@ import {
126
126
  postLowCreditsNotificationToSlack,
127
127
  postMessageToSlack
128
128
  } from "./chunk-CC67R4RB.js";
129
- import "./chunk-MKO2KCCS.js";
129
+ import "./chunk-VVV7WLJ6.js";
130
130
  import "./chunk-PDX44BCA.js";
131
131
  export {
132
132
  AWSBackend,
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  SubtractCreditsSchema,
4
4
  subtractCredits
5
- } from "./chunk-TPSQ5MIR.js";
6
- import "./chunk-B3YFSFVU.js";
5
+ } from "./chunk-FNZZAMET.js";
6
+ import "./chunk-EVPT4ARN.js";
7
7
  import "./chunk-CC67R4RB.js";
8
- import "./chunk-MKO2KCCS.js";
8
+ import "./chunk-VVV7WLJ6.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  SubtractCreditsSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -76,6 +76,7 @@
76
76
  "mime-types": "^2.1.35",
77
77
  "mongoose": "^8.8.3",
78
78
  "ollama": "^0.5.12",
79
+ "open": "^11.0.0",
79
80
  "openai": "^5.12.2",
80
81
  "p-limit": "^6.2.0",
81
82
  "qrcode": "^1.5.4",