@integrity-labs/agt-cli 0.28.957 → 0.28.959

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/dist/bin/agt.js CHANGED
@@ -40,12 +40,12 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-W4WCFH5J.js";
43
+ } from "../chunk-MSVXOKWK.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
47
47
  readDirectChatSessionState
48
- } from "../chunk-WU3POTSH.js";
48
+ } from "../chunk-JDULE5NX.js";
49
49
  import {
50
50
  AnchorSessionClient,
51
51
  CHANNEL_REGISTRY,
@@ -79,7 +79,7 @@ import {
79
79
  serializeManifestForSlackCli,
80
80
  sessionFileExists,
81
81
  sessionTranscriptDir
82
- } from "../chunk-CRM7ITIY.js";
82
+ } from "../chunk-KCAFGTQM.js";
83
83
  import "../chunk-DHWNVVX4.js";
84
84
  import "../chunk-XWVM4KPK.js";
85
85
 
@@ -5471,7 +5471,7 @@ import { execFileSync, execSync } from "child_process";
5471
5471
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5472
5472
  import chalk18 from "chalk";
5473
5473
  import ora16 from "ora";
5474
- var cliVersion = true ? "0.28.957" : "dev";
5474
+ var cliVersion = true ? "0.28.959" : "dev";
5475
5475
  async function fetchLatestVersion() {
5476
5476
  const host2 = getHost();
5477
5477
  if (!host2) return null;
@@ -6731,7 +6731,7 @@ function handleError(err) {
6731
6731
  }
6732
6732
 
6733
6733
  // src/bin/agt.ts
6734
- var cliVersion2 = true ? "0.28.957" : "dev";
6734
+ var cliVersion2 = true ? "0.28.959" : "dev";
6735
6735
  var program = new Command();
6736
6736
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6737
6737
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -4,6 +4,7 @@ import {
4
4
  PLATFORM_STORAGE_RULE,
5
5
  SECRET_PATTERNS,
6
6
  claudeModelAlias,
7
+ containerMemoryForAgentClass,
7
8
  encodeClaudeProjectPath,
8
9
  getOrCreateDailySession,
9
10
  isClaudeFastMode,
@@ -19,7 +20,7 @@ import {
19
20
  rotateDailySession,
20
21
  sessionFileExists,
21
22
  todayLocalIso
22
- } from "./chunk-CRM7ITIY.js";
23
+ } from "./chunk-KCAFGTQM.js";
23
24
  import {
24
25
  classifyUnanswerablePane,
25
26
  findUsageLimitResetHint,
@@ -146,6 +147,121 @@ function hardBoundedCapture(file, args, opts) {
146
147
  return r.kind === "ok" ? r.stdout : null;
147
148
  }
148
149
 
150
+ // src/lib/container-memory-sync.ts
151
+ var DOCKER_MEMORY_OVERRIDE = /^[1-9]\d*[bkmg]?$/i;
152
+ var DOCKER_MIN_MEMORY_BYTES = 6 * 1024 ** 2;
153
+ function validMemoryOverride() {
154
+ const raw = process.env.AGT_ISOLATION_MEMORY?.trim();
155
+ if (!raw || !DOCKER_MEMORY_OVERRIDE.test(raw)) return null;
156
+ const bytes = parseDockerMemoryBytes(raw);
157
+ return bytes !== null && bytes >= DOCKER_MIN_MEMORY_BYTES ? raw : null;
158
+ }
159
+ function isInvalidMemoryOverride() {
160
+ const raw = process.env.AGT_ISOLATION_MEMORY?.trim();
161
+ return !!raw && validMemoryOverride() === null;
162
+ }
163
+ function resolveContainerMemory(agentClass) {
164
+ return validMemoryOverride() ?? containerMemoryForAgentClass(agentClass);
165
+ }
166
+ var UNIT_BYTES = {
167
+ "": 1,
168
+ k: 1024,
169
+ m: 1024 ** 2,
170
+ g: 1024 ** 3,
171
+ t: 1024 ** 4
172
+ };
173
+ function parseDockerMemoryBytes(value) {
174
+ const m = /^\s*(\d+(?:\.\d+)?)\s*([kmgt]?)(?:i?b)?\s*$/i.exec(value);
175
+ if (!m) return null;
176
+ const bytes = Math.floor(Number(m[1]) * UNIT_BYTES[m[2].toLowerCase()]);
177
+ return Number.isSafeInteger(bytes) && bytes > 0 ? bytes : null;
178
+ }
179
+ var defaultDeps = (log2) => ({
180
+ exec: (args) => hardBoundedExecFile("docker", args, { timeoutMs: 15e3 }),
181
+ log: log2
182
+ });
183
+ var appliedBytesBySession = /* @__PURE__ */ new Map();
184
+ var lastLogBySession = /* @__PURE__ */ new Map();
185
+ function logOnce(deps, codeName, msg) {
186
+ if (lastLogBySession.get(codeName) === msg) return;
187
+ lastLogBySession.set(codeName, msg);
188
+ deps.log(msg);
189
+ }
190
+ function seedContainerMemory(codeName, memory) {
191
+ const bytes = parseDockerMemoryBytes(memory);
192
+ if (bytes === null) appliedBytesBySession.delete(codeName);
193
+ else appliedBytesBySession.set(codeName, bytes);
194
+ lastLogBySession.delete(codeName);
195
+ }
196
+ function syncContainerMemory(codeName, agentClass, log2, deps = defaultDeps(log2)) {
197
+ const desired = resolveContainerMemory(agentClass);
198
+ const desiredBytes = parseDockerMemoryBytes(desired);
199
+ const container = `agt-${codeName}`;
200
+ if (isInvalidMemoryOverride()) {
201
+ logOnce(
202
+ deps,
203
+ `${codeName}:override`,
204
+ `[isolation-memory] AGT_ISOLATION_MEMORY='${process.env.AGT_ISOLATION_MEMORY}' is not a valid Docker memory size (integer with optional b/k/m/g, at least 6m) \u2014 ignored; using the agent_class ceiling ${desired}`
205
+ );
206
+ }
207
+ if (desiredBytes === null) {
208
+ logOnce(deps, codeName, `[isolation-memory] '${codeName}': unparseable memory ceiling '${desired}' \u2014 not applied`);
209
+ return "failed";
210
+ }
211
+ let currentBytes = appliedBytesBySession.get(codeName);
212
+ if (currentBytes === void 0) {
213
+ const inspected = deps.exec(["inspect", "-f", "{{.HostConfig.Memory}}", container]);
214
+ const parsed = inspected.kind === "ok" ? Number(inspected.stdout.trim()) : NaN;
215
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
216
+ logOnce(
217
+ deps,
218
+ codeName,
219
+ `[isolation-memory] '${codeName}': could not read ${container}'s memory ceiling (${describe(inspected)}) \u2014 will retry`
220
+ );
221
+ return "failed";
222
+ }
223
+ currentBytes = parsed === 0 ? Number.POSITIVE_INFINITY : parsed;
224
+ appliedBytesBySession.set(codeName, currentBytes);
225
+ }
226
+ if (currentBytes === desiredBytes) {
227
+ lastLogBySession.delete(codeName);
228
+ return "unchanged";
229
+ }
230
+ if (currentBytes > desiredBytes) {
231
+ logOnce(
232
+ deps,
233
+ codeName,
234
+ `[isolation-memory] '${codeName}': ceiling ${formatBytes(currentBytes)} -> ${desired} (agent_class=${String(agentClass)}) is a decrease \u2014 deferred to the next respawn, not applied live (lowering memory.max under use OOM-kills inside the container)`
235
+ );
236
+ return "deferred-lower";
237
+ }
238
+ const updated = deps.exec(["update", "--memory", desired, "--memory-swap", desired, container]);
239
+ if (updated.kind !== "ok") {
240
+ logOnce(
241
+ deps,
242
+ codeName,
243
+ `[isolation-memory] '${codeName}': docker update to ${desired} failed (${describe(updated)}) \u2014 will retry`
244
+ );
245
+ return "failed";
246
+ }
247
+ appliedBytesBySession.set(codeName, desiredBytes);
248
+ lastLogBySession.delete(codeName);
249
+ deps.log(
250
+ `[isolation-memory] '${codeName}': ceiling ${formatBytes(currentBytes)} -> ${desired} (agent_class=${String(agentClass)}), applied live`
251
+ );
252
+ return "raised";
253
+ }
254
+ function describe(r) {
255
+ if (r.kind === "ok") return `unexpected output '${r.stdout.trim().slice(0, 80)}'`;
256
+ if (r.kind === "timed-out") return "timed out";
257
+ return r.message.trim().slice(0, 200) || `exit ${r.status}`;
258
+ }
259
+ function formatBytes(bytes) {
260
+ if (!Number.isFinite(bytes)) return "unlimited";
261
+ const gib = bytes / 1024 ** 3;
262
+ return Number.isInteger(gib) ? `${gib}g` : `${Math.round(bytes / 1024 ** 2)}m`;
263
+ }
264
+
149
265
  // src/lib/persistent-session.ts
150
266
  import { join as join7, dirname as dirname5 } from "path";
151
267
  import { homedir as homedir5, platform, userInfo as userInfo2 } from "os";
@@ -3735,7 +3851,7 @@ function ensureClaudeStateLayout(args) {
3735
3851
  mkdirSync6(join7(projects, encodeClaudeProjectPath(args.projectDir)), { recursive: true });
3736
3852
  }
3737
3853
  function buildDockerRunCommand(args) {
3738
- const { codeName, agentId, wrapperPath, projectDir, homeDir, runId, passApiKey, passOpenRouter, passModelPolicyGateway, passModelPolicyModel, egress, forwardSlackReplyBinding, forwardBlockTurnEndAllMarkers, forwardKanbanWaiting, forwardNotifyDispatch, forwardTurnFailureNotice, forwardChannelSecrets } = args;
3854
+ const { codeName, agentId, wrapperPath, projectDir, homeDir, runId, passApiKey, passOpenRouter, passModelPolicyGateway, passModelPolicyModel, egress, forwardSlackReplyBinding, forwardBlockTurnEndAllMarkers, forwardKanbanWaiting, forwardNotifyDispatch, forwardTurnFailureNotice, forwardChannelSecrets, agentClass } = args;
3739
3855
  const q = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
3740
3856
  const agentDir2 = join7(homeDir, ".augmented", codeName);
3741
3857
  const agentIdDir = join7(homeDir, ".augmented", agentId);
@@ -3761,7 +3877,7 @@ function buildDockerRunCommand(args) {
3761
3877
  ...CLAUDE_NULLED_FILES.map((name) => `-v ${q(`/dev/null:${join7(claudeHome, name)}`)}`)
3762
3878
  ];
3763
3879
  const image = process.env.AGT_ISOLATION_IMAGE || "agt-runtime:latest";
3764
- const memory = process.env.AGT_ISOLATION_MEMORY || "2g";
3880
+ const memory = resolveContainerMemory(agentClass);
3765
3881
  const memorySwap = memory;
3766
3882
  const cpus = process.env.AGT_ISOLATION_CPUS || "1.0";
3767
3883
  const pids = process.env.AGT_ISOLATION_PIDS || "512";
@@ -4574,7 +4690,9 @@ function spawnSession(config, session) {
4574
4690
  // no longer carries them for the in-container wrapper to source, so
4575
4691
  // without the forward `${SLACK_BOT_TOKEN}` resolves empty and the
4576
4692
  // channel MCP dies. Empty/undef ⇒ no forwards (file-sourced as before).
4577
- forwardChannelSecrets: config.channelSpawnSecrets ? Object.keys(config.channelSpawnSecrets) : void 0
4693
+ forwardChannelSecrets: config.channelSpawnSecrets ? Object.keys(config.channelSpawnSecrets) : void 0,
4694
+ // ENG-10641: the memory ceiling follows the agent's class.
4695
+ agentClass: config.agentClass
4578
4696
  }) : JSON.stringify(wrapperPath);
4579
4697
  const tmuxEnv = buildSpawnEnv({
4580
4698
  base: process.env,
@@ -5357,6 +5475,9 @@ export {
5357
5475
  LATE_BOUND_VARS,
5358
5476
  expandTemplateVars,
5359
5477
  parseEnvIntegrations,
5478
+ resolveContainerMemory,
5479
+ seedContainerMemory,
5480
+ syncContainerMemory,
5360
5481
  agentRuntimeKey,
5361
5482
  log,
5362
5483
  sha256,
@@ -5454,4 +5575,4 @@ export {
5454
5575
  stopAllSessionsAndWait,
5455
5576
  getProjectDir
5456
5577
  };
5457
- //# sourceMappingURL=chunk-WU3POTSH.js.map
5578
+ //# sourceMappingURL=chunk-JDULE5NX.js.map