@lazyingart/agintiflow 0.16.1 → 0.16.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/README.md +1 -1
- package/package.json +1 -1
- package/public/app.js +3 -0
- package/public/index.html +6 -0
- package/public/styles.css +17 -0
- package/scripts/smoke-auth.js +4 -2
- package/src/auth-onboarding.js +22 -2
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ aginti --list-profiles
|
|
|
46
46
|
aginti --sandbox-status
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
On first interactive use, if no main model key is detected, `aginti` opens an auth wizard. Use Up/Down to choose DeepSeek, OpenAI, or Qwen, paste the key, and press Enter to save it to the project-local ignored file `.aginti/.env` with `0600` permissions. The wizard then offers the optional auxiliary image key; press Esc to skip. You can rerun it even when keys already exist:
|
|
49
|
+
On first interactive use, if no main model key is detected, `aginti` opens an auth wizard. Use Up/Down to choose DeepSeek, OpenAI, or Qwen, paste the key, and press Enter to save it to the project-local ignored file `.aginti/.env` with `0600` permissions. The wizard points to DeepSeek keys at `https://platform.deepseek.com/api_keys` and OpenAI keys at `https://platform.openai.com/api-keys`. It then offers the optional auxiliary image key; press Esc to skip. You can rerun it even when keys already exist:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
52
|
aginti auth
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -25,6 +25,9 @@ const translations = {
|
|
|
25
25
|
"DeepSeek/OpenAI/Qwen keys are missing. Use mock mode, export an env var, or save a project-local model key.",
|
|
26
26
|
setupEnvHelp:
|
|
27
27
|
"Env vars: DEEPSEEK_API_KEY, OPENAI_API_KEY, QWEN_API_KEY, LLM_API_KEY, and optional GRSAI for image generation. Mock mode remains available for local tests.",
|
|
28
|
+
setupKeyLinksLabel: "Get keys:",
|
|
29
|
+
deepseekKeyLink: "DeepSeek API keys",
|
|
30
|
+
openaiKeyLink: "OpenAI API keys",
|
|
28
31
|
setupProviderLabel: "Provider",
|
|
29
32
|
setupKeyLabel: "API key",
|
|
30
33
|
saveKeyButton: "Save local key",
|
package/public/index.html
CHANGED
|
@@ -50,6 +50,12 @@
|
|
|
50
50
|
<p class="subtle" data-i18n="setupEnvHelp">
|
|
51
51
|
Env vars: DEEPSEEK_API_KEY, OPENAI_API_KEY, QWEN_API_KEY, or LLM_API_KEY. Mock mode remains available for local tests.
|
|
52
52
|
</p>
|
|
53
|
+
<p class="subtle key-links">
|
|
54
|
+
<span data-i18n="setupKeyLinksLabel">Get keys:</span>
|
|
55
|
+
<a href="https://platform.deepseek.com/api_keys" target="_blank" rel="noreferrer" data-i18n="deepseekKeyLink">DeepSeek API keys</a>
|
|
56
|
+
<span aria-hidden="true">·</span>
|
|
57
|
+
<a href="https://platform.openai.com/api-keys" target="_blank" rel="noreferrer" data-i18n="openaiKeyLink">OpenAI API keys</a>
|
|
58
|
+
</p>
|
|
53
59
|
</div>
|
|
54
60
|
<div class="grid">
|
|
55
61
|
<label>
|
package/public/styles.css
CHANGED
|
@@ -137,6 +137,23 @@ h1 {
|
|
|
137
137
|
overflow-wrap: anywhere;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
.setup-card .key-links {
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-wrap: wrap;
|
|
143
|
+
gap: 6px;
|
|
144
|
+
align-items: center;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.setup-card .key-links a {
|
|
148
|
+
color: #075985;
|
|
149
|
+
font-weight: 750;
|
|
150
|
+
text-decoration: none;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.setup-card .key-links a:hover {
|
|
154
|
+
text-decoration: underline;
|
|
155
|
+
}
|
|
156
|
+
|
|
140
157
|
.setup-card[hidden] {
|
|
141
158
|
display: none;
|
|
142
159
|
}
|
package/scripts/smoke-auth.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "node:fs/promises";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { normalizeAuthProvider } from "../src/auth-onboarding.js";
|
|
7
|
+
import { authProviderKeyHelp, authProviderKeyUrl, normalizeAuthProvider } from "../src/auth-onboarding.js";
|
|
8
8
|
import { getProviderDefaults } from "../src/model-routing.js";
|
|
9
9
|
import { providerKeyStatus, setProviderKey } from "../src/project.js";
|
|
10
10
|
|
|
@@ -53,6 +53,8 @@ async function runCli(args, stdin = "") {
|
|
|
53
53
|
try {
|
|
54
54
|
assert(normalizeAuthProvider("auxilliary") === "grsai", "auxilliary alias did not normalize to grsai");
|
|
55
55
|
assert(normalizeAuthProvider("qwen") === "qwen", "qwen provider did not normalize");
|
|
56
|
+
assert(authProviderKeyUrl("deepseek") === "https://platform.deepseek.com/api_keys", "DeepSeek key URL is missing");
|
|
57
|
+
assert(authProviderKeyHelp("openai").includes("https://platform.openai.com/api-keys"), "OpenAI key help is missing");
|
|
56
58
|
const qwenDefaults = getProviderDefaults("qwen");
|
|
57
59
|
assert(qwenDefaults.provider === "qwen" && qwenDefaults.model, "qwen provider defaults are not available");
|
|
58
60
|
|
|
@@ -75,7 +77,7 @@ try {
|
|
|
75
77
|
{
|
|
76
78
|
ok: true,
|
|
77
79
|
projectRoot: tempRoot,
|
|
78
|
-
checks: ["normalize-auth-provider", "qwen-defaults", "qwen-key-status", "cli-key-status-redacted"],
|
|
80
|
+
checks: ["normalize-auth-provider", "provider-key-links", "qwen-defaults", "qwen-key-status", "cli-key-status-redacted"],
|
|
79
81
|
},
|
|
80
82
|
null,
|
|
81
83
|
2
|
package/src/auth-onboarding.js
CHANGED
|
@@ -10,12 +10,14 @@ export const MAIN_AUTH_PROVIDERS = [
|
|
|
10
10
|
label: "DeepSeek",
|
|
11
11
|
keyName: "DEEPSEEK_API_KEY",
|
|
12
12
|
description: "default fast/pro route",
|
|
13
|
+
keyUrl: "https://platform.deepseek.com/api_keys",
|
|
13
14
|
},
|
|
14
15
|
{
|
|
15
16
|
id: "openai",
|
|
16
17
|
label: "OpenAI",
|
|
17
18
|
keyName: "OPENAI_API_KEY",
|
|
18
19
|
description: "OpenAI-compatible fallback",
|
|
20
|
+
keyUrl: "https://platform.openai.com/api-keys",
|
|
19
21
|
},
|
|
20
22
|
{
|
|
21
23
|
id: "qwen",
|
|
@@ -55,6 +57,19 @@ function providerLabel(provider = "") {
|
|
|
55
57
|
return match?.label || provider;
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
export function authProviderKeyUrl(provider = "") {
|
|
61
|
+
const normalized = normalizeAuthProvider(provider, "");
|
|
62
|
+
const match = [...MAIN_AUTH_PROVIDERS, AUXILIARY_AUTH_PROVIDER].find((item) => item.id === normalized);
|
|
63
|
+
return match?.keyUrl || "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function authProviderKeyHelp(provider = "") {
|
|
67
|
+
const normalized = normalizeAuthProvider(provider, "");
|
|
68
|
+
const label = providerLabel(normalized);
|
|
69
|
+
const url = authProviderKeyUrl(normalized);
|
|
70
|
+
return url ? `Get ${label} API key: ${url}` : "";
|
|
71
|
+
}
|
|
72
|
+
|
|
58
73
|
class MutedWritable extends Writable {
|
|
59
74
|
constructor(target) {
|
|
60
75
|
super();
|
|
@@ -144,17 +159,21 @@ export async function promptHidden(promptText) {
|
|
|
144
159
|
}
|
|
145
160
|
|
|
146
161
|
function renderProviderPicker({ providers, selected, title, status }) {
|
|
162
|
+
const keyLinks = providers
|
|
163
|
+
.filter((provider) => provider.keyUrl)
|
|
164
|
+
.map((provider) => `${provider.label}: ${provider.keyUrl}`);
|
|
147
165
|
const lines = [
|
|
148
166
|
`\n${title}`,
|
|
149
167
|
"Use Up/Down to choose, Enter to confirm, Esc to go back/skip.",
|
|
150
168
|
`Current key status: ${status}`,
|
|
169
|
+
keyLinks.length ? `API key pages: ${keyLinks.join(" · ")}` : "",
|
|
151
170
|
"",
|
|
152
171
|
...providers.map((provider, index) => {
|
|
153
172
|
const cursor = index === selected ? ">" : " ";
|
|
154
173
|
return `${cursor} ${provider.label.padEnd(10)} ${provider.keyName.padEnd(16)} ${provider.description}`;
|
|
155
174
|
}),
|
|
156
175
|
];
|
|
157
|
-
return lines.join("\n");
|
|
176
|
+
return lines.filter((line, index) => line || index > 2).join("\n");
|
|
158
177
|
}
|
|
159
178
|
|
|
160
179
|
export async function chooseAuthProvider({
|
|
@@ -295,7 +314,8 @@ export async function runAuthWizard(projectRoot = process.cwd(), options = {}) {
|
|
|
295
314
|
|
|
296
315
|
if (mainProvider) {
|
|
297
316
|
const current = status[mainProvider] ? "currently available; paste a new key to replace, or Esc to keep existing" : "missing";
|
|
298
|
-
const
|
|
317
|
+
const keyHelp = authProviderKeyHelp(mainProvider);
|
|
318
|
+
const prompt = `${keyHelp ? `${keyHelp}\n` : ""}${providerLabel(mainProvider)} main API key (${current}) [hidden]: `;
|
|
299
319
|
const secret = await promptSecret(prompt, { allowEscape: true });
|
|
300
320
|
if (secret.value) {
|
|
301
321
|
const result = await setProviderKey(projectRoot, mainProvider, secret.value);
|