@giovannijecha/jecode 0.3.1 → 0.4.0
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/README.md +23 -16
- package/dist/command-settings.js +19 -0
- package/dist/commands.js +8 -12
- package/dist/credential-commands.js +63 -80
- package/dist/credentials.js +7 -1
- package/dist/model-command.js +171 -0
- package/dist/permission-command.js +52 -53
- package/dist/provider-commands.js +71 -228
- package/dist/provider-errors.js +4 -3
- package/dist/provider-label.js +2 -2
- package/dist/settings-command.js +43 -98
- package/dist/tui/app-workflows.js +10 -5
- package/dist/tui/app.js +1 -1
- package/dist/tui/components/composer.js +1 -1
- package/dist/tui/components/footer.js +1 -1
- package/dist/tui/components/menu.js +27 -15
- package/dist/tui/components/messages.js +2 -2
- package/dist/tui/components/prompt.js +2 -2
- package/dist/tui/components/status.js +2 -2
- package/dist/tui/components/tool.js +6 -52
- package/dist/tui/editor.js +54 -7
- package/dist/tui/feedback.js +2 -2
- package/dist/tui/field.js +1 -1
- package/dist/tui/help.js +4 -1
- package/dist/tui/input.js +4 -0
- package/dist/tui/keys.js +14 -3
- package/dist/tui/overlay.js +6 -0
- package/dist/tui/picker.js +26 -10
- package/dist/tui/session-view.js +2 -2
- package/dist/tui/view.js +1 -1
- package/dist/ui/inline.js +2 -2
- package/dist/ui/markdown.js +7 -7
- package/dist/ui/theme.js +4 -4
- package/package.json +1 -1
|
@@ -9,59 +9,55 @@ export async function permissionsCommand(session, host) {
|
|
|
9
9
|
}
|
|
10
10
|
let selected = 0;
|
|
11
11
|
while (true) {
|
|
12
|
-
const
|
|
13
|
-
const index = await choose(permissionsPicker(tools, session.palette, selected));
|
|
12
|
+
const index = await choose(permissionControlPicker(control, host, selected));
|
|
14
13
|
if (index === undefined)
|
|
15
14
|
return;
|
|
16
|
-
const tool =
|
|
15
|
+
const tool = control.listTools()[index];
|
|
17
16
|
if (tool === undefined)
|
|
18
17
|
return;
|
|
19
18
|
selected = index;
|
|
20
|
-
|
|
19
|
+
if (tool.locked) {
|
|
20
|
+
lockedNotice(tool.name, host);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (tool.remembered > 0) {
|
|
24
|
+
await reviewGrants(tool.name, control, choose, session.palette);
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
|
-
export function permissionsPicker(tools,
|
|
24
|
-
const launchOverride = tools.some((tool) => tool.locked);
|
|
28
|
+
export function permissionsPicker(tools, index = 0, adjust) {
|
|
25
29
|
return {
|
|
26
|
-
title:
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
title: [],
|
|
31
|
+
options: tools.map((tool) => {
|
|
32
|
+
const description = toolDescription(tool);
|
|
33
|
+
return {
|
|
34
|
+
label: tool.name,
|
|
35
|
+
...(description === undefined ? {} : { description }),
|
|
36
|
+
value: tool.locked ? `${tool.mode} · locked` : tool.mode,
|
|
37
|
+
adjustable: !tool.locked,
|
|
38
|
+
};
|
|
39
|
+
}),
|
|
40
|
+
visible: tools.length,
|
|
41
|
+
...(adjust === undefined ? {} : { adjust }),
|
|
29
42
|
index: Math.min(Math.max(0, index), Math.max(0, tools.length - 1)),
|
|
30
43
|
};
|
|
31
44
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
? "Session only · ask is the safe default"
|
|
48
|
-
: "Session only · deny hides this tool from the model",
|
|
49
|
-
options: [
|
|
50
|
-
...modes.map((mode) => ({ label: mode, hint: modeHint(mode, tool.dangerous) })),
|
|
51
|
-
...(grants.length === 0
|
|
52
|
-
? []
|
|
53
|
-
: [{ label: "remembered approvals", hint: String(grants.length) }]),
|
|
54
|
-
],
|
|
55
|
-
index: Math.max(0, modes.indexOf(tool.mode)),
|
|
45
|
+
function permissionControlPicker(control, host, selected) {
|
|
46
|
+
return permissionsPicker(control.listTools(), selected, (index, step) => {
|
|
47
|
+
const tool = control.listTools()[index];
|
|
48
|
+
if (tool === undefined)
|
|
49
|
+
return permissionControlPicker(control, host, selected);
|
|
50
|
+
if (tool.locked) {
|
|
51
|
+
lockedNotice(tool.name, host);
|
|
52
|
+
return permissionControlPicker(control, host, index);
|
|
53
|
+
}
|
|
54
|
+
const modes = modesFor(tool);
|
|
55
|
+
const at = Math.max(0, modes.indexOf(tool.mode));
|
|
56
|
+
const next = modes[(at + step + modes.length) % modes.length];
|
|
57
|
+
if (next !== undefined)
|
|
58
|
+
control.set(tool.name, next);
|
|
59
|
+
return permissionControlPicker(control, host, index);
|
|
56
60
|
});
|
|
57
|
-
if (index === undefined)
|
|
58
|
-
return;
|
|
59
|
-
const mode = modes[index];
|
|
60
|
-
if (mode !== undefined) {
|
|
61
|
-
control.set(tool.name, mode);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
await reviewGrants(tool.name, control, choose, pal);
|
|
65
61
|
}
|
|
66
62
|
async function reviewGrants(tool, control, choose, pal) {
|
|
67
63
|
let selected = 0;
|
|
@@ -75,7 +71,6 @@ async function reviewGrants(tool, control, choose, pal) {
|
|
|
75
71
|
];
|
|
76
72
|
const index = await choose({
|
|
77
73
|
title: heading("remembered", tool, pal),
|
|
78
|
-
description: "Allowed without asking · this session",
|
|
79
74
|
options,
|
|
80
75
|
index: Math.min(selected, options.length - 1),
|
|
81
76
|
});
|
|
@@ -92,16 +87,20 @@ async function reviewGrants(tool, control, choose, pal) {
|
|
|
92
87
|
selected = index;
|
|
93
88
|
}
|
|
94
89
|
}
|
|
95
|
-
function
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
function modesFor(tool) {
|
|
91
|
+
return tool.dangerous ? ["ask", "allow", "deny"] : ["allow", "deny"];
|
|
92
|
+
}
|
|
93
|
+
function toolDescription(tool) {
|
|
94
|
+
const parts = [
|
|
95
|
+
tool.dangerous ? undefined : "read only",
|
|
96
|
+
tool.remembered === 0 ? undefined : `${tool.remembered} remembered`,
|
|
97
|
+
].filter((part) => part !== undefined);
|
|
98
|
+
return parts.length === 0 ? undefined : parts.join(" · ");
|
|
100
99
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
function lockedNotice(tool, host) {
|
|
101
|
+
host.emit({
|
|
102
|
+
kind: "notice",
|
|
103
|
+
text: `restart without --auto-approve to change ${tool}`,
|
|
104
|
+
tone: "warn",
|
|
105
|
+
});
|
|
107
106
|
}
|
|
@@ -1,227 +1,81 @@
|
|
|
1
|
-
// Provider and
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
// Provider access and connection management. Runtime selection lives in /models.
|
|
2
|
+
import { saveCommandSettings } from "./command-settings.js";
|
|
3
|
+
import { apiKeyCommand } from "./credential-commands.js";
|
|
4
|
+
import { credentialSource } from "./credentials.js";
|
|
5
|
+
import { ollamaConnectionHint, ollamaConnectionSetting, } from "./ollama-settings-command.js";
|
|
6
|
+
import { openAIAccountHint } from "./openai-account.js";
|
|
7
|
+
import { openAIAccountCommand } from "./openai-account-command.js";
|
|
7
8
|
import { providerLabel } from "./provider-label.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* than the row would be worth hidden. A blocked choice opens the same masked
|
|
15
|
-
* credential flow used by settings, and cancellation leaves the old choice.
|
|
16
|
-
*/
|
|
17
|
-
export async function providersCommand(session, host, behavior = {}) {
|
|
9
|
+
import { PROVIDERS } from "./providers/index.js";
|
|
10
|
+
import { ollamaConnection } from "./providers/ollama.js";
|
|
11
|
+
import { heading } from "./tui/picker.js";
|
|
12
|
+
const OLLAMA_KEY = "OLLAMA_API_KEY";
|
|
13
|
+
/** The single control plane for API keys, OAuth accounts, and Ollama endpoints. */
|
|
14
|
+
export async function providersCommand(session, host) {
|
|
18
15
|
const choose = chooser(host);
|
|
19
16
|
if (choose === undefined)
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
if (index === undefined)
|
|
32
|
-
return false;
|
|
33
|
-
const chosen = PROVIDERS[index];
|
|
34
|
-
if (chosen === undefined)
|
|
35
|
-
return false;
|
|
36
|
-
// Picking the provider already in use is not a no-op when it cannot run:
|
|
37
|
-
// it is how the user asks to fix the reason it cannot.
|
|
38
|
-
if (chosen.id === session.provider.id) {
|
|
39
|
-
if (!(await ensureProviderAuthentication(chosen, session, host)))
|
|
40
|
-
return false;
|
|
41
|
-
return session.model === ""
|
|
42
|
-
? modelsCommand(session, host, { announce: false, save: behavior.save })
|
|
43
|
-
: true;
|
|
44
|
-
}
|
|
45
|
-
// A provider that cannot run is worth one offer to fix it, here, rather
|
|
46
|
-
// than a note telling the user to leave and export something.
|
|
47
|
-
const blocked = chosen.blocked();
|
|
48
|
-
if (blocked !== undefined) {
|
|
49
|
-
await ensureProviderAuthentication(chosen, session, host);
|
|
50
|
-
const still = chosen.blocked();
|
|
51
|
-
if (still !== undefined) {
|
|
52
|
-
host.emit({
|
|
53
|
-
kind: "notice",
|
|
54
|
-
text: `${providerLabel(chosen.id)} still needs ${authenticationNeed(chosen)} · provider unchanged`,
|
|
55
|
-
tone: "warn",
|
|
56
|
-
});
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const before = {
|
|
61
|
-
provider: session.provider,
|
|
62
|
-
model: session.model,
|
|
63
|
-
providerId: session.config.providerId,
|
|
64
|
-
configModel: session.config.model,
|
|
65
|
-
effort: session.config.effort,
|
|
66
|
-
};
|
|
67
|
-
session.provider = chosen;
|
|
68
|
-
// The model belonged to the old provider. Carrying it across would send
|
|
69
|
-
// `claude-sonnet-5` to OpenAI and call the 404 a bug in the provider.
|
|
70
|
-
session.model = readSettings().models?.[chosen.id] ?? chosen.defaultModel;
|
|
71
|
-
session.config.providerId = chosen.id;
|
|
72
|
-
session.config.model = session.model;
|
|
73
|
-
if (session.model === "") {
|
|
74
|
-
if (!(await modelsCommand(session, host, { announce: false, save: false }))) {
|
|
75
|
-
restoreProvider(session, before);
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
const alignment = await alignEffort(session, host);
|
|
81
|
-
if (!alignment.ok) {
|
|
82
|
-
restoreProvider(session, before);
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
if (behavior.save !== false) {
|
|
87
|
-
const saved = readSettings();
|
|
88
|
-
const models = { ...saved.models };
|
|
89
|
-
if (session.model !== "")
|
|
90
|
-
models[chosen.id] = session.model;
|
|
91
|
-
const patch = {
|
|
92
|
-
provider: chosen.id,
|
|
93
|
-
models,
|
|
94
|
-
...(session.config.effort === before.effort ? {} : { effort: session.config.effort }),
|
|
95
|
-
};
|
|
96
|
-
if (!(await saveDefaults(host, patch))) {
|
|
97
|
-
restoreProvider(session, before);
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (behavior.announce !== false) {
|
|
102
|
-
host.emit({
|
|
103
|
-
kind: "notice",
|
|
104
|
-
text: session.model === "" ? `provider · ${chosen.id} · pick a model` : `provider · ${chosen.id}`,
|
|
105
|
-
tone: "info",
|
|
17
|
+
return;
|
|
18
|
+
let selected = Math.max(0, PROVIDERS.findIndex((provider) => provider.id === session.provider.id));
|
|
19
|
+
while (true) {
|
|
20
|
+
const index = await choose({
|
|
21
|
+
title: [],
|
|
22
|
+
options: PROVIDERS.map((provider) => ({
|
|
23
|
+
label: providerLabel(provider.id),
|
|
24
|
+
value: providerAccessHint(provider),
|
|
25
|
+
})),
|
|
26
|
+
index: selected,
|
|
106
27
|
});
|
|
28
|
+
if (index === undefined)
|
|
29
|
+
return;
|
|
30
|
+
const provider = PROVIDERS[index];
|
|
31
|
+
if (provider === undefined)
|
|
32
|
+
return;
|
|
33
|
+
selected = index;
|
|
34
|
+
await manageProvider(provider, session, host);
|
|
35
|
+
// Esc closes only the nested provider flow. Ctrl+C also settles that
|
|
36
|
+
// picker, but aborts the command signal and must not reopen the parent.
|
|
37
|
+
throwIfAborted(host.signal);
|
|
107
38
|
}
|
|
108
|
-
return true;
|
|
109
39
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
host.emit({
|
|
126
|
-
kind: "notice",
|
|
127
|
-
text: `${providerLabel(provider.id)} still needs ${authenticationNeed(provider)}`,
|
|
128
|
-
tone: "warn",
|
|
129
|
-
});
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
host.status?.(`Asking ${provider.id}`);
|
|
134
|
-
let ids;
|
|
135
|
-
try {
|
|
136
|
-
ids = await provider.models(host.signal, (status) => host.status?.(status));
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
host.emit({
|
|
140
|
-
kind: "notice",
|
|
141
|
-
text: providerFailure(provider, error, true),
|
|
142
|
-
tone: "error",
|
|
143
|
-
});
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
finally {
|
|
147
|
-
host.status?.(undefined);
|
|
148
|
-
}
|
|
149
|
-
if (ids.length === 0) {
|
|
150
|
-
host.emit({ kind: "notice", text: `${provider.id} offers no models`, tone: "warn" });
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
const index = await choose({
|
|
154
|
-
title: heading("model", provider.id, session.palette),
|
|
155
|
-
options: ids.map((id) => ({ label: id })),
|
|
156
|
-
searchable: true,
|
|
157
|
-
query: "",
|
|
158
|
-
index: Math.max(0, ids.indexOf(session.model)),
|
|
159
|
-
});
|
|
160
|
-
if (index === undefined)
|
|
161
|
-
return false;
|
|
162
|
-
const chosen = ids[index];
|
|
163
|
-
if (chosen === undefined)
|
|
164
|
-
return false;
|
|
165
|
-
const before = {
|
|
166
|
-
model: session.model,
|
|
167
|
-
configModel: session.config.model,
|
|
168
|
-
effort: session.config.effort,
|
|
169
|
-
};
|
|
170
|
-
session.model = chosen;
|
|
171
|
-
session.config.model = chosen;
|
|
172
|
-
const alignment = await alignEffort(session, host);
|
|
173
|
-
if (!alignment.ok) {
|
|
174
|
-
session.model = before.model;
|
|
175
|
-
session.config.model = before.configModel;
|
|
176
|
-
session.config.effort = before.effort;
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
if (behavior.save !== false) {
|
|
180
|
-
const saved = readSettings();
|
|
181
|
-
const models = { ...saved.models, [provider.id]: chosen };
|
|
182
|
-
const patch = {
|
|
183
|
-
models,
|
|
184
|
-
...(session.config.effort === before.effort ? {} : { effort: session.config.effort }),
|
|
185
|
-
};
|
|
186
|
-
if (!(await saveDefaults(host, patch))) {
|
|
187
|
-
session.model = before.model;
|
|
188
|
-
session.config.model = before.configModel;
|
|
189
|
-
session.config.effort = before.effort;
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
40
|
+
export function providerAccessHint(provider) {
|
|
41
|
+
if (provider.id === "ollama") {
|
|
42
|
+
const connection = ollamaConnection();
|
|
43
|
+
if (connection.loopback)
|
|
44
|
+
return `${ollamaConnectionHint()} · no key needed`;
|
|
45
|
+
return `${ollamaConnectionHint()} · API key ${credentialSource(OLLAMA_KEY) ?? "missing"}`;
|
|
46
|
+
}
|
|
47
|
+
if (provider.auth.kind === "oauth")
|
|
48
|
+
return openAIAccountHint();
|
|
49
|
+
return `API key · ${credentialSource(provider.auth.keyVar) ?? "missing"}`;
|
|
50
|
+
}
|
|
51
|
+
async function manageProvider(provider, session, host) {
|
|
52
|
+
if (provider.id === "ollama") {
|
|
53
|
+
await ollamaProviderCommand(session, host);
|
|
54
|
+
return;
|
|
192
55
|
}
|
|
193
|
-
if (
|
|
194
|
-
|
|
56
|
+
if (provider.auth.kind === "oauth") {
|
|
57
|
+
await openAIAccountCommand(session, host);
|
|
58
|
+
return;
|
|
195
59
|
}
|
|
196
|
-
|
|
60
|
+
await apiKeyCommand(provider.auth.keyVar, providerLabel(provider.id), session, host);
|
|
197
61
|
}
|
|
198
|
-
function
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
62
|
+
async function ollamaProviderCommand(session, host) {
|
|
63
|
+
if (host.choose === undefined)
|
|
64
|
+
return;
|
|
65
|
+
const index = await host.choose({
|
|
66
|
+
title: heading("Ollama", "access and connection", session.palette),
|
|
67
|
+
options: [
|
|
68
|
+
{ label: "connection", hint: ollamaConnectionHint() },
|
|
69
|
+
{ label: "API key", hint: credentialSource(OLLAMA_KEY) ?? "missing" },
|
|
70
|
+
],
|
|
71
|
+
index: 0,
|
|
72
|
+
});
|
|
73
|
+
if (index === 0) {
|
|
74
|
+
await ollamaConnectionSetting(session, host, (patch) => saveCommandSettings(host, patch));
|
|
211
75
|
}
|
|
212
|
-
|
|
213
|
-
host
|
|
214
|
-
kind: "notice",
|
|
215
|
-
text: providerFailure(session.provider, error, true),
|
|
216
|
-
tone: "error",
|
|
217
|
-
});
|
|
218
|
-
return { ok: false };
|
|
76
|
+
else if (index === 1) {
|
|
77
|
+
await apiKeyCommand(OLLAMA_KEY, "Ollama", session, host);
|
|
219
78
|
}
|
|
220
|
-
const adjusted = compatibleEffort(session.config.effort, supported);
|
|
221
|
-
if (adjusted === undefined || adjusted === session.config.effort)
|
|
222
|
-
return { ok: true };
|
|
223
|
-
session.config.effort = adjusted;
|
|
224
|
-
return { ok: true, adjusted };
|
|
225
79
|
}
|
|
226
80
|
function chooser(host) {
|
|
227
81
|
if (host.choose === undefined) {
|
|
@@ -229,19 +83,8 @@ function chooser(host) {
|
|
|
229
83
|
}
|
|
230
84
|
return host.choose;
|
|
231
85
|
}
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
return
|
|
235
|
-
|
|
236
|
-
await host.saveSettings(patch);
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
catch (error) {
|
|
240
|
-
host.emit({
|
|
241
|
-
kind: "notice",
|
|
242
|
-
text: `could not save settings · ${error.message}`,
|
|
243
|
-
tone: "error",
|
|
244
|
-
});
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
86
|
+
function throwIfAborted(signal) {
|
|
87
|
+
if (signal?.aborted !== true)
|
|
88
|
+
return;
|
|
89
|
+
throw signal.reason instanceof Error ? signal.reason : new Error("interrupted");
|
|
247
90
|
}
|
package/dist/provider-errors.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Actionable provider failures for user-facing command and turn surfaces.
|
|
2
|
+
import { providerLabel } from "./provider-label.js";
|
|
2
3
|
const CONNECTION_FAILURE = /network error calling|timed out waiting for response headers|response body was idle/i;
|
|
3
4
|
export function providerFailure(provider, error, labelProvider = false) {
|
|
4
5
|
if (provider.id === "ollama" && CONNECTION_FAILURE.test(error.message)) {
|
|
5
6
|
return provider.location?.() === "local"
|
|
6
|
-
? "Ollama is not reachable on this computer · start Ollama or choose cloud in /
|
|
7
|
-
: "Ollama is not reachable · check its connection in /
|
|
7
|
+
? "Ollama is not reachable on this computer · start Ollama or choose cloud in /providers"
|
|
8
|
+
: "Ollama is not reachable · check its connection in /providers";
|
|
8
9
|
}
|
|
9
|
-
return labelProvider ? `${provider.id}: ${error.message}` : error.message;
|
|
10
|
+
return labelProvider ? `${providerLabel(provider.id)}: ${error.message}` : error.message;
|
|
10
11
|
}
|
package/dist/provider-label.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
export function providerLabel(id) {
|
|
3
3
|
switch (id) {
|
|
4
4
|
case "anthropic": return "Anthropic";
|
|
5
|
-
case "openai": return "OpenAI";
|
|
6
|
-
case "openai-codex": return "
|
|
5
|
+
case "openai": return "OpenAI API";
|
|
6
|
+
case "openai-codex": return "ChatGPT";
|
|
7
7
|
case "ollama": return "Ollama";
|
|
8
8
|
default: return id === "" ? "Provider" : `${id[0]?.toUpperCase() ?? ""}${id.slice(1)}`;
|
|
9
9
|
}
|