@aliyunrds/ctxdb 1.0.10 → 1.0.11-beta.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.
@@ -2,12 +2,15 @@
2
2
  import {
3
3
  composeUserPromptSubmit,
4
4
  formatUserPromptSubmitStdout
5
- } from "../chunk-5HPYYOPH.js";
6
- import "../chunk-VMBCSFGF.js";
7
- import "../chunk-SZ3AZDMU.js";
5
+ } from "../chunk-6XK3RDZ6.js";
6
+ import "../chunk-XEX5344F.js";
8
7
  import {
9
8
  isCircuitOpen
10
- } from "../chunk-XWJAZAMN.js";
9
+ } from "../chunk-7RMETV4M.js";
10
+ import {
11
+ shouldSkipHooks
12
+ } from "../chunk-5ML4VSXN.js";
13
+ import "../chunk-JM7EOAQZ.js";
11
14
  import {
12
15
  HttpClient,
13
16
  agentFromArgvWithFallback,
@@ -16,11 +19,8 @@ import {
16
19
  resolveDataApiCredential,
17
20
  setDebug,
18
21
  skillPromptContext
19
- } from "../chunk-TZFDXKLJ.js";
22
+ } from "../chunk-HHKQPWYI.js";
20
23
  import "../chunk-5ITT5GSP.js";
21
- import {
22
- shouldSkipHooks
23
- } from "../chunk-5ML4VSXN.js";
24
24
  import "../chunk-PI2SUS3M.js";
25
25
 
26
26
  // src/hooks/user-prompt-submit.ts
@@ -23403,6 +23403,14 @@ function buildWarmupQuery(cwd, git) {
23403
23403
  // src/capture.ts
23404
23404
  init_define_CTXDB_DISTRIBUTION_MANIFEST();
23405
23405
  import { createHash as createHash5 } from "crypto";
23406
+
23407
+ // ../ctxdb/src/lib/memory-upload-agent.ts
23408
+ init_define_CTXDB_DISTRIBUTION_MANIFEST();
23409
+ function resolveMemoryUploadAgentId(configuredAgentId, agent = "default") {
23410
+ return configuredAgentId || agent;
23411
+ }
23412
+
23413
+ // src/capture.ts
23406
23414
  var EMPTY2 = {
23407
23415
  captured: false,
23408
23416
  reason: "",
@@ -23500,9 +23508,9 @@ async function runCapture(messages, cfg, client, timeoutMs, lastFingerprint, ses
23500
23508
  const payload = {
23501
23509
  messages: filtered,
23502
23510
  user_id: cfg.userId,
23511
+ agent_id: resolveMemoryUploadAgentId(cfg.agentId, "opencode"),
23503
23512
  async_mode: true
23504
23513
  };
23505
- if (cfg.agentId) payload.agent_id = cfg.agentId;
23506
23514
  if (cfg.appId) payload.app_id = cfg.appId;
23507
23515
  if (sessionId) payload.run_id = sessionId;
23508
23516
  let resp;
@@ -23566,12 +23574,12 @@ function touchSession(rt, sessionID) {
23566
23574
  function pruneSessions(state) {
23567
23575
  const now = Date.now();
23568
23576
  for (const [id, s] of state) {
23569
- if (now - s.touched > SESSION_TTL_MS) state.delete(id);
23577
+ if (!s.idleTask && now - s.touched > SESSION_TTL_MS) state.delete(id);
23570
23578
  }
23571
23579
  if (state.size > SESSION_MAX) {
23572
23580
  const overflow = state.size - SESSION_MAX;
23573
- const sorted = [...state.entries()].sort((a, b) => a[1].touched - b[1].touched);
23574
- for (let i = 0; i < overflow; i++) state.delete(sorted[i][0]);
23581
+ const sorted = [...state.entries()].filter(([, s]) => !s.idleTask).sort((a, b) => a[1].touched - b[1].touched);
23582
+ for (let i = 0; i < Math.min(overflow, sorted.length); i++) state.delete(sorted[i][0]);
23575
23583
  }
23576
23584
  }
23577
23585
  function extractTextPrompt(parts) {
@@ -23684,59 +23692,17 @@ async function buildHooks(input) {
23684
23692
  const sessionID = ev.properties?.sessionID;
23685
23693
  if (!sessionID) return;
23686
23694
  const state = touchSession(rt, sessionID);
23687
- let messages;
23688
- try {
23689
- const data = await withTimeout(
23690
- input.client.session.messages({
23691
- path: { id: sessionID },
23692
- // Skill evidence needs the whole paired turn; a 24-message tail can lose the user goal/calls.
23693
- query: {},
23694
- throwOnError: true
23695
- }),
23696
- CAPTURE_TIMEOUT_MS,
23697
- "session.messages"
23698
- );
23699
- messages = unwrapSessionMessagesResponse(data);
23700
- } catch (err) {
23701
- logError(rt.config, "event.fetchMessages", err);
23702
- return;
23703
- }
23704
- if (messages.length === 0) return;
23695
+ const task = (state.idleTask ?? Promise.resolve()).catch(() => {
23696
+ }).then(() => captureIdle(input, rt, state, sessionID));
23697
+ state.idleTask = task;
23705
23698
  try {
23706
- const binding = sessionBinding(sessionID, void 0, "opencode");
23707
- const latest = [...messages].reverse().find((m) => m.info?.role === "assistant");
23708
- if (latest?.info?.time?.completed && !latest.info.error && latest.info.finish === "stop") {
23709
- const usableTurns = new Set(messages.filter((m) => m.info?.role === "assistant" && m.info.time?.completed && !m.info.error && m.info.finish === "stop").map((m) => m.info.parentID));
23710
- const usable = messages.filter((m) => {
23711
- const turn = m.info?.role === "user" ? m.info.id : m.info?.parentID;
23712
- return turn !== void 0 && usableTurns.has(turn);
23713
- });
23714
- const answer = (latest.parts ?? []).filter((p) => p.type === "text" && !p.synthetic && !p.ignored).map((p) => p.text).join("\n");
23715
- await skillStopRows(binding, usable, { last_assistant_message: answer, turn_id: latest.info.parentID }, null);
23699
+ await task;
23700
+ } finally {
23701
+ if (state.idleTask === task) {
23702
+ state.idleTask = void 0;
23703
+ state.touched = Date.now();
23716
23704
  }
23717
- } catch {
23718
- logError(rt.config, "skill.checkpoint", new Error("skill_checkpoint_unavailable"));
23719
- }
23720
- if (!rt.config.autoCapture) return;
23721
- const outcome = await runCapture(
23722
- messages,
23723
- rt.config,
23724
- rt.http,
23725
- CAPTURE_TIMEOUT_MS,
23726
- state.lastFingerprint,
23727
- sessionID
23728
- );
23729
- if (outcome.captured && outcome.fingerprint) {
23730
- state.lastFingerprint = outcome.fingerprint;
23731
23705
  }
23732
- if (!outcome.captured && outcome.reason.startsWith("http_error:")) {
23733
- logError(rt.config, "event.capture", new Error(outcome.reason));
23734
- }
23735
- logDebug(
23736
- rt.config,
23737
- "event.capture",
23738
- `sessionID=${sessionID} captured=${outcome.captured} reason=${outcome.reason} count=${outcome.messageCount}`
23739
- );
23740
23706
  } catch (err) {
23741
23707
  logError(rt.config, "event", err);
23742
23708
  }
@@ -23744,6 +23710,61 @@ async function buildHooks(input) {
23744
23710
  };
23745
23711
  return hooks;
23746
23712
  }
23713
+ async function captureIdle(input, rt, state, sessionID) {
23714
+ let messages;
23715
+ try {
23716
+ const data = await withTimeout(
23717
+ input.client.session.messages({
23718
+ path: { id: sessionID },
23719
+ // Skill evidence needs the whole paired turn; a 24-message tail can lose the user goal/calls.
23720
+ query: {},
23721
+ throwOnError: true
23722
+ }),
23723
+ CAPTURE_TIMEOUT_MS,
23724
+ "session.messages"
23725
+ );
23726
+ messages = unwrapSessionMessagesResponse(data);
23727
+ } catch (err) {
23728
+ logError(rt.config, "event.fetchMessages", err);
23729
+ return;
23730
+ }
23731
+ if (messages.length === 0) return;
23732
+ try {
23733
+ const binding = sessionBinding(sessionID, void 0, "opencode");
23734
+ const latest = [...messages].reverse().find((m) => m.info?.role === "assistant");
23735
+ if (latest?.info?.time?.completed && !latest.info.error && latest.info.finish === "stop") {
23736
+ const usableTurns = new Set(messages.filter((m) => m.info?.role === "assistant" && m.info.time?.completed && !m.info.error && m.info.finish === "stop").map((m) => m.info.parentID));
23737
+ const usable = messages.filter((m) => {
23738
+ const turn = m.info?.role === "user" ? m.info.id : m.info?.parentID;
23739
+ return turn !== void 0 && usableTurns.has(turn);
23740
+ });
23741
+ const answer = (latest.parts ?? []).filter((p) => p.type === "text" && !p.synthetic && !p.ignored).map((p) => p.text).join("\n");
23742
+ await skillStopRows(binding, usable, { last_assistant_message: answer, turn_id: latest.info.parentID }, null);
23743
+ }
23744
+ } catch {
23745
+ logError(rt.config, "skill.checkpoint", new Error("skill_checkpoint_unavailable"));
23746
+ }
23747
+ if (!rt.config.autoCapture) return;
23748
+ const outcome = await runCapture(
23749
+ messages,
23750
+ rt.config,
23751
+ rt.http,
23752
+ CAPTURE_TIMEOUT_MS,
23753
+ state.lastFingerprint,
23754
+ sessionID
23755
+ );
23756
+ if (outcome.captured && outcome.fingerprint) {
23757
+ state.lastFingerprint = outcome.fingerprint;
23758
+ }
23759
+ if (!outcome.captured && outcome.reason.startsWith("http_error:")) {
23760
+ logError(rt.config, "event.capture", new Error(outcome.reason));
23761
+ }
23762
+ logDebug(
23763
+ rt.config,
23764
+ "event.capture",
23765
+ `sessionID=${sessionID} captured=${outcome.captured} reason=${outcome.reason} count=${outcome.messageCount}`
23766
+ );
23767
+ }
23747
23768
  async function searchAndLogRecall(scope, kind, query, sessionId, rt) {
23748
23769
  const result = await searchAndFormatRecall(
23749
23770
  query,
@@ -4,7 +4,7 @@ import {
4
4
  recordVersionCheckFailure,
5
5
  recordVersionCheckSuccess,
6
6
  releaseVersionCheckLock
7
- } from "../chunk-QUPLZ7KF.js";
7
+ } from "../chunk-G3MDJEX5.js";
8
8
  import "../chunk-5ITT5GSP.js";
9
9
  import "../chunk-PI2SUS3M.js";
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aliyunrds/ctxdb",
3
- "version": "1.0.10",
3
+ "version": "1.0.11-beta.0",
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",