@posthog/wizard 2.81.1 → 2.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-interface-DMP3DZRd.js → agent-interface-fcDXqb-_.js} +285 -66
- package/dist/agent-interface-fcDXqb-_.js.map +1 -0
- package/dist/{agent-prompt-loader-BrivWIna.js → agent-prompt-loader-F9gGPMt0.js} +6 -6
- package/dist/{agent-prompt-loader-BrivWIna.js.map → agent-prompt-loader-F9gGPMt0.js.map} +1 -1
- package/dist/analytics-C9QnGvuc.js +2 -0
- package/dist/{analytics-X7JfAmh6.js → analytics-GQv--mQm.js} +6 -4
- package/dist/analytics-GQv--mQm.js.map +1 -0
- package/dist/api-CsXfZKkq.js +2 -0
- package/dist/{api-BkDwZoL4.js → api-WUOSLXPJ.js} +71 -3
- package/dist/{api-BkDwZoL4.js.map → api-WUOSLXPJ.js.map} +1 -1
- package/dist/api-key-login-CDSxsYtP.js +2 -0
- package/dist/{api-key-login-DE0yKkP4.js → api-key-login-tysMeZnR.js} +5 -5
- package/dist/{api-key-login-DE0yKkP4.js.map → api-key-login-tysMeZnR.js.map} +1 -1
- package/dist/bin.js +1 -1
- package/dist/{bounded-fs-iDiqDQ9v.js → bounded-fs-B31zq2ir.js} +6 -4
- package/dist/bounded-fs-B31zq2ir.js.map +1 -0
- package/dist/{ci-install-BAftKh2Z.js → ci-install-CYSFbFXd.js} +4 -4
- package/dist/{ci-install-BAftKh2Z.js.map → ci-install-CYSFbFXd.js.map} +1 -1
- package/dist/{debug-C3tLP-ZW.js → debug-BTUMatFI.js} +3 -3
- package/dist/{debug-C3tLP-ZW.js.map → debug-BTUMatFI.js.map} +1 -1
- package/dist/{gateway-IQjQ582o.js → gateway-CJ8Jqbll.js} +20 -6
- package/dist/{gateway-IQjQ582o.js.map → gateway-CJ8Jqbll.js.map} +1 -1
- package/dist/{headless-XNvdWVEp.js → headless-DZ3mq07K.js} +1 -1
- package/dist/{headless-DOhxEmw5.js → headless-le-QqOuj.js} +2 -2
- package/dist/{headless-DOhxEmw5.js.map → headless-le-QqOuj.js.map} +1 -1
- package/dist/{host-resolution-DI2oucSK.js → host-resolution-Cht8bL39.js} +4 -4
- package/dist/{host-resolution-DI2oucSK.js.map → host-resolution-Cht8bL39.js.map} +1 -1
- package/dist/{install-DaZ6pvEl.js → install-55JbRsO-.js} +1 -1
- package/dist/{install-BixbBDLR.js → install-BhnFP3p3.js} +5 -5
- package/dist/{install-BixbBDLR.js.map → install-BhnFP3p3.js.map} +1 -1
- package/dist/{interactive-WLNQWF0D.js → interactive-9qRL8259.js} +3 -3
- package/dist/{interactive-WLNQWF0D.js.map → interactive-9qRL8259.js.map} +1 -1
- package/dist/{links-Bye4fsrj.js → links-5Blqk4Im.js} +3 -3
- package/dist/{links-Bye4fsrj.js.map → links-5Blqk4Im.js.map} +1 -1
- package/dist/{main-CN8nbuZO.js → main-CUIcozEG.js} +24 -21
- package/dist/main-CUIcozEG.js.map +1 -0
- package/dist/{mcp-B2o4d9DS.js → mcp-D73aCOHK.js} +3 -3
- package/dist/{mcp-B2o4d9DS.js.map → mcp-D73aCOHK.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-COs1DfAm.js → mcp-prompt-streaming-B5lIQ0l1.js} +5 -5
- package/dist/{mcp-prompt-streaming-COs1DfAm.js.map → mcp-prompt-streaming-B5lIQ0l1.js.map} +1 -1
- package/dist/{models-Cow22jET.js → models-CLTglHFZ.js} +6 -2
- package/dist/models-CLTglHFZ.js.map +1 -0
- package/dist/{oauth-session-Bj_-BY7o.js → oauth-session-CfkZ339p.js} +45 -3
- package/dist/oauth-session-CfkZ339p.js.map +1 -0
- package/dist/{orchestrator-tools-lhFIBGnp.js → orchestrator-tools-lvNVQhzs.js} +3 -3
- package/dist/{orchestrator-tools-lhFIBGnp.js.map → orchestrator-tools-lvNVQhzs.js.map} +1 -1
- package/dist/{package-manager-DZ4wcTz3.js → package-manager-BqRNp5y_.js} +4 -4
- package/dist/{package-manager-DZ4wcTz3.js.map → package-manager-BqRNp5y_.js.map} +1 -1
- package/dist/{pi-DREdQRPP.js → pi-2pYz2OY3.js} +61 -24
- package/dist/pi-2pYz2OY3.js.map +1 -0
- package/dist/{playground-CJx3lwTH.js → playground-jxZNxRwC.js} +4 -4
- package/dist/{playground-CJx3lwTH.js.map → playground-jxZNxRwC.js.map} +1 -1
- package/dist/{posthog-integration-DDSPdbpw.js → posthog-integration-DxRkw5DI.js} +79 -36
- package/dist/posthog-integration-DxRkw5DI.js.map +1 -0
- package/dist/{programs-DvlhdeM_.js → programs-D2793-PK.js} +2 -2
- package/dist/{programs-6SFfUBmm.js → programs-eTv2T2rs.js} +142 -62
- package/dist/programs-eTv2T2rs.js.map +1 -0
- package/dist/provisioning-CtQ0GEHa.js +2 -0
- package/dist/{provisioning-tRDPH7EQ.js → provisioning-c5JJ30KX.js} +4 -4
- package/dist/{provisioning-tRDPH7EQ.js.map → provisioning-c5JJ30KX.js.map} +1 -1
- package/dist/{queue-tools-DrJKvFHZ.js → queue-tools-10w8lhEs.js} +14 -5
- package/dist/queue-tools-10w8lhEs.js.map +1 -0
- package/dist/{results-Crcubw0Q.js → results-C45prSKD.js} +2 -2
- package/dist/{results-Crcubw0Q.js.map → results-C45prSKD.js.map} +1 -1
- package/dist/{run-DVFTMbxf.js → run-CM24OgPF.js} +10 -10
- package/dist/{run-DVFTMbxf.js.map → run-CM24OgPF.js.map} +1 -1
- package/dist/{run-BrIGaPy7.js → run-jugssomh.js} +7 -7
- package/dist/{run-BrIGaPy7.js.map → run-jugssomh.js.map} +1 -1
- package/dist/run-tool-BZFgFb_2.js +2 -0
- package/dist/{run-tool-CxdPXmlY.js → run-tool-DZrZFoGq.js} +13 -13
- package/dist/{run-tool-CxdPXmlY.js.map → run-tool-DZrZFoGq.js.map} +1 -1
- package/dist/{runners-loOOmHyc.js → runners-CoIYt0iI.js} +8 -8
- package/dist/{runners-loOOmHyc.js.map → runners-CoIYt0iI.js.map} +1 -1
- package/dist/{security-C_grSgIM.js → security-ppK2MwCn.js} +6 -5
- package/dist/{security-C_grSgIM.js.map → security-ppK2MwCn.js.map} +1 -1
- package/dist/{setup-utils-BYXbb9NM.js → setup-utils-B5E1rXLa.js} +3 -3
- package/dist/{setup-utils-BYXbb9NM.js.map → setup-utils-B5E1rXLa.js.map} +1 -1
- package/dist/{start-playground-Blh0Swil.js → start-playground-DujiUNFT.js} +7 -7
- package/dist/{start-playground-Blh0Swil.js.map → start-playground-DujiUNFT.js.map} +1 -1
- package/dist/{subagent-DQ_enM8C.js → subagent-BdDWA8j5.js} +12 -4
- package/dist/subagent-BdDWA8j5.js.map +1 -0
- package/dist/{task-Dm9wZbVW.js → task-Y8lWoDE7.js} +46 -23
- package/dist/task-Y8lWoDE7.js.map +1 -0
- package/dist/{telemetry-NeZhrBeW.js → telemetry-Cwqf0iur.js} +2 -2
- package/dist/{telemetry-NeZhrBeW.js.map → telemetry-Cwqf0iur.js.map} +1 -1
- package/dist/{terminal-Z4hCXfie.js → terminal-BLL-X6YP.js} +401 -41
- package/dist/terminal-BLL-X6YP.js.map +1 -0
- package/dist/{tools-dUJHRo6X.js → tools-C8k90ISV.js} +13 -13
- package/dist/{tools-dUJHRo6X.js.map → tools-C8k90ISV.js.map} +1 -1
- package/dist/{tools-1aM6bI9Y.js → tools-g42e5kJz.js} +15 -11
- package/dist/tools-g42e5kJz.js.map +1 -0
- package/dist/{tui-CCO7VVTA.js → tui-BPWJ-J-k.js} +1 -1
- package/dist/{tui-Cmi_ckGg.js → tui-CBnRWnrm.js} +4 -4
- package/dist/tui-CBnRWnrm.js.map +1 -0
- package/dist/{upload-step-e2Jp2fcr.js → upload-step-CFoxwd5t.js} +3 -3
- package/dist/{upload-step-e2Jp2fcr.js.map → upload-step-CFoxwd5t.js.map} +1 -1
- package/dist/{urls-Cu4RO30x.js → urls-BTZhm5eA.js} +2 -2
- package/dist/{urls-Cu4RO30x.js.map → urls-BTZhm5eA.js.map} +1 -1
- package/dist/{wizard-abort-BPEiPCXk.js → wizard-abort-HtpiSsQO.js} +4 -4
- package/dist/{wizard-abort-BPEiPCXk.js.map → wizard-abort-HtpiSsQO.js.map} +1 -1
- package/dist/{yara-hooks-canFIYTc.js → yara-hooks-BPYhN9WM.js} +4 -4
- package/dist/{yara-hooks-canFIYTc.js.map → yara-hooks-BPYhN9WM.js.map} +1 -1
- package/dist/{yara-hooks-CFD60h78.js → yara-hooks-BwhEDXIt.js} +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-DMP3DZRd.js.map +0 -1
- package/dist/analytics-X7JfAmh6.js.map +0 -1
- package/dist/analytics-dcL9EQ4r.js +0 -2
- package/dist/api-BrMGAI-b.js +0 -2
- package/dist/api-key-login-CZEgx2jb.js +0 -2
- package/dist/bounded-fs-iDiqDQ9v.js.map +0 -1
- package/dist/main-CN8nbuZO.js.map +0 -1
- package/dist/models-Cow22jET.js.map +0 -1
- package/dist/oauth-session-Bj_-BY7o.js.map +0 -1
- package/dist/pi-DREdQRPP.js.map +0 -1
- package/dist/posthog-integration-DDSPdbpw.js.map +0 -1
- package/dist/programs-6SFfUBmm.js.map +0 -1
- package/dist/provisioning-CPGWgv7p.js +0 -2
- package/dist/queue-tools-DrJKvFHZ.js.map +0 -1
- package/dist/run-tool-GfISLgEs.js +0 -2
- package/dist/subagent-DQ_enM8C.js.map +0 -1
- package/dist/task-Dm9wZbVW.js.map +0 -1
- package/dist/terminal-Z4hCXfie.js.map +0 -1
- package/dist/tools-1aM6bI9Y.js.map +0 -1
- package/dist/tui-Cmi_ckGg.js.map +0 -1
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import { a as initLogFile, i as getLogFilePath, o as logToFile, r as formatLogLine, v as runtimeEnv } from "./debug-
|
|
2
|
-
import {
|
|
1
|
+
import { a as initLogFile, i as getLogFilePath, o as logToFile, r as formatLogLine, v as runtimeEnv } from "./debug-BTUMatFI.js";
|
|
2
|
+
import { at as wizardUserAgentForProgram, et as WIZARD_REMARK_EVENT_NAME, l as AWS_SKILLS_BASE_URL, n as analytics } from "./analytics-GQv--mQm.js";
|
|
3
3
|
import { i as classifyAuthFailure } from "./errors-DhFeR8Sp.js";
|
|
4
|
-
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-
|
|
5
|
-
import { c as
|
|
6
|
-
import { i as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-B31zq2ir.js";
|
|
5
|
+
import { c as isGrantRevoked, i as oauthCredentials, s as rotateAfterUnauthorized } from "./oauth-session-CfkZ339p.js";
|
|
6
|
+
import { c as REMARK_INSTRUCTION, d as buildWizardPropertiesBlob, f as gatewayAuth, i as gatewayApiFor, l as RESUME_INSTRUCTION, n as buildGatewayModel, p as isPastRefresh, s as AgentSignals, u as policyAbortReason } from "./gateway-CJ8Jqbll.js";
|
|
7
|
+
import { i as modelCapabilities, o as triageModelFor } from "./models-CLTglHFZ.js";
|
|
8
|
+
import { d as taskReported, l as buildOrchestratorTools, v as makeMutex, y as writeJsonAtomic } from "./queue-tools-10w8lhEs.js";
|
|
9
|
+
import { C as coerceAuditChecks, _ as downloadSkill, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks, x as AUDIT_CHECKS_FILE, y as fetchSkillMenu } from "./yara-hooks-BPYhN9WM.js";
|
|
10
|
+
import { a as createMarkdownNotebook, f as updateMarkdownNotebook, s as fetchMarkdownNotebook } from "./api-WUOSLXPJ.js";
|
|
9
11
|
import { createRequire } from "node:module";
|
|
10
|
-
import * as fs$
|
|
12
|
+
import * as fs$2 from "fs";
|
|
11
13
|
import fs from "fs";
|
|
12
14
|
import path from "path";
|
|
13
15
|
import path$1 from "node:path";
|
|
14
16
|
import { spawnSync } from "node:child_process";
|
|
15
17
|
import { closeSync, constants, fchmodSync, lstatSync, openSync, renameSync, unlinkSync, writeSync } from "node:fs";
|
|
16
|
-
import
|
|
18
|
+
import axios from "axios";
|
|
19
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
17
20
|
import * as os from "os";
|
|
21
|
+
import { readFile } from "fs/promises";
|
|
18
22
|
import { minimatch } from "minimatch";
|
|
19
23
|
import { randomUUID as randomUUID$1 } from "crypto";
|
|
20
24
|
import { z } from "zod";
|
|
@@ -62,6 +66,11 @@ function createTriageLLMProvider(auth, harness) {
|
|
|
62
66
|
});
|
|
63
67
|
const text = message.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
64
68
|
if (message.stopReason === "error") logToFile(`[YARA] triage call failed on ${model.id}: ${message.errorMessage ?? "unknown"} — every flagged match will be acted on`);
|
|
69
|
+
const refusal = policyAbortReason(text);
|
|
70
|
+
if (refusal) {
|
|
71
|
+
logToFile(`[YARA] gateway policy refused the triage call: ${refusal}`);
|
|
72
|
+
throw new Error("AI gateway refused the triage call");
|
|
73
|
+
}
|
|
65
74
|
return text;
|
|
66
75
|
} finally {
|
|
67
76
|
clearTimeout(timer);
|
|
@@ -1518,6 +1527,173 @@ const WIZARD_TOOL_NAMES = {
|
|
|
1518
1527
|
readHandoffs: `mcp__${SERVER_NAME}__read_handoffs`
|
|
1519
1528
|
};
|
|
1520
1529
|
//#endregion
|
|
1530
|
+
//#region src/agent/tools/handoff-notebook.ts
|
|
1531
|
+
/**
|
|
1532
|
+
* The PostHog notebook that mirrors a run's handoff report. The first call of a
|
|
1533
|
+
* run creates it, later calls (a report task retry) update the same one, so a
|
|
1534
|
+
* run owns one notebook. It never throws: a notebook that can't be written is a
|
|
1535
|
+
* skip the caller reports, not a failed handoff.
|
|
1536
|
+
*/
|
|
1537
|
+
const NOTEBOOK_SCOPE = "notebook:write";
|
|
1538
|
+
const DEFAULT_TITLE = "PostHog setup report";
|
|
1539
|
+
/** One deadline for the whole sync, so a slow PostHog cannot hold the agent's tool call. */
|
|
1540
|
+
const SYNC_DEADLINE_MS = 8e3;
|
|
1541
|
+
/** The notebook each program of a run holds: where to update it and the version to send. */
|
|
1542
|
+
const notebooks = /* @__PURE__ */ new Map();
|
|
1543
|
+
/** An alphanumeric id of the 12 characters the backend allows, the same for one key every time. */
|
|
1544
|
+
const shortIdFor = (key) => createHash("sha256").update(key).digest("hex").slice(0, 12);
|
|
1545
|
+
/** The backend's title limit, the one the MCP's notebook tools enforce. */
|
|
1546
|
+
const MAX_TITLE_LENGTH = 256;
|
|
1547
|
+
/** The report's first H1, which the report is told to open with. */
|
|
1548
|
+
const titleOf = (markdown) => (/^# +(.+)$/m.exec(markdown)?.[1].trim() || DEFAULT_TITLE).slice(0, MAX_TITLE_LENGTH);
|
|
1549
|
+
const failed = (reason, description, heldUrl) => {
|
|
1550
|
+
logToFile(`[publish_handoff] notebook ${heldUrl ? "not updated" : "skipped"} (${reason})`);
|
|
1551
|
+
return heldUrl ? {
|
|
1552
|
+
outcome: "not_updated",
|
|
1553
|
+
reason,
|
|
1554
|
+
description,
|
|
1555
|
+
url: heldUrl
|
|
1556
|
+
} : {
|
|
1557
|
+
outcome: "skipped",
|
|
1558
|
+
reason,
|
|
1559
|
+
description
|
|
1560
|
+
};
|
|
1561
|
+
};
|
|
1562
|
+
const responseStatus = (err) => axios.isAxiosError(err) ? err.response?.status : void 0;
|
|
1563
|
+
const TIMEOUT_CODES = new Set([
|
|
1564
|
+
"ERR_CANCELED",
|
|
1565
|
+
"ECONNABORTED",
|
|
1566
|
+
"ETIMEDOUT"
|
|
1567
|
+
]);
|
|
1568
|
+
const isTimeout = (err, signal) => signal.aborted || err instanceof Error && TIMEOUT_CODES.has(err.code ?? "");
|
|
1569
|
+
/** A short code for telemetry and a few words for the agent; neither carries a body or a token. */
|
|
1570
|
+
function failureFor(err, signal, heldUrl) {
|
|
1571
|
+
if (isTimeout(err, signal)) return failed("timeout", "PostHog did not answer in time", heldUrl);
|
|
1572
|
+
const status = responseStatus(err);
|
|
1573
|
+
if (status === 401) return failed("unauthorized", "PostHog rejected the login", heldUrl);
|
|
1574
|
+
if (status === 403) return failed("http_403", "PostHog denied access", heldUrl);
|
|
1575
|
+
if (status !== void 0) return failed(`http_${status}`, `PostHog returned HTTP ${status}`, heldUrl);
|
|
1576
|
+
return failed("error", "the request to PostHog failed", heldUrl);
|
|
1577
|
+
}
|
|
1578
|
+
/** A write worth one more try: no response at all (not a cancel), or a server error. */
|
|
1579
|
+
function isTransient(err, signal) {
|
|
1580
|
+
if (isTimeout(err, signal)) return false;
|
|
1581
|
+
const status = responseStatus(err);
|
|
1582
|
+
return status === void 0 || status >= 500;
|
|
1583
|
+
}
|
|
1584
|
+
/** Whether a failed create may still have made the notebook: lost response, server error, or an id clash. */
|
|
1585
|
+
function mayHaveLanded(err) {
|
|
1586
|
+
const status = responseStatus(err);
|
|
1587
|
+
return status === void 0 || status >= 500 || status === 400 || status === 409;
|
|
1588
|
+
}
|
|
1589
|
+
/** Give up on `work` when the deadline passes, even if the call under it ignores the signal. */
|
|
1590
|
+
function beforeDeadline(work, signal) {
|
|
1591
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
1592
|
+
return new Promise((resolve, reject) => {
|
|
1593
|
+
const onAbort = () => reject(signal.reason);
|
|
1594
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1595
|
+
work.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
/** Create this program's notebook from `markdown`, or update it when an earlier call in the run made one. */
|
|
1599
|
+
async function syncHandoffNotebook(markdown, programId = "") {
|
|
1600
|
+
const controller = new AbortController();
|
|
1601
|
+
const timer = setTimeout(() => controller.abort(), SYNC_DEADLINE_MS);
|
|
1602
|
+
try {
|
|
1603
|
+
return await sync(markdown, programId, controller.signal);
|
|
1604
|
+
} finally {
|
|
1605
|
+
clearTimeout(timer);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
async function sync(markdown, programId, signal) {
|
|
1609
|
+
const key = `${analytics.runId}:${programId}`;
|
|
1610
|
+
const held = notebooks.get(key);
|
|
1611
|
+
const shortId = held?.shortId ?? shortIdFor(key);
|
|
1612
|
+
const heldUrl = held?.url;
|
|
1613
|
+
let fetched;
|
|
1614
|
+
try {
|
|
1615
|
+
fetched = await beforeDeadline(oauthCredentials(), signal);
|
|
1616
|
+
} catch (err) {
|
|
1617
|
+
return failureFor(err, signal, heldUrl);
|
|
1618
|
+
}
|
|
1619
|
+
const urlFor = (login) => `${login.host.appHost}/project/${login.projectId}/notebooks/${shortId}`;
|
|
1620
|
+
if (!fetched) return failed("no_login", "not logged in to PostHog", heldUrl);
|
|
1621
|
+
let credentials = fetched;
|
|
1622
|
+
if (credentials.missingScopes?.includes(NOTEBOOK_SCOPE)) return failed("missing_scope", `the login lacks the ${NOTEBOOK_SCOPE} permission`, heldUrl);
|
|
1623
|
+
/** Push `markdown` as this login: create, or update at the version the server holds. */
|
|
1624
|
+
const push = async (login, retried) => {
|
|
1625
|
+
const args = [
|
|
1626
|
+
login.accessToken,
|
|
1627
|
+
login.projectId,
|
|
1628
|
+
login.host.apiHost
|
|
1629
|
+
];
|
|
1630
|
+
let version = held?.version;
|
|
1631
|
+
const lookup = async () => {
|
|
1632
|
+
try {
|
|
1633
|
+
return await fetchMarkdownNotebook(...args, shortId, signal);
|
|
1634
|
+
} catch {
|
|
1635
|
+
return null;
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
if (retried) {
|
|
1639
|
+
const found = await lookup();
|
|
1640
|
+
if (found?.markdown === markdown) return found.version;
|
|
1641
|
+
version = found?.version ?? version;
|
|
1642
|
+
}
|
|
1643
|
+
if (version === void 0) try {
|
|
1644
|
+
return await createMarkdownNotebook(...args, {
|
|
1645
|
+
shortId,
|
|
1646
|
+
title: titleOf(markdown),
|
|
1647
|
+
markdown
|
|
1648
|
+
}, signal);
|
|
1649
|
+
} catch (err) {
|
|
1650
|
+
const found = mayHaveLanded(err) ? await lookup() : null;
|
|
1651
|
+
if (!found) throw err;
|
|
1652
|
+
if (found.markdown === markdown) return found.version;
|
|
1653
|
+
version = found.version;
|
|
1654
|
+
}
|
|
1655
|
+
return updateMarkdownNotebook(...args, {
|
|
1656
|
+
shortId,
|
|
1657
|
+
markdown,
|
|
1658
|
+
version
|
|
1659
|
+
}, signal);
|
|
1660
|
+
};
|
|
1661
|
+
/** One try, plus one more with a rotated token after a 401. */
|
|
1662
|
+
const authorized = async (retried) => {
|
|
1663
|
+
try {
|
|
1664
|
+
return await push(credentials, retried);
|
|
1665
|
+
} catch (err) {
|
|
1666
|
+
if (responseStatus(err) !== 401) throw err;
|
|
1667
|
+
const recovery = await beforeDeadline(rotateAfterUnauthorized(credentials, { requireRefreshToken: false }), signal);
|
|
1668
|
+
if (recovery.kind !== "rotated") throw err;
|
|
1669
|
+
credentials = recovery.credentials;
|
|
1670
|
+
return push(credentials, retried);
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
let version;
|
|
1674
|
+
try {
|
|
1675
|
+
try {
|
|
1676
|
+
version = await beforeDeadline(authorized(false), signal);
|
|
1677
|
+
} catch (err) {
|
|
1678
|
+
if (!isTransient(err, signal)) throw err;
|
|
1679
|
+
version = await beforeDeadline(authorized(true), signal);
|
|
1680
|
+
}
|
|
1681
|
+
} catch (err) {
|
|
1682
|
+
return failureFor(err, signal, heldUrl);
|
|
1683
|
+
}
|
|
1684
|
+
const url = urlFor(credentials);
|
|
1685
|
+
notebooks.set(key, {
|
|
1686
|
+
shortId,
|
|
1687
|
+
version,
|
|
1688
|
+
url
|
|
1689
|
+
});
|
|
1690
|
+
logToFile(`[publish_handoff] notebook ${held ? "updated" : "created"}`);
|
|
1691
|
+
return {
|
|
1692
|
+
outcome: held ? "updated" : "created",
|
|
1693
|
+
url
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
//#endregion
|
|
1521
1697
|
//#region src/shared/utils/needs-attention.ts
|
|
1522
1698
|
/** The heading of the warning block a handoff report opens with when work is left. */
|
|
1523
1699
|
const NEEDS_ATTENTION_HEADING = "Needs your attention";
|
|
@@ -1557,7 +1733,7 @@ const PUBLISH_HANDOFF_TOOL_NAME = "publish_handoff";
|
|
|
1557
1733
|
* full report per step, each replaced by the next, and a step that read the
|
|
1558
1734
|
* call as its own finish skipped `complete_task` and was restarted.
|
|
1559
1735
|
*/
|
|
1560
|
-
const PUBLISH_HANDOFF_DESCRIPTION = `Publish the handoff document — the full markdown report of what the whole run did — to the wizard session. A run publishes once: call it only when your own instructions ask you to write that report, passing the complete report as \`content\`, and never write the report to a file yourself. When anything is left for the user to do, open the report, right under the H1, with a \`> ⚠️ **${NEEDS_ATTENTION_HEADING}**\` block quote, one \`> - \` bullet per item. It is not how you report your own work — in a run made of several tasks each step finishes with complete_task, and a step that was not asked for the run report leaves this one uncalled, because the section it owns travels in its handoff.`;
|
|
1736
|
+
const PUBLISH_HANDOFF_DESCRIPTION = `Publish the handoff document — the full markdown report of what the whole run did — to the wizard session. A run publishes once: call it only when your own instructions ask you to write that report, passing the complete report as \`content\`, and never write the report to a file yourself. When anything is left for the user to do, open the report, right under the H1, with a \`> ⚠️ **${NEEDS_ATTENTION_HEADING}**\` block quote, one \`> - \` bullet per item. It is not how you report your own work — in a run made of several tasks each step finishes with complete_task, and a step that was not asked for the run report leaves this one uncalled, because the section it owns travels in its handoff. When the result names a PostHog notebook, the wizard already mirrored the report there: never create a notebook yourself.`;
|
|
1561
1737
|
/** Appended for a task agent: the reminder lands as it decides it has finished. */
|
|
1562
1738
|
const TASK_REPORTING_NOTE = " This does not report your task: call complete_task to finish.";
|
|
1563
1739
|
const PUBLISH_HANDOFF_CONTENT_DESCRIPTION = "The complete handoff report as markdown, starting with an H1 heading.";
|
|
@@ -1621,7 +1797,14 @@ function writeHandoffFileAtomically(targetPath, text) {
|
|
|
1621
1797
|
};
|
|
1622
1798
|
}
|
|
1623
1799
|
}
|
|
1624
|
-
|
|
1800
|
+
const notebookNote = (notebook) => {
|
|
1801
|
+
switch (notebook.outcome) {
|
|
1802
|
+
case "skipped": return `Notebook not created: ${notebook.description}.`;
|
|
1803
|
+
case "not_updated": return `Notebook not updated: ${notebook.description}. It still holds the earlier report: ${notebook.url}.`;
|
|
1804
|
+
default: return `Notebook ${notebook.outcome}: ${notebook.url}. Do not create another notebook.`;
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
async function publishHandoff(content, emit, opts = {}) {
|
|
1625
1808
|
if (content.trim() === "") {
|
|
1626
1809
|
analytics.wizardCapture("handoff published", {
|
|
1627
1810
|
handoff_ok: false,
|
|
@@ -1649,18 +1832,28 @@ function publishHandoff(content, emit, opts = {}) {
|
|
|
1649
1832
|
logToFile(`[publish_handoff] host output write failed (${write.reason}): ${write.detail}`);
|
|
1650
1833
|
}
|
|
1651
1834
|
}
|
|
1835
|
+
const notebookRequested = opts.handoffNotebook === true;
|
|
1836
|
+
const notebook = notebookRequested ? await syncHandoffNotebook(text, opts.programId) : void 0;
|
|
1837
|
+
if (notebook?.outcome === "created" || notebook?.outcome === "updated") emit?.({
|
|
1838
|
+
kind: "url",
|
|
1839
|
+
which: "notebook",
|
|
1840
|
+
url: notebook.url
|
|
1841
|
+
});
|
|
1652
1842
|
analytics.wizardCapture("handoff published", {
|
|
1653
1843
|
handoff_ok: true,
|
|
1654
1844
|
handoff_chars: text.length,
|
|
1655
1845
|
handoff_truncated: truncated,
|
|
1656
|
-
handoff_output_written: handoffOutputWritten
|
|
1846
|
+
handoff_output_written: handoffOutputWritten,
|
|
1847
|
+
notebook_requested: notebookRequested,
|
|
1848
|
+
notebook_outcome: notebook?.outcome,
|
|
1849
|
+
notebook_skip_reason: notebook?.outcome === "skipped" || notebook?.outcome === "not_updated" ? notebook.reason : void 0
|
|
1657
1850
|
});
|
|
1658
1851
|
const notes = [];
|
|
1659
1852
|
if (truncated) notes.push("truncated to the 64 KB limit");
|
|
1660
1853
|
if (handoffOutputError) notes.push(`host output write failed: ${handoffOutputError}`);
|
|
1661
1854
|
return {
|
|
1662
1855
|
ok: true,
|
|
1663
|
-
message: `Handoff published (${text.length} chars${notes.length > 0 ? `, ${notes.join("; ")}` : ""}).${opts.taskAgent ? TASK_REPORTING_NOTE : ""}`
|
|
1856
|
+
message: `Handoff published (${text.length} chars${notes.length > 0 ? `, ${notes.join("; ")}` : ""}).${notebook ? ` ${notebookNote(notebook)}` : ""}${opts.taskAgent ? TASK_REPORTING_NOTE : ""}`
|
|
1664
1857
|
};
|
|
1665
1858
|
}
|
|
1666
1859
|
//#endregion
|
|
@@ -1746,7 +1939,7 @@ async function getSDKModule$1() {
|
|
|
1746
1939
|
* Must be called asynchronously because the SDK is an ESM module loaded via dynamic import.
|
|
1747
1940
|
*/
|
|
1748
1941
|
async function createWizardToolsServer(options) {
|
|
1749
|
-
const { workingDirectory, detectPackageManager, skillsBaseUrl, askBridge, askMaxQuestions = 10, secretVault = createSecretVault(), orchestrator, triageProvider, emit } = options;
|
|
1942
|
+
const { workingDirectory, detectPackageManager, skillsBaseUrl, askBridge, askMaxQuestions = 10, secretVault = createSecretVault(), orchestrator, triageProvider, emit, programId, handoffNotebook } = options;
|
|
1750
1943
|
const { tool, createSdkMcpServer } = await getSDKModule$1();
|
|
1751
1944
|
const askAccounting = createAskAccounting(askMaxQuestions);
|
|
1752
1945
|
let cachedSkillMenu = {};
|
|
@@ -2032,8 +2225,12 @@ async function createWizardToolsServer(options) {
|
|
|
2032
2225
|
};
|
|
2033
2226
|
}
|
|
2034
2227
|
}),
|
|
2035
|
-
tool(PUBLISH_HANDOFF_TOOL_NAME, PUBLISH_HANDOFF_DESCRIPTION, { content: z.string().describe(PUBLISH_HANDOFF_CONTENT_DESCRIPTION) }, (args) => {
|
|
2036
|
-
const result = publishHandoff(args.content, emit, {
|
|
2228
|
+
tool(PUBLISH_HANDOFF_TOOL_NAME, PUBLISH_HANDOFF_DESCRIPTION, { content: z.string().describe(PUBLISH_HANDOFF_CONTENT_DESCRIPTION) }, async (args) => {
|
|
2229
|
+
const result = await publishHandoff(args.content, emit, {
|
|
2230
|
+
taskAgent: orchestrator?.currentTaskId !== void 0,
|
|
2231
|
+
programId,
|
|
2232
|
+
handoffNotebook
|
|
2233
|
+
});
|
|
2037
2234
|
logToFile(`publish_handoff: ${result.message}`);
|
|
2038
2235
|
return {
|
|
2039
2236
|
content: [{
|
|
@@ -2200,34 +2397,6 @@ function classifyToolToStage(toolName) {
|
|
|
2200
2397
|
return null;
|
|
2201
2398
|
}
|
|
2202
2399
|
//#endregion
|
|
2203
|
-
//#region src/shared/auth-session-state.ts
|
|
2204
|
-
/**
|
|
2205
|
-
* Whether this run's OAuth grant is known to be dead.
|
|
2206
|
-
*
|
|
2207
|
-
* Process-global on purpose. A run has exactly one login, but the two sides of
|
|
2208
|
-
* this fact are far apart: the pre-run refresh learns it in `authenticate.ts`,
|
|
2209
|
-
* and the only consumer is the 401 handler inside the agent message loop, which
|
|
2210
|
-
* holds no session. Threading it would mean a field on `AgentConfig` set at four
|
|
2211
|
-
* `initializeAgent` call sites — and the session it would read from may be a
|
|
2212
|
-
* shallow copy (`prepareRunSession`), so the value could be written to one
|
|
2213
|
-
* object and read from another.
|
|
2214
|
-
*
|
|
2215
|
-
* A leaf module with no imports, so either side can depend on it without a cycle.
|
|
2216
|
-
*/
|
|
2217
|
-
let grantRevoked = false;
|
|
2218
|
-
/**
|
|
2219
|
-
* Record that the token endpoint permanently refused this grant. Not an abort:
|
|
2220
|
-
* the access token in hand may still have minutes of life, so the run continues
|
|
2221
|
-
* and this only decides what a later 401 gets blamed on.
|
|
2222
|
-
*/
|
|
2223
|
-
function markGrantRevoked() {
|
|
2224
|
-
grantRevoked = true;
|
|
2225
|
-
}
|
|
2226
|
-
/** True once a token refresh failed because the grant itself is gone. */
|
|
2227
|
-
function isGrantRevoked() {
|
|
2228
|
-
return grantRevoked;
|
|
2229
|
-
}
|
|
2230
|
-
//#endregion
|
|
2231
2400
|
//#region src/agent/output-signals.ts
|
|
2232
2401
|
/**
|
|
2233
2402
|
* Parses the signal-bearing lines out of agent output and discards the rest.
|
|
@@ -2546,7 +2715,7 @@ const BLOCKING_SETTINGS_KEYS = ["apiKeyHelper"];
|
|
|
2546
2715
|
*/
|
|
2547
2716
|
function checkSettingsFile(filePath) {
|
|
2548
2717
|
try {
|
|
2549
|
-
const raw = fs$
|
|
2718
|
+
const raw = fs$2.readFileSync(filePath, "utf-8");
|
|
2550
2719
|
const parsed = JSON.parse(raw);
|
|
2551
2720
|
const matched = [];
|
|
2552
2721
|
const envBlock = parsed?.env;
|
|
@@ -2647,10 +2816,10 @@ function ensureBackupGitignored(claudeDir) {
|
|
|
2647
2816
|
const gitignorePath = path.join(claudeDir, ".gitignore");
|
|
2648
2817
|
const entry = `*${BACKUP_SUFFIX}`;
|
|
2649
2818
|
try {
|
|
2650
|
-
const existing = fs$
|
|
2819
|
+
const existing = fs$2.existsSync(gitignorePath) ? fs$2.readFileSync(gitignorePath, "utf-8") : "";
|
|
2651
2820
|
if (existing.split("\n").map((l) => l.trim()).includes(entry)) return;
|
|
2652
2821
|
const sep = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
2653
|
-
fs$
|
|
2822
|
+
fs$2.writeFileSync(gitignorePath, `${existing}${sep}${entry}\n`);
|
|
2654
2823
|
} catch (error) {
|
|
2655
2824
|
analytics.captureException(error);
|
|
2656
2825
|
}
|
|
@@ -2662,15 +2831,15 @@ function ensureBackupGitignored(claudeDir) {
|
|
|
2662
2831
|
*/
|
|
2663
2832
|
function backupAndFixClaudeSettings(workingDirectory) {
|
|
2664
2833
|
for (const { claudeDir, original, backup } of settingsBackupTargets(workingDirectory)) {
|
|
2665
|
-
if (!fs$
|
|
2834
|
+
if (!fs$2.existsSync(original)) continue;
|
|
2666
2835
|
try {
|
|
2667
|
-
if (!fs$
|
|
2668
|
-
fs$
|
|
2669
|
-
const mode = fs$
|
|
2670
|
-
fs$
|
|
2836
|
+
if (!fs$2.existsSync(backup)) {
|
|
2837
|
+
fs$2.copyFileSync(original, backup);
|
|
2838
|
+
const mode = fs$2.statSync(original).mode & 511;
|
|
2839
|
+
fs$2.chmodSync(backup, mode);
|
|
2671
2840
|
}
|
|
2672
2841
|
ensureBackupGitignored(claudeDir);
|
|
2673
|
-
fs$
|
|
2842
|
+
fs$2.unlinkSync(original);
|
|
2674
2843
|
analytics.wizardCapture("backedup-claude-settings");
|
|
2675
2844
|
registerCleanup(() => {
|
|
2676
2845
|
try {
|
|
@@ -2697,10 +2866,10 @@ function backupAndFixClaudeSettings(workingDirectory) {
|
|
|
2697
2866
|
*/
|
|
2698
2867
|
function restoreClaudeSettings(workingDirectory) {
|
|
2699
2868
|
for (const { original, backup } of settingsBackupTargets(workingDirectory)) {
|
|
2700
|
-
if (!fs$
|
|
2869
|
+
if (!fs$2.existsSync(backup)) continue;
|
|
2701
2870
|
try {
|
|
2702
|
-
fs$
|
|
2703
|
-
fs$
|
|
2871
|
+
fs$2.copyFileSync(backup, original);
|
|
2872
|
+
fs$2.rmSync(backup, { force: true });
|
|
2704
2873
|
analytics.wizardCapture("restored-claude-settings");
|
|
2705
2874
|
return;
|
|
2706
2875
|
} catch (error) {
|
|
@@ -2724,10 +2893,10 @@ function restoreClaudeSettings(workingDirectory) {
|
|
|
2724
2893
|
*/
|
|
2725
2894
|
function recoverOrphanedSettingsBackups(workingDirectory) {
|
|
2726
2895
|
for (const { original, backup } of settingsBackupTargets(workingDirectory)) {
|
|
2727
|
-
if (!fs$
|
|
2896
|
+
if (!fs$2.existsSync(backup) || fs$2.existsSync(original)) continue;
|
|
2728
2897
|
try {
|
|
2729
|
-
fs$
|
|
2730
|
-
fs$
|
|
2898
|
+
fs$2.copyFileSync(backup, original);
|
|
2899
|
+
fs$2.rmSync(backup, { force: true });
|
|
2731
2900
|
analytics.wizardCapture("recovered-orphaned-settings");
|
|
2732
2901
|
} catch (error) {
|
|
2733
2902
|
analytics.captureException(error);
|
|
@@ -2780,7 +2949,7 @@ const claudeConfigDir = (homeDir = os.homedir()) => process.env.CLAUDE_CONFIG_DI
|
|
|
2780
2949
|
*/
|
|
2781
2950
|
function createIsolatedAgentConfigDir() {
|
|
2782
2951
|
const base = process.platform === "win32" ? os.tmpdir() : "/tmp";
|
|
2783
|
-
return fs$
|
|
2952
|
+
return fs$2.mkdtempSync(path.join(base, "posthog-wizard-claude-"));
|
|
2784
2953
|
}
|
|
2785
2954
|
/**
|
|
2786
2955
|
* Look for a stored Claude login. `homeDir` / `platform` are injectable for
|
|
@@ -2790,7 +2959,7 @@ function detectStoredClaudeLogin(homeDir = os.homedir(), platform = process.plat
|
|
|
2790
2959
|
const credentialsPath = path.join(claudeConfigDir(homeDir), ".credentials.json");
|
|
2791
2960
|
let credentialsFile = false;
|
|
2792
2961
|
try {
|
|
2793
|
-
credentialsFile = fs$
|
|
2962
|
+
credentialsFile = fs$2.existsSync(credentialsPath);
|
|
2794
2963
|
} catch (error) {
|
|
2795
2964
|
logToFile(`[stored-login] checked ${credentialsPath} — unreadable (${error instanceof Error ? error.message : String(error)}), treating as absent`);
|
|
2796
2965
|
analytics.wizardCapture("stored login check failed", { step: "credentials-file" });
|
|
@@ -2870,7 +3039,7 @@ function buildAuthErrorContext(workingDirectory, gatewayUrl, homeDir = os.homedi
|
|
|
2870
3039
|
* Phase 1 — collect remark (once): block with remark prompt
|
|
2871
3040
|
* Phase 2 — allow stop: return {}
|
|
2872
3041
|
*/
|
|
2873
|
-
function createStopHook(signals, requestRemark = true) {
|
|
3042
|
+
function createStopHook(signals, requestRemark = true, onRemark) {
|
|
2874
3043
|
let remarkRequested = false;
|
|
2875
3044
|
return (input) => {
|
|
2876
3045
|
logToFile("Stop hook triggered", {
|
|
@@ -2883,6 +3052,7 @@ function createStopHook(signals, requestRemark = true) {
|
|
|
2883
3052
|
}
|
|
2884
3053
|
if (requestRemark && !remarkRequested) {
|
|
2885
3054
|
remarkRequested = true;
|
|
3055
|
+
onRemark?.(input.last_assistant_message);
|
|
2886
3056
|
logToFile("Stop hook: requesting reflection");
|
|
2887
3057
|
return {
|
|
2888
3058
|
decision: "block",
|
|
@@ -3101,9 +3271,12 @@ async function initializeAgent(config, options) {
|
|
|
3101
3271
|
askMaxQuestions: config.askMaxQuestions,
|
|
3102
3272
|
orchestrator: config.orchestrator,
|
|
3103
3273
|
triageProvider,
|
|
3104
|
-
emit: config.emit
|
|
3274
|
+
emit: config.emit,
|
|
3275
|
+
programId: config.programId,
|
|
3276
|
+
handoffNotebook: config.handoffNotebook
|
|
3105
3277
|
});
|
|
3106
3278
|
const model = config.modelOverride ?? "claude-sonnet-5";
|
|
3279
|
+
const queue = config.orchestrator;
|
|
3107
3280
|
const agentRunConfig = {
|
|
3108
3281
|
workingDirectory: config.workingDirectory,
|
|
3109
3282
|
mcpServers,
|
|
@@ -3118,6 +3291,7 @@ async function initializeAgent(config, options) {
|
|
|
3118
3291
|
disallowedTools: config.disallowedTools,
|
|
3119
3292
|
getPendingQuestion: config.getPendingQuestion,
|
|
3120
3293
|
suppressTaskRender: !!config.orchestrator,
|
|
3294
|
+
taskReported: queue && (() => taskReported(queue)),
|
|
3121
3295
|
capture: config.capture,
|
|
3122
3296
|
triageProvider,
|
|
3123
3297
|
gatewayAuth: auth,
|
|
@@ -3272,6 +3446,18 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3272
3446
|
};
|
|
3273
3447
|
let timedOut = false;
|
|
3274
3448
|
let abortReason = null;
|
|
3449
|
+
let policyAborted = false;
|
|
3450
|
+
const subagentCallIds = /* @__PURE__ */ new Set();
|
|
3451
|
+
let remarkTurn = false;
|
|
3452
|
+
const policyAbort = (reply) => {
|
|
3453
|
+
const reason = typeof reply === "string" ? policyAbortReason(reply) : void 0;
|
|
3454
|
+
if (!reason || abortReason || remarkTurn || agentConfig.taskReported?.()) return;
|
|
3455
|
+
abortReason = reason;
|
|
3456
|
+
policyAborted = true;
|
|
3457
|
+
logToFile(`Agent emitted [posthog:abort]: ${reason}`);
|
|
3458
|
+
abortController.abort();
|
|
3459
|
+
signalDone();
|
|
3460
|
+
};
|
|
3275
3461
|
let yaraViolationReason = null;
|
|
3276
3462
|
let sessionId;
|
|
3277
3463
|
let reminted = false;
|
|
@@ -3375,6 +3561,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3375
3561
|
CLAUDE_CODE_OAUTH_TOKEN: agentConfig.gatewayAuth.token,
|
|
3376
3562
|
CLAUDE_CONFIG_DIR: agentConfigDir,
|
|
3377
3563
|
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "true",
|
|
3564
|
+
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1",
|
|
3378
3565
|
POSTHOG_MCP_TOKEN: await agentConfig.currentPosthogApiKey?.() ?? agentConfig.posthogApiKey,
|
|
3379
3566
|
MCP_CONNECTION_NONBLOCKING: "0",
|
|
3380
3567
|
ANTHROPIC_CUSTOM_HEADERS: buildAgentEnv(agentConfig.wizardMetadata ?? {}, agentConfig.wizardFlags ?? {}, agentConfig.gatewayAuth.teamId)
|
|
@@ -3414,7 +3601,17 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3414
3601
|
PreToolUse: warlockDisabled ? [] : createPreToolUseYaraHooks(triageProvider, onYaraTerminate),
|
|
3415
3602
|
PostToolUse: warlockDisabled ? [] : createPostToolUseYaraHooks(triageProvider, onYaraTerminate),
|
|
3416
3603
|
Stop: [{
|
|
3417
|
-
hooks: [createStopHook(signals, config?.requestRemark ?? true)
|
|
3604
|
+
hooks: [createStopHook(signals, config?.requestRemark ?? true, (lastReply) => {
|
|
3605
|
+
policyAbort(lastReply);
|
|
3606
|
+
remarkTurn = true;
|
|
3607
|
+
})],
|
|
3608
|
+
timeout: 30
|
|
3609
|
+
}],
|
|
3610
|
+
SubagentStop: [{
|
|
3611
|
+
hooks: [async (input) => {
|
|
3612
|
+
policyAbort(await transcriptRefusal(input.agent_transcript_path));
|
|
3613
|
+
return {};
|
|
3614
|
+
}],
|
|
3418
3615
|
timeout: 30
|
|
3419
3616
|
}]
|
|
3420
3617
|
}
|
|
@@ -3458,6 +3655,10 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3458
3655
|
}
|
|
3459
3656
|
}
|
|
3460
3657
|
}
|
|
3658
|
+
const blocks = message.message?.content;
|
|
3659
|
+
for (const block of Array.isArray(blocks) ? blocks : []) if (block.type === "tool_use" && block.name === "Agent") subagentCallIds.add(block.id);
|
|
3660
|
+
else if (message.type === "assistant" && block.type === "text") policyAbort(block.text);
|
|
3661
|
+
else if (message.type === "user" && block.type === "tool_result" && subagentCallIds.has(block.tool_use_id)) policyAbort(contentText(block.content));
|
|
3461
3662
|
if (message.type === "assistant" && sdkErrorStatus(message.error) === 401 || message.type === "result" && (sdkErrorStatus(message.api_error_status) === 401 || sdkErrorStatus(message.status) === 401) || message.type === "result" && Array.isArray(message.errors) && message.errors.some((error) => sdkErrorStatus(error) === 401)) {
|
|
3462
3663
|
signalDone();
|
|
3463
3664
|
if (agentConfig.refreshGatewayAuth && !reminted && isPastRefresh(agentConfig.gatewayAuth) && !agentConfig.signal?.aborted) {
|
|
@@ -3721,6 +3922,7 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
3721
3922
|
duration_ms: durationMs,
|
|
3722
3923
|
duration_seconds: Math.round(durationMs / 1e3),
|
|
3723
3924
|
model: agentConfig.model,
|
|
3925
|
+
...policyAborted ? { source: "gateway_policy" } : {},
|
|
3724
3926
|
...config?.analyticsProperties
|
|
3725
3927
|
});
|
|
3726
3928
|
} catch {}
|
|
@@ -3847,6 +4049,23 @@ function extractTaskIdFromToolResult(result) {
|
|
|
3847
4049
|
if (typeof obj.taskId === "string") return obj.taskId;
|
|
3848
4050
|
if (typeof obj.id === "string") return obj.id;
|
|
3849
4051
|
}
|
|
4052
|
+
/** A message's or tool_result's text, whether its content is a string or blocks. */
|
|
4053
|
+
function contentText(content) {
|
|
4054
|
+
if (!Array.isArray(content)) return typeof content === "string" ? content : "";
|
|
4055
|
+
return content.map((b) => b.text ?? "").join("\n");
|
|
4056
|
+
}
|
|
4057
|
+
/** The first assistant reply in a subagent transcript that starts with the policy abort marker. */
|
|
4058
|
+
async function transcriptRefusal(transcriptPath) {
|
|
4059
|
+
const raw = transcriptPath ? await readFile(transcriptPath, "utf8").catch(() => "") : "";
|
|
4060
|
+
for (const line of raw.split("\n")) {
|
|
4061
|
+
if (!line.includes(AgentSignals.POLICY_ABORT)) continue;
|
|
4062
|
+
try {
|
|
4063
|
+
const entry = JSON.parse(line);
|
|
4064
|
+
const text = contentText(entry.message?.content);
|
|
4065
|
+
if (entry.type === "assistant" && policyAbortReason(text)) return text;
|
|
4066
|
+
} catch {}
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
3850
4069
|
/**
|
|
3851
4070
|
* Fallback id extractor for the inner tool_result block.content — used only
|
|
3852
4071
|
* when message.tool_use_result is absent. In current SDK versions the inner
|
|
@@ -4052,6 +4271,6 @@ function handleSDKMessage(message, options, spinner, signals, emit, receivedSucc
|
|
|
4052
4271
|
}
|
|
4053
4272
|
}
|
|
4054
4273
|
//#endregion
|
|
4055
|
-
export {
|
|
4274
|
+
export { vaultSensitiveAnswers as $, AUDIT_STATUSES as A, checkEnvKeys as B, readNeedsAttention as C, AUDIT_RESOLVE_CHECKS_PARAM_DESCRIPTION as D, AUDIT_RESOLVE_CHECKS_DESCRIPTION as E, WIZARD_ASK_SENSITIVE_DESCRIPTION as F, mergeEnvValues as G, describeAskCancellation as H, WIZARD_ASK_SUBJECT_DESCRIPTION as I, resolveAuditChecks as J, normaliseAskSubject as K, WIZARD_ASK_TOOL_DESCRIPTION as L, CHECK_ENV_KEYS_FILE_PATH_DESCRIPTION as M, ENV_FILE_PATH_DESCRIPTION as N, AUDIT_SEED_CHECKS_DESCRIPTION as O, WIZARD_ASK_KIND_DESCRIPTION as P, templateEnvWriteRefusal as Q, WIZARD_TOOL_NAMES as R, NEEDS_ATTENTION_HEADING as S, AUDIT_ADD_CHECKS_PARAM_DESCRIPTION as T, ensureGitignoreCoverage as U, createAskAccounting as V, legacyKeyNameRefusal as W, resolveEnvSecretRefs as X, resolveEnvPath as Y, seedAuditChecks as Z, createSecretVault as _, wizardCanUseTool as a, isEnvFileName as at, PUBLISH_HANDOFF_TOOL_NAME as b, checkAllSettingsConflicts as c, createTriageLLMProvider as ct, restoreClaudeSettings as d, createWizardAskBridge as et, sanitizeAgentSubprocessEnv as f, assembleCommandments as g, AgentOutputSignals as h, runAgent as i, MAX_ENV_KEY_SET as it, CHECK_ENV_KEYS_DESCRIPTION as j, AUDIT_SEED_CHECKS_PARAM_DESCRIPTION as k, classifySettingsConflicts as l, runCleanups as m, buildRunTags as n, LONGER_ASK_TIMEOUT_MS as nt, createIsolatedAgentConfigDir as o, parseEnvKeyNames as ot, registerCleanup as p, resolveAskQuestionKinds as q, initializeAgent as r, shouldDisableAsk as rt, backupAndFixClaudeSettings as s, toPromptSafeRelativePath as st, buildAgentEnv as t, isFullyCancelled as tt, recoverOrphanedSettingsBackups as u, PUBLISH_HANDOFF_CONTENT_DESCRIPTION as v, AUDIT_ADD_CHECKS_DESCRIPTION as w, publishHandoff as x, PUBLISH_HANDOFF_DESCRIPTION as y, addAuditChecks as z };
|
|
4056
4275
|
|
|
4057
|
-
//# sourceMappingURL=agent-interface-
|
|
4276
|
+
//# sourceMappingURL=agent-interface-fcDXqb-_.js.map
|