bingocode 1.1.200-beta.19 → 1.1.200-beta.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bingocode",
3
- "version": "1.1.200-beta.19",
3
+ "version": "1.1.200-beta.20",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "claude": "bin/claude-win.cjs",
@@ -1,229 +1,229 @@
1
- version: 2
2
-
3
- # Provider Preset Configuration
4
- # fields array declares fields to be filled when adding
5
- # key: 'name' | 'apiKey' | 'baseUrl' mapped directly to top-level fields, others saved in extra.<key>
6
- # secret: true uses mask display in frontend
7
- #
8
- # modelsUrl: model list path relative to baseUrl, empty string means dynamic pulling not supported
9
- # modelsAuthStyle: bearer → Authorization: Bearer <apiKey>
10
- # x-api-key → x-api-key: <apiKey> + anthropic-version header
11
- # modelsDataPath: record field name for models array in JSON response (almost always 'data')
12
-
13
- presets:
14
- - id: official
15
- name: Claude Official
16
- baseUrl: ''
17
- apiFormat: anthropic
18
- needsApiKey: false
19
- websiteUrl: https://www.anthropic.com/claude-code
20
- modelsUrl: /v1/models
21
- modelsAuthStyle: x-api-key
22
- modelsDataPath: data
23
- fields:
24
- - key: name
25
- label: Provider Nickname
26
- required: true
27
- secret: false
28
- placeholder: 'e.g. Claude Official'
29
-
30
- - id: openai
31
- name: OpenAI
32
- baseUrl: https://api.openai.com/v1
33
- apiFormat: openai_chat
34
- needsApiKey: true
35
- websiteUrl: https://platform.openai.com
36
- modelsUrl: /v1/models
37
- modelsAuthStyle: bearer
38
- modelsDataPath: data
39
- fields:
40
- - key: name
41
- label: Provider Nickname
42
- required: true
43
- secret: false
44
- placeholder: 'e.g. My OpenAI'
45
- - key: apiKey
46
- label: API Key
47
- required: true
48
- secret: true
49
- placeholder: 'sk-...'
50
- - key: baseUrl
51
- label: Base URL (Optional)
52
- required: false
53
- secret: false
54
- default: https://api.openai.com/v1
55
- placeholder: 'https://api.openai.com/v1'
56
-
57
- - id: gemini
58
- name: Google Gemini
59
- baseUrl: https://generativelanguage.googleapis.com/v1beta/openai
60
- apiFormat: openai_chat
61
- needsApiKey: true
62
- websiteUrl: https://aistudio.google.com
63
- modelsUrl: /v1/models
64
- modelsAuthStyle: bearer
65
- modelsDataPath: data
66
- fields:
67
- - key: name
68
- label: Provider Nickname
69
- required: true
70
- secret: false
71
- placeholder: 'e.g. My Gemini'
72
- - key: apiKey
73
- label: API Key
74
- required: true
75
- secret: true
76
- placeholder: 'Gemini API Key'
77
-
78
- - id: mistral
79
- name: Mistral AI
80
- baseUrl: https://api.mistral.ai/v1
81
- apiFormat: openai_chat
82
- needsApiKey: true
83
- websiteUrl: https://console.mistral.ai
84
- modelsUrl: /v1/models
85
- modelsAuthStyle: bearer
86
- modelsDataPath: data
87
- fields:
88
- - key: name
89
- label: Provider Nickname
90
- required: true
91
- secret: false
92
- placeholder: 'e.g. My Mistral'
93
- - key: apiKey
94
- label: API Key
95
- required: true
96
- secret: true
97
- placeholder: 'Mistral API Key'
98
-
99
- - id: deepseek
100
- name: DeepSeek
101
- baseUrl: https://api.deepseek.com/anthropic
102
- apiFormat: anthropic
103
- needsApiKey: true
104
- websiteUrl: https://platform.deepseek.com
105
- # Models list follows OpenAI endpoint (no /v1/models under /anthropic)
106
- modelsUrl: https://api.deepseek.com/v1/models
107
- modelsAuthStyle: bearer
108
- modelsDataPath: data
109
- fields:
110
- - key: name
111
- label: Provider Nickname
112
- required: true
113
- secret: false
114
- placeholder: 'e.g. My DeepSeek'
115
- - key: apiKey
116
- label: API Key
117
- required: true
118
- secret: true
119
- placeholder: 'sk-...'
120
-
121
- - id: nvidia
122
- name: NVIDIA API
123
- baseUrl: https://integrate.api.nvidia.com/v1
124
- apiFormat: openai_chat
125
- needsApiKey: true
126
- websiteUrl: https://build.nvidia.com/explore/discover
127
- modelsUrl: /models
128
- modelsAuthStyle: bearer
129
- modelsDataPath: data
130
- fields:
131
- - key: name
132
- label: Provider Nickname
133
- required: true
134
- secret: false
135
- placeholder: 'e.g. My NVIDIA'
136
- - key: apiKey
137
- label: API Key
138
- required: true
139
- secret: true
140
- placeholder: 'nvapi-...'
141
-
142
- - id: zhipuglm
143
- name: Zhipu GLM
144
- baseUrl: https://open.bigmodel.cn/api/paas/v4
145
- apiFormat: openai_chat
146
- needsApiKey: true
147
- websiteUrl: https://open.bigmodel.cn
148
- modelsUrl: /v4/models
149
- modelsAuthStyle: bearer
150
- modelsDataPath: data
151
- fields:
152
- - key: name
153
- label: Provider Nickname
154
- required: true
155
- secret: false
156
- placeholder: 'e.g. My GLM'
157
- - key: apiKey
158
- label: API Key
159
- required: true
160
- secret: true
161
- placeholder: 'Zhipu API Key (glm-5.1)'
162
-
163
- - id: kimi
164
- name: Kimi
165
- baseUrl: https://api.moonshot.ai/v1
166
- apiFormat: openai_chat
167
- needsApiKey: true
168
- websiteUrl: https://platform.moonshot.cn
169
- modelsUrl: /models
170
- modelsAuthStyle: bearer
171
- modelsDataPath: data
172
- fields:
173
- - key: name
174
- label: Provider Nickname
175
- required: true
176
- secret: false
177
- placeholder: 'e.g. My Kimi'
178
- - key: apiKey
179
- label: API Key
180
- required: true
181
- secret: true
182
- placeholder: 'Moonshot API Key (kimi-k2.6)'
183
-
184
- - id: minimax
185
- name: MiniMax
186
- baseUrl: https://api.minimax.io/v1
187
- apiFormat: openai_chat
188
- needsApiKey: true
189
- websiteUrl: https://platform.minimaxi.com
190
- modelsUrl: /models
191
- modelsAuthStyle: bearer
192
- modelsDataPath: data
193
- fields:
194
- - key: name
195
- label: Provider Nickname
196
- required: true
197
- secret: false
198
- placeholder: 'e.g. My MiniMax'
199
- - key: apiKey
200
- label: API Key
201
- required: true
202
- secret: true
203
- placeholder: 'MiniMax API Key (MiniMax-M2.7)'
204
-
205
- - id: custom
206
- name: Custom
207
- baseUrl: ''
208
- apiFormat: openai_chat
209
- needsApiKey: true
210
- websiteUrl: ''
211
- modelsUrl: /v1/models
212
- modelsAuthStyle: bearer
213
- modelsDataPath: data
214
- fields:
215
- - key: name
216
- label: Provider Nickname
217
- required: true
218
- secret: false
219
- placeholder: 'e.g. My Custom Provider'
220
- - key: baseUrl
221
- label: Base URL
222
- required: true
223
- secret: false
224
- placeholder: 'https://your-api-endpoint.com/v1'
225
- - key: apiKey
226
- label: API Key
227
- required: false
228
- secret: true
229
- placeholder: '(Optional) API Key'
1
+ version: 2
2
+
3
+ # Provider Preset Configuration
4
+ # fields array declares fields to be filled when adding
5
+ # key: 'name' | 'apiKey' | 'baseUrl' mapped directly to top-level fields, others saved in extra.<key>
6
+ # secret: true uses mask display in frontend
7
+ #
8
+ # modelsUrl: model list path relative to baseUrl, empty string means dynamic pulling not supported
9
+ # modelsAuthStyle: bearer → Authorization: Bearer <apiKey>
10
+ # x-api-key → x-api-key: <apiKey> + anthropic-version header
11
+ # modelsDataPath: record field name for models array in JSON response (almost always 'data')
12
+
13
+ presets:
14
+ - id: official
15
+ name: Claude Official
16
+ baseUrl: ''
17
+ apiFormat: anthropic
18
+ needsApiKey: false
19
+ websiteUrl: https://www.anthropic.com/claude-code
20
+ modelsUrl: /v1/models
21
+ modelsAuthStyle: x-api-key
22
+ modelsDataPath: data
23
+ fields:
24
+ - key: name
25
+ label: Provider Nickname
26
+ required: true
27
+ secret: false
28
+ placeholder: 'e.g. Claude Official'
29
+
30
+ - id: openai
31
+ name: OpenAI
32
+ baseUrl: https://api.openai.com/v1
33
+ apiFormat: openai_chat
34
+ needsApiKey: true
35
+ websiteUrl: https://platform.openai.com
36
+ modelsUrl: /v1/models
37
+ modelsAuthStyle: bearer
38
+ modelsDataPath: data
39
+ fields:
40
+ - key: name
41
+ label: Provider Nickname
42
+ required: true
43
+ secret: false
44
+ placeholder: 'e.g. My OpenAI'
45
+ - key: apiKey
46
+ label: API Key
47
+ required: true
48
+ secret: true
49
+ placeholder: 'sk-...'
50
+ - key: baseUrl
51
+ label: Base URL (Optional)
52
+ required: false
53
+ secret: false
54
+ default: https://api.openai.com/v1
55
+ placeholder: 'https://api.openai.com/v1'
56
+
57
+ - id: gemini
58
+ name: Google Gemini
59
+ baseUrl: https://generativelanguage.googleapis.com/v1beta/openai
60
+ apiFormat: openai_chat
61
+ needsApiKey: true
62
+ websiteUrl: https://aistudio.google.com
63
+ modelsUrl: /v1/models
64
+ modelsAuthStyle: bearer
65
+ modelsDataPath: data
66
+ fields:
67
+ - key: name
68
+ label: Provider Nickname
69
+ required: true
70
+ secret: false
71
+ placeholder: 'e.g. My Gemini'
72
+ - key: apiKey
73
+ label: API Key
74
+ required: true
75
+ secret: true
76
+ placeholder: 'Gemini API Key'
77
+
78
+ - id: mistral
79
+ name: Mistral AI
80
+ baseUrl: https://api.mistral.ai/v1
81
+ apiFormat: openai_chat
82
+ needsApiKey: true
83
+ websiteUrl: https://console.mistral.ai
84
+ modelsUrl: /v1/models
85
+ modelsAuthStyle: bearer
86
+ modelsDataPath: data
87
+ fields:
88
+ - key: name
89
+ label: Provider Nickname
90
+ required: true
91
+ secret: false
92
+ placeholder: 'e.g. My Mistral'
93
+ - key: apiKey
94
+ label: API Key
95
+ required: true
96
+ secret: true
97
+ placeholder: 'Mistral API Key'
98
+
99
+ - id: deepseek
100
+ name: DeepSeek
101
+ baseUrl: https://api.deepseek.com/anthropic
102
+ apiFormat: anthropic
103
+ needsApiKey: true
104
+ websiteUrl: https://platform.deepseek.com
105
+ # Models list follows OpenAI endpoint (no /v1/models under /anthropic)
106
+ modelsUrl: https://api.deepseek.com/v1/models
107
+ modelsAuthStyle: bearer
108
+ modelsDataPath: data
109
+ fields:
110
+ - key: name
111
+ label: Provider Nickname
112
+ required: true
113
+ secret: false
114
+ placeholder: 'e.g. My DeepSeek'
115
+ - key: apiKey
116
+ label: API Key
117
+ required: true
118
+ secret: true
119
+ placeholder: 'sk-...'
120
+
121
+ - id: nvidia
122
+ name: NVIDIA API
123
+ baseUrl: https://integrate.api.nvidia.com/v1
124
+ apiFormat: openai_chat
125
+ needsApiKey: true
126
+ websiteUrl: https://build.nvidia.com/explore/discover
127
+ modelsUrl: /models
128
+ modelsAuthStyle: bearer
129
+ modelsDataPath: data
130
+ fields:
131
+ - key: name
132
+ label: Provider Nickname
133
+ required: true
134
+ secret: false
135
+ placeholder: 'e.g. My NVIDIA'
136
+ - key: apiKey
137
+ label: API Key
138
+ required: true
139
+ secret: true
140
+ placeholder: 'nvapi-...'
141
+
142
+ - id: zhipuglm
143
+ name: Zhipu GLM
144
+ baseUrl: https://open.bigmodel.cn/api/paas/v4
145
+ apiFormat: openai_chat
146
+ needsApiKey: true
147
+ websiteUrl: https://open.bigmodel.cn
148
+ modelsUrl: /v4/models
149
+ modelsAuthStyle: bearer
150
+ modelsDataPath: data
151
+ fields:
152
+ - key: name
153
+ label: Provider Nickname
154
+ required: true
155
+ secret: false
156
+ placeholder: 'e.g. My GLM'
157
+ - key: apiKey
158
+ label: API Key
159
+ required: true
160
+ secret: true
161
+ placeholder: 'Zhipu API Key (glm-5.1)'
162
+
163
+ - id: kimi
164
+ name: Kimi
165
+ baseUrl: https://api.moonshot.ai/v1
166
+ apiFormat: openai_chat
167
+ needsApiKey: true
168
+ websiteUrl: https://platform.moonshot.cn
169
+ modelsUrl: /models
170
+ modelsAuthStyle: bearer
171
+ modelsDataPath: data
172
+ fields:
173
+ - key: name
174
+ label: Provider Nickname
175
+ required: true
176
+ secret: false
177
+ placeholder: 'e.g. My Kimi'
178
+ - key: apiKey
179
+ label: API Key
180
+ required: true
181
+ secret: true
182
+ placeholder: 'Moonshot API Key (kimi-k2.6)'
183
+
184
+ - id: minimax
185
+ name: MiniMax
186
+ baseUrl: https://api.minimax.io/v1
187
+ apiFormat: openai_chat
188
+ needsApiKey: true
189
+ websiteUrl: https://platform.minimaxi.com
190
+ modelsUrl: /models
191
+ modelsAuthStyle: bearer
192
+ modelsDataPath: data
193
+ fields:
194
+ - key: name
195
+ label: Provider Nickname
196
+ required: true
197
+ secret: false
198
+ placeholder: 'e.g. My MiniMax'
199
+ - key: apiKey
200
+ label: API Key
201
+ required: true
202
+ secret: true
203
+ placeholder: 'MiniMax API Key (MiniMax-M2.7)'
204
+
205
+ - id: custom
206
+ name: Custom
207
+ baseUrl: ''
208
+ apiFormat: openai_chat
209
+ needsApiKey: true
210
+ websiteUrl: ''
211
+ modelsUrl: /v1/models
212
+ modelsAuthStyle: bearer
213
+ modelsDataPath: data
214
+ fields:
215
+ - key: name
216
+ label: Provider Nickname
217
+ required: true
218
+ secret: false
219
+ placeholder: 'e.g. My Custom Provider'
220
+ - key: baseUrl
221
+ label: Base URL
222
+ required: true
223
+ secret: false
224
+ placeholder: 'https://your-api-endpoint.com/v1'
225
+ - key: apiKey
226
+ label: API Key
227
+ required: false
228
+ secret: true
229
+ placeholder: '(Optional) API Key'
@@ -269,6 +269,18 @@ export class ProviderService {
269
269
  // --- Settings sync ---
270
270
 
271
271
  private async syncToSettings(provider: SavedProvider): Promise<void> {
272
+ // Prefer slot-based model IDs when slots are configured, so that the
273
+ // slot table (set via "Configure Model Slots" in the TUI) is the single
274
+ // source of truth. Falling back to provider.models only when no slots
275
+ // exist keeps things working for users who haven't configured slots yet.
276
+ const slots = await this.readSlots()
277
+ const hasSlots = Object.keys(slots).length > 0
278
+ if (hasSlots) {
279
+ await this.syncSettingsForSlots(slots)
280
+ return
281
+ }
282
+
283
+ // Legacy fallback: no slots configured — use provider.models directly
272
284
  const settings = await this.readSettings()
273
285
  const existingEnv = (settings.env as Record<string, string>) || {}
274
286
 
@@ -5,7 +5,7 @@ import { ConfigurableShortcutHint } from 'src/components/ConfigurableShortcutHin
5
5
  import { CtrlOToExpand, SubAgentProvider } from 'src/components/CtrlOToExpand.js';
6
6
  import { Byline } from 'src/components/design-system/Byline.js';
7
7
  import { KeyboardShortcutHint } from 'src/components/design-system/KeyboardShortcutHint.js';
8
- import type { z } from 'zod/v4';
8
+ import { z } from 'zod/v4';
9
9
  import { AgentProgressLine } from '../../components/AgentProgressLine.js';
10
10
  import { FallbackToolUseErrorMessage } from '../../components/FallbackToolUseErrorMessage.js';
11
11
  import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage.js';
@@ -15,7 +15,7 @@ import { MessageResponse } from '../../components/MessageResponse.js';
15
15
  import { ToolUseLoader } from '../../components/ToolUseLoader.js';
16
16
  import { Box, Text } from '../../ink.js';
17
17
  import { getDumpPromptsPath } from '../../services/api/dumpPrompts.js';
18
- import { findToolByName, type Tools } from '../../Tool.js';
18
+ import { buildTool, findToolByName, type Tools } from '../../Tool.js';
19
19
  import type { Message, ProgressMessage } from '../../types/message.js';
20
20
  import type { AgentToolProgress } from '../../types/tools.js';
21
21
  import { count } from '../../utils/array.js';
@@ -540,6 +540,35 @@ export function renderToolUseProgressMessage(progressMessages: ProgressMessage<P
540
540
  lookups: subagentLookups,
541
541
  inProgressToolUseIDs: collapsedInProgressIDs
542
542
  } = buildSubagentLookups(progressMessages.filter((pm): pm is ProgressMessage<AgentToolProgress> => hasProgressMessage(pm.data)).map(pm => pm.data));
543
+
544
+ // Augment tools with fallback entries for sub-agent tools not in the
545
+ // coordinator's tool set. In brain mode the coordinator only has
546
+ // [Agent, AskUserQuestion], but sub-agents call Read/Grep/Bash/Edit/etc.
547
+ // Without fallbacks, findToolByName returns null and renders blank lines.
548
+ const knownToolNames = new Set(tools.map(t => t.name))
549
+ let augmentedTools = tools
550
+ for (const block of subagentLookups.toolUseByToolUseID.values()) {
551
+ if (!knownToolNames.has(block.name)) {
552
+ knownToolNames.add(block.name)
553
+ const fallback = buildTool({
554
+ name: block.name,
555
+ inputSchema: z.object({}).passthrough(),
556
+ description: async () => `Sub-agent tool: ${block.name}`,
557
+ call: async () => ({ data: {} as unknown }) as any,
558
+ maxResultSizeChars: 100_000,
559
+ prompt: async () => '',
560
+ mapToolResultToToolResultBlockParam: (content: unknown, toolUseID: string) => ({
561
+ tool_use_id: toolUseID,
562
+ content: [{ type: 'text' as const, text: String(content) }],
563
+ type: 'tool_result' as const,
564
+ }),
565
+ renderToolUseMessage: () => block.name,
566
+ renderToolResultMessage: () => null,
567
+ })
568
+ augmentedTools = [...augmentedTools, fallback]
569
+ }
570
+ }
571
+
543
572
  return <MessageResponse>
544
573
  <Box flexDirection="column">
545
574
  <SubAgentProvider>
@@ -558,7 +587,7 @@ export function renderToolUseProgressMessage(progressMessages: ProgressMessage<P
558
587
  // content (tool not found, renderToolUseMessage returns null)
559
588
  // doesn't leave a blank line. Tool call headers are single-line
560
589
  // anyway so truncation isn't needed.
561
- return <MessageComponent key={processed.message.uuid} message={processed.message.data.message} lookups={subagentLookups} addMargin={false} tools={tools} commands={[]} verbose={verbose} inProgressToolUseIDs={collapsedInProgressIDs} progressMessagesForMessage={[]} shouldAnimate={false} shouldShowDot={false} style="condensed" isTranscriptMode={false} isStatic={true} />;
590
+ return <MessageComponent key={processed.message.uuid} message={processed.message.data.message} lookups={subagentLookups} addMargin={false} tools={augmentedTools} commands={[]} verbose={verbose} inProgressToolUseIDs={collapsedInProgressIDs} progressMessagesForMessage={[]} shouldAnimate={false} shouldShowDot={false} style="condensed" isTranscriptMode={false} isStatic={true} />;
562
591
  })}
563
592
  </SubAgentProvider>
564
593
  {hiddenToolUseCount > 0 && <Text dimColor>