@chrysb/alphaclaw 0.6.0-beta.2 → 0.6.0-beta.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/lib/public/js/components/models-tab/provider-auth-card.js +18 -1
- package/lib/public/js/components/models-tab/use-models.js +15 -8
- package/lib/public/js/lib/model-config.js +8 -4
- package/lib/server/constants.js +5 -0
- package/lib/server/db/usage/pricing.js +1 -0
- package/lib/server/routes/models.js +12 -1
- package/lib/server/telegram-workspace.js +6 -2
- package/package.json +1 -1
|
@@ -100,6 +100,9 @@ const resolveProfileId = (mode, provider) => {
|
|
|
100
100
|
return `${p}:${mode.profileSuffix || "default"}`;
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
const getCredentialValue = (value) =>
|
|
104
|
+
String(value?.key || value?.token || value?.access || "").trim();
|
|
105
|
+
|
|
103
106
|
const CodexOAuthSection = ({ codexStatus, onRefreshCodex }) => {
|
|
104
107
|
const [authStarted, setAuthStarted] = useState(false);
|
|
105
108
|
const [authWaiting, setAuthWaiting] = useState(false);
|
|
@@ -285,6 +288,18 @@ export const ProviderAuthCard = ({
|
|
|
285
288
|
|
|
286
289
|
const effectiveOrder = getEffectiveOrder(provider);
|
|
287
290
|
const activeProfileId = effectiveOrder?.[0] || null;
|
|
291
|
+
const savedOrder = authOrder[provider] || null;
|
|
292
|
+
|
|
293
|
+
const hasUnsavedProfileChanges = credentialModes.some((mode) => {
|
|
294
|
+
const profileId = resolveProfileId(mode, provider);
|
|
295
|
+
const savedValue = authProfiles.find((p) => p.id === profileId) || null;
|
|
296
|
+
const draftValue = getProfileValue(profileId);
|
|
297
|
+
return getCredentialValue(draftValue) !== getCredentialValue(savedValue);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const hasUnsavedOrderChanges =
|
|
301
|
+
JSON.stringify(effectiveOrder || null) !== JSON.stringify(savedOrder);
|
|
302
|
+
const hasUnsavedChanges = hasUnsavedProfileChanges || hasUnsavedOrderChanges;
|
|
288
303
|
|
|
289
304
|
const isConnected =
|
|
290
305
|
credentialModes.some((mode) => {
|
|
@@ -306,7 +321,9 @@ export const ProviderAuthCard = ({
|
|
|
306
321
|
<h3 class="card-label">${meta.label}</h3>
|
|
307
322
|
${showsInlineOauthStatus && credentialModes.length === 0
|
|
308
323
|
? null
|
|
309
|
-
:
|
|
324
|
+
: hasUnsavedChanges
|
|
325
|
+
? html`<${Badge} tone="warning">Unsaved</${Badge}>`
|
|
326
|
+
: isConnected
|
|
310
327
|
? html`<${Badge} tone="success">Connected</${Badge}>`
|
|
311
328
|
: html`<${Badge} tone="warning">Not configured</${Badge}>`}
|
|
312
329
|
</div>
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
import { showToast } from "../toast.js";
|
|
10
10
|
|
|
11
11
|
let kModelsTabCache = null;
|
|
12
|
+
const getCredentialValue = (value) =>
|
|
13
|
+
String(value?.key || value?.token || value?.access || "").trim();
|
|
12
14
|
|
|
13
15
|
export const useModels = (agentId) => {
|
|
14
16
|
const isScoped = !!agentId;
|
|
@@ -99,10 +101,7 @@ export const useModels = (agentId) => {
|
|
|
99
101
|
const hasProfileChanges = Object.entries(profileEdits).some(
|
|
100
102
|
([id, cred]) => {
|
|
101
103
|
const existing = authProfiles.find((p) => p.id === id);
|
|
102
|
-
|
|
103
|
-
const oldVal =
|
|
104
|
-
existing?.key || existing?.token || existing?.access || "";
|
|
105
|
-
return newVal !== oldVal && newVal !== "";
|
|
104
|
+
return getCredentialValue(cred) !== getCredentialValue(existing);
|
|
106
105
|
},
|
|
107
106
|
);
|
|
108
107
|
const hasOrderChanges = Object.entries(orderEdits).some(
|
|
@@ -199,9 +198,9 @@ export const useModels = (agentId) => {
|
|
|
199
198
|
setSaving(true);
|
|
200
199
|
try {
|
|
201
200
|
const changedProfiles = Object.entries(profileEdits)
|
|
202
|
-
.filter(([, cred]) => {
|
|
203
|
-
const
|
|
204
|
-
return
|
|
201
|
+
.filter(([id, cred]) => {
|
|
202
|
+
const existing = authProfiles.find((p) => p.id === id);
|
|
203
|
+
return getCredentialValue(cred) !== getCredentialValue(existing);
|
|
205
204
|
})
|
|
206
205
|
.map(([id, cred]) => ({ id, ...cred }));
|
|
207
206
|
|
|
@@ -225,7 +224,15 @@ export const useModels = (agentId) => {
|
|
|
225
224
|
} finally {
|
|
226
225
|
setSaving(false);
|
|
227
226
|
}
|
|
228
|
-
}, [
|
|
227
|
+
}, [
|
|
228
|
+
saving,
|
|
229
|
+
primary,
|
|
230
|
+
configuredModels,
|
|
231
|
+
profileEdits,
|
|
232
|
+
orderEdits,
|
|
233
|
+
authProfiles,
|
|
234
|
+
refresh,
|
|
235
|
+
]);
|
|
229
236
|
|
|
230
237
|
const refreshCodexStatus = useCallback(async () => {
|
|
231
238
|
try {
|
|
@@ -11,19 +11,23 @@ export const getAuthProviderFromModelProvider = (provider) => {
|
|
|
11
11
|
export const kFeaturedModelDefs = [
|
|
12
12
|
{
|
|
13
13
|
label: "Opus 4.6",
|
|
14
|
-
preferredKeys: ["anthropic/claude-opus-4-6"
|
|
14
|
+
preferredKeys: ["anthropic/claude-opus-4-6"],
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
label: "Sonnet 4.6",
|
|
18
|
-
preferredKeys: ["anthropic/claude-sonnet-4-6"
|
|
18
|
+
preferredKeys: ["anthropic/claude-sonnet-4-6"],
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
label: "Codex 5.3",
|
|
22
|
-
preferredKeys: ["openai-codex/gpt-5.3-codex"
|
|
22
|
+
preferredKeys: ["openai-codex/gpt-5.3-codex"],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: "GPT-5.4",
|
|
26
|
+
preferredKeys: ["openai-codex/gpt-5.4"],
|
|
23
27
|
},
|
|
24
28
|
{
|
|
25
29
|
label: "Gemini 3.1 Pro",
|
|
26
|
-
preferredKeys: ["google/gemini-3.1-pro-preview"
|
|
30
|
+
preferredKeys: ["google/gemini-3.1-pro-preview"],
|
|
27
31
|
},
|
|
28
32
|
];
|
|
29
33
|
|
package/lib/server/constants.js
CHANGED
|
@@ -106,6 +106,11 @@ const kFallbackOnboardingModels = [
|
|
|
106
106
|
provider: "anthropic",
|
|
107
107
|
label: "Claude Haiku 4.6",
|
|
108
108
|
},
|
|
109
|
+
{
|
|
110
|
+
key: "openai-codex/gpt-5.4",
|
|
111
|
+
provider: "openai-codex",
|
|
112
|
+
label: "GPT-5.4",
|
|
113
|
+
},
|
|
109
114
|
{
|
|
110
115
|
key: "openai-codex/gpt-5.3-codex",
|
|
111
116
|
provider: "openai-codex",
|
|
@@ -8,6 +8,7 @@ const kGlobalModelPricing = {
|
|
|
8
8
|
"claude-sonnet-4-6": { input: 3.0, output: 15.0 },
|
|
9
9
|
"claude-haiku-4-6": { input: 0.8, output: 4.0 },
|
|
10
10
|
"gpt-5": { input: 1.25, output: 10.0 },
|
|
11
|
+
"gpt-5.4": { input: 2.5, output: 10.0 },
|
|
11
12
|
"gpt-5.1-codex": { input: 2.5, output: 10.0 },
|
|
12
13
|
"gpt-5.3-codex": { input: 2.5, output: 10.0 },
|
|
13
14
|
"gpt-4.1": { input: 2.0, output: 8.0 },
|
|
@@ -34,6 +34,11 @@ const registerModelRoutes = ({
|
|
|
34
34
|
return next;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const removeEnvVar = (items, key) => {
|
|
38
|
+
const next = Array.isArray(items) ? [...items] : [];
|
|
39
|
+
return next.filter((entry) => entry.key !== key);
|
|
40
|
+
};
|
|
41
|
+
|
|
37
42
|
const readEnvVarMap = () => {
|
|
38
43
|
if (typeof readEnvFile !== "function") return new Map();
|
|
39
44
|
return new Map(
|
|
@@ -105,10 +110,16 @@ const registerModelRoutes = ({
|
|
|
105
110
|
if (profile?.type !== "api_key") continue;
|
|
106
111
|
const envKey = authProfiles.getEnvVarForApiKeyProvider?.(profile.provider);
|
|
107
112
|
const envValue = String(profile?.key || "").trim();
|
|
108
|
-
if (!envKey
|
|
113
|
+
if (!envKey) continue;
|
|
109
114
|
const prevValue = String(
|
|
110
115
|
nextEnvVars.find((entry) => entry.key === envKey)?.value || "",
|
|
111
116
|
);
|
|
117
|
+
if (!envValue) {
|
|
118
|
+
if (!prevValue) continue;
|
|
119
|
+
nextEnvVars = removeEnvVar(nextEnvVars, envKey);
|
|
120
|
+
changed = true;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
112
123
|
if (prevValue === envValue) continue;
|
|
113
124
|
nextEnvVars = upsertEnvVar(nextEnvVars, envKey, envValue);
|
|
114
125
|
changed = true;
|
|
@@ -88,8 +88,12 @@ const syncConfigForTelegram = ({
|
|
|
88
88
|
const promptTopics = {};
|
|
89
89
|
for (const [threadId, topic] of Object.entries(registryTopics)) {
|
|
90
90
|
const systemPrompt = String(topic?.systemInstructions || "").trim();
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
const topicAgentId = String(topic?.agentId || "").trim();
|
|
92
|
+
if (!systemPrompt && !topicAgentId) continue;
|
|
93
|
+
promptTopics[threadId] = {
|
|
94
|
+
...(systemPrompt ? { systemPrompt } : {}),
|
|
95
|
+
...(topicAgentId ? { agentId: topicAgentId } : {}),
|
|
96
|
+
};
|
|
93
97
|
}
|
|
94
98
|
if (Object.keys(promptTopics).length > 0) {
|
|
95
99
|
targetConfig.groups[groupId].topics = promptTopics;
|