@aliyunrds/ctxdb 1.0.8-beta.2 → 1.0.8-beta.4
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 +47 -10
- package/dist/{chunk-X75B57M2.js → chunk-5DGRNP55.js} +1 -1
- package/dist/{chunk-R67JELM7.js → chunk-5ITT5GSP.js} +3 -2
- package/dist/{chunk-5ZSZMN2T.js → chunk-6MEWI73Y.js} +2 -2
- package/dist/{chunk-LYHGJOHM.js → chunk-76AXXLVE.js} +4 -3
- package/dist/{chunk-4FCZ2TZM.js → chunk-O6MKQ2I3.js} +1 -1
- package/dist/{chunk-ULAWTBBC.js → chunk-OEZM2ZYA.js} +1 -1
- package/dist/{chunk-VIG4SYLU.js → chunk-PI2SUS3M.js} +1 -1
- package/dist/{chunk-DMS5YHIK.js → chunk-SVO6H62S.js} +69 -28
- package/dist/{chunk-H33NUAHP.js → chunk-WJTV7JNR.js} +13 -6
- package/dist/{chunk-CULTDVI2.js → chunk-ZW7YXNJ6.js} +1 -1
- package/dist/cli/main.js +303 -81
- package/dist/hooks/hermes-post-llm-call.js +9 -7
- package/dist/hooks/hermes-pre-llm-call.js +12 -11
- package/dist/hooks/pre-tool-use.js +1 -1
- package/dist/hooks/session-start.js +11 -10
- package/dist/hooks/stop.js +9 -7
- package/dist/hooks/user-prompt-submit.js +11 -10
- package/dist/opencode/index.js +630 -41
- package/dist/workers/version-check.js +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,9 +17,42 @@ Config and logs live under `~/.ctxdb/`. `~/.ctxdb/ctxdb.json` is one file, but r
|
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
20
|
+
### Public Device Flow login (requires the enabled Core/API phase 2 service)
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
ctxdb login --agent qoder --server https://<core-host> --no-browser
|
|
24
|
+
# Complete the displayed user code through the console/independent POP test client.
|
|
25
|
+
ctxdb auth status --agent qoder --json
|
|
26
|
+
ctxdb setup --agent qoder
|
|
27
|
+
ctxdb logout --agent qoder --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Public login uses Core Device Flow only; it never calls POP, starts a localhost callback,
|
|
31
|
+
or uses the internal login server. `--device-code` explicitly selects the same default flow.
|
|
32
|
+
Device Flow always uses `default`, following the current Member permissions and resource ACLs.
|
|
33
|
+
`login` does not accept `--scope`; creation and approval do not send a scope selector.
|
|
34
|
+
Login does not install hooks/skills. Run setup separately for each selected Agent.
|
|
35
|
+
|
|
36
|
+
Each profile contains only an `oauth_credential_ref`; AT/RT live in owner-only files under
|
|
37
|
+
`~/.ctxdb/oauth-credentials/`. `CTXDB_CONFIG_PATH` can select an isolated configuration file;
|
|
38
|
+
the OAuth directory is its sibling. CLI, Hooks and OpenCode share a cross-process, single-flight
|
|
39
|
+
refresh implementation. A lost refresh response or crashed refresh requires a new login, not
|
|
40
|
+
a retry of the old RT. Managed failure/logout never falls back to an API key or another profile.
|
|
41
|
+
Re-login replaces only the selected profile; logout reports remote-revoke failure separately.
|
|
42
|
+
AT/RT must not be copied into Agent/Skill configuration or handed to a sandbox.
|
|
43
|
+
|
|
44
|
+
The optional sibling `device-environments.json` (`version: 1`, `environments: [{core_url,
|
|
45
|
+
authorization_url}]`) maps a Core origin to a deployment-approved HTTPS console page.
|
|
46
|
+
CLI appends only `user_code` to that locally configured URL. There is no server discovery or
|
|
47
|
+
invented default console page. Without a mapping, the code can be used with the independent POP
|
|
48
|
+
test client. This phase never opens a browser automatically; `--no-browser` is supported.
|
|
49
|
+
|
|
50
|
+
POSIX uses private files/directories; Windows validates an owner-only ACL using local PowerShell.
|
|
51
|
+
Native Windows acceptance remains separate from the macOS local test record.
|
|
52
|
+
|
|
20
53
|
### Internal browser-login distribution
|
|
21
54
|
|
|
22
|
-
The same source also builds `@ali/ctxdb-internal`.
|
|
55
|
+
The same source also builds `@ali/ctxdb-internal`. Its existing prototype
|
|
23
56
|
adds `ctxdb login --server <url>`, `ctxdb login --device-code`, `ctxdb logout`,
|
|
24
57
|
and `ctxdb auth status`. The default login uses a browser loopback callback;
|
|
25
58
|
`--device-code` supports remote or headless terminals. Both methods discover a
|
|
@@ -31,17 +64,19 @@ Internal login stores its single active connection in owner-only
|
|
|
31
64
|
without writing an `api_key` field into the Agent or default profile; an
|
|
32
65
|
existing field in either updated profile is removed. At runtime this managed
|
|
33
66
|
credential overrides the API key and DATA URL in the existing v2
|
|
34
|
-
`~/.ctxdb/ctxdb.json`; `CTXDB_API_KEY
|
|
35
|
-
priority overrides.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`
|
|
67
|
+
`~/.ctxdb/ctxdb.json`; `CTXDB_ACCESS_TOKEN`, `CTXDB_API_KEY`, and
|
|
68
|
+
`CTXDB_BASE_URL` remain higher-priority overrides. `ctxdb login` rejects all
|
|
69
|
+
three while `ctxdb logout` rejects the two credential overrides, so command
|
|
70
|
+
output cannot disagree with subsequent DATA requests. Re-login replaces the
|
|
71
|
+
active connection and revokes the previous key after setup succeeds. The
|
|
72
|
+
public `@aliyunrds/ctxdb` build uses the distinct Device Flow implementation above and
|
|
73
|
+
continues to support API-key setup. It never reads the internal credential store. Build the
|
|
74
|
+
internal staging package with `pnpm build:internal`.
|
|
40
75
|
|
|
41
76
|
The distinction is a compile-time distribution manifest, not a runtime
|
|
42
77
|
environment-variable or file-existence check. The `public` manifest disables
|
|
43
|
-
`interactiveLogin` and `managedCredentials
|
|
44
|
-
|
|
78
|
+
internal-protocol flags `interactiveLogin` and `managedCredentials`, and enables `deviceFlow`;
|
|
79
|
+
the `internal` manifest enables the former two and disables `deviceFlow`. The CLI hooks and the separately bundled OpenCode plugin receive the
|
|
45
80
|
same manifest, so installing a public build on a machine that happens to have
|
|
46
81
|
`~/.ctxdb/credentials.json` does not make that build consume the file.
|
|
47
82
|
|
|
@@ -603,7 +638,9 @@ Field reference:
|
|
|
603
638
|
| `knowledge_top_k` | int | `6` | KB chunks pulled per recall (only effective when `recall_knowledge: true`) |
|
|
604
639
|
| `debug` | bool | `false` | Configured preference for verbose hook logging and full recall tracing. Effective debug is forced on for every final `base_url` outside the exact official-production allowlist; see “Debug control and recall replay”. General logs go to `~/.ctxdb/logs/ctxdb.log`, structured full-content recall records to `~/.ctxdb/logs/recall-trace.jsonl` |
|
|
605
640
|
|
|
606
|
-
Env-var overrides apply to the selected agent config (env wins): `CTXDB_AGENT` / `CTXDB_API_KEY` / `CTXDB_BASE_URL` / `CTXDB_USER_ID` / `CTXDB_AGENT_ID` / `CTXDB_APP_ID`. The internal login command additionally reads `CTXDB_LOGIN_SERVER` as its provider-neutral login endpoint. The last two default to unset — the request body omits `agent_id`/`app_id` entirely; set them only when you want per-agent / per-app scope isolation on the server.
|
|
641
|
+
Env-var overrides apply to the selected agent config (env wins): `CTXDB_AGENT` / `CTXDB_ACCESS_TOKEN` / `CTXDB_API_KEY` / `CTXDB_BASE_URL` / `CTXDB_USER_ID` / `CTXDB_AGENT_ID` / `CTXDB_APP_ID`. The internal login command additionally reads `CTXDB_LOGIN_SERVER` as its provider-neutral login endpoint. The last two default to unset — the request body omits `agent_id`/`app_id` entirely; set them only when you want per-agent / per-app scope isolation on the server.
|
|
642
|
+
|
|
643
|
+
Downstream Agent hosts can set `CTXDB_ACCESS_TOKEN` to send `Authorization: Bearer <token>` to the Data API. It is runtime-only, never written to `~/.ctxdb/ctxdb.json`, and takes precedence over a managed session or API key for CLI, process hooks, and OpenCode; a rejected token does not fall back to another credential. `ctxdb setup` can use a managed reference or an environment AT for validation, but never persists the AT. An environment-only credential must remain available to the Agent runtime after setup.
|
|
607
644
|
|
|
608
645
|
Hook/plugin escape hatch: set `CTXDB_SKIP_HOOKS=TRUE` on the agent process to make all ctxdb hook entrypoints exit immediately before reading config or calling the API. Direct `ctxdb memory` / `ctxdb kb` / `ctxdb setup` CLI commands are unchanged.
|
|
609
646
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
define_CTXDB_DISTRIBUTION_MANIFEST_default
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PI2SUS3M.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/distribution-capabilities.ts
|
|
7
7
|
var PUBLIC_DISTRIBUTION = {
|
|
@@ -10,7 +10,8 @@ var PUBLIC_DISTRIBUTION = {
|
|
|
10
10
|
packageRegistry: null,
|
|
11
11
|
capabilities: {
|
|
12
12
|
interactiveLogin: false,
|
|
13
|
-
managedCredentials: false
|
|
13
|
+
managedCredentials: false,
|
|
14
|
+
deviceFlow: true
|
|
14
15
|
}
|
|
15
16
|
};
|
|
16
17
|
var DISTRIBUTION_MANIFEST = typeof define_CTXDB_DISTRIBUTION_MANIFEST_default === "undefined" ? PUBLIC_DISTRIBUTION : define_CTXDB_DISTRIBUTION_MANIFEST_default;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fetchKbCatalogBlock,
|
|
4
4
|
recallTurn
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WJTV7JNR.js";
|
|
6
6
|
import {
|
|
7
7
|
debug
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SVO6H62S.js";
|
|
9
9
|
|
|
10
10
|
// src/lib/warmup-recall.ts
|
|
11
11
|
import { execSync } from "child_process";
|
|
@@ -4,12 +4,13 @@ import {
|
|
|
4
4
|
isConnectionError,
|
|
5
5
|
resetCircuit,
|
|
6
6
|
tripCircuit
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5DGRNP55.js";
|
|
8
8
|
import {
|
|
9
9
|
CtxdbError,
|
|
10
10
|
debug,
|
|
11
|
+
isDataApiReady,
|
|
11
12
|
isDebug
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SVO6H62S.js";
|
|
13
14
|
|
|
14
15
|
// src/lib/capture-orchestrator.ts
|
|
15
16
|
import {
|
|
@@ -398,7 +399,7 @@ async function captureParsedMessages(parsed, cfg, client, agent = "default", ses
|
|
|
398
399
|
};
|
|
399
400
|
}
|
|
400
401
|
function capturePreflight(cfg, agent) {
|
|
401
|
-
if (!cfg
|
|
402
|
+
if (!isDataApiReady(cfg)) {
|
|
402
403
|
return { captured: false, reason: "config_incomplete", messageCount: 0 };
|
|
403
404
|
}
|
|
404
405
|
if (!cfg.autoCapture) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// <define:__CTXDB_DISTRIBUTION_MANIFEST__>
|
|
4
|
-
var define_CTXDB_DISTRIBUTION_MANIFEST_default = { id: "public", packageName: "@aliyunrds/ctxdb", packageRegistry: null, capabilities: { interactiveLogin: false, managedCredentials: false } };
|
|
4
|
+
var define_CTXDB_DISTRIBUTION_MANIFEST_default = { id: "public", packageName: "@aliyunrds/ctxdb", packageRegistry: null, capabilities: { interactiveLogin: false, managedCredentials: false, deviceFlow: true } };
|
|
5
5
|
|
|
6
6
|
export {
|
|
7
7
|
define_CTXDB_DISTRIBUTION_MANIFEST_default
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DISTRIBUTION_MANIFEST
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5ITT5GSP.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/credentials.ts
|
|
7
|
+
function apiKeyCredential(apiKey) {
|
|
8
|
+
return { type: "api-key", value: apiKey };
|
|
9
|
+
}
|
|
10
|
+
function resolveDataApiCredential(cfg, env = process.env) {
|
|
11
|
+
const accessToken = env.CTXDB_ACCESS_TOKEN?.trim();
|
|
12
|
+
if (accessToken) return { type: "access-token", value: accessToken };
|
|
13
|
+
if (env.CTXDB_API_KEY) return apiKeyCredential(env.CTXDB_API_KEY);
|
|
14
|
+
if (cfg.oauthCredential) return { type: "oauth-session", profile: cfg.oauthCredential };
|
|
15
|
+
return cfg.apiKey ? apiKeyCredential(cfg.apiKey) : null;
|
|
16
|
+
}
|
|
17
|
+
function isDataApiReady(cfg, env = process.env) {
|
|
18
|
+
return Boolean(cfg.baseUrl && resolveDataApiCredential(cfg, env));
|
|
19
|
+
}
|
|
5
20
|
|
|
6
21
|
// src/lib/logger.ts
|
|
7
22
|
import { appendFileSync, mkdirSync } from "fs";
|
|
@@ -69,6 +84,7 @@ var PACKAGE_NAME = PACKAGE_IDENTITY.name;
|
|
|
69
84
|
var PACKAGE_VERSION = PACKAGE_IDENTITY.version;
|
|
70
85
|
|
|
71
86
|
// src/lib/http-client.ts
|
|
87
|
+
import { OAuthProfileProvider } from "@aliyunrds/ctxdb-shared";
|
|
72
88
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
73
89
|
var CtxdbError = class extends Error {
|
|
74
90
|
constructor(message) {
|
|
@@ -82,7 +98,7 @@ var AuthError = class extends CtxdbError {
|
|
|
82
98
|
errorMessage;
|
|
83
99
|
data;
|
|
84
100
|
responseBody;
|
|
85
|
-
constructor(message = "Unauthorized (HTTP 401) \u2014 check
|
|
101
|
+
constructor(message = "Unauthorized (HTTP 401) \u2014 check Data API credential", fields = {}) {
|
|
86
102
|
super(message);
|
|
87
103
|
this.name = "AuthError";
|
|
88
104
|
this.errorCode = fields.errorCode;
|
|
@@ -147,6 +163,7 @@ var CtxdbHttpError = class extends CtxdbError {
|
|
|
147
163
|
};
|
|
148
164
|
var HttpClient = class {
|
|
149
165
|
baseUrl;
|
|
166
|
+
credential;
|
|
150
167
|
apiKey;
|
|
151
168
|
timeoutMs;
|
|
152
169
|
userAgent;
|
|
@@ -154,12 +171,14 @@ var HttpClient = class {
|
|
|
154
171
|
fetchImpl;
|
|
155
172
|
authorizationProvider;
|
|
156
173
|
constructor(opts) {
|
|
157
|
-
|
|
158
|
-
if (!
|
|
159
|
-
throw new
|
|
174
|
+
const credential = opts.credential ?? (opts.apiKey ? apiKeyCredential(opts.apiKey) : null);
|
|
175
|
+
if (!credential && !opts.authorizationProvider) {
|
|
176
|
+
throw new CtxdbError("DATA API credential is required");
|
|
160
177
|
}
|
|
178
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
179
|
+
this.credential = credential;
|
|
161
180
|
this.apiKey = opts.apiKey ?? "";
|
|
162
|
-
this.authorizationProvider = opts.authorizationProvider;
|
|
181
|
+
this.authorizationProvider = opts.authorizationProvider ?? (credential?.type === "oauth-session" ? new OAuthProfileProvider(credential.profile) : void 0);
|
|
163
182
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
164
183
|
this.userAgent = opts.userAgent ?? `ctxdb-cli/${PACKAGE_VERSION}`;
|
|
165
184
|
this.extraHeaders = { ...opts.extraHeaders ?? {} };
|
|
@@ -174,15 +193,30 @@ var HttpClient = class {
|
|
|
174
193
|
...this.extraHeaders,
|
|
175
194
|
...requestHeaders
|
|
176
195
|
};
|
|
196
|
+
if (authorization.scheme === "Bearer") {
|
|
197
|
+
for (const key of Object.keys(h)) if (key.toLowerCase() === "authorization") delete h[key];
|
|
198
|
+
h.Authorization = `Bearer ${authorization.value}`;
|
|
199
|
+
}
|
|
177
200
|
if (contentType) h["Content-Type"] = contentType;
|
|
178
201
|
return h;
|
|
179
202
|
}
|
|
180
203
|
async doRequest(method, path, init = {}) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
204
|
+
let authorization;
|
|
205
|
+
if (this.authorizationProvider) {
|
|
206
|
+
authorization = await this.authorizationProvider.resolve();
|
|
207
|
+
} else {
|
|
208
|
+
const credential = this.credential;
|
|
209
|
+
if (!credential || credential.type === "oauth-session") throw new CtxdbError("DATA API credential is required");
|
|
210
|
+
authorization = {
|
|
211
|
+
scheme: credential.type === "access-token" ? "Bearer" : "Token",
|
|
212
|
+
value: credential.value,
|
|
213
|
+
baseUrl: this.baseUrl,
|
|
214
|
+
expiresAt: null
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const safeText = (value) => {
|
|
218
|
+
const text = String(value);
|
|
219
|
+
return authorization.scheme === "Bearer" ? text.split(authorization.value).join("[REDACTED]") : text;
|
|
186
220
|
};
|
|
187
221
|
let url = `${authorization.baseUrl.replace(/\/+$/, "")}${path}`;
|
|
188
222
|
if (init.params) {
|
|
@@ -213,15 +247,16 @@ var HttpClient = class {
|
|
|
213
247
|
init.headers
|
|
214
248
|
),
|
|
215
249
|
body: init.body,
|
|
216
|
-
signal: controller.signal
|
|
250
|
+
signal: controller.signal,
|
|
251
|
+
...authorization.scheme === "Bearer" ? { redirect: "error" } : {}
|
|
217
252
|
});
|
|
218
253
|
} catch (err) {
|
|
219
254
|
if (err?.name === "AbortError") {
|
|
220
255
|
if (dbg) debug("http", `\u2717 ${method} ${path} timeout after ${Date.now() - t0}ms`);
|
|
221
256
|
throw new CtxdbError(`request timeout after ${effectiveTimeout}ms: ${url}`);
|
|
222
257
|
}
|
|
223
|
-
if (dbg) debug("http", `\u2717 ${method} ${path} network error after ${Date.now() - t0}ms: ${err?.message ?? err}`);
|
|
224
|
-
throw new CtxdbError(`network error contacting ${url}: ${err?.message ?? err}`);
|
|
258
|
+
if (dbg) debug("http", `\u2717 ${method} ${path} network error after ${Date.now() - t0}ms: ${safeText(err?.message ?? err)}`);
|
|
259
|
+
throw new CtxdbError(`network error contacting ${url}: ${safeText(err?.message ?? err)}`);
|
|
225
260
|
}
|
|
226
261
|
if (resp.status === 204) {
|
|
227
262
|
if (dbg) debug("http", `\u2190 ${method} ${path} 204 (${Date.now() - t0}ms)`);
|
|
@@ -229,14 +264,14 @@ var HttpClient = class {
|
|
|
229
264
|
}
|
|
230
265
|
let text;
|
|
231
266
|
try {
|
|
232
|
-
text = await resp.text();
|
|
267
|
+
text = safeText(await resp.text());
|
|
233
268
|
} catch (err) {
|
|
234
269
|
if (err?.name === "AbortError") {
|
|
235
270
|
if (dbg) debug("http", `\u2717 ${method} ${path} body-read timeout after ${Date.now() - t0}ms`);
|
|
236
271
|
throw new CtxdbError(`request timeout after ${effectiveTimeout}ms (body read): ${url}`);
|
|
237
272
|
}
|
|
238
|
-
if (dbg) debug("http", `\u2717 ${method} ${path} body-read error after ${Date.now() - t0}ms: ${err?.message ?? err}`);
|
|
239
|
-
throw new CtxdbError(`network error reading body from ${url}: ${err?.message ?? err}`);
|
|
273
|
+
if (dbg) debug("http", `\u2717 ${method} ${path} body-read error after ${Date.now() - t0}ms: ${safeText(err?.message ?? err)}`);
|
|
274
|
+
throw new CtxdbError(`network error reading body from ${url}: ${safeText(err?.message ?? err)}`);
|
|
240
275
|
}
|
|
241
276
|
if (!resp.ok) {
|
|
242
277
|
const parsedError = parseErrorResponse(text, `HTTP ${resp.status}`);
|
|
@@ -801,10 +836,11 @@ function readActiveCredentialSync(path = defaultCredentialsPath()) {
|
|
|
801
836
|
|
|
802
837
|
// src/lib/config.ts
|
|
803
838
|
import {
|
|
804
|
-
resolveDebugPolicy
|
|
839
|
+
resolveDebugPolicy,
|
|
840
|
+
oauthProfile
|
|
805
841
|
} from "@aliyunrds/ctxdb-shared";
|
|
806
|
-
function defaultConfigPath() {
|
|
807
|
-
return join5(homedir4(), ".ctxdb", "ctxdb.json");
|
|
842
|
+
function defaultConfigPath(env = process.env) {
|
|
843
|
+
return env.CTXDB_CONFIG_PATH || join5(homedir4(), ".ctxdb", "ctxdb.json");
|
|
808
844
|
}
|
|
809
845
|
var DEFAULT_CONFIG_PATH = join5(homedir4(), ".ctxdb", "ctxdb.json");
|
|
810
846
|
function configDir() {
|
|
@@ -816,9 +852,6 @@ var DEFAULT_TOP_K = 5;
|
|
|
816
852
|
var DEFAULT_THRESHOLD = 0.4;
|
|
817
853
|
var DEFAULT_KNOWLEDGE_TOP_K = 6;
|
|
818
854
|
var DEFAULT_KB_CATALOG_INJECTION = "session_start";
|
|
819
|
-
function isComplete(cfg) {
|
|
820
|
-
return Boolean(cfg.apiKey && cfg.baseUrl);
|
|
821
|
-
}
|
|
822
855
|
function resolveConfigAgent(options = {}, preloadedRaw) {
|
|
823
856
|
if (isAgentSlug(options.agent)) return options.agent;
|
|
824
857
|
return agentFromEnv(options.env);
|
|
@@ -908,8 +941,8 @@ function applyEnv(cfg, env) {
|
|
|
908
941
|
return applyDebugPolicy(cfg);
|
|
909
942
|
}
|
|
910
943
|
function load(options = {}) {
|
|
911
|
-
const path = options.path ?? defaultConfigPath();
|
|
912
944
|
const env = options.env ?? process.env;
|
|
945
|
+
const path = options.path ?? defaultConfigPath(env);
|
|
913
946
|
const raw = readRaw(path);
|
|
914
947
|
const agent = resolveConfigAgent({ ...options, path, env }, raw);
|
|
915
948
|
if (!isV2Schema(raw)) {
|
|
@@ -935,7 +968,7 @@ function load(options = {}) {
|
|
|
935
968
|
const defaultRaw = agentRawFromFile(raw, "default");
|
|
936
969
|
if (Object.keys(defaultRaw).length > 0) {
|
|
937
970
|
for (const [k, v] of Object.entries(defaultRaw)) {
|
|
938
|
-
if (!(k in agentRaw)) {
|
|
971
|
+
if (k !== "oauth_credential_ref" && !(k in agentRaw)) {
|
|
939
972
|
agentRaw[k] = v;
|
|
940
973
|
}
|
|
941
974
|
}
|
|
@@ -949,11 +982,16 @@ function load(options = {}) {
|
|
|
949
982
|
cfg.apiKey = managed.payload.apiKey;
|
|
950
983
|
cfg.baseUrl = managed.payload.baseUrl;
|
|
951
984
|
}
|
|
952
|
-
|
|
985
|
+
applyEnv(cfg, env);
|
|
986
|
+
if (DISTRIBUTION_MANIFEST.capabilities.deviceFlow) {
|
|
987
|
+
cfg.oauthCredential = oauthProfile(agentRaw.oauth_credential_ref, path, agent, cfg.baseUrl);
|
|
988
|
+
}
|
|
989
|
+
return cfg;
|
|
953
990
|
}
|
|
954
991
|
function configToDisk(cfg) {
|
|
955
992
|
return {
|
|
956
|
-
|
|
993
|
+
...cfg.oauthCredential ? { oauth_credential_ref: cfg.oauthCredential.reference } : {},
|
|
994
|
+
api_key: cfg.oauthCredential ? null : cfg.apiKey,
|
|
957
995
|
base_url: cfg.baseUrl,
|
|
958
996
|
user_id: cfg.userId,
|
|
959
997
|
agent_id: cfg.agentId,
|
|
@@ -1061,6 +1099,8 @@ function writeInstalledPkgVersion(version, path) {
|
|
|
1061
1099
|
}
|
|
1062
1100
|
|
|
1063
1101
|
export {
|
|
1102
|
+
resolveDataApiCredential,
|
|
1103
|
+
isDataApiReady,
|
|
1064
1104
|
setDebug,
|
|
1065
1105
|
isDebug,
|
|
1066
1106
|
debug,
|
|
@@ -1080,10 +1120,11 @@ export {
|
|
|
1080
1120
|
detectInstalledAgents,
|
|
1081
1121
|
agentFromEnv,
|
|
1082
1122
|
agentFromArgvWithFallback,
|
|
1123
|
+
secureAtomicWrite,
|
|
1124
|
+
defaultConfigPath,
|
|
1083
1125
|
configDir,
|
|
1084
1126
|
DEFAULT_BASE_URL,
|
|
1085
1127
|
DEFAULT_USER_ID,
|
|
1086
|
-
isComplete,
|
|
1087
1128
|
load,
|
|
1088
1129
|
removeAgent,
|
|
1089
1130
|
save,
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
listKnowledgeBases
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZW7YXNJ6.js";
|
|
5
5
|
import {
|
|
6
6
|
isConnectionError,
|
|
7
7
|
resetCircuit,
|
|
8
8
|
tripCircuit
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5DGRNP55.js";
|
|
10
10
|
import {
|
|
11
|
-
CtxdbError
|
|
12
|
-
|
|
11
|
+
CtxdbError,
|
|
12
|
+
isDataApiReady,
|
|
13
|
+
resolveDataApiCredential
|
|
14
|
+
} from "./chunk-SVO6H62S.js";
|
|
13
15
|
|
|
14
16
|
// src/lib/kb-catalog.ts
|
|
15
17
|
function sanitizeKeyEntities(raw) {
|
|
@@ -152,12 +154,13 @@ async function recallTurn(prompt, cfg, client, agentOrOptions = "default") {
|
|
|
152
154
|
const options = typeof agentOrOptions === "string" ? { agent: agentOrOptions } : agentOrOptions;
|
|
153
155
|
const agent = options.agent ?? "default";
|
|
154
156
|
if (!prompt.trim()) return { ...EMPTY, reason: "empty_prompt" };
|
|
155
|
-
if (!cfg
|
|
157
|
+
if (!isDataApiReady(cfg)) {
|
|
156
158
|
return { ...EMPTY, reason: "config_incomplete" };
|
|
157
159
|
}
|
|
158
160
|
if (!cfg.autoRecall) {
|
|
159
161
|
return { ...EMPTY, reason: "auto_recall_disabled" };
|
|
160
162
|
}
|
|
163
|
+
const credential = resolveDataApiCredential(cfg);
|
|
161
164
|
const query = stripSystemReminders(prompt);
|
|
162
165
|
const trace = cfg.debug ? {
|
|
163
166
|
agent,
|
|
@@ -175,7 +178,11 @@ async function recallTurn(prompt, cfg, client, agentOrOptions = "default") {
|
|
|
175
178
|
},
|
|
176
179
|
store: {
|
|
177
180
|
...options.traceStore,
|
|
178
|
-
secrets: [
|
|
181
|
+
secrets: [
|
|
182
|
+
...options.traceStore?.secrets ?? [],
|
|
183
|
+
cfg.apiKey,
|
|
184
|
+
credential.value
|
|
185
|
+
]
|
|
179
186
|
}
|
|
180
187
|
} : null;
|
|
181
188
|
if (trace) {
|