Skip to content

Commit 5c48b5d

Browse files
feat: report failure tool
1 parent 5b85f25 commit 5c48b5d

File tree

4 files changed

+92
-108
lines changed

4 files changed

+92
-108
lines changed

extensions/cli/src/tools/allBuiltIns.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { fetchTool } from "./fetch.js";
44
import { listFilesTool } from "./listFiles.js";
55
import { multiEditTool } from "./multiEdit.js";
66
import { readFileTool } from "./readFile.js";
7+
import { reportFailureTool } from "./reportFailure.js";
78
import { runTerminalCommandTool } from "./runTerminalCommand.js";
89
import { searchCodeTool } from "./searchCode.js";
9-
import { statusTool } from "./status.js";
1010
import { writeChecklistTool } from "./writeChecklist.js";
1111
import { writeFileTool } from "./writeFile.js";
1212

@@ -22,5 +22,5 @@ export const ALL_BUILT_IN_TOOLS = [
2222
fetchTool,
2323
writeChecklistTool,
2424
exitTool,
25-
statusTool,
25+
reportFailureTool,
2626
];

extensions/cli/src/tools/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import { fetchTool } from "./fetch.js";
2525
import { listFilesTool } from "./listFiles.js";
2626
import { multiEditTool } from "./multiEdit.js";
2727
import { readFileTool } from "./readFile.js";
28+
import { reportFailureTool } from "./reportFailure.js";
2829
import { runTerminalCommandTool } from "./runTerminalCommand.js";
2930
import { searchCodeTool } from "./searchCode.js";
30-
import { statusTool } from "./status.js";
3131
import {
3232
type Tool,
3333
type ToolCall,
@@ -49,6 +49,7 @@ const BASE_BUILTIN_TOOLS: Tool[] = [
4949
runTerminalCommandTool,
5050
fetchTool,
5151
writeChecklistTool,
52+
reportFailureTool,
5253
];
5354

5455
// Get all builtin tools including dynamic ones, with capability-based filtering
@@ -87,11 +88,6 @@ export async function getAllAvailableTools(
8788
tools.push(exitTool);
8889
}
8990

90-
// Add beta status tool if --beta-status-tool flag is present
91-
if (process.argv.includes("--beta-status-tool")) {
92-
tools.push(statusTool);
93-
}
94-
9591
const mcpState = await serviceContainer.get<MCPServiceState>(
9692
SERVICE_NAMES.MCP,
9793
);
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { ContinueError, ContinueErrorReason } from "core/util/errors.js";
2+
3+
import {
4+
ApiRequestError,
5+
AuthenticationRequiredError,
6+
post,
7+
} from "../util/apiClient.js";
8+
import { logger } from "../util/logger.js";
9+
10+
import { Tool } from "./types.js";
11+
12+
/**
13+
* Extract the agent ID from the --id command line flag
14+
*/
15+
function getAgentIdFromArgs(): string | undefined {
16+
const args = process.argv;
17+
const idIndex = args.indexOf("--id");
18+
if (idIndex !== -1 && idIndex + 1 < args.length) {
19+
return args[idIndex + 1];
20+
}
21+
return undefined;
22+
}
23+
24+
export const reportFailureTool: Tool = {
25+
name: "ReportFailure",
26+
displayName: "Report Failure",
27+
description:
28+
"Report that the task has failed due to an unrecoverable error. Include a succinct explanation for the user.",
29+
parameters: {
30+
type: "object",
31+
required: ["errorMessage"],
32+
properties: {
33+
errorMessage: {
34+
type: "string",
35+
description: "Explain what went wrong and why you cannot continue.",
36+
},
37+
},
38+
},
39+
readonly: true,
40+
isBuiltIn: true,
41+
run: async (args: { errorMessage: string }): Promise<string> => {
42+
try {
43+
const trimmedMessage = args.errorMessage.trim();
44+
if (!trimmedMessage) {
45+
throw new ContinueError(
46+
ContinueErrorReason.Unspecified,
47+
"errorMessage is required to report a failure.",
48+
);
49+
}
50+
51+
const agentId = getAgentIdFromArgs();
52+
if (!agentId) {
53+
const errorMessage =
54+
"Agent ID is required. Please use the --id flag with cn serve.";
55+
logger.error(errorMessage);
56+
throw new ContinueError(ContinueErrorReason.Unspecified, errorMessage);
57+
}
58+
59+
await post(`agents/${agentId}/status`, {
60+
status: "FAILED",
61+
errorMessage: trimmedMessage,
62+
});
63+
64+
logger.info(`Failure reported: ${trimmedMessage}`);
65+
return "Failure reported to user.";
66+
} catch (error) {
67+
if (error instanceof ContinueError) {
68+
throw error;
69+
}
70+
71+
if (error instanceof AuthenticationRequiredError) {
72+
logger.error(error.message);
73+
throw new Error("Error: Authentication required");
74+
}
75+
76+
if (error instanceof ApiRequestError) {
77+
throw new Error(
78+
`Error reporting failure: ${error.status} ${error.response || error.statusText}`,
79+
);
80+
}
81+
82+
const errorMessage =
83+
error instanceof Error ? error.message : String(error);
84+
logger.error(`Error reporting failure: ${errorMessage}`);
85+
throw new Error(`Error reporting failure: ${errorMessage}`);
86+
}
87+
},
88+
};

extensions/cli/src/tools/status.ts

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)