@bike4mind/cli 0.2.2 → 0.2.3-feat-questmaster-gpt5-function-calling.17056
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifactExtractor-GXQ5YZF7.js +0 -0
- package/dist/{chunk-5N4PG5EH.js → chunk-55HUCQWS.js} +1 -1
- package/dist/chunk-AMDXHL6S.js +0 -0
- package/dist/chunk-BDQBOLYG.js +0 -0
- package/dist/chunk-BPFEGDC7.js +0 -0
- package/dist/{chunk-NZADYDFG.js → chunk-BSDDDQF4.js} +400 -110
- package/dist/{chunk-Y4HMTEDH.js → chunk-CS24JD7W.js} +1 -1
- package/dist/chunk-PDX44BCA.js +0 -0
- package/dist/{chunk-GZTILMGE.js → chunk-QGLZY6IF.js} +1 -1
- package/dist/chunk-WR6YZRQV.js +0 -0
- package/dist/{create-ZTK4723N.js → create-XI66RQVC.js} +2 -2
- package/dist/formatConverter-I7EIUVDY.js +0 -0
- package/dist/index.js +12 -11
- package/dist/llmMarkdownGenerator-4ZR3FLEQ.js +0 -0
- package/dist/markdownGenerator-7WE7WKME.js +0 -0
- package/dist/{mementoService-5XQYECNM.js → mementoService-DCTBFBVO.js} +2 -2
- package/dist/notificationDeduplicator-UW7D75QS.js +0 -0
- package/dist/src-6J6LFPZ6.js +0 -0
- package/dist/{src-DOO3QAO2.js → src-Y26NRIGO.js} +7 -1
- package/dist/{subtractCredits-3QOJA6XF.js → subtractCredits-MPEEX4N7.js} +2 -2
- package/dist/utils-JPMDGUBL.js +0 -0
- package/package.json +18 -16
|
File without changes
|
package/dist/chunk-AMDXHL6S.js
CHANGED
|
File without changes
|
package/dist/chunk-BDQBOLYG.js
CHANGED
|
File without changes
|
package/dist/chunk-BPFEGDC7.js
CHANGED
|
File without changes
|
|
@@ -4112,6 +4112,12 @@ 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
|
+
}
|
|
4115
4121
|
}
|
|
4116
4122
|
const response = await this._api.chat.completions.create(parameters, {
|
|
4117
4123
|
signal: options.abortSignal
|
|
@@ -7978,6 +7984,165 @@ function extractQuestMasterData(reply, options = {}) {
|
|
|
7978
7984
|
return questMasterData;
|
|
7979
7985
|
}
|
|
7980
7986
|
|
|
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
|
+
|
|
7981
8146
|
// ../../b4m-core/packages/utils/dist/src/questMaster.js
|
|
7982
8147
|
var sanitizeId = (id) => {
|
|
7983
8148
|
return id.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9_.-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -8008,10 +8173,9 @@ var QuestMaster = class {
|
|
|
8008
8173
|
}
|
|
8009
8174
|
return "Easy";
|
|
8010
8175
|
}
|
|
8011
|
-
async processQuestPlan(
|
|
8176
|
+
async processQuestPlan(input) {
|
|
8012
8177
|
try {
|
|
8013
8178
|
await this.onStatusUpdate(this.quest, "Processing quest plan...");
|
|
8014
|
-
this.logger.log("Processing quest plan:", questPlanText);
|
|
8015
8179
|
const defaultResponse = {
|
|
8016
8180
|
type: "narrative",
|
|
8017
8181
|
meta: {
|
|
@@ -8028,135 +8192,161 @@ var QuestMaster = class {
|
|
|
8028
8192
|
}
|
|
8029
8193
|
]
|
|
8030
8194
|
};
|
|
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
|
-
}
|
|
8046
8195
|
if (!this.quest) {
|
|
8047
8196
|
throw new Error("No quest context available");
|
|
8048
8197
|
}
|
|
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 = [];
|
|
8055
8198
|
let questResponse;
|
|
8056
|
-
if (
|
|
8057
|
-
|
|
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
|
-
}
|
|
8199
|
+
if (input !== null && typeof input === "object") {
|
|
8200
|
+
this.logger.log("Processing quest plan from function calling result");
|
|
8080
8201
|
questResponse = {
|
|
8081
8202
|
type: "quest_plan",
|
|
8082
8203
|
meta: {
|
|
8083
|
-
goal,
|
|
8084
|
-
totalSteps:
|
|
8085
|
-
tags
|
|
8204
|
+
goal: input.goal,
|
|
8205
|
+
totalSteps: input.quests.length,
|
|
8206
|
+
tags: input.tags
|
|
8086
8207
|
},
|
|
8087
|
-
quests:
|
|
8208
|
+
quests: input.quests.map((quest) => ({
|
|
8088
8209
|
id: quest.id,
|
|
8089
|
-
// No fallback - we filtered for valid IDs
|
|
8090
8210
|
title: quest.title,
|
|
8091
|
-
// No fallback - we filtered for valid titles
|
|
8092
8211
|
description: quest.description,
|
|
8093
|
-
|
|
8094
|
-
complexity: quest.complexity || "Medium",
|
|
8212
|
+
complexity: quest.complexity,
|
|
8095
8213
|
status: "not_started",
|
|
8096
|
-
subQuests:
|
|
8214
|
+
subQuests: quest.subQuests.map((sub) => ({
|
|
8097
8215
|
id: sub.id,
|
|
8098
8216
|
title: sub.title,
|
|
8099
8217
|
status: "not_started"
|
|
8100
|
-
}))
|
|
8218
|
+
}))
|
|
8101
8219
|
}))
|
|
8102
8220
|
};
|
|
8103
|
-
if (questResponse.quests.some((quest) => quest.subQuests.length === 0)) {
|
|
8104
|
-
throw new Error("Some quests have no valid subquests after filtering");
|
|
8105
|
-
}
|
|
8106
8221
|
} else {
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
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;
|
|
8238
|
+
}
|
|
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);
|
|
8113
8258
|
}
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
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
|
+
};
|
|
8133
8345
|
}
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
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
|
-
};
|
|
8346
|
+
} catch (parseError) {
|
|
8347
|
+
this.logger.error("Error parsing quest plan JSON:", parseError);
|
|
8348
|
+
questResponse = defaultResponse;
|
|
8156
8349
|
}
|
|
8157
|
-
} catch (parseError) {
|
|
8158
|
-
this.logger.error("Error parsing quest plan JSON:", parseError);
|
|
8159
|
-
questResponse = defaultResponse;
|
|
8160
8350
|
}
|
|
8161
8351
|
}
|
|
8162
8352
|
if (!this.validateQuestResponse(questResponse)) {
|
|
@@ -8356,9 +8546,106 @@ var QuestMaster = class {
|
|
|
8356
8546
|
}
|
|
8357
8547
|
-->`;
|
|
8358
8548
|
}
|
|
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
|
+
}
|
|
8359
8636
|
async createQuestPlan(model, prompt) {
|
|
8360
8637
|
try {
|
|
8361
8638
|
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
|
+
}
|
|
8362
8649
|
const messages = [
|
|
8363
8650
|
{
|
|
8364
8651
|
role: "system",
|
|
@@ -10452,6 +10739,9 @@ export {
|
|
|
10452
10739
|
sendToConnection,
|
|
10453
10740
|
ClientMessageSender,
|
|
10454
10741
|
OpenaiModerationsService,
|
|
10742
|
+
isGPT5ModelWithToolSupport,
|
|
10743
|
+
createQuestPlanToolSchema,
|
|
10744
|
+
parseQuestPlanFunctionCall,
|
|
10455
10745
|
QuestMaster,
|
|
10456
10746
|
OpenAIImageService,
|
|
10457
10747
|
TestImageService,
|
package/dist/chunk-PDX44BCA.js
CHANGED
|
File without changes
|
package/dist/chunk-WR6YZRQV.js
CHANGED
|
File without changes
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-55HUCQWS.js";
|
|
6
|
+
import "./chunk-BSDDDQF4.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
8
|
import "./chunk-WR6YZRQV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getEffectiveApiKey,
|
|
5
5
|
getOpenWeatherKey,
|
|
6
6
|
getSerperKey
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-QGLZY6IF.js";
|
|
8
|
+
import "./chunk-CS24JD7W.js";
|
|
9
|
+
import "./chunk-55HUCQWS.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-
|
|
18
|
+
} from "./chunk-BSDDDQF4.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.
|
|
9181
|
+
version: "0.2.3-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
|
|
9182
9182
|
type: "module",
|
|
9183
9183
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9184
9184
|
license: "UNLICENSED",
|
|
@@ -9279,11 +9279,11 @@ var package_default = {
|
|
|
9279
9279
|
zustand: "^4.5.4"
|
|
9280
9280
|
},
|
|
9281
9281
|
devDependencies: {
|
|
9282
|
-
"@bike4mind/agents": "
|
|
9283
|
-
"@bike4mind/common": "
|
|
9284
|
-
"@bike4mind/mcp": "
|
|
9285
|
-
"@bike4mind/services": "
|
|
9286
|
-
"@bike4mind/utils": "
|
|
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",
|
|
9287
9287
|
"@types/diff": "^5.0.9",
|
|
9288
9288
|
"@types/jsonwebtoken": "^9.0.4",
|
|
9289
9289
|
"@types/node": "^22.9.0",
|
|
@@ -9294,7 +9294,8 @@ var package_default = {
|
|
|
9294
9294
|
tsx: "^4.21.0",
|
|
9295
9295
|
typescript: "^5.9.3",
|
|
9296
9296
|
vitest: "^3.2.4"
|
|
9297
|
-
}
|
|
9297
|
+
},
|
|
9298
|
+
gitHead: "aaf443baeab1b87a7675e1577cc6535b2042bcdc"
|
|
9298
9299
|
};
|
|
9299
9300
|
|
|
9300
9301
|
// src/config/constants.ts
|
|
File without changes
|
|
File without changes
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-QGLZY6IF.js";
|
|
6
|
+
import "./chunk-BSDDDQF4.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
8
|
import "./chunk-WR6YZRQV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
File without changes
|
package/dist/src-6J6LFPZ6.js
CHANGED
|
File without changes
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
cleanMermaidSyntax,
|
|
66
66
|
computeCosineSimilarity,
|
|
67
67
|
convertCodeBlocksToArtifacts,
|
|
68
|
+
createQuestPlanToolSchema,
|
|
68
69
|
createTokenizer,
|
|
69
70
|
decodeBase64DataUrl,
|
|
70
71
|
detectURLs,
|
|
@@ -97,6 +98,7 @@ import {
|
|
|
97
98
|
includeImagePromptSystemMessage,
|
|
98
99
|
initializeConfig,
|
|
99
100
|
invalidateSettingsCache,
|
|
101
|
+
isGPT5ModelWithToolSupport,
|
|
100
102
|
isMermaidSyntax,
|
|
101
103
|
isModelAccessible,
|
|
102
104
|
isPlainText,
|
|
@@ -105,6 +107,7 @@ import {
|
|
|
105
107
|
isZodError,
|
|
106
108
|
obfuscateApiKey,
|
|
107
109
|
parseArtifacts,
|
|
110
|
+
parseQuestPlanFunctionCall,
|
|
108
111
|
processFabFilesServer,
|
|
109
112
|
processUrlsFromPrompt,
|
|
110
113
|
secureParameters,
|
|
@@ -117,7 +120,7 @@ import {
|
|
|
117
120
|
validateMermaidSyntax,
|
|
118
121
|
warmUpSettingsCache,
|
|
119
122
|
withRetry
|
|
120
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-BSDDDQF4.js";
|
|
121
124
|
import {
|
|
122
125
|
Logger,
|
|
123
126
|
NotificationDeduplicator,
|
|
@@ -196,6 +199,7 @@ export {
|
|
|
196
199
|
cleanMermaidSyntax,
|
|
197
200
|
computeCosineSimilarity,
|
|
198
201
|
convertCodeBlocksToArtifacts,
|
|
202
|
+
createQuestPlanToolSchema,
|
|
199
203
|
createTokenizer,
|
|
200
204
|
decodeBase64DataUrl,
|
|
201
205
|
detectURLs,
|
|
@@ -228,6 +232,7 @@ export {
|
|
|
228
232
|
includeImagePromptSystemMessage,
|
|
229
233
|
initializeConfig,
|
|
230
234
|
invalidateSettingsCache,
|
|
235
|
+
isGPT5ModelWithToolSupport,
|
|
231
236
|
isMermaidSyntax,
|
|
232
237
|
isModelAccessible,
|
|
233
238
|
isPlainText,
|
|
@@ -238,6 +243,7 @@ export {
|
|
|
238
243
|
notifyEventLogsToSlack,
|
|
239
244
|
obfuscateApiKey,
|
|
240
245
|
parseArtifacts,
|
|
246
|
+
parseQuestPlanFunctionCall,
|
|
241
247
|
postLowCreditsNotificationToSlack,
|
|
242
248
|
postMessageToSlack,
|
|
243
249
|
processFabFilesServer,
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-CS24JD7W.js";
|
|
6
|
+
import "./chunk-BSDDDQF4.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
8
|
import "./chunk-WR6YZRQV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
package/dist/utils-JPMDGUBL.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3-feat-questmaster-gpt5-function-calling.17056+aaf443bae",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -30,6 +30,15 @@
|
|
|
30
30
|
"dist",
|
|
31
31
|
"bin"
|
|
32
32
|
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "tsx src/index.tsx",
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"start": "node dist/index.js",
|
|
40
|
+
"prepublishOnly": "pnpm build"
|
|
41
|
+
},
|
|
33
42
|
"dependencies": {
|
|
34
43
|
"@anthropic-ai/sdk": "^0.22.0",
|
|
35
44
|
"@aws-sdk/client-apigatewaymanagementapi": "3.654.0",
|
|
@@ -92,6 +101,11 @@
|
|
|
92
101
|
"zustand": "^4.5.4"
|
|
93
102
|
},
|
|
94
103
|
"devDependencies": {
|
|
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",
|
|
95
109
|
"@types/diff": "^5.0.9",
|
|
96
110
|
"@types/jsonwebtoken": "^9.0.4",
|
|
97
111
|
"@types/node": "^22.9.0",
|
|
@@ -101,19 +115,7 @@
|
|
|
101
115
|
"tsup": "^8.5.1",
|
|
102
116
|
"tsx": "^4.21.0",
|
|
103
117
|
"typescript": "^5.9.3",
|
|
104
|
-
"vitest": "^3.2.4"
|
|
105
|
-
"@bike4mind/common": "2.37.0",
|
|
106
|
-
"@bike4mind/agents": "0.1.0",
|
|
107
|
-
"@bike4mind/mcp": "1.19.4",
|
|
108
|
-
"@bike4mind/services": "2.31.0",
|
|
109
|
-
"@bike4mind/utils": "2.0.3"
|
|
118
|
+
"vitest": "^3.2.4"
|
|
110
119
|
},
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
"build": "tsup",
|
|
114
|
-
"typecheck": "tsc --noEmit",
|
|
115
|
-
"test": "vitest run",
|
|
116
|
-
"test:watch": "vitest",
|
|
117
|
-
"start": "node dist/index.js"
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
+
"gitHead": "aaf443baeab1b87a7675e1577cc6535b2042bcdc"
|
|
121
|
+
}
|