@ccpocket/bridge 1.88.1 → 1.88.3
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/codex-process.d.ts +12 -0
- package/dist/codex-process.js +137 -15
- package/dist/codex-process.js.map +1 -1
- package/dist/performance-mode.js +4 -2
- package/dist/performance-mode.js.map +1 -1
- package/dist/sdk-process.d.ts +6 -0
- package/dist/sdk-process.js +57 -29
- package/dist/sdk-process.js.map +1 -1
- package/dist/session.d.ts +3 -0
- package/dist/session.js +36 -8
- package/dist/session.js.map +1 -1
- package/dist/websocket.js +1 -0
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/codex-process.d.ts
CHANGED
|
@@ -121,6 +121,8 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
|
121
121
|
private pendingTurnCompletion;
|
|
122
122
|
private pendingApprovals;
|
|
123
123
|
private pendingUserInputs;
|
|
124
|
+
private pendingRequestOrder;
|
|
125
|
+
private nextPendingRequestOrder;
|
|
124
126
|
private lastTokenUsage;
|
|
125
127
|
/** Full skill metadata from the last `skills/list` response. */
|
|
126
128
|
private _skills;
|
|
@@ -320,9 +322,19 @@ export declare class CodexProcess extends EventEmitter<CodexProcessEvents> {
|
|
|
320
322
|
toolName: string;
|
|
321
323
|
input: Record<string, unknown>;
|
|
322
324
|
} | undefined;
|
|
325
|
+
getPendingPermissions(): Array<{
|
|
326
|
+
toolUseId: string;
|
|
327
|
+
toolName: string;
|
|
328
|
+
input: Record<string, unknown>;
|
|
329
|
+
}>;
|
|
323
330
|
/** Emit a synthetic tool_result so history replay can match it to a permission_request. */
|
|
324
331
|
private emitToolResult;
|
|
325
332
|
private resolvePendingApproval;
|
|
333
|
+
private rememberPendingRequest;
|
|
334
|
+
private forgetPendingRequest;
|
|
335
|
+
private oldestPendingRequestId;
|
|
336
|
+
private pendingRequestIdsInOrder;
|
|
337
|
+
private oldestApprovalCompatibleRequestId;
|
|
326
338
|
private resolvePendingUserInput;
|
|
327
339
|
/**
|
|
328
340
|
* Approve a pending user-input request (McpElicitation fallback).
|
package/dist/codex-process.js
CHANGED
|
@@ -77,6 +77,8 @@ export class CodexProcess extends EventEmitter {
|
|
|
77
77
|
pendingTurnCompletion = null;
|
|
78
78
|
pendingApprovals = new Map();
|
|
79
79
|
pendingUserInputs = new Map();
|
|
80
|
+
pendingRequestOrder = new Map();
|
|
81
|
+
nextPendingRequestOrder = 0;
|
|
80
82
|
lastTokenUsage = null;
|
|
81
83
|
/** Full skill metadata from the last `skills/list` response. */
|
|
82
84
|
_skills = [];
|
|
@@ -663,6 +665,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
663
665
|
}
|
|
664
666
|
this.pendingApprovals.clear();
|
|
665
667
|
this.pendingUserInputs.clear();
|
|
668
|
+
this.pendingRequestOrder.clear();
|
|
666
669
|
this.stdoutLineChunks = [];
|
|
667
670
|
this.stdoutLineChars = 0;
|
|
668
671
|
this.cleanupSteerTempPaths();
|
|
@@ -684,6 +687,8 @@ export class CodexProcess extends EventEmitter {
|
|
|
684
687
|
this.pendingTurnCompletion = null;
|
|
685
688
|
this.pendingApprovals.clear();
|
|
686
689
|
this.pendingUserInputs.clear();
|
|
690
|
+
this.pendingRequestOrder.clear();
|
|
691
|
+
this.nextPendingRequestOrder = 0;
|
|
687
692
|
this.cleanupSteerTempPaths();
|
|
688
693
|
this.lastTokenUsage = null;
|
|
689
694
|
this.startModel = sanitizeCodexModel(options?.model);
|
|
@@ -838,21 +843,25 @@ export class CodexProcess extends EventEmitter {
|
|
|
838
843
|
}
|
|
839
844
|
}
|
|
840
845
|
approve(toolUseId) {
|
|
846
|
+
const targetToolUseId = toolUseId ?? this.oldestApprovalCompatibleRequestId();
|
|
847
|
+
if (!targetToolUseId)
|
|
848
|
+
return false;
|
|
841
849
|
// Check if this is a plan completion approval
|
|
842
850
|
if (this.pendingPlanCompletion &&
|
|
843
|
-
|
|
851
|
+
targetToolUseId === this.pendingPlanCompletion.toolUseId) {
|
|
844
852
|
this.handlePlanApproved();
|
|
845
853
|
return true;
|
|
846
854
|
}
|
|
847
|
-
const pending = this.resolvePendingApproval(
|
|
855
|
+
const pending = this.resolvePendingApproval(targetToolUseId);
|
|
848
856
|
if (!pending) {
|
|
849
857
|
// Fallback: McpElicitation lives in pendingUserInputs
|
|
850
|
-
if (this.approveUserInput(
|
|
858
|
+
if (this.approveUserInput(targetToolUseId, "Accept"))
|
|
851
859
|
return true;
|
|
852
860
|
console.log("[codex-process] approve() called but no pending permission requests");
|
|
853
861
|
return false;
|
|
854
862
|
}
|
|
855
863
|
this.pendingApprovals.delete(pending.toolUseId);
|
|
864
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
856
865
|
this.respondToServerRequest(pending.requestId, buildApprovalResponse(pending, "accept"));
|
|
857
866
|
this.emitToolResult(pending.toolUseId, "Approved", "approved");
|
|
858
867
|
if (this.pendingApprovals.size === 0 &&
|
|
@@ -863,16 +872,25 @@ export class CodexProcess extends EventEmitter {
|
|
|
863
872
|
return true;
|
|
864
873
|
}
|
|
865
874
|
approveAlways(toolUseId) {
|
|
866
|
-
const
|
|
875
|
+
const targetToolUseId = toolUseId ?? this.oldestApprovalCompatibleRequestId();
|
|
876
|
+
if (!targetToolUseId)
|
|
877
|
+
return false;
|
|
878
|
+
if (this.pendingPlanCompletion &&
|
|
879
|
+
targetToolUseId === this.pendingPlanCompletion.toolUseId) {
|
|
880
|
+
this.handlePlanApproved();
|
|
881
|
+
return true;
|
|
882
|
+
}
|
|
883
|
+
const pending = this.resolvePendingApproval(targetToolUseId);
|
|
867
884
|
if (!pending) {
|
|
868
885
|
// Fallback: McpElicitation lives in pendingUserInputs
|
|
869
|
-
if (this.approveUserInput(
|
|
886
|
+
if (this.approveUserInput(targetToolUseId, "Allow for this session")) {
|
|
870
887
|
return true;
|
|
871
888
|
}
|
|
872
889
|
console.log("[codex-process] approveAlways() called but no pending permission requests");
|
|
873
890
|
return false;
|
|
874
891
|
}
|
|
875
892
|
this.pendingApprovals.delete(pending.toolUseId);
|
|
893
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
876
894
|
this.respondToServerRequest(pending.requestId, buildApprovalResponse(pending, "acceptForSession"));
|
|
877
895
|
this.emitToolResult(pending.toolUseId, "Approved (always)", "approved_for_session");
|
|
878
896
|
if (this.pendingApprovals.size === 0 &&
|
|
@@ -883,21 +901,25 @@ export class CodexProcess extends EventEmitter {
|
|
|
883
901
|
return true;
|
|
884
902
|
}
|
|
885
903
|
reject(toolUseId, _message) {
|
|
904
|
+
const targetToolUseId = toolUseId ?? this.oldestApprovalCompatibleRequestId();
|
|
905
|
+
if (!targetToolUseId)
|
|
906
|
+
return false;
|
|
886
907
|
// Check if this is a plan completion rejection
|
|
887
908
|
if (this.pendingPlanCompletion &&
|
|
888
|
-
|
|
909
|
+
targetToolUseId === this.pendingPlanCompletion.toolUseId) {
|
|
889
910
|
this.handlePlanRejected(_message);
|
|
890
911
|
return true;
|
|
891
912
|
}
|
|
892
|
-
const pending = this.resolvePendingApproval(
|
|
913
|
+
const pending = this.resolvePendingApproval(targetToolUseId);
|
|
893
914
|
if (!pending) {
|
|
894
915
|
// Fallback: McpElicitation lives in pendingUserInputs
|
|
895
|
-
if (this.rejectUserInput(
|
|
916
|
+
if (this.rejectUserInput(targetToolUseId, "Decline"))
|
|
896
917
|
return true;
|
|
897
918
|
console.log("[codex-process] reject() called but no pending permission requests");
|
|
898
919
|
return false;
|
|
899
920
|
}
|
|
900
921
|
this.pendingApprovals.delete(pending.toolUseId);
|
|
922
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
901
923
|
this.respondToServerRequest(pending.requestId, buildApprovalResponse(pending, resolveApprovalRejectDecision(pending)));
|
|
902
924
|
this.emitToolResult(pending.toolUseId, "Rejected", "rejected");
|
|
903
925
|
if (this.pendingApprovals.size === 0 &&
|
|
@@ -914,8 +936,9 @@ export class CodexProcess extends EventEmitter {
|
|
|
914
936
|
return false;
|
|
915
937
|
}
|
|
916
938
|
this.pendingUserInputs.delete(pending.toolUseId);
|
|
939
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
917
940
|
this.respondToServerRequest(pending.requestId, buildUserInputResponse(pending, result));
|
|
918
|
-
this.emitToolResult(pending.toolUseId,
|
|
941
|
+
this.emitToolResult(pending.toolUseId, questionAnswerResultForHistory(pending, result), "answered");
|
|
919
942
|
if (this.pendingApprovals.size === 0 &&
|
|
920
943
|
!this.hasBlockingUserInput() &&
|
|
921
944
|
!this.pendingPlanCompletion) {
|
|
@@ -1014,9 +1037,11 @@ export class CodexProcess extends EventEmitter {
|
|
|
1014
1037
|
}
|
|
1015
1038
|
}
|
|
1016
1039
|
getPendingPermission(toolUseId) {
|
|
1017
|
-
|
|
1040
|
+
const selectedToolUseId = toolUseId ?? this.oldestPendingRequestId();
|
|
1041
|
+
if (!selectedToolUseId)
|
|
1042
|
+
return undefined;
|
|
1018
1043
|
if (this.pendingPlanCompletion) {
|
|
1019
|
-
if (
|
|
1044
|
+
if (selectedToolUseId === this.pendingPlanCompletion.toolUseId) {
|
|
1020
1045
|
return {
|
|
1021
1046
|
toolUseId: this.pendingPlanCompletion.toolUseId,
|
|
1022
1047
|
toolName: "ExitPlanMode",
|
|
@@ -1024,7 +1049,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1024
1049
|
};
|
|
1025
1050
|
}
|
|
1026
1051
|
}
|
|
1027
|
-
const pending = this.
|
|
1052
|
+
const pending = this.pendingApprovals.get(selectedToolUseId);
|
|
1028
1053
|
if (pending) {
|
|
1029
1054
|
return {
|
|
1030
1055
|
toolUseId: pending.toolUseId,
|
|
@@ -1032,7 +1057,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1032
1057
|
input: { ...pending.input },
|
|
1033
1058
|
};
|
|
1034
1059
|
}
|
|
1035
|
-
const pendingAsk = this.
|
|
1060
|
+
const pendingAsk = this.pendingUserInputs.get(selectedToolUseId);
|
|
1036
1061
|
if (!pendingAsk)
|
|
1037
1062
|
return undefined;
|
|
1038
1063
|
return {
|
|
@@ -1041,6 +1066,11 @@ export class CodexProcess extends EventEmitter {
|
|
|
1041
1066
|
input: { ...pendingAsk.input },
|
|
1042
1067
|
};
|
|
1043
1068
|
}
|
|
1069
|
+
getPendingPermissions() {
|
|
1070
|
+
return this.pendingRequestIdsInOrder()
|
|
1071
|
+
.map((toolUseId) => this.getPendingPermission(toolUseId))
|
|
1072
|
+
.filter((request) => request !== undefined);
|
|
1073
|
+
}
|
|
1044
1074
|
/** Emit a synthetic tool_result so history replay can match it to a permission_request. */
|
|
1045
1075
|
emitToolResult(toolUseId, content, permissionOutcome) {
|
|
1046
1076
|
this.emitMessage({
|
|
@@ -1056,6 +1086,39 @@ export class CodexProcess extends EventEmitter {
|
|
|
1056
1086
|
const first = this.pendingApprovals.values().next();
|
|
1057
1087
|
return first.done ? undefined : first.value;
|
|
1058
1088
|
}
|
|
1089
|
+
rememberPendingRequest(toolUseId) {
|
|
1090
|
+
this.pendingRequestOrder.set(toolUseId, this.nextPendingRequestOrder++);
|
|
1091
|
+
}
|
|
1092
|
+
forgetPendingRequest(toolUseId) {
|
|
1093
|
+
this.pendingRequestOrder.delete(toolUseId);
|
|
1094
|
+
}
|
|
1095
|
+
oldestPendingRequestId() {
|
|
1096
|
+
return this.pendingRequestIdsInOrder()[0];
|
|
1097
|
+
}
|
|
1098
|
+
pendingRequestIdsInOrder() {
|
|
1099
|
+
const pendingIds = new Set([
|
|
1100
|
+
...this.pendingApprovals.keys(),
|
|
1101
|
+
...this.pendingUserInputs.keys(),
|
|
1102
|
+
...(this.pendingPlanCompletion
|
|
1103
|
+
? [this.pendingPlanCompletion.toolUseId]
|
|
1104
|
+
: []),
|
|
1105
|
+
]);
|
|
1106
|
+
return [...pendingIds].sort((a, b) => (this.pendingRequestOrder.get(a) ?? Number.MAX_SAFE_INTEGER) -
|
|
1107
|
+
(this.pendingRequestOrder.get(b) ?? Number.MAX_SAFE_INTEGER));
|
|
1108
|
+
}
|
|
1109
|
+
oldestApprovalCompatibleRequestId() {
|
|
1110
|
+
const pendingIds = new Set([
|
|
1111
|
+
...this.pendingApprovals.keys(),
|
|
1112
|
+
...[...this.pendingUserInputs.values()]
|
|
1113
|
+
.filter((request) => request.kind !== "questions")
|
|
1114
|
+
.map((request) => request.toolUseId),
|
|
1115
|
+
...(this.pendingPlanCompletion
|
|
1116
|
+
? [this.pendingPlanCompletion.toolUseId]
|
|
1117
|
+
: []),
|
|
1118
|
+
]);
|
|
1119
|
+
return [...pendingIds].sort((a, b) => (this.pendingRequestOrder.get(a) ?? Number.MAX_SAFE_INTEGER) -
|
|
1120
|
+
(this.pendingRequestOrder.get(b) ?? Number.MAX_SAFE_INTEGER))[0];
|
|
1121
|
+
}
|
|
1059
1122
|
resolvePendingUserInput(toolUseId) {
|
|
1060
1123
|
if (toolUseId)
|
|
1061
1124
|
return this.pendingUserInputs.get(toolUseId);
|
|
@@ -1070,7 +1133,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1070
1133
|
*/
|
|
1071
1134
|
approveUserInput(toolUseId, result) {
|
|
1072
1135
|
const pending = this.resolvePendingUserInput(toolUseId);
|
|
1073
|
-
if (!pending)
|
|
1136
|
+
if (!pending || pending.kind === "questions")
|
|
1074
1137
|
return false;
|
|
1075
1138
|
if (pending.kind === "tool_suggestion") {
|
|
1076
1139
|
if (pending.input.installState === "needs_auth") {
|
|
@@ -1082,6 +1145,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1082
1145
|
return true;
|
|
1083
1146
|
}
|
|
1084
1147
|
this.pendingUserInputs.delete(pending.toolUseId);
|
|
1148
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
1085
1149
|
this.respondToServerRequest(pending.requestId, buildUserInputResponse(pending, result));
|
|
1086
1150
|
this.emitToolResult(pending.toolUseId, "Approved", result === "Allow for this session"
|
|
1087
1151
|
? "approved_for_session"
|
|
@@ -1104,6 +1168,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1104
1168
|
}
|
|
1105
1169
|
resolveToolSuggestion(pending, toolResult) {
|
|
1106
1170
|
this.pendingUserInputs.delete(pending.toolUseId);
|
|
1171
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
1107
1172
|
this.respondToServerRequest(pending.requestId, {
|
|
1108
1173
|
action: "accept",
|
|
1109
1174
|
content: null,
|
|
@@ -1125,9 +1190,10 @@ export class CodexProcess extends EventEmitter {
|
|
|
1125
1190
|
*/
|
|
1126
1191
|
rejectUserInput(toolUseId, result) {
|
|
1127
1192
|
const pending = this.resolvePendingUserInput(toolUseId);
|
|
1128
|
-
if (!pending)
|
|
1193
|
+
if (!pending || pending.kind === "questions")
|
|
1129
1194
|
return false;
|
|
1130
1195
|
this.pendingUserInputs.delete(pending.toolUseId);
|
|
1196
|
+
this.forgetPendingRequest(pending.toolUseId);
|
|
1131
1197
|
this.respondToServerRequest(pending.requestId, buildUserInputResponse(pending, resolveUserInputRejectResult(pending, result)));
|
|
1132
1198
|
this.emitToolResult(pending.toolUseId, "Rejected", "rejected");
|
|
1133
1199
|
if (this.pendingApprovals.size === 0 &&
|
|
@@ -1147,6 +1213,8 @@ export class CodexProcess extends EventEmitter {
|
|
|
1147
1213
|
const planText = this.pendingPlanCompletion?.planText ?? "";
|
|
1148
1214
|
const resolvedToolUseId = this.pendingPlanCompletion?.toolUseId;
|
|
1149
1215
|
this.pendingPlanCompletion = null;
|
|
1216
|
+
if (resolvedToolUseId)
|
|
1217
|
+
this.forgetPendingRequest(resolvedToolUseId);
|
|
1150
1218
|
this._collaborationMode = "default";
|
|
1151
1219
|
console.log("[codex-process] Plan approved, switching to Default mode");
|
|
1152
1220
|
// Emit synthetic tool_result so history replay knows this approval is resolved
|
|
@@ -1172,6 +1240,8 @@ export class CodexProcess extends EventEmitter {
|
|
|
1172
1240
|
handlePlanRejected(feedback) {
|
|
1173
1241
|
const resolvedToolUseId = this.pendingPlanCompletion?.toolUseId;
|
|
1174
1242
|
this.pendingPlanCompletion = null;
|
|
1243
|
+
if (resolvedToolUseId)
|
|
1244
|
+
this.forgetPendingRequest(resolvedToolUseId);
|
|
1175
1245
|
console.log("[codex-process] Plan rejected, continuing in Plan mode");
|
|
1176
1246
|
// Stay in Plan mode
|
|
1177
1247
|
// Emit synthetic tool_result so history replay knows this approval is resolved
|
|
@@ -1882,6 +1952,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1882
1952
|
? { reason: params.reason }
|
|
1883
1953
|
: {}),
|
|
1884
1954
|
};
|
|
1955
|
+
this.rememberPendingRequest(toolUseId);
|
|
1885
1956
|
this.pendingApprovals.set(toolUseId, {
|
|
1886
1957
|
requestId: id,
|
|
1887
1958
|
toolUseId,
|
|
@@ -1909,6 +1980,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1909
1980
|
? { reason: params.reason }
|
|
1910
1981
|
: {}),
|
|
1911
1982
|
};
|
|
1983
|
+
this.rememberPendingRequest(toolUseId);
|
|
1912
1984
|
this.pendingApprovals.set(toolUseId, {
|
|
1913
1985
|
requestId: id,
|
|
1914
1986
|
toolUseId,
|
|
@@ -1940,6 +2012,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1940
2012
|
isSecret: q.isSecret,
|
|
1941
2013
|
})),
|
|
1942
2014
|
};
|
|
2015
|
+
this.rememberPendingRequest(toolUseId);
|
|
1943
2016
|
this.pendingUserInputs.set(toolUseId, {
|
|
1944
2017
|
requestId: id,
|
|
1945
2018
|
toolUseId,
|
|
@@ -1947,6 +2020,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1947
2020
|
questions: questions.map((q) => ({
|
|
1948
2021
|
id: q.id,
|
|
1949
2022
|
question: q.question,
|
|
2023
|
+
isSecret: q.isSecret,
|
|
1950
2024
|
})),
|
|
1951
2025
|
input,
|
|
1952
2026
|
kind: "questions",
|
|
@@ -1971,6 +2045,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1971
2045
|
? { reason: params.reason }
|
|
1972
2046
|
: {}),
|
|
1973
2047
|
};
|
|
2048
|
+
this.rememberPendingRequest(toolUseId);
|
|
1974
2049
|
this.pendingApprovals.set(toolUseId, {
|
|
1975
2050
|
requestId: id,
|
|
1976
2051
|
toolUseId,
|
|
@@ -1994,6 +2069,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
1994
2069
|
const toolName = elicitation.kind === "tool_suggestion"
|
|
1995
2070
|
? "ToolSuggestion"
|
|
1996
2071
|
: "McpElicitation";
|
|
2072
|
+
this.rememberPendingRequest(toolUseId);
|
|
1997
2073
|
this.pendingUserInputs.set(toolUseId, {
|
|
1998
2074
|
requestId: id,
|
|
1999
2075
|
toolUseId,
|
|
@@ -2306,6 +2382,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
2306
2382
|
// Plan mode: emit synthetic plan approval and wait for user decision
|
|
2307
2383
|
if (this._collaborationMode === "plan" && this.lastPlanItemText) {
|
|
2308
2384
|
const toolUseId = `plan_${randomUUID()}`;
|
|
2385
|
+
this.rememberPendingRequest(toolUseId);
|
|
2309
2386
|
this.pendingPlanCompletion = {
|
|
2310
2387
|
toolUseId,
|
|
2311
2388
|
planText: this.lastPlanItemText,
|
|
@@ -2932,6 +3009,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
2932
3009
|
const approval = [...this.pendingApprovals.values()].find((entry) => entry.requestId === requestId);
|
|
2933
3010
|
if (approval) {
|
|
2934
3011
|
this.pendingApprovals.delete(approval.toolUseId);
|
|
3012
|
+
this.forgetPendingRequest(approval.toolUseId);
|
|
2935
3013
|
this.emitMessage({
|
|
2936
3014
|
type: "permission_resolved",
|
|
2937
3015
|
toolUseId: approval.toolUseId,
|
|
@@ -2940,6 +3018,7 @@ export class CodexProcess extends EventEmitter {
|
|
|
2940
3018
|
const inputRequest = [...this.pendingUserInputs.values()].find((entry) => entry.requestId === requestId);
|
|
2941
3019
|
if (inputRequest) {
|
|
2942
3020
|
this.pendingUserInputs.delete(inputRequest.toolUseId);
|
|
3021
|
+
this.forgetPendingRequest(inputRequest.toolUseId);
|
|
2943
3022
|
this.emitMessage({
|
|
2944
3023
|
type: "permission_resolved",
|
|
2945
3024
|
toolUseId: inputRequest.toolUseId,
|
|
@@ -2981,6 +3060,49 @@ function buildUserInputResponse(pending, rawResult) {
|
|
|
2981
3060
|
}
|
|
2982
3061
|
return buildElicitationResponse(pending, rawResult);
|
|
2983
3062
|
}
|
|
3063
|
+
/** Keep secret question values out of the replayable transcript. */
|
|
3064
|
+
function questionAnswerResultForHistory(pending, rawResult) {
|
|
3065
|
+
if (pending.kind !== "questions" ||
|
|
3066
|
+
!pending.questions.some((question) => question.isSecret)) {
|
|
3067
|
+
return rawResult;
|
|
3068
|
+
}
|
|
3069
|
+
const parsed = parseResultObject(rawResult);
|
|
3070
|
+
const structuredResult = isJsonObjectOrArray(rawResult);
|
|
3071
|
+
const answers = {};
|
|
3072
|
+
for (const [index, question] of pending.questions.entries()) {
|
|
3073
|
+
const candidate = parsed.byId[question.id] ?? parsed.byQuestion[question.question];
|
|
3074
|
+
const fallback = index === 0 && candidate === undefined && !structuredResult
|
|
3075
|
+
? plainAnswerValue(rawResult)
|
|
3076
|
+
: null;
|
|
3077
|
+
const values = normalizeAnswerValues(candidate ?? fallback);
|
|
3078
|
+
if (question.isSecret) {
|
|
3079
|
+
if (values.length > 0)
|
|
3080
|
+
answers[question.id] = { redacted: true };
|
|
3081
|
+
}
|
|
3082
|
+
else if (values.length > 0) {
|
|
3083
|
+
answers[question.id] = values;
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
return JSON.stringify({ answers });
|
|
3087
|
+
}
|
|
3088
|
+
function isJsonObjectOrArray(value) {
|
|
3089
|
+
try {
|
|
3090
|
+
const parsed = JSON.parse(value);
|
|
3091
|
+
return parsed !== null && typeof parsed === "object";
|
|
3092
|
+
}
|
|
3093
|
+
catch {
|
|
3094
|
+
return false;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
function plainAnswerValue(value) {
|
|
3098
|
+
try {
|
|
3099
|
+
const parsed = JSON.parse(value);
|
|
3100
|
+
return typeof parsed === "string" ? parsed : null;
|
|
3101
|
+
}
|
|
3102
|
+
catch {
|
|
3103
|
+
return value;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
2984
3106
|
function resolveUserInputRejectResult(pending, fallback) {
|
|
2985
3107
|
if (pending.kind !== "elicitation_approval")
|
|
2986
3108
|
return fallback;
|