@blackbox_ai/blackbox-cli 0.9.2 → 1.0.2
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/assets/notification.mp3 +0 -0
- package/dist/package.json +2 -2
- package/dist/src/commands/voice.js +39 -34
- package/dist/src/commands/voice.js.map +1 -1
- package/dist/src/config/config.js +1 -4
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/settings.d.ts +2 -0
- package/dist/src/config/settings.js +22 -1
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +36 -7
- package/dist/src/config/settingsSchema.js +35 -8
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/gemini.js +25 -20
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/services/BuiltinCommandLoader.js +2 -2
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/agentExecutor.d.ts +5 -0
- package/dist/src/services/agentExecutor.js +6 -2
- package/dist/src/services/agentExecutor.js.map +1 -1
- package/dist/src/services/voiceRecordingService.d.ts +13 -1
- package/dist/src/services/voiceRecordingService.js +38 -5
- package/dist/src/services/voiceRecordingService.js.map +1 -1
- package/dist/src/ui/App.js +255 -20
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/agentCommand.js +134 -43
- package/dist/src/ui/commands/agentCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +15 -2
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.js +5 -0
- package/dist/src/ui/commands/quitCommand.js.map +1 -1
- package/dist/src/ui/commands/subAgentsCommand.d.ts +7 -0
- package/dist/src/ui/commands/subAgentsCommand.js +32 -0
- package/dist/src/ui/commands/subAgentsCommand.js.map +1 -0
- package/dist/src/ui/commands/types.d.ts +14 -3
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/voiceCommand.js +70 -34
- package/dist/src/ui/commands/voiceCommand.js.map +1 -1
- package/dist/src/ui/commands/voiceCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/voiceCommand.test.js +131 -0
- package/dist/src/ui/commands/voiceCommand.test.js.map +1 -0
- package/dist/src/ui/components/AgentModelSelector.js +1 -1
- package/dist/src/ui/components/AgentModelSelector.js.map +1 -1
- package/dist/src/ui/components/AgentSetDialog.d.ts +15 -0
- package/dist/src/ui/components/AgentSetDialog.js +52 -0
- package/dist/src/ui/components/AgentSetDialog.js.map +1 -0
- package/dist/src/ui/components/ApiKeyInputDialog.d.ts +17 -0
- package/dist/src/ui/components/ApiKeyInputDialog.js +44 -0
- package/dist/src/ui/components/ApiKeyInputDialog.js.map +1 -0
- package/dist/src/ui/components/AuthDialog.js +32 -46
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +6 -0
- package/dist/src/ui/components/Footer.js +17 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/GenericProviderKeyPrompt.js +1 -1
- package/dist/src/ui/components/GenericProviderKeyPrompt.js.map +1 -1
- package/dist/src/ui/components/Header.js +2 -9
- package/dist/src/ui/components/Header.js.map +1 -1
- package/dist/src/ui/components/HistoryBrowserDialog.js +2 -1
- package/dist/src/ui/components/HistoryBrowserDialog.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +3 -1
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/MemoryUsageDisplay.js +41 -8
- package/dist/src/ui/components/MemoryUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.js +4 -3
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +3 -2
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/Tips.js +1 -1
- package/dist/src/ui/components/Tips.js.map +1 -1
- package/dist/src/ui/components/agents/SingleAgentDialog.d.ts +7 -4
- package/dist/src/ui/components/agents/SingleAgentDialog.js +135 -63
- package/dist/src/ui/components/agents/SingleAgentDialog.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.js +1 -9
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/ErrorMessage.js +2 -1
- package/dist/src/ui/components/messages/ErrorMessage.js.map +1 -1
- package/dist/src/ui/components/messages/InfoMessage.js +2 -1
- package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.js +4 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/UserMessage.js +1 -2
- package/dist/src/ui/components/messages/UserMessage.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js +14 -4
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.d.ts +18 -0
- package/dist/src/ui/contexts/SessionContext.js +25 -1
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -2
- package/dist/src/ui/hooks/slashCommandProcessor.js +54 -2
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAgentCommandProcessor.d.ts +12 -2
- package/dist/src/ui/hooks/useAgentCommandProcessor.js +169 -4
- package/dist/src/ui/hooks/useAgentCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.d.ts +2 -1
- package/dist/src/ui/hooks/useAuthCommand.js +22 -2
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useDialogClose.d.ts +2 -0
- package/dist/src/ui/hooks/useDialogClose.js +5 -0
- package/dist/src/ui/hooks/useDialogClose.js.map +1 -1
- package/dist/src/ui/hooks/useEncryptedStream.d.ts +2 -1
- package/dist/src/ui/hooks/useEncryptedStream.js +17 -4
- package/dist/src/ui/hooks/useEncryptedStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +216 -21
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useInputBoxColor.d.ts +13 -0
- package/dist/src/ui/hooks/useInputBoxColor.js +62 -0
- package/dist/src/ui/hooks/useInputBoxColor.js.map +1 -0
- package/dist/src/ui/hooks/useMessageQueue.d.ts +7 -1
- package/dist/src/ui/hooks/useMessageQueue.js +9 -3
- package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
- package/dist/src/ui/utils/agentConversationUtils.d.ts +28 -0
- package/dist/src/ui/utils/agentConversationUtils.js +71 -0
- package/dist/src/ui/utils/agentConversationUtils.js.map +1 -0
- package/dist/src/ui/utils/colorBlend.d.ts +33 -0
- package/dist/src/ui/utils/colorBlend.js +61 -0
- package/dist/src/ui/utils/colorBlend.js.map +1 -0
- package/dist/src/ui/utils/commandUtils.d.ts +2 -1
- package/dist/src/ui/utils/commandUtils.js +14 -1
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.test.js +25 -0
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
- package/dist/src/ui/utils/terminalBackgroundDetector.d.ts +16 -0
- package/dist/src/ui/utils/terminalBackgroundDetector.js +124 -23
- package/dist/src/ui/utils/terminalBackgroundDetector.js.map +1 -1
- package/dist/src/utils/agentCommandBuilder.d.ts +16 -4
- package/dist/src/utils/agentCommandBuilder.js +66 -26
- package/dist/src/utils/agentCommandBuilder.js.map +1 -1
- package/dist/src/utils/apiKeyUtils.d.ts +47 -0
- package/dist/src/utils/apiKeyUtils.js +177 -0
- package/dist/src/utils/apiKeyUtils.js.map +1 -0
- package/dist/src/utils/backgroundUpdateCheck.js +104 -7
- package/dist/src/utils/backgroundUpdateCheck.js.map +1 -1
- package/dist/src/utils/memoryManager.d.ts +85 -0
- package/dist/src/utils/memoryManager.js +258 -0
- package/dist/src/utils/memoryManager.js.map +1 -0
- package/dist/src/utils/memoryMonitor.d.ts +89 -0
- package/dist/src/utils/memoryMonitor.js +238 -0
- package/dist/src/utils/memoryMonitor.js.map +1 -0
- package/dist/src/utils/memoryWrapper.d.ts +18 -0
- package/dist/src/utils/memoryWrapper.js +62 -0
- package/dist/src/utils/memoryWrapper.js.map +1 -0
- package/dist/src/utils/preLaunchUpdateCheck.js +17 -7
- package/dist/src/utils/preLaunchUpdateCheck.js.map +1 -1
- package/dist/src/utils/soundNotification.d.ts +15 -0
- package/dist/src/utils/soundNotification.js +138 -0
- package/dist/src/utils/soundNotification.js.map +1 -0
- package/dist/src/utils/versionStorage.d.ts +20 -0
- package/dist/src/utils/versionStorage.js +62 -0
- package/dist/src/utils/versionStorage.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
// Cache for terminal background RGB to avoid re-detection
|
|
7
|
+
let cachedTerminalBgRgb = undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Gets the cached terminal background RGB, or null if not yet detected.
|
|
10
|
+
* @returns Cached RGB tuple or null
|
|
11
|
+
*/
|
|
12
|
+
export function getCachedTerminalBackgroundRgb() {
|
|
13
|
+
return cachedTerminalBgRgb ?? null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sets the cached terminal background RGB.
|
|
17
|
+
* @param rgb RGB tuple or null
|
|
18
|
+
*/
|
|
19
|
+
export function setCachedTerminalBackgroundRgb(rgb) {
|
|
20
|
+
cachedTerminalBgRgb = rgb;
|
|
21
|
+
}
|
|
6
22
|
/**
|
|
7
23
|
* Detects if the terminal has a light or dark background.
|
|
8
24
|
* Uses OSC 11 escape sequence to query the terminal background color.
|
|
@@ -48,34 +64,119 @@ export async function detectTerminalBackground() {
|
|
|
48
64
|
}
|
|
49
65
|
};
|
|
50
66
|
const cleanup = () => {
|
|
51
|
-
process.stdin.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
if (!process.stdin.isTTY) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
process.stdin.removeListener('data', onData);
|
|
72
|
+
// Immediately restore original raw mode state
|
|
73
|
+
process.stdin.setRawMode(originalRawMode);
|
|
74
|
+
// Don't pause - let the normal input system handle stdin
|
|
75
|
+
// The input system will set up its own listeners
|
|
76
|
+
}
|
|
77
|
+
catch (_err) {
|
|
78
|
+
// Ignore errors during cleanup
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
try {
|
|
82
|
+
// Set up stdin to receive the response
|
|
83
|
+
// Only modify stdin if it's in a valid state
|
|
84
|
+
if (process.stdin.isTTY && !process.stdin.destroyed) {
|
|
85
|
+
const wasPaused = process.stdin.isPaused();
|
|
86
|
+
process.stdin.setRawMode(true);
|
|
87
|
+
if (wasPaused) {
|
|
88
|
+
process.stdin.resume();
|
|
68
89
|
}
|
|
90
|
+
process.stdin.on('data', onData);
|
|
91
|
+
// Query the terminal background color using OSC 11
|
|
92
|
+
// Write directly to stdout to avoid any buffering issues
|
|
93
|
+
process.stdout.write('\x1b]11;?\x1b\\');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
cleanup();
|
|
97
|
+
resolve(null);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (_err) {
|
|
101
|
+
cleanup();
|
|
102
|
+
resolve(null);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Gets the actual RGB terminal background color.
|
|
108
|
+
* Uses OSC 11 escape sequence to query the terminal background color.
|
|
109
|
+
* @returns Promise that resolves to RGB tuple [r, g, b] or null if detection fails
|
|
110
|
+
*/
|
|
111
|
+
export async function getTerminalBackgroundRgb() {
|
|
112
|
+
// Check if we're in a TTY
|
|
113
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
const timeout = setTimeout(() => {
|
|
118
|
+
cleanup();
|
|
119
|
+
resolve(null);
|
|
120
|
+
}, 100); // 100ms timeout
|
|
121
|
+
let response = '';
|
|
122
|
+
let resolved = false;
|
|
123
|
+
const stdinTTY = process.stdin;
|
|
124
|
+
const originalRawMode = stdinTTY.isRaw;
|
|
125
|
+
const onData = (data) => {
|
|
126
|
+
const chunk = data.toString();
|
|
127
|
+
response += chunk;
|
|
128
|
+
// OSC 11 response format: ESC ] 11 ; rgb:RRRR/GGGG/BBBB ESC \
|
|
129
|
+
// or: ESC ] 11 ; rgb:RR/GG/BB ESC \
|
|
130
|
+
// Some terminals may send the response multiple times or with variations
|
|
131
|
+
// eslint-disable-next-line no-control-regex
|
|
132
|
+
const match = response.match(/\x1b\]11;rgb:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i);
|
|
133
|
+
if (match && !resolved) {
|
|
134
|
+
resolved = true;
|
|
135
|
+
clearTimeout(timeout);
|
|
136
|
+
// Parse RGB values (they can be 2 or 4 hex digits)
|
|
137
|
+
const r = parseInt(match[1].substring(0, 2), 16);
|
|
138
|
+
const g = parseInt(match[2].substring(0, 2), 16);
|
|
139
|
+
const b = parseInt(match[3].substring(0, 2), 16);
|
|
140
|
+
// Cache the result
|
|
141
|
+
cachedTerminalBgRgb = [r, g, b];
|
|
142
|
+
// Clean up immediately and resolve
|
|
143
|
+
cleanup();
|
|
144
|
+
resolve([r, g, b]);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const cleanup = () => {
|
|
148
|
+
if (!process.stdin.isTTY) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
process.stdin.removeListener('data', onData);
|
|
153
|
+
// Immediately restore original raw mode state
|
|
154
|
+
process.stdin.setRawMode(originalRawMode);
|
|
155
|
+
// Don't pause - let the normal input system handle stdin
|
|
156
|
+
// The input system will set up its own listeners
|
|
157
|
+
}
|
|
158
|
+
catch (_err) {
|
|
159
|
+
// Ignore errors during cleanup
|
|
69
160
|
}
|
|
70
161
|
};
|
|
71
162
|
try {
|
|
72
163
|
// Set up stdin to receive the response
|
|
73
|
-
|
|
74
|
-
process.stdin.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
164
|
+
// Only modify stdin if it's in a valid state
|
|
165
|
+
if (process.stdin.isTTY && !process.stdin.destroyed) {
|
|
166
|
+
const wasPaused = process.stdin.isPaused();
|
|
167
|
+
process.stdin.setRawMode(true);
|
|
168
|
+
if (wasPaused) {
|
|
169
|
+
process.stdin.resume();
|
|
170
|
+
}
|
|
171
|
+
process.stdin.on('data', onData);
|
|
172
|
+
// Query the terminal background color using OSC 11
|
|
173
|
+
// Write directly to stdout to avoid any buffering issues
|
|
174
|
+
process.stdout.write('\x1b]11;?\x1b\\');
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
cleanup();
|
|
178
|
+
resolve(null);
|
|
179
|
+
}
|
|
79
180
|
}
|
|
80
181
|
catch (_err) {
|
|
81
182
|
cleanup();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminalBackgroundDetector.js","sourceRoot":"","sources":["../../../../src/ui/utils/terminalBackgroundDetector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAEzB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAmB,CAAC;QAC7C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,KAAK,CAAC;YAElB,8DAA8D;YAC9D,oCAAoC;YACpC,4CAA4C;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAEpF,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBAEtB,mDAAmD;gBACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,2DAA2D;gBAC3D,qDAAqD;gBACrD,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAE/D,MAAM,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;gBAElD,mCAAmC;gBACnC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"terminalBackgroundDetector.js","sourceRoot":"","sources":["../../../../src/ui/utils/terminalBackgroundDetector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,0DAA0D;AAC1D,IAAI,mBAAmB,GAAgD,SAAS,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,8BAA8B;IAC5C,OAAO,mBAAmB,IAAI,IAAI,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAAC,GAAoC;IACjF,mBAAmB,GAAG,GAAG,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAEzB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAmB,CAAC;QAC7C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,KAAK,CAAC;YAElB,8DAA8D;YAC9D,oCAAoC;YACpC,4CAA4C;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAEpF,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBAEtB,mDAAmD;gBACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,2DAA2D;gBAC3D,qDAAqD;gBACrD,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;gBAE/D,MAAM,MAAM,GAAG,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;gBAElD,mCAAmC;gBACnC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,8CAA8C;gBAC9C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBAC1C,yDAAyD;gBACzD,iDAAiD;YACnD,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,+BAA+B;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,uCAAuC;YACvC,6CAA6C;YAC7C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,mDAAmD;gBACnD,yDAAyD;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,IAAI,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,gBAAgB;QAEzB,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAmB,CAAC;QAC7C,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,KAAK,CAAC;YAElB,8DAA8D;YAC9D,oCAAoC;YACpC,yEAAyE;YACzE,4CAA4C;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAEpF,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;gBAEtB,mDAAmD;gBACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,mBAAmB;gBACnB,mBAAmB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAEhC,mCAAmC;gBACnC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC7C,8CAA8C;gBAC9C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;gBAC1C,yDAAyD;gBACzD,iDAAiD;YACnD,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,+BAA+B;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,uCAAuC;YACvC,6CAA6C;YAC7C,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC/B,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,mDAAmD;gBACnD,yDAAyD;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,IAAI,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,MAAM,UAAU,GAAG,MAAM,wBAAwB,EAAE,CAAC;IAEpD,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,iEAAiE;IACjE,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Blackbox
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import type { LoadedSettings } from '../config/settings.js';
|
|
6
7
|
export type AgentType = 'blackbox' | 'claude' | 'codex' | 'gemini';
|
|
7
8
|
/**
|
|
8
9
|
* Determines if an agent should use direct client integration vs CLI execution.
|
|
@@ -10,6 +11,17 @@ export type AgentType = 'blackbox' | 'claude' | 'codex' | 'gemini';
|
|
|
10
11
|
* Other agents use CLI execution for their specific implementations.
|
|
11
12
|
*/
|
|
12
13
|
export declare function shouldUseDirectClient(agentType: AgentType): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Options for building agent commands with multi-turn support
|
|
16
|
+
*/
|
|
17
|
+
export interface AgentCommandOptions {
|
|
18
|
+
/** Session ID for multi-turn conversations (used by Claude CLI --resume) */
|
|
19
|
+
sessionId?: string;
|
|
20
|
+
/** Whether this is the first message in the session */
|
|
21
|
+
isFirstMessage?: boolean;
|
|
22
|
+
/** Past messages/conversation history to prepend to the instruction (for multi-turn) */
|
|
23
|
+
pastMessages?: string;
|
|
24
|
+
}
|
|
13
25
|
/**
|
|
14
26
|
* Builds the CLI command for the specified agent type.
|
|
15
27
|
* This is the single source of truth for agent command generation,
|
|
@@ -18,19 +30,19 @@ export declare function shouldUseDirectClient(agentType: AgentType): boolean;
|
|
|
18
30
|
* Note: For blackbox agent in single agent mode, direct client integration is preferred
|
|
19
31
|
* over CLI execution to reuse existing streaming and tool infrastructure.
|
|
20
32
|
*/
|
|
21
|
-
export declare function buildAgentCommand(agentType: AgentType, model: string, task: string): string;
|
|
33
|
+
export declare function buildAgentCommand(agentType: AgentType, model: string, task: string, options?: AgentCommandOptions, settings?: LoadedSettings): string;
|
|
22
34
|
/**
|
|
23
35
|
* Builds the enhanced Claude command with jq parsing for readable output.
|
|
24
36
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
25
37
|
*/
|
|
26
|
-
export declare function buildClaudeCommandWithJqParsing(model: string, task: string, outputFile: string): string;
|
|
38
|
+
export declare function buildClaudeCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
|
|
27
39
|
/**
|
|
28
40
|
* Builds the enhanced Codex command with jq parsing for readable output.
|
|
29
41
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
30
42
|
*/
|
|
31
|
-
export declare function buildCodexCommandWithJqParsing(model: string, task: string, outputFile: string): string;
|
|
43
|
+
export declare function buildCodexCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
|
|
32
44
|
/**
|
|
33
45
|
* Builds the enhanced Gemini command with jq parsing for readable output.
|
|
34
46
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
35
47
|
*/
|
|
36
|
-
export declare function buildGeminiCommandWithJqParsing(model: string, task: string, outputFile: string): string;
|
|
48
|
+
export declare function buildGeminiCommandWithJqParsing(model: string, task: string, outputFile: string, settings?: LoadedSettings): string;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { resolveOpenAIModel } from '@blackbox_ai/blackbox-cli-core';
|
|
7
|
+
import { getEffectiveApiKey } from './apiKeyUtils.js';
|
|
7
8
|
/**
|
|
8
9
|
* Determines if an agent should use direct client integration vs CLI execution.
|
|
9
10
|
* Blackbox agent uses the existing Gemini client directly to reuse streaming, tools, and UI components.
|
|
@@ -20,28 +21,56 @@ export function shouldUseDirectClient(agentType) {
|
|
|
20
21
|
* Note: For blackbox agent in single agent mode, direct client integration is preferred
|
|
21
22
|
* over CLI execution to reuse existing streaming and tool infrastructure.
|
|
22
23
|
*/
|
|
23
|
-
export function buildAgentCommand(agentType, model, task) {
|
|
24
|
+
export function buildAgentCommand(agentType, model, task, options, settings) {
|
|
24
25
|
// Escape single quotes in the task for shell safety
|
|
25
26
|
const escapedTask = task.replace(/'/g, "'\\''");
|
|
26
27
|
switch (agentType) {
|
|
27
|
-
case 'blackbox':
|
|
28
|
-
|
|
28
|
+
case 'blackbox': {
|
|
29
|
+
// For multi-turn support: prepend past messages to the instruction
|
|
30
|
+
// This follows the remote-code approach which is simpler and more reliable
|
|
31
|
+
let finalInstruction = escapedTask;
|
|
32
|
+
if (options?.pastMessages) {
|
|
33
|
+
// Escape the past messages for shell safety
|
|
34
|
+
const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
|
|
35
|
+
finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
|
|
36
|
+
}
|
|
37
|
+
return `blackbox -p '${finalInstruction}' -y`;
|
|
38
|
+
}
|
|
29
39
|
case 'claude': {
|
|
30
|
-
const blackboxApiKey =
|
|
40
|
+
const blackboxApiKey = getEffectiveApiKey('claude', settings);
|
|
31
41
|
if (!blackboxApiKey) {
|
|
32
|
-
throw new Error('BLACKBOX_API_KEY
|
|
42
|
+
throw new Error('BLACKBOX_API_KEY is required for Claude Code agent. Please run "/agent configure" to set up your API key.');
|
|
43
|
+
}
|
|
44
|
+
// For multi-turn support: prepend past messages to the instruction
|
|
45
|
+
// This follows the remote-code approach which is simpler and more reliable
|
|
46
|
+
let finalInstruction = escapedTask;
|
|
47
|
+
if (options?.pastMessages) {
|
|
48
|
+
// Escape the past messages for shell safety
|
|
49
|
+
const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
|
|
50
|
+
finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
|
|
33
51
|
}
|
|
34
|
-
return `ANTHROPIC_API_KEY="${blackboxApiKey}" ANTHROPIC_BASE_URL="https://api.blackbox.ai" claude --model "${model}" -p --output-format=stream-json --include-partial-messages --dangerously-skip-permissions --verbose '${
|
|
52
|
+
return `ANTHROPIC_API_KEY="${blackboxApiKey}" ANTHROPIC_BASE_URL="https://api.blackbox.ai" claude --model "${model}" -p --output-format=stream-json --include-partial-messages --dangerously-skip-permissions --verbose '${finalInstruction}'`;
|
|
35
53
|
}
|
|
36
54
|
case 'codex': {
|
|
55
|
+
// Get effective API keys from both environment and settings
|
|
56
|
+
const blackboxApiKey = getEffectiveApiKey('blackbox', settings);
|
|
57
|
+
const openaiApiKey = getEffectiveApiKey('codex', settings);
|
|
37
58
|
// Resolve model to use Blackbox provider if available
|
|
38
59
|
const apiKeys = {
|
|
39
|
-
blackbox_api_key:
|
|
40
|
-
openai_api_key:
|
|
60
|
+
blackbox_api_key: blackboxApiKey,
|
|
61
|
+
openai_api_key: openaiApiKey
|
|
41
62
|
};
|
|
42
63
|
const resolved = resolveOpenAIModel(model, apiKeys);
|
|
43
64
|
if (!resolved.userApiKey) {
|
|
44
|
-
throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY
|
|
65
|
+
throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY is required for Codex agent. Please run "/agent configure" to set up your API key.');
|
|
66
|
+
}
|
|
67
|
+
// For multi-turn support: prepend past messages to the instruction
|
|
68
|
+
// This follows the remote-code approach which is simpler and more reliable
|
|
69
|
+
let finalInstruction = escapedTask;
|
|
70
|
+
if (options?.pastMessages) {
|
|
71
|
+
// Escape the past messages for shell safety
|
|
72
|
+
const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
|
|
73
|
+
finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
|
|
45
74
|
}
|
|
46
75
|
// Check if using Blackbox provider
|
|
47
76
|
if (resolved.selectedModel.startsWith('blackboxai/')) {
|
|
@@ -67,7 +96,7 @@ log_requests = true`;
|
|
|
67
96
|
return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
|
|
68
97
|
${configToml}
|
|
69
98
|
EOF
|
|
70
|
-
BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-approvals-and-sandbox '${
|
|
99
|
+
BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${finalInstruction}'`;
|
|
71
100
|
}
|
|
72
101
|
else {
|
|
73
102
|
// Create config.toml for OpenAI provider
|
|
@@ -90,15 +119,23 @@ log_requests = true`;
|
|
|
90
119
|
return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
|
|
91
120
|
${configToml}
|
|
92
121
|
EOF
|
|
93
|
-
OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-approvals-and-sandbox '${
|
|
122
|
+
OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${finalInstruction}'`;
|
|
94
123
|
}
|
|
95
124
|
}
|
|
96
125
|
case 'gemini': {
|
|
97
|
-
const geminiApiKey =
|
|
126
|
+
const geminiApiKey = getEffectiveApiKey('gemini', settings);
|
|
98
127
|
if (!geminiApiKey) {
|
|
99
|
-
throw new Error('GEMINI_API_KEY
|
|
128
|
+
throw new Error('GEMINI_API_KEY is required for Gemini agent. Please run "/agent configure" to set up your API key.');
|
|
129
|
+
}
|
|
130
|
+
// For multi-turn support: prepend past messages to the instruction
|
|
131
|
+
// This follows the remote-code approach which is simpler and more reliable
|
|
132
|
+
let finalInstruction = escapedTask;
|
|
133
|
+
if (options?.pastMessages) {
|
|
134
|
+
// Escape the past messages for shell safety
|
|
135
|
+
const escapedPastMessages = options.pastMessages.replace(/'/g, "'\\''");
|
|
136
|
+
finalInstruction = `${escapedPastMessages}\n\nFOLLOWUP REQUEST:\n${escapedTask}`;
|
|
100
137
|
}
|
|
101
|
-
return `GEMINI_API_KEY="${geminiApiKey}" gemini --model "${model}" --yolo '${
|
|
138
|
+
return `GEMINI_API_KEY="${geminiApiKey}" gemini --model "${model}" --yolo '${finalInstruction}' --output-format stream-json`;
|
|
102
139
|
}
|
|
103
140
|
default:
|
|
104
141
|
throw new Error(`Unsupported agent type: ${agentType}`);
|
|
@@ -108,10 +145,10 @@ OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-a
|
|
|
108
145
|
* Builds the enhanced Claude command with jq parsing for readable output.
|
|
109
146
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
110
147
|
*/
|
|
111
|
-
export function buildClaudeCommandWithJqParsing(model, task, outputFile) {
|
|
112
|
-
const blackboxApiKey =
|
|
148
|
+
export function buildClaudeCommandWithJqParsing(model, task, outputFile, settings) {
|
|
149
|
+
const blackboxApiKey = getEffectiveApiKey('claude', settings);
|
|
113
150
|
if (!blackboxApiKey) {
|
|
114
|
-
throw new Error('BLACKBOX_API_KEY
|
|
151
|
+
throw new Error('BLACKBOX_API_KEY is required for Claude Code agent. Please run "/agent configure" to set up your API key.');
|
|
115
152
|
}
|
|
116
153
|
const escapedTask = task.replace(/'/g, "'\\''");
|
|
117
154
|
return `ANTHROPIC_API_KEY="${blackboxApiKey}" ANTHROPIC_BASE_URL="https://api.blackbox.ai" claude --model "${model}" -p --output-format=stream-json --dangerously-skip-permissions --verbose '${escapedTask}' 2>&1 | jq -r '
|
|
@@ -149,15 +186,18 @@ export function buildClaudeCommandWithJqParsing(model, task, outputFile) {
|
|
|
149
186
|
* Builds the enhanced Codex command with jq parsing for readable output.
|
|
150
187
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
151
188
|
*/
|
|
152
|
-
export function buildCodexCommandWithJqParsing(model, task, outputFile) {
|
|
189
|
+
export function buildCodexCommandWithJqParsing(model, task, outputFile, settings) {
|
|
190
|
+
// Get effective API keys from both environment and settings
|
|
191
|
+
const blackboxApiKey = getEffectiveApiKey('blackbox', settings);
|
|
192
|
+
const openaiApiKey = getEffectiveApiKey('codex', settings);
|
|
153
193
|
// Resolve model to use Blackbox provider if available
|
|
154
194
|
const apiKeys = {
|
|
155
|
-
blackbox_api_key:
|
|
156
|
-
openai_api_key:
|
|
195
|
+
blackbox_api_key: blackboxApiKey,
|
|
196
|
+
openai_api_key: openaiApiKey
|
|
157
197
|
};
|
|
158
198
|
const resolved = resolveOpenAIModel(model, apiKeys);
|
|
159
199
|
if (!resolved.userApiKey) {
|
|
160
|
-
throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY
|
|
200
|
+
throw new Error('Either BLACKBOX_API_KEY or OPENAI_API_KEY is required for Codex agent. Please run "/agent configure" to set up your API key.');
|
|
161
201
|
}
|
|
162
202
|
const escapedTask = task.replace(/'/g, "'\\''");
|
|
163
203
|
// Check if using Blackbox provider
|
|
@@ -182,7 +222,7 @@ log_requests = true`;
|
|
|
182
222
|
return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
|
|
183
223
|
${configToml}
|
|
184
224
|
EOF
|
|
185
|
-
BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
|
|
225
|
+
BLACKBOX_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
|
|
186
226
|
if .type == "item.completed" and .item.type == "agent_message" then
|
|
187
227
|
.item.text
|
|
188
228
|
elif .type == "item.started" and .item.type == "command_execution" then
|
|
@@ -227,7 +267,7 @@ log_requests = true`;
|
|
|
227
267
|
return `mkdir -p ~/.codex && cat > ~/.codex/config.toml << 'EOF'
|
|
228
268
|
${configToml}
|
|
229
269
|
EOF
|
|
230
|
-
OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
|
|
270
|
+
OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox '${escapedTask}' 2>&1 | jq -r '
|
|
231
271
|
if .type == "item.completed" and .item.type == "agent_message" then
|
|
232
272
|
.item.text
|
|
233
273
|
elif .type == "item.started" and .item.type == "command_execution" then
|
|
@@ -257,10 +297,10 @@ OPENAI_API_KEY="${resolved.userApiKey}" codex exec --json --dangerously-bypass-a
|
|
|
257
297
|
* Builds the enhanced Gemini command with jq parsing for readable output.
|
|
258
298
|
* Used specifically in multi-agent scenarios for better output formatting.
|
|
259
299
|
*/
|
|
260
|
-
export function buildGeminiCommandWithJqParsing(model, task, outputFile) {
|
|
261
|
-
const geminiApiKey =
|
|
300
|
+
export function buildGeminiCommandWithJqParsing(model, task, outputFile, settings) {
|
|
301
|
+
const geminiApiKey = getEffectiveApiKey('gemini', settings);
|
|
262
302
|
if (!geminiApiKey) {
|
|
263
|
-
throw new Error('GEMINI_API_KEY
|
|
303
|
+
throw new Error('GEMINI_API_KEY is required for Gemini agent. Please run "/agent configure" to set up your API key.');
|
|
264
304
|
}
|
|
265
305
|
const escapedTask = task.replace(/'/g, "'\\''");
|
|
266
306
|
return `GEMINI_API_KEY="${geminiApiKey}" gemini --model "${model}" --yolo '${escapedTask}' --output-format stream-json | jq -r '
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentCommandBuilder.js","sourceRoot":"","sources":["../../../src/utils/agentCommandBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"agentCommandBuilder.js","sourceRoot":"","sources":["../../../src/utils/agentCommandBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Blackbox
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentType } from '@blackbox_ai/blackbox-cli-core';
|
|
7
|
+
import type { LoadedSettings } from '../config/settings.js';
|
|
8
|
+
export interface ApiKeyInfo {
|
|
9
|
+
envVarName: string;
|
|
10
|
+
settingsPath: string;
|
|
11
|
+
displayName: string;
|
|
12
|
+
placeholder: string;
|
|
13
|
+
validator: (key: string) => boolean;
|
|
14
|
+
description: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Mapping of agent types to their API key requirements
|
|
18
|
+
*/
|
|
19
|
+
export declare const AGENT_API_KEY_MAP: Record<AgentType, ApiKeyInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Check if an API key is available for the given agent type
|
|
22
|
+
* Checks both environment variables and settings
|
|
23
|
+
*/
|
|
24
|
+
export declare function hasApiKeyForAgent(agentType: AgentType, settings?: LoadedSettings): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Get API key from settings for the given agent type
|
|
27
|
+
*/
|
|
28
|
+
export declare function getApiKeyFromSettings(agentType: AgentType, settings: LoadedSettings): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get the effective API key for an agent (env var takes precedence over settings)
|
|
31
|
+
*/
|
|
32
|
+
export declare function getEffectiveApiKey(agentType: AgentType, settings?: LoadedSettings): string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Save API key to settings for the given agent type
|
|
35
|
+
*/
|
|
36
|
+
export declare function saveApiKeyToSettings(agentType: AgentType, apiKey: string, settings: LoadedSettings): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get missing API key info for agents that don't have keys
|
|
39
|
+
*/
|
|
40
|
+
export declare function getMissingApiKeyInfo(agentTypes: AgentType[], settings?: LoadedSettings): ApiKeyInfo[];
|
|
41
|
+
/**
|
|
42
|
+
* Validate API key format for a specific agent type
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateApiKey(agentType: AgentType, apiKey: string): {
|
|
45
|
+
valid: boolean;
|
|
46
|
+
error?: string;
|
|
47
|
+
};
|