@fatagnus/codebuff 1.0.4 → 1.0.6
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/convex.cjs +124 -37
- package/dist/convex.mjs +124 -37
- package/package.json +2 -5
package/dist/convex.cjs
CHANGED
|
@@ -5459,11 +5459,14 @@ __p += '`;
|
|
|
5459
5459
|
// src/convex.ts
|
|
5460
5460
|
var exports_convex = {};
|
|
5461
5461
|
__export(exports_convex, {
|
|
5462
|
+
validateSpawnPermission: () => validateSpawnPermission,
|
|
5462
5463
|
sanitizeErrorMessage: () => sanitizeErrorMessage,
|
|
5463
5464
|
run: () => run,
|
|
5464
5465
|
isRetryableStatusCode: () => isRetryableStatusCode,
|
|
5466
|
+
getMatchingSpawn: () => getMatchingSpawn,
|
|
5465
5467
|
getErrorStatusCode: () => getErrorStatusCode,
|
|
5466
5468
|
getCustomToolDefinition: () => getCustomToolDefinition,
|
|
5469
|
+
filterUnfinishedToolCalls: () => filterUnfinishedToolCalls,
|
|
5467
5470
|
createServerError: () => createServerError,
|
|
5468
5471
|
createPaymentRequiredError: () => createPaymentRequiredError,
|
|
5469
5472
|
createNetworkError: () => createNetworkError,
|
|
@@ -5473,19 +5476,23 @@ __export(exports_convex, {
|
|
|
5473
5476
|
convexInitialSessionState: () => convexInitialSessionState,
|
|
5474
5477
|
convexApplyOverridesToSessionState: () => convexApplyOverridesToSessionState,
|
|
5475
5478
|
buildUserMessageContent: () => buildUserMessageContent,
|
|
5479
|
+
buildToolsForApi: () => buildToolsForApi,
|
|
5480
|
+
buildSystemPrompt: () => buildSystemPrompt,
|
|
5476
5481
|
WEBSITE_URL: () => WEBSITE_URL,
|
|
5477
5482
|
RETRY_BACKOFF_MAX_DELAY_MS: () => RETRY_BACKOFF_MAX_DELAY_MS,
|
|
5478
5483
|
RETRY_BACKOFF_BASE_DELAY_MS: () => RETRY_BACKOFF_BASE_DELAY_MS,
|
|
5479
5484
|
RETRYABLE_STATUS_CODES: () => RETRYABLE_STATUS_CODES,
|
|
5480
5485
|
RECONNECTION_RETRY_DELAY_MS: () => RECONNECTION_RETRY_DELAY_MS,
|
|
5481
5486
|
RECONNECTION_MESSAGE_DURATION_MS: () => RECONNECTION_MESSAGE_DURATION_MS,
|
|
5487
|
+
MAX_SUBAGENT_DEPTH: () => MAX_SUBAGENT_DEPTH,
|
|
5482
5488
|
MAX_RETRIES_PER_MESSAGE: () => MAX_RETRIES_PER_MESSAGE,
|
|
5483
5489
|
IS_TEST: () => IS_TEST,
|
|
5484
5490
|
IS_PROD: () => IS_PROD,
|
|
5485
5491
|
IS_DEV: () => IS_DEV,
|
|
5486
5492
|
ConvexUnsupportedToolError: () => ConvexUnsupportedToolError,
|
|
5487
5493
|
ConvexCodebuffClient: () => ConvexCodebuffClient,
|
|
5488
|
-
CODEBUFF_BINARY: () => CODEBUFF_BINARY
|
|
5494
|
+
CODEBUFF_BINARY: () => CODEBUFF_BINARY,
|
|
5495
|
+
BASE_AGENT_IDS: () => BASE_AGENT_IDS
|
|
5489
5496
|
});
|
|
5490
5497
|
module.exports = __toCommonJS(exports_convex);
|
|
5491
5498
|
|
|
@@ -6104,6 +6111,35 @@ function userMessage(content) {
|
|
|
6104
6111
|
sentAt: Date.now()
|
|
6105
6112
|
};
|
|
6106
6113
|
}
|
|
6114
|
+
function withSystemTags(text) {
|
|
6115
|
+
return `<system>${text}</system>`;
|
|
6116
|
+
}
|
|
6117
|
+
function filterUnfinishedToolCalls(messages) {
|
|
6118
|
+
const completedToolCallIds = new Set;
|
|
6119
|
+
for (const msg of messages) {
|
|
6120
|
+
if (msg.role === "tool") {
|
|
6121
|
+
completedToolCallIds.add(msg.toolCallId);
|
|
6122
|
+
}
|
|
6123
|
+
}
|
|
6124
|
+
return messages.map((msg) => {
|
|
6125
|
+
if (msg.role !== "assistant") {
|
|
6126
|
+
return msg;
|
|
6127
|
+
}
|
|
6128
|
+
const filteredContent = msg.content.filter((part) => {
|
|
6129
|
+
if (part.type === "tool-call") {
|
|
6130
|
+
return completedToolCallIds.has(part.toolCallId);
|
|
6131
|
+
}
|
|
6132
|
+
return true;
|
|
6133
|
+
});
|
|
6134
|
+
if (filteredContent.length === 0) {
|
|
6135
|
+
return null;
|
|
6136
|
+
}
|
|
6137
|
+
return {
|
|
6138
|
+
...msg,
|
|
6139
|
+
content: filteredContent
|
|
6140
|
+
};
|
|
6141
|
+
}).filter((msg) => msg !== null);
|
|
6142
|
+
}
|
|
6107
6143
|
var createAbortError = (signal) => {
|
|
6108
6144
|
if (signal?.reason instanceof Error) {
|
|
6109
6145
|
return signal.reason;
|
|
@@ -6453,25 +6489,25 @@ async function handleToolCall(context) {
|
|
|
6453
6489
|
} = context;
|
|
6454
6490
|
const customToolHandler = customToolDefinitions[toolName];
|
|
6455
6491
|
if (customToolHandler) {
|
|
6456
|
-
return await customToolHandler.execute(input);
|
|
6492
|
+
return { output: await customToolHandler.execute(input), creditsUsed: 0 };
|
|
6457
6493
|
}
|
|
6458
6494
|
let override = overrides[toolName];
|
|
6459
6495
|
if (!override && toolName === "str_replace") {
|
|
6460
6496
|
override = overrides["write_file"];
|
|
6461
6497
|
}
|
|
6462
6498
|
if (override) {
|
|
6463
|
-
return await override(input);
|
|
6499
|
+
return { output: await override(input), creditsUsed: 0 };
|
|
6464
6500
|
}
|
|
6465
6501
|
switch (toolName) {
|
|
6466
6502
|
case "end_turn":
|
|
6467
|
-
return [{ type: "json", value: { message: "Turn ended." } }];
|
|
6503
|
+
return { output: [{ type: "json", value: { message: "Turn ended." } }], creditsUsed: 0 };
|
|
6468
6504
|
case "read_files": {
|
|
6469
6505
|
const files = await readFiles({
|
|
6470
6506
|
filePaths: input.paths || input.filePaths || [],
|
|
6471
6507
|
override: overrides.read_files,
|
|
6472
6508
|
projectFiles
|
|
6473
6509
|
});
|
|
6474
|
-
return [{ type: "json", value: files }];
|
|
6510
|
+
return { output: [{ type: "json", value: files }], creditsUsed: 0 };
|
|
6475
6511
|
}
|
|
6476
6512
|
case "spawn_agents": {
|
|
6477
6513
|
return await handleSpawnAgents(context);
|
|
@@ -6488,10 +6524,13 @@ async function handleToolCall(context) {
|
|
|
6488
6524
|
case "glob":
|
|
6489
6525
|
throw new ConvexUnsupportedToolError("glob", "File system access is not available in Convex");
|
|
6490
6526
|
case "run_file_change_hooks":
|
|
6491
|
-
return
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6527
|
+
return {
|
|
6528
|
+
output: [{
|
|
6529
|
+
type: "json",
|
|
6530
|
+
value: { message: "File change hooks are not supported in Convex mode" }
|
|
6531
|
+
}],
|
|
6532
|
+
creditsUsed: 0
|
|
6533
|
+
};
|
|
6495
6534
|
default:
|
|
6496
6535
|
throw new Error(`Tool not implemented in Convex SDK: ${toolName}. ` + `Please provide an override or modify your agent to not use this tool.`);
|
|
6497
6536
|
}
|
|
@@ -6519,12 +6558,15 @@ async function handleSpawnAgents(context) {
|
|
|
6519
6558
|
throw new Error('spawn_agents requires an "agents" array parameter');
|
|
6520
6559
|
}
|
|
6521
6560
|
if (currentDepth >= MAX_SUBAGENT_DEPTH) {
|
|
6522
|
-
return
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6561
|
+
return {
|
|
6562
|
+
output: [{
|
|
6563
|
+
type: "json",
|
|
6564
|
+
value: {
|
|
6565
|
+
errorMessage: `Maximum subagent depth (${MAX_SUBAGENT_DEPTH}) exceeded. Cannot spawn more subagents.`
|
|
6566
|
+
}
|
|
6567
|
+
}],
|
|
6568
|
+
creditsUsed: 0
|
|
6569
|
+
};
|
|
6528
6570
|
}
|
|
6529
6571
|
const parentSpawnableAgents = parentAgentDefinition?.spawnableAgents ?? [];
|
|
6530
6572
|
const results = await Promise.allSettled(agents.map(async ({ agent_type: agentTypeStr, prompt, params: spawnParams }) => {
|
|
@@ -6543,6 +6585,20 @@ async function handleSpawnAgents(context) {
|
|
|
6543
6585
|
prompt
|
|
6544
6586
|
});
|
|
6545
6587
|
}
|
|
6588
|
+
let inheritedMessageHistory;
|
|
6589
|
+
if (childAgentDef.includeMessageHistory) {
|
|
6590
|
+
inheritedMessageHistory = filterUnfinishedToolCalls(context.parentMessageHistory ?? []);
|
|
6591
|
+
inheritedMessageHistory.push({
|
|
6592
|
+
role: "user",
|
|
6593
|
+
content: [
|
|
6594
|
+
{
|
|
6595
|
+
type: "text",
|
|
6596
|
+
text: withSystemTags(`Subagent ${childAgentDef.id} has been spawned.`)
|
|
6597
|
+
}
|
|
6598
|
+
],
|
|
6599
|
+
tags: ["SUBAGENT_SPAWN"]
|
|
6600
|
+
});
|
|
6601
|
+
}
|
|
6546
6602
|
const result = await executeAgentLoop({
|
|
6547
6603
|
apiKey,
|
|
6548
6604
|
runId,
|
|
@@ -6556,6 +6612,7 @@ async function handleSpawnAgents(context) {
|
|
|
6556
6612
|
currentDepth: currentDepth + 1,
|
|
6557
6613
|
overrideTools: overrides,
|
|
6558
6614
|
customToolDefinitions,
|
|
6615
|
+
inheritedMessageHistory,
|
|
6559
6616
|
handleStreamChunk: handleStreamChunk ? async (chunk) => {
|
|
6560
6617
|
if (typeof chunk === "string") {
|
|
6561
6618
|
await handleStreamChunk({
|
|
@@ -6587,24 +6644,35 @@ async function handleSpawnAgents(context) {
|
|
|
6587
6644
|
creditsUsed: result.creditsUsed
|
|
6588
6645
|
};
|
|
6589
6646
|
}));
|
|
6647
|
+
let totalSubagentCredits = 0;
|
|
6648
|
+
for (const result of results) {
|
|
6649
|
+
if (result.status === "fulfilled") {
|
|
6650
|
+
totalSubagentCredits += result.value.creditsUsed;
|
|
6651
|
+
}
|
|
6652
|
+
}
|
|
6590
6653
|
const reports = results.map((result, index) => {
|
|
6591
6654
|
if (result.status === "fulfilled") {
|
|
6592
|
-
const { agentType, agentName, output } = result.value;
|
|
6655
|
+
const { agentType, agentName, output, creditsUsed } = result.value;
|
|
6593
6656
|
return {
|
|
6594
6657
|
agentName,
|
|
6595
6658
|
agentType,
|
|
6596
|
-
value: output
|
|
6659
|
+
value: output,
|
|
6660
|
+
creditsUsed
|
|
6597
6661
|
};
|
|
6598
6662
|
} else {
|
|
6599
6663
|
const agentTypeStr = agents[index].agent_type;
|
|
6600
6664
|
return {
|
|
6601
6665
|
agentType: agentTypeStr,
|
|
6602
6666
|
agentName: agentTypeStr,
|
|
6603
|
-
value: { errorMessage: `Error spawning agent: ${result.reason}` }
|
|
6667
|
+
value: { errorMessage: `Error spawning agent: ${result.reason}` },
|
|
6668
|
+
creditsUsed: 0
|
|
6604
6669
|
};
|
|
6605
6670
|
}
|
|
6606
6671
|
});
|
|
6607
|
-
return
|
|
6672
|
+
return {
|
|
6673
|
+
output: [{ type: "json", value: reports }],
|
|
6674
|
+
creditsUsed: totalSubagentCredits
|
|
6675
|
+
};
|
|
6608
6676
|
}
|
|
6609
6677
|
async function executeAgentLoop(options) {
|
|
6610
6678
|
const {
|
|
@@ -6623,17 +6691,19 @@ async function executeAgentLoop(options) {
|
|
|
6623
6691
|
handleStreamChunk,
|
|
6624
6692
|
handleEvent,
|
|
6625
6693
|
logger,
|
|
6626
|
-
signal
|
|
6694
|
+
signal,
|
|
6695
|
+
inheritedMessageHistory
|
|
6627
6696
|
} = options;
|
|
6628
6697
|
const systemPrompt = buildSystemPrompt(agentDefinition, projectFiles);
|
|
6629
6698
|
const tools = buildToolsForApi(agentDefinition, Object.values(customToolDefinitions));
|
|
6630
6699
|
const model = agentDefinition.model || "anthropic/claude-sonnet-4";
|
|
6631
|
-
const messages = [];
|
|
6700
|
+
const messages = inheritedMessageHistory ? [...inheritedMessageHistory] : [];
|
|
6632
6701
|
if (prompt || params) {
|
|
6633
6702
|
messages.push(userMessage(buildUserMessageContent(prompt, params, undefined)));
|
|
6634
6703
|
}
|
|
6635
6704
|
let totalSteps = 0;
|
|
6636
|
-
let
|
|
6705
|
+
let directCreditsUsed = 0;
|
|
6706
|
+
let subagentCreditsUsed = 0;
|
|
6637
6707
|
let fullResponse = "";
|
|
6638
6708
|
while (totalSteps < maxAgentSteps) {
|
|
6639
6709
|
if (signal?.aborted) {
|
|
@@ -6691,7 +6761,7 @@ async function executeAgentLoop(options) {
|
|
|
6691
6761
|
}
|
|
6692
6762
|
try {
|
|
6693
6763
|
const input = JSON.parse(tc.arguments || "{}");
|
|
6694
|
-
const
|
|
6764
|
+
const toolResult = await handleToolCall({
|
|
6695
6765
|
toolName: tc.name,
|
|
6696
6766
|
input,
|
|
6697
6767
|
overrides: overrideTools,
|
|
@@ -6707,13 +6777,15 @@ async function executeAgentLoop(options) {
|
|
|
6707
6777
|
handleStreamChunk,
|
|
6708
6778
|
handleEvent,
|
|
6709
6779
|
logger,
|
|
6710
|
-
signal
|
|
6780
|
+
signal,
|
|
6781
|
+
parentMessageHistory: messages
|
|
6711
6782
|
});
|
|
6783
|
+
subagentCreditsUsed += toolResult.creditsUsed;
|
|
6712
6784
|
messages.push({
|
|
6713
6785
|
role: "tool",
|
|
6714
6786
|
toolCallId: tc.id,
|
|
6715
6787
|
toolName: tc.name,
|
|
6716
|
-
content:
|
|
6788
|
+
content: toolResult.output
|
|
6717
6789
|
});
|
|
6718
6790
|
} catch (error) {
|
|
6719
6791
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -6729,10 +6801,13 @@ async function executeAgentLoop(options) {
|
|
|
6729
6801
|
break;
|
|
6730
6802
|
}
|
|
6731
6803
|
}
|
|
6804
|
+
const totalCreditsUsed = directCreditsUsed + subagentCreditsUsed;
|
|
6732
6805
|
return {
|
|
6733
6806
|
response: fullResponse,
|
|
6734
6807
|
output: fullResponse || "Agent completed.",
|
|
6735
|
-
creditsUsed,
|
|
6808
|
+
creditsUsed: totalCreditsUsed,
|
|
6809
|
+
directCreditsUsed,
|
|
6810
|
+
subagentCreditsUsed,
|
|
6736
6811
|
messages
|
|
6737
6812
|
};
|
|
6738
6813
|
}
|
|
@@ -6948,16 +7023,18 @@ async function run(options) {
|
|
|
6948
7023
|
messageHistoryLength: initialMessages.length
|
|
6949
7024
|
});
|
|
6950
7025
|
}
|
|
7026
|
+
const effectiveAgentDef = agentDefinition ?? {
|
|
7027
|
+
id: agentId,
|
|
7028
|
+
displayName: agentId,
|
|
7029
|
+
systemPrompt: "You are a helpful AI assistant.",
|
|
7030
|
+
toolNames: ["read_files", "end_turn"],
|
|
7031
|
+
model: "anthropic/claude-sonnet-4"
|
|
7032
|
+
};
|
|
6951
7033
|
const result = await executeAgentLoop({
|
|
6952
7034
|
apiKey,
|
|
6953
7035
|
runId,
|
|
6954
7036
|
agentId: mainAgentId,
|
|
6955
|
-
agentDefinition:
|
|
6956
|
-
id: agentId,
|
|
6957
|
-
displayName: agentId,
|
|
6958
|
-
systemPrompt: "You are a helpful AI assistant.",
|
|
6959
|
-
toolNames: ["read_files", "end_turn"]
|
|
6960
|
-
},
|
|
7037
|
+
agentDefinition: effectiveAgentDef,
|
|
6961
7038
|
agentDefinitions,
|
|
6962
7039
|
projectFiles,
|
|
6963
7040
|
maxAgentSteps,
|
|
@@ -6971,13 +7048,10 @@ async function run(options) {
|
|
|
6971
7048
|
logger,
|
|
6972
7049
|
signal
|
|
6973
7050
|
});
|
|
6974
|
-
const allMessages = [...initialMessages.slice(0, -1), ...result.messages];
|
|
6975
|
-
if (initialMessages.length > 0 && result.messages.length === 0) {
|
|
6976
|
-
allMessages.push(...initialMessages);
|
|
6977
|
-
}
|
|
6978
7051
|
sessionState.mainAgentState.messageHistory = result.messages.length > 0 ? result.messages : initialMessages;
|
|
6979
7052
|
sessionState.mainAgentState.creditsUsed = result.creditsUsed;
|
|
6980
|
-
|
|
7053
|
+
sessionState.mainAgentState.directCreditsUsed = result.directCreditsUsed;
|
|
7054
|
+
await finishAgentRun(apiKey, runId, "completed", Math.ceil(result.messages.length / 2), result.directCreditsUsed, result.creditsUsed, logger);
|
|
6981
7055
|
if (handleEvent) {
|
|
6982
7056
|
await handleEvent({
|
|
6983
7057
|
type: "finish",
|
|
@@ -7046,3 +7120,16 @@ Provide a handleEvent function to handle this error.`);
|
|
|
7046
7120
|
}
|
|
7047
7121
|
}
|
|
7048
7122
|
}
|
|
7123
|
+
|
|
7124
|
+
// src/convex.ts
|
|
7125
|
+
if (typeof Promise.withResolvers !== "function") {
|
|
7126
|
+
Promise.withResolvers = function() {
|
|
7127
|
+
let resolve;
|
|
7128
|
+
let reject;
|
|
7129
|
+
const promise = new Promise((res, rej) => {
|
|
7130
|
+
resolve = res;
|
|
7131
|
+
reject = rej;
|
|
7132
|
+
});
|
|
7133
|
+
return { promise, resolve, reject };
|
|
7134
|
+
};
|
|
7135
|
+
}
|
package/dist/convex.mjs
CHANGED
|
@@ -6047,6 +6047,35 @@ function userMessage(content) {
|
|
|
6047
6047
|
sentAt: Date.now()
|
|
6048
6048
|
};
|
|
6049
6049
|
}
|
|
6050
|
+
function withSystemTags(text) {
|
|
6051
|
+
return `<system>${text}</system>`;
|
|
6052
|
+
}
|
|
6053
|
+
function filterUnfinishedToolCalls(messages) {
|
|
6054
|
+
const completedToolCallIds = new Set;
|
|
6055
|
+
for (const msg of messages) {
|
|
6056
|
+
if (msg.role === "tool") {
|
|
6057
|
+
completedToolCallIds.add(msg.toolCallId);
|
|
6058
|
+
}
|
|
6059
|
+
}
|
|
6060
|
+
return messages.map((msg) => {
|
|
6061
|
+
if (msg.role !== "assistant") {
|
|
6062
|
+
return msg;
|
|
6063
|
+
}
|
|
6064
|
+
const filteredContent = msg.content.filter((part) => {
|
|
6065
|
+
if (part.type === "tool-call") {
|
|
6066
|
+
return completedToolCallIds.has(part.toolCallId);
|
|
6067
|
+
}
|
|
6068
|
+
return true;
|
|
6069
|
+
});
|
|
6070
|
+
if (filteredContent.length === 0) {
|
|
6071
|
+
return null;
|
|
6072
|
+
}
|
|
6073
|
+
return {
|
|
6074
|
+
...msg,
|
|
6075
|
+
content: filteredContent
|
|
6076
|
+
};
|
|
6077
|
+
}).filter((msg) => msg !== null);
|
|
6078
|
+
}
|
|
6050
6079
|
var createAbortError = (signal) => {
|
|
6051
6080
|
if (signal?.reason instanceof Error) {
|
|
6052
6081
|
return signal.reason;
|
|
@@ -6396,25 +6425,25 @@ async function handleToolCall(context) {
|
|
|
6396
6425
|
} = context;
|
|
6397
6426
|
const customToolHandler = customToolDefinitions[toolName];
|
|
6398
6427
|
if (customToolHandler) {
|
|
6399
|
-
return await customToolHandler.execute(input);
|
|
6428
|
+
return { output: await customToolHandler.execute(input), creditsUsed: 0 };
|
|
6400
6429
|
}
|
|
6401
6430
|
let override = overrides[toolName];
|
|
6402
6431
|
if (!override && toolName === "str_replace") {
|
|
6403
6432
|
override = overrides["write_file"];
|
|
6404
6433
|
}
|
|
6405
6434
|
if (override) {
|
|
6406
|
-
return await override(input);
|
|
6435
|
+
return { output: await override(input), creditsUsed: 0 };
|
|
6407
6436
|
}
|
|
6408
6437
|
switch (toolName) {
|
|
6409
6438
|
case "end_turn":
|
|
6410
|
-
return [{ type: "json", value: { message: "Turn ended." } }];
|
|
6439
|
+
return { output: [{ type: "json", value: { message: "Turn ended." } }], creditsUsed: 0 };
|
|
6411
6440
|
case "read_files": {
|
|
6412
6441
|
const files = await readFiles({
|
|
6413
6442
|
filePaths: input.paths || input.filePaths || [],
|
|
6414
6443
|
override: overrides.read_files,
|
|
6415
6444
|
projectFiles
|
|
6416
6445
|
});
|
|
6417
|
-
return [{ type: "json", value: files }];
|
|
6446
|
+
return { output: [{ type: "json", value: files }], creditsUsed: 0 };
|
|
6418
6447
|
}
|
|
6419
6448
|
case "spawn_agents": {
|
|
6420
6449
|
return await handleSpawnAgents(context);
|
|
@@ -6431,10 +6460,13 @@ async function handleToolCall(context) {
|
|
|
6431
6460
|
case "glob":
|
|
6432
6461
|
throw new ConvexUnsupportedToolError("glob", "File system access is not available in Convex");
|
|
6433
6462
|
case "run_file_change_hooks":
|
|
6434
|
-
return
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6463
|
+
return {
|
|
6464
|
+
output: [{
|
|
6465
|
+
type: "json",
|
|
6466
|
+
value: { message: "File change hooks are not supported in Convex mode" }
|
|
6467
|
+
}],
|
|
6468
|
+
creditsUsed: 0
|
|
6469
|
+
};
|
|
6438
6470
|
default:
|
|
6439
6471
|
throw new Error(`Tool not implemented in Convex SDK: ${toolName}. ` + `Please provide an override or modify your agent to not use this tool.`);
|
|
6440
6472
|
}
|
|
@@ -6462,12 +6494,15 @@ async function handleSpawnAgents(context) {
|
|
|
6462
6494
|
throw new Error('spawn_agents requires an "agents" array parameter');
|
|
6463
6495
|
}
|
|
6464
6496
|
if (currentDepth >= MAX_SUBAGENT_DEPTH) {
|
|
6465
|
-
return
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6497
|
+
return {
|
|
6498
|
+
output: [{
|
|
6499
|
+
type: "json",
|
|
6500
|
+
value: {
|
|
6501
|
+
errorMessage: `Maximum subagent depth (${MAX_SUBAGENT_DEPTH}) exceeded. Cannot spawn more subagents.`
|
|
6502
|
+
}
|
|
6503
|
+
}],
|
|
6504
|
+
creditsUsed: 0
|
|
6505
|
+
};
|
|
6471
6506
|
}
|
|
6472
6507
|
const parentSpawnableAgents = parentAgentDefinition?.spawnableAgents ?? [];
|
|
6473
6508
|
const results = await Promise.allSettled(agents.map(async ({ agent_type: agentTypeStr, prompt, params: spawnParams }) => {
|
|
@@ -6486,6 +6521,20 @@ async function handleSpawnAgents(context) {
|
|
|
6486
6521
|
prompt
|
|
6487
6522
|
});
|
|
6488
6523
|
}
|
|
6524
|
+
let inheritedMessageHistory;
|
|
6525
|
+
if (childAgentDef.includeMessageHistory) {
|
|
6526
|
+
inheritedMessageHistory = filterUnfinishedToolCalls(context.parentMessageHistory ?? []);
|
|
6527
|
+
inheritedMessageHistory.push({
|
|
6528
|
+
role: "user",
|
|
6529
|
+
content: [
|
|
6530
|
+
{
|
|
6531
|
+
type: "text",
|
|
6532
|
+
text: withSystemTags(`Subagent ${childAgentDef.id} has been spawned.`)
|
|
6533
|
+
}
|
|
6534
|
+
],
|
|
6535
|
+
tags: ["SUBAGENT_SPAWN"]
|
|
6536
|
+
});
|
|
6537
|
+
}
|
|
6489
6538
|
const result = await executeAgentLoop({
|
|
6490
6539
|
apiKey,
|
|
6491
6540
|
runId,
|
|
@@ -6499,6 +6548,7 @@ async function handleSpawnAgents(context) {
|
|
|
6499
6548
|
currentDepth: currentDepth + 1,
|
|
6500
6549
|
overrideTools: overrides,
|
|
6501
6550
|
customToolDefinitions,
|
|
6551
|
+
inheritedMessageHistory,
|
|
6502
6552
|
handleStreamChunk: handleStreamChunk ? async (chunk) => {
|
|
6503
6553
|
if (typeof chunk === "string") {
|
|
6504
6554
|
await handleStreamChunk({
|
|
@@ -6530,24 +6580,35 @@ async function handleSpawnAgents(context) {
|
|
|
6530
6580
|
creditsUsed: result.creditsUsed
|
|
6531
6581
|
};
|
|
6532
6582
|
}));
|
|
6583
|
+
let totalSubagentCredits = 0;
|
|
6584
|
+
for (const result of results) {
|
|
6585
|
+
if (result.status === "fulfilled") {
|
|
6586
|
+
totalSubagentCredits += result.value.creditsUsed;
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6533
6589
|
const reports = results.map((result, index) => {
|
|
6534
6590
|
if (result.status === "fulfilled") {
|
|
6535
|
-
const { agentType, agentName, output } = result.value;
|
|
6591
|
+
const { agentType, agentName, output, creditsUsed } = result.value;
|
|
6536
6592
|
return {
|
|
6537
6593
|
agentName,
|
|
6538
6594
|
agentType,
|
|
6539
|
-
value: output
|
|
6595
|
+
value: output,
|
|
6596
|
+
creditsUsed
|
|
6540
6597
|
};
|
|
6541
6598
|
} else {
|
|
6542
6599
|
const agentTypeStr = agents[index].agent_type;
|
|
6543
6600
|
return {
|
|
6544
6601
|
agentType: agentTypeStr,
|
|
6545
6602
|
agentName: agentTypeStr,
|
|
6546
|
-
value: { errorMessage: `Error spawning agent: ${result.reason}` }
|
|
6603
|
+
value: { errorMessage: `Error spawning agent: ${result.reason}` },
|
|
6604
|
+
creditsUsed: 0
|
|
6547
6605
|
};
|
|
6548
6606
|
}
|
|
6549
6607
|
});
|
|
6550
|
-
return
|
|
6608
|
+
return {
|
|
6609
|
+
output: [{ type: "json", value: reports }],
|
|
6610
|
+
creditsUsed: totalSubagentCredits
|
|
6611
|
+
};
|
|
6551
6612
|
}
|
|
6552
6613
|
async function executeAgentLoop(options) {
|
|
6553
6614
|
const {
|
|
@@ -6566,17 +6627,19 @@ async function executeAgentLoop(options) {
|
|
|
6566
6627
|
handleStreamChunk,
|
|
6567
6628
|
handleEvent,
|
|
6568
6629
|
logger,
|
|
6569
|
-
signal
|
|
6630
|
+
signal,
|
|
6631
|
+
inheritedMessageHistory
|
|
6570
6632
|
} = options;
|
|
6571
6633
|
const systemPrompt = buildSystemPrompt(agentDefinition, projectFiles);
|
|
6572
6634
|
const tools = buildToolsForApi(agentDefinition, Object.values(customToolDefinitions));
|
|
6573
6635
|
const model = agentDefinition.model || "anthropic/claude-sonnet-4";
|
|
6574
|
-
const messages = [];
|
|
6636
|
+
const messages = inheritedMessageHistory ? [...inheritedMessageHistory] : [];
|
|
6575
6637
|
if (prompt || params) {
|
|
6576
6638
|
messages.push(userMessage(buildUserMessageContent(prompt, params, undefined)));
|
|
6577
6639
|
}
|
|
6578
6640
|
let totalSteps = 0;
|
|
6579
|
-
let
|
|
6641
|
+
let directCreditsUsed = 0;
|
|
6642
|
+
let subagentCreditsUsed = 0;
|
|
6580
6643
|
let fullResponse = "";
|
|
6581
6644
|
while (totalSteps < maxAgentSteps) {
|
|
6582
6645
|
if (signal?.aborted) {
|
|
@@ -6634,7 +6697,7 @@ async function executeAgentLoop(options) {
|
|
|
6634
6697
|
}
|
|
6635
6698
|
try {
|
|
6636
6699
|
const input = JSON.parse(tc.arguments || "{}");
|
|
6637
|
-
const
|
|
6700
|
+
const toolResult = await handleToolCall({
|
|
6638
6701
|
toolName: tc.name,
|
|
6639
6702
|
input,
|
|
6640
6703
|
overrides: overrideTools,
|
|
@@ -6650,13 +6713,15 @@ async function executeAgentLoop(options) {
|
|
|
6650
6713
|
handleStreamChunk,
|
|
6651
6714
|
handleEvent,
|
|
6652
6715
|
logger,
|
|
6653
|
-
signal
|
|
6716
|
+
signal,
|
|
6717
|
+
parentMessageHistory: messages
|
|
6654
6718
|
});
|
|
6719
|
+
subagentCreditsUsed += toolResult.creditsUsed;
|
|
6655
6720
|
messages.push({
|
|
6656
6721
|
role: "tool",
|
|
6657
6722
|
toolCallId: tc.id,
|
|
6658
6723
|
toolName: tc.name,
|
|
6659
|
-
content:
|
|
6724
|
+
content: toolResult.output
|
|
6660
6725
|
});
|
|
6661
6726
|
} catch (error) {
|
|
6662
6727
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -6672,10 +6737,13 @@ async function executeAgentLoop(options) {
|
|
|
6672
6737
|
break;
|
|
6673
6738
|
}
|
|
6674
6739
|
}
|
|
6740
|
+
const totalCreditsUsed = directCreditsUsed + subagentCreditsUsed;
|
|
6675
6741
|
return {
|
|
6676
6742
|
response: fullResponse,
|
|
6677
6743
|
output: fullResponse || "Agent completed.",
|
|
6678
|
-
creditsUsed,
|
|
6744
|
+
creditsUsed: totalCreditsUsed,
|
|
6745
|
+
directCreditsUsed,
|
|
6746
|
+
subagentCreditsUsed,
|
|
6679
6747
|
messages
|
|
6680
6748
|
};
|
|
6681
6749
|
}
|
|
@@ -6891,16 +6959,18 @@ async function run(options) {
|
|
|
6891
6959
|
messageHistoryLength: initialMessages.length
|
|
6892
6960
|
});
|
|
6893
6961
|
}
|
|
6962
|
+
const effectiveAgentDef = agentDefinition ?? {
|
|
6963
|
+
id: agentId,
|
|
6964
|
+
displayName: agentId,
|
|
6965
|
+
systemPrompt: "You are a helpful AI assistant.",
|
|
6966
|
+
toolNames: ["read_files", "end_turn"],
|
|
6967
|
+
model: "anthropic/claude-sonnet-4"
|
|
6968
|
+
};
|
|
6894
6969
|
const result = await executeAgentLoop({
|
|
6895
6970
|
apiKey,
|
|
6896
6971
|
runId,
|
|
6897
6972
|
agentId: mainAgentId,
|
|
6898
|
-
agentDefinition:
|
|
6899
|
-
id: agentId,
|
|
6900
|
-
displayName: agentId,
|
|
6901
|
-
systemPrompt: "You are a helpful AI assistant.",
|
|
6902
|
-
toolNames: ["read_files", "end_turn"]
|
|
6903
|
-
},
|
|
6973
|
+
agentDefinition: effectiveAgentDef,
|
|
6904
6974
|
agentDefinitions,
|
|
6905
6975
|
projectFiles,
|
|
6906
6976
|
maxAgentSteps,
|
|
@@ -6914,13 +6984,10 @@ async function run(options) {
|
|
|
6914
6984
|
logger,
|
|
6915
6985
|
signal
|
|
6916
6986
|
});
|
|
6917
|
-
const allMessages = [...initialMessages.slice(0, -1), ...result.messages];
|
|
6918
|
-
if (initialMessages.length > 0 && result.messages.length === 0) {
|
|
6919
|
-
allMessages.push(...initialMessages);
|
|
6920
|
-
}
|
|
6921
6987
|
sessionState.mainAgentState.messageHistory = result.messages.length > 0 ? result.messages : initialMessages;
|
|
6922
6988
|
sessionState.mainAgentState.creditsUsed = result.creditsUsed;
|
|
6923
|
-
|
|
6989
|
+
sessionState.mainAgentState.directCreditsUsed = result.directCreditsUsed;
|
|
6990
|
+
await finishAgentRun(apiKey, runId, "completed", Math.ceil(result.messages.length / 2), result.directCreditsUsed, result.creditsUsed, logger);
|
|
6924
6991
|
if (handleEvent) {
|
|
6925
6992
|
await handleEvent({
|
|
6926
6993
|
type: "finish",
|
|
@@ -6989,12 +7056,28 @@ Provide a handleEvent function to handle this error.`);
|
|
|
6989
7056
|
}
|
|
6990
7057
|
}
|
|
6991
7058
|
}
|
|
7059
|
+
|
|
7060
|
+
// src/convex.ts
|
|
7061
|
+
if (typeof Promise.withResolvers !== "function") {
|
|
7062
|
+
Promise.withResolvers = function() {
|
|
7063
|
+
let resolve;
|
|
7064
|
+
let reject;
|
|
7065
|
+
const promise = new Promise((res, rej) => {
|
|
7066
|
+
resolve = res;
|
|
7067
|
+
reject = rej;
|
|
7068
|
+
});
|
|
7069
|
+
return { promise, resolve, reject };
|
|
7070
|
+
};
|
|
7071
|
+
}
|
|
6992
7072
|
export {
|
|
7073
|
+
validateSpawnPermission,
|
|
6993
7074
|
sanitizeErrorMessage,
|
|
6994
7075
|
run,
|
|
6995
7076
|
isRetryableStatusCode,
|
|
7077
|
+
getMatchingSpawn,
|
|
6996
7078
|
getErrorStatusCode,
|
|
6997
7079
|
getCustomToolDefinition,
|
|
7080
|
+
filterUnfinishedToolCalls,
|
|
6998
7081
|
createServerError,
|
|
6999
7082
|
createPaymentRequiredError,
|
|
7000
7083
|
createNetworkError,
|
|
@@ -7004,17 +7087,21 @@ export {
|
|
|
7004
7087
|
convexInitialSessionState,
|
|
7005
7088
|
convexApplyOverridesToSessionState,
|
|
7006
7089
|
buildUserMessageContent,
|
|
7090
|
+
buildToolsForApi,
|
|
7091
|
+
buildSystemPrompt,
|
|
7007
7092
|
WEBSITE_URL,
|
|
7008
7093
|
RETRY_BACKOFF_MAX_DELAY_MS,
|
|
7009
7094
|
RETRY_BACKOFF_BASE_DELAY_MS,
|
|
7010
7095
|
RETRYABLE_STATUS_CODES,
|
|
7011
7096
|
RECONNECTION_RETRY_DELAY_MS,
|
|
7012
7097
|
RECONNECTION_MESSAGE_DURATION_MS,
|
|
7098
|
+
MAX_SUBAGENT_DEPTH,
|
|
7013
7099
|
MAX_RETRIES_PER_MESSAGE,
|
|
7014
7100
|
IS_TEST,
|
|
7015
7101
|
IS_PROD,
|
|
7016
7102
|
IS_DEV,
|
|
7017
7103
|
ConvexUnsupportedToolError,
|
|
7018
7104
|
ConvexCodebuffClient,
|
|
7019
|
-
CODEBUFF_BINARY
|
|
7105
|
+
CODEBUFF_BINARY,
|
|
7106
|
+
BASE_AGENT_IDS
|
|
7020
7107
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fatagnus/codebuff",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.6",
|
|
5
5
|
"description": "Official SDK for Codebuff — AI coding agent & framework",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"type": "module",
|
|
@@ -72,10 +72,7 @@
|
|
|
72
72
|
"ws": "^8.18.0",
|
|
73
73
|
"zod": "^4.2.1"
|
|
74
74
|
},
|
|
75
|
-
|
|
76
|
-
"@vscode/tree-sitter-wasm": "0.1.4",
|
|
77
|
-
"web-tree-sitter": "0.25.6"
|
|
78
|
-
},
|
|
75
|
+
|
|
79
76
|
"devDependencies": {
|
|
80
77
|
"@types/bun": "^1.3.5",
|
|
81
78
|
"@types/diff": "8.0.0",
|