@ai-agent-forge/plugin-sdk 0.88.14 → 0.88.15
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-task-scheduler.d.ts +154 -0
- package/dist/agent-task-scheduler.d.ts.map +1 -0
- package/dist/agent-task-scheduler.js +186 -0
- package/dist/agent-task-scheduler.js.map +1 -0
- package/dist/browser-fetch.d.ts +58 -0
- package/dist/browser-fetch.d.ts.map +1 -0
- package/dist/browser-fetch.js +135 -0
- package/dist/browser-fetch.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-client.d.ts +45 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +14 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/network-route.d.ts +55 -0
- package/dist/network-route.d.ts.map +1 -0
- package/dist/network-route.js +187 -0
- package/dist/network-route.js.map +1 -0
- package/dist/observability.d.ts +21 -0
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js.map +1 -1
- package/dist/operation.d.ts +33 -0
- package/dist/operation.d.ts.map +1 -1
- package/dist/operation.js +50 -1
- package/dist/operation.js.map +1 -1
- package/dist/public-api.d.ts +198 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +43 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-fetch.js","sourceRoot":"","sources":["../src/browser-fetch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Browser-fetch capability contract(联网检索设计 §5.9, P1.5).\n *\n * `agent-forge.browser.fetch@1` is a plugin-to-plugin service: a consumer asks\n * `browser-playwright` to load a page with the shared browser profile and\n * return bounded visible text. The capability never returns cookies,\n * localStorage or auth files; profile storage stays inside the browser plugin.\n *\n * The request/result payloads are the public design contract. The capability\n * response wraps them in an explicit `ok` union so a provider can report\n * structured failures (`browser_profile_busy`, `browser_login_required`, …)\n * without inventing an Error subclass that would not survive the capability\n * boundary.\n */\n\nexport const BROWSER_FETCH_CAPABILITY_ID = \"agent-forge.browser.fetch\";\nexport const BROWSER_FETCH_VERSION_V1 = 1;\nexport const BROWSER_FETCH_MAX_TEXT_CHARS = 16 * 1024;\nexport const BROWSER_FETCH_DEFAULT_TIMEOUT_MS = 30_000;\nexport const BROWSER_FETCH_MIN_TIMEOUT_MS = 1_000;\nexport const BROWSER_FETCH_MAX_TIMEOUT_MS = 120_000;\nexport const BROWSER_FETCH_MAX_TITLE_CHARS = 512;\nexport const BROWSER_FETCH_MAX_ERROR_CHARS = 2048;\nexport const BROWSER_PROFILE_NAME_MAX_CHARS = 64;\n\nconst BROWSER_FETCH_ERROR_CODES: ReadonlySet<string> = new Set<string>([\n\t\"browser_unavailable\",\n\t\"browser_cancelled\",\n\t\"browser_timeout\",\n\t\"browser_fetch_failed\",\n\t\"browser_profile_busy\",\n\t\"browser_profile_invalid\",\n\t\"browser_profile_missing\",\n\t\"browser_login_required\",\n]);\n\nexport type BrowserFetchErrorCodeV1 =\n\t| \"browser_unavailable\"\n\t| \"browser_cancelled\"\n\t| \"browser_timeout\"\n\t| \"browser_fetch_failed\"\n\t| \"browser_profile_busy\"\n\t| \"browser_profile_invalid\"\n\t| \"browser_profile_missing\"\n\t| \"browser_login_required\";\n\nexport interface BrowserFetchRequestV1 {\n\treadonly version: 1;\n\treadonly url: string;\n\t/** Named profile; default \"default\". Never a filesystem path. */\n\treadonly profile?: string;\n\treadonly timeoutMs?: number;\n}\n\nexport interface BrowserFetchResultV1 {\n\treadonly version: 1;\n\treadonly finalUrl: string;\n\treadonly title?: string;\n\t/** Visible page text, bounded to {@link BROWSER_FETCH_MAX_TEXT_CHARS}. */\n\treadonly text: string;\n\treadonly truncated: boolean;\n}\n\nexport interface BrowserFetchErrorV1 {\n\treadonly code: BrowserFetchErrorCodeV1;\n\treadonly message: string;\n}\n\nexport type BrowserFetchCapabilityResponseV1 =\n\t| { readonly version: 1; readonly ok: true; readonly result: BrowserFetchResultV1 }\n\t| { readonly version: 1; readonly ok: false; readonly error: BrowserFetchErrorV1 };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn url.protocol === \"http:\" || url.protocol === \"https:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Profile names are directory segments, never paths: no separators or dots-only names. */\nexport function isValidBrowserProfileNameV1(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.length > 0 &&\n\t\tvalue.length <= BROWSER_PROFILE_NAME_MAX_CHARS &&\n\t\t/^[a-z0-9][a-z0-9._-]*$/.test(value) &&\n\t\tvalue !== \".\" &&\n\t\tvalue !== \"..\"\n\t);\n}\n\nexport function parseBrowserFetchRequestV1(value: unknown): BrowserFetchRequestV1 {\n\tif (!isRecord(value)) throw new TypeError(\"browser.fetch request must be an object\");\n\tfor (const key of Object.keys(value)) {\n\t\tif (key !== \"version\" && key !== \"url\" && key !== \"profile\" && key !== \"timeoutMs\") {\n\t\t\tthrow new TypeError(`browser.fetch request has unknown key ${JSON.stringify(key)}`);\n\t\t}\n\t}\n\tif (value.version !== 1)\n\t\tthrow new TypeError(`browser.fetch request version must be 1, got ${String(value.version)}`);\n\tif (typeof value.url !== \"string\" || value.url.length === 0 || value.url.length > 2048 || !isHttpUrl(value.url)) {\n\t\tthrow new TypeError(\"browser.fetch request url must be an http(s) URL of at most 2048 characters\");\n\t}\n\tconst profile = value.profile === undefined ? \"default\" : value.profile;\n\tif (!isValidBrowserProfileNameV1(profile)) {\n\t\tthrow new TypeError(\n\t\t\t`browser.fetch request profile must match [a-z0-9][a-z0-9._-]* and be at most ${BROWSER_PROFILE_NAME_MAX_CHARS} characters`,\n\t\t);\n\t}\n\tconst timeoutMs = value.timeoutMs === undefined ? BROWSER_FETCH_DEFAULT_TIMEOUT_MS : value.timeoutMs;\n\tif (\n\t\ttypeof timeoutMs !== \"number\" ||\n\t\t!Number.isInteger(timeoutMs) ||\n\t\ttimeoutMs < BROWSER_FETCH_MIN_TIMEOUT_MS ||\n\t\ttimeoutMs > BROWSER_FETCH_MAX_TIMEOUT_MS\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`browser.fetch request timeoutMs must be an integer between ${BROWSER_FETCH_MIN_TIMEOUT_MS} and ${BROWSER_FETCH_MAX_TIMEOUT_MS}`,\n\t\t);\n\t}\n\treturn { version: 1, url: value.url, profile, timeoutMs };\n}\n\nexport function parseBrowserFetchResultV1(value: unknown): BrowserFetchResultV1 {\n\tif (!isRecord(value)) throw new TypeError(\"browser.fetch result must be an object\");\n\tif (value.version !== 1) throw new TypeError(`browser.fetch result version must be 1, got ${String(value.version)}`);\n\tif (typeof value.finalUrl !== \"string\" || !isHttpUrl(value.finalUrl)) {\n\t\tthrow new TypeError(\"browser.fetch result finalUrl must be an http(s) URL\");\n\t}\n\tif (\n\t\tvalue.title !== undefined &&\n\t\t(typeof value.title !== \"string\" || value.title.length > BROWSER_FETCH_MAX_TITLE_CHARS)\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`browser.fetch result title must be a string of at most ${BROWSER_FETCH_MAX_TITLE_CHARS} characters`,\n\t\t);\n\t}\n\tif (typeof value.text !== \"string\" || value.text.length > BROWSER_FETCH_MAX_TEXT_CHARS) {\n\t\tthrow new TypeError(\n\t\t\t`browser.fetch result text must be a string of at most ${BROWSER_FETCH_MAX_TEXT_CHARS} characters`,\n\t\t);\n\t}\n\tif (typeof value.truncated !== \"boolean\") throw new TypeError(\"browser.fetch result truncated must be a boolean\");\n\treturn {\n\t\tversion: 1,\n\t\tfinalUrl: value.finalUrl,\n\t\t...(value.title === undefined ? {} : { title: value.title }),\n\t\ttext: value.text,\n\t\ttruncated: value.truncated,\n\t};\n}\n\nexport function parseBrowserFetchCapabilityResponseV1(value: unknown): BrowserFetchCapabilityResponseV1 {\n\tif (!isRecord(value)) throw new TypeError(\"browser.fetch capability response must be an object\");\n\tif (value.version !== 1) {\n\t\tthrow new TypeError(`browser.fetch capability response version must be 1, got ${String(value.version)}`);\n\t}\n\tif (value.ok === true) {\n\t\treturn { version: 1, ok: true, result: parseBrowserFetchResultV1(value.result) };\n\t}\n\tif (value.ok === false) {\n\t\tconst error = value.error;\n\t\tif (!isRecord(error)) throw new TypeError(\"browser.fetch capability error must be an object\");\n\t\tif (typeof error.code !== \"string\" || !BROWSER_FETCH_ERROR_CODES.has(error.code)) {\n\t\t\tthrow new TypeError(`browser.fetch capability error has an unknown code ${JSON.stringify(error.code)}`);\n\t\t}\n\t\tif (\n\t\t\ttypeof error.message !== \"string\" ||\n\t\t\terror.message.length === 0 ||\n\t\t\terror.message.length > BROWSER_FETCH_MAX_ERROR_CHARS\n\t\t) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`browser.fetch capability error message must be 1..${BROWSER_FETCH_MAX_ERROR_CHARS} characters`,\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tversion: 1,\n\t\t\tok: false,\n\t\t\terror: { code: error.code as BrowserFetchErrorCodeV1, message: error.message },\n\t\t};\n\t}\n\tthrow new TypeError(\"browser.fetch capability response ok must be a boolean\");\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
export * from "./agent-task-scheduler.ts";
|
|
1
2
|
export * from "./artifact.ts";
|
|
3
|
+
export * from "./browser-fetch.ts";
|
|
2
4
|
export * from "./capability-manifest.ts";
|
|
3
5
|
export * from "./common.ts";
|
|
4
6
|
export * from "./context-budget.ts";
|
|
5
7
|
export * from "./diff.ts";
|
|
6
8
|
export * from "./durable.ts";
|
|
7
9
|
export * from "./ecosystem-manifest.ts";
|
|
10
|
+
export * from "./mcp-client.ts";
|
|
8
11
|
export * from "./memory.ts";
|
|
12
|
+
export * from "./network-route.ts";
|
|
9
13
|
export * from "./observability.ts";
|
|
10
14
|
export * from "./operation.ts";
|
|
11
15
|
export * from "./public-api.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./artifact.ts\";\nexport * from \"./capability-manifest.ts\";\nexport * from \"./common.ts\";\nexport * from \"./context-budget.ts\";\nexport * from \"./diff.ts\";\nexport * from \"./durable.ts\";\nexport * from \"./ecosystem-manifest.ts\";\nexport * from \"./memory.ts\";\nexport * from \"./observability.ts\";\nexport * from \"./operation.ts\";\nexport * from \"./public-api.ts\";\nexport * from \"./render.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./agent-task-scheduler.ts\";\nexport * from \"./artifact.ts\";\nexport * from \"./browser-fetch.ts\";\nexport * from \"./capability-manifest.ts\";\nexport * from \"./common.ts\";\nexport * from \"./context-budget.ts\";\nexport * from \"./diff.ts\";\nexport * from \"./durable.ts\";\nexport * from \"./ecosystem-manifest.ts\";\nexport * from \"./mcp-client.ts\";\nexport * from \"./memory.ts\";\nexport * from \"./network-route.ts\";\nexport * from \"./observability.ts\";\nexport * from \"./operation.ts\";\nexport * from \"./public-api.ts\";\nexport * from \"./render.ts\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
export * from "./agent-task-scheduler.js";
|
|
1
2
|
export * from "./artifact.js";
|
|
3
|
+
export * from "./browser-fetch.js";
|
|
2
4
|
export * from "./capability-manifest.js";
|
|
3
5
|
export * from "./common.js";
|
|
4
6
|
export * from "./context-budget.js";
|
|
5
7
|
export * from "./diff.js";
|
|
6
8
|
export * from "./durable.js";
|
|
7
9
|
export * from "./ecosystem-manifest.js";
|
|
10
|
+
export * from "./mcp-client.js";
|
|
8
11
|
export * from "./memory.js";
|
|
12
|
+
export * from "./network-route.js";
|
|
9
13
|
export * from "./observability.js";
|
|
10
14
|
export * from "./operation.js";
|
|
11
15
|
export * from "./public-api.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./artifact.ts\";\nexport * from \"./capability-manifest.ts\";\nexport * from \"./common.ts\";\nexport * from \"./context-budget.ts\";\nexport * from \"./diff.ts\";\nexport * from \"./durable.ts\";\nexport * from \"./ecosystem-manifest.ts\";\nexport * from \"./memory.ts\";\nexport * from \"./observability.ts\";\nexport * from \"./operation.ts\";\nexport * from \"./public-api.ts\";\nexport * from \"./render.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["export * from \"./agent-task-scheduler.ts\";\nexport * from \"./artifact.ts\";\nexport * from \"./browser-fetch.ts\";\nexport * from \"./capability-manifest.ts\";\nexport * from \"./common.ts\";\nexport * from \"./context-budget.ts\";\nexport * from \"./diff.ts\";\nexport * from \"./durable.ts\";\nexport * from \"./ecosystem-manifest.ts\";\nexport * from \"./mcp-client.ts\";\nexport * from \"./memory.ts\";\nexport * from \"./network-route.ts\";\nexport * from \"./observability.ts\";\nexport * from \"./operation.ts\";\nexport * from \"./public-api.ts\";\nexport * from \"./render.ts\";\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public MCP client capability contract(联网检索设计 §5.2,P1a)。
|
|
3
|
+
*
|
|
4
|
+
* 每个由宿主物化的 MCP server 插件提供
|
|
5
|
+
* `agent-forge.mcp.client.<server>@1`;消费方只经能力目录
|
|
6
|
+
* 调用,不直接依赖 `plugins/mcp-http` 的实现。请求/响应必须是 JSON 可序列化
|
|
7
|
+
* 数据;失败以 `status:"failed"` 信封返回,不跨边界抛裸异常。
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginErrorV1 } from "./operation.ts";
|
|
10
|
+
export declare const MCP_CLIENT_CAPABILITY_PREFIX: "agent-forge.mcp.client.";
|
|
11
|
+
export interface McpClientToolV1 {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly description?: string;
|
|
14
|
+
/** Raw server input schema (JSON Schema), preserved for discovery/argument validation. */
|
|
15
|
+
readonly inputSchema?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export type McpClientRequestV1 = {
|
|
18
|
+
readonly version: 1;
|
|
19
|
+
readonly operation: "listTools";
|
|
20
|
+
readonly server: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly version: 1;
|
|
23
|
+
readonly operation: "callTool";
|
|
24
|
+
readonly server: string;
|
|
25
|
+
readonly tool: string;
|
|
26
|
+
readonly arguments: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
export type McpClientResponseV1 = {
|
|
29
|
+
readonly version: 1;
|
|
30
|
+
readonly status: "ok";
|
|
31
|
+
readonly value: unknown;
|
|
32
|
+
} | {
|
|
33
|
+
readonly version: 1;
|
|
34
|
+
readonly status: "failed";
|
|
35
|
+
readonly error: PluginErrorV1;
|
|
36
|
+
};
|
|
37
|
+
export interface McpClientListToolsValueV1 {
|
|
38
|
+
readonly server: string;
|
|
39
|
+
/** Comes from the generated plugin's resolved `clientOnly` config; callers must not infer it from the id. */
|
|
40
|
+
readonly clientOnly: boolean;
|
|
41
|
+
readonly tools: readonly McpClientToolV1[];
|
|
42
|
+
}
|
|
43
|
+
/** Build the per-server capability id. */
|
|
44
|
+
export declare function mcpClientCapabilityId(server: string): string;
|
|
45
|
+
//# sourceMappingURL=mcp-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,eAAO,MAAM,4BAA4B,2BAAqC,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0FAA0F;IAC1F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAC3B;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjF;IACA,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEL,MAAM,MAAM,mBAAmB,GAC5B;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6GAA6G;IAC7G,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CAC3C;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D","sourcesContent":["/**\n * Public MCP client capability contract(联网检索设计 §5.2,P1a)。\n *\n * 每个由宿主物化的 MCP server 插件提供\n * `agent-forge.mcp.client.<server>@1`;消费方只经能力目录\n * 调用,不直接依赖 `plugins/mcp-http` 的实现。请求/响应必须是 JSON 可序列化\n * 数据;失败以 `status:\"failed\"` 信封返回,不跨边界抛裸异常。\n */\n\nimport type { PluginErrorV1 } from \"./operation.ts\";\n\nexport const MCP_CLIENT_CAPABILITY_PREFIX = \"agent-forge.mcp.client.\" as const;\n\nexport interface McpClientToolV1 {\n\treadonly name: string;\n\treadonly description?: string;\n\t/** Raw server input schema (JSON Schema), preserved for discovery/argument validation. */\n\treadonly inputSchema?: unknown;\n}\n\nexport type McpClientRequestV1 =\n\t| { readonly version: 1; readonly operation: \"listTools\"; readonly server: string }\n\t| {\n\t\t\treadonly version: 1;\n\t\t\treadonly operation: \"callTool\";\n\t\t\treadonly server: string;\n\t\t\treadonly tool: string;\n\t\t\treadonly arguments: Record<string, unknown>;\n\t };\n\nexport type McpClientResponseV1 =\n\t| { readonly version: 1; readonly status: \"ok\"; readonly value: unknown }\n\t| { readonly version: 1; readonly status: \"failed\"; readonly error: PluginErrorV1 };\n\nexport interface McpClientListToolsValueV1 {\n\treadonly server: string;\n\t/** Comes from the generated plugin's resolved `clientOnly` config; callers must not infer it from the id. */\n\treadonly clientOnly: boolean;\n\treadonly tools: readonly McpClientToolV1[];\n}\n\n/** Build the per-server capability id. */\nexport function mcpClientCapabilityId(server: string): string {\n\treturn `${MCP_CLIENT_CAPABILITY_PREFIX}${server}`;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public MCP client capability contract(联网检索设计 §5.2,P1a)。
|
|
3
|
+
*
|
|
4
|
+
* 每个由宿主物化的 MCP server 插件提供
|
|
5
|
+
* `agent-forge.mcp.client.<server>@1`;消费方只经能力目录
|
|
6
|
+
* 调用,不直接依赖 `plugins/mcp-http` 的实现。请求/响应必须是 JSON 可序列化
|
|
7
|
+
* 数据;失败以 `status:"failed"` 信封返回,不跨边界抛裸异常。
|
|
8
|
+
*/
|
|
9
|
+
export const MCP_CLIENT_CAPABILITY_PREFIX = "agent-forge.mcp.client.";
|
|
10
|
+
/** Build the per-server capability id. */
|
|
11
|
+
export function mcpClientCapabilityId(server) {
|
|
12
|
+
return `${MCP_CLIENT_CAPABILITY_PREFIX}${server}`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,CAAC,MAAM,4BAA4B,GAAG,yBAAkC,CAAC;AA8B/E,0CAA0C;AAC1C,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAU;IAC7D,OAAO,GAAG,4BAA4B,GAAG,MAAM,EAAE,CAAC;AAAA,CAClD","sourcesContent":["/**\n * Public MCP client capability contract(联网检索设计 §5.2,P1a)。\n *\n * 每个由宿主物化的 MCP server 插件提供\n * `agent-forge.mcp.client.<server>@1`;消费方只经能力目录\n * 调用,不直接依赖 `plugins/mcp-http` 的实现。请求/响应必须是 JSON 可序列化\n * 数据;失败以 `status:\"failed\"` 信封返回,不跨边界抛裸异常。\n */\n\nimport type { PluginErrorV1 } from \"./operation.ts\";\n\nexport const MCP_CLIENT_CAPABILITY_PREFIX = \"agent-forge.mcp.client.\" as const;\n\nexport interface McpClientToolV1 {\n\treadonly name: string;\n\treadonly description?: string;\n\t/** Raw server input schema (JSON Schema), preserved for discovery/argument validation. */\n\treadonly inputSchema?: unknown;\n}\n\nexport type McpClientRequestV1 =\n\t| { readonly version: 1; readonly operation: \"listTools\"; readonly server: string }\n\t| {\n\t\t\treadonly version: 1;\n\t\t\treadonly operation: \"callTool\";\n\t\t\treadonly server: string;\n\t\t\treadonly tool: string;\n\t\t\treadonly arguments: Record<string, unknown>;\n\t };\n\nexport type McpClientResponseV1 =\n\t| { readonly version: 1; readonly status: \"ok\"; readonly value: unknown }\n\t| { readonly version: 1; readonly status: \"failed\"; readonly error: PluginErrorV1 };\n\nexport interface McpClientListToolsValueV1 {\n\treadonly server: string;\n\t/** Comes from the generated plugin's resolved `clientOnly` config; callers must not infer it from the id. */\n\treadonly clientOnly: boolean;\n\treadonly tools: readonly McpClientToolV1[];\n}\n\n/** Build the per-server capability id. */\nexport function mcpClientCapabilityId(server: string): string {\n\treturn `${MCP_CLIENT_CAPABILITY_PREFIX}${server}`;\n}\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared network route contract(联网检索设计 §7.1): P1 routes every external
|
|
3
|
+
* egress either `direct` or through a single HTTP/HTTPS proxy. The route only
|
|
4
|
+
* picks the egress — it never rejects loopback/private targets and never logs
|
|
5
|
+
* credentials. `auto`/`overrides`/SOCKS5 are out of contract in P1 and are
|
|
6
|
+
* rejected at parse time.
|
|
7
|
+
*/
|
|
8
|
+
export interface ProxyEndpointV1 {
|
|
9
|
+
/** Absolute http:// or https:// URL with a host and no path/query/hash/userinfo. */
|
|
10
|
+
readonly url: string;
|
|
11
|
+
readonly username?: string;
|
|
12
|
+
readonly password?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface NetworkRouteConfigV1 {
|
|
15
|
+
readonly version: 1;
|
|
16
|
+
readonly mode: "direct" | "proxy";
|
|
17
|
+
readonly proxy?: ProxyEndpointV1;
|
|
18
|
+
/** Allow falling back to direct when the proxy fails; default false (design §7.1). */
|
|
19
|
+
readonly fallbackToDirect?: boolean;
|
|
20
|
+
/** Hosts that always go direct (e.g. local MCP); egress choice only, no private-net rejection. */
|
|
21
|
+
readonly bypass?: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
export interface NetworkRouteResolutionV1 {
|
|
24
|
+
readonly mode: "direct" | "proxy";
|
|
25
|
+
readonly proxy?: ProxyEndpointV1;
|
|
26
|
+
/** Why the egress was chosen: the config mode itself, or a bypass entry forcing direct. */
|
|
27
|
+
readonly reason: "mode" | "bypass";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Strict parser for the P1 route config (design §7.1): every field is
|
|
31
|
+
* type-checked, unknown keys are rejected, and `mode: "proxy"` requires a
|
|
32
|
+
* proxy endpoint. Throws with a field-scoped message — callers must surface
|
|
33
|
+
* the error (config errors never silently downgrade to direct).
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseNetworkRouteConfigV1(value: unknown): NetworkRouteConfigV1;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the egress for one target host (design §7.1): bypass wins over the
|
|
38
|
+
* proxy mode; proxy mode returns the configured endpoint. Never rejects
|
|
39
|
+
* loopback/private targets and never logs — consumers own those decisions.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveNetworkRouteV1(config: NetworkRouteConfigV1, host: string): NetworkRouteResolutionV1;
|
|
42
|
+
/**
|
|
43
|
+
* Pure env parsing (design §7.1/§10): `HTTPS_PROXY` wins over `HTTP_PROXY`;
|
|
44
|
+
* a proxy means `mode: "proxy"`; `NO_PROXY` entries (comma-separated) become
|
|
45
|
+
* `bypass`; no proxy means `direct`. Reads only the argument — never
|
|
46
|
+
* `process.env`. Throws on a malformed proxy URL (fail-closed, no downgrade).
|
|
47
|
+
*/
|
|
48
|
+
export declare function networkRouteConfigFromEnv(env: Record<string, string | undefined>): NetworkRouteConfigV1;
|
|
49
|
+
/**
|
|
50
|
+
* Settings precedence (design §7.1/§10): a settings-provided route wins as-is —
|
|
51
|
+
* an explicit `mode: "direct"` must not be flipped back to proxy by env vars.
|
|
52
|
+
* Without settings the env fallback applies.
|
|
53
|
+
*/
|
|
54
|
+
export declare function mergeNetworkRouteConfig(settings: NetworkRouteConfigV1 | undefined, env: Record<string, string | undefined>): NetworkRouteConfigV1;
|
|
55
|
+
//# sourceMappingURL=network-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-route.d.ts","sourceRoot":"","sources":["../src/network-route.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,uFAAsF;IACtF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,kGAAkG;IAClG,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CACnC;AAkED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CA0C9E;AA2BD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAQ1G;AASD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,oBAAoB,CAavG;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,EAC1C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACrC,oBAAoB,CAEtB","sourcesContent":["/**\n * Shared network route contract(联网检索设计 §7.1): P1 routes every external\n * egress either `direct` or through a single HTTP/HTTPS proxy. The route only\n * picks the egress — it never rejects loopback/private targets and never logs\n * credentials. `auto`/`overrides`/SOCKS5 are out of contract in P1 and are\n * rejected at parse time.\n */\n\nexport interface ProxyEndpointV1 {\n\t/** Absolute http:// or https:// URL with a host and no path/query/hash/userinfo. */\n\treadonly url: string;\n\treadonly username?: string;\n\treadonly password?: string;\n}\n\nexport interface NetworkRouteConfigV1 {\n\treadonly version: 1;\n\treadonly mode: \"direct\" | \"proxy\";\n\treadonly proxy?: ProxyEndpointV1;\n\t/** Allow falling back to direct when the proxy fails; default false (design §7.1). */\n\treadonly fallbackToDirect?: boolean;\n\t/** Hosts that always go direct (e.g. local MCP); egress choice only, no private-net rejection. */\n\treadonly bypass?: readonly string[];\n}\n\nexport interface NetworkRouteResolutionV1 {\n\treadonly mode: \"direct\" | \"proxy\";\n\treadonly proxy?: ProxyEndpointV1;\n\t/** Why the egress was chosen: the config mode itself, or a bypass entry forcing direct. */\n\treadonly reason: \"mode\" | \"bypass\";\n}\n\nconst NETWORK_ROUTE_CONFIG_KEYS: ReadonlySet<string> = new Set([\n\t\"version\",\n\t\"mode\",\n\t\"proxy\",\n\t\"fallbackToDirect\",\n\t\"bypass\",\n]);\n\nconst PROXY_ENDPOINT_KEYS: ReadonlySet<string> = new Set([\"url\", \"username\", \"password\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertOnlyKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, label: string): void {\n\tfor (const key of Object.keys(value)) {\n\t\tif (!allowed.has(key)) throw new Error(`${label} has unknown key \"${key}\"`);\n\t}\n}\n\nfunction parseProxyEndpointV1(value: unknown): ProxyEndpointV1 {\n\tif (!isRecord(value)) throw new Error(\"network.proxy must be an object\");\n\tassertOnlyKeys(value, PROXY_ENDPOINT_KEYS, \"network.proxy\");\n\n\tconst url = value.url;\n\tif (typeof url !== \"string\" || url.trim() === \"\") {\n\t\tthrow new Error(\"network.proxy.url must be a non-empty string\");\n\t}\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new Error(`network.proxy.url must be an absolute http:// or https:// URL: ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\tthrow new Error(`network.proxy.url must use http:// or https:// (P1 has no SOCKS5): ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.hostname === \"\") {\n\t\tthrow new Error(`network.proxy.url must include a host: ${JSON.stringify(url)}`);\n\t}\n\tif ((parsed.pathname !== \"\" && parsed.pathname !== \"/\") || parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new Error(`network.proxy.url must not include a path, query, or hash: ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.username !== \"\" || parsed.password !== \"\") {\n\t\tthrow new Error(\n\t\t\t`network.proxy.url must not embed credentials; use network.proxy.username/password instead: ${JSON.stringify(url)}`,\n\t\t);\n\t}\n\n\tconst username = value.username;\n\tif (username !== undefined && typeof username !== \"string\") {\n\t\tthrow new Error(\"network.proxy.username must be a string when present\");\n\t}\n\tconst password = value.password;\n\tif (password !== undefined && typeof password !== \"string\") {\n\t\tthrow new Error(\"network.proxy.password must be a string when present\");\n\t}\n\treturn {\n\t\turl,\n\t\t...(username === undefined ? {} : { username }),\n\t\t...(password === undefined ? {} : { password }),\n\t};\n}\n\n/**\n * Strict parser for the P1 route config (design §7.1): every field is\n * type-checked, unknown keys are rejected, and `mode: \"proxy\"` requires a\n * proxy endpoint. Throws with a field-scoped message — callers must surface\n * the error (config errors never silently downgrade to direct).\n */\nexport function parseNetworkRouteConfigV1(value: unknown): NetworkRouteConfigV1 {\n\tif (!isRecord(value)) throw new Error(\"network config must be an object\");\n\tassertOnlyKeys(value, NETWORK_ROUTE_CONFIG_KEYS, \"network config\");\n\n\tif (value.version !== 1) throw new Error(`network.version must be 1: ${String(value.version)}`);\n\n\tconst mode = value.mode;\n\tif (mode !== \"direct\" && mode !== \"proxy\") {\n\t\tthrow new Error(`network.mode must be \"direct\" or \"proxy\": ${String(mode)}`);\n\t}\n\n\tconst fallbackToDirect = value.fallbackToDirect;\n\tif (fallbackToDirect !== undefined && typeof fallbackToDirect !== \"boolean\") {\n\t\tthrow new Error(\"network.fallbackToDirect must be a boolean when present\");\n\t}\n\n\tlet bypass: readonly string[] | undefined;\n\tif (value.bypass !== undefined) {\n\t\tif (!Array.isArray(value.bypass)) throw new Error(\"network.bypass must be an array of strings\");\n\t\tbypass = value.bypass.map((entry, index) => {\n\t\t\tif (typeof entry !== \"string\" || entry.trim() === \"\") {\n\t\t\t\tthrow new Error(`network.bypass[${index}] must be a non-empty string`);\n\t\t\t}\n\t\t\treturn entry;\n\t\t});\n\t}\n\n\tlet proxy: ProxyEndpointV1 | undefined;\n\tif (value.proxy !== undefined) {\n\t\tproxy = parseProxyEndpointV1(value.proxy);\n\t}\n\tif (mode === \"proxy\" && proxy === undefined) {\n\t\tthrow new Error('network mode \"proxy\" requires network.proxy.url');\n\t}\n\n\treturn {\n\t\tversion: 1,\n\t\tmode,\n\t\t...(proxy === undefined ? {} : { proxy }),\n\t\t...(fallbackToDirect === undefined ? {} : { fallbackToDirect }),\n\t\t...(bypass === undefined ? {} : { bypass }),\n\t};\n}\n\n/** Lowercase and strip one trailing dot so `Example.COM.` matches `example.com`. */\nfunction normalizeHostEntry(entry: string): string {\n\tconst lowered = entry.toLowerCase();\n\treturn lowered.endsWith(\".\") ? lowered.slice(0, -1) : lowered;\n}\n\n/**\n * Bypass match (design §7.1): exact host, `*.suffix` subdomain wildcard, or a\n * leading dot as an exact equivalent of `*.`. IP literals participate as exact\n * strings only — P1 has no CIDR.\n */\nfunction matchesBypassEntry(pattern: string, host: string): boolean {\n\tconst normalized = normalizeHostEntry(pattern);\n\tif (normalized === \"\") return false;\n\tif (normalized.startsWith(\"*.\")) {\n\t\tconst suffix = normalized.slice(2);\n\t\treturn suffix !== \"\" && host.endsWith(`.${suffix}`);\n\t}\n\tif (normalized.startsWith(\".\")) {\n\t\tconst suffix = normalized.slice(1);\n\t\treturn suffix !== \"\" && host.endsWith(`.${suffix}`);\n\t}\n\treturn normalized === host;\n}\n\n/**\n * Resolve the egress for one target host (design §7.1): bypass wins over the\n * proxy mode; proxy mode returns the configured endpoint. Never rejects\n * loopback/private targets and never logs — consumers own those decisions.\n */\nexport function resolveNetworkRouteV1(config: NetworkRouteConfigV1, host: string): NetworkRouteResolutionV1 {\n\tconst normalizedHost = normalizeHostEntry(host);\n\tif (config.mode === \"proxy\" && config.proxy !== undefined) {\n\t\tconst bypassed = (config.bypass ?? []).some((pattern) => matchesBypassEntry(pattern, normalizedHost));\n\t\tif (bypassed) return { mode: \"direct\", reason: \"bypass\" };\n\t\treturn { mode: \"proxy\", proxy: config.proxy, reason: \"mode\" };\n\t}\n\treturn { mode: \"direct\", reason: \"mode\" };\n}\n\nconst firstNonEmpty = (values: Array<string | undefined>): string | undefined => {\n\tfor (const value of values) {\n\t\tif (value !== undefined && value.trim() !== \"\") return value;\n\t}\n\treturn undefined;\n};\n\n/**\n * Pure env parsing (design §7.1/§10): `HTTPS_PROXY` wins over `HTTP_PROXY`;\n * a proxy means `mode: \"proxy\"`; `NO_PROXY` entries (comma-separated) become\n * `bypass`; no proxy means `direct`. Reads only the argument — never\n * `process.env`. Throws on a malformed proxy URL (fail-closed, no downgrade).\n */\nexport function networkRouteConfigFromEnv(env: Record<string, string | undefined>): NetworkRouteConfigV1 {\n\tconst proxyUrl = firstNonEmpty([env.HTTPS_PROXY, env.HTTP_PROXY]);\n\tif (proxyUrl === undefined) return { version: 1, mode: \"direct\" };\n\tconst bypass = (env.NO_PROXY ?? \"\")\n\t\t.split(\",\")\n\t\t.map((entry) => entry.trim())\n\t\t.filter((entry) => entry !== \"\");\n\treturn parseNetworkRouteConfigV1({\n\t\tversion: 1,\n\t\tmode: \"proxy\",\n\t\tproxy: { url: proxyUrl },\n\t\t...(bypass.length === 0 ? {} : { bypass }),\n\t});\n}\n\n/**\n * Settings precedence (design §7.1/§10): a settings-provided route wins as-is —\n * an explicit `mode: \"direct\"` must not be flipped back to proxy by env vars.\n * Without settings the env fallback applies.\n */\nexport function mergeNetworkRouteConfig(\n\tsettings: NetworkRouteConfigV1 | undefined,\n\tenv: Record<string, string | undefined>,\n): NetworkRouteConfigV1 {\n\treturn settings === undefined ? networkRouteConfigFromEnv(env) : settings;\n}\n"]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared network route contract(联网检索设计 §7.1): P1 routes every external
|
|
3
|
+
* egress either `direct` or through a single HTTP/HTTPS proxy. The route only
|
|
4
|
+
* picks the egress — it never rejects loopback/private targets and never logs
|
|
5
|
+
* credentials. `auto`/`overrides`/SOCKS5 are out of contract in P1 and are
|
|
6
|
+
* rejected at parse time.
|
|
7
|
+
*/
|
|
8
|
+
const NETWORK_ROUTE_CONFIG_KEYS = new Set([
|
|
9
|
+
"version",
|
|
10
|
+
"mode",
|
|
11
|
+
"proxy",
|
|
12
|
+
"fallbackToDirect",
|
|
13
|
+
"bypass",
|
|
14
|
+
]);
|
|
15
|
+
const PROXY_ENDPOINT_KEYS = new Set(["url", "username", "password"]);
|
|
16
|
+
function isRecord(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
function assertOnlyKeys(value, allowed, label) {
|
|
20
|
+
for (const key of Object.keys(value)) {
|
|
21
|
+
if (!allowed.has(key))
|
|
22
|
+
throw new Error(`${label} has unknown key "${key}"`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function parseProxyEndpointV1(value) {
|
|
26
|
+
if (!isRecord(value))
|
|
27
|
+
throw new Error("network.proxy must be an object");
|
|
28
|
+
assertOnlyKeys(value, PROXY_ENDPOINT_KEYS, "network.proxy");
|
|
29
|
+
const url = value.url;
|
|
30
|
+
if (typeof url !== "string" || url.trim() === "") {
|
|
31
|
+
throw new Error("network.proxy.url must be a non-empty string");
|
|
32
|
+
}
|
|
33
|
+
let parsed;
|
|
34
|
+
try {
|
|
35
|
+
parsed = new URL(url);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new Error(`network.proxy.url must be an absolute http:// or https:// URL: ${JSON.stringify(url)}`);
|
|
39
|
+
}
|
|
40
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
41
|
+
throw new Error(`network.proxy.url must use http:// or https:// (P1 has no SOCKS5): ${JSON.stringify(url)}`);
|
|
42
|
+
}
|
|
43
|
+
if (parsed.hostname === "") {
|
|
44
|
+
throw new Error(`network.proxy.url must include a host: ${JSON.stringify(url)}`);
|
|
45
|
+
}
|
|
46
|
+
if ((parsed.pathname !== "" && parsed.pathname !== "/") || parsed.search !== "" || parsed.hash !== "") {
|
|
47
|
+
throw new Error(`network.proxy.url must not include a path, query, or hash: ${JSON.stringify(url)}`);
|
|
48
|
+
}
|
|
49
|
+
if (parsed.username !== "" || parsed.password !== "") {
|
|
50
|
+
throw new Error(`network.proxy.url must not embed credentials; use network.proxy.username/password instead: ${JSON.stringify(url)}`);
|
|
51
|
+
}
|
|
52
|
+
const username = value.username;
|
|
53
|
+
if (username !== undefined && typeof username !== "string") {
|
|
54
|
+
throw new Error("network.proxy.username must be a string when present");
|
|
55
|
+
}
|
|
56
|
+
const password = value.password;
|
|
57
|
+
if (password !== undefined && typeof password !== "string") {
|
|
58
|
+
throw new Error("network.proxy.password must be a string when present");
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
url,
|
|
62
|
+
...(username === undefined ? {} : { username }),
|
|
63
|
+
...(password === undefined ? {} : { password }),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Strict parser for the P1 route config (design §7.1): every field is
|
|
68
|
+
* type-checked, unknown keys are rejected, and `mode: "proxy"` requires a
|
|
69
|
+
* proxy endpoint. Throws with a field-scoped message — callers must surface
|
|
70
|
+
* the error (config errors never silently downgrade to direct).
|
|
71
|
+
*/
|
|
72
|
+
export function parseNetworkRouteConfigV1(value) {
|
|
73
|
+
if (!isRecord(value))
|
|
74
|
+
throw new Error("network config must be an object");
|
|
75
|
+
assertOnlyKeys(value, NETWORK_ROUTE_CONFIG_KEYS, "network config");
|
|
76
|
+
if (value.version !== 1)
|
|
77
|
+
throw new Error(`network.version must be 1: ${String(value.version)}`);
|
|
78
|
+
const mode = value.mode;
|
|
79
|
+
if (mode !== "direct" && mode !== "proxy") {
|
|
80
|
+
throw new Error(`network.mode must be "direct" or "proxy": ${String(mode)}`);
|
|
81
|
+
}
|
|
82
|
+
const fallbackToDirect = value.fallbackToDirect;
|
|
83
|
+
if (fallbackToDirect !== undefined && typeof fallbackToDirect !== "boolean") {
|
|
84
|
+
throw new Error("network.fallbackToDirect must be a boolean when present");
|
|
85
|
+
}
|
|
86
|
+
let bypass;
|
|
87
|
+
if (value.bypass !== undefined) {
|
|
88
|
+
if (!Array.isArray(value.bypass))
|
|
89
|
+
throw new Error("network.bypass must be an array of strings");
|
|
90
|
+
bypass = value.bypass.map((entry, index) => {
|
|
91
|
+
if (typeof entry !== "string" || entry.trim() === "") {
|
|
92
|
+
throw new Error(`network.bypass[${index}] must be a non-empty string`);
|
|
93
|
+
}
|
|
94
|
+
return entry;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
let proxy;
|
|
98
|
+
if (value.proxy !== undefined) {
|
|
99
|
+
proxy = parseProxyEndpointV1(value.proxy);
|
|
100
|
+
}
|
|
101
|
+
if (mode === "proxy" && proxy === undefined) {
|
|
102
|
+
throw new Error('network mode "proxy" requires network.proxy.url');
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
version: 1,
|
|
106
|
+
mode,
|
|
107
|
+
...(proxy === undefined ? {} : { proxy }),
|
|
108
|
+
...(fallbackToDirect === undefined ? {} : { fallbackToDirect }),
|
|
109
|
+
...(bypass === undefined ? {} : { bypass }),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** Lowercase and strip one trailing dot so `Example.COM.` matches `example.com`. */
|
|
113
|
+
function normalizeHostEntry(entry) {
|
|
114
|
+
const lowered = entry.toLowerCase();
|
|
115
|
+
return lowered.endsWith(".") ? lowered.slice(0, -1) : lowered;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Bypass match (design §7.1): exact host, `*.suffix` subdomain wildcard, or a
|
|
119
|
+
* leading dot as an exact equivalent of `*.`. IP literals participate as exact
|
|
120
|
+
* strings only — P1 has no CIDR.
|
|
121
|
+
*/
|
|
122
|
+
function matchesBypassEntry(pattern, host) {
|
|
123
|
+
const normalized = normalizeHostEntry(pattern);
|
|
124
|
+
if (normalized === "")
|
|
125
|
+
return false;
|
|
126
|
+
if (normalized.startsWith("*.")) {
|
|
127
|
+
const suffix = normalized.slice(2);
|
|
128
|
+
return suffix !== "" && host.endsWith(`.${suffix}`);
|
|
129
|
+
}
|
|
130
|
+
if (normalized.startsWith(".")) {
|
|
131
|
+
const suffix = normalized.slice(1);
|
|
132
|
+
return suffix !== "" && host.endsWith(`.${suffix}`);
|
|
133
|
+
}
|
|
134
|
+
return normalized === host;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Resolve the egress for one target host (design §7.1): bypass wins over the
|
|
138
|
+
* proxy mode; proxy mode returns the configured endpoint. Never rejects
|
|
139
|
+
* loopback/private targets and never logs — consumers own those decisions.
|
|
140
|
+
*/
|
|
141
|
+
export function resolveNetworkRouteV1(config, host) {
|
|
142
|
+
const normalizedHost = normalizeHostEntry(host);
|
|
143
|
+
if (config.mode === "proxy" && config.proxy !== undefined) {
|
|
144
|
+
const bypassed = (config.bypass ?? []).some((pattern) => matchesBypassEntry(pattern, normalizedHost));
|
|
145
|
+
if (bypassed)
|
|
146
|
+
return { mode: "direct", reason: "bypass" };
|
|
147
|
+
return { mode: "proxy", proxy: config.proxy, reason: "mode" };
|
|
148
|
+
}
|
|
149
|
+
return { mode: "direct", reason: "mode" };
|
|
150
|
+
}
|
|
151
|
+
const firstNonEmpty = (values) => {
|
|
152
|
+
for (const value of values) {
|
|
153
|
+
if (value !== undefined && value.trim() !== "")
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
return undefined;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Pure env parsing (design §7.1/§10): `HTTPS_PROXY` wins over `HTTP_PROXY`;
|
|
160
|
+
* a proxy means `mode: "proxy"`; `NO_PROXY` entries (comma-separated) become
|
|
161
|
+
* `bypass`; no proxy means `direct`. Reads only the argument — never
|
|
162
|
+
* `process.env`. Throws on a malformed proxy URL (fail-closed, no downgrade).
|
|
163
|
+
*/
|
|
164
|
+
export function networkRouteConfigFromEnv(env) {
|
|
165
|
+
const proxyUrl = firstNonEmpty([env.HTTPS_PROXY, env.HTTP_PROXY]);
|
|
166
|
+
if (proxyUrl === undefined)
|
|
167
|
+
return { version: 1, mode: "direct" };
|
|
168
|
+
const bypass = (env.NO_PROXY ?? "")
|
|
169
|
+
.split(",")
|
|
170
|
+
.map((entry) => entry.trim())
|
|
171
|
+
.filter((entry) => entry !== "");
|
|
172
|
+
return parseNetworkRouteConfigV1({
|
|
173
|
+
version: 1,
|
|
174
|
+
mode: "proxy",
|
|
175
|
+
proxy: { url: proxyUrl },
|
|
176
|
+
...(bypass.length === 0 ? {} : { bypass }),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Settings precedence (design §7.1/§10): a settings-provided route wins as-is —
|
|
181
|
+
* an explicit `mode: "direct"` must not be flipped back to proxy by env vars.
|
|
182
|
+
* Without settings the env fallback applies.
|
|
183
|
+
*/
|
|
184
|
+
export function mergeNetworkRouteConfig(settings, env) {
|
|
185
|
+
return settings === undefined ? networkRouteConfigFromEnv(env) : settings;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=network-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-route.js","sourceRoot":"","sources":["../src/network-route.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared network route contract(联网检索设计 §7.1): P1 routes every external\n * egress either `direct` or through a single HTTP/HTTPS proxy. The route only\n * picks the egress — it never rejects loopback/private targets and never logs\n * credentials. `auto`/`overrides`/SOCKS5 are out of contract in P1 and are\n * rejected at parse time.\n */\n\nexport interface ProxyEndpointV1 {\n\t/** Absolute http:// or https:// URL with a host and no path/query/hash/userinfo. */\n\treadonly url: string;\n\treadonly username?: string;\n\treadonly password?: string;\n}\n\nexport interface NetworkRouteConfigV1 {\n\treadonly version: 1;\n\treadonly mode: \"direct\" | \"proxy\";\n\treadonly proxy?: ProxyEndpointV1;\n\t/** Allow falling back to direct when the proxy fails; default false (design §7.1). */\n\treadonly fallbackToDirect?: boolean;\n\t/** Hosts that always go direct (e.g. local MCP); egress choice only, no private-net rejection. */\n\treadonly bypass?: readonly string[];\n}\n\nexport interface NetworkRouteResolutionV1 {\n\treadonly mode: \"direct\" | \"proxy\";\n\treadonly proxy?: ProxyEndpointV1;\n\t/** Why the egress was chosen: the config mode itself, or a bypass entry forcing direct. */\n\treadonly reason: \"mode\" | \"bypass\";\n}\n\nconst NETWORK_ROUTE_CONFIG_KEYS: ReadonlySet<string> = new Set([\n\t\"version\",\n\t\"mode\",\n\t\"proxy\",\n\t\"fallbackToDirect\",\n\t\"bypass\",\n]);\n\nconst PROXY_ENDPOINT_KEYS: ReadonlySet<string> = new Set([\"url\", \"username\", \"password\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertOnlyKeys(value: Record<string, unknown>, allowed: ReadonlySet<string>, label: string): void {\n\tfor (const key of Object.keys(value)) {\n\t\tif (!allowed.has(key)) throw new Error(`${label} has unknown key \"${key}\"`);\n\t}\n}\n\nfunction parseProxyEndpointV1(value: unknown): ProxyEndpointV1 {\n\tif (!isRecord(value)) throw new Error(\"network.proxy must be an object\");\n\tassertOnlyKeys(value, PROXY_ENDPOINT_KEYS, \"network.proxy\");\n\n\tconst url = value.url;\n\tif (typeof url !== \"string\" || url.trim() === \"\") {\n\t\tthrow new Error(\"network.proxy.url must be a non-empty string\");\n\t}\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new Error(`network.proxy.url must be an absolute http:// or https:// URL: ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n\t\tthrow new Error(`network.proxy.url must use http:// or https:// (P1 has no SOCKS5): ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.hostname === \"\") {\n\t\tthrow new Error(`network.proxy.url must include a host: ${JSON.stringify(url)}`);\n\t}\n\tif ((parsed.pathname !== \"\" && parsed.pathname !== \"/\") || parsed.search !== \"\" || parsed.hash !== \"\") {\n\t\tthrow new Error(`network.proxy.url must not include a path, query, or hash: ${JSON.stringify(url)}`);\n\t}\n\tif (parsed.username !== \"\" || parsed.password !== \"\") {\n\t\tthrow new Error(\n\t\t\t`network.proxy.url must not embed credentials; use network.proxy.username/password instead: ${JSON.stringify(url)}`,\n\t\t);\n\t}\n\n\tconst username = value.username;\n\tif (username !== undefined && typeof username !== \"string\") {\n\t\tthrow new Error(\"network.proxy.username must be a string when present\");\n\t}\n\tconst password = value.password;\n\tif (password !== undefined && typeof password !== \"string\") {\n\t\tthrow new Error(\"network.proxy.password must be a string when present\");\n\t}\n\treturn {\n\t\turl,\n\t\t...(username === undefined ? {} : { username }),\n\t\t...(password === undefined ? {} : { password }),\n\t};\n}\n\n/**\n * Strict parser for the P1 route config (design §7.1): every field is\n * type-checked, unknown keys are rejected, and `mode: \"proxy\"` requires a\n * proxy endpoint. Throws with a field-scoped message — callers must surface\n * the error (config errors never silently downgrade to direct).\n */\nexport function parseNetworkRouteConfigV1(value: unknown): NetworkRouteConfigV1 {\n\tif (!isRecord(value)) throw new Error(\"network config must be an object\");\n\tassertOnlyKeys(value, NETWORK_ROUTE_CONFIG_KEYS, \"network config\");\n\n\tif (value.version !== 1) throw new Error(`network.version must be 1: ${String(value.version)}`);\n\n\tconst mode = value.mode;\n\tif (mode !== \"direct\" && mode !== \"proxy\") {\n\t\tthrow new Error(`network.mode must be \"direct\" or \"proxy\": ${String(mode)}`);\n\t}\n\n\tconst fallbackToDirect = value.fallbackToDirect;\n\tif (fallbackToDirect !== undefined && typeof fallbackToDirect !== \"boolean\") {\n\t\tthrow new Error(\"network.fallbackToDirect must be a boolean when present\");\n\t}\n\n\tlet bypass: readonly string[] | undefined;\n\tif (value.bypass !== undefined) {\n\t\tif (!Array.isArray(value.bypass)) throw new Error(\"network.bypass must be an array of strings\");\n\t\tbypass = value.bypass.map((entry, index) => {\n\t\t\tif (typeof entry !== \"string\" || entry.trim() === \"\") {\n\t\t\t\tthrow new Error(`network.bypass[${index}] must be a non-empty string`);\n\t\t\t}\n\t\t\treturn entry;\n\t\t});\n\t}\n\n\tlet proxy: ProxyEndpointV1 | undefined;\n\tif (value.proxy !== undefined) {\n\t\tproxy = parseProxyEndpointV1(value.proxy);\n\t}\n\tif (mode === \"proxy\" && proxy === undefined) {\n\t\tthrow new Error('network mode \"proxy\" requires network.proxy.url');\n\t}\n\n\treturn {\n\t\tversion: 1,\n\t\tmode,\n\t\t...(proxy === undefined ? {} : { proxy }),\n\t\t...(fallbackToDirect === undefined ? {} : { fallbackToDirect }),\n\t\t...(bypass === undefined ? {} : { bypass }),\n\t};\n}\n\n/** Lowercase and strip one trailing dot so `Example.COM.` matches `example.com`. */\nfunction normalizeHostEntry(entry: string): string {\n\tconst lowered = entry.toLowerCase();\n\treturn lowered.endsWith(\".\") ? lowered.slice(0, -1) : lowered;\n}\n\n/**\n * Bypass match (design §7.1): exact host, `*.suffix` subdomain wildcard, or a\n * leading dot as an exact equivalent of `*.`. IP literals participate as exact\n * strings only — P1 has no CIDR.\n */\nfunction matchesBypassEntry(pattern: string, host: string): boolean {\n\tconst normalized = normalizeHostEntry(pattern);\n\tif (normalized === \"\") return false;\n\tif (normalized.startsWith(\"*.\")) {\n\t\tconst suffix = normalized.slice(2);\n\t\treturn suffix !== \"\" && host.endsWith(`.${suffix}`);\n\t}\n\tif (normalized.startsWith(\".\")) {\n\t\tconst suffix = normalized.slice(1);\n\t\treturn suffix !== \"\" && host.endsWith(`.${suffix}`);\n\t}\n\treturn normalized === host;\n}\n\n/**\n * Resolve the egress for one target host (design §7.1): bypass wins over the\n * proxy mode; proxy mode returns the configured endpoint. Never rejects\n * loopback/private targets and never logs — consumers own those decisions.\n */\nexport function resolveNetworkRouteV1(config: NetworkRouteConfigV1, host: string): NetworkRouteResolutionV1 {\n\tconst normalizedHost = normalizeHostEntry(host);\n\tif (config.mode === \"proxy\" && config.proxy !== undefined) {\n\t\tconst bypassed = (config.bypass ?? []).some((pattern) => matchesBypassEntry(pattern, normalizedHost));\n\t\tif (bypassed) return { mode: \"direct\", reason: \"bypass\" };\n\t\treturn { mode: \"proxy\", proxy: config.proxy, reason: \"mode\" };\n\t}\n\treturn { mode: \"direct\", reason: \"mode\" };\n}\n\nconst firstNonEmpty = (values: Array<string | undefined>): string | undefined => {\n\tfor (const value of values) {\n\t\tif (value !== undefined && value.trim() !== \"\") return value;\n\t}\n\treturn undefined;\n};\n\n/**\n * Pure env parsing (design §7.1/§10): `HTTPS_PROXY` wins over `HTTP_PROXY`;\n * a proxy means `mode: \"proxy\"`; `NO_PROXY` entries (comma-separated) become\n * `bypass`; no proxy means `direct`. Reads only the argument — never\n * `process.env`. Throws on a malformed proxy URL (fail-closed, no downgrade).\n */\nexport function networkRouteConfigFromEnv(env: Record<string, string | undefined>): NetworkRouteConfigV1 {\n\tconst proxyUrl = firstNonEmpty([env.HTTPS_PROXY, env.HTTP_PROXY]);\n\tif (proxyUrl === undefined) return { version: 1, mode: \"direct\" };\n\tconst bypass = (env.NO_PROXY ?? \"\")\n\t\t.split(\",\")\n\t\t.map((entry) => entry.trim())\n\t\t.filter((entry) => entry !== \"\");\n\treturn parseNetworkRouteConfigV1({\n\t\tversion: 1,\n\t\tmode: \"proxy\",\n\t\tproxy: { url: proxyUrl },\n\t\t...(bypass.length === 0 ? {} : { bypass }),\n\t});\n}\n\n/**\n * Settings precedence (design §7.1/§10): a settings-provided route wins as-is —\n * an explicit `mode: \"direct\"` must not be flipped back to proxy by env vars.\n * Without settings the env fallback applies.\n */\nexport function mergeNetworkRouteConfig(\n\tsettings: NetworkRouteConfigV1 | undefined,\n\tenv: Record<string, string | undefined>,\n): NetworkRouteConfigV1 {\n\treturn settings === undefined ? networkRouteConfigFromEnv(env) : settings;\n}\n"]}
|
package/dist/observability.d.ts
CHANGED
|
@@ -199,6 +199,27 @@ export interface TraceSinkOptionsV1 {
|
|
|
199
199
|
* Default 393_216 (384 KiB).
|
|
200
200
|
*/
|
|
201
201
|
readonly maxSnapshotBytes?: number;
|
|
202
|
+
/**
|
|
203
|
+
* Whether `llm.request.data.payload` records the full provider payload
|
|
204
|
+
* snapshot. Default **false** (2026-10-18): the trace is a process record —
|
|
205
|
+
* turn/tool/lifecycle order, timings, token usage, errors — and the message
|
|
206
|
+
* bodies already live in the session log. A 41.5h run wrote 662MB of
|
|
207
|
+
* snapshots (1,975 requests × ~306KB) that duplicated the session file.
|
|
208
|
+
* Set true (CLI/SDK: `AGENT_FORGE_TRACE_FULL_PAYLOAD=1`) for forensics.
|
|
209
|
+
* Metadata (model, messageCount, toolNames, systemPromptChars) is always
|
|
210
|
+
* recorded, and error records are never affected by this switch.
|
|
211
|
+
*/
|
|
212
|
+
readonly includeProviderPayload?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Per-file size ceiling for the trace sink, in bytes. Once the file reaches
|
|
215
|
+
* it the collector stops appending and reports a sink failure (the session
|
|
216
|
+
* keeps running untraced). A file-count cap cannot bound disk: `sessions/`
|
|
217
|
+
* once held 91 trace files — far under the 500-file cap — one of them 694 MB,
|
|
218
|
+
* 96.9% of it `llm.request.payload` snapshots (2026-10-21 measurement).
|
|
219
|
+
* Default 268_435_456 (256 MiB). Exposed for tests and hosts that need a
|
|
220
|
+
* tighter ceiling.
|
|
221
|
+
*/
|
|
222
|
+
readonly maxFileBytes?: number;
|
|
202
223
|
/**
|
|
203
224
|
* OTLP/HTTP+JSON trace export (design §8). Omitted keeps the exporter
|
|
204
225
|
* absent: no transport, no buffering, file-sink behavior unchanged. The
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW,CAAC;AAEnE,2EAA2E;AAC3E,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACpD;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mCAAmC;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,WAAW,iCAAiC;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qCAAqC;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kCAAkC;IAClD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAED,oGAAoG;AACpG,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,uFAAuF;AACvF,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,6DAA6D;AAC7D,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,iFAAiF;AACjF,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtF;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,6BAA6B,GAAG,mBAAmB,CAAC;IAC9E,QAAQ,CAAC,MAAM,EAAE,sBAAsB,GAAG,mBAAmB,CAAC;IAC9D,QAAQ,CAAC,YAAY,EAAE,4BAA4B,GAAG,mBAAmB,CAAC;CAC1E;AAED,oEAAoE;AACpE,MAAM,WAAW,2BAA2B;IAC3C,qGAAqG;IACrG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GACpB,eAAe,GACf,WAAW,GACX,aAAa,GACb,cAAc,GACd,WAAW,GACX,WAAW,GACX,OAAO,GACP,UAAU,GACV,YAAY,CAAC;AAEhB;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,qIAUgB,CAAC;AAK5C,yDAAwD;AACxD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IACvC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,2FAA0F;AAC1F,MAAM,WAAW,kBAAkB;IAClC,gGAA8F;IAC9F,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IACnC,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KAC5F,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACxD,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C,8EAA8E;IAC9E,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAAC;IAClC,0EAA0E;IAC1E,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/D,yEAAyE;IACzE,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,oBAAoB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC5C;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/C;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,MAAM,GAAG,SAAS,CAAC;IACxC;;;;;;;OAOG;IACH,cAAc,CAAC,CAAC,MAAM,EAAE,2BAA2B,GAAG,SAAS,GAAG,IAAI,CAAC;CACvE;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC3C,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/D,oEAAmE;IACnE,eAAe,CAAC,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,iBAAiB,CAAC;CACrE;AAED,4GAA4G;AAC5G,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,mCAAmC,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,iCAAiC,GAAG,IAAI,CAAC;IAC7D,QAAQ,CAAC,WAAW,EAAE,SAAS,qCAAqC,EAAE,CAAC;IACvE,QAAQ,CAAC,MAAM,EAAE,kCAAkC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE;QACpB,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;QACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,MAAM,CAAC,EAAE,0BAA0B,GAAG,SAAS,2BAA2B,EAAE,CAAC;IACnF,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,4BAA4B,CAAC;IAC5D,UAAU,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,iBAAiB,CAAC;IACrE,KAAK,IAAI,2BAA2B,CAAC;IACrC,mBAAmB,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9G;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/D;;;;;;OAMG;IACH,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5C,OAAO,IAAI,IAAI,CAAC;CAChB","sourcesContent":["/**\n * Public contracts for the first-party observability plugin (event journal +\n * problem reports + trace sink). The plugin package\n * (`@agent-forge/plugin-observability`) is the implementation; this module is\n * the single authoring authority for its public types and the host-facing\n * trace adapter contract. The host re-exports the surface from its historical\n * `plugins/observability-types.ts` path so existing imports keep resolving.\n *\n * Contains types only, plus the `TRACE_KINDS_V1` value mirror with its\n * compile-time drift guards (CLI `--trace-kind` validation consumes the\n * value).\n */\n\nimport type { LoggerRecord, OutputArtifactRef } from \"./public-api.ts\";\n\nexport type ObservabilityLogLevel = \"info\" | \"warn\" | \"error\";\n\n/**\n * Output projection surface carried by the problem report's whole-document\n * projection. Authority moved from the host's `host/output-serializer.ts`\n * (D-075 S4 second batch); the host re-exports it from there.\n */\nexport type HostOutputSurfaceV1 = \"tui\" | \"cli-text\" | \"inspector\";\n\n/** One bounded-journal record derived from a delivered lifecycle event. */\nexport interface ObservabilityJournalEntryV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\t/** Session id extracted from the event data; null when the event has none. */\n\treadonly sessionId: string | null;\n\t/** Lifecycle event type, e.g. \"model.stream\" or \"tool.commit\". */\n\treadonly stage: string;\n\treadonly level: ObservabilityLogLevel;\n\t/** Event correlation id, used as the trace grouping key. */\n\treadonly traceId?: string;\n\treadonly summary: string;\n\t/** Validated lifecycle event data, retained verbatim for diagnosis. */\n\treadonly data?: unknown;\n}\n\nexport interface ObservabilityQueryFilterV1 {\n\treadonly sessionId?: string;\n\treadonly stage?: string;\n\treadonly level?: ObservabilityLogLevel;\n\treadonly traceId?: string;\n\t/** When set, returns the most recent `limit` matching entries in order. */\n\treadonly limit?: number;\n}\n\nexport interface ObservabilityTraceStepV1 {\n\treadonly entry: ObservabilityJournalEntryV1;\n\t/** Milliseconds since the previous step; null on the first step. */\n\treadonly durationMs: number | null;\n}\n\nexport interface ObservabilityTraceTimelineV1 {\n\treadonly traceId: string;\n\treadonly steps: readonly ObservabilityTraceStepV1[];\n}\n\nexport interface ObservabilityJournalStatsV1 {\n\treadonly size: number;\n\treadonly dropped: number;\n}\n\nexport interface ObservabilityProblemReportSessionV1 {\n\treadonly sessionId: string;\n\treadonly entryCount: number;\n\treadonly firstSequence: number | null;\n\treadonly lastSequence: number | null;\n}\n\n/** Full error envelope of the most recent error-level entry for the session. */\nexport interface ObservabilityProblemReportErrorV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\treadonly stage: string;\n\t/** Lifecycle phase when the event carries one (model.stream). */\n\treadonly phase?: string;\n\treadonly traceId: string | null;\n\treadonly code: string;\n\treadonly message: string;\n}\n\nexport interface ObservabilityProblemReportTailEntryV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\treadonly stage: string;\n\treadonly level: ObservabilityLogLevel;\n\treadonly traceId: string | null;\n\treadonly summary: string;\n\t/**\n\t * Payload rendered through the host output serializer redaction channel;\n\t * internal field keys are replaced at any depth before export.\n\t */\n\treadonly data?: string;\n}\n\nexport interface ObservabilityProblemReportCountsV1 {\n\treadonly byStage: Readonly<Record<string, number>>;\n\treadonly byLevel: Readonly<Record<string, number>>;\n}\n\n/** A metric the journal cannot currently source; the reason names the missing event granularity. */\nexport interface MetricsNotSampledV1 {\n\treadonly status: \"not_sampled\";\n\treadonly reason: string;\n}\n\n/** Cancel-latency samples: delay from a cancel signal to the turn's terminal event. */\nexport interface MetricsCancelLatencySampledV1 {\n\treadonly status: \"sampled\";\n\treadonly count: number;\n\treadonly p50Ms: number | null;\n\treadonly p95Ms: number | null;\n}\n\n/** Token totals summed over usage-bearing journal events. */\nexport interface MetricsTokensSampledV1 {\n\treadonly status: \"sampled\";\n\treadonly totalTokens: number;\n}\n\n/** Memory recall hit rate over `memory_recall` tool executions in the window. */\nexport interface MetricsMemoryRecallSampledV1 {\n\treadonly status: \"sampled\";\n\treadonly calls: number;\n\treadonly hits: number;\n\treadonly hitRate: number;\n}\n\nexport interface MetricsToolErrorsV1 {\n\treadonly calls: number;\n\treadonly errors: number;\n\t/** `null` when no tool executions occurred in the window. */\n\treadonly errorRate: number | null;\n\t/** Errors per tool name, descending by count then ascending by name. */\n\treadonly topErrors: readonly { readonly toolName: string; readonly errors: number }[];\n}\n\nexport interface MetricsTurnsV1 {\n\treadonly count: number;\n\treadonly successCount: number;\n\t/** `null` when no turns occurred in the window. */\n\treadonly successRate: number | null;\n\treadonly p50DurationMs: number | null;\n\treadonly p95DurationMs: number | null;\n}\n\n/** Window metadata: which turns were aggregated and their time span. */\nexport interface MetricsWindowV1 {\n\t/** Requested turn bound; `null` when the whole journal was aggregated. */\n\treadonly windowTurns: number | null;\n\treadonly sampledTurns: number;\n\treadonly firstAt: number | null;\n\treadonly lastAt: number | null;\n}\n\n/**\n * Deterministic product metrics aggregated read-only from the journal ring.\n * Metrics the journal cannot source are reported as `not_sampled` with the\n * reason instead of being fabricated.\n */\nexport interface MetricsSnapshotV1 {\n\treadonly version: 1;\n\treadonly window: MetricsWindowV1;\n\treadonly turns: MetricsTurnsV1;\n\treadonly tools: MetricsToolErrorsV1;\n\treadonly cancelLatencyMs: MetricsCancelLatencySampledV1 | MetricsNotSampledV1;\n\treadonly tokens: MetricsTokensSampledV1 | MetricsNotSampledV1;\n\treadonly memoryRecall: MetricsMemoryRecallSampledV1 | MetricsNotSampledV1;\n}\n\n/** Aggregate options for {@link ObservabilityPlugin.getMetrics}. */\nexport interface ObservabilityMetricsOptions {\n\t/** Aggregate only the most recent `windowTurns` correlationId groups; omit for the whole journal. */\n\treadonly windowTurns?: number;\n}\n\n/**\n * Trace record kinds for `agent-forge/trace.v1`\n * (design: docs/design/会话轨迹与日志设计.md §4.2).\n */\nexport type TraceKindV1 =\n\t| \"session.start\"\n\t| \"turn.span\"\n\t| \"llm.request\"\n\t| \"llm.response\"\n\t| \"tool.span\"\n\t| \"lifecycle\"\n\t| \"error\"\n\t| \"decision\"\n\t| \"plugin.log\";\n\n/**\n * Runtime mirror of `TraceKindV1` for value-level consumers (CLI\n * `--trace-kind` validation), kept beside the union so the two compile-time\n * drift guards fail the build when they diverge in either direction:\n * - the `satisfies` below rejects a list entry the union no longer has;\n * - `_TRACE_KINDS_EXHAUSTIVE_CHECK` rejects a union member missing from the\n * list (`never` is not assignable from `true`).\n */\nexport const TRACE_KINDS_V1 = [\n\t\"session.start\",\n\t\"turn.span\",\n\t\"llm.request\",\n\t\"llm.response\",\n\t\"tool.span\",\n\t\"lifecycle\",\n\t\"error\",\n\t\"decision\",\n\t\"plugin.log\",\n] as const satisfies readonly TraceKindV1[];\n\ntype TraceKindListV1 = (typeof TRACE_KINDS_V1)[number];\nconst _TRACE_KINDS_EXHAUSTIVE_CHECK: TraceKindV1 extends TraceKindListV1 ? true : never = true;\n\n/** One append-only JSONL trace record (design §4.2). */\nexport interface TraceRecordV1 {\n\treadonly v: 1;\n\treadonly schema: \"agent-forge/trace.v1\";\n\t/** Monotonic sequence within one trace file, starting at 1. */\n\treadonly seq: number;\n\t/** Host timestamp (epoch ms). */\n\treadonly t: number;\n\t/** Duration of a closed span (ms). */\n\treadonly dur?: number;\n\treadonly kind: TraceKindV1;\n\t/** Turn/request correlation id, shared with lifecycle events and logs. */\n\treadonly traceId?: string;\n\treadonly level?: ObservabilityLogLevel;\n\t/** Kind-specific bounded data. */\n\treadonly data?: unknown;\n}\n\n/** Bounds for trace payload snapshots (design §4.3); each field defaults when omitted. */\nexport interface TraceSinkOptionsV1 {\n\t/** Strings longer than this truncate with a `…[truncated N chars]` suffix. Default 16_000. */\n\treadonly maxStringChars?: number;\n\t/**\n\t * Serialized snapshot budget in bytes, enforced largest-string-first inside\n\t * `llm.request.data.payload`. Strictly below the 512 KiB per-record budget.\n\t * Default 393_216 (384 KiB).\n\t */\n\treadonly maxSnapshotBytes?: number;\n\t/**\n\t * OTLP/HTTP+JSON trace export (design §8). Omitted keeps the exporter\n\t * absent: no transport, no buffering, file-sink behavior unchanged. The\n\t * endpoint is the OTLP base URL (e.g. `http://localhost:4318`); the\n\t * `/v1/traces` signal path is appended unless already present.\n\t */\n\treadonly otlp?: OtlpExportOptionsV1;\n}\n\n/** OTLP/HTTP+JSON exporter options; all durations/bounds are deterministic inputs. */\nexport interface OtlpExportOptionsV1 {\n\t/** OTLP base URL; `/v1/traces` is appended unless already present. */\n\treadonly endpoint: string;\n\t/**\n\t * Transport injection for deterministic tests and custom hosts (proxy,\n\t * in-process collector); defaults to `globalThis.fetch`. Only the fields\n\t * below are consumed by the plugin.\n\t */\n\treadonly fetchImpl?: (\n\t\turl: string,\n\t\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n\t) => Promise<{ ok: boolean; status: number }>;\n\t/** Per-flush HTTP timeout in ms. Default 5_000. */\n\treadonly timeoutMs?: number;\n\t/** Buffered-span count that triggers an early flush. Default 64. */\n\treadonly flushThreshold?: number;\n}\n\n/**\n * Telemetry export seam (design §8): the single attachment point for trace\n * exporters (first OTLP/HTTP+JSON; future Prometheus-style pull surfaces hook\n * here instead of growing bespoke taps). Hosts inject sinks through\n * `ObservabilityTraceConfig.exportSinks`; the plugin never reaches into host\n * internals and never lets a sink break event delivery.\n */\nexport interface ObservabilityExportSinkV1 {\n\t/** Called synchronously for every finalized trace record. Must not throw. */\n\treadonly onTraceRecord: (record: TraceRecordV1) => void;\n\t/** Best-effort flush; resolves after the batch is delivered or dropped. */\n\treadonly flush: (reason: string) => Promise<void>;\n}\n\n/**\n * Host-injected adapter for the trace sink (design §4.4). The host closure\n * owns session-path resolution, provider payload capture, and failure\n * reporting; the plugin never reaches into host internals.\n */\nexport interface ObservabilityHostAdapterV1 {\n\t/** Trace file path for the current session, or `null` when tracing is off. */\n\tgetTraceFilePath(): string | null;\n\t/** Host push of the finalized provider payload (sdk `onPayload` tail). */\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/** Trace write-failure channel; the host forwards to the process log. */\n\tonSinkFailure(error: unknown): void;\n\t/**\n\t * Correlation id of the turn currently in flight, or `undefined` outside a\n\t * turn. Omitted keeps the phase-1 behavior: `llm.request` and `plugin.log`\n\t * records carry no traceId.\n\t */\n\tgetTurnCorrelationId?(): string | undefined;\n\t/**\n\t * Session-header fact: the parent agent session id recorded at session\n\t * creation (`SessionHeader.parentAgentSession`, session-manager.ts).\n\t * Omitted — or returning `undefined` when the header has no such field —\n\t * keeps the previous behavior: the `session.start` record carries no\n\t * `parentSessionId`.\n\t */\n\tgetParentAgentSessionId?(): string | undefined;\n\t/**\n\t * Session-header fact: the parent-turn correlation id that created this\n\t * session (`SessionHeader.parentTraceId`, session-manager.ts; frozen at\n\t * creation). Omitted — or returning `undefined` — keeps the previous\n\t * behavior: the `session.start` record carries no `parentTraceId`.\n\t */\n\tgetParentTraceId?(): string | undefined;\n\t/**\n\t * Plugin-to-host facade registration (D-075 S4 second batch). The plugin\n\t * entry calls it once after creating the plugin instance so the host's\n\t * assembly refs (provider payload capture, plugin.log mirror, /metrics\n\t * source) keep their embedded-era semantics; calling it again with\n\t * `undefined` on teardown clears them. Omitted on hosts that consume the\n\t * facade through another channel — the entry must probe before calling.\n\t */\n\tregisterFacade?(facade: ObservabilityPluginFacadeV1 | undefined): void;\n}\n\n/**\n * The narrow plugin-facing face the host consumes through\n * {@link ObservabilityHostAdapterV1.registerFacade}. The plugin instance is\n * structurally assignable to it.\n */\nexport interface ObservabilityPluginFacadeV1 {\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/** Optional: present since the plugin.log mirror (design §7.2). */\n\tmirrorPluginLog?(record: LoggerRecord): void;\n\tgetMetrics(options?: ObservabilityMetricsOptions): MetricsSnapshotV1;\n}\n\n/** Deterministic problem report; `reportId` is FNV-1a-32 hex over the canonical JSON of the report body. */\nexport interface ProblemReportV1 {\n\treadonly version: 1;\n\treadonly reportId: string;\n\treadonly createdAt: number;\n\treadonly reason: string;\n\treadonly session: ObservabilityProblemReportSessionV1;\n\treadonly lastError: ObservabilityProblemReportErrorV1 | null;\n\treadonly journalTail: readonly ObservabilityProblemReportTailEntryV1[];\n\treadonly counts: ObservabilityProblemReportCountsV1;\n\treadonly dropped: number;\n\treadonly redactionApplied: boolean;\n\t/** Whole-report projection rendered by the host output serializer. */\n\treadonly projection: {\n\t\treadonly surface: HostOutputSurfaceV1;\n\t\treadonly text: string;\n\t};\n\t/** Present only when the host declared the `output-artifacts` feature. */\n\treadonly artifact?: OutputArtifactRef;\n}\n\n/**\n * The observability plugin's public behavior face (journal read side, trace\n * explanation, deterministic metrics, problem-report export). The plugin\n * package returns this shape from its factory; hosts consume it through\n * {@link ObservabilityPluginFacadeV1} or their own references.\n */\nexport interface ObservabilityPlugin {\n\treadonly id: string;\n\tquery(filter?: ObservabilityQueryFilterV1): readonly ObservabilityJournalEntryV1[];\n\texplainTrace(traceId: string): ObservabilityTraceTimelineV1;\n\tgetMetrics(options?: ObservabilityMetricsOptions): MetricsSnapshotV1;\n\tstats(): ObservabilityJournalStatsV1;\n\texportProblemReport(input: { readonly sessionId: string; readonly reason: string }): Promise<ProblemReportV1>;\n\t/**\n\t * Receives the finalized provider payload from the host adapter and emits\n\t * one `llm.request` trace record with a bounded redacted snapshot (design\n\t * §4.3). No-op when no trace adapter was injected.\n\t */\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/**\n\t * Receives one plugin LoggerAPI record forwarded by the host runtime sink\n\t * (`CapabilityRuntimeOptions.onLogRecord`) and appends a `plugin.log` trace\n\t * record (design §4.2/§7.2). No-op when no trace adapter was injected.\n\t * Must never call `api.logger`: the host forwards logger output here, so\n\t * logging from inside would recurse.\n\t */\n\tmirrorPluginLog(record: LoggerRecord): void;\n\tdispose(): void;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Public contracts for the first-party observability plugin (event journal +\n * problem reports + trace sink). The plugin package\n * (`@agent-forge/plugin-observability`) is the implementation; this module is\n * the single authoring authority for its public types and the host-facing\n * trace adapter contract. The host re-exports the surface from its historical\n * `plugins/observability-types.ts` path so existing imports keep resolving.\n *\n * Contains types only, plus the `TRACE_KINDS_V1` value mirror with its\n * compile-time drift guards (CLI `--trace-kind` validation consumes the\n * value).\n */\n\nimport type { LoggerRecord, OutputArtifactRef } from \"./public-api.ts\";\n\nexport type ObservabilityLogLevel = \"info\" | \"warn\" | \"error\";\n\n/**\n * Output projection surface carried by the problem report's whole-document\n * projection. Authority moved from the host's `host/output-serializer.ts`\n * (D-075 S4 second batch); the host re-exports it from there.\n */\nexport type HostOutputSurfaceV1 = \"tui\" | \"cli-text\" | \"inspector\";\n\n/** One bounded-journal record derived from a delivered lifecycle event. */\nexport interface ObservabilityJournalEntryV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\t/** Session id extracted from the event data; null when the event has none. */\n\treadonly sessionId: string | null;\n\t/** Lifecycle event type, e.g. \"model.stream\" or \"tool.commit\". */\n\treadonly stage: string;\n\treadonly level: ObservabilityLogLevel;\n\t/** Event correlation id, used as the trace grouping key. */\n\treadonly traceId?: string;\n\treadonly summary: string;\n\t/** Validated lifecycle event data, retained verbatim for diagnosis. */\n\treadonly data?: unknown;\n}\n\nexport interface ObservabilityQueryFilterV1 {\n\treadonly sessionId?: string;\n\treadonly stage?: string;\n\treadonly level?: ObservabilityLogLevel;\n\treadonly traceId?: string;\n\t/** When set, returns the most recent `limit` matching entries in order. */\n\treadonly limit?: number;\n}\n\nexport interface ObservabilityTraceStepV1 {\n\treadonly entry: ObservabilityJournalEntryV1;\n\t/** Milliseconds since the previous step; null on the first step. */\n\treadonly durationMs: number | null;\n}\n\nexport interface ObservabilityTraceTimelineV1 {\n\treadonly traceId: string;\n\treadonly steps: readonly ObservabilityTraceStepV1[];\n}\n\nexport interface ObservabilityJournalStatsV1 {\n\treadonly size: number;\n\treadonly dropped: number;\n}\n\nexport interface ObservabilityProblemReportSessionV1 {\n\treadonly sessionId: string;\n\treadonly entryCount: number;\n\treadonly firstSequence: number | null;\n\treadonly lastSequence: number | null;\n}\n\n/** Full error envelope of the most recent error-level entry for the session. */\nexport interface ObservabilityProblemReportErrorV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\treadonly stage: string;\n\t/** Lifecycle phase when the event carries one (model.stream). */\n\treadonly phase?: string;\n\treadonly traceId: string | null;\n\treadonly code: string;\n\treadonly message: string;\n}\n\nexport interface ObservabilityProblemReportTailEntryV1 {\n\treadonly sequence: number;\n\treadonly at: number;\n\treadonly stage: string;\n\treadonly level: ObservabilityLogLevel;\n\treadonly traceId: string | null;\n\treadonly summary: string;\n\t/**\n\t * Payload rendered through the host output serializer redaction channel;\n\t * internal field keys are replaced at any depth before export.\n\t */\n\treadonly data?: string;\n}\n\nexport interface ObservabilityProblemReportCountsV1 {\n\treadonly byStage: Readonly<Record<string, number>>;\n\treadonly byLevel: Readonly<Record<string, number>>;\n}\n\n/** A metric the journal cannot currently source; the reason names the missing event granularity. */\nexport interface MetricsNotSampledV1 {\n\treadonly status: \"not_sampled\";\n\treadonly reason: string;\n}\n\n/** Cancel-latency samples: delay from a cancel signal to the turn's terminal event. */\nexport interface MetricsCancelLatencySampledV1 {\n\treadonly status: \"sampled\";\n\treadonly count: number;\n\treadonly p50Ms: number | null;\n\treadonly p95Ms: number | null;\n}\n\n/** Token totals summed over usage-bearing journal events. */\nexport interface MetricsTokensSampledV1 {\n\treadonly status: \"sampled\";\n\treadonly totalTokens: number;\n}\n\n/** Memory recall hit rate over `memory_recall` tool executions in the window. */\nexport interface MetricsMemoryRecallSampledV1 {\n\treadonly status: \"sampled\";\n\treadonly calls: number;\n\treadonly hits: number;\n\treadonly hitRate: number;\n}\n\nexport interface MetricsToolErrorsV1 {\n\treadonly calls: number;\n\treadonly errors: number;\n\t/** `null` when no tool executions occurred in the window. */\n\treadonly errorRate: number | null;\n\t/** Errors per tool name, descending by count then ascending by name. */\n\treadonly topErrors: readonly { readonly toolName: string; readonly errors: number }[];\n}\n\nexport interface MetricsTurnsV1 {\n\treadonly count: number;\n\treadonly successCount: number;\n\t/** `null` when no turns occurred in the window. */\n\treadonly successRate: number | null;\n\treadonly p50DurationMs: number | null;\n\treadonly p95DurationMs: number | null;\n}\n\n/** Window metadata: which turns were aggregated and their time span. */\nexport interface MetricsWindowV1 {\n\t/** Requested turn bound; `null` when the whole journal was aggregated. */\n\treadonly windowTurns: number | null;\n\treadonly sampledTurns: number;\n\treadonly firstAt: number | null;\n\treadonly lastAt: number | null;\n}\n\n/**\n * Deterministic product metrics aggregated read-only from the journal ring.\n * Metrics the journal cannot source are reported as `not_sampled` with the\n * reason instead of being fabricated.\n */\nexport interface MetricsSnapshotV1 {\n\treadonly version: 1;\n\treadonly window: MetricsWindowV1;\n\treadonly turns: MetricsTurnsV1;\n\treadonly tools: MetricsToolErrorsV1;\n\treadonly cancelLatencyMs: MetricsCancelLatencySampledV1 | MetricsNotSampledV1;\n\treadonly tokens: MetricsTokensSampledV1 | MetricsNotSampledV1;\n\treadonly memoryRecall: MetricsMemoryRecallSampledV1 | MetricsNotSampledV1;\n}\n\n/** Aggregate options for {@link ObservabilityPlugin.getMetrics}. */\nexport interface ObservabilityMetricsOptions {\n\t/** Aggregate only the most recent `windowTurns` correlationId groups; omit for the whole journal. */\n\treadonly windowTurns?: number;\n}\n\n/**\n * Trace record kinds for `agent-forge/trace.v1`\n * (design: docs/design/会话轨迹与日志设计.md §4.2).\n */\nexport type TraceKindV1 =\n\t| \"session.start\"\n\t| \"turn.span\"\n\t| \"llm.request\"\n\t| \"llm.response\"\n\t| \"tool.span\"\n\t| \"lifecycle\"\n\t| \"error\"\n\t| \"decision\"\n\t| \"plugin.log\";\n\n/**\n * Runtime mirror of `TraceKindV1` for value-level consumers (CLI\n * `--trace-kind` validation), kept beside the union so the two compile-time\n * drift guards fail the build when they diverge in either direction:\n * - the `satisfies` below rejects a list entry the union no longer has;\n * - `_TRACE_KINDS_EXHAUSTIVE_CHECK` rejects a union member missing from the\n * list (`never` is not assignable from `true`).\n */\nexport const TRACE_KINDS_V1 = [\n\t\"session.start\",\n\t\"turn.span\",\n\t\"llm.request\",\n\t\"llm.response\",\n\t\"tool.span\",\n\t\"lifecycle\",\n\t\"error\",\n\t\"decision\",\n\t\"plugin.log\",\n] as const satisfies readonly TraceKindV1[];\n\ntype TraceKindListV1 = (typeof TRACE_KINDS_V1)[number];\nconst _TRACE_KINDS_EXHAUSTIVE_CHECK: TraceKindV1 extends TraceKindListV1 ? true : never = true;\n\n/** One append-only JSONL trace record (design §4.2). */\nexport interface TraceRecordV1 {\n\treadonly v: 1;\n\treadonly schema: \"agent-forge/trace.v1\";\n\t/** Monotonic sequence within one trace file, starting at 1. */\n\treadonly seq: number;\n\t/** Host timestamp (epoch ms). */\n\treadonly t: number;\n\t/** Duration of a closed span (ms). */\n\treadonly dur?: number;\n\treadonly kind: TraceKindV1;\n\t/** Turn/request correlation id, shared with lifecycle events and logs. */\n\treadonly traceId?: string;\n\treadonly level?: ObservabilityLogLevel;\n\t/** Kind-specific bounded data. */\n\treadonly data?: unknown;\n}\n\n/** Bounds for trace payload snapshots (design §4.3); each field defaults when omitted. */\nexport interface TraceSinkOptionsV1 {\n\t/** Strings longer than this truncate with a `…[truncated N chars]` suffix. Default 16_000. */\n\treadonly maxStringChars?: number;\n\t/**\n\t * Serialized snapshot budget in bytes, enforced largest-string-first inside\n\t * `llm.request.data.payload`. Strictly below the 512 KiB per-record budget.\n\t * Default 393_216 (384 KiB).\n\t */\n\treadonly maxSnapshotBytes?: number;\n\t/**\n\t * Whether `llm.request.data.payload` records the full provider payload\n\t * snapshot. Default **false** (2026-10-18): the trace is a process record —\n\t * turn/tool/lifecycle order, timings, token usage, errors — and the message\n\t * bodies already live in the session log. A 41.5h run wrote 662MB of\n\t * snapshots (1,975 requests × ~306KB) that duplicated the session file.\n\t * Set true (CLI/SDK: `AGENT_FORGE_TRACE_FULL_PAYLOAD=1`) for forensics.\n\t * Metadata (model, messageCount, toolNames, systemPromptChars) is always\n\t * recorded, and error records are never affected by this switch.\n\t */\n\treadonly includeProviderPayload?: boolean;\n\t/**\n\t * Per-file size ceiling for the trace sink, in bytes. Once the file reaches\n\t * it the collector stops appending and reports a sink failure (the session\n\t * keeps running untraced). A file-count cap cannot bound disk: `sessions/`\n\t * once held 91 trace files — far under the 500-file cap — one of them 694 MB,\n\t * 96.9% of it `llm.request.payload` snapshots (2026-10-21 measurement).\n\t * Default 268_435_456 (256 MiB). Exposed for tests and hosts that need a\n\t * tighter ceiling.\n\t */\n\treadonly maxFileBytes?: number;\n\t/**\n\t * OTLP/HTTP+JSON trace export (design §8). Omitted keeps the exporter\n\t * absent: no transport, no buffering, file-sink behavior unchanged. The\n\t * endpoint is the OTLP base URL (e.g. `http://localhost:4318`); the\n\t * `/v1/traces` signal path is appended unless already present.\n\t */\n\treadonly otlp?: OtlpExportOptionsV1;\n}\n\n/** OTLP/HTTP+JSON exporter options; all durations/bounds are deterministic inputs. */\nexport interface OtlpExportOptionsV1 {\n\t/** OTLP base URL; `/v1/traces` is appended unless already present. */\n\treadonly endpoint: string;\n\t/**\n\t * Transport injection for deterministic tests and custom hosts (proxy,\n\t * in-process collector); defaults to `globalThis.fetch`. Only the fields\n\t * below are consumed by the plugin.\n\t */\n\treadonly fetchImpl?: (\n\t\turl: string,\n\t\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n\t) => Promise<{ ok: boolean; status: number }>;\n\t/** Per-flush HTTP timeout in ms. Default 5_000. */\n\treadonly timeoutMs?: number;\n\t/** Buffered-span count that triggers an early flush. Default 64. */\n\treadonly flushThreshold?: number;\n}\n\n/**\n * Telemetry export seam (design §8): the single attachment point for trace\n * exporters (first OTLP/HTTP+JSON; future Prometheus-style pull surfaces hook\n * here instead of growing bespoke taps). Hosts inject sinks through\n * `ObservabilityTraceConfig.exportSinks`; the plugin never reaches into host\n * internals and never lets a sink break event delivery.\n */\nexport interface ObservabilityExportSinkV1 {\n\t/** Called synchronously for every finalized trace record. Must not throw. */\n\treadonly onTraceRecord: (record: TraceRecordV1) => void;\n\t/** Best-effort flush; resolves after the batch is delivered or dropped. */\n\treadonly flush: (reason: string) => Promise<void>;\n}\n\n/**\n * Host-injected adapter for the trace sink (design §4.4). The host closure\n * owns session-path resolution, provider payload capture, and failure\n * reporting; the plugin never reaches into host internals.\n */\nexport interface ObservabilityHostAdapterV1 {\n\t/** Trace file path for the current session, or `null` when tracing is off. */\n\tgetTraceFilePath(): string | null;\n\t/** Host push of the finalized provider payload (sdk `onPayload` tail). */\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/** Trace write-failure channel; the host forwards to the process log. */\n\tonSinkFailure(error: unknown): void;\n\t/**\n\t * Correlation id of the turn currently in flight, or `undefined` outside a\n\t * turn. Omitted keeps the phase-1 behavior: `llm.request` and `plugin.log`\n\t * records carry no traceId.\n\t */\n\tgetTurnCorrelationId?(): string | undefined;\n\t/**\n\t * Session-header fact: the parent agent session id recorded at session\n\t * creation (`SessionHeader.parentAgentSession`, session-manager.ts).\n\t * Omitted — or returning `undefined` when the header has no such field —\n\t * keeps the previous behavior: the `session.start` record carries no\n\t * `parentSessionId`.\n\t */\n\tgetParentAgentSessionId?(): string | undefined;\n\t/**\n\t * Session-header fact: the parent-turn correlation id that created this\n\t * session (`SessionHeader.parentTraceId`, session-manager.ts; frozen at\n\t * creation). Omitted — or returning `undefined` — keeps the previous\n\t * behavior: the `session.start` record carries no `parentTraceId`.\n\t */\n\tgetParentTraceId?(): string | undefined;\n\t/**\n\t * Plugin-to-host facade registration (D-075 S4 second batch). The plugin\n\t * entry calls it once after creating the plugin instance so the host's\n\t * assembly refs (provider payload capture, plugin.log mirror, /metrics\n\t * source) keep their embedded-era semantics; calling it again with\n\t * `undefined` on teardown clears them. Omitted on hosts that consume the\n\t * facade through another channel — the entry must probe before calling.\n\t */\n\tregisterFacade?(facade: ObservabilityPluginFacadeV1 | undefined): void;\n}\n\n/**\n * The narrow plugin-facing face the host consumes through\n * {@link ObservabilityHostAdapterV1.registerFacade}. The plugin instance is\n * structurally assignable to it.\n */\nexport interface ObservabilityPluginFacadeV1 {\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/** Optional: present since the plugin.log mirror (design §7.2). */\n\tmirrorPluginLog?(record: LoggerRecord): void;\n\tgetMetrics(options?: ObservabilityMetricsOptions): MetricsSnapshotV1;\n}\n\n/** Deterministic problem report; `reportId` is FNV-1a-32 hex over the canonical JSON of the report body. */\nexport interface ProblemReportV1 {\n\treadonly version: 1;\n\treadonly reportId: string;\n\treadonly createdAt: number;\n\treadonly reason: string;\n\treadonly session: ObservabilityProblemReportSessionV1;\n\treadonly lastError: ObservabilityProblemReportErrorV1 | null;\n\treadonly journalTail: readonly ObservabilityProblemReportTailEntryV1[];\n\treadonly counts: ObservabilityProblemReportCountsV1;\n\treadonly dropped: number;\n\treadonly redactionApplied: boolean;\n\t/** Whole-report projection rendered by the host output serializer. */\n\treadonly projection: {\n\t\treadonly surface: HostOutputSurfaceV1;\n\t\treadonly text: string;\n\t};\n\t/** Present only when the host declared the `output-artifacts` feature. */\n\treadonly artifact?: OutputArtifactRef;\n}\n\n/**\n * The observability plugin's public behavior face (journal read side, trace\n * explanation, deterministic metrics, problem-report export). The plugin\n * package returns this shape from its factory; hosts consume it through\n * {@link ObservabilityPluginFacadeV1} or their own references.\n */\nexport interface ObservabilityPlugin {\n\treadonly id: string;\n\tquery(filter?: ObservabilityQueryFilterV1): readonly ObservabilityJournalEntryV1[];\n\texplainTrace(traceId: string): ObservabilityTraceTimelineV1;\n\tgetMetrics(options?: ObservabilityMetricsOptions): MetricsSnapshotV1;\n\tstats(): ObservabilityJournalStatsV1;\n\texportProblemReport(input: { readonly sessionId: string; readonly reason: string }): Promise<ProblemReportV1>;\n\t/**\n\t * Receives the finalized provider payload from the host adapter and emits\n\t * one `llm.request` trace record with a bounded redacted snapshot (design\n\t * §4.3). No-op when no trace adapter was injected.\n\t */\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\t/**\n\t * Receives one plugin LoggerAPI record forwarded by the host runtime sink\n\t * (`CapabilityRuntimeOptions.onLogRecord`) and appends a `plugin.log` trace\n\t * record (design §4.2/§7.2). No-op when no trace adapter was injected.\n\t * Must never call `api.logger`: the host forwards logger output here, so\n\t * logging from inside would recurse.\n\t */\n\tmirrorPluginLog(record: LoggerRecord): void;\n\tdispose(): void;\n}\n"]}
|