@bike4mind/cli 0.2.3-feat-questmaster-gpt5-function-calling.17056 → 0.2.3-fix-cli-credit-tracking-production.17058

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.
@@ -7,7 +7,7 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-BSDDDQF4.js";
10
+ } from "./chunk-NZADYDFG.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
@@ -6,7 +6,7 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-BSDDDQF4.js";
9
+ } from "./chunk-NZADYDFG.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
@@ -4112,12 +4112,6 @@ var OpenAIBackend = class {
4112
4112
  }
4113
4113
  if (options.tools?.length) {
4114
4114
  parameters.tools = this.formatTools(options.tools);
4115
- if (options.tool_choice) {
4116
- parameters.tool_choice = options.tool_choice;
4117
- }
4118
- if (options.parallel_tool_calls !== void 0) {
4119
- parameters.parallel_tool_calls = options.parallel_tool_calls;
4120
- }
4121
4115
  }
4122
4116
  const response = await this._api.chat.completions.create(parameters, {
4123
4117
  signal: options.abortSignal
@@ -7984,165 +7978,6 @@ function extractQuestMasterData(reply, options = {}) {
7984
7978
  return questMasterData;
7985
7979
  }
7986
7980
 
7987
- // ../../b4m-core/packages/utils/dist/src/questMasterToolSchema.js
7988
- var GPT5_MODELS_WITH_TOOL_SUPPORT = [
7989
- ChatModels.GPT5,
7990
- ChatModels.GPT5_MINI,
7991
- ChatModels.GPT5_NANO,
7992
- ChatModels.GPT5_1,
7993
- ChatModels.GPT5_2
7994
- ];
7995
- function isGPT5ModelWithToolSupport(model) {
7996
- return GPT5_MODELS_WITH_TOOL_SUPPORT.includes(model);
7997
- }
7998
- var createQuestPlanToolSchema = {
7999
- name: "create_quest_plan",
8000
- description: `Break down a user request into a structured quest plan with actionable tasks.
8001
-
8002
- GUIDELINES:
8003
- - Analyze the user's request and create 3-7 main quests
8004
- - Each quest must have 2-5 specific, actionable subquests
8005
- - Quest titles should be clear and action-oriented (e.g., "Set up database schema" not "Step 1")
8006
- - Provide detailed descriptions for each quest
8007
- - Assess complexity accurately: Easy (< 1 hour), Medium (1-4 hours), Hard (> 4 hours)
8008
- - Generate 2-5 relevant tags categorizing the work (e.g., "web-development", "database", "api")
8009
-
8010
- ALWAYS call this function to respond. Do NOT respond with plain text.`,
8011
- parameters: {
8012
- type: "object",
8013
- properties: {
8014
- goal: {
8015
- type: "string",
8016
- description: "The overall objective the user wants to achieve"
8017
- },
8018
- tags: {
8019
- type: "array",
8020
- items: { type: "string" },
8021
- description: 'Categories for this quest (e.g., "web-development", "api", "database")'
8022
- },
8023
- quests: {
8024
- type: "array",
8025
- description: "The main quests (3-7) that break down the goal",
8026
- items: {
8027
- type: "object",
8028
- properties: {
8029
- id: {
8030
- type: "string",
8031
- description: 'Unique identifier (e.g., "quest-1", "setup-database")'
8032
- },
8033
- title: {
8034
- type: "string",
8035
- description: 'Clear, action-oriented title (e.g., "Configure authentication middleware")'
8036
- },
8037
- description: {
8038
- type: "string",
8039
- description: "Detailed explanation of what needs to be done and why"
8040
- },
8041
- complexity: {
8042
- type: "string",
8043
- enum: ["Easy", "Medium", "Hard"],
8044
- description: "Difficulty assessment based on effort required"
8045
- },
8046
- subQuests: {
8047
- type: "array",
8048
- description: "Concrete subtasks (2-5) within this quest",
8049
- items: {
8050
- type: "object",
8051
- properties: {
8052
- id: {
8053
- type: "string",
8054
- description: "Unique identifier for the subquest"
8055
- },
8056
- title: {
8057
- type: "string",
8058
- description: "Specific, actionable subtask title"
8059
- }
8060
- },
8061
- required: ["id", "title"]
8062
- }
8063
- }
8064
- },
8065
- required: ["id", "title", "description", "complexity", "subQuests"]
8066
- }
8067
- }
8068
- },
8069
- required: ["goal", "quests"]
8070
- }
8071
- };
8072
- function parseQuestPlanFunctionCall(args) {
8073
- if (!args || typeof args !== "string" || args.trim() === "") {
8074
- throw new Error("Function call arguments are empty or invalid");
8075
- }
8076
- let parsed;
8077
- try {
8078
- parsed = JSON.parse(args);
8079
- } catch (e) {
8080
- throw new Error(`Failed to parse function call arguments as JSON: ${e}`);
8081
- }
8082
- if (!parsed || typeof parsed !== "object") {
8083
- throw new Error("Function call arguments must be an object");
8084
- }
8085
- const result = parsed;
8086
- if (!result.goal || typeof result.goal !== "string" || result.goal.trim() === "") {
8087
- throw new Error("Function call missing required field: goal (must be non-empty string)");
8088
- }
8089
- if (!Array.isArray(result.quests)) {
8090
- throw new Error("Function call missing required field: quests (must be an array)");
8091
- }
8092
- if (result.quests.length === 0) {
8093
- throw new Error("Function call returned empty quests array");
8094
- }
8095
- for (let i = 0; i < result.quests.length; i++) {
8096
- const quest = result.quests[i];
8097
- if (!quest || typeof quest !== "object") {
8098
- throw new Error(`Quest ${i} is not a valid object`);
8099
- }
8100
- const questObj = quest;
8101
- if (!questObj.id || typeof questObj.id !== "string" || questObj.id.trim() === "") {
8102
- throw new Error(`Quest ${i} missing required field: id (must be non-empty string)`);
8103
- }
8104
- if (!questObj.title || typeof questObj.title !== "string" || questObj.title.trim() === "") {
8105
- throw new Error(`Quest ${i} missing required field: title (must be non-empty string)`);
8106
- }
8107
- if (!questObj.description || typeof questObj.description !== "string" || questObj.description.trim() === "") {
8108
- throw new Error(`Quest ${i} missing required field: description (must be non-empty string)`);
8109
- }
8110
- if (!questObj.complexity || !["Easy", "Medium", "Hard"].includes(questObj.complexity)) {
8111
- throw new Error(`Quest ${i} has invalid complexity: ${questObj.complexity} (must be Easy, Medium, or Hard)`);
8112
- }
8113
- if (!Array.isArray(questObj.subQuests)) {
8114
- throw new Error(`Quest "${questObj.id}" missing required field: subQuests (must be an array)`);
8115
- }
8116
- if (questObj.subQuests.length === 0) {
8117
- throw new Error(`Quest "${questObj.id}" has no subQuests (minimum 2 required)`);
8118
- }
8119
- for (let j = 0; j < questObj.subQuests.length; j++) {
8120
- const subQuest = questObj.subQuests[j];
8121
- if (!subQuest || typeof subQuest !== "object") {
8122
- throw new Error(`Quest "${questObj.id}" subQuest ${j} is not a valid object`);
8123
- }
8124
- const subQuestObj = subQuest;
8125
- if (!subQuestObj.id || typeof subQuestObj.id !== "string" || subQuestObj.id.trim() === "") {
8126
- throw new Error(`Quest "${questObj.id}" subQuest ${j} missing required field: id (must be non-empty string)`);
8127
- }
8128
- if (!subQuestObj.title || typeof subQuestObj.title !== "string" || subQuestObj.title.trim() === "") {
8129
- throw new Error(`Quest "${questObj.id}" subQuest ${j} missing required field: title (must be non-empty string)`);
8130
- }
8131
- }
8132
- }
8133
- if (result.tags !== void 0) {
8134
- if (!Array.isArray(result.tags)) {
8135
- throw new Error("Function call field tags must be an array if provided");
8136
- }
8137
- for (let i = 0; i < result.tags.length; i++) {
8138
- if (typeof result.tags[i] !== "string") {
8139
- throw new Error(`Function call field tags[${i}] must be a string`);
8140
- }
8141
- }
8142
- }
8143
- return result;
8144
- }
8145
-
8146
7981
  // ../../b4m-core/packages/utils/dist/src/questMaster.js
8147
7982
  var sanitizeId = (id) => {
8148
7983
  return id.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9_.-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
@@ -8173,9 +8008,10 @@ var QuestMaster = class {
8173
8008
  }
8174
8009
  return "Easy";
8175
8010
  }
8176
- async processQuestPlan(input) {
8011
+ async processQuestPlan(questPlanText) {
8177
8012
  try {
8178
8013
  await this.onStatusUpdate(this.quest, "Processing quest plan...");
8014
+ this.logger.log("Processing quest plan:", questPlanText);
8179
8015
  const defaultResponse = {
8180
8016
  type: "narrative",
8181
8017
  meta: {
@@ -8192,161 +8028,135 @@ var QuestMaster = class {
8192
8028
  }
8193
8029
  ]
8194
8030
  };
8031
+ if (!questPlanText || typeof questPlanText !== "string") {
8032
+ this.logger.warn("Invalid questPlanText received:", questPlanText);
8033
+ if (this.quest) {
8034
+ this.quest.questMasterReply = JSON.stringify(defaultResponse);
8035
+ await this.db.quests.update({
8036
+ id: this.quest.id,
8037
+ questMasterReply: this.quest.questMasterReply,
8038
+ reply: null,
8039
+ replies: [],
8040
+ status: "done",
8041
+ type: "message"
8042
+ });
8043
+ }
8044
+ return;
8045
+ }
8195
8046
  if (!this.quest) {
8196
8047
  throw new Error("No quest context available");
8197
8048
  }
8049
+ const extracted = extractQuestMasterData(questPlanText, { logger: this.logger });
8050
+ const metaStartTag = "<!--QuestMasterMeta";
8051
+ const metaEndTag = "-->";
8052
+ const metaStartIndex = questPlanText.indexOf(metaStartTag);
8053
+ let goal = "Quest Plan";
8054
+ let tags = [];
8198
8055
  let questResponse;
8199
- if (input !== null && typeof input === "object") {
8200
- this.logger.log("Processing quest plan from function calling result");
8056
+ if (metaStartIndex !== -1) {
8057
+ const metaEndIndex = questPlanText.indexOf(metaEndTag, metaStartIndex);
8058
+ if (metaEndIndex !== -1) {
8059
+ const metaContent = questPlanText.slice(metaStartIndex + metaStartTag.length, metaEndIndex).trim();
8060
+ try {
8061
+ const jsonStartIndex = metaContent.indexOf("{");
8062
+ if (jsonStartIndex !== -1) {
8063
+ const metaData = JSON.parse(metaContent.slice(jsonStartIndex));
8064
+ goal = metaData.goal || goal;
8065
+ tags = Array.isArray(metaData.tags) ? metaData.tags : [];
8066
+ }
8067
+ } catch (err) {
8068
+ this.logger.error("Error parsing meta data:", err);
8069
+ }
8070
+ }
8071
+ }
8072
+ if (extracted.length > 0) {
8073
+ this.logger.log("Successfully extracted QuestMaster data:", extracted);
8074
+ await this.onStatusUpdate(this.quest, "Extracted QuestMaster data");
8075
+ const validQuests = extracted.filter((quest) => quest !== null && typeof quest === "object" && quest.id && quest.title && quest.title !== "Step 1" && // Explicitly filter out generic Step 1
8076
+ quest.description && quest.description !== "No description available");
8077
+ if (validQuests.length === 0) {
8078
+ throw new Error("No valid quests found after filtering");
8079
+ }
8201
8080
  questResponse = {
8202
8081
  type: "quest_plan",
8203
8082
  meta: {
8204
- goal: input.goal,
8205
- totalSteps: input.quests.length,
8206
- tags: input.tags
8083
+ goal,
8084
+ totalSteps: validQuests.length,
8085
+ tags
8207
8086
  },
8208
- quests: input.quests.map((quest) => ({
8087
+ quests: validQuests.map((quest) => ({
8209
8088
  id: quest.id,
8089
+ // No fallback - we filtered for valid IDs
8210
8090
  title: quest.title,
8091
+ // No fallback - we filtered for valid titles
8211
8092
  description: quest.description,
8212
- complexity: quest.complexity,
8093
+ // No fallback - we filtered for valid descriptions
8094
+ complexity: quest.complexity || "Medium",
8213
8095
  status: "not_started",
8214
- subQuests: quest.subQuests.map((sub) => ({
8096
+ subQuests: Array.isArray(quest.subQuests) ? quest.subQuests.filter((sub) => sub && sub.id && sub.title && !sub.title.startsWith("Subtask")).map((sub) => ({
8215
8097
  id: sub.id,
8216
8098
  title: sub.title,
8217
8099
  status: "not_started"
8218
- }))
8100
+ })) : []
8219
8101
  }))
8220
8102
  };
8221
- } else {
8222
- const questPlanText = input;
8223
- this.logger.log("Processing quest plan:", questPlanText);
8224
- if (!questPlanText || typeof questPlanText !== "string") {
8225
- this.logger.warn("Invalid questPlanText received:", questPlanText);
8226
- if (this.quest) {
8227
- this.quest.questMasterReply = JSON.stringify(defaultResponse);
8228
- await this.db.quests.update({
8229
- id: this.quest.id,
8230
- questMasterReply: this.quest.questMasterReply,
8231
- reply: null,
8232
- replies: [],
8233
- status: "done",
8234
- type: "message"
8235
- });
8236
- }
8237
- return;
8103
+ if (questResponse.quests.some((quest) => quest.subQuests.length === 0)) {
8104
+ throw new Error("Some quests have no valid subquests after filtering");
8238
8105
  }
8239
- const extracted = extractQuestMasterData(questPlanText, { logger: this.logger });
8240
- const metaStartTag = "<!--QuestMasterMeta";
8241
- const metaEndTag = "-->";
8242
- const metaStartIndex = questPlanText.indexOf(metaStartTag);
8243
- let goal = "Quest Plan";
8244
- let tags = [];
8245
- if (metaStartIndex !== -1) {
8246
- const metaEndIndex = questPlanText.indexOf(metaEndTag, metaStartIndex);
8247
- if (metaEndIndex !== -1) {
8248
- const metaContent = questPlanText.slice(metaStartIndex + metaStartTag.length, metaEndIndex).trim();
8249
- try {
8250
- const jsonStartIndex = metaContent.indexOf("{");
8251
- if (jsonStartIndex !== -1) {
8252
- const metaData = JSON.parse(metaContent.slice(jsonStartIndex));
8253
- goal = metaData.goal || goal;
8254
- tags = Array.isArray(metaData.tags) ? metaData.tags : [];
8255
- }
8256
- } catch (err) {
8257
- this.logger.error("Error parsing meta data:", err);
8106
+ } else {
8107
+ try {
8108
+ const questPlan = JSON.parse(questPlanText);
8109
+ if (questPlan && questPlan.questChain && Array.isArray(questPlan.questChain)) {
8110
+ const validQuestChain = questPlan.questChain.filter((item) => item && item.quest && item.quest !== "Step 1" && item.details && item.details !== "No description available");
8111
+ if (validQuestChain.length === 0) {
8112
+ throw new Error("No valid quests found in quest chain");
8258
8113
  }
8259
- }
8260
- }
8261
- if (extracted.length > 0) {
8262
- this.logger.log("Successfully extracted QuestMaster data:", extracted);
8263
- await this.onStatusUpdate(this.quest, "Extracted QuestMaster data");
8264
- const validQuests = extracted.filter((quest) => quest !== null && typeof quest === "object" && quest.id && quest.title && quest.title !== "Step 1" && // Explicitly filter out generic Step 1
8265
- quest.description && quest.description !== "No description available");
8266
- if (validQuests.length === 0) {
8267
- throw new Error("No valid quests found after filtering");
8268
- }
8269
- questResponse = {
8270
- type: "quest_plan",
8271
- meta: {
8272
- goal,
8273
- totalSteps: validQuests.length,
8274
- tags
8275
- },
8276
- quests: validQuests.map((quest) => ({
8277
- id: quest.id,
8278
- // No fallback - we filtered for valid IDs
8279
- title: quest.title,
8280
- // No fallback - we filtered for valid titles
8281
- description: quest.description,
8282
- // No fallback - we filtered for valid descriptions
8283
- complexity: quest.complexity || "Medium",
8284
- status: "not_started",
8285
- subQuests: Array.isArray(quest.subQuests) ? quest.subQuests.filter((sub) => sub && sub.id && sub.title && !sub.title.startsWith("Subtask")).map((sub) => ({
8286
- id: sub.id,
8287
- title: sub.title,
8288
- status: "not_started"
8289
- })) : []
8290
- }))
8291
- };
8292
- if (questResponse.quests.some((quest) => quest.subQuests.length === 0)) {
8293
- throw new Error("Some quests have no valid subquests after filtering");
8294
- }
8295
- } else {
8296
- try {
8297
- const questPlan = JSON.parse(questPlanText);
8298
- if (questPlan && questPlan.questChain && Array.isArray(questPlan.questChain)) {
8299
- const validQuestChain = questPlan.questChain.filter((item) => item && item.quest && item.quest !== "Step 1" && item.details && item.details !== "No description available");
8300
- if (validQuestChain.length === 0) {
8301
- throw new Error("No valid quests found in quest chain");
8302
- }
8303
- questResponse = {
8304
- type: "quest_plan",
8305
- meta: {
8306
- goal: questPlan.abstractObjective || "Process Request",
8307
- totalSteps: validQuestChain.length
8308
- },
8309
- quests: validQuestChain.map((item, index) => ({
8310
- id: `quest-${index + 1}`,
8311
- title: item.quest,
8312
- description: item.details,
8313
- complexity: this.determineComplexity(item.details),
8314
- status: "not_started",
8315
- subQuests: []
8316
- // This will trigger a retry since we require subquests
8317
- }))
8318
- };
8319
- } else {
8320
- if (!questPlanText.trim() || questPlanText.trim() === "Step 1") {
8321
- throw new Error("Empty or invalid response received");
8322
- }
8323
- questResponse = {
8324
- type: "narrative",
8325
- meta: {
8326
- goal: "Direct Response",
8327
- totalSteps: 1
8328
- },
8329
- quests: [
8330
- {
8331
- id: "narrative-1",
8332
- title: "Process Response",
8333
- description: questPlanText.trim(),
8334
- complexity: "Medium",
8335
- subQuests: [
8336
- {
8337
- id: "narrative-1-1",
8338
- title: "Review Response",
8339
- status: "not_started"
8340
- }
8341
- ]
8342
- }
8343
- ]
8344
- };
8114
+ questResponse = {
8115
+ type: "quest_plan",
8116
+ meta: {
8117
+ goal: questPlan.abstractObjective || "Process Request",
8118
+ totalSteps: validQuestChain.length
8119
+ },
8120
+ quests: validQuestChain.map((item, index) => ({
8121
+ id: `quest-${index + 1}`,
8122
+ title: item.quest,
8123
+ description: item.details,
8124
+ complexity: this.determineComplexity(item.details),
8125
+ status: "Not Started",
8126
+ subQuests: []
8127
+ // This will trigger a retry since we require subquests
8128
+ }))
8129
+ };
8130
+ } else {
8131
+ if (!questPlanText.trim() || questPlanText.trim() === "Step 1") {
8132
+ throw new Error("Empty or invalid response received");
8345
8133
  }
8346
- } catch (parseError) {
8347
- this.logger.error("Error parsing quest plan JSON:", parseError);
8348
- questResponse = defaultResponse;
8134
+ questResponse = {
8135
+ type: "narrative",
8136
+ meta: {
8137
+ goal: "Direct Response",
8138
+ totalSteps: 1
8139
+ },
8140
+ quests: [
8141
+ {
8142
+ id: "narrative-1",
8143
+ title: "Process Response",
8144
+ description: questPlanText.trim(),
8145
+ complexity: "Medium",
8146
+ subQuests: [
8147
+ {
8148
+ id: "narrative-1-1",
8149
+ title: "Review Response",
8150
+ status: "not_started"
8151
+ }
8152
+ ]
8153
+ }
8154
+ ]
8155
+ };
8349
8156
  }
8157
+ } catch (parseError) {
8158
+ this.logger.error("Error parsing quest plan JSON:", parseError);
8159
+ questResponse = defaultResponse;
8350
8160
  }
8351
8161
  }
8352
8162
  if (!this.validateQuestResponse(questResponse)) {
@@ -8546,106 +8356,9 @@ var QuestMaster = class {
8546
8356
  }
8547
8357
  -->`;
8548
8358
  }
8549
- /**
8550
- * Create a quest plan using GPT-5's function calling feature.
8551
- * This method is used when the model is a GPT-5 variant that supports tools
8552
- * but doesn't reliably follow HTML comment formatting.
8553
- *
8554
- * @param model - The GPT-5 model to use
8555
- * @param prompt - The user's request to break down into quests
8556
- * @returns The parsed quest plan result
8557
- */
8558
- async createQuestPlanWithFunctionCalling(model, prompt, retryCount = 0) {
8559
- const MAX_RETRIES = 2;
8560
- const messages = [
8561
- {
8562
- role: "system",
8563
- content: `You are the QuestMaster, an AI agent that breaks down complex tasks into manageable quests.
8564
-
8565
- When given a user request, you MUST call the create_quest_plan function to structure your response.
8566
- Do NOT respond with plain text - ALWAYS use the function call.
8567
-
8568
- Guidelines:
8569
- - Break down complex tasks into 3-7 main quests
8570
- - Each quest needs 2-5 specific, actionable subquests
8571
- - Make titles clear and action-oriented (e.g., "Set up database schema" not "Step 1")
8572
- - Provide detailed descriptions explaining what needs to be done
8573
- - Assess complexity accurately: Easy (< 1 hour), Medium (1-4 hours), Hard (> 4 hours)
8574
- - Generate 2-5 relevant tags categorizing the work`
8575
- },
8576
- { role: "user", content: prompt }
8577
- ];
8578
- const toolDef = {
8579
- toolFn: async (params) => JSON.stringify(params),
8580
- // Not executed, just captured
8581
- toolSchema: createQuestPlanToolSchema
8582
- };
8583
- const options = {
8584
- temperature: retryCount > 0 ? 0.5 : 0.7,
8585
- // Lower temperature for structured JSON outputs; even lower on retries
8586
- n: 1,
8587
- stream: false,
8588
- tools: [toolDef],
8589
- executeTools: false,
8590
- // Don't execute, just capture the function call
8591
- tool_choice: { type: "function", function: { name: "create_quest_plan" } },
8592
- // Force function call
8593
- parallel_tool_calls: false
8594
- // Required for structured outputs
8595
- };
8596
- let functionResult = null;
8597
- let lastError = null;
8598
- try {
8599
- await this.llm.complete(model, messages, options, async (text, completionInfo) => {
8600
- if (completionInfo?.toolsUsed?.length) {
8601
- const toolCall = completionInfo.toolsUsed[0];
8602
- if (toolCall.name === "create_quest_plan" && toolCall.arguments) {
8603
- this.logger.log("GPT-5 function call received, parsing arguments...");
8604
- functionResult = parseQuestPlanFunctionCall(toolCall.arguments);
8605
- }
8606
- }
8607
- });
8608
- } catch (error) {
8609
- lastError = error instanceof Error ? error : new Error(String(error));
8610
- this.logger.error("Error in GPT-5 function calling:", lastError);
8611
- }
8612
- if (!functionResult) {
8613
- if (retryCount < MAX_RETRIES) {
8614
- this.logger.warn(`GPT-5 did not return function call, retrying (attempt ${retryCount + 1}/${MAX_RETRIES})...`);
8615
- return this.createQuestPlanWithFunctionCalling(model, prompt, retryCount + 1);
8616
- }
8617
- throw lastError || new Error("GPT-5 did not call create_quest_plan function after retries");
8618
- }
8619
- const result = functionResult;
8620
- const questsWithoutSubquests = result.quests.filter((q) => !q.subQuests || q.subQuests.length === 0);
8621
- if (questsWithoutSubquests.length > 0) {
8622
- if (retryCount < MAX_RETRIES) {
8623
- this.logger.warn(`Some quests missing subquests: ${questsWithoutSubquests.map((q) => q.id).join(", ")}, retrying...`);
8624
- return this.createQuestPlanWithFunctionCalling(model, prompt, retryCount + 1);
8625
- } else {
8626
- this.logger.warn(`Returning quest plan with ${questsWithoutSubquests.length} quests missing subquests after max retries (${MAX_RETRIES}): ${questsWithoutSubquests.map((q) => q.id).join(", ")}`);
8627
- }
8628
- }
8629
- this.logger.log("Successfully received GPT-5 function call result:", {
8630
- goal: result.goal,
8631
- questCount: result.quests.length,
8632
- tags: result.tags
8633
- });
8634
- return result;
8635
- }
8636
8359
  async createQuestPlan(model, prompt) {
8637
8360
  try {
8638
8361
  await this.onStatusUpdate(this.quest, "Creating quest plan...");
8639
- if (isGPT5ModelWithToolSupport(model)) {
8640
- this.logger.log(`Using function calling approach for GPT-5 model: ${model}`);
8641
- try {
8642
- const result = await this.createQuestPlanWithFunctionCalling(model, prompt);
8643
- await this.processQuestPlan(result);
8644
- return;
8645
- } catch (functionCallError) {
8646
- this.logger.error("Function calling failed, falling back to HTML approach:", functionCallError);
8647
- }
8648
- }
8649
8362
  const messages = [
8650
8363
  {
8651
8364
  role: "system",
@@ -10739,9 +10452,6 @@ export {
10739
10452
  sendToConnection,
10740
10453
  ClientMessageSender,
10741
10454
  OpenaiModerationsService,
10742
- isGPT5ModelWithToolSupport,
10743
- createQuestPlanToolSchema,
10744
- parseQuestPlanFunctionCall,
10745
10455
  QuestMaster,
10746
10456
  OpenAIImageService,
10747
10457
  TestImageService,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-BSDDDQF4.js";
5
+ } from "./chunk-NZADYDFG.js";
6
6
  import {
7
7
  GenericCreditDeductTransaction,
8
8
  ImageEditUsageTransaction,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-55HUCQWS.js";
6
- import "./chunk-BSDDDQF4.js";
5
+ } from "./chunk-5N4PG5EH.js";
6
+ import "./chunk-NZADYDFG.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
8
  import "./chunk-WR6YZRQV.js";
9
9
  import "./chunk-PDX44BCA.js";
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-QGLZY6IF.js";
8
- import "./chunk-CS24JD7W.js";
9
- import "./chunk-55HUCQWS.js";
7
+ } from "./chunk-GZTILMGE.js";
8
+ import "./chunk-Y4HMTEDH.js";
9
+ import "./chunk-5N4PG5EH.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-BSDDDQF4.js";
18
+ } from "./chunk-NZADYDFG.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-AMDXHL6S.js";
@@ -9178,7 +9178,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
9178
9178
  // package.json
9179
9179
  var package_default = {
9180
9180
  name: "@bike4mind/cli",
9181
- version: "0.2.3-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9181
+ version: "0.2.3-fix-cli-credit-tracking-production.17058+0c3a6031d",
9182
9182
  type: "module",
9183
9183
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9184
9184
  license: "UNLICENSED",
@@ -9280,10 +9280,10 @@ var package_default = {
9280
9280
  },
9281
9281
  devDependencies: {
9282
9282
  "@bike4mind/agents": "0.1.0",
9283
- "@bike4mind/common": "2.37.1-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9284
- "@bike4mind/mcp": "1.19.5-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9285
- "@bike4mind/services": "2.31.1-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9286
- "@bike4mind/utils": "2.0.4-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9283
+ "@bike4mind/common": "2.37.1-fix-cli-credit-tracking-production.17058+0c3a6031d",
9284
+ "@bike4mind/mcp": "1.19.5-fix-cli-credit-tracking-production.17058+0c3a6031d",
9285
+ "@bike4mind/services": "2.31.1-fix-cli-credit-tracking-production.17058+0c3a6031d",
9286
+ "@bike4mind/utils": "2.0.4-fix-cli-credit-tracking-production.17058+0c3a6031d",
9287
9287
  "@types/diff": "^5.0.9",
9288
9288
  "@types/jsonwebtoken": "^9.0.4",
9289
9289
  "@types/node": "^22.9.0",
@@ -9295,7 +9295,7 @@ var package_default = {
9295
9295
  typescript: "^5.9.3",
9296
9296
  vitest: "^3.2.4"
9297
9297
  },
9298
- gitHead: "aaf443baeab1b87a7675e1577cc6535b2042bcdc"
9298
+ gitHead: "0c3a6031d972f1c677c04c1da2e786f1609656e9"
9299
9299
  };
9300
9300
 
9301
9301
  // src/config/constants.ts
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  findMostSimilarMemento,
4
4
  getRelevantMementos
5
- } from "./chunk-QGLZY6IF.js";
6
- import "./chunk-BSDDDQF4.js";
5
+ } from "./chunk-GZTILMGE.js";
6
+ import "./chunk-NZADYDFG.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
8
  import "./chunk-WR6YZRQV.js";
9
9
  import "./chunk-PDX44BCA.js";
@@ -65,7 +65,6 @@ import {
65
65
  cleanMermaidSyntax,
66
66
  computeCosineSimilarity,
67
67
  convertCodeBlocksToArtifacts,
68
- createQuestPlanToolSchema,
69
68
  createTokenizer,
70
69
  decodeBase64DataUrl,
71
70
  detectURLs,
@@ -98,7 +97,6 @@ import {
98
97
  includeImagePromptSystemMessage,
99
98
  initializeConfig,
100
99
  invalidateSettingsCache,
101
- isGPT5ModelWithToolSupport,
102
100
  isMermaidSyntax,
103
101
  isModelAccessible,
104
102
  isPlainText,
@@ -107,7 +105,6 @@ import {
107
105
  isZodError,
108
106
  obfuscateApiKey,
109
107
  parseArtifacts,
110
- parseQuestPlanFunctionCall,
111
108
  processFabFilesServer,
112
109
  processUrlsFromPrompt,
113
110
  secureParameters,
@@ -120,7 +117,7 @@ import {
120
117
  validateMermaidSyntax,
121
118
  warmUpSettingsCache,
122
119
  withRetry
123
- } from "./chunk-BSDDDQF4.js";
120
+ } from "./chunk-NZADYDFG.js";
124
121
  import {
125
122
  Logger,
126
123
  NotificationDeduplicator,
@@ -199,7 +196,6 @@ export {
199
196
  cleanMermaidSyntax,
200
197
  computeCosineSimilarity,
201
198
  convertCodeBlocksToArtifacts,
202
- createQuestPlanToolSchema,
203
199
  createTokenizer,
204
200
  decodeBase64DataUrl,
205
201
  detectURLs,
@@ -232,7 +228,6 @@ export {
232
228
  includeImagePromptSystemMessage,
233
229
  initializeConfig,
234
230
  invalidateSettingsCache,
235
- isGPT5ModelWithToolSupport,
236
231
  isMermaidSyntax,
237
232
  isModelAccessible,
238
233
  isPlainText,
@@ -243,7 +238,6 @@ export {
243
238
  notifyEventLogsToSlack,
244
239
  obfuscateApiKey,
245
240
  parseArtifacts,
246
- parseQuestPlanFunctionCall,
247
241
  postLowCreditsNotificationToSlack,
248
242
  postMessageToSlack,
249
243
  processFabFilesServer,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  SubtractCreditsSchema,
4
4
  subtractCredits
5
- } from "./chunk-CS24JD7W.js";
6
- import "./chunk-BSDDDQF4.js";
5
+ } from "./chunk-Y4HMTEDH.js";
6
+ import "./chunk-NZADYDFG.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
8
  import "./chunk-WR6YZRQV.js";
9
9
  import "./chunk-PDX44BCA.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.3-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
3
+ "version": "0.2.3-fix-cli-credit-tracking-production.17058+0c3a6031d",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -102,10 +102,10 @@
102
102
  },
103
103
  "devDependencies": {
104
104
  "@bike4mind/agents": "0.1.0",
105
- "@bike4mind/common": "2.37.1-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
106
- "@bike4mind/mcp": "1.19.5-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
107
- "@bike4mind/services": "2.31.1-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
108
- "@bike4mind/utils": "2.0.4-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
105
+ "@bike4mind/common": "2.37.1-fix-cli-credit-tracking-production.17058+0c3a6031d",
106
+ "@bike4mind/mcp": "1.19.5-fix-cli-credit-tracking-production.17058+0c3a6031d",
107
+ "@bike4mind/services": "2.31.1-fix-cli-credit-tracking-production.17058+0c3a6031d",
108
+ "@bike4mind/utils": "2.0.4-fix-cli-credit-tracking-production.17058+0c3a6031d",
109
109
  "@types/diff": "^5.0.9",
110
110
  "@types/jsonwebtoken": "^9.0.4",
111
111
  "@types/node": "^22.9.0",
@@ -117,5 +117,5 @@
117
117
  "typescript": "^5.9.3",
118
118
  "vitest": "^3.2.4"
119
119
  },
120
- "gitHead": "aaf443baeab1b87a7675e1577cc6535b2042bcdc"
120
+ "gitHead": "0c3a6031d972f1c677c04c1da2e786f1609656e9"
121
121
  }