@aliyunrds/ctxdb 1.0.8-beta.2 → 1.0.8-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/README.md +11 -7
- package/dist/{chunk-CULTDVI2.js → chunk-3NJ37TEY.js} +1 -1
- package/dist/{chunk-H33NUAHP.js → chunk-7OX6UVPB.js} +13 -6
- package/dist/{chunk-4FCZ2TZM.js → chunk-AUBVVYQL.js} +1 -1
- package/dist/{chunk-DMS5YHIK.js → chunk-BUK4SZC2.js} +36 -14
- package/dist/{chunk-X75B57M2.js → chunk-EI63DQX3.js} +1 -1
- package/dist/{chunk-5ZSZMN2T.js → chunk-LZ2LOWZL.js} +2 -2
- package/dist/{chunk-LYHGJOHM.js → chunk-ZFS6OMWE.js} +4 -3
- package/dist/cli/main.js +25 -13
- package/dist/hooks/hermes-post-llm-call.js +7 -5
- package/dist/hooks/hermes-pre-llm-call.js +10 -9
- package/dist/hooks/session-start.js +9 -8
- package/dist/hooks/stop.js +7 -5
- package/dist/hooks/user-prompt-submit.js +9 -8
- package/dist/opencode/index.js +21 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,12 +31,14 @@ Internal login stores its single active connection in owner-only
|
|
|
31
31
|
without writing an `api_key` field into the Agent or default profile; an
|
|
32
32
|
existing field in either updated profile is removed. At runtime this managed
|
|
33
33
|
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
|
-
`
|
|
34
|
+
`~/.ctxdb/ctxdb.json`; `CTXDB_ACCESS_TOKEN`, `CTXDB_API_KEY`, and
|
|
35
|
+
`CTXDB_BASE_URL` remain higher-priority overrides. `ctxdb login` rejects all
|
|
36
|
+
three while `ctxdb logout` rejects the two credential overrides, so command
|
|
37
|
+
output cannot disagree with subsequent DATA requests. Re-login replaces the
|
|
38
|
+
active connection and revokes the previous key after setup succeeds. The
|
|
39
|
+
public `@aliyunrds/ctxdb` build does not contain or advertise these commands and
|
|
40
|
+
continues to use `ctxdb setup` and the v2 config exactly as before. Build the
|
|
41
|
+
internal staging package with `pnpm build:internal`.
|
|
40
42
|
|
|
41
43
|
The distinction is a compile-time distribution manifest, not a runtime
|
|
42
44
|
environment-variable or file-existence check. The `public` manifest disables
|
|
@@ -603,7 +605,9 @@ Field reference:
|
|
|
603
605
|
| `knowledge_top_k` | int | `6` | KB chunks pulled per recall (only effective when `recall_knowledge: true`) |
|
|
604
606
|
| `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
607
|
|
|
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.
|
|
608
|
+
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.
|
|
609
|
+
|
|
610
|
+
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 an API key for CLI, process hooks, and the in-process OpenCode plugin; a rejected token does not fall back to the API key. `ctxdb setup` remains API-key-only and never persists or validates an access token.
|
|
607
611
|
|
|
608
612
|
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
613
|
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
listKnowledgeBases
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3NJ37TEY.js";
|
|
5
5
|
import {
|
|
6
6
|
isConnectionError,
|
|
7
7
|
resetCircuit,
|
|
8
8
|
tripCircuit
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-EI63DQX3.js";
|
|
10
10
|
import {
|
|
11
|
-
CtxdbError
|
|
12
|
-
|
|
11
|
+
CtxdbError,
|
|
12
|
+
isDataApiReady,
|
|
13
|
+
resolveDataApiCredential
|
|
14
|
+
} from "./chunk-BUK4SZC2.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) {
|
|
@@ -3,6 +3,19 @@ import {
|
|
|
3
3
|
DISTRIBUTION_MANIFEST
|
|
4
4
|
} from "./chunk-R67JELM7.js";
|
|
5
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
|
+
return cfg.apiKey ? apiKeyCredential(cfg.apiKey) : null;
|
|
14
|
+
}
|
|
15
|
+
function isDataApiReady(cfg, env = process.env) {
|
|
16
|
+
return Boolean(cfg.baseUrl && resolveDataApiCredential(cfg, env));
|
|
17
|
+
}
|
|
18
|
+
|
|
6
19
|
// src/lib/logger.ts
|
|
7
20
|
import { appendFileSync, mkdirSync } from "fs";
|
|
8
21
|
import { homedir } from "os";
|
|
@@ -82,7 +95,7 @@ var AuthError = class extends CtxdbError {
|
|
|
82
95
|
errorMessage;
|
|
83
96
|
data;
|
|
84
97
|
responseBody;
|
|
85
|
-
constructor(message = "Unauthorized (HTTP 401) \u2014 check
|
|
98
|
+
constructor(message = "Unauthorized (HTTP 401) \u2014 check Data API credential", fields = {}) {
|
|
86
99
|
super(message);
|
|
87
100
|
this.name = "AuthError";
|
|
88
101
|
this.errorCode = fields.errorCode;
|
|
@@ -147,6 +160,7 @@ var CtxdbHttpError = class extends CtxdbError {
|
|
|
147
160
|
};
|
|
148
161
|
var HttpClient = class {
|
|
149
162
|
baseUrl;
|
|
163
|
+
credential;
|
|
150
164
|
apiKey;
|
|
151
165
|
timeoutMs;
|
|
152
166
|
userAgent;
|
|
@@ -154,10 +168,12 @@ var HttpClient = class {
|
|
|
154
168
|
fetchImpl;
|
|
155
169
|
authorizationProvider;
|
|
156
170
|
constructor(opts) {
|
|
157
|
-
|
|
158
|
-
if (!
|
|
159
|
-
throw new
|
|
171
|
+
const credential = opts.credential ?? (opts.apiKey ? apiKeyCredential(opts.apiKey) : null);
|
|
172
|
+
if (!credential && !opts.authorizationProvider) {
|
|
173
|
+
throw new CtxdbError("DATA API credential is required");
|
|
160
174
|
}
|
|
175
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
176
|
+
this.credential = credential;
|
|
161
177
|
this.apiKey = opts.apiKey ?? "";
|
|
162
178
|
this.authorizationProvider = opts.authorizationProvider;
|
|
163
179
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -178,12 +194,19 @@ var HttpClient = class {
|
|
|
178
194
|
return h;
|
|
179
195
|
}
|
|
180
196
|
async doRequest(method, path, init = {}) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
197
|
+
let authorization;
|
|
198
|
+
if (this.authorizationProvider) {
|
|
199
|
+
authorization = await this.authorizationProvider.resolve();
|
|
200
|
+
} else {
|
|
201
|
+
const credential = this.credential;
|
|
202
|
+
if (!credential) throw new CtxdbError("DATA API credential is required");
|
|
203
|
+
authorization = {
|
|
204
|
+
scheme: credential.type === "access-token" ? "Bearer" : "Token",
|
|
205
|
+
value: credential.value,
|
|
206
|
+
baseUrl: this.baseUrl,
|
|
207
|
+
expiresAt: null
|
|
208
|
+
};
|
|
209
|
+
}
|
|
187
210
|
let url = `${authorization.baseUrl.replace(/\/+$/, "")}${path}`;
|
|
188
211
|
if (init.params) {
|
|
189
212
|
const qs = new URLSearchParams();
|
|
@@ -816,9 +839,6 @@ var DEFAULT_TOP_K = 5;
|
|
|
816
839
|
var DEFAULT_THRESHOLD = 0.4;
|
|
817
840
|
var DEFAULT_KNOWLEDGE_TOP_K = 6;
|
|
818
841
|
var DEFAULT_KB_CATALOG_INJECTION = "session_start";
|
|
819
|
-
function isComplete(cfg) {
|
|
820
|
-
return Boolean(cfg.apiKey && cfg.baseUrl);
|
|
821
|
-
}
|
|
822
842
|
function resolveConfigAgent(options = {}, preloadedRaw) {
|
|
823
843
|
if (isAgentSlug(options.agent)) return options.agent;
|
|
824
844
|
return agentFromEnv(options.env);
|
|
@@ -1061,6 +1081,9 @@ function writeInstalledPkgVersion(version, path) {
|
|
|
1061
1081
|
}
|
|
1062
1082
|
|
|
1063
1083
|
export {
|
|
1084
|
+
apiKeyCredential,
|
|
1085
|
+
resolveDataApiCredential,
|
|
1086
|
+
isDataApiReady,
|
|
1064
1087
|
setDebug,
|
|
1065
1088
|
isDebug,
|
|
1066
1089
|
debug,
|
|
@@ -1083,7 +1106,6 @@ export {
|
|
|
1083
1106
|
configDir,
|
|
1084
1107
|
DEFAULT_BASE_URL,
|
|
1085
1108
|
DEFAULT_USER_ID,
|
|
1086
|
-
isComplete,
|
|
1087
1109
|
load,
|
|
1088
1110
|
removeAgent,
|
|
1089
1111
|
save,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fetchKbCatalogBlock,
|
|
4
4
|
recallTurn
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7OX6UVPB.js";
|
|
6
6
|
import {
|
|
7
7
|
debug
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BUK4SZC2.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-EI63DQX3.js";
|
|
8
8
|
import {
|
|
9
9
|
CtxdbError,
|
|
10
10
|
debug,
|
|
11
|
+
isDataApiReady,
|
|
11
12
|
isDebug
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BUK4SZC2.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) {
|
package/dist/cli/main.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
uploadFile,
|
|
17
17
|
uploadText,
|
|
18
18
|
validateLocalFile
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-3NJ37TEY.js";
|
|
20
20
|
import {
|
|
21
21
|
AGENT_CHOICES,
|
|
22
22
|
CtxdbError,
|
|
@@ -31,19 +31,20 @@ import {
|
|
|
31
31
|
agentHomeDir,
|
|
32
32
|
agentHomeDirs,
|
|
33
33
|
agentPlatformSupport,
|
|
34
|
+
apiKeyCredential,
|
|
34
35
|
configuredAgents,
|
|
35
36
|
detectInstalledAgents,
|
|
36
37
|
hasConfiguredAgent,
|
|
37
38
|
inspectAgentHomes,
|
|
38
39
|
isAgentSlug,
|
|
39
40
|
isBuiltinAgent,
|
|
40
|
-
isComplete,
|
|
41
41
|
load,
|
|
42
42
|
removeAgent,
|
|
43
|
+
resolveDataApiCredential,
|
|
43
44
|
save,
|
|
44
45
|
updateConfiguredDebug,
|
|
45
46
|
writeInstalledPkgVersion
|
|
46
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-BUK4SZC2.js";
|
|
47
48
|
import {
|
|
48
49
|
beginUpdateNotification,
|
|
49
50
|
completeUpdateNotification,
|
|
@@ -275,6 +276,8 @@ function formatStatusResult(r) {
|
|
|
275
276
|
["base_url", r.base_url],
|
|
276
277
|
["user_id", r.user_id],
|
|
277
278
|
["api_key", r.api_key_set ? "set" : "not set"],
|
|
279
|
+
["access_token", r.access_token_set ? "set" : "not set"],
|
|
280
|
+
["credential_type", r.credential_type ?? "none"],
|
|
278
281
|
["auto_capture", r.auto_capture],
|
|
279
282
|
["auto_recall", r.auto_recall],
|
|
280
283
|
["top_k", r.top_k],
|
|
@@ -323,15 +326,16 @@ function agentFromFlags(flags) {
|
|
|
323
326
|
function buildContext(args) {
|
|
324
327
|
const agent = agentFromFlags(args?.flags ?? {});
|
|
325
328
|
const cfg = load({ agent });
|
|
326
|
-
|
|
327
|
-
|
|
329
|
+
const credential = resolveDataApiCredential(cfg);
|
|
330
|
+
if (!cfg.baseUrl || !credential) {
|
|
331
|
+
const hint = agent === "default" ? "run `ctxdb setup --api-key=<key> --base-url=<url>` or set CTXDB_ACCESS_TOKEN / CTXDB_API_KEY / CTXDB_BASE_URL env vars" : `run \`ctxdb setup --agent ${agent}\` or set CTXDB_ACCESS_TOKEN / CTXDB_API_KEY / CTXDB_BASE_URL / CTXDB_USER_ID env vars`;
|
|
328
332
|
process.stderr.write(`config incomplete for agent ${agent}: ${hint}
|
|
329
333
|
`);
|
|
330
334
|
process.exit(2);
|
|
331
335
|
}
|
|
332
336
|
const client = new HttpClient({
|
|
333
337
|
baseUrl: cfg.baseUrl,
|
|
334
|
-
|
|
338
|
+
credential
|
|
335
339
|
});
|
|
336
340
|
return { cfg, client, agent };
|
|
337
341
|
}
|
|
@@ -724,7 +728,10 @@ async function runSetup(options) {
|
|
|
724
728
|
});
|
|
725
729
|
} else {
|
|
726
730
|
try {
|
|
727
|
-
const client = new HttpClient({
|
|
731
|
+
const client = new HttpClient({
|
|
732
|
+
baseUrl: cfg.baseUrl,
|
|
733
|
+
credential: apiKeyCredential(cfg.apiKey)
|
|
734
|
+
});
|
|
728
735
|
await client.get("/v1/ping/");
|
|
729
736
|
steps.push({ step: "validate-ping", ok: true });
|
|
730
737
|
} catch (err) {
|
|
@@ -2090,12 +2097,13 @@ FLAGS
|
|
|
2090
2097
|
`;
|
|
2091
2098
|
async function inspectStatus(agent) {
|
|
2092
2099
|
const cfg = load({ agent });
|
|
2093
|
-
const
|
|
2100
|
+
const credential = resolveDataApiCredential(cfg);
|
|
2101
|
+
const complete = Boolean(cfg.baseUrl && credential);
|
|
2094
2102
|
let connected = false;
|
|
2095
2103
|
let pingError = null;
|
|
2096
|
-
if (complete) {
|
|
2104
|
+
if (complete && credential) {
|
|
2097
2105
|
try {
|
|
2098
|
-
const client = new HttpClient({ baseUrl: cfg.baseUrl,
|
|
2106
|
+
const client = new HttpClient({ baseUrl: cfg.baseUrl, credential });
|
|
2099
2107
|
await client.get("/v1/ping/");
|
|
2100
2108
|
connected = true;
|
|
2101
2109
|
} catch (err) {
|
|
@@ -2110,6 +2118,8 @@ async function inspectStatus(agent) {
|
|
|
2110
2118
|
base_url: cfg.baseUrl,
|
|
2111
2119
|
user_id: cfg.userId,
|
|
2112
2120
|
api_key_set: Boolean(cfg.apiKey),
|
|
2121
|
+
access_token_set: Boolean(process.env.CTXDB_ACCESS_TOKEN?.trim()),
|
|
2122
|
+
credential_type: credential?.type ?? null,
|
|
2113
2123
|
auto_capture: cfg.autoCapture,
|
|
2114
2124
|
auto_recall: cfg.autoRecall,
|
|
2115
2125
|
top_k: cfg.topK,
|
|
@@ -2192,12 +2202,13 @@ ${hint}
|
|
|
2192
2202
|
async function ping(args) {
|
|
2193
2203
|
const agent = agentFromFlags(args.flags);
|
|
2194
2204
|
const cfg = load({ agent });
|
|
2195
|
-
|
|
2205
|
+
const credential = resolveDataApiCredential(cfg);
|
|
2206
|
+
if (!cfg.baseUrl || !credential) {
|
|
2196
2207
|
fail(
|
|
2197
|
-
`config incomplete for agent ${agent} \u2014 run \`ctxdb setup --agent ${agent}\` or set CTXDB_API_KEY / CTXDB_BASE_URL / CTXDB_USER_ID`
|
|
2208
|
+
`config incomplete for agent ${agent} \u2014 run \`ctxdb setup --agent ${agent}\` or set CTXDB_ACCESS_TOKEN / CTXDB_API_KEY / CTXDB_BASE_URL / CTXDB_USER_ID`
|
|
2198
2209
|
);
|
|
2199
2210
|
}
|
|
2200
|
-
const client = new HttpClient({ baseUrl: cfg.baseUrl,
|
|
2211
|
+
const client = new HttpClient({ baseUrl: cfg.baseUrl, credential });
|
|
2201
2212
|
const resp = await client.get("/v1/ping/");
|
|
2202
2213
|
printResult(resp, !!args.flags.json);
|
|
2203
2214
|
return 0;
|
|
@@ -4474,6 +4485,7 @@ AGENT RESOLUTION (when --agent is omitted):
|
|
|
4474
4485
|
ENV VARS (override selected ~/.ctxdb/ctxdb.json agent config):
|
|
4475
4486
|
CTXDB_AGENT CTXDB_API_KEY CTXDB_BASE_URL CTXDB_USER_ID
|
|
4476
4487
|
CTXDB_AGENT_ID CTXDB_APP_ID
|
|
4488
|
+
CTXDB_ACCESS_TOKEN Runtime-only Data API Bearer credential; takes precedence over API key
|
|
4477
4489
|
|
|
4478
4490
|
UPDATE CHECK ENV VARS:
|
|
4479
4491
|
CTXDB_DISABLE_UPDATE_CHECK=1
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
captureParsedMessages
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-ZFS6OMWE.js";
|
|
5
|
+
import "../chunk-EI63DQX3.js";
|
|
6
6
|
import {
|
|
7
7
|
HttpClient,
|
|
8
8
|
agentFromArgvWithFallback,
|
|
9
9
|
debug,
|
|
10
10
|
load,
|
|
11
|
+
resolveDataApiCredential,
|
|
11
12
|
setDebug
|
|
12
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-BUK4SZC2.js";
|
|
13
14
|
import {
|
|
14
15
|
shouldSkipHooks
|
|
15
16
|
} from "../chunk-5ML4VSXN.js";
|
|
@@ -170,19 +171,20 @@ async function main() {
|
|
|
170
171
|
}
|
|
171
172
|
const input = extractHermesPostLlmCall(event);
|
|
172
173
|
const cfg = load({ agent });
|
|
174
|
+
const credential = resolveDataApiCredential(cfg);
|
|
173
175
|
setDebug(cfg.debug);
|
|
174
176
|
debug("hermes.post_llm_call", "start", {
|
|
175
177
|
sessionId: input.sessionId,
|
|
176
178
|
messageCount: input.messages.length,
|
|
177
179
|
userId: cfg.userId
|
|
178
180
|
});
|
|
179
|
-
if (!cfg.
|
|
181
|
+
if (!cfg.baseUrl || !credential) {
|
|
180
182
|
debug("hermes.post_llm_call", "skip (config incomplete)");
|
|
181
183
|
return 0;
|
|
182
184
|
}
|
|
183
185
|
const client = new HttpClient({
|
|
184
186
|
baseUrl: cfg.baseUrl,
|
|
185
|
-
|
|
187
|
+
credential,
|
|
186
188
|
timeoutMs: 5e3
|
|
187
189
|
});
|
|
188
190
|
const result = await captureParsedMessages(
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
import {
|
|
3
3
|
HOOK_TIMEOUT_MS,
|
|
4
4
|
composeSessionStart
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-LZ2LOWZL.js";
|
|
6
6
|
import {
|
|
7
7
|
composeUserPromptSubmit
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-AUBVVYQL.js";
|
|
9
9
|
import {
|
|
10
10
|
fetchKbCatalogBlock
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-7OX6UVPB.js";
|
|
12
|
+
import "../chunk-3NJ37TEY.js";
|
|
13
13
|
import {
|
|
14
14
|
isCircuitOpen
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-EI63DQX3.js";
|
|
16
16
|
import {
|
|
17
17
|
HttpClient,
|
|
18
18
|
agentFromArgvWithFallback,
|
|
19
19
|
debug,
|
|
20
|
-
isComplete,
|
|
21
20
|
load,
|
|
21
|
+
resolveDataApiCredential,
|
|
22
22
|
setDebug
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-BUK4SZC2.js";
|
|
24
24
|
import {
|
|
25
25
|
shouldSkipHooks
|
|
26
26
|
} from "../chunk-5ML4VSXN.js";
|
|
@@ -109,6 +109,7 @@ async function main() {
|
|
|
109
109
|
}
|
|
110
110
|
const input = extractHermesPreLlmCall(event);
|
|
111
111
|
const cfg = load({ agent });
|
|
112
|
+
const credential = resolveDataApiCredential(cfg);
|
|
112
113
|
setDebug(cfg.debug);
|
|
113
114
|
debug("hermes.pre_llm_call", "start", {
|
|
114
115
|
prompt: input.prompt.slice(0, 200),
|
|
@@ -120,7 +121,7 @@ async function main() {
|
|
|
120
121
|
const wantsRecall = cfg.autoRecall && Boolean(input.prompt.trim());
|
|
121
122
|
const wantsSessionStart = input.isFirstTurn && Boolean(input.cwd) && (cfg.warmupRecall || cfg.kbCatalogInjection === "session_start");
|
|
122
123
|
const wantsRepeatedSessionCatalog = cfg.kbCatalogInjection === "session_start";
|
|
123
|
-
if (!
|
|
124
|
+
if (!cfg.baseUrl || !credential || !wantsRecall && !wantsSessionStart && !wantsRepeatedSessionCatalog) {
|
|
124
125
|
debug("hermes.pre_llm_call", "skip (config incomplete or no enabled injection)");
|
|
125
126
|
return 0;
|
|
126
127
|
}
|
|
@@ -132,7 +133,7 @@ async function main() {
|
|
|
132
133
|
}
|
|
133
134
|
const client = new HttpClient({
|
|
134
135
|
baseUrl: cfg.baseUrl,
|
|
135
|
-
|
|
136
|
+
credential,
|
|
136
137
|
timeoutMs: HOOK_TIMEOUT_MS
|
|
137
138
|
});
|
|
138
139
|
const composed = await composeHermesPreLlmCall(cfg, agent, client, input);
|
|
@@ -3,20 +3,20 @@ import {
|
|
|
3
3
|
HOOK_TIMEOUT_MS,
|
|
4
4
|
composeSessionStart,
|
|
5
5
|
formatSessionStartStdout
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-LZ2LOWZL.js";
|
|
7
|
+
import "../chunk-7OX6UVPB.js";
|
|
8
|
+
import "../chunk-3NJ37TEY.js";
|
|
9
9
|
import {
|
|
10
10
|
isCircuitOpen
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-EI63DQX3.js";
|
|
12
12
|
import {
|
|
13
13
|
HttpClient,
|
|
14
14
|
agentFromArgvWithFallback,
|
|
15
15
|
debug,
|
|
16
|
-
isComplete,
|
|
17
16
|
load,
|
|
17
|
+
resolveDataApiCredential,
|
|
18
18
|
setDebug
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-BUK4SZC2.js";
|
|
20
20
|
import {
|
|
21
21
|
shouldSkipHooks
|
|
22
22
|
} from "../chunk-5ML4VSXN.js";
|
|
@@ -51,10 +51,11 @@ async function main() {
|
|
|
51
51
|
const sessionId = typeof event.session_id === "string" ? event.session_id : typeof event.sessionId === "string" ? event.sessionId : null;
|
|
52
52
|
if (!cwd) return 0;
|
|
53
53
|
const cfg = load({ agent });
|
|
54
|
+
const credential = resolveDataApiCredential(cfg);
|
|
54
55
|
setDebug(cfg.debug);
|
|
55
56
|
debug("warmup", "start", { cwd, userId: cfg.userId });
|
|
56
57
|
const kbInjectHere = cfg.kbCatalogInjection === "session_start";
|
|
57
|
-
if (!
|
|
58
|
+
if (!cfg.baseUrl || !credential || !cfg.warmupRecall && !kbInjectHere) {
|
|
58
59
|
debug("warmup", "skip (config incomplete or both warmup+kb off)");
|
|
59
60
|
return 0;
|
|
60
61
|
}
|
|
@@ -64,7 +65,7 @@ async function main() {
|
|
|
64
65
|
}
|
|
65
66
|
const client = new HttpClient({
|
|
66
67
|
baseUrl: cfg.baseUrl,
|
|
67
|
-
|
|
68
|
+
credential,
|
|
68
69
|
timeoutMs: HOOK_TIMEOUT_MS
|
|
69
70
|
});
|
|
70
71
|
const composed = await composeSessionStart(
|
package/dist/hooks/stop.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
captureTurn
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-ZFS6OMWE.js";
|
|
5
|
+
import "../chunk-EI63DQX3.js";
|
|
6
6
|
import {
|
|
7
7
|
HttpClient,
|
|
8
8
|
agentFromArgvWithFallback,
|
|
9
9
|
debug,
|
|
10
10
|
load,
|
|
11
|
+
resolveDataApiCredential,
|
|
11
12
|
setDebug
|
|
12
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-BUK4SZC2.js";
|
|
13
14
|
import {
|
|
14
15
|
shouldSkipHooks
|
|
15
16
|
} from "../chunk-5ML4VSXN.js";
|
|
@@ -47,13 +48,14 @@ async function main() {
|
|
|
47
48
|
if (typeof transcriptPath !== "string" || !transcriptPath) return 0;
|
|
48
49
|
const sessionId = extractHookSessionId(event);
|
|
49
50
|
const cfg = load({ agent });
|
|
51
|
+
const credential = resolveDataApiCredential(cfg);
|
|
50
52
|
setDebug(cfg.debug);
|
|
51
53
|
debug("capture", "start", { transcriptPath, userId: cfg.userId });
|
|
52
|
-
if (!cfg.
|
|
54
|
+
if (!cfg.baseUrl || !credential) {
|
|
53
55
|
debug("capture", "skip (config incomplete)");
|
|
54
56
|
return 0;
|
|
55
57
|
}
|
|
56
|
-
const client = new HttpClient({ baseUrl: cfg.baseUrl,
|
|
58
|
+
const client = new HttpClient({ baseUrl: cfg.baseUrl, credential, timeoutMs: 5e3 });
|
|
57
59
|
const result = await captureTurn(transcriptPath, cfg, client, agent, sessionId);
|
|
58
60
|
if (result.captured) {
|
|
59
61
|
debug("capture", `ok (${result.messageCount} msgs)`, result);
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
import {
|
|
3
3
|
composeUserPromptSubmit,
|
|
4
4
|
formatUserPromptSubmitStdout
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-AUBVVYQL.js";
|
|
6
|
+
import "../chunk-7OX6UVPB.js";
|
|
7
|
+
import "../chunk-3NJ37TEY.js";
|
|
8
8
|
import {
|
|
9
9
|
isCircuitOpen
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-EI63DQX3.js";
|
|
11
11
|
import {
|
|
12
12
|
HttpClient,
|
|
13
13
|
agentFromArgvWithFallback,
|
|
14
14
|
debug,
|
|
15
|
-
isComplete,
|
|
16
15
|
load,
|
|
16
|
+
resolveDataApiCredential,
|
|
17
17
|
setDebug
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-BUK4SZC2.js";
|
|
19
19
|
import {
|
|
20
20
|
shouldSkipHooks
|
|
21
21
|
} from "../chunk-5ML4VSXN.js";
|
|
@@ -50,9 +50,10 @@ async function main() {
|
|
|
50
50
|
const sessionId = typeof event.session_id === "string" ? event.session_id : typeof event.sessionId === "string" ? event.sessionId : null;
|
|
51
51
|
if (!prompt.trim()) return 0;
|
|
52
52
|
const cfg = load({ agent });
|
|
53
|
+
const credential = resolveDataApiCredential(cfg);
|
|
53
54
|
setDebug(cfg.debug);
|
|
54
55
|
debug("recall", "start", { prompt: prompt.slice(0, 200), userId: cfg.userId });
|
|
55
|
-
if (!
|
|
56
|
+
if (!cfg.baseUrl || !credential || !cfg.autoRecall) {
|
|
56
57
|
debug("recall", "skip (config incomplete or autoRecall=false)");
|
|
57
58
|
return 0;
|
|
58
59
|
}
|
|
@@ -62,7 +63,7 @@ async function main() {
|
|
|
62
63
|
`);
|
|
63
64
|
return 0;
|
|
64
65
|
}
|
|
65
|
-
const client = new HttpClient({ baseUrl: cfg.baseUrl,
|
|
66
|
+
const client = new HttpClient({ baseUrl: cfg.baseUrl, credential, timeoutMs: 5e3 });
|
|
66
67
|
const { ctx, recall, kbBlock } = await composeUserPromptSubmit(
|
|
67
68
|
cfg,
|
|
68
69
|
agent,
|
package/dist/opencode/index.js
CHANGED
|
@@ -892,6 +892,9 @@ function agentRaw(raw) {
|
|
|
892
892
|
if (!section || typeof section !== "object" || Array.isArray(section)) return {};
|
|
893
893
|
return section;
|
|
894
894
|
}
|
|
895
|
+
function accessTokenFromEnv(env = process.env) {
|
|
896
|
+
return env.CTXDB_ACCESS_TOKEN?.trim() || null;
|
|
897
|
+
}
|
|
895
898
|
function applyEnv(cfg, env) {
|
|
896
899
|
if (env.CTXDB_API_KEY) cfg.apiKey = env.CTXDB_API_KEY;
|
|
897
900
|
if (env.CTXDB_BASE_URL) cfg.baseUrl = env.CTXDB_BASE_URL.replace(/\/+$/, "");
|
|
@@ -976,8 +979,8 @@ function loadOpencodeConfig(options = {}) {
|
|
|
976
979
|
}
|
|
977
980
|
return applyEnv(cfg, env);
|
|
978
981
|
}
|
|
979
|
-
function isConfigured(cfg) {
|
|
980
|
-
return Boolean(cfg.apiKey && cfg.baseUrl);
|
|
982
|
+
function isConfigured(cfg, env = process.env) {
|
|
983
|
+
return Boolean((accessTokenFromEnv(env) || cfg.apiKey) && cfg.baseUrl);
|
|
981
984
|
}
|
|
982
985
|
|
|
983
986
|
// src/http-client.ts
|
|
@@ -995,11 +998,13 @@ var CtxdbHttpError = class extends Error {
|
|
|
995
998
|
var HttpClient = class {
|
|
996
999
|
baseUrl;
|
|
997
1000
|
apiKey;
|
|
1001
|
+
accessToken;
|
|
998
1002
|
userAgent;
|
|
999
1003
|
fetchImpl;
|
|
1000
1004
|
constructor(opts) {
|
|
1001
1005
|
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
1002
1006
|
this.apiKey = opts.apiKey;
|
|
1007
|
+
this.accessToken = opts.accessToken ?? null;
|
|
1003
1008
|
this.userAgent = opts.userAgent ?? "ctxdb-opencode-plugin/0.0.0";
|
|
1004
1009
|
this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
1005
1010
|
}
|
|
@@ -1008,7 +1013,8 @@ var HttpClient = class {
|
|
|
1008
1013
|
"User-Agent": this.userAgent,
|
|
1009
1014
|
Connection: "close"
|
|
1010
1015
|
};
|
|
1011
|
-
if (this.
|
|
1016
|
+
if (this.accessToken) h.Authorization = `Bearer ${this.accessToken}`;
|
|
1017
|
+
else if (this.apiKey) h.Authorization = `Token ${this.apiKey}`;
|
|
1012
1018
|
if (contentType) h["Content-Type"] = contentType;
|
|
1013
1019
|
return h;
|
|
1014
1020
|
}
|
|
@@ -1125,7 +1131,11 @@ async function searchAndFormatRecall(prompt, cfg, client, timeoutMs, traceOption
|
|
|
1125
1131
|
},
|
|
1126
1132
|
store: {
|
|
1127
1133
|
...traceOptions.traceStore,
|
|
1128
|
-
secrets: [
|
|
1134
|
+
secrets: [
|
|
1135
|
+
...traceOptions.traceStore?.secrets ?? [],
|
|
1136
|
+
cfg.apiKey,
|
|
1137
|
+
client.accessToken
|
|
1138
|
+
]
|
|
1129
1139
|
}
|
|
1130
1140
|
} : null;
|
|
1131
1141
|
if (trace) {
|
|
@@ -1454,10 +1464,14 @@ var SESSION_TTL_MS = 15 * 60 * 1e3;
|
|
|
1454
1464
|
var SESSION_MAX = 100;
|
|
1455
1465
|
var RECALL_TIMEOUT_MS = 5e3;
|
|
1456
1466
|
var CAPTURE_TIMEOUT_MS = 8e3;
|
|
1457
|
-
function buildRuntime(config, cwd) {
|
|
1467
|
+
function buildRuntime(config, cwd, env = process.env) {
|
|
1458
1468
|
return {
|
|
1459
1469
|
config,
|
|
1460
|
-
http: new HttpClient({
|
|
1470
|
+
http: new HttpClient({
|
|
1471
|
+
baseUrl: config.baseUrl,
|
|
1472
|
+
apiKey: config.apiKey,
|
|
1473
|
+
accessToken: accessTokenFromEnv(env)
|
|
1474
|
+
}),
|
|
1461
1475
|
sessionState: /* @__PURE__ */ new Map(),
|
|
1462
1476
|
cwd
|
|
1463
1477
|
};
|
|
@@ -1500,7 +1514,7 @@ async function buildHooks(input) {
|
|
|
1500
1514
|
logDebug(
|
|
1501
1515
|
config,
|
|
1502
1516
|
"config",
|
|
1503
|
-
"opencode integration disabled: missing agents.opencode.api_key
|
|
1517
|
+
"opencode integration disabled: missing CTXDB_ACCESS_TOKEN or API key in agents.opencode.api_key / CTXDB_API_KEY"
|
|
1504
1518
|
);
|
|
1505
1519
|
return {};
|
|
1506
1520
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliyunrds/ctxdb",
|
|
3
|
-
"version": "1.0.8-beta.
|
|
3
|
+
"version": "1.0.8-beta.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Unified access layer for RDS ContextDatabase: `ctxdb` CLI (memory + KB ops), one-shot multi-agent installer, per-agent config, hooks/plugins, and SKILL.md.",
|
|
6
6
|
"license": "Apache-2.0",
|