@integrity-labs/agt-cli 0.28.625 → 0.28.626
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,7 +40,7 @@ import {
|
|
|
40
40
|
success,
|
|
41
41
|
table,
|
|
42
42
|
warn
|
|
43
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-4NCEO44Q.js";
|
|
44
44
|
import {
|
|
45
45
|
readDirectChatSessionState
|
|
46
46
|
} from "../chunk-7QNQRV3A.js";
|
|
@@ -4909,7 +4909,7 @@ import { execFileSync, execSync } from "child_process";
|
|
|
4909
4909
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
4910
4910
|
import chalk18 from "chalk";
|
|
4911
4911
|
import ora16 from "ora";
|
|
4912
|
-
var cliVersion = true ? "0.28.
|
|
4912
|
+
var cliVersion = true ? "0.28.626" : "dev";
|
|
4913
4913
|
async function fetchLatestVersion() {
|
|
4914
4914
|
const host2 = getHost();
|
|
4915
4915
|
if (!host2) return null;
|
|
@@ -6089,7 +6089,7 @@ function handleError(err) {
|
|
|
6089
6089
|
}
|
|
6090
6090
|
|
|
6091
6091
|
// src/bin/agt.ts
|
|
6092
|
-
var cliVersion2 = true ? "0.28.
|
|
6092
|
+
var cliVersion2 = true ? "0.28.626" : "dev";
|
|
6093
6093
|
var program = new Command();
|
|
6094
6094
|
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");
|
|
6095
6095
|
program.hook("preAction", async (thisCommand, actionCommand) => {
|
|
@@ -6069,7 +6069,7 @@ function exchangeFailureKind(err) {
|
|
|
6069
6069
|
}
|
|
6070
6070
|
|
|
6071
6071
|
// src/lib/api-client.ts
|
|
6072
|
-
var agtCliVersion = true ? "0.28.
|
|
6072
|
+
var agtCliVersion = true ? "0.28.626" : "dev";
|
|
6073
6073
|
var lastConfigHash = null;
|
|
6074
6074
|
function setConfigHash(hash) {
|
|
6075
6075
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -9589,4 +9589,4 @@ export {
|
|
|
9589
9589
|
managerInstallSystemUnitCommand,
|
|
9590
9590
|
managerUninstallSystemUnitCommand
|
|
9591
9591
|
};
|
|
9592
|
-
//# sourceMappingURL=chunk-
|
|
9592
|
+
//# sourceMappingURL=chunk-4NCEO44Q.js.map
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
safeWriteJsonAtomic,
|
|
55
55
|
setConfigHash,
|
|
56
56
|
tripClass
|
|
57
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-4NCEO44Q.js";
|
|
58
58
|
import {
|
|
59
59
|
getProjectDir as getProjectDir2,
|
|
60
60
|
getReadyTasks,
|
|
@@ -12033,7 +12033,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12033
12033
|
var lastVersionCheckAt = 0;
|
|
12034
12034
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12035
12035
|
var lastResponsivenessProbeAt = 0;
|
|
12036
|
-
var agtCliVersion = true ? "0.28.
|
|
12036
|
+
var agtCliVersion = true ? "0.28.626" : "dev";
|
|
12037
12037
|
function resolveBrewPath(execFileSync3) {
|
|
12038
12038
|
try {
|
|
12039
12039
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -21333,64 +21333,67 @@ var AdminDebugClient = class _AdminDebugClient {
|
|
|
21333
21333
|
};
|
|
21334
21334
|
|
|
21335
21335
|
// src/tool-schemas.ts
|
|
21336
|
+
function strictObject(shape) {
|
|
21337
|
+
return external_exports.object(shape).strict();
|
|
21338
|
+
}
|
|
21336
21339
|
var limitSchema = external_exports.number().int().min(1).max(100).optional().describe("Max rows to return (default 25, server caps at 100).");
|
|
21337
|
-
var searchAgentsSchema =
|
|
21340
|
+
var searchAgentsSchema = strictObject({
|
|
21338
21341
|
q: external_exports.string().max(128).optional().describe("Case-insensitive substring match on code_name or display_name."),
|
|
21339
21342
|
status: external_exports.string().max(32).optional().describe("Filter by agent status (draft | active | paused | revoked)."),
|
|
21340
21343
|
environment: external_exports.string().max(32).optional().describe("Filter by environment (dev | stage | prod)."),
|
|
21341
21344
|
limit: limitSchema
|
|
21342
21345
|
});
|
|
21343
|
-
var searchOrgsSchema =
|
|
21346
|
+
var searchOrgsSchema = strictObject({
|
|
21344
21347
|
q: external_exports.string().max(128).optional().describe("Case-insensitive substring match on organization name or slug."),
|
|
21345
21348
|
management_mode: external_exports.enum(["fully_managed", "self_managed"]).optional().describe("Filter by management mode (fully_managed | self_managed)."),
|
|
21346
21349
|
is_internal: external_exports.boolean().optional().describe("Filter to Integrity-Labs-internal orgs (true) or customer orgs (false)."),
|
|
21347
21350
|
limit: limitSchema
|
|
21348
21351
|
});
|
|
21349
|
-
var getAgentSchema =
|
|
21352
|
+
var getAgentSchema = strictObject({
|
|
21350
21353
|
agent_id: external_exports.string().min(1).max(64).describe("The agent UUID to fetch a composite diagnostic for.")
|
|
21351
21354
|
});
|
|
21352
|
-
var getAgentIntegrationsSchema =
|
|
21355
|
+
var getAgentIntegrationsSchema = strictObject({
|
|
21353
21356
|
agent_id: external_exports.string().min(1).max(64).describe("The agent UUID whose effective integration set to resolve.")
|
|
21354
21357
|
});
|
|
21355
|
-
var searchHostsSchema =
|
|
21358
|
+
var searchHostsSchema = strictObject({
|
|
21356
21359
|
q: external_exports.string().max(128).optional().describe("Case-insensitive substring match on host name."),
|
|
21357
21360
|
status: external_exports.string().max(32).optional().describe("Filter by host status (active | decommissioned)."),
|
|
21358
21361
|
limit: limitSchema
|
|
21359
21362
|
});
|
|
21360
|
-
var getHostSchema =
|
|
21363
|
+
var getHostSchema = strictObject({
|
|
21361
21364
|
host: external_exports.string().min(1).max(128).describe("The host id (uuid) or its exact, case-insensitive name. Use the id if the name is ambiguous."),
|
|
21362
21365
|
since_hours: external_exports.number().int().min(1).max(720).optional().describe("Window for the restart-count rollup, in hours. Default 24.")
|
|
21363
21366
|
});
|
|
21364
|
-
var inspectFlagsSchema =
|
|
21367
|
+
var inspectFlagsSchema = strictObject({
|
|
21365
21368
|
host: external_exports.string().min(1).max(128).optional().describe("The host id (uuid) or its exact, case-insensitive name. Pass this OR agent_id."),
|
|
21366
21369
|
agent_id: external_exports.string().min(1).max(64).optional().describe("The agent UUID \u2014 flags are inspected on the agent's current host. Pass this OR host.")
|
|
21367
21370
|
});
|
|
21368
|
-
var evalFailuresSchema =
|
|
21371
|
+
var evalFailuresSchema = strictObject({
|
|
21369
21372
|
period: external_exports.enum(["24h", "7d", "30d"]).optional().describe("Window to report over (24h | 7d | 30d). Default 7d."),
|
|
21370
21373
|
agent_id: external_exports.string().min(1).max(64).optional().describe("Filter to one agent (UUID); omit for a fleet-wide breakdown across your authorized orgs.")
|
|
21371
21374
|
});
|
|
21372
21375
|
var alertIdField = external_exports.string().min(1).max(64).describe("The alert id (uuid), from debug_list_alerts.");
|
|
21373
21376
|
var triageReasonField = external_exports.string().max(2e3).optional().describe("Why \u2014 recorded on the cross-org audit trail. Be specific.");
|
|
21374
|
-
var ackAlertSchema =
|
|
21377
|
+
var ackAlertSchema = strictObject({
|
|
21375
21378
|
alert_id: alertIdField,
|
|
21376
21379
|
reason: triageReasonField
|
|
21377
21380
|
});
|
|
21378
|
-
var snoozeAlertSchema =
|
|
21381
|
+
var snoozeAlertSchema = strictObject({
|
|
21379
21382
|
alert_id: alertIdField,
|
|
21380
21383
|
duration: external_exports.enum(["15m", "1h", "4h", "until_tomorrow"]).describe("How long to suppress paging: 15m | 1h | 4h | until_tomorrow (09:00 UTC next day)."),
|
|
21381
21384
|
reason: triageReasonField
|
|
21382
21385
|
});
|
|
21383
|
-
var closeAlertSchema =
|
|
21386
|
+
var closeAlertSchema = strictObject({
|
|
21384
21387
|
alert_id: alertIdField,
|
|
21385
21388
|
reason: triageReasonField
|
|
21386
21389
|
});
|
|
21387
|
-
var hostVersionsSchema =
|
|
21390
|
+
var hostVersionsSchema = strictObject({
|
|
21388
21391
|
q: external_exports.string().max(128).optional().describe("Case-insensitive substring match on host name."),
|
|
21389
21392
|
status: external_exports.string().max(32).optional().describe("Filter by host status (active | decommissioned)."),
|
|
21390
21393
|
since_hours: external_exports.number().int().min(1).max(720).optional().describe("Window for the restart count, in hours. Default 24."),
|
|
21391
21394
|
limit: limitSchema
|
|
21392
21395
|
});
|
|
21393
|
-
var tailLogsSchema =
|
|
21396
|
+
var tailLogsSchema = strictObject({
|
|
21394
21397
|
agent_id: external_exports.string().min(1).max(64).describe(
|
|
21395
21398
|
"UUID of the agent whose host log to tail. Fails closed (uniform not-found) if you are not authorized for its org."
|
|
21396
21399
|
),
|
|
@@ -21401,7 +21404,7 @@ var tailLogsSchema = external_exports.object({
|
|
|
21401
21404
|
"Trailing lines to return (default 200, max 2000). Output is also byte-capped (~20 KB, newest kept) to stay within SSM limits \u2014 `truncated` flags when it clipped."
|
|
21402
21405
|
)
|
|
21403
21406
|
});
|
|
21404
|
-
var queryLogsSchema =
|
|
21407
|
+
var queryLogsSchema = strictObject({
|
|
21405
21408
|
agent_id: external_exports.string().min(1).max(64).describe(
|
|
21406
21409
|
"UUID of the agent whose host log to query. Fails closed (uniform not-found) if you are not authorized for its org."
|
|
21407
21410
|
),
|
|
@@ -21418,7 +21421,7 @@ var queryLogsSchema = external_exports.object({
|
|
|
21418
21421
|
"Max lines to return (default 1000, max 5000; newest kept). Output is also byte-capped (~20 KB, newest kept) to stay within SSM limits \u2014 `truncated` flags when it clipped. Narrow the window if truncated."
|
|
21419
21422
|
)
|
|
21420
21423
|
});
|
|
21421
|
-
var probeIntegrationSchema =
|
|
21424
|
+
var probeIntegrationSchema = strictObject({
|
|
21422
21425
|
agent_id: external_exports.string().min(1).max(64).describe(
|
|
21423
21426
|
"UUID of the agent whose integration to probe. Fails closed (uniform not-found) if you are not authorized for its org."
|
|
21424
21427
|
),
|
|
@@ -21429,12 +21432,12 @@ var probeIntegrationSchema = external_exports.object({
|
|
|
21429
21432
|
"The integration slug (its definition code_name, e.g. `gmail`, `slack`, `here-now`) to probe on that agent."
|
|
21430
21433
|
)
|
|
21431
21434
|
});
|
|
21432
|
-
var inspectDeadLettersSchema =
|
|
21435
|
+
var inspectDeadLettersSchema = strictObject({
|
|
21433
21436
|
agent_id: external_exports.string().min(1).max(64).describe(
|
|
21434
21437
|
"UUID of the agent whose dead-lettered inbound to list. Fails closed (uniform not-found) if you are not authorized for its org."
|
|
21435
21438
|
)
|
|
21436
21439
|
});
|
|
21437
|
-
var replayDeadLetterSchema =
|
|
21440
|
+
var replayDeadLetterSchema = strictObject({
|
|
21438
21441
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose dead letter to replay."),
|
|
21439
21442
|
channel: external_exports.enum(["slack", "telegram"]).describe("Which inbound channel the dead letter belongs to (from the inspect result)."),
|
|
21440
21443
|
store: external_exports.string().min(1).max(128).regex(
|
|
@@ -21444,39 +21447,39 @@ var replayDeadLetterSchema = external_exports.object({
|
|
|
21444
21447
|
marker_name: external_exports.string().trim().min(1).max(256).describe("The exact `marker_name` from the inspect result identifying which parked message to re-inject."),
|
|
21445
21448
|
reason: external_exports.string().min(1).max(2e3).describe("Why this message should be re-injected \u2014 shown verbatim to the human approver. Be specific.")
|
|
21446
21449
|
});
|
|
21447
|
-
var inspectRestartRequestsSchema =
|
|
21450
|
+
var inspectRestartRequestsSchema = strictObject({
|
|
21448
21451
|
agent_id: external_exports.string().min(1).max(64).optional().describe(
|
|
21449
21452
|
"Optional: narrow to ONE agent's restart request. Omit for a fleet-wide list across every authorized org. Fails closed (empty) for orgs you are not authorized for."
|
|
21450
21453
|
),
|
|
21451
21454
|
limit: limitSchema
|
|
21452
21455
|
});
|
|
21453
|
-
var clearRestartRequestSchema =
|
|
21456
|
+
var clearRestartRequestSchema = strictObject({
|
|
21454
21457
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose stuck restart request to clear (from the inspect result)."),
|
|
21455
21458
|
reason: external_exports.string().min(1).max(2e3).describe("Why this stuck restart request should be cleared \u2014 shown verbatim to the human approver. Be specific.")
|
|
21456
21459
|
});
|
|
21457
|
-
var listAlertsSchema =
|
|
21460
|
+
var listAlertsSchema = strictObject({
|
|
21458
21461
|
severity: external_exports.string().max(16).optional().describe("Filter by severity (critical | warning | info)."),
|
|
21459
21462
|
open: external_exports.boolean().optional().describe("When true, only currently-open (unclosed) alerts."),
|
|
21460
21463
|
limit: limitSchema
|
|
21461
21464
|
});
|
|
21462
|
-
var requestAccessSchema =
|
|
21465
|
+
var requestAccessSchema = strictObject({
|
|
21463
21466
|
target_org_id: external_exports.string().min(1).max(64).describe("UUID of the customer organization to open scoped read access to."),
|
|
21464
21467
|
reason: external_exports.string().min(1).max(2e3).describe(
|
|
21465
21468
|
"Why access is needed \u2014 recorded on the customer-visible access log and shown to the org when they review or revoke it. Be specific."
|
|
21466
21469
|
)
|
|
21467
21470
|
});
|
|
21468
|
-
var requestActionSchema =
|
|
21471
|
+
var requestActionSchema = strictObject({
|
|
21469
21472
|
action: external_exports.enum(["restart", "clear_pending_inbound"]).describe(
|
|
21470
21473
|
"The remedial action. restart = bounce the agent (reversible; backlog replays). clear_pending_inbound = move stuck pending-inbound markers aside (drops queued inbound messages; they are NOT reprocessed)."
|
|
21471
21474
|
),
|
|
21472
21475
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent to act on."),
|
|
21473
21476
|
reason: external_exports.string().min(1).max(2e3).describe("Why this action is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21474
21477
|
});
|
|
21475
|
-
var restartAgentSchema =
|
|
21478
|
+
var restartAgentSchema = strictObject({
|
|
21476
21479
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent to restart."),
|
|
21477
21480
|
reason: external_exports.string().min(1).max(2e3).describe("Why the restart is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21478
21481
|
});
|
|
21479
|
-
var requestConfigUpdateSchema =
|
|
21482
|
+
var requestConfigUpdateSchema = strictObject({
|
|
21480
21483
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose config to change."),
|
|
21481
21484
|
field: external_exports.enum(["primary_model", "secondary_model", "tertiary_model"]).describe("The agent-config field to change. Only the model tiers are settable."),
|
|
21482
21485
|
new_value: external_exports.string().min(1).max(128).describe(
|
|
@@ -21484,17 +21487,17 @@ var requestConfigUpdateSchema = external_exports.object({
|
|
|
21484
21487
|
),
|
|
21485
21488
|
reason: external_exports.string().min(1).max(2e3).describe("Why this change is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21486
21489
|
});
|
|
21487
|
-
var checkActionStatusSchema =
|
|
21490
|
+
var checkActionStatusSchema = strictObject({
|
|
21488
21491
|
request_id: external_exports.string().min(1).max(64).describe("The action request_id returned by request_action, request_config_update, or request_ssm_run.")
|
|
21489
21492
|
});
|
|
21490
|
-
var requestSsmRunSchema =
|
|
21493
|
+
var requestSsmRunSchema = strictObject({
|
|
21491
21494
|
target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose host to run the diagnostic on."),
|
|
21492
21495
|
command: external_exports.enum(["host_health", "manager_status", "manager_journal", "process_list", "agent_dir"]).describe(
|
|
21493
21496
|
"The allowlisted, READ-ONLY diagnostic to run (closed set \u2014 no free-form shell). host_health = uptime + df -h + free -m (is the box wedged / out of disk / out of memory?); manager_status = systemctl status agt-manager.service (is the manager daemon up?); manager_journal = journalctl -u agt-manager.service -n 200 (recent systemd-captured manager output); process_list = ps (pid/ppid/user/etime/rss/comm, no argv/env) filtered to claude + agt-manager; agent_dir = ls -la ~/.augmented/<code_name>/ (file NAMES only \u2014 stuck markers, state files; never contents). For file CONTENTS use debug_tail_logs (it covers manager.log/pane.log/channel-stderr/manager-state.json)."
|
|
21494
21497
|
),
|
|
21495
21498
|
reason: external_exports.string().min(1).max(2e3).describe("Why this diagnostic is needed \u2014 shown verbatim to the human approver. Be specific.")
|
|
21496
21499
|
});
|
|
21497
|
-
var queryAuditLogSchema =
|
|
21500
|
+
var queryAuditLogSchema = strictObject({
|
|
21498
21501
|
agent_id: external_exports.string().min(1).max(64).optional().describe(
|
|
21499
21502
|
"UUID of ONE agent whose audit events to read (the read is scoped to that agent's org). Omit for a CROSS-AGENT query across all authorized orgs (optionally narrowed with org_id)."
|
|
21500
21503
|
),
|
|
@@ -21583,10 +21586,9 @@ var client = new AdminDebugClient({
|
|
|
21583
21586
|
runId: AGT_RUN_ID || void 0
|
|
21584
21587
|
});
|
|
21585
21588
|
var server = new McpServer({ name: "augmented-admin-mcp", version: package_default.version });
|
|
21586
|
-
server.
|
|
21589
|
+
server.registerTool(
|
|
21587
21590
|
"debug_search_agents",
|
|
21588
|
-
"Search managed end-user agents across authorized orgs for troubleshooting. Returns a diagnostic projection per agent (code_name, status, environment, risk_tier, org, heartbeat verdict) \u2014 never credentials or transcripts. Authorized = IL-owned + fully-managed orgs (standing) plus any self-managed org you hold an active grant for (see debug_request_access). Filter with { q, status, environment, limit }.",
|
|
21589
|
-
searchAgentsSchema.shape,
|
|
21591
|
+
{ description: "Search managed end-user agents across authorized orgs for troubleshooting. Returns a diagnostic projection per agent (code_name, status, environment, risk_tier, org, heartbeat verdict) \u2014 never credentials or transcripts. Authorized = IL-owned + fully-managed orgs (standing) plus any self-managed org you hold an active grant for (see debug_request_access). Filter with { q, status, environment, limit }.", inputSchema: searchAgentsSchema },
|
|
21590
21592
|
async (args) => {
|
|
21591
21593
|
try {
|
|
21592
21594
|
const result = await client.searchAgents(args);
|
|
@@ -21596,10 +21598,9 @@ server.tool(
|
|
|
21596
21598
|
}
|
|
21597
21599
|
}
|
|
21598
21600
|
);
|
|
21599
|
-
server.
|
|
21601
|
+
server.registerTool(
|
|
21600
21602
|
"debug_get_agent",
|
|
21601
|
-
'Fetch a composite diagnostic for ONE agent: the agent projection plus its host (heartbeat verdict, framework, EC2/auth status), its integrations, and recent alerts. The primary "why is this agent unhealthy?" read. Never returns credentials. Pass { agent_id }.\n\nThe payload carries TWO integration reads, and confusing them produces wrong root-cause (ENG-8271):\n \u2022 `effective_integrations` \u2014 the COMPLETE set the agent runs with: agent + team + ORG scope, each entry carrying `scope` ("agent" | "team" | "org") and `source_id`. Read THIS to answer "does this agent have integration X?". `effective_count` equals the manager\'s `Integrations provisioned for \'<code_name>\' (N)`, so the two reconcile; `by_scope`, `inherited_definition_ids`, `scopes_skipped`, `excluded_control_plane_only`, `shadowed_by_more_specific` and `duplicate_merge_keys` attribute any row that did not make the count.\n \u2022 `agent_integrations` \u2014 PER-AGENT rows only, kept for compatibility. Team- and org-scoped installs are ABSENT. Do NOT infer "not installed" from an absence here: an org-level install is genuinely missing from this array while being fully present on the agent. Same warning ships in-payload as `agent_integrations_note`.',
|
|
21602
|
-
getAgentSchema.shape,
|
|
21603
|
+
{ description: 'Fetch a composite diagnostic for ONE agent: the agent projection plus its host (heartbeat verdict, framework, EC2/auth status), its integrations, and recent alerts. The primary "why is this agent unhealthy?" read. Never returns credentials. Pass { agent_id }.\n\nThe payload carries TWO integration reads, and confusing them produces wrong root-cause (ENG-8271):\n \u2022 `effective_integrations` \u2014 the COMPLETE set the agent runs with: agent + team + ORG scope, each entry carrying `scope` ("agent" | "team" | "org") and `source_id`. Read THIS to answer "does this agent have integration X?". `effective_count` equals the manager\'s `Integrations provisioned for \'<code_name>\' (N)`, so the two reconcile; `by_scope`, `inherited_definition_ids`, `scopes_skipped`, `excluded_control_plane_only`, `shadowed_by_more_specific` and `duplicate_merge_keys` attribute any row that did not make the count.\n \u2022 `agent_integrations` \u2014 PER-AGENT rows only, kept for compatibility. Team- and org-scoped installs are ABSENT. Do NOT infer "not installed" from an absence here: an org-level install is genuinely missing from this array while being fully present on the agent. Same warning ships in-payload as `agent_integrations_note`.', inputSchema: getAgentSchema },
|
|
21603
21604
|
async (args) => {
|
|
21604
21605
|
try {
|
|
21605
21606
|
const result = await client.getAgent(args.agent_id);
|
|
@@ -21609,10 +21610,9 @@ server.tool(
|
|
|
21609
21610
|
}
|
|
21610
21611
|
}
|
|
21611
21612
|
);
|
|
21612
|
-
server.
|
|
21613
|
+
server.registerTool(
|
|
21613
21614
|
"debug_get_agent_integrations",
|
|
21614
|
-
'Resolve ONE agent\'s EFFECTIVE integration set \u2014 the focused read for "does this agent have integration X, and where is it installed from?" (ENG-8271). Same resolution as `debug_get_agent`\'s `effective_integrations`, without the host/alerts payload.\n\nReturns { agent_id, code_name, team_id, organization_id, effective_integrations: { effective_count, by_scope, inherited_definition_ids, excluded_control_plane_only, shadowed_by_more_specific, duplicate_merge_keys, scopes_queried, scopes_skipped, integrations[] } } - the same `effective_integrations` object `debug_get_agent` returns, so one shape covers both tools. Each entry: { definition_id, display_name, connection_key, scope ("agent" | "team" | "org"), source_id, status, status_message, auth_type, last_connectivity_check_at, last_connectivity_status, consecutive_connectivity_failures, wired_verdict, last_session_tool_bind_at }. Never credentials.\n\nPrefer this over reading `agent_integrations`: TEAM/ORG-scope installs are invisible to a per-agent read, so absence there is not evidence. `effective_count` reconciles against the manager\'s `Integrations provisioned for \'<code_name>\' (N)` or the tool-bind probe\'s `due=N`; docs/runbooks/admin-debug-dogfood.md lists the benign divergences to rule out before treating a mismatch as a bug. `wired_verdict` is the host\'s last session-tool-bind result (bound | missing | unreachable | unknown), the closest available answer to "is it in the agent\'s .mcp.json right now?"; `null` means never probed, which is NOT "not wired".\n\nFails closed (uniform not-found) for an unauthorized/unknown agent; a failed scope query returns an error rather than a smaller count. Audited as a cross-org access. Pass { agent_id }.',
|
|
21615
|
-
getAgentIntegrationsSchema.shape,
|
|
21615
|
+
{ description: 'Resolve ONE agent\'s EFFECTIVE integration set \u2014 the focused read for "does this agent have integration X, and where is it installed from?" (ENG-8271). Same resolution as `debug_get_agent`\'s `effective_integrations`, without the host/alerts payload.\n\nReturns { agent_id, code_name, team_id, organization_id, effective_integrations: { effective_count, by_scope, inherited_definition_ids, excluded_control_plane_only, shadowed_by_more_specific, duplicate_merge_keys, scopes_queried, scopes_skipped, integrations[] } } - the same `effective_integrations` object `debug_get_agent` returns, so one shape covers both tools. Each entry: { definition_id, display_name, connection_key, scope ("agent" | "team" | "org"), source_id, status, status_message, auth_type, last_connectivity_check_at, last_connectivity_status, consecutive_connectivity_failures, wired_verdict, last_session_tool_bind_at }. Never credentials.\n\nPrefer this over reading `agent_integrations`: TEAM/ORG-scope installs are invisible to a per-agent read, so absence there is not evidence. `effective_count` reconciles against the manager\'s `Integrations provisioned for \'<code_name>\' (N)` or the tool-bind probe\'s `due=N`; docs/runbooks/admin-debug-dogfood.md lists the benign divergences to rule out before treating a mismatch as a bug. `wired_verdict` is the host\'s last session-tool-bind result (bound | missing | unreachable | unknown), the closest available answer to "is it in the agent\'s .mcp.json right now?"; `null` means never probed, which is NOT "not wired".\n\nFails closed (uniform not-found) for an unauthorized/unknown agent; a failed scope query returns an error rather than a smaller count. Audited as a cross-org access. Pass { agent_id }.', inputSchema: getAgentIntegrationsSchema },
|
|
21616
21616
|
async (args) => {
|
|
21617
21617
|
try {
|
|
21618
21618
|
const result = await client.getAgentIntegrations(args.agent_id);
|
|
@@ -21622,10 +21622,9 @@ server.tool(
|
|
|
21622
21622
|
}
|
|
21623
21623
|
}
|
|
21624
21624
|
);
|
|
21625
|
-
server.
|
|
21625
|
+
server.registerTool(
|
|
21626
21626
|
"debug_search_hosts",
|
|
21627
|
-
"Search managed hosts across authorized orgs. Returns a projection per host (name, org, status, framework version, last-seen verdict, EC2 + Claude auth status) \u2014 no api-key fingerprints or secrets. Filter with { q, status, limit }.",
|
|
21628
|
-
searchHostsSchema.shape,
|
|
21627
|
+
{ description: "Search managed hosts across authorized orgs. Returns a projection per host (name, org, status, framework version, last-seen verdict, EC2 + Claude auth status) \u2014 no api-key fingerprints or secrets. Filter with { q, status, limit }.", inputSchema: searchHostsSchema },
|
|
21629
21628
|
async (args) => {
|
|
21630
21629
|
try {
|
|
21631
21630
|
const result = await client.searchHosts(args);
|
|
@@ -21635,10 +21634,9 @@ server.tool(
|
|
|
21635
21634
|
}
|
|
21636
21635
|
}
|
|
21637
21636
|
);
|
|
21638
|
-
server.
|
|
21637
|
+
server.registerTool(
|
|
21639
21638
|
"debug_get_host",
|
|
21640
|
-
"Fetch a host-centric composite for ONE host \u2014 the host equivalent of debug_get_agent, and the right entry point for host-WIDE incidents (e.g. an env drift or a bad deploy hitting every agent on a box). One read returns: the host projection (status, framework + CC version, last-seen verdict, EC2 + Claude auth), EVERY agent bound to the host (each with its own heartbeat verdict + org), a rollup of alerts (the host's own infra alerts \u2014 including NULL-team ones like host_down / probe_timeout \u2014 PLUS each bound agent's alerts), and a { agent_count, restart_count, restart_window_hours } rollup. Saves stitching debug_search_hosts + per-agent reads together. Resolve the host by its id (uuid) or its exact, case-insensitive name; an ambiguous name returns a 400 asking for the id. Returns { host: { \u2026, agents[], recent_alerts[], rollup } }. Fails closed (uniform not-found) for an unauthorized or unknown host; every call is audited as a cross-org access. Pass { host, since_hours? } (since_hours sets the restart-count window, default 24).",
|
|
21641
|
-
getHostSchema.shape,
|
|
21639
|
+
{ description: "Fetch a host-centric composite for ONE host \u2014 the host equivalent of debug_get_agent, and the right entry point for host-WIDE incidents (e.g. an env drift or a bad deploy hitting every agent on a box). One read returns: the host projection (status, framework + CC version, last-seen verdict, EC2 + Claude auth), EVERY agent bound to the host (each with its own heartbeat verdict + org), a rollup of alerts (the host's own infra alerts \u2014 including NULL-team ones like host_down / probe_timeout \u2014 PLUS each bound agent's alerts), and a { agent_count, restart_count, restart_window_hours } rollup. Saves stitching debug_search_hosts + per-agent reads together. Resolve the host by its id (uuid) or its exact, case-insensitive name; an ambiguous name returns a 400 asking for the id. Returns { host: { \u2026, agents[], recent_alerts[], rollup } }. Fails closed (uniform not-found) for an unauthorized or unknown host; every call is audited as a cross-org access. Pass { host, since_hours? } (since_hours sets the restart-count window, default 24).", inputSchema: getHostSchema },
|
|
21642
21640
|
async (args) => {
|
|
21643
21641
|
try {
|
|
21644
21642
|
const result = await client.getHost(args);
|
|
@@ -21648,10 +21646,9 @@ server.tool(
|
|
|
21648
21646
|
}
|
|
21649
21647
|
}
|
|
21650
21648
|
);
|
|
21651
|
-
server.
|
|
21649
|
+
server.registerTool(
|
|
21652
21650
|
"debug_inspect_flags",
|
|
21653
|
-
"Inspect an agent/host's EFFECTIVE feature flags WITH source attribution \u2014 the one-call answer to \"is an env override silently masking a flag?\" (the ENG-6478 / koda drift class), instead of grepping manager.log for WARN spam. For each registry flag it returns { effective, source, env_value, env_var, heartbeat_value, central_value, default_value, env_masks_heartbeat, host_stale, sensitive }. `source` mirrors how the host actually resolves a flag: env override > heartbeat-materialized (the value the control plane last sent the host) > compiled default. `env_masks_heartbeat:true` is the smoking gun for ENG-6478 (a host env gate overriding a different DB-resolved value); `host_stale:true` means the host hasn't picked up a central change. Host-side values come from the host's latest config snapshot (so snapshot:null \u21D2 the host hasn't reported one and attribution degrades to default + central). Top-level `drift_keys` lists the flags worth looking at. Pass exactly one of { host } (id or exact name) or { agent_id } (inspects its current host). Read-only; fails closed for an unauthorized/unknown target; audited as a cross-org access.",
|
|
21654
|
-
inspectFlagsSchema.shape,
|
|
21651
|
+
{ description: "Inspect an agent/host's EFFECTIVE feature flags WITH source attribution \u2014 the one-call answer to \"is an env override silently masking a flag?\" (the ENG-6478 / koda drift class), instead of grepping manager.log for WARN spam. For each registry flag it returns { effective, source, env_value, env_var, heartbeat_value, central_value, default_value, env_masks_heartbeat, host_stale, sensitive }. `source` mirrors how the host actually resolves a flag: env override > heartbeat-materialized (the value the control plane last sent the host) > compiled default. `env_masks_heartbeat:true` is the smoking gun for ENG-6478 (a host env gate overriding a different DB-resolved value); `host_stale:true` means the host hasn't picked up a central change. Host-side values come from the host's latest config snapshot (so snapshot:null \u21D2 the host hasn't reported one and attribution degrades to default + central). Top-level `drift_keys` lists the flags worth looking at. Pass exactly one of { host } (id or exact name) or { agent_id } (inspects its current host). Read-only; fails closed for an unauthorized/unknown target; audited as a cross-org access.", inputSchema: inspectFlagsSchema },
|
|
21655
21652
|
async (args) => {
|
|
21656
21653
|
try {
|
|
21657
21654
|
const hasHost = typeof args.host === "string" && args.host.length > 0;
|
|
@@ -21669,10 +21666,9 @@ server.tool(
|
|
|
21669
21666
|
}
|
|
21670
21667
|
}
|
|
21671
21668
|
);
|
|
21672
|
-
server.
|
|
21669
|
+
server.registerTool(
|
|
21673
21670
|
"debug_list_alerts",
|
|
21674
|
-
"List recent platform alerts across authorized orgs (host-down, agent-stale, probe-timeout, auth-failed), including NULL-team host alerts. Returns a projection per alert (kind, severity, message, source, open/closed state). Filter with { severity, open, limit }.",
|
|
21675
|
-
listAlertsSchema.shape,
|
|
21671
|
+
{ description: "List recent platform alerts across authorized orgs (host-down, agent-stale, probe-timeout, auth-failed), including NULL-team host alerts. Returns a projection per alert (kind, severity, message, source, open/closed state). Filter with { severity, open, limit }.", inputSchema: listAlertsSchema },
|
|
21676
21672
|
async (args) => {
|
|
21677
21673
|
try {
|
|
21678
21674
|
const result = await client.listAlerts(args);
|
|
@@ -21682,10 +21678,9 @@ server.tool(
|
|
|
21682
21678
|
}
|
|
21683
21679
|
}
|
|
21684
21680
|
);
|
|
21685
|
-
server.
|
|
21681
|
+
server.registerTool(
|
|
21686
21682
|
"debug_ack_alert",
|
|
21687
|
-
"Acknowledge an open alert \u2014 close the triage loop here instead of bouncing to the webapp. Stops escalation/paging for it without closing it. Unlike the host-affecting remedial actions this is a low-risk, reversible control-plane write (it sets acknowledged_at/by on the alert row), so it applies directly \u2014 gated by the admin-debug write mode and authorized against the alert's org (a NULL-org infra alert is IL-internal-only). Returns { alert_id, action, write_mode, applied, alert }. `applied:false` means write mode is `shadow` (validated, not written). Get the alert id from debug_list_alerts. Pass { alert_id, reason? }. Every call is audited as a cross-org access.",
|
|
21688
|
-
ackAlertSchema.shape,
|
|
21683
|
+
{ description: "Acknowledge an open alert \u2014 close the triage loop here instead of bouncing to the webapp. Stops escalation/paging for it without closing it. Unlike the host-affecting remedial actions this is a low-risk, reversible control-plane write (it sets acknowledged_at/by on the alert row), so it applies directly \u2014 gated by the admin-debug write mode and authorized against the alert's org (a NULL-org infra alert is IL-internal-only). Returns { alert_id, action, write_mode, applied, alert }. `applied:false` means write mode is `shadow` (validated, not written). Get the alert id from debug_list_alerts. Pass { alert_id, reason? }. Every call is audited as a cross-org access.", inputSchema: ackAlertSchema },
|
|
21689
21684
|
async (args) => {
|
|
21690
21685
|
try {
|
|
21691
21686
|
const result = await client.ackAlert(args);
|
|
@@ -21695,10 +21690,9 @@ server.tool(
|
|
|
21695
21690
|
}
|
|
21696
21691
|
}
|
|
21697
21692
|
);
|
|
21698
|
-
server.
|
|
21693
|
+
server.registerTool(
|
|
21699
21694
|
"debug_snooze_alert",
|
|
21700
|
-
"Snooze an open alert \u2014 suppress fresh pages for it until 15m | 1h | 4h | until_tomorrow (09:00 UTC next day), without closing it. Low-risk reversible control-plane write (sets snoozed_until); applies directly under the admin-debug write mode, authorized against the alert's org. Returns { alert_id, action, write_mode, applied, alert }; `applied:false` \u21D2 shadow mode. Pass { alert_id, duration, reason? }. Audited as a cross-org access.",
|
|
21701
|
-
snoozeAlertSchema.shape,
|
|
21695
|
+
{ description: "Snooze an open alert \u2014 suppress fresh pages for it until 15m | 1h | 4h | until_tomorrow (09:00 UTC next day), without closing it. Low-risk reversible control-plane write (sets snoozed_until); applies directly under the admin-debug write mode, authorized against the alert's org. Returns { alert_id, action, write_mode, applied, alert }; `applied:false` \u21D2 shadow mode. Pass { alert_id, duration, reason? }. Audited as a cross-org access.", inputSchema: snoozeAlertSchema },
|
|
21702
21696
|
async (args) => {
|
|
21703
21697
|
try {
|
|
21704
21698
|
const result = await client.snoozeAlert(args);
|
|
@@ -21708,10 +21702,9 @@ server.tool(
|
|
|
21708
21702
|
}
|
|
21709
21703
|
}
|
|
21710
21704
|
);
|
|
21711
|
-
server.
|
|
21705
|
+
server.registerTool(
|
|
21712
21706
|
"debug_close_alert",
|
|
21713
|
-
"Close an open alert (closed_reason=manual) \u2014 resolve it from here when you've confirmed it's handled, instead of the webapp. Low-risk control-plane write (sets closed_at + closed_reason); applies directly under the admin-debug write mode, authorized against the alert's org. Only OPEN alerts can be closed (a 409 means it was already closed). Returns { alert_id, action, write_mode, applied, alert }; `applied:false` \u21D2 shadow mode. Pass { alert_id, reason? }. Audited as a cross-org access.",
|
|
21714
|
-
closeAlertSchema.shape,
|
|
21707
|
+
{ description: "Close an open alert (closed_reason=manual) \u2014 resolve it from here when you've confirmed it's handled, instead of the webapp. Low-risk control-plane write (sets closed_at + closed_reason); applies directly under the admin-debug write mode, authorized against the alert's org. Only OPEN alerts can be closed (a 409 means it was already closed). Returns { alert_id, action, write_mode, applied, alert }; `applied:false` \u21D2 shadow mode. Pass { alert_id, reason? }. Audited as a cross-org access.", inputSchema: closeAlertSchema },
|
|
21715
21708
|
async (args) => {
|
|
21716
21709
|
try {
|
|
21717
21710
|
const result = await client.closeAlert(args);
|
|
@@ -21721,10 +21714,9 @@ server.tool(
|
|
|
21721
21714
|
}
|
|
21722
21715
|
}
|
|
21723
21716
|
);
|
|
21724
|
-
server.
|
|
21717
|
+
server.registerTool(
|
|
21725
21718
|
"debug_search_orgs",
|
|
21726
|
-
`List the ORGANIZATIONS you're authorized to read \u2014 the org-level entry point for triage and access decisions, so you don't have to infer orgs off agent/host rows or probe one org's tier with debug_request_access. Returns a projection per org: { organization_id, organization_slug, display_name, is_internal, management_mode (fully_managed | self_managed), standing_reason (internal | fully_managed | granted \u2014 WHY you can read it), has_active_grant (do you hold a live grant right now), host_count, agent_count, active_agent_count, open_alert_count, created_at }. Use it to (1) decide access in one read \u2014 see a self_managed org and its grant state before deciding to debug_request_access; (2) triage the fleet \u2014 "which orgs have open alerts" (open_alert_count includes stuck-restart alerts) without walking agents; (3) disambiguate a slug \u2192 id \u2192 tier without needing an agent/host to exist. Authorized = IL-owned (is_internal) + fully-managed orgs (standing) plus any self-managed org you hold an active grant for. Filter with { q (slug/name substring), management_mode, is_internal, limit }. Projection only \u2014 no secrets, no transcripts; org-walled in SQL and audited as a cross-org access.`,
|
|
21727
|
-
searchOrgsSchema.shape,
|
|
21719
|
+
{ description: `List the ORGANIZATIONS you're authorized to read \u2014 the org-level entry point for triage and access decisions, so you don't have to infer orgs off agent/host rows or probe one org's tier with debug_request_access. Returns a projection per org: { organization_id, organization_slug, display_name, is_internal, management_mode (fully_managed | self_managed), standing_reason (internal | fully_managed | granted \u2014 WHY you can read it), has_active_grant (do you hold a live grant right now), host_count, agent_count, active_agent_count, open_alert_count, created_at }. Use it to (1) decide access in one read \u2014 see a self_managed org and its grant state before deciding to debug_request_access; (2) triage the fleet \u2014 "which orgs have open alerts" (open_alert_count includes stuck-restart alerts) without walking agents; (3) disambiguate a slug \u2192 id \u2192 tier without needing an agent/host to exist. Authorized = IL-owned (is_internal) + fully-managed orgs (standing) plus any self-managed org you hold an active grant for. Filter with { q (slug/name substring), management_mode, is_internal, limit }. Projection only \u2014 no secrets, no transcripts; org-walled in SQL and audited as a cross-org access.`, inputSchema: searchOrgsSchema },
|
|
21728
21720
|
async (args) => {
|
|
21729
21721
|
try {
|
|
21730
21722
|
const result = await client.searchOrgs(args);
|
|
@@ -21734,10 +21726,9 @@ server.tool(
|
|
|
21734
21726
|
}
|
|
21735
21727
|
}
|
|
21736
21728
|
);
|
|
21737
|
-
server.
|
|
21729
|
+
server.registerTool(
|
|
21738
21730
|
"debug_host_versions",
|
|
21739
|
-
'Fleet-wide host health snapshot for triaging "which host is unhealthy?". Returns a projection per authorized host: { id, name, org, framework, framework_version (the Claude Code version the host runs), last_seen_verdict, agent_count, restart_count, restart_window_hours }. `restart_count` tallies `agent.restart` audit events across the host\'s agents within the window (default 24h) \u2014 a high count is the tell for a thrashing host. Use it to spot version skew (an old framework_version) or restart storms across the fleet at a glance. Filter with { q, status, since_hours, limit }.',
|
|
21740
|
-
hostVersionsSchema.shape,
|
|
21731
|
+
{ description: 'Fleet-wide host health snapshot for triaging "which host is unhealthy?". Returns a projection per authorized host: { id, name, org, framework, framework_version (the Claude Code version the host runs), last_seen_verdict, agent_count, restart_count, restart_window_hours }. `restart_count` tallies `agent.restart` audit events across the host\'s agents within the window (default 24h) \u2014 a high count is the tell for a thrashing host. Use it to spot version skew (an old framework_version) or restart storms across the fleet at a glance. Filter with { q, status, since_hours, limit }.', inputSchema: hostVersionsSchema },
|
|
21741
21732
|
async (args) => {
|
|
21742
21733
|
try {
|
|
21743
21734
|
const result = await client.hostVersions(args);
|
|
@@ -21747,10 +21738,9 @@ server.tool(
|
|
|
21747
21738
|
}
|
|
21748
21739
|
}
|
|
21749
21740
|
);
|
|
21750
|
-
server.
|
|
21741
|
+
server.registerTool(
|
|
21751
21742
|
"debug_tail_logs",
|
|
21752
|
-
"Live-tail an agent's HOST logs over SSM to ground-truth \"what was it actually doing?\" \u2014 the host-reaching read, used after debug_get_agent points at a sick agent. Resolves the agent's current host and returns the trailing lines of ONE allowlisted operational log: { agent_id, code_name, host, log, content (the tail), log_present, lines_requested, truncated, ssm_status }. Logs: `manager` (manager.log \u2014 respawn/wedge/lifecycle), `pane` (pane.log \u2014 the tmux pane, the agent's visible I/O, e.g. a stuck AskUserQuestion), `slack-stderr`/`telegram-stderr`/`direct-chat-stderr` (a channel MCP's crash output, e.g. attachment-download 400s), `manager-state` (manager-state.json). Fails closed for an unauthorized org. Only operational logs are reachable \u2014 secret files (.mcp.json, .env.integrations) are NOT. Pass { agent_id, log?, lines? } (lines default 200, max 2000; output ~20 KB-capped, newest kept). Every call is audited as a cross-org host access.",
|
|
21753
|
-
tailLogsSchema.shape,
|
|
21743
|
+
{ description: "Live-tail an agent's HOST logs over SSM to ground-truth \"what was it actually doing?\" \u2014 the host-reaching read, used after debug_get_agent points at a sick agent. Resolves the agent's current host and returns the trailing lines of ONE allowlisted operational log: { agent_id, code_name, host, log, content (the tail), log_present, lines_requested, truncated, ssm_status }. Logs: `manager` (manager.log \u2014 respawn/wedge/lifecycle), `pane` (pane.log \u2014 the tmux pane, the agent's visible I/O, e.g. a stuck AskUserQuestion), `slack-stderr`/`telegram-stderr`/`direct-chat-stderr` (a channel MCP's crash output, e.g. attachment-download 400s), `manager-state` (manager-state.json). Fails closed for an unauthorized org. Only operational logs are reachable \u2014 secret files (.mcp.json, .env.integrations) are NOT. Pass { agent_id, log?, lines? } (lines default 200, max 2000; output ~20 KB-capped, newest kept). Every call is audited as a cross-org host access.", inputSchema: tailLogsSchema },
|
|
21754
21744
|
async (args) => {
|
|
21755
21745
|
try {
|
|
21756
21746
|
const result = await client.tailLogs(args);
|
|
@@ -21760,10 +21750,9 @@ server.tool(
|
|
|
21760
21750
|
}
|
|
21761
21751
|
}
|
|
21762
21752
|
);
|
|
21763
|
-
server.
|
|
21753
|
+
server.registerTool(
|
|
21764
21754
|
"debug_query_logs",
|
|
21765
|
-
'Read an agent\'s HOST logs OVER A TIME WINDOW, spanning rotated files \u2014 the historical counterpart to debug_tail_logs. Where tail only shows the live tail of the current file (minutes, and gone once it rotates), this reads the active log AND its logrotate siblings (manager.log-YYYYMMDD, manager.log-YYYYMMDD.gz, \u2026 7 days kept on-host) and filters lines to [since, until]. Windows older than 7 days return nothing: those rotations have been archived to S3, and hosts are write-only to that bucket by design, so an older window needs an operator S3 fetch rather than this tool (ENG-8330). Seven days is the ONE local-retention window for everything the host archives, Claude session transcripts included. This is the read path for "did it restart at 4pm YESTERDAY?" \u2014 use it when the answer is older than the live tail or spans a rotation. Returns { agent_id, code_name, host, log, since, until, time_filtered, content, log_present, lines_requested, truncated, ssm_status }. Time filtering applies to `manager` (its lines carry an ISO8601 prefix); `pane`/`slack-stderr`/`telegram-stderr`/`direct-chat-stderr`/`manager-state`/`channel-quarantine` return their byte-capped tail unfiltered (time_filtered:false \u2014 the last two are JSON, not line-oriented). Only operational logs are reachable \u2014 secret files (.mcp.json, .env.integrations) are NOT. Pass { agent_id, log?, since?, until?, lines? } (since/until ISO8601 UTC e.g. 2026-06-14T16:00:00Z, default unbounded; lines default 1000, max 5000; output ~20 KB-capped, newest kept \u2014 narrow the window if truncated). Fails closed for an unauthorized org; every call is audited as a cross-org host access.',
|
|
21766
|
-
queryLogsSchema.shape,
|
|
21755
|
+
{ description: 'Read an agent\'s HOST logs OVER A TIME WINDOW, spanning rotated files \u2014 the historical counterpart to debug_tail_logs. Where tail only shows the live tail of the current file (minutes, and gone once it rotates), this reads the active log AND its logrotate siblings (manager.log-YYYYMMDD, manager.log-YYYYMMDD.gz, \u2026 7 days kept on-host) and filters lines to [since, until]. Windows older than 7 days return nothing: those rotations have been archived to S3, and hosts are write-only to that bucket by design, so an older window needs an operator S3 fetch rather than this tool (ENG-8330). Seven days is the ONE local-retention window for everything the host archives, Claude session transcripts included. This is the read path for "did it restart at 4pm YESTERDAY?" \u2014 use it when the answer is older than the live tail or spans a rotation. Returns { agent_id, code_name, host, log, since, until, time_filtered, content, log_present, lines_requested, truncated, ssm_status }. Time filtering applies to `manager` (its lines carry an ISO8601 prefix); `pane`/`slack-stderr`/`telegram-stderr`/`direct-chat-stderr`/`manager-state`/`channel-quarantine` return their byte-capped tail unfiltered (time_filtered:false \u2014 the last two are JSON, not line-oriented). Only operational logs are reachable \u2014 secret files (.mcp.json, .env.integrations) are NOT. Pass { agent_id, log?, since?, until?, lines? } (since/until ISO8601 UTC e.g. 2026-06-14T16:00:00Z, default unbounded; lines default 1000, max 5000; output ~20 KB-capped, newest kept \u2014 narrow the window if truncated). Fails closed for an unauthorized org; every call is audited as a cross-org host access.', inputSchema: queryLogsSchema },
|
|
21767
21756
|
async (args) => {
|
|
21768
21757
|
try {
|
|
21769
21758
|
const result = await client.queryLogs(args);
|
|
@@ -21773,10 +21762,9 @@ server.tool(
|
|
|
21773
21762
|
}
|
|
21774
21763
|
}
|
|
21775
21764
|
);
|
|
21776
|
-
server.
|
|
21765
|
+
server.registerTool(
|
|
21777
21766
|
"debug_eval_failures",
|
|
21778
|
-
'Report WHY conversations could not be scored by the host-side success evaluator: the failure counterpart to the "conversation success" trend, which only ever shows EVALUATED conversations (so an agent whose conversations all fail to reconstruct silently vanishes from it). Use when conversation scores look thin/absent for an agent, or to audit eval coverage fleet-wide. Returns { scope, period, scanned, truncated, report, recent }. `report` is the aggregate: { total, gaveUp (subset that hit the retry cap, will never be scored), byReason[] (org-wide count + gaveUp per reason), perAgent[] (worst-first standing) }. The three reasons are data-shaped: `no_transcript` (the host had no local transcript at all), `not_reconstructable` (transcripts exist but none carry the conversation\'s channel ref), `empty_transcript` (turns reconstructed but rendered to nothing). `recent` is the newest failing conversations (boundary + reason only, NEVER transcript content). NOTE: transient/misconfigured EVAL BACKEND failures are NOT here; those show on the host (hosts.eval_backend_*), check debug_get_host. Pass { period? (24h|7d|30d, default 7d), agent_id? (omit for fleet-wide) }. Org-walled in SQL; every call is audited as a cross-org access.',
|
|
21779
|
-
evalFailuresSchema.shape,
|
|
21767
|
+
{ description: 'Report WHY conversations could not be scored by the host-side success evaluator: the failure counterpart to the "conversation success" trend, which only ever shows EVALUATED conversations (so an agent whose conversations all fail to reconstruct silently vanishes from it). Use when conversation scores look thin/absent for an agent, or to audit eval coverage fleet-wide. Returns { scope, period, scanned, truncated, report, recent }. `report` is the aggregate: { total, gaveUp (subset that hit the retry cap, will never be scored), byReason[] (org-wide count + gaveUp per reason), perAgent[] (worst-first standing) }. The three reasons are data-shaped: `no_transcript` (the host had no local transcript at all), `not_reconstructable` (transcripts exist but none carry the conversation\'s channel ref), `empty_transcript` (turns reconstructed but rendered to nothing). `recent` is the newest failing conversations (boundary + reason only, NEVER transcript content). NOTE: transient/misconfigured EVAL BACKEND failures are NOT here; those show on the host (hosts.eval_backend_*), check debug_get_host. Pass { period? (24h|7d|30d, default 7d), agent_id? (omit for fleet-wide) }. Org-walled in SQL; every call is audited as a cross-org access.', inputSchema: evalFailuresSchema },
|
|
21780
21768
|
async (args) => {
|
|
21781
21769
|
try {
|
|
21782
21770
|
const result = await client.evalFailures(args);
|
|
@@ -21786,10 +21774,9 @@ server.tool(
|
|
|
21786
21774
|
}
|
|
21787
21775
|
}
|
|
21788
21776
|
);
|
|
21789
|
-
server.
|
|
21777
|
+
server.registerTool(
|
|
21790
21778
|
"debug_probe_integration",
|
|
21791
|
-
"Force a FRESH host-side connectivity probe for ONE of an agent's integrations and return the LIVE verdict \u2014 use when a user reports an integration \"isn't working\" but the console shows it connected, or to confirm a fix landed. Unlike the cached status the dashboard shows, this SSH-less SSM-invokes the agent's host to run the probe against its actual wired `.mcp.json` + credentials, so it can't disagree with reality. Returns { agent_id, code_name, slug, host, verdict, message, probed_at, ssm_status }. `verdict` is the live result: `ok` | `degraded` | `transient_error` (retryable) | `down` | `not_probeable` (no probe wired for this kind) \u2014 or a central degrade: `unreachable` (agent has no host), `not_installed` (integration not on this agent), `host_cli_too_old` (the host predates the probe \u2014 update its agt-cli), `probe_error`. Pass { agent_id, slug } where slug is the integration's definition code_name (e.g. `gmail`, `slack`, `here-now`). Fails closed for an unauthorized org; every call is audited as a cross-org host access.",
|
|
21792
|
-
probeIntegrationSchema.shape,
|
|
21779
|
+
{ description: "Force a FRESH host-side connectivity probe for ONE of an agent's integrations and return the LIVE verdict \u2014 use when a user reports an integration \"isn't working\" but the console shows it connected, or to confirm a fix landed. Unlike the cached status the dashboard shows, this SSH-less SSM-invokes the agent's host to run the probe against its actual wired `.mcp.json` + credentials, so it can't disagree with reality. Returns { agent_id, code_name, slug, host, verdict, message, probed_at, ssm_status }. `verdict` is the live result: `ok` | `degraded` | `transient_error` (retryable) | `down` | `not_probeable` (no probe wired for this kind) \u2014 or a central degrade: `unreachable` (agent has no host), `not_installed` (integration not on this agent), `host_cli_too_old` (the host predates the probe \u2014 update its agt-cli), `probe_error`. Pass { agent_id, slug } where slug is the integration's definition code_name (e.g. `gmail`, `slack`, `here-now`). Fails closed for an unauthorized org; every call is audited as a cross-org host access.", inputSchema: probeIntegrationSchema },
|
|
21793
21780
|
async (args) => {
|
|
21794
21781
|
try {
|
|
21795
21782
|
const result = await client.probeIntegration(args);
|
|
@@ -21799,10 +21786,9 @@ server.tool(
|
|
|
21799
21786
|
}
|
|
21800
21787
|
}
|
|
21801
21788
|
);
|
|
21802
|
-
server.
|
|
21789
|
+
server.registerTool(
|
|
21803
21790
|
"debug_inspect_dead_letters",
|
|
21804
|
-
"List an agent's DEAD-LETTERED / quarantined inbound \u2014 customer messages that were parked on the host instead of delivered (so the agent never saw them), rather than silently lost. Use when a user says \"the agent never replied\" but nothing shows in the normal flow, or to audit what fell into the dead-letter path. Resolves the agent's current host and reads two on-disk stores over SSM: `stale` (markers moved aside on a wedge-respawn because the agent couldn't receive) and `cleared:<stamp>` (markers the clear_pending_inbound remedial action moved aside). Returns { agent_id, code_name, host, markers[], total, ssm_status } where each marker is { index, store, channel (slack|telegram), marker_name, received_at, undeliverable, discretionary, replay_count, conversation, message_ref } \u2014 routing metadata only, NEVER the message body. To re-inject one, pass its exact { channel, store, marker_name } to debug_replay_dead_letter. Fails closed for an unauthorized org; every call is audited as a cross-org host access. Pass { agent_id }.",
|
|
21805
|
-
inspectDeadLettersSchema.shape,
|
|
21791
|
+
{ description: "List an agent's DEAD-LETTERED / quarantined inbound \u2014 customer messages that were parked on the host instead of delivered (so the agent never saw them), rather than silently lost. Use when a user says \"the agent never replied\" but nothing shows in the normal flow, or to audit what fell into the dead-letter path. Resolves the agent's current host and reads two on-disk stores over SSM: `stale` (markers moved aside on a wedge-respawn because the agent couldn't receive) and `cleared:<stamp>` (markers the clear_pending_inbound remedial action moved aside). Returns { agent_id, code_name, host, markers[], total, ssm_status } where each marker is { index, store, channel (slack|telegram), marker_name, received_at, undeliverable, discretionary, replay_count, conversation, message_ref } \u2014 routing metadata only, NEVER the message body. To re-inject one, pass its exact { channel, store, marker_name } to debug_replay_dead_letter. Fails closed for an unauthorized org; every call is audited as a cross-org host access. Pass { agent_id }.", inputSchema: inspectDeadLettersSchema },
|
|
21806
21792
|
async (args) => {
|
|
21807
21793
|
try {
|
|
21808
21794
|
const result = await client.inspectDeadLetters(args);
|
|
@@ -21812,10 +21798,9 @@ server.tool(
|
|
|
21812
21798
|
}
|
|
21813
21799
|
}
|
|
21814
21800
|
);
|
|
21815
|
-
server.
|
|
21801
|
+
server.registerTool(
|
|
21816
21802
|
"debug_inspect_restart_requests",
|
|
21817
|
-
'List STUCK / pending agent restart requests across authorized orgs \u2014 the agent_restart_stuck class. A restart request is "stuck" when the manager never acked it (e.g. one sat open on an agent for ~27 days). Use this when an agent went quiet and you suspect a restart that never landed, or to audit the fleet for unacked restarts. Returns { requests[], count } where each request is { agent_id, code_name, organization_id, host, restart_requested_at, stuck_seconds, is_stuck, incident, alert } \u2014 `is_stuck` flags age past the alert threshold (15 min); `incident`/`alert` carry the open ledger row + paged alert when the cron has escalated it. Routing metadata only, never message content. To cancel one, pass its agent_id to request_clear_restart_request. Pass { agent_id? (narrow to one), limit? }; fleet-wide when agent_id is omitted. Org-walled in SQL; every call is audited as a cross-org access.',
|
|
21818
|
-
inspectRestartRequestsSchema.shape,
|
|
21803
|
+
{ description: 'List STUCK / pending agent restart requests across authorized orgs \u2014 the agent_restart_stuck class. A restart request is "stuck" when the manager never acked it (e.g. one sat open on an agent for ~27 days). Use this when an agent went quiet and you suspect a restart that never landed, or to audit the fleet for unacked restarts. Returns { requests[], count } where each request is { agent_id, code_name, organization_id, host, restart_requested_at, stuck_seconds, is_stuck, incident, alert } \u2014 `is_stuck` flags age past the alert threshold (15 min); `incident`/`alert` carry the open ledger row + paged alert when the cron has escalated it. Routing metadata only, never message content. To cancel one, pass its agent_id to request_clear_restart_request. Pass { agent_id? (narrow to one), limit? }; fleet-wide when agent_id is omitted. Org-walled in SQL; every call is audited as a cross-org access.', inputSchema: inspectRestartRequestsSchema },
|
|
21819
21804
|
async (args) => {
|
|
21820
21805
|
try {
|
|
21821
21806
|
const result = await client.inspectRestartRequests(args);
|
|
@@ -21825,10 +21810,9 @@ server.tool(
|
|
|
21825
21810
|
}
|
|
21826
21811
|
}
|
|
21827
21812
|
);
|
|
21828
|
-
server.
|
|
21813
|
+
server.registerTool(
|
|
21829
21814
|
"request_clear_restart_request",
|
|
21830
|
-
"Request a HITL-gated CLEAR of a STUCK restart request \u2014 cancel a restart the manager never acked (listed by debug_inspect_restart_requests) and resolve its agent_restart_stuck alert. Use it to clear a restart signal wedged open for hours/days/weeks. This is NOT a restart and NOT a host action: it nulls the agent's `restart_requested_at` signal in the central DB and closes the alert/incident; the agent keeps running as-is, no in-flight work is destroyed. Reversible \u2014 request a fresh restart afterwards if one is still needed. A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). Async: returns { request_id, status, write_mode, notification_status }; after approval, poll check_action_status (result_payload carries { cleared_bindings, alert_closed }). Pass { target_agent_id, reason }.",
|
|
21831
|
-
clearRestartRequestSchema.shape,
|
|
21815
|
+
{ description: "Request a HITL-gated CLEAR of a STUCK restart request \u2014 cancel a restart the manager never acked (listed by debug_inspect_restart_requests) and resolve its agent_restart_stuck alert. Use it to clear a restart signal wedged open for hours/days/weeks. This is NOT a restart and NOT a host action: it nulls the agent's `restart_requested_at` signal in the central DB and closes the alert/incident; the agent keeps running as-is, no in-flight work is destroyed. Reversible \u2014 request a fresh restart afterwards if one is still needed. A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). Async: returns { request_id, status, write_mode, notification_status }; after approval, poll check_action_status (result_payload carries { cleared_bindings, alert_closed }). Pass { target_agent_id, reason }.", inputSchema: clearRestartRequestSchema },
|
|
21832
21816
|
async (args) => {
|
|
21833
21817
|
try {
|
|
21834
21818
|
const result = await client.requestClearRestartRequest({
|
|
@@ -21841,10 +21825,9 @@ server.tool(
|
|
|
21841
21825
|
}
|
|
21842
21826
|
}
|
|
21843
21827
|
);
|
|
21844
|
-
server.
|
|
21828
|
+
server.registerTool(
|
|
21845
21829
|
"debug_query_audit_log",
|
|
21846
|
-
'Read recent audit events to troubleshoot why/when agents bounced \u2014 primarily restart events. Defaults to the "agent.restart" action: each event returns { created_at, source, reason, detail, actor_kind, agent_id, code_name }, where `source` is the restart trigger (agent-self-request, channel-command, maintenance-window, stale-mcp, hot-reload-mcp, mcp-presence-reaper, day-rollover, auth-tuple-change, \u2026) and `reason` is the free-text rationale when one was given (e.g. the agent\'s own words for a request_restart). `detail` (ENG-8293) is the structured "what changed?" payload, null for sources that don\'t emit one. For `auth-tuple-change` it is { auth_tuple: { changed[], unchanged[], components[] } } naming WHICH credential/identity component moved and its before/after fingerprint \u2014 the auth tuple is deliberately NOT keyed on the rotating access token, so an auth-tuple-change is always a genuine credential or identity change, and `detail.auth_tuple.changed` is how you tell which one. Comparing `components[].to` across agents answers whether a restart WAVE was one control-plane push (same new value everywhere) or coincidental per-agent rotations. Two modes: (1) pass { agent_id } to scope to ONE agent (fails closed if you\'re not authorized for its org) \u2014 use when a specific agent went quiet. (2) OMIT agent_id for a CROSS-AGENT sweep across every org you\'re authorized for (optionally narrow with { org_id }) \u2014 use to spot fleet-wide restart storms or compare agents. Filter the action with `action` (pass "all" to drop the action filter and read every event type), and bound with { since_hours?, limit? }. Cross-agent results are org-walled in SQL; unauthorized orgs are invisible.',
|
|
21847
|
-
queryAuditLogSchema.shape,
|
|
21830
|
+
{ description: 'Read recent audit events to troubleshoot why/when agents bounced \u2014 primarily restart events. Defaults to the "agent.restart" action: each event returns { created_at, source, reason, detail, actor_kind, agent_id, code_name }, where `source` is the restart trigger (agent-self-request, channel-command, maintenance-window, stale-mcp, hot-reload-mcp, mcp-presence-reaper, day-rollover, auth-tuple-change, \u2026) and `reason` is the free-text rationale when one was given (e.g. the agent\'s own words for a request_restart). `detail` (ENG-8293) is the structured "what changed?" payload, null for sources that don\'t emit one. For `auth-tuple-change` it is { auth_tuple: { changed[], unchanged[], components[] } } naming WHICH credential/identity component moved and its before/after fingerprint \u2014 the auth tuple is deliberately NOT keyed on the rotating access token, so an auth-tuple-change is always a genuine credential or identity change, and `detail.auth_tuple.changed` is how you tell which one. Comparing `components[].to` across agents answers whether a restart WAVE was one control-plane push (same new value everywhere) or coincidental per-agent rotations. Two modes: (1) pass { agent_id } to scope to ONE agent (fails closed if you\'re not authorized for its org) \u2014 use when a specific agent went quiet. (2) OMIT agent_id for a CROSS-AGENT sweep across every org you\'re authorized for (optionally narrow with { org_id }) \u2014 use to spot fleet-wide restart storms or compare agents. Filter the action with `action` (pass "all" to drop the action filter and read every event type), and bound with { since_hours?, limit? }. Cross-agent results are org-walled in SQL; unauthorized orgs are invisible.', inputSchema: queryAuditLogSchema },
|
|
21848
21831
|
async (args) => {
|
|
21849
21832
|
try {
|
|
21850
21833
|
const result = await client.queryAuditLog(args);
|
|
@@ -21854,10 +21837,9 @@ server.tool(
|
|
|
21854
21837
|
}
|
|
21855
21838
|
}
|
|
21856
21839
|
);
|
|
21857
|
-
server.
|
|
21840
|
+
server.registerTool(
|
|
21858
21841
|
"debug_request_access",
|
|
21859
|
-
"Open scoped READ access to a SELF-MANAGED customer org so the read tools (debug_search_agents / debug_get_agent / debug_search_hosts / debug_list_alerts) can reach it. Use this when a read returns nothing for an org you have a legitimate support reason to troubleshoot. It mints a short-TTL, logged, customer-revocable read grant \u2014 the customer sees the access in their Support-access console and can revoke it, and it auto-expires; it does NOT grant any write/remedial capability. For an already-authorized org (Integrity-Labs-internal or fully-managed) this returns { already_authorized: true } instead of minting a redundant grant \u2014 just use the read tools. Pass { target_org_id, reason }; the reason is recorded verbatim on the customer-visible access log, so be specific.",
|
|
21860
|
-
requestAccessSchema.shape,
|
|
21842
|
+
{ description: "Open scoped READ access to a SELF-MANAGED customer org so the read tools (debug_search_agents / debug_get_agent / debug_search_hosts / debug_list_alerts) can reach it. Use this when a read returns nothing for an org you have a legitimate support reason to troubleshoot. It mints a short-TTL, logged, customer-revocable read grant \u2014 the customer sees the access in their Support-access console and can revoke it, and it auto-expires; it does NOT grant any write/remedial capability. For an already-authorized org (Integrity-Labs-internal or fully-managed) this returns { already_authorized: true } instead of minting a redundant grant \u2014 just use the read tools. Pass { target_org_id, reason }; the reason is recorded verbatim on the customer-visible access log, so be specific.", inputSchema: requestAccessSchema },
|
|
21861
21843
|
async (args) => {
|
|
21862
21844
|
try {
|
|
21863
21845
|
const result = await client.requestAccess({
|
|
@@ -21870,10 +21852,9 @@ server.tool(
|
|
|
21870
21852
|
}
|
|
21871
21853
|
}
|
|
21872
21854
|
);
|
|
21873
|
-
server.
|
|
21855
|
+
server.registerTool(
|
|
21874
21856
|
"request_action",
|
|
21875
|
-
`Request a HITL-gated remedial action on a customer agent: "restart" (bounce the agent \u2014 reversible, backlog replays) or "clear_pending_inbound" (move stuck pending-inbound markers aside \u2014 drops queued inbound messages, NOT reprocessed). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { action, target_agent_id, reason }.`,
|
|
21876
|
-
requestActionSchema.shape,
|
|
21857
|
+
{ description: `Request a HITL-gated remedial action on a customer agent: "restart" (bounce the agent \u2014 reversible, backlog replays) or "clear_pending_inbound" (move stuck pending-inbound markers aside \u2014 drops queued inbound messages, NOT reprocessed). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { action, target_agent_id, reason }.`, inputSchema: requestActionSchema },
|
|
21877
21858
|
async (args) => {
|
|
21878
21859
|
try {
|
|
21879
21860
|
const result = await client.requestAction(args.action, {
|
|
@@ -21886,10 +21867,9 @@ server.tool(
|
|
|
21886
21867
|
}
|
|
21887
21868
|
}
|
|
21888
21869
|
);
|
|
21889
|
-
server.
|
|
21870
|
+
server.registerTool(
|
|
21890
21871
|
"debug_restart_agent",
|
|
21891
|
-
`Request a HITL-gated RESTART of a customer agent \u2014 bounce its session so the manager respawns it on the next poll (reversible; the inbound backlog replays). Use this to recover a wedged agent or to make it pick up a newly-bound integration/config change. A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Org-agnostic: keyed on the agent's host assignment, so it works cross-org without an active-org dependency. This is the same path as request_action({ action: "restart" }), exposed as a dedicated tool for discoverability. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { target_agent_id, reason }.`,
|
|
21892
|
-
restartAgentSchema.shape,
|
|
21872
|
+
{ description: `Request a HITL-gated RESTART of a customer agent \u2014 bounce its session so the manager respawns it on the next poll (reversible; the inbound backlog replays). Use this to recover a wedged agent or to make it pick up a newly-bound integration/config change. A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Org-agnostic: keyed on the agent's host assignment, so it works cross-org without an active-org dependency. This is the same path as request_action({ action: "restart" }), exposed as a dedicated tool for discoverability. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { target_agent_id, reason }.`, inputSchema: restartAgentSchema },
|
|
21893
21873
|
async (args) => {
|
|
21894
21874
|
try {
|
|
21895
21875
|
const result = await client.requestAction("restart", {
|
|
@@ -21902,10 +21882,9 @@ server.tool(
|
|
|
21902
21882
|
}
|
|
21903
21883
|
}
|
|
21904
21884
|
);
|
|
21905
|
-
server.
|
|
21885
|
+
server.registerTool(
|
|
21906
21886
|
"request_config_update",
|
|
21907
|
-
"Request a HITL-gated change to a customer agent's model config (primary/secondary/tertiary_model). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). The change is reversible and applies at the agent's NEXT session launch after /host/refresh \u2014 it does not restart the agent. The new value is validated against the agent before approval is requested: Claude Code (subscription) agents take a family alias (fable/opus/opus[fast]/sonnet/haiku); routed agents take a full stored model id (e.g. openrouter/anthropic/claude-opus-4-6). Use this to fix a misconfigured model (e.g. an agent wedged on a model its auth can't access). Returns { request_id, status, write_mode, notification_status }. Pass { target_agent_id, field, new_value, reason }.",
|
|
21908
|
-
requestConfigUpdateSchema.shape,
|
|
21887
|
+
{ description: "Request a HITL-gated change to a customer agent's model config (primary/secondary/tertiary_model). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). The change is reversible and applies at the agent's NEXT session launch after /host/refresh \u2014 it does not restart the agent. The new value is validated against the agent before approval is requested: Claude Code (subscription) agents take a family alias (fable/opus/opus[fast]/sonnet/haiku); routed agents take a full stored model id (e.g. openrouter/anthropic/claude-opus-4-6). Use this to fix a misconfigured model (e.g. an agent wedged on a model its auth can't access). Returns { request_id, status, write_mode, notification_status }. Pass { target_agent_id, field, new_value, reason }.", inputSchema: requestConfigUpdateSchema },
|
|
21909
21888
|
async (args) => {
|
|
21910
21889
|
try {
|
|
21911
21890
|
const result = await client.requestConfigUpdate({
|
|
@@ -21920,10 +21899,9 @@ server.tool(
|
|
|
21920
21899
|
}
|
|
21921
21900
|
}
|
|
21922
21901
|
);
|
|
21923
|
-
server.
|
|
21902
|
+
server.registerTool(
|
|
21924
21903
|
"request_ssm_run",
|
|
21925
|
-
"Request a HITL-gated, ALLOWLISTED read-only DIAGNOSTIC command on a customer agent's host over SSM \u2014 the escape hatch for host/process/service facts the typed read tools (debug_get_agent, debug_tail_logs, debug_host_versions) don't cover. A HUMAN must approve the EXACT command in Slack before it runs, and only if writes are armed (shadow mode runs the approval but executes nothing). This is NOT a shell: `command` is a CLOSED enum \u2014 host_health (uptime/df/free), manager_status (systemctl status agt-manager), manager_journal (journalctl -n 200), process_list (ps comm-only, no argv/env), agent_dir (ls -la ~/.augmented/<code_name>/, names only). No free-form commands, no file-content reads (use debug_tail_logs for log contents). Async: returns { request_id, status, write_mode, command_key, resolved_command, notification_status }; after approval, poll check_action_status to read the command OUTPUT in result_payload. Pass { target_agent_id, command, reason }.",
|
|
21926
|
-
requestSsmRunSchema.shape,
|
|
21904
|
+
{ description: "Request a HITL-gated, ALLOWLISTED read-only DIAGNOSTIC command on a customer agent's host over SSM \u2014 the escape hatch for host/process/service facts the typed read tools (debug_get_agent, debug_tail_logs, debug_host_versions) don't cover. A HUMAN must approve the EXACT command in Slack before it runs, and only if writes are armed (shadow mode runs the approval but executes nothing). This is NOT a shell: `command` is a CLOSED enum \u2014 host_health (uptime/df/free), manager_status (systemctl status agt-manager), manager_journal (journalctl -n 200), process_list (ps comm-only, no argv/env), agent_dir (ls -la ~/.augmented/<code_name>/, names only). No free-form commands, no file-content reads (use debug_tail_logs for log contents). Async: returns { request_id, status, write_mode, command_key, resolved_command, notification_status }; after approval, poll check_action_status to read the command OUTPUT in result_payload. Pass { target_agent_id, command, reason }.", inputSchema: requestSsmRunSchema },
|
|
21927
21905
|
async (args) => {
|
|
21928
21906
|
try {
|
|
21929
21907
|
const result = await client.requestSsmRun({
|
|
@@ -21937,10 +21915,9 @@ server.tool(
|
|
|
21937
21915
|
}
|
|
21938
21916
|
}
|
|
21939
21917
|
);
|
|
21940
|
-
server.
|
|
21918
|
+
server.registerTool(
|
|
21941
21919
|
"debug_replay_dead_letter",
|
|
21942
|
-
"Request a HITL-gated REPLAY of ONE dead-lettered inbound \u2014 re-inject a customer message that was parked on the host (listed by debug_inspect_dead_letters) back into the agent's live inbound so it is reprocessed. This is the inverse of clear_pending_inbound: use it to recover a message a wedged agent missed. A HUMAN must approve in Slack before anything happens, and only if writes are armed (shadow mode runs the approval but executes nothing). The marker is matched on the host by the exact (channel, store, marker_name) you pass \u2014 copy them verbatim from the inspect result \u2014 so a stale or wrong selector safely no-ops (`replayed:false, reason:not_found`) rather than moving the wrong message. Async: returns { request_id, status, write_mode, notification_status }; after approval, poll check_action_status (result_payload carries { replayed, moved_to }). Pass { target_agent_id, channel, store, marker_name, reason }.",
|
|
21943
|
-
replayDeadLetterSchema.shape,
|
|
21920
|
+
{ description: "Request a HITL-gated REPLAY of ONE dead-lettered inbound \u2014 re-inject a customer message that was parked on the host (listed by debug_inspect_dead_letters) back into the agent's live inbound so it is reprocessed. This is the inverse of clear_pending_inbound: use it to recover a message a wedged agent missed. A HUMAN must approve in Slack before anything happens, and only if writes are armed (shadow mode runs the approval but executes nothing). The marker is matched on the host by the exact (channel, store, marker_name) you pass \u2014 copy them verbatim from the inspect result \u2014 so a stale or wrong selector safely no-ops (`replayed:false, reason:not_found`) rather than moving the wrong message. Async: returns { request_id, status, write_mode, notification_status }; after approval, poll check_action_status (result_payload carries { replayed, moved_to }). Pass { target_agent_id, channel, store, marker_name, reason }.", inputSchema: replayDeadLetterSchema },
|
|
21944
21921
|
async (args) => {
|
|
21945
21922
|
try {
|
|
21946
21923
|
const result = await client.requestReplayDeadLetter({
|
|
@@ -21956,10 +21933,9 @@ server.tool(
|
|
|
21956
21933
|
}
|
|
21957
21934
|
}
|
|
21958
21935
|
);
|
|
21959
|
-
server.
|
|
21936
|
+
server.registerTool(
|
|
21960
21937
|
"check_action_status",
|
|
21961
|
-
"Poll the decision on a remedial action you requested (the approval result is also pushed to you via direct-chat). Returns { status, result_payload, denial_reason, resolved_at } \u2014 for an approved request_ssm_run, result_payload carries the command output; for debug_replay_dead_letter, result_payload carries { replayed, moved_to }. Pass { request_id }.",
|
|
21962
|
-
checkActionStatusSchema.shape,
|
|
21938
|
+
{ description: "Poll the decision on a remedial action you requested (the approval result is also pushed to you via direct-chat). Returns { status, result_payload, denial_reason, resolved_at } \u2014 for an approved request_ssm_run, result_payload carries the command output; for debug_replay_dead_letter, result_payload carries { replayed, moved_to }. Pass { request_id }.", inputSchema: checkActionStatusSchema },
|
|
21963
21939
|
async (args) => {
|
|
21964
21940
|
try {
|
|
21965
21941
|
const result = await client.getActionStatus(args.request_id);
|
package/package.json
CHANGED
|
File without changes
|