@integrity-labs/agt-cli 0.28.747 → 0.28.749

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.
@@ -13,7 +13,7 @@ import {
13
13
  parseEnvFileEntries,
14
14
  parseEnvIntegrations,
15
15
  shellQuote
16
- } from "./chunk-R35LZDRH.js";
16
+ } from "./chunk-3LQYVRKX.js";
17
17
  import {
18
18
  BIND_FAILURE_QUARANTINE_THRESHOLD,
19
19
  INTEGRATIONS_SECTION_END,
@@ -62,7 +62,7 @@ import {
62
62
  sessionTranscriptDir,
63
63
  worseConnectivityOutcome,
64
64
  wrapScheduledTaskPrompt
65
- } from "./chunk-62TAD4HO.js";
65
+ } from "./chunk-DFOBTAPL.js";
66
66
  import {
67
67
  parsePsRows
68
68
  } from "./chunk-XWVM4KPK.js";
@@ -6430,7 +6430,7 @@ function exchangeFailureKind(err) {
6430
6430
  }
6431
6431
 
6432
6432
  // src/lib/api-client.ts
6433
- var agtCliVersion = true ? "0.28.747" : "dev";
6433
+ var agtCliVersion = true ? "0.28.749" : "dev";
6434
6434
  var lastConfigHash = null;
6435
6435
  function setConfigHash(hash) {
6436
6436
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10476,4 +10476,4 @@ export {
10476
10476
  managerInstallSystemUnitCommand,
10477
10477
  managerUninstallSystemUnitCommand
10478
10478
  };
10479
- //# sourceMappingURL=chunk-OYASDDR4.js.map
10479
+ //# sourceMappingURL=chunk-WTBSFYTA.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-V6L4Y2P5.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-VX5THUBN.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-REZ462KO.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-QOHDIQBD.js.map
@@ -57,7 +57,7 @@ import {
57
57
  safeWriteJsonAtomic,
58
58
  setConfigHash,
59
59
  tripClass
60
- } from "../chunk-OYASDDR4.js";
60
+ } from "../chunk-WTBSFYTA.js";
61
61
  import {
62
62
  getProjectDir as getProjectDir2,
63
63
  getReadyTasks,
@@ -118,7 +118,7 @@ import {
118
118
  takeZombieDetection,
119
119
  toOpencodeModel,
120
120
  writeEgressAllowlist
121
- } from "../chunk-R35LZDRH.js";
121
+ } from "../chunk-3LQYVRKX.js";
122
122
  import {
123
123
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
124
124
  AnchorSessionClient,
@@ -126,6 +126,7 @@ import {
126
126
  CONVERSATION_FAILURE_CATEGORIES,
127
127
  DEFAULT_FRAMEWORK,
128
128
  DEFAULT_NEIGHBOURHOOD_MS,
129
+ EXTRACTOR_IDENTIFIER_RULE,
129
130
  FLAGS_SCHEMA_VERSION,
130
131
  FLAG_REGISTRY,
131
132
  FORCED_UPDATE_HARD_DEADLINE_MS,
@@ -156,6 +157,7 @@ import {
156
157
  extractFrontmatter,
157
158
  extractQualifyingTurns,
158
159
  extractToolCallEvents,
160
+ findIdentifierUrls,
159
161
  findRunMarker,
160
162
  forcedUpdatePendingForMs,
161
163
  formatActorId,
@@ -163,6 +165,7 @@ import {
163
165
  formatRunMarker,
164
166
  getFramework,
165
167
  getIntegration,
168
+ identifierMemoryName,
166
169
  isAgentIdle,
167
170
  isAgentTimezoneOverrideExpired,
168
171
  isBareAck,
@@ -197,13 +200,14 @@ import {
197
200
  resolveAvatarEnvUrl,
198
201
  resolveChannels,
199
202
  resolveDmTarget,
203
+ scrubPreservingIdentifiers,
200
204
  serializeAccountEnforcementMarker,
201
205
  sessionTranscriptDir,
202
206
  stabiliseResetInstant,
203
207
  subagentActivityAgeSeconds,
204
208
  sumTranscriptUsageInWindow,
205
209
  transcriptActivityAgeSeconds
206
- } from "../chunk-62TAD4HO.js";
210
+ } from "../chunk-DFOBTAPL.js";
207
211
  import {
208
212
  reapOrphanChannelMcps
209
213
  } from "../chunk-XWVM4KPK.js";
@@ -3921,14 +3925,14 @@ var SECRET_PATTERNS = [
3921
3925
  /\b[\w.+-]+@[\w-]+\.[\w.-]+\b/g
3922
3926
  ];
3923
3927
  function scrubSensitive(text) {
3924
- let out = text;
3925
- for (const re of SECRET_PATTERNS) out = out.replace(re, "[redacted]");
3926
- return out;
3928
+ return scrubPreservingIdentifiers(text, SECRET_PATTERNS);
3927
3929
  }
3928
3930
  var state5 = /* @__PURE__ */ new Map();
3929
3931
  function buildExtractionPrompt(channel, transcript) {
3930
3932
  return `You are extracting durable, reusable memories from one completed ${channel} conversation between an AI agent and an end-user. A good memory is a stable preference, fact, correction, or recurring work context that will help the agent in FUTURE conversations \u2014 not a one-off task detail or pleasantry.
3931
3933
 
3934
+ ${EXTRACTOR_IDENTIFIER_RULE} The "no secrets" rule below still wins: if the identifier itself carries a credential (a token, password or signing parameter), leave it out.
3935
+
3932
3936
  Conversation transcript:
3933
3937
  """
3934
3938
  ${transcript}
@@ -3936,7 +3940,7 @@ ${transcript}
3936
3940
 
3937
3941
  Extract 0-5 candidate memories. For each:
3938
3942
  - name: short descriptive title (max 50 chars)
3939
- - content: the memory itself, self-contained (max 200 chars). Do NOT include secrets or sensitive personal data.
3943
+ - content: the memory itself, self-contained (max 200 chars \u2014 or up to 500 when it carries an identifier that must be copied exactly). Do NOT include secrets or sensitive personal data.
3940
3944
  - type: "user" (a person's stable preference), "feedback" (a correction to how the agent should work), "project" (durable work context), or "reference" (a pointer to an external resource)
3941
3945
  - confidence: 0.0-1.0 \u2014 how sure you are this is worth remembering long-term
3942
3946
  - rationale: why this should persist (max 100 chars)
@@ -3975,6 +3979,70 @@ function parseCandidates(raw) {
3975
3979
  }
3976
3980
  return out;
3977
3981
  }
3982
+ var FORCED_IDENTIFIER_CONFIDENCE = 0.9;
3983
+ var MAX_FORCED_IDENTIFIERS = 3;
3984
+ var MAX_FORCED_CONTENT = 500;
3985
+ function detectMissedIdentifiers(turns, candidates) {
3986
+ const userTurns = turns.filter((t) => t.role === "user");
3987
+ if (userTurns.length === 0) return [];
3988
+ const already = candidates.map((c) => c.content).join("\n");
3989
+ const out = [];
3990
+ const seen = /* @__PURE__ */ new Set();
3991
+ for (const turn of userTurns) {
3992
+ for (const url of findIdentifierUrls(turn.text)) {
3993
+ if (seen.has(url)) continue;
3994
+ seen.add(url);
3995
+ if (already.includes(url)) continue;
3996
+ const context = turn.text.replace(url, " ").replace(/\s+/g, " ").trim().slice(0, 140);
3997
+ const content = url.length >= MAX_FORCED_CONTENT ? url : `${url}${context ? ` \u2014 shared by the user: ${context}` : ""}`.slice(
3998
+ 0,
3999
+ MAX_FORCED_CONTENT
4000
+ );
4001
+ out.push({
4002
+ name: identifierMemoryName(url),
4003
+ content,
4004
+ type: "reference",
4005
+ confidence: FORCED_IDENTIFIER_CONFIDENCE,
4006
+ rationale: "Identifier supplied by the user; unrecoverable after a restart."
4007
+ });
4008
+ if (out.length >= MAX_FORCED_IDENTIFIERS) return out;
4009
+ }
4010
+ }
4011
+ return out;
4012
+ }
4013
+ async function salvageIdentifiers(args) {
4014
+ const forced = detectMissedIdentifiers(args.turns, []);
4015
+ if (forced.length === 0) return 0;
4016
+ const scrubbed = forced.map((c) => ({
4017
+ ...c,
4018
+ content: scrubSensitive(c.content),
4019
+ rationale: scrubSensitive(c.rationale)
4020
+ }));
4021
+ try {
4022
+ const res = await args.api.post(
4023
+ "/host/memories/identifiers",
4024
+ {
4025
+ agent_id: args.agentId,
4026
+ conversation_id: args.conversationId,
4027
+ candidates: scrubbed
4028
+ }
4029
+ );
4030
+ if (!res?.ok) return 0;
4031
+ return res.promoted ?? 0;
4032
+ } catch {
4033
+ return 0;
4034
+ }
4035
+ }
4036
+ async function salvageOnce(st, conversationId, fn) {
4037
+ if (st.salvaged.has(conversationId)) return 0;
4038
+ st.salvaged.add(conversationId);
4039
+ return fn();
4040
+ }
4041
+ function pruneSalvaged(st, stillPending) {
4042
+ for (const id of st.salvaged) {
4043
+ if (!stillPending.has(id)) st.salvaged.delete(id);
4044
+ }
4045
+ }
3978
4046
  async function maybeExtractMemories(args) {
3979
4047
  const { api: api2, backend, codeName, agentId, log: log2 } = args;
3980
4048
  const now = args.now ?? /* @__PURE__ */ new Date();
@@ -3983,7 +4051,8 @@ async function maybeExtractMemories(args) {
3983
4051
  if (existing && nowMs - existing.lastCheckedAt < MIN_CHECK_INTERVAL_MS5) {
3984
4052
  return;
3985
4053
  }
3986
- state5.set(codeName, { lastCheckedAt: nowMs });
4054
+ const st = { lastCheckedAt: nowMs, salvaged: existing?.salvaged ?? /* @__PURE__ */ new Set() };
4055
+ state5.set(codeName, st);
3987
4056
  let pending2;
3988
4057
  try {
3989
4058
  const resp = await api2.get(
@@ -3994,6 +4063,7 @@ async function maybeExtractMemories(args) {
3994
4063
  log2(`[memory-extract] ${codeName}: pending fetch failed: ${err.message}`);
3995
4064
  return;
3996
4065
  }
4066
+ pruneSalvaged(st, new Set(pending2.map((p) => p.conversation_id)));
3997
4067
  if (pending2.length === 0) return;
3998
4068
  const dir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
3999
4069
  const allTurns = readRecentTurns(dir, nowMs);
@@ -4003,6 +4073,7 @@ async function maybeExtractMemories(args) {
4003
4073
  }
4004
4074
  return;
4005
4075
  }
4076
+ let salvaged = 0;
4006
4077
  for (const conv of pending2) {
4007
4078
  const windowStart = Date.parse(conv.started_at) - WINDOW_PAD_MS2;
4008
4079
  const windowEnd = Date.parse(conv.last_message_at) + WINDOW_PAD_MS2;
@@ -4023,13 +4094,25 @@ async function maybeExtractMemories(args) {
4023
4094
  } catch (err) {
4024
4095
  log2(`[memory-extract] ${codeName}: extraction failed: ${err.message}`);
4025
4096
  args.onModelCallError?.(err);
4097
+ salvaged += await salvageOnce(
4098
+ st,
4099
+ conv.conversation_id,
4100
+ () => salvageIdentifiers({ api: api2, agentId, conversationId: conv.conversation_id, turns, log: log2, codeName })
4101
+ );
4026
4102
  continue;
4027
4103
  }
4028
4104
  if (candidates === null) {
4029
4105
  log2(`[memory-extract] ${codeName}: unparseable output for ${conv.conversation_id.slice(0, 8)} \u2014 will retry`);
4106
+ salvaged += await salvageOnce(
4107
+ st,
4108
+ conv.conversation_id,
4109
+ () => salvageIdentifiers({ api: api2, agentId, conversationId: conv.conversation_id, turns, log: log2, codeName })
4110
+ );
4030
4111
  continue;
4031
4112
  }
4032
- const scrubbed = candidates.map((c) => ({
4113
+ const forced = detectMissedIdentifiers(turns, candidates);
4114
+ const merged = [...forced, ...candidates];
4115
+ const scrubbed = merged.map((c) => ({
4033
4116
  ...c,
4034
4117
  content: scrubSensitive(c.content),
4035
4118
  rationale: scrubSensitive(c.rationale)
@@ -4044,7 +4127,7 @@ async function maybeExtractMemories(args) {
4044
4127
  }
4045
4128
  );
4046
4129
  log2(
4047
- `[memory-extract] ${codeName}: ${conv.conversation_id.slice(0, 8)} \u2192 ${candidates.length} candidate(s), ${res?.promoted ?? 0} promoted`
4130
+ `[memory-extract] ${codeName}: ${conv.conversation_id.slice(0, 8)} \u2192 ${candidates.length} candidate(s), ${forced.length} identifier(s) recovered, ${res?.promoted ?? 0} promoted`
4048
4131
  );
4049
4132
  } catch (err) {
4050
4133
  log2(`[memory-extract] ${codeName}: report failed: ${err.message}`);
@@ -4061,6 +4144,9 @@ async function maybeExtractMemories(args) {
4061
4144
  onModelCallError: args.onModelCallError
4062
4145
  });
4063
4146
  }
4147
+ if (salvaged > 0) {
4148
+ log2(`[memory-extract] ${codeName}: identifiers_salvaged=${salvaged} (model call failed)`);
4149
+ }
4064
4150
  }
4065
4151
  async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
4066
4152
  try {
@@ -12631,7 +12717,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
12631
12717
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
12632
12718
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
12633
12719
  async function channelInboundActivityAgeSecondsFor(codeName) {
12634
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-RDF5NWRH.js");
12720
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-PMH4Z3MU.js");
12635
12721
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
12636
12722
  if (newest === null) return null;
12637
12723
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -13284,7 +13370,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
13284
13370
  var lastVersionCheckAt = 0;
13285
13371
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
13286
13372
  var lastResponsivenessProbeAt = 0;
13287
- var agtCliVersion = true ? "0.28.747" : "dev";
13373
+ var agtCliVersion = true ? "0.28.749" : "dev";
13288
13374
  function resolveBrewPath(execFileSync3) {
13289
13375
  try {
13290
13376
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14825,7 +14911,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
14825
14911
  if (codeNames.length === 0) return;
14826
14912
  void (async () => {
14827
14913
  try {
14828
- const { collectDiagnostics } = await import("../persistent-session-V6L4Y2P5.js");
14914
+ const { collectDiagnostics } = await import("../persistent-session-VX5THUBN.js");
14829
14915
  await api.post("/host/heartbeat", {
14830
14916
  host_id: hostId,
14831
14917
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -14966,7 +15052,7 @@ async function pollCycleInner() {
14966
15052
  }
14967
15053
  try {
14968
15054
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
14969
- const { collectDiagnostics } = await import("../persistent-session-V6L4Y2P5.js");
15055
+ const { collectDiagnostics } = await import("../persistent-session-VX5THUBN.js");
14970
15056
  const diagCodeNames = [...agentState.persistentSessionAgents];
14971
15057
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
14972
15058
  let tailscaleHostname;
@@ -15135,7 +15221,7 @@ async function pollCycleInner() {
15135
15221
  collectPanelessActivityProbes,
15136
15222
  getResponsivenessIntervalMs,
15137
15223
  occupancyQualificationClassifications
15138
- } = await import("../responsiveness-probe-RDF5NWRH.js");
15224
+ } = await import("../responsiveness-probe-PMH4Z3MU.js");
15139
15225
  const probeIntervalMs = getResponsivenessIntervalMs();
15140
15226
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
15141
15227
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -15245,7 +15331,7 @@ async function pollCycleInner() {
15245
15331
  collectResponsivenessProbes,
15246
15332
  livePendingInboundOldestAgeSeconds,
15247
15333
  parkPendingInbound
15248
- } = await import("../responsiveness-probe-RDF5NWRH.js");
15334
+ } = await import("../responsiveness-probe-PMH4Z3MU.js");
15249
15335
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
15250
15336
  const wedgeNow = /* @__PURE__ */ new Date();
15251
15337
  const liveAgents = agentState.persistentSessionAgents;
@@ -15401,7 +15487,7 @@ async function pollCycleInner() {
15401
15487
  }
15402
15488
  try {
15403
15489
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
15404
- const { probeSessionAuth } = await import("../session-auth-dead-KOCHZPYI.js");
15490
+ const { probeSessionAuth } = await import("../session-auth-dead-3FTENJFF.js");
15405
15491
  const observations = [];
15406
15492
  const pendingCacheCommits = [];
15407
15493
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -19365,7 +19451,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
19365
19451
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
19366
19452
  void (async () => {
19367
19453
  try {
19368
- const { collectDiagnostics } = await import("../persistent-session-V6L4Y2P5.js");
19454
+ const { collectDiagnostics } = await import("../persistent-session-VX5THUBN.js");
19369
19455
  await api.post("/host/heartbeat", {
19370
19456
  host_id: hostId,
19371
19457
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -19411,7 +19497,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
19411
19497
  }
19412
19498
  try {
19413
19499
  const hostId = await getHostId();
19414
- const { collectDiagnostics } = await import("../persistent-session-V6L4Y2P5.js");
19500
+ const { collectDiagnostics } = await import("../persistent-session-VX5THUBN.js");
19415
19501
  await api.post("/host/heartbeat", {
19416
19502
  host_id: hostId,
19417
19503
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -20047,7 +20133,7 @@ async function processClaudePairSessions(agents) {
20047
20133
  killPairSession,
20048
20134
  pairTmuxSession,
20049
20135
  finalizeClaudePairOnboarding
20050
- } = await import("../claude-pair-runtime-REZ462KO.js");
20136
+ } = await import("../claude-pair-runtime-QOHDIQBD.js");
20051
20137
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
20052
20138
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
20053
20139
  const killed = await killPairSession(pairTmuxSession(pairId));