@ai-agent-forge/plugin-sdk 0.88.5 → 0.88.13
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/capability-manifest.d.ts.map +1 -1
- package/dist/capability-manifest.js +18 -0
- package/dist/capability-manifest.js.map +1 -1
- package/dist/durable.d.ts +9 -0
- package/dist/durable.d.ts.map +1 -1
- package/dist/durable.js.map +1 -1
- package/dist/observability.d.ts +1 -1
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js.map +1 -1
- package/dist/public-api.d.ts +18 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-manifest.d.ts","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAKX,cAAc,EACd,MAAM,iBAAiB,CAAC;AA+IzB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAe,GAAG,cAAc,CAkFzG","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"capability-manifest.d.ts","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAKX,cAAc,EACd,MAAM,iBAAiB,CAAC;AA4JzB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAe,GAAG,cAAc,CAyFzG","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\n/**\n * Manifest entries resolve via path.resolve(dirname(manifestPath), entry) in\n * the host loader, so a crafted entry could point outside the plugin\n * directory. Apply the install host's normalizedEntryName rule family\n * lexically: relative shapes only — no absolute path, drive letter,\n * backslash, \":\" or \"..\" segments. \"./\" prefixes and ordinary relative\n * segments stay allowed.\n */\nfunction isRelativeManifestEntry(entry: string): boolean {\n\tif (entry.trim() === \"\" || entry.includes(\"\\\\\") || entry.startsWith(\"/\") || entry.includes(\":\")) return false;\n\treturn !entry.split(\"/\").includes(\"..\");\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tassertPluginCapabilityId(id, \"id\", manifestPath);\n\tassertPluginCapabilityId(version, \"version\", manifestPath);\n\tif (!isRelativeManifestEntry(entry)) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin manifest entry must be a relative path without drive letters, backslashes, \":\" or \"..\" segments: ${manifestPath}`,\n\t\t);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
|
|
@@ -24,6 +24,19 @@ function isJsonConfigValue(value) {
|
|
|
24
24
|
return false;
|
|
25
25
|
return Object.values(value).every(isJsonConfigValue);
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Manifest entries resolve via path.resolve(dirname(manifestPath), entry) in
|
|
29
|
+
* the host loader, so a crafted entry could point outside the plugin
|
|
30
|
+
* directory. Apply the install host's normalizedEntryName rule family
|
|
31
|
+
* lexically: relative shapes only — no absolute path, drive letter,
|
|
32
|
+
* backslash, ":" or ".." segments. "./" prefixes and ordinary relative
|
|
33
|
+
* segments stay allowed.
|
|
34
|
+
*/
|
|
35
|
+
function isRelativeManifestEntry(entry) {
|
|
36
|
+
if (entry.trim() === "" || entry.includes("\\") || entry.startsWith("/") || entry.includes(":"))
|
|
37
|
+
return false;
|
|
38
|
+
return !entry.split("/").includes("..");
|
|
39
|
+
}
|
|
27
40
|
function assertPluginCapabilityId(value, field, manifestPath) {
|
|
28
41
|
if (typeof value !== "string" || !value.trim()) {
|
|
29
42
|
throw new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);
|
|
@@ -150,6 +163,11 @@ export function parseCapabilityPluginManifest(value, manifestPath = "<manifest>"
|
|
|
150
163
|
typeof entry !== "string") {
|
|
151
164
|
throw new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);
|
|
152
165
|
}
|
|
166
|
+
assertPluginCapabilityId(id, "id", manifestPath);
|
|
167
|
+
assertPluginCapabilityId(version, "version", manifestPath);
|
|
168
|
+
if (!isRelativeManifestEntry(entry)) {
|
|
169
|
+
throw new Error(`Capability plugin manifest entry must be a relative path without drive letters, backslashes, ":" or ".." segments: ${manifestPath}`);
|
|
170
|
+
}
|
|
153
171
|
if (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {
|
|
154
172
|
throw new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);
|
|
155
173
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability-manifest.js","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"capability-manifest.js","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\n/**\n * Manifest entries resolve via path.resolve(dirname(manifestPath), entry) in\n * the host loader, so a crafted entry could point outside the plugin\n * directory. Apply the install host's normalizedEntryName rule family\n * lexically: relative shapes only — no absolute path, drive letter,\n * backslash, \":\" or \"..\" segments. \"./\" prefixes and ordinary relative\n * segments stay allowed.\n */\nfunction isRelativeManifestEntry(entry: string): boolean {\n\tif (entry.trim() === \"\" || entry.includes(\"\\\\\") || entry.startsWith(\"/\") || entry.includes(\":\")) return false;\n\treturn !entry.split(\"/\").includes(\"..\");\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tassertPluginCapabilityId(id, \"id\", manifestPath);\n\tassertPluginCapabilityId(version, \"version\", manifestPath);\n\tif (!isRelativeManifestEntry(entry)) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin manifest entry must be a relative path without drive letters, backslashes, \":\" or \"..\" segments: ${manifestPath}`,\n\t\t);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
|
package/dist/durable.d.ts
CHANGED
|
@@ -89,6 +89,15 @@ export interface DurableServiceV1 {
|
|
|
89
89
|
loadArtifact(input: {
|
|
90
90
|
readonly artifactId: string;
|
|
91
91
|
}): DurableArtifactRecordV1 | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Records for one session, ordered by artifactId for stable output. Optional:
|
|
94
|
+
* backends without enumeration answer nothing here, and consumers surface an
|
|
95
|
+
* explicit "not implemented" instead of an empty list (App artifact panel is
|
|
96
|
+
* the first consumer). Read-only; never gated by the writer lease.
|
|
97
|
+
*/
|
|
98
|
+
listArtifacts?(input: {
|
|
99
|
+
readonly sessionId: string;
|
|
100
|
+
}): readonly DurableArtifactRecordV1[];
|
|
92
101
|
/** All session records, ordered by sessionId for stable output. */
|
|
93
102
|
listSessions(): readonly DurableSessionRecordV1[];
|
|
94
103
|
claimWriter(writerId: string): DurableWriterClaimV1;
|
package/dist/durable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable.d.ts","sourceRoot":"","sources":["../src/durable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Durable service contract types (7.4b) — the plugin-facing persistence\n * surface of the host's durable store.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S4 third batch, type-only\n * migration from the host's `src/durable/durable-service.ts`). The host keeps\n * the implementation (`createDurableService`, writer lease, backends) and its\n * historical module exports; these pure type definitions are the contract a\n * capability plugin programs against (e.g. the first-party subagent-delegate\n * plugin's scheduler persists terminal records through `results.store`).\n * No runtime behavior lives here — importing this module never pulls in\n * `node:fs`.\n */\n\nexport interface DurableSessionRecordV1 {\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableOperationRecordV1 {\n\treadonly operationId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableArtifactRecordV1 {\n\treadonly artifactId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableSnapshotV1 {\n\treadonly version: 1;\n\treadonly exportedAt: number;\n\treadonly sessions: readonly DurableSessionRecordV1[];\n\treadonly operations: readonly DurableOperationRecordV1[];\n\treadonly artifacts: readonly DurableArtifactRecordV1[];\n\treadonly writer: { readonly holder: string | null; readonly crashPending: string | null };\n}\n\nexport type DurableWriterClaimV1 = { readonly status: \"claimed\" } | { readonly status: \"held\"; readonly by: string };\n\nexport type DurableWriterRecoveryV1 =\n\t| { readonly status: \"recovered\"; readonly previousWriter?: string }\n\t| { readonly status: \"held\" };\n\nexport interface DurableReadinessV1 {\n\treadonly ready: boolean;\n\treadonly reason?: string;\n}\n\n/** Diagnostics from the startup log replay of a backend-backed service. */\nexport interface DurableReplayDiagnosticsV1 {\n\t/** Malformed log lines skipped while replaying. */\n\treadonly corruptedLines: number;\n\t/** True when the log existed but could not be read. */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableServiceV1 {\n\tpersistSession(input: {\n\t\treadonly writerId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableSessionRecordV1;\n\tloadSession(input: { readonly sessionId: string }): DurableSessionRecordV1 | undefined;\n\tpersistOperation(input: {\n\t\treadonly writerId: string;\n\t\treadonly operationId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableOperationRecordV1;\n\tloadOperation(input: { readonly operationId: string }): DurableOperationRecordV1 | undefined;\n\tpersistArtifact(input: {\n\t\treadonly writerId: string;\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableArtifactRecordV1;\n\tloadArtifact(input: { readonly artifactId: string }): DurableArtifactRecordV1 | undefined;\n\t/** All session records, ordered by sessionId for stable output. */\n\tlistSessions(): readonly DurableSessionRecordV1[];\n\tclaimWriter(writerId: string): DurableWriterClaimV1;\n\treleaseWriter(writerId: string): { readonly status: \"released\" };\n\trecoverWriter(writerId: string): DurableWriterRecoveryV1;\n\treadiness(): DurableReadinessV1;\n\texportState(): DurableSnapshotV1;\n\timportState(snapshot: unknown): void;\n\t/**\n\t * Diagnostics from the startup log replay of the backend (zeros/false\n\t * without a backend). Corrupted lines were skipped, not fatal.\n\t */\n\treplayDiagnostics(): DurableReplayDiagnosticsV1;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"durable.d.ts","sourceRoot":"","sources":["../src/durable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Durable service contract types (7.4b) — the plugin-facing persistence\n * surface of the host's durable store.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S4 third batch, type-only\n * migration from the host's `src/durable/durable-service.ts`). The host keeps\n * the implementation (`createDurableService`, writer lease, backends) and its\n * historical module exports; these pure type definitions are the contract a\n * capability plugin programs against (e.g. the first-party subagent-delegate\n * plugin's scheduler persists terminal records through `results.store`).\n * No runtime behavior lives here — importing this module never pulls in\n * `node:fs`.\n */\n\nexport interface DurableSessionRecordV1 {\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableOperationRecordV1 {\n\treadonly operationId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableArtifactRecordV1 {\n\treadonly artifactId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableSnapshotV1 {\n\treadonly version: 1;\n\treadonly exportedAt: number;\n\treadonly sessions: readonly DurableSessionRecordV1[];\n\treadonly operations: readonly DurableOperationRecordV1[];\n\treadonly artifacts: readonly DurableArtifactRecordV1[];\n\treadonly writer: { readonly holder: string | null; readonly crashPending: string | null };\n}\n\nexport type DurableWriterClaimV1 = { readonly status: \"claimed\" } | { readonly status: \"held\"; readonly by: string };\n\nexport type DurableWriterRecoveryV1 =\n\t| { readonly status: \"recovered\"; readonly previousWriter?: string }\n\t| { readonly status: \"held\" };\n\nexport interface DurableReadinessV1 {\n\treadonly ready: boolean;\n\treadonly reason?: string;\n}\n\n/** Diagnostics from the startup log replay of a backend-backed service. */\nexport interface DurableReplayDiagnosticsV1 {\n\t/** Malformed log lines skipped while replaying. */\n\treadonly corruptedLines: number;\n\t/** True when the log existed but could not be read. */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableServiceV1 {\n\tpersistSession(input: {\n\t\treadonly writerId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableSessionRecordV1;\n\tloadSession(input: { readonly sessionId: string }): DurableSessionRecordV1 | undefined;\n\tpersistOperation(input: {\n\t\treadonly writerId: string;\n\t\treadonly operationId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableOperationRecordV1;\n\tloadOperation(input: { readonly operationId: string }): DurableOperationRecordV1 | undefined;\n\tpersistArtifact(input: {\n\t\treadonly writerId: string;\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableArtifactRecordV1;\n\tloadArtifact(input: { readonly artifactId: string }): DurableArtifactRecordV1 | undefined;\n\t/**\n\t * Records for one session, ordered by artifactId for stable output. Optional:\n\t * backends without enumeration answer nothing here, and consumers surface an\n\t * explicit \"not implemented\" instead of an empty list (App artifact panel is\n\t * the first consumer). Read-only; never gated by the writer lease.\n\t */\n\tlistArtifacts?(input: { readonly sessionId: string }): readonly DurableArtifactRecordV1[];\n\t/** All session records, ordered by sessionId for stable output. */\n\tlistSessions(): readonly DurableSessionRecordV1[];\n\tclaimWriter(writerId: string): DurableWriterClaimV1;\n\treleaseWriter(writerId: string): { readonly status: \"released\" };\n\trecoverWriter(writerId: string): DurableWriterRecoveryV1;\n\treadiness(): DurableReadinessV1;\n\texportState(): DurableSnapshotV1;\n\timportState(snapshot: unknown): void;\n\t/**\n\t * Diagnostics from the startup log replay of the backend (zeros/false\n\t * without a backend). Corrupted lines were skipped, not fatal.\n\t */\n\treplayDiagnostics(): DurableReplayDiagnosticsV1;\n}\n"]}
|
package/dist/durable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"durable.js","sourceRoot":"","sources":["../src/durable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG","sourcesContent":["/**\n * Durable service contract types (7.4b) — the plugin-facing persistence\n * surface of the host's durable store.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S4 third batch, type-only\n * migration from the host's `src/durable/durable-service.ts`). The host keeps\n * the implementation (`createDurableService`, writer lease, backends) and its\n * historical module exports; these pure type definitions are the contract a\n * capability plugin programs against (e.g. the first-party subagent-delegate\n * plugin's scheduler persists terminal records through `results.store`).\n * No runtime behavior lives here — importing this module never pulls in\n * `node:fs`.\n */\n\nexport interface DurableSessionRecordV1 {\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableOperationRecordV1 {\n\treadonly operationId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableArtifactRecordV1 {\n\treadonly artifactId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableSnapshotV1 {\n\treadonly version: 1;\n\treadonly exportedAt: number;\n\treadonly sessions: readonly DurableSessionRecordV1[];\n\treadonly operations: readonly DurableOperationRecordV1[];\n\treadonly artifacts: readonly DurableArtifactRecordV1[];\n\treadonly writer: { readonly holder: string | null; readonly crashPending: string | null };\n}\n\nexport type DurableWriterClaimV1 = { readonly status: \"claimed\" } | { readonly status: \"held\"; readonly by: string };\n\nexport type DurableWriterRecoveryV1 =\n\t| { readonly status: \"recovered\"; readonly previousWriter?: string }\n\t| { readonly status: \"held\" };\n\nexport interface DurableReadinessV1 {\n\treadonly ready: boolean;\n\treadonly reason?: string;\n}\n\n/** Diagnostics from the startup log replay of a backend-backed service. */\nexport interface DurableReplayDiagnosticsV1 {\n\t/** Malformed log lines skipped while replaying. */\n\treadonly corruptedLines: number;\n\t/** True when the log existed but could not be read. */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableServiceV1 {\n\tpersistSession(input: {\n\t\treadonly writerId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableSessionRecordV1;\n\tloadSession(input: { readonly sessionId: string }): DurableSessionRecordV1 | undefined;\n\tpersistOperation(input: {\n\t\treadonly writerId: string;\n\t\treadonly operationId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableOperationRecordV1;\n\tloadOperation(input: { readonly operationId: string }): DurableOperationRecordV1 | undefined;\n\tpersistArtifact(input: {\n\t\treadonly writerId: string;\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableArtifactRecordV1;\n\tloadArtifact(input: { readonly artifactId: string }): DurableArtifactRecordV1 | undefined;\n\t/** All session records, ordered by sessionId for stable output. */\n\tlistSessions(): readonly DurableSessionRecordV1[];\n\tclaimWriter(writerId: string): DurableWriterClaimV1;\n\treleaseWriter(writerId: string): { readonly status: \"released\" };\n\trecoverWriter(writerId: string): DurableWriterRecoveryV1;\n\treadiness(): DurableReadinessV1;\n\texportState(): DurableSnapshotV1;\n\timportState(snapshot: unknown): void;\n\t/**\n\t * Diagnostics from the startup log replay of the backend (zeros/false\n\t * without a backend). Corrupted lines were skipped, not fatal.\n\t */\n\treplayDiagnostics(): DurableReplayDiagnosticsV1;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"durable.js","sourceRoot":"","sources":["../src/durable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG","sourcesContent":["/**\n * Durable service contract types (7.4b) — the plugin-facing persistence\n * surface of the host's durable store.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S4 third batch, type-only\n * migration from the host's `src/durable/durable-service.ts`). The host keeps\n * the implementation (`createDurableService`, writer lease, backends) and its\n * historical module exports; these pure type definitions are the contract a\n * capability plugin programs against (e.g. the first-party subagent-delegate\n * plugin's scheduler persists terminal records through `results.store`).\n * No runtime behavior lives here — importing this module never pulls in\n * `node:fs`.\n */\n\nexport interface DurableSessionRecordV1 {\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableOperationRecordV1 {\n\treadonly operationId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableArtifactRecordV1 {\n\treadonly artifactId: string;\n\treadonly sessionId: string;\n\treadonly data: unknown;\n\treadonly persistedAt: number;\n}\n\nexport interface DurableSnapshotV1 {\n\treadonly version: 1;\n\treadonly exportedAt: number;\n\treadonly sessions: readonly DurableSessionRecordV1[];\n\treadonly operations: readonly DurableOperationRecordV1[];\n\treadonly artifacts: readonly DurableArtifactRecordV1[];\n\treadonly writer: { readonly holder: string | null; readonly crashPending: string | null };\n}\n\nexport type DurableWriterClaimV1 = { readonly status: \"claimed\" } | { readonly status: \"held\"; readonly by: string };\n\nexport type DurableWriterRecoveryV1 =\n\t| { readonly status: \"recovered\"; readonly previousWriter?: string }\n\t| { readonly status: \"held\" };\n\nexport interface DurableReadinessV1 {\n\treadonly ready: boolean;\n\treadonly reason?: string;\n}\n\n/** Diagnostics from the startup log replay of a backend-backed service. */\nexport interface DurableReplayDiagnosticsV1 {\n\t/** Malformed log lines skipped while replaying. */\n\treadonly corruptedLines: number;\n\t/** True when the log existed but could not be read. */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableServiceV1 {\n\tpersistSession(input: {\n\t\treadonly writerId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableSessionRecordV1;\n\tloadSession(input: { readonly sessionId: string }): DurableSessionRecordV1 | undefined;\n\tpersistOperation(input: {\n\t\treadonly writerId: string;\n\t\treadonly operationId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableOperationRecordV1;\n\tloadOperation(input: { readonly operationId: string }): DurableOperationRecordV1 | undefined;\n\tpersistArtifact(input: {\n\t\treadonly writerId: string;\n\t\treadonly artifactId: string;\n\t\treadonly sessionId: string;\n\t\treadonly data: unknown;\n\t}): DurableArtifactRecordV1;\n\tloadArtifact(input: { readonly artifactId: string }): DurableArtifactRecordV1 | undefined;\n\t/**\n\t * Records for one session, ordered by artifactId for stable output. Optional:\n\t * backends without enumeration answer nothing here, and consumers surface an\n\t * explicit \"not implemented\" instead of an empty list (App artifact panel is\n\t * the first consumer). Read-only; never gated by the writer lease.\n\t */\n\tlistArtifacts?(input: { readonly sessionId: string }): readonly DurableArtifactRecordV1[];\n\t/** All session records, ordered by sessionId for stable output. */\n\tlistSessions(): readonly DurableSessionRecordV1[];\n\tclaimWriter(writerId: string): DurableWriterClaimV1;\n\treleaseWriter(writerId: string): { readonly status: \"released\" };\n\trecoverWriter(writerId: string): DurableWriterRecoveryV1;\n\treadiness(): DurableReadinessV1;\n\texportState(): DurableSnapshotV1;\n\timportState(snapshot: unknown): void;\n\t/**\n\t * Diagnostics from the startup log replay of the backend (zeros/false\n\t * without a backend). Corrupted lines were skipped, not fatal.\n\t */\n\treplayDiagnostics(): DurableReplayDiagnosticsV1;\n}\n"]}
|
package/dist/observability.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ export interface MetricsCancelLatencySampledV1 {
|
|
|
100
100
|
readonly p50Ms: number | null;
|
|
101
101
|
readonly p95Ms: number | null;
|
|
102
102
|
}
|
|
103
|
-
/** Token
|
|
103
|
+
/** Token totals summed over usage-bearing journal events. */
|
|
104
104
|
export interface MetricsTokensSampledV1 {
|
|
105
105
|
readonly status: "sampled";
|
|
106
106
|
readonly totalTokens: number;
|
|
@@ -1 +1 @@
|
|
|
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/cost 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 * 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuLH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,eAAe;IACf,WAAW;IACX,aAAa;IACb,cAAc;IACd,WAAW;IACX,WAAW;IACX,OAAO;IACP,UAAU;IACV,YAAY;CAC8B,CAAC;AAG5C,MAAM,6BAA6B,GAAuD,IAAI,CAAC","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/cost 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.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuLH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,eAAe;IACf,WAAW;IACX,aAAa;IACb,cAAc;IACd,WAAW;IACX,WAAW;IACX,OAAO;IACP,UAAU;IACV,YAAY;CAC8B,CAAC;AAG5C,MAAM,6BAA6B,GAAuD,IAAI,CAAC","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"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* surface (D-075 S2); the host (`@agent-forge/agent-forge`) re-exports it from
|
|
9
9
|
* its historical module path so existing imports keep resolving.
|
|
10
10
|
*/
|
|
11
|
+
import type { DurableServiceV1 } from "./durable.ts";
|
|
11
12
|
import type { MemoryStorageComponentsV1 } from "./memory.ts";
|
|
12
13
|
import type { ObservabilityHostAdapterV1, TraceSinkOptionsV1 } from "./observability.ts";
|
|
13
14
|
/** @experimental Promoted out of draft only when a real consumer drives stabilization. */
|
|
@@ -220,6 +221,21 @@ export interface HostCapabilities {
|
|
|
220
221
|
* 凭据条目投影(`api.host.modelCatalog`)。缺席 = 宿主不提供目录读面。
|
|
221
222
|
*/
|
|
222
223
|
modelCatalog?: ModelCatalogV1;
|
|
224
|
+
/**
|
|
225
|
+
* Durable agent-task results store (durable replay assembly, 2026-10-13
|
|
226
|
+
* 用户裁决"子代理任务结果必须可回放", host service contract). Runtime
|
|
227
|
+
* service, not a type: the host passes its durable facility (`store` plus
|
|
228
|
+
* its writer id) and the first-party subagent-delegate plugin binds it as
|
|
229
|
+
* the scheduler's `results` store, so terminal records survive in the
|
|
230
|
+
* host's durable log outside the sessions tree. The host owns the writer
|
|
231
|
+
* lease lifecycle (the CLI default store self-heals the lease per persist;
|
|
232
|
+
* the serve assembly claims once at startup). Absent = the plugin degrades
|
|
233
|
+
* to in-memory records only (no durable replay), never a load failure.
|
|
234
|
+
*/
|
|
235
|
+
agentTaskResults?: {
|
|
236
|
+
readonly store: DurableServiceV1;
|
|
237
|
+
readonly writerId: string;
|
|
238
|
+
};
|
|
223
239
|
}
|
|
224
240
|
export interface DisposableRegistration {
|
|
225
241
|
id: string;
|
|
@@ -1701,6 +1717,8 @@ export declare const SUMMARY_MODEL_INVOCATION_ERROR_CODES: {
|
|
|
1701
1717
|
readonly lengthCap: "summary_length_cap";
|
|
1702
1718
|
/** The model attempted a tool call in a tool-less completion. */
|
|
1703
1719
|
readonly toolCall: "summary_tool_call";
|
|
1720
|
+
/** Completed response has no non-whitespace summary text. */
|
|
1721
|
+
readonly emptyText: "summary_empty_text";
|
|
1704
1722
|
/** The transport threw; `message` mirrors the original error text. */
|
|
1705
1723
|
readonly transportError: "summary_transport_error";
|
|
1706
1724
|
};
|