@bike4mind/cli 0.2.3-feat-questmaster-gpt5-function-calling.17056 → 0.2.3-feat-cli-clear-command.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";
@@ -384,6 +384,11 @@ var COMMANDS = [
384
384
  {
385
385
  name: "usage",
386
386
  description: "Show credit usage and balance"
387
+ },
388
+ {
389
+ name: "clear",
390
+ description: "Start a new session",
391
+ aliases: ["new"]
387
392
  }
388
393
  ];
389
394
 
@@ -9178,7 +9183,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
9178
9183
  // package.json
9179
9184
  var package_default = {
9180
9185
  name: "@bike4mind/cli",
9181
- version: "0.2.3-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
9186
+ version: "0.2.3-feat-cli-clear-command.17058+9fe45e4bf",
9182
9187
  type: "module",
9183
9188
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9184
9189
  license: "UNLICENSED",
@@ -9280,10 +9285,10 @@ var package_default = {
9280
9285
  },
9281
9286
  devDependencies: {
9282
9287
  "@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",
9288
+ "@bike4mind/common": "2.37.1-feat-cli-clear-command.17058+9fe45e4bf",
9289
+ "@bike4mind/mcp": "1.19.5-feat-cli-clear-command.17058+9fe45e4bf",
9290
+ "@bike4mind/services": "2.31.1-feat-cli-clear-command.17058+9fe45e4bf",
9291
+ "@bike4mind/utils": "2.0.4-feat-cli-clear-command.17058+9fe45e4bf",
9287
9292
  "@types/diff": "^5.0.9",
9288
9293
  "@types/jsonwebtoken": "^9.0.4",
9289
9294
  "@types/node": "^22.9.0",
@@ -9295,7 +9300,7 @@ var package_default = {
9295
9300
  typescript: "^5.9.3",
9296
9301
  vitest: "^3.2.4"
9297
9302
  },
9298
- gitHead: "aaf443baeab1b87a7675e1577cc6535b2042bcdc"
9303
+ gitHead: "9fe45e4bfb34840cd5b5cb738bb276b0520e89c6"
9299
9304
  };
9300
9305
 
9301
9306
  // src/config/constants.ts
@@ -9675,6 +9680,7 @@ Remember: Use context from previous messages to understand follow-up questions.`
9675
9680
  Available commands:
9676
9681
  /help - Show this help message
9677
9682
  /exit - Exit the CLI
9683
+ /clear - Start a new session
9678
9684
  /login - Authenticate with your B4M account
9679
9685
  /logout - Clear authentication and sign out
9680
9686
  /whoami - Show current authenticated user
@@ -9849,6 +9855,35 @@ Tool Permissions:
9849
9855
  console.log(`Expires: ${new Date(authTokens.expiresAt).toLocaleString()}`);
9850
9856
  console.log("");
9851
9857
  break;
9858
+ case "clear":
9859
+ case "new": {
9860
+ console.clear();
9861
+ const model = state.session?.model || state.config?.defaultModel || "claude-sonnet";
9862
+ const newSession = {
9863
+ id: uuidv49(),
9864
+ name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
9865
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
9866
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9867
+ model,
9868
+ messages: [],
9869
+ metadata: {
9870
+ totalTokens: 0,
9871
+ totalCost: 0,
9872
+ toolCallCount: 0
9873
+ }
9874
+ };
9875
+ await logger.initialize(newSession.id);
9876
+ logger.debug("=== New Session Started via /clear ===");
9877
+ setState((prev) => ({ ...prev, session: newSession }));
9878
+ setStoreSession(newSession);
9879
+ useCliStore.getState().clearAgentSteps();
9880
+ usageCache = null;
9881
+ console.log("New session started.");
9882
+ console.log(`
9883
+ \u{1F4DD} Session: ${newSession.name} | \u{1F916} Model: ${newSession.model} | \u{1F4CA} Tokens: 0
9884
+ `);
9885
+ break;
9886
+ }
9852
9887
  case "usage": {
9853
9888
  const usageAuthTokens = await state.configStore.getAuthTokens();
9854
9889
  if (!usageAuthTokens || new Date(usageAuthTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
@@ -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-feat-cli-clear-command.17058+9fe45e4bf",
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-feat-cli-clear-command.17058+9fe45e4bf",
106
+ "@bike4mind/mcp": "1.19.5-feat-cli-clear-command.17058+9fe45e4bf",
107
+ "@bike4mind/services": "2.31.1-feat-cli-clear-command.17058+9fe45e4bf",
108
+ "@bike4mind/utils": "2.0.4-feat-cli-clear-command.17058+9fe45e4bf",
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": "9fe45e4bfb34840cd5b5cb738bb276b0520e89c6"
121
121
  }