Skip to content

Commit 2a7ffff

Browse files
committed
ship: iteration 1 - address review feedback
1 parent 5a05b0d commit 2a7ffff

3 files changed

Lines changed: 87 additions & 13 deletions

File tree

apps/ade-cli/src/adeRpcServer.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3062,6 +3062,45 @@ describe("adeRpcServer", () => {
30623062
expect(finishArgs.metadataPatch?.resultStatus).toBe("success");
30633063
});
30643064

3065+
it("does not mask successful action responses when audit finish fails", async () => {
3066+
const { runtime, operationFinish } = createRuntime();
3067+
operationFinish.mockImplementationOnce(() => {
3068+
throw new Error("finish failed");
3069+
});
3070+
const handler = createAdeRpcRequestHandler({ runtime, serverVersion: "test" });
3071+
3072+
await initialize(handler);
3073+
const response = await callTool(handler, "list_lanes", {});
3074+
3075+
expect(response.isError).toBeUndefined();
3076+
expect(response.structuredContent.lanes).toHaveLength(2);
3077+
expect(operationFinish).toHaveBeenCalledTimes(1);
3078+
expect(runtime.logger.warn).toHaveBeenCalledWith(
3079+
"ade_rpc.action_audit_finish_failed",
3080+
expect.objectContaining({ actionName: "list_lanes", status: "succeeded" }),
3081+
);
3082+
});
3083+
3084+
it("records failed audit metadata for returned action failure payloads", async () => {
3085+
const { runtime, operationFinish } = createRuntime();
3086+
runtime.gitService.push.mockResolvedValueOnce({ success: false, error: "push failed" });
3087+
const handler = createAdeRpcRequestHandler({ runtime, serverVersion: "test" });
3088+
3089+
await initialize(handler, { callerId: "agent-1", role: "agent" });
3090+
const response = await callTool(handler, "run_ade_action", {
3091+
domain: "git",
3092+
action: "push",
3093+
args: { laneId: "lane-1" },
3094+
});
3095+
3096+
expect(response.isError).toBeUndefined();
3097+
expect(response.structuredContent.result.success).toBe(false);
3098+
expect(operationFinish).toHaveBeenCalledWith(expect.objectContaining({
3099+
status: "failed",
3100+
metadataPatch: expect.objectContaining({ resultStatus: "error", error: "push failed" }),
3101+
}));
3102+
});
3103+
30653104
// ---------- Rate limit tests ----------
30663105

30673106
afterEach(() => {

apps/ade-cli/src/adeRpcServer.ts

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5245,6 +5245,41 @@ export function createAdeRpcRequestHandler(args: {
52455245
throw new JsonRpcError(JsonRpcErrorCode.methodNotFound, `Unsupported ADE action: ${actionName}`);
52465246
};
52475247

5248+
const failedActionPayloadMessage = (value: unknown): string | null => {
5249+
if (!isRecord(value)) return null;
5250+
const failed = value.ok === false || value.success === false;
5251+
if (!failed) return null;
5252+
const error = value.error;
5253+
if (typeof error === "string" && error.trim()) return error.trim();
5254+
if (isRecord(error) && typeof error.message === "string" && error.message.trim()) {
5255+
return error.message.trim();
5256+
}
5257+
return "Action returned a failed result.";
5258+
};
5259+
5260+
const actionResultFailureMessage = (value: unknown): string | null => {
5261+
if (!isRecord(value)) return null;
5262+
return failedActionPayloadMessage(value) ?? failedActionPayloadMessage(value.result);
5263+
};
5264+
5265+
const finishActionAudit = (
5266+
actionName: string,
5267+
operationId: string,
5268+
status: "succeeded" | "failed",
5269+
metadataPatch: Record<string, unknown>,
5270+
): void => {
5271+
try {
5272+
runtime.operationService.finish({ operationId, status, metadataPatch });
5273+
} catch (error) {
5274+
runtime.logger.warn("ade_rpc.action_audit_finish_failed", {
5275+
actionName,
5276+
operationId,
5277+
status,
5278+
error: error instanceof Error ? error.message : String(error),
5279+
});
5280+
}
5281+
};
5282+
52485283
const callActionWithAudit = async (
52495284
actionName: string,
52505285
actionArgs: Record<string, unknown>,
@@ -5261,21 +5296,21 @@ export function createAdeRpcRequestHandler(args: {
52615296
});
52625297
try {
52635298
const result = await callAction(actionName, actionArgs);
5264-
runtime.operationService.finish({
5265-
operationId: operation.operationId,
5266-
status: "succeeded",
5267-
metadataPatch: { resultStatus: "success" },
5268-
});
5299+
const failureMessage = actionResultFailureMessage(result);
5300+
if (failureMessage) {
5301+
finishActionAudit(actionName, operation.operationId, "failed", {
5302+
resultStatus: "error",
5303+
error: failureMessage,
5304+
});
5305+
return result;
5306+
}
5307+
finishActionAudit(actionName, operation.operationId, "succeeded", { resultStatus: "success" });
52695308
return result;
52705309
} catch (error) {
52715310
const message = error instanceof Error ? error.message : String(error);
5272-
runtime.operationService.finish({
5273-
operationId: operation.operationId,
5274-
status: "failed",
5275-
metadataPatch: {
5276-
resultStatus: "error",
5277-
error: message,
5278-
},
5311+
finishActionAudit(actionName, operation.operationId, "failed", {
5312+
resultStatus: "error",
5313+
error: message,
52795314
});
52805315
throw error;
52815316
}

apps/desktop/src/main/services/pty/ptyService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3055,7 +3055,7 @@ export function createPtyService({
30553055
if (chatSessionId) {
30563056
attachedEntry.chatSessionId = chatSessionId;
30573057
terminalChatSessions.set(existingSession.id, chatSessionId);
3058-
promoteActiveChatTerminal(chatSessionId, existingSession.id, existingSession.toolType);
3058+
promoteActiveChatTerminal(chatSessionId, existingSession.id, attachedEntry.toolTypeHint);
30593059
if (existingSession.chatSessionId !== chatSessionId) {
30603060
try { sessionService.setChatSessionId(existingSession.id, chatSessionId); } catch {}
30613061
}

0 commit comments

Comments
 (0)