{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,MAAM,WAAW,gBAAgB,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IACvF,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IAClE,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACxC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACtC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CACxC;AAMD,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IAEnE,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAY3C;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE5C;IAED,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAIpC;IAED,IAAI,IAAI,gBAAgB,EAAE,CAEzB;IAED,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAS5E;CACD;AA6CD,MAAM,WAAW,iBAAiB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACF;AAED,MAAM,WAAW,kBAAkB;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACnC;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,CAmEzG,CAAC;AAQF,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,cAAc,GAAG,uBAAuB,GAAG,wBAAwB,CAAC;AAEhF,MAAM,WAAW,wBAAwB;IACxC,QAAQ,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACF;AAED,MAAM,MAAM,eAAe,GAAG,wBAAwB,GAAG,yBAAyB,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACnC;AAmSD,eAAO,MAAM,cAAc,EAAE,gBAAgB,CAAC,cAAc,EAAE,eAAe,EAAE,eAAe,CAsF7F,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAElE,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAErE,eAAO,MAAM,YAAY,EAAE,gBAAgB,CAAC,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAwD7F,CAAC;AAEF,MAAM,WAAW,mBAAmB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAAE,CAAC;AAEpG,eAAO,MAAM,mBAAmB,EAAE,gBAAgB,CAAC,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAmDlH,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CACjE;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAoC5G,CAAC;AAIF,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACvC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACzC;AAED,eAAO,MAAM,cAAc,EAAE,gBAAgB,CAAC,cAAc,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAkEnG,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,aAAa,GACtB;IACA,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACA,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAChB,CAAC;AAEL,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAsBD,eAAO,MAAM,WAAW,EAAE,gBAAgB,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CA6B1F,CAAC;AAEF,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACtC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,mBAAmB,GAAG,wBAAwB,CAAC;AAEjG,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACzC,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,yBAAyB,CAAC;AAErG,eAAO,MAAM,aAAa,EAAE,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAkDhG,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,gEAAgE;IAChE,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,gBAAgB,CAAC,eAAe,EAAE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAgCtG,CAAC;AAEF,wBAAgB,2BAA2B,IAAI,cAAc,CAY5D","sourcesContent":["import { canonicalJson } from \"../storage.ts\";\nimport type { EvoComponentSelection } from \"../types.ts\";\nimport { assertEvoAbiId, assertEvoCapability, assertEvoComponentId } from \"./manifest.ts\";\n\nexport interface EvoAbiDefinition<TInput = unknown, TOutput = unknown, TConfig = unknown> {\n\tid: string;\n\tsurface: string;\n\tactivationBoundary: \"turn\" | \"session\" | \"process\" | \"invocation\";\n\tcapabilityCeiling: readonly string[];\n\tvalidateConfig(value: unknown): TConfig;\n\tvalidateInput(value: unknown): TInput;\n\tvalidateOutput(value: unknown): TOutput;\n}\n\nfunction assertSurfaceId(value: string): void {\n\tassertEvoComponentId(value, \"ABI surface\");\n}\n\nexport class EvoAbiRegistry {\n\tprivate readonly definitions = new Map<string, EvoAbiDefinition>();\n\n\tregister(definition: EvoAbiDefinition): void {\n\t\tassertEvoAbiId(definition.id, \"ABI id\");\n\t\tassertSurfaceId(definition.surface);\n\t\tfor (const capability of definition.capabilityCeiling) assertEvoCapability(capability);\n\t\tif (new Set(definition.capabilityCeiling).size !== definition.capabilityCeiling.length) {\n\t\t\tthrow new Error(`ABI ${definition.id} capability ceiling contains duplicates`);\n\t\t}\n\t\tif (this.definitions.has(definition.id)) throw new Error(`ABI is already registered: ${definition.id}`);\n\t\tthis.definitions.set(definition.id, {\n\t\t\t...definition,\n\t\t\tcapabilityCeiling: [...definition.capabilityCeiling].sort(),\n\t\t});\n\t}\n\n\tget(id: string): EvoAbiDefinition | undefined {\n\t\treturn this.definitions.get(id);\n\t}\n\n\trequire(id: string): EvoAbiDefinition {\n\t\tconst definition = this.get(id);\n\t\tif (!definition) throw new Error(`Unknown Evo component ABI: ${id}`);\n\t\treturn definition;\n\t}\n\n\tlist(): EvoAbiDefinition[] {\n\t\treturn [...this.definitions.values()].sort((left, right) => left.id.localeCompare(right.id));\n\t}\n\n\tvalidateSelection(surface: string, selection: EvoComponentSelection): unknown {\n\t\tconst definition = this.require(selection.abi);\n\t\tif (definition.surface !== surface) {\n\t\t\tthrow new Error(`ABI ${definition.id} belongs to surface ${definition.surface}, not ${surface}`);\n\t\t}\n\t\tconst config = definition.validateConfig(selection.config ?? {});\n\t\t// Force config to be JSON data now, before it reaches a component process.\n\t\tcanonicalJson(config);\n\t\treturn config;\n\t}\n}\n\nfunction asRecord(value: unknown, label: string): Record<string, unknown> {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${label} must be an object`);\n\t}\n\treturn value as Record<string, unknown>;\n}\n\nfunction jsonValue(value: unknown, label: string): unknown {\n\ttry {\n\t\treturn JSON.parse(canonicalJson(value)) as unknown;\n\t} catch (error) {\n\t\tthrow new Error(`${label} must be JSON serializable`, { cause: error });\n\t}\n}\n\nfunction rejectUnknownKeys(record: Record<string, unknown>, allowed: readonly string[], label: string): void {\n\tconst allowedKeys = new Set(allowed);\n\tfor (const key of Object.keys(record)) {\n\t\tif (!allowedKeys.has(key)) throw new Error(`${label} has unknown key: ${key}`);\n\t}\n}\n\nfunction validateEmptyConfig(value: unknown, label: string): Record<string, never> {\n\tconst config = asRecord(jsonValue(value, label), label);\n\trejectUnknownKeys(config, [], label);\n\treturn {};\n}\n\nfunction requireNonEmptyString(value: unknown, label: string): string {\n\tif (typeof value !== \"string\" || !value) throw new Error(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction requireJsonRecordArray(value: unknown, label: string): Record<string, unknown>[] {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\treturn value.map((entry, index) => asRecord(entry, `${label}[${index}]`));\n}\n\nfunction requireStringArray(value: unknown, label: string): string[] {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\treturn value.map((entry, index) => requireNonEmptyString(entry, `${label}[${index}]`));\n}\n\nexport interface CompactionV1Input {\n\tconversation: string;\n\tpreviousSummary?: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\treason: \"manual\" | \"threshold\" | \"overflow\";\n\tcustomInstructions?: string;\n}\n\nexport interface CompactionV1Output {\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\tdetails?: unknown;\n\tmetrics?: {\n\t\tdurationMs?: number;\n\t\tinputTokens?: number;\n\t\toutputTokens?: number;\n\t};\n}\n\nexport interface CompactionV1Config {\n\tmaxSummaryTokens?: number;\n\tstyle?: \"structured\" | \"narrative\";\n}\n\nexport const COMPACTION_V1_ABI: EvoAbiDefinition<CompactionV1Input, CompactionV1Output, CompactionV1Config> = {\n\tid: \"compaction/v1\",\n\tsurface: \"compaction\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [],\n\tvalidateConfig(value) {\n\t\tconst config = asRecord(jsonValue(value, \"compaction/v1 config\"), \"compaction/v1 config\");\n\t\tfor (const key of Object.keys(config)) {\n\t\t\tif (key !== \"maxSummaryTokens\" && key !== \"style\") {\n\t\t\t\tthrow new Error(`compaction/v1 config has unknown key: ${key}`);\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tconfig.maxSummaryTokens !== undefined &&\n\t\t\t(!Number.isSafeInteger(config.maxSummaryTokens) ||\n\t\t\t\t(config.maxSummaryTokens as number) <= 0 ||\n\t\t\t\t(config.maxSummaryTokens as number) > 32_768)\n\t\t) {\n\t\t\tthrow new Error(\"compaction/v1 config.maxSummaryTokens must be an integer from 1 to 32768\");\n\t\t}\n\t\tif (config.style !== undefined && config.style !== \"structured\" && config.style !== \"narrative\") {\n\t\t\tthrow new Error(\"compaction/v1 config.style is invalid\");\n\t\t}\n\t\treturn {\n\t\t\t...(config.maxSummaryTokens === undefined ? {} : { maxSummaryTokens: config.maxSummaryTokens as number }),\n\t\t\t...(config.style === undefined ? {} : { style: config.style as \"structured\" | \"narrative\" }),\n\t\t};\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(value, \"compaction/v1 input\");\n\t\tif (\n\t\t\ttypeof input.conversation !== \"string\" ||\n\t\t\ttypeof input.firstKeptEntryId !== \"string\" ||\n\t\t\t!input.firstKeptEntryId ||\n\t\t\ttypeof input.tokensBefore !== \"number\" ||\n\t\t\t!Number.isFinite(input.tokensBefore) ||\n\t\t\tinput.tokensBefore < 0 ||\n\t\t\t(input.reason !== \"manual\" && input.reason !== \"threshold\" && input.reason !== \"overflow\") ||\n\t\t\t(input.previousSummary !== undefined && typeof input.previousSummary !== \"string\") ||\n\t\t\t(input.customInstructions !== undefined && typeof input.customInstructions !== \"string\")\n\t\t) {\n\t\t\tthrow new Error(\"compaction/v1 input is invalid\");\n\t\t}\n\t\treturn input as unknown as CompactionV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(value, \"compaction/v1 output\");\n\t\tif (\n\t\t\ttypeof output.summary !== \"string\" ||\n\t\t\t!output.summary.trim() ||\n\t\t\ttypeof output.firstKeptEntryId !== \"string\" ||\n\t\t\t!output.firstKeptEntryId\n\t\t) {\n\t\t\tthrow new Error(\"compaction/v1 output must contain a summary and firstKeptEntryId\");\n\t\t}\n\t\tif (output.details !== undefined) jsonValue(output.details, \"compaction/v1 details\");\n\t\tif (output.metrics !== undefined) {\n\t\t\tconst metrics = asRecord(output.metrics, \"compaction/v1 metrics\");\n\t\t\tfor (const key of [\"durationMs\", \"inputTokens\", \"outputTokens\"] as const) {\n\t\t\t\tconst metric = metrics[key];\n\t\t\t\tif (metric !== undefined && (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0)) {\n\t\t\t\t\tthrow new Error(`compaction/v1 metrics.${key} must be non-negative`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output as unknown as CompactionV1Output;\n\t},\n};\n\n// context/v1 — the conversation-history axis. Two modes discriminated by `mode`:\n// `transform` (ephemeral view recomputed each turn) and `checkpoint` (durable\n// summary, byte-compatible with compaction/v1's contract). Empty ceiling for\n// prune/redact/summarize; retrieve/infer are added later for RAG and abstractive\n// summaries. See docs/host-abis.md.\n\nexport interface ContextV1TransformInput {\n\tmode: \"transform\";\n\tmessages: unknown[];\n\ttokenEstimate?: number;\n\tcontextWindow?: number;\n\tmodel?: string;\n\treason: \"turn\";\n}\n\nexport interface ContextV1CheckpointInput {\n\tmode: \"checkpoint\";\n\tconversation: string;\n\tpreviousSummary?: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\treason: \"manual\" | \"threshold\" | \"overflow\";\n\tcustomInstructions?: string;\n}\n\nexport type ContextV1Input = ContextV1TransformInput | ContextV1CheckpointInput;\n\nexport interface ContextV1TransformOutput {\n\tmessages: unknown[];\n}\n\nexport interface ContextV1CheckpointOutput {\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\tdetails?: unknown;\n\tmetrics?: {\n\t\tdurationMs?: number;\n\t\tinputTokens?: number;\n\t\toutputTokens?: number;\n\t};\n}\n\nexport type ContextV1Output = ContextV1TransformOutput | ContextV1CheckpointOutput;\n\nexport interface ContextV1Config {\n\tmaxSummaryTokens?: number;\n\tstyle?: \"structured\" | \"narrative\";\n}\n\nfunction assertJsonMessageArray(value: unknown, label: string): unknown[] {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tfor (const [index, entry] of value.entries()) {\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${label}[${index}] must be a message object`);\n\t\t}\n\t}\n\tjsonValue(value, label);\n\treturn value;\n}\n\nfunction requireFiniteNumber(value: unknown, label: string, minimum = Number.NEGATIVE_INFINITY): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < minimum) {\n\t\tthrow new Error(`${label} must be a finite number${minimum === 0 ? \" greater than or equal to zero\" : \"\"}`);\n\t}\n\treturn value;\n}\n\nfunction assertTextContent(value: unknown, label: string): void {\n\tconst content = asRecord(value, label);\n\trejectUnknownKeys(content, [\"type\", \"text\", \"textSignature\"], label);\n\tif (content.type !== \"text\" || typeof content.text !== \"string\") {\n\t\tthrow new Error(`${label} must be text content`);\n\t}\n\tif (content.textSignature !== undefined && typeof content.textSignature !== \"string\") {\n\t\tthrow new Error(`${label}.textSignature must be a string`);\n\t}\n}\n\nfunction assertImageContent(value: unknown, label: string): void {\n\tconst content = asRecord(value, label);\n\trejectUnknownKeys(content, [\"type\", \"data\", \"mimeType\"], label);\n\tif (\n\t\tcontent.type !== \"image\" ||\n\t\ttypeof content.data !== \"string\" ||\n\t\ttypeof content.mimeType !== \"string\" ||\n\t\t!content.mimeType\n\t) {\n\t\tthrow new Error(`${label} must be image content`);\n\t}\n}\n\nfunction assertThinkingContent(value: unknown, label: string): void {\n\tconst content = asRecord(value, label);\n\trejectUnknownKeys(content, [\"type\", \"thinking\", \"thinkingSignature\", \"redacted\"], label);\n\tif (content.type !== \"thinking\" || typeof content.thinking !== \"string\") {\n\t\tthrow new Error(`${label} must be thinking content`);\n\t}\n\tif (content.thinkingSignature !== undefined && typeof content.thinkingSignature !== \"string\") {\n\t\tthrow new Error(`${label}.thinkingSignature must be a string`);\n\t}\n\tif (content.redacted !== undefined && typeof content.redacted !== \"boolean\") {\n\t\tthrow new Error(`${label}.redacted must be boolean`);\n\t}\n}\n\nfunction assertToolCallContent(value: unknown, label: string): void {\n\tconst content = asRecord(value, label);\n\trejectUnknownKeys(content, [\"type\", \"id\", \"name\", \"arguments\", \"thoughtSignature\"], label);\n\tif (\n\t\tcontent.type !== \"toolCall\" ||\n\t\ttypeof content.id !== \"string\" ||\n\t\t!content.id ||\n\t\ttypeof content.name !== \"string\" ||\n\t\t!content.name\n\t) {\n\t\tthrow new Error(`${label} must be tool-call content`);\n\t}\n\tasRecord(content.arguments, `${label}.arguments`);\n\tif (content.thoughtSignature !== undefined && typeof content.thoughtSignature !== \"string\") {\n\t\tthrow new Error(`${label}.thoughtSignature must be a string`);\n\t}\n}\n\nfunction assertUserContent(value: unknown, label: string): void {\n\tif (typeof value === \"string\") return;\n\tif (!Array.isArray(value)) throw new Error(`${label} must be a string or content array`);\n\tfor (const [index, content] of value.entries()) {\n\t\tconst type = asRecord(content, `${label}[${index}]`).type;\n\t\tif (type === \"text\") assertTextContent(content, `${label}[${index}]`);\n\t\telse if (type === \"image\") assertImageContent(content, `${label}[${index}]`);\n\t\telse throw new Error(`${label}[${index}] must be text or image content`);\n\t}\n}\n\nfunction assertAssistantContent(value: unknown, label: string, allowToolCalls: boolean): void {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tfor (const [index, content] of value.entries()) {\n\t\tconst contentLabel = `${label}[${index}]`;\n\t\tconst type = asRecord(content, contentLabel).type;\n\t\tif (type === \"text\") assertTextContent(content, contentLabel);\n\t\telse if (type === \"thinking\") assertThinkingContent(content, contentLabel);\n\t\telse if (type === \"toolCall\" && allowToolCalls) assertToolCallContent(content, contentLabel);\n\t\telse {\n\t\t\tthrow new Error(`${contentLabel} must be text or thinking content${allowToolCalls ? \", or a tool call\" : \"\"}`);\n\t\t}\n\t}\n}\n\nfunction assertToolResultContent(value: unknown, label: string): void {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tfor (const [index, content] of value.entries()) {\n\t\tconst contentLabel = `${label}[${index}]`;\n\t\tconst type = asRecord(content, contentLabel).type;\n\t\tif (type === \"text\") assertTextContent(content, contentLabel);\n\t\telse if (type === \"image\") assertImageContent(content, contentLabel);\n\t\telse throw new Error(`${contentLabel} must be text or image content`);\n\t}\n}\n\nfunction assertUsage(value: unknown, label: string): void {\n\tconst usage = asRecord(value, label);\n\trejectUnknownKeys(\n\t\tusage,\n\t\t[\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"cacheWrite1h\", \"reasoning\", \"totalTokens\", \"cost\"],\n\t\tlabel,\n\t);\n\tfor (const key of [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"totalTokens\"] as const) {\n\t\trequireFiniteNumber(usage[key], `${label}.${key}`, 0);\n\t}\n\tfor (const key of [\"cacheWrite1h\", \"reasoning\"] as const) {\n\t\tif (usage[key] !== undefined) requireFiniteNumber(usage[key], `${label}.${key}`, 0);\n\t}\n\tconst cost = asRecord(usage.cost, `${label}.cost`);\n\trejectUnknownKeys(cost, [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"total\"], `${label}.cost`);\n\tfor (const key of [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"total\"] as const) {\n\t\trequireFiniteNumber(cost[key], `${label}.cost.${key}`, 0);\n\t}\n}\n\nfunction assertDiagnostics(value: unknown, label: string): void {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tfor (const [index, diagnosticValue] of value.entries()) {\n\t\tconst diagnosticLabel = `${label}[${index}]`;\n\t\tconst diagnostic = asRecord(diagnosticValue, diagnosticLabel);\n\t\trejectUnknownKeys(diagnostic, [\"type\", \"timestamp\", \"error\", \"details\"], diagnosticLabel);\n\t\trequireNonEmptyString(diagnostic.type, `${diagnosticLabel}.type`);\n\t\tassertTimestamp(diagnostic.timestamp, `${diagnosticLabel}.timestamp`);\n\t\tif (diagnostic.error !== undefined) {\n\t\t\tconst errorLabel = `${diagnosticLabel}.error`;\n\t\t\tconst error = asRecord(diagnostic.error, errorLabel);\n\t\t\trejectUnknownKeys(error, [\"name\", \"message\", \"stack\", \"code\"], errorLabel);\n\t\t\tif (typeof error.message !== \"string\") throw new Error(`${errorLabel}.message must be a string`);\n\t\t\tfor (const key of [\"name\", \"stack\"] as const) {\n\t\t\t\tif (error[key] !== undefined && typeof error[key] !== \"string\") {\n\t\t\t\t\tthrow new Error(`${errorLabel}.${key} must be a string`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (\n\t\t\t\terror.code !== undefined &&\n\t\t\t\ttypeof error.code !== \"string\" &&\n\t\t\t\t(typeof error.code !== \"number\" || !Number.isFinite(error.code))\n\t\t\t) {\n\t\t\t\tthrow new Error(`${errorLabel}.code must be a string or finite number`);\n\t\t\t}\n\t\t}\n\t\tif (diagnostic.details !== undefined) asRecord(diagnostic.details, `${diagnosticLabel}.details`);\n\t}\n}\n\nconst STOP_REASONS = new Set([\"stop\", \"length\", \"toolUse\", \"error\", \"aborted\"]);\n\nfunction assertTimestamp(value: unknown, label: string): void {\n\trequireFiniteNumber(value, label, 0);\n}\n\nfunction assertAgentMessage(value: unknown, label: string): void {\n\tconst message = asRecord(value, label);\n\tswitch (message.role) {\n\t\tcase \"user\":\n\t\t\trejectUnknownKeys(message, [\"role\", \"content\", \"timestamp\"], label);\n\t\t\tassertUserContent(message.content, `${label}.content`);\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"assistant\":\n\t\t\trejectUnknownKeys(\n\t\t\t\tmessage,\n\t\t\t\t[\n\t\t\t\t\t\"role\",\n\t\t\t\t\t\"content\",\n\t\t\t\t\t\"api\",\n\t\t\t\t\t\"provider\",\n\t\t\t\t\t\"model\",\n\t\t\t\t\t\"responseModel\",\n\t\t\t\t\t\"responseId\",\n\t\t\t\t\t\"diagnostics\",\n\t\t\t\t\t\"usage\",\n\t\t\t\t\t\"stopReason\",\n\t\t\t\t\t\"errorMessage\",\n\t\t\t\t\t\"timestamp\",\n\t\t\t\t],\n\t\t\t\tlabel,\n\t\t\t);\n\t\t\tassertAssistantContent(message.content, `${label}.content`, true);\n\t\t\tfor (const key of [\"api\", \"provider\", \"model\"] as const) {\n\t\t\t\trequireNonEmptyString(message[key], `${label}.${key}`);\n\t\t\t}\n\t\t\tfor (const key of [\"responseModel\", \"responseId\", \"errorMessage\"] as const) {\n\t\t\t\tif (message[key] !== undefined && typeof message[key] !== \"string\") {\n\t\t\t\t\tthrow new Error(`${label}.${key} must be a string`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (message.diagnostics !== undefined) assertDiagnostics(message.diagnostics, `${label}.diagnostics`);\n\t\t\tassertUsage(message.usage, `${label}.usage`);\n\t\t\tif (typeof message.stopReason !== \"string\" || !STOP_REASONS.has(message.stopReason)) {\n\t\t\t\tthrow new Error(`${label}.stopReason is invalid`);\n\t\t\t}\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"toolResult\":\n\t\t\trejectUnknownKeys(\n\t\t\t\tmessage,\n\t\t\t\t[\"role\", \"toolCallId\", \"toolName\", \"content\", \"details\", \"addedToolNames\", \"isError\", \"timestamp\"],\n\t\t\t\tlabel,\n\t\t\t);\n\t\t\trequireNonEmptyString(message.toolCallId, `${label}.toolCallId`);\n\t\t\trequireNonEmptyString(message.toolName, `${label}.toolName`);\n\t\t\tassertToolResultContent(message.content, `${label}.content`);\n\t\t\tif (message.details !== undefined) jsonValue(message.details, `${label}.details`);\n\t\t\tif (message.addedToolNames !== undefined) {\n\t\t\t\trequireStringArray(message.addedToolNames, `${label}.addedToolNames`);\n\t\t\t}\n\t\t\tif (typeof message.isError !== \"boolean\") throw new Error(`${label}.isError must be boolean`);\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"bashExecution\":\n\t\t\trejectUnknownKeys(\n\t\t\t\tmessage,\n\t\t\t\t[\n\t\t\t\t\t\"role\",\n\t\t\t\t\t\"command\",\n\t\t\t\t\t\"output\",\n\t\t\t\t\t\"exitCode\",\n\t\t\t\t\t\"cancelled\",\n\t\t\t\t\t\"truncated\",\n\t\t\t\t\t\"fullOutputPath\",\n\t\t\t\t\t\"timestamp\",\n\t\t\t\t\t\"excludeFromContext\",\n\t\t\t\t],\n\t\t\t\tlabel,\n\t\t\t);\n\t\t\tfor (const key of [\"command\", \"output\"] as const) {\n\t\t\t\tif (typeof message[key] !== \"string\") throw new Error(`${label}.${key} must be a string`);\n\t\t\t}\n\t\t\tif (message.exitCode !== undefined) requireFiniteNumber(message.exitCode, `${label}.exitCode`);\n\t\t\tif (message.fullOutputPath !== undefined && typeof message.fullOutputPath !== \"string\") {\n\t\t\t\tthrow new Error(`${label}.fullOutputPath must be a string`);\n\t\t\t}\n\t\t\tfor (const key of [\"cancelled\", \"truncated\"] as const) {\n\t\t\t\tif (typeof message[key] !== \"boolean\") throw new Error(`${label}.${key} must be boolean`);\n\t\t\t}\n\t\t\tif (message.excludeFromContext !== undefined && typeof message.excludeFromContext !== \"boolean\") {\n\t\t\t\tthrow new Error(`${label}.excludeFromContext must be boolean`);\n\t\t\t}\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"custom\":\n\t\t\trejectUnknownKeys(message, [\"role\", \"customType\", \"content\", \"display\", \"details\", \"timestamp\"], label);\n\t\t\trequireNonEmptyString(message.customType, `${label}.customType`);\n\t\t\tassertUserContent(message.content, `${label}.content`);\n\t\t\tif (typeof message.display !== \"boolean\") throw new Error(`${label}.display must be boolean`);\n\t\t\tif (message.details !== undefined) jsonValue(message.details, `${label}.details`);\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"branchSummary\":\n\t\t\trejectUnknownKeys(message, [\"role\", \"summary\", \"fromId\", \"timestamp\"], label);\n\t\t\trequireNonEmptyString(message.summary, `${label}.summary`);\n\t\t\trequireNonEmptyString(message.fromId, `${label}.fromId`);\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tcase \"compactionSummary\":\n\t\t\trejectUnknownKeys(message, [\"role\", \"summary\", \"tokensBefore\", \"timestamp\"], label);\n\t\t\trequireNonEmptyString(message.summary, `${label}.summary`);\n\t\t\trequireFiniteNumber(message.tokensBefore, `${label}.tokensBefore`, 0);\n\t\t\tassertTimestamp(message.timestamp, `${label}.timestamp`);\n\t\t\treturn;\n\t\tdefault:\n\t\t\tthrow new Error(`${label}.role is unsupported`);\n\t}\n}\n\nfunction assertAgentMessageArray(value: unknown, label: string): unknown[] {\n\tif (!Array.isArray(value)) throw new Error(`${label} must be an array`);\n\tfor (const [index, message] of value.entries()) {\n\t\tassertAgentMessage(message, `${label}[${index}]`);\n\t}\n\treturn value;\n}\n\nexport const CONTEXT_V1_ABI: EvoAbiDefinition<ContextV1Input, ContextV1Output, ContextV1Config> = {\n\tid: \"context/v1\",\n\tsurface: \"context\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [\"infer\", \"retrieve\"],\n\tvalidateConfig(value) {\n\t\tconst config = asRecord(jsonValue(value, \"context/v1 config\"), \"context/v1 config\");\n\t\tfor (const key of Object.keys(config)) {\n\t\t\tif (key !== \"maxSummaryTokens\" && key !== \"style\") {\n\t\t\t\tthrow new Error(`context/v1 config has unknown key: ${key}`);\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tconfig.maxSummaryTokens !== undefined &&\n\t\t\t(!Number.isSafeInteger(config.maxSummaryTokens) ||\n\t\t\t\t(config.maxSummaryTokens as number) <= 0 ||\n\t\t\t\t(config.maxSummaryTokens as number) > 32_768)\n\t\t) {\n\t\t\tthrow new Error(\"context/v1 config.maxSummaryTokens must be an integer from 1 to 32768\");\n\t\t}\n\t\tif (config.style !== undefined && config.style !== \"structured\" && config.style !== \"narrative\") {\n\t\t\tthrow new Error(\"context/v1 config.style is invalid\");\n\t\t}\n\t\treturn {\n\t\t\t...(config.maxSummaryTokens === undefined ? {} : { maxSummaryTokens: config.maxSummaryTokens as number }),\n\t\t\t...(config.style === undefined ? {} : { style: config.style as \"structured\" | \"narrative\" }),\n\t\t};\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(value, \"context/v1 input\");\n\t\tif (input.mode === \"transform\") {\n\t\t\tassertJsonMessageArray(input.messages, \"context/v1 transform input.messages\");\n\t\t\tif (input.reason !== \"turn\") throw new Error(\"context/v1 transform input.reason must be 'turn'\");\n\t\t\tfor (const key of [\"tokenEstimate\", \"contextWindow\"] as const) {\n\t\t\t\tconst metric = input[key];\n\t\t\t\tif (metric !== undefined && (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0)) {\n\t\t\t\t\tthrow new Error(`context/v1 transform input.${key} must be a non-negative number`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (input.model !== undefined && typeof input.model !== \"string\") {\n\t\t\t\tthrow new Error(\"context/v1 transform input.model must be a string\");\n\t\t\t}\n\t\t\treturn input as unknown as ContextV1Input;\n\t\t}\n\t\tif (input.mode === \"checkpoint\") {\n\t\t\tif (\n\t\t\t\ttypeof input.conversation !== \"string\" ||\n\t\t\t\ttypeof input.firstKeptEntryId !== \"string\" ||\n\t\t\t\t!input.firstKeptEntryId ||\n\t\t\t\ttypeof input.tokensBefore !== \"number\" ||\n\t\t\t\t!Number.isFinite(input.tokensBefore) ||\n\t\t\t\tinput.tokensBefore < 0 ||\n\t\t\t\t(input.reason !== \"manual\" && input.reason !== \"threshold\" && input.reason !== \"overflow\") ||\n\t\t\t\t(input.previousSummary !== undefined && typeof input.previousSummary !== \"string\") ||\n\t\t\t\t(input.customInstructions !== undefined && typeof input.customInstructions !== \"string\")\n\t\t\t) {\n\t\t\t\tthrow new Error(\"context/v1 checkpoint input is invalid\");\n\t\t\t}\n\t\t\treturn input as unknown as ContextV1Input;\n\t\t}\n\t\tthrow new Error(\"context/v1 input.mode must be 'transform' or 'checkpoint'\");\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"context/v1 output\"), \"context/v1 output\");\n\t\tif (Array.isArray(output.messages)) {\n\t\t\tassertAgentMessageArray(output.messages, \"context/v1 transform output.messages\");\n\t\t\treturn output as unknown as ContextV1Output;\n\t\t}\n\t\tif (typeof output.summary === \"string\") {\n\t\t\tif (!output.summary.trim() || typeof output.firstKeptEntryId !== \"string\" || !output.firstKeptEntryId) {\n\t\t\t\tthrow new Error(\"context/v1 checkpoint output must contain a summary and firstKeptEntryId\");\n\t\t\t}\n\t\t\tif (output.details !== undefined) jsonValue(output.details, \"context/v1 details\");\n\t\t\tif (output.metrics !== undefined) {\n\t\t\t\tconst metrics = asRecord(output.metrics, \"context/v1 metrics\");\n\t\t\t\tfor (const key of [\"durationMs\", \"inputTokens\", \"outputTokens\"] as const) {\n\t\t\t\t\tconst metric = metrics[key];\n\t\t\t\t\tif (metric !== undefined && (typeof metric !== \"number\" || !Number.isFinite(metric) || metric < 0)) {\n\t\t\t\t\t\tthrow new Error(`context/v1 metrics.${key} must be non-negative`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn output as unknown as ContextV1Output;\n\t\t}\n\t\tthrow new Error(\"context/v1 output must contain messages (transform) or a summary (checkpoint)\");\n\t},\n};\n\nexport interface GuardV1BeforeInput {\n\tmode: \"before\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: Record<string, unknown>;\n}\n\nexport interface GuardV1AfterInput {\n\tmode: \"after\";\n\ttoolCallId: string;\n\ttoolName: string;\n\targs: Record<string, unknown>;\n\tcontent: unknown[];\n\tdetails?: unknown;\n\tisError: boolean;\n}\n\nexport type GuardV1Input = GuardV1BeforeInput | GuardV1AfterInput;\n\nexport interface GuardV1BeforeOutput {\n\tmode: \"before\";\n\tblock?: boolean;\n\treason?: string;\n\targs?: Record<string, unknown>;\n}\n\nexport interface GuardV1AfterOutput {\n\tmode: \"after\";\n\tcontent?: unknown[];\n\tdetails?: unknown;\n\tisError?: boolean;\n\tterminate?: boolean;\n}\n\nexport type GuardV1Output = GuardV1BeforeOutput | GuardV1AfterOutput;\n\nexport const GUARD_V1_ABI: EvoAbiDefinition<GuardV1Input, GuardV1Output, Record<string, never>> = {\n\tid: \"guard/v1\",\n\tsurface: \"guard\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"guard/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"guard/v1 input\"), \"guard/v1 input\");\n\t\trequireNonEmptyString(input.toolCallId, \"guard/v1 input.toolCallId\");\n\t\trequireNonEmptyString(input.toolName, \"guard/v1 input.toolName\");\n\t\tasRecord(input.args, \"guard/v1 input.args\");\n\t\tif (input.mode === \"before\") {\n\t\t\trejectUnknownKeys(input, [\"mode\", \"toolCallId\", \"toolName\", \"args\"], \"guard/v1 before input\");\n\t\t\treturn input as unknown as GuardV1BeforeInput;\n\t\t}\n\t\tif (input.mode === \"after\") {\n\t\t\trejectUnknownKeys(\n\t\t\t\tinput,\n\t\t\t\t[\"mode\", \"toolCallId\", \"toolName\", \"args\", \"content\", \"details\", \"isError\"],\n\t\t\t\t\"guard/v1 after input\",\n\t\t\t);\n\t\t\tassertJsonMessageArray(input.content, \"guard/v1 after input.content\");\n\t\t\tif (input.details !== undefined) jsonValue(input.details, \"guard/v1 after input.details\");\n\t\t\tif (typeof input.isError !== \"boolean\") throw new Error(\"guard/v1 after input.isError must be boolean\");\n\t\t\treturn input as unknown as GuardV1AfterInput;\n\t\t}\n\t\tthrow new Error(\"guard/v1 input.mode must be 'before' or 'after'\");\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"guard/v1 output\"), \"guard/v1 output\");\n\t\tif (output.mode === \"before\") {\n\t\t\trejectUnknownKeys(output, [\"mode\", \"block\", \"reason\", \"args\"], \"guard/v1 before output\");\n\t\t\tif (output.block !== undefined && typeof output.block !== \"boolean\") {\n\t\t\t\tthrow new Error(\"guard/v1 before output.block must be boolean\");\n\t\t\t}\n\t\t\tif (output.reason !== undefined && typeof output.reason !== \"string\") {\n\t\t\t\tthrow new Error(\"guard/v1 before output.reason must be a string\");\n\t\t\t}\n\t\t\tif (output.args !== undefined) asRecord(output.args, \"guard/v1 before output.args\");\n\t\t\treturn output as unknown as GuardV1BeforeOutput;\n\t\t}\n\t\tif (output.mode === \"after\") {\n\t\t\trejectUnknownKeys(output, [\"mode\", \"content\", \"details\", \"isError\", \"terminate\"], \"guard/v1 after output\");\n\t\t\tif (output.content !== undefined) assertToolResultContent(output.content, \"guard/v1 after output.content\");\n\t\t\tif (output.details !== undefined) jsonValue(output.details, \"guard/v1 after output.details\");\n\t\t\tfor (const key of [\"isError\", \"terminate\"] as const) {\n\t\t\t\tif (output[key] !== undefined && typeof output[key] !== \"boolean\") {\n\t\t\t\t\tthrow new Error(`guard/v1 after output.${key} must be boolean`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn output as unknown as GuardV1AfterOutput;\n\t\t}\n\t\tthrow new Error(\"guard/v1 output.mode must be 'before' or 'after'\");\n\t},\n};\n\nexport interface InstructionsV1Input {\n\tsystemPrompt: string;\n\toptions: Record<string, unknown>;\n}\n\nexport interface InstructionsV1Section {\n\tname?: string;\n\tcontent: string;\n}\n\nexport type InstructionsV1Output = { systemPrompt: string } | { sections: InstructionsV1Section[] };\n\nexport const INSTRUCTIONS_V1_ABI: EvoAbiDefinition<InstructionsV1Input, InstructionsV1Output, Record<string, never>> = {\n\tid: \"instructions/v1\",\n\tsurface: \"instructions\",\n\tactivationBoundary: \"turn\",\n\tcapabilityCeiling: [\"read-file\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"instructions/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"instructions/v1 input\"), \"instructions/v1 input\");\n\t\trejectUnknownKeys(input, [\"systemPrompt\", \"options\"], \"instructions/v1 input\");\n\t\tif (typeof input.systemPrompt !== \"string\") {\n\t\t\tthrow new Error(\"instructions/v1 input.systemPrompt must be a string\");\n\t\t}\n\t\tasRecord(input.options, \"instructions/v1 input.options\");\n\t\treturn input as unknown as InstructionsV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"instructions/v1 output\"), \"instructions/v1 output\");\n\t\tconst hasPrompt = Object.hasOwn(output, \"systemPrompt\");\n\t\tconst hasSections = Object.hasOwn(output, \"sections\");\n\t\tif (hasPrompt === hasSections) {\n\t\t\tthrow new Error(\"instructions/v1 output must contain exactly one of systemPrompt or sections\");\n\t\t}\n\t\tif (hasPrompt) {\n\t\t\trejectUnknownKeys(output, [\"systemPrompt\"], \"instructions/v1 output\");\n\t\t\tif (typeof output.systemPrompt !== \"string\") {\n\t\t\t\tthrow new Error(\"instructions/v1 output.systemPrompt must be a string\");\n\t\t\t}\n\t\t\treturn { systemPrompt: output.systemPrompt };\n\t\t}\n\t\trejectUnknownKeys(output, [\"sections\"], \"instructions/v1 output\");\n\t\tif (!Array.isArray(output.sections) || output.sections.length === 0) {\n\t\t\tthrow new Error(\"instructions/v1 output.sections must be a non-empty array\");\n\t\t}\n\t\tconst sections = output.sections.map((value, index) => {\n\t\t\tconst section = asRecord(value, `instructions/v1 output.sections[${index}]`);\n\t\t\trejectUnknownKeys(section, [\"name\", \"content\"], `instructions/v1 output.sections[${index}]`);\n\t\t\tif (section.name !== undefined && typeof section.name !== \"string\") {\n\t\t\t\tthrow new Error(`instructions/v1 output.sections[${index}].name must be a string`);\n\t\t\t}\n\t\t\tif (typeof section.content !== \"string\") {\n\t\t\t\tthrow new Error(`instructions/v1 output.sections[${index}].content must be a string`);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...(section.name === undefined ? {} : { name: section.name }),\n\t\t\t\tcontent: section.content,\n\t\t\t};\n\t\t});\n\t\treturn { sections };\n\t},\n};\n\nexport interface GenerationV1Input {\n\tmessage: Record<string, unknown>;\n}\n\nexport interface GenerationV1Output {\n\tmessage?: Record<string, unknown>;\n\tredo?: boolean;\n\tstopReason?: \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n}\n\nexport const GENERATION_V1_ABI: EvoAbiDefinition<GenerationV1Input, GenerationV1Output, Record<string, never>> = {\n\tid: \"generation/v1\",\n\tsurface: \"generation\",\n\tactivationBoundary: \"turn\",\n\tcapabilityCeiling: [\"infer\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"generation/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"generation/v1 input\"), \"generation/v1 input\");\n\t\trejectUnknownKeys(input, [\"message\"], \"generation/v1 input\");\n\t\tasRecord(input.message, \"generation/v1 input.message\");\n\t\treturn input as unknown as GenerationV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"generation/v1 output\"), \"generation/v1 output\");\n\t\trejectUnknownKeys(output, [\"message\", \"redo\", \"stopReason\"], \"generation/v1 output\");\n\t\tif (!Object.hasOwn(output, \"message\") && !Object.hasOwn(output, \"redo\") && !Object.hasOwn(output, \"stopReason\")) {\n\t\t\tthrow new Error(\"generation/v1 output must contain message, redo, or stopReason\");\n\t\t}\n\t\tif (output.message !== undefined) {\n\t\t\tconst message = asRecord(output.message, \"generation/v1 output.message\");\n\t\t\tif (message.role !== \"assistant\") throw new Error(\"generation/v1 output.message.role must be assistant\");\n\t\t\tassertAssistantContent(message.content, \"generation/v1 output.message.content\", false);\n\t\t}\n\t\tif (output.redo !== undefined && typeof output.redo !== \"boolean\") {\n\t\t\tthrow new Error(\"generation/v1 output.redo must be boolean\");\n\t\t}\n\t\tif (\n\t\t\toutput.stopReason !== undefined &&\n\t\t\t(typeof output.stopReason !== \"string\" || !STOP_REASONS.has(output.stopReason))\n\t\t) {\n\t\t\tthrow new Error(\"generation/v1 output.stopReason is invalid\");\n\t\t}\n\t\treturn output as unknown as GenerationV1Output;\n\t},\n};\n\nconst THINKING_LEVELS = new Set([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"]);\n\nexport interface ControlV1Usage {\n\ttokens: number | null;\n\tcontextWindow: number;\n\tpercent: number | null;\n}\n\nexport interface ControlV1Input {\n\tturnIndex: number;\n\tmessage: Record<string, unknown>;\n\ttoolResults: Record<string, unknown>[];\n\tusage?: ControlV1Usage;\n\tmodel?: string;\n\treasoning?: string;\n}\n\nexport interface ControlV1Output {\n\tstop?: boolean;\n\tmodel?: string;\n\treasoning?: string;\n\tmemoryDeltas?: Record<string, unknown>[];\n}\n\nexport const CONTROL_V1_ABI: EvoAbiDefinition<ControlV1Input, ControlV1Output, Record<string, never>> = {\n\tid: \"control/v1\",\n\tsurface: \"control\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [\"memory-write\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"control/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"control/v1 input\"), \"control/v1 input\");\n\t\trejectUnknownKeys(\n\t\t\tinput,\n\t\t\t[\"turnIndex\", \"message\", \"toolResults\", \"usage\", \"model\", \"reasoning\"],\n\t\t\t\"control/v1 input\",\n\t\t);\n\t\tif (!Number.isSafeInteger(input.turnIndex) || (input.turnIndex as number) < 0) {\n\t\t\tthrow new Error(\"control/v1 input.turnIndex must be a non-negative safe integer\");\n\t\t}\n\t\tasRecord(input.message, \"control/v1 input.message\");\n\t\tassertJsonMessageArray(input.toolResults, \"control/v1 input.toolResults\");\n\t\tif (input.usage !== undefined) {\n\t\t\tconst usage = asRecord(input.usage, \"control/v1 input.usage\");\n\t\t\trejectUnknownKeys(usage, [\"tokens\", \"contextWindow\", \"percent\"], \"control/v1 input.usage\");\n\t\t\tif (usage.tokens !== null && (typeof usage.tokens !== \"number\" || !Number.isFinite(usage.tokens))) {\n\t\t\t\tthrow new Error(\"control/v1 input.usage.tokens must be a finite number or null\");\n\t\t\t}\n\t\t\tif (\n\t\t\t\ttypeof usage.contextWindow !== \"number\" ||\n\t\t\t\t!Number.isFinite(usage.contextWindow) ||\n\t\t\t\tusage.contextWindow < 0\n\t\t\t) {\n\t\t\t\tthrow new Error(\"control/v1 input.usage.contextWindow must be a non-negative number\");\n\t\t\t}\n\t\t\tif (usage.percent !== null && (typeof usage.percent !== \"number\" || !Number.isFinite(usage.percent))) {\n\t\t\t\tthrow new Error(\"control/v1 input.usage.percent must be a finite number or null\");\n\t\t\t}\n\t\t}\n\t\tif (input.model !== undefined) requireNonEmptyString(input.model, \"control/v1 input.model\");\n\t\tif (input.reasoning !== undefined && !THINKING_LEVELS.has(input.reasoning as string)) {\n\t\t\tthrow new Error(\"control/v1 input.reasoning is invalid\");\n\t\t}\n\t\treturn input as unknown as ControlV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"control/v1 output\"), \"control/v1 output\");\n\t\trejectUnknownKeys(output, [\"stop\", \"model\", \"reasoning\", \"memoryDeltas\"], \"control/v1 output\");\n\t\tif (\n\t\t\t!Object.hasOwn(output, \"stop\") &&\n\t\t\t!Object.hasOwn(output, \"model\") &&\n\t\t\t!Object.hasOwn(output, \"reasoning\") &&\n\t\t\t!Object.hasOwn(output, \"memoryDeltas\")\n\t\t) {\n\t\t\tthrow new Error(\"control/v1 output must contain stop, model, reasoning, or memoryDeltas\");\n\t\t}\n\t\tif (output.stop !== undefined && typeof output.stop !== \"boolean\") {\n\t\t\tthrow new Error(\"control/v1 output.stop must be boolean\");\n\t\t}\n\t\tif (output.model !== undefined) requireNonEmptyString(output.model, \"control/v1 output.model\");\n\t\tif (output.reasoning !== undefined && !THINKING_LEVELS.has(output.reasoning as string)) {\n\t\t\tthrow new Error(\"control/v1 output.reasoning is invalid\");\n\t\t}\n\t\tif (output.memoryDeltas !== undefined) {\n\t\t\trequireJsonRecordArray(output.memoryDeltas, \"control/v1 output.memoryDeltas\");\n\t\t}\n\t\treturn output as unknown as ControlV1Output;\n\t},\n};\n\nexport interface ToolV1Input {\n\tparams: Record<string, unknown>;\n}\n\nexport type ToolV1Content =\n\t| {\n\t\t\ttype: \"text\";\n\t\t\ttext: string;\n\t\t\ttextSignature?: string;\n\t  }\n\t| {\n\t\t\ttype: \"image\";\n\t\t\tdata: string;\n\t\t\tmimeType: string;\n\t  };\n\nexport interface ToolV1Output {\n\tcontent: ToolV1Content[];\n\tdetails: unknown;\n\taddedToolNames?: string[];\n\tterminate?: boolean;\n}\n\nfunction validateToolV1Content(value: unknown, index: number): ToolV1Content {\n\tconst label = `tool/v1 output.content[${index}]`;\n\tconst content = asRecord(value, label);\n\tif (content.type === \"text\") {\n\t\trejectUnknownKeys(content, [\"type\", \"text\", \"textSignature\"], label);\n\t\tif (typeof content.text !== \"string\") throw new Error(`${label}.text must be a string`);\n\t\tif (content.textSignature !== undefined && typeof content.textSignature !== \"string\") {\n\t\t\tthrow new Error(`${label}.textSignature must be a string`);\n\t\t}\n\t\treturn content as unknown as ToolV1Content;\n\t}\n\tif (content.type === \"image\") {\n\t\trejectUnknownKeys(content, [\"type\", \"data\", \"mimeType\"], label);\n\t\trequireNonEmptyString(content.data, `${label}.data`);\n\t\trequireNonEmptyString(content.mimeType, `${label}.mimeType`);\n\t\treturn content as unknown as ToolV1Content;\n\t}\n\tthrow new Error(`${label}.type must be 'text' or 'image'`);\n}\n\nexport const TOOL_V1_ABI: EvoAbiDefinition<ToolV1Input, ToolV1Output, Record<string, never>> = {\n\tid: \"tool/v1\",\n\tsurface: \"tool\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [\"exec\", \"http-fetch\", \"infer\", \"list-dir\", \"read-file\", \"write-file\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"tool/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"tool/v1 input\"), \"tool/v1 input\");\n\t\trejectUnknownKeys(input, [\"params\"], \"tool/v1 input\");\n\t\tasRecord(input.params, \"tool/v1 input.params\");\n\t\treturn input as unknown as ToolV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"tool/v1 output\"), \"tool/v1 output\");\n\t\trejectUnknownKeys(output, [\"content\", \"details\", \"addedToolNames\", \"terminate\"], \"tool/v1 output\");\n\t\tif (!Array.isArray(output.content)) throw new Error(\"tool/v1 output.content must be an array\");\n\t\toutput.content.forEach(validateToolV1Content);\n\t\tif (!Object.hasOwn(output, \"details\")) throw new Error(\"tool/v1 output.details is required\");\n\t\tjsonValue(output.details, \"tool/v1 output.details\");\n\t\tif (output.addedToolNames !== undefined) {\n\t\t\trequireStringArray(output.addedToolNames, \"tool/v1 output.addedToolNames\");\n\t\t}\n\t\tif (output.terminate !== undefined && typeof output.terminate !== \"boolean\") {\n\t\t\tthrow new Error(\"tool/v1 output.terminate must be boolean\");\n\t\t}\n\t\treturn output as unknown as ToolV1Output;\n\t},\n};\n\nexport interface MemoryV1RecallInput {\n\tmode: \"recall\";\n\tquery: string;\n}\n\nexport interface MemoryV1EncodeInput {\n\tmode: \"encode\";\n\tturnDigest: Record<string, unknown>;\n}\n\nexport interface MemoryV1ConsolidateInput {\n\tmode: \"consolidate\";\n\tcandidates: Record<string, unknown>[];\n}\n\nexport type MemoryV1Input = MemoryV1RecallInput | MemoryV1EncodeInput | MemoryV1ConsolidateInput;\n\nexport interface MemoryV1RecallOutput {\n\tmode: \"recall\";\n\tfragments: Record<string, unknown>[];\n}\n\nexport interface MemoryV1EncodeOutput {\n\tmode: \"encode\";\n\twrites: Record<string, unknown>[];\n\tupdates: Record<string, unknown>[];\n\tforgets: string[];\n}\n\nexport interface MemoryV1ConsolidateOutput {\n\tmode: \"consolidate\";\n\tmerged: Record<string, unknown>[];\n\tinsights: Record<string, unknown>[];\n\tforget: string[];\n}\n\nexport type MemoryV1Output = MemoryV1RecallOutput | MemoryV1EncodeOutput | MemoryV1ConsolidateOutput;\n\nexport const MEMORY_V1_ABI: EvoAbiDefinition<MemoryV1Input, MemoryV1Output, Record<string, never>> = {\n\tid: \"memory/v1\",\n\tsurface: \"memory\",\n\tactivationBoundary: \"session\",\n\tcapabilityCeiling: [\"infer\", \"memory-read\", \"memory-write\", \"retrieve\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"memory/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"memory/v1 input\"), \"memory/v1 input\");\n\t\tif (input.mode === \"recall\") {\n\t\t\trejectUnknownKeys(input, [\"mode\", \"query\"], \"memory/v1 recall input\");\n\t\t\trequireNonEmptyString(input.query, \"memory/v1 recall input.query\");\n\t\t\treturn input as unknown as MemoryV1RecallInput;\n\t\t}\n\t\tif (input.mode === \"encode\") {\n\t\t\trejectUnknownKeys(input, [\"mode\", \"turnDigest\"], \"memory/v1 encode input\");\n\t\t\tasRecord(input.turnDigest, \"memory/v1 encode input.turnDigest\");\n\t\t\treturn input as unknown as MemoryV1EncodeInput;\n\t\t}\n\t\tif (input.mode === \"consolidate\") {\n\t\t\trejectUnknownKeys(input, [\"mode\", \"candidates\"], \"memory/v1 consolidate input\");\n\t\t\trequireJsonRecordArray(input.candidates, \"memory/v1 consolidate input.candidates\");\n\t\t\treturn input as unknown as MemoryV1ConsolidateInput;\n\t\t}\n\t\tthrow new Error(\"memory/v1 input.mode must be 'recall', 'encode', or 'consolidate'\");\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"memory/v1 output\"), \"memory/v1 output\");\n\t\tif (output.mode === \"recall\") {\n\t\t\trejectUnknownKeys(output, [\"mode\", \"fragments\"], \"memory/v1 recall output\");\n\t\t\trequireJsonRecordArray(output.fragments, \"memory/v1 recall output.fragments\");\n\t\t\treturn output as unknown as MemoryV1RecallOutput;\n\t\t}\n\t\tif (output.mode === \"encode\") {\n\t\t\trejectUnknownKeys(output, [\"mode\", \"writes\", \"updates\", \"forgets\"], \"memory/v1 encode output\");\n\t\t\trequireJsonRecordArray(output.writes, \"memory/v1 encode output.writes\");\n\t\t\trequireJsonRecordArray(output.updates, \"memory/v1 encode output.updates\");\n\t\t\trequireStringArray(output.forgets, \"memory/v1 encode output.forgets\");\n\t\t\treturn output as unknown as MemoryV1EncodeOutput;\n\t\t}\n\t\tif (output.mode === \"consolidate\") {\n\t\t\trejectUnknownKeys(output, [\"mode\", \"merged\", \"insights\", \"forget\"], \"memory/v1 consolidate output\");\n\t\t\trequireJsonRecordArray(output.merged, \"memory/v1 consolidate output.merged\");\n\t\t\trequireJsonRecordArray(output.insights, \"memory/v1 consolidate output.insights\");\n\t\t\trequireStringArray(output.forget, \"memory/v1 consolidate output.forget\");\n\t\t\treturn output as unknown as MemoryV1ConsolidateOutput;\n\t\t}\n\t\tthrow new Error(\"memory/v1 output.mode must be 'recall', 'encode', or 'consolidate'\");\n\t},\n};\n\nexport interface WorkflowV1Host {\n\t/** Default provider/model route for spawned child agents. */\n\tmodel?: string;\n\t/** Tool names the spawn-agent grant allows. */\n\ttools?: string[];\n\t/** Per-call output token ceiling from the spawn-agent grant. */\n\tmaxOutputTokensPerCall?: number;\n}\n\nexport interface WorkflowV1Input {\n\ttrigger: string;\n\targs: Record<string, unknown>;\n\thost?: WorkflowV1Host;\n}\n\nexport interface WorkflowV1Output {\n\tresult: unknown;\n}\n\nexport const WORKFLOW_V1_ABI: EvoAbiDefinition<WorkflowV1Input, WorkflowV1Output, Record<string, never>> = {\n\tid: \"workflow/v1\",\n\tsurface: \"workflow\",\n\tactivationBoundary: \"invocation\",\n\tcapabilityCeiling: [\"memory-read\", \"memory-write\", \"spawn-agent\"],\n\tvalidateConfig(value) {\n\t\treturn validateEmptyConfig(value, \"workflow/v1 config\");\n\t},\n\tvalidateInput(value) {\n\t\tconst input = asRecord(jsonValue(value, \"workflow/v1 input\"), \"workflow/v1 input\");\n\t\trejectUnknownKeys(input, [\"trigger\", \"args\", \"host\"], \"workflow/v1 input\");\n\t\trequireNonEmptyString(input.trigger, \"workflow/v1 input.trigger\");\n\t\tasRecord(input.args, \"workflow/v1 input.args\");\n\t\tif (input.host !== undefined) {\n\t\t\tconst host = asRecord(input.host, \"workflow/v1 input.host\");\n\t\t\trejectUnknownKeys(host, [\"model\", \"tools\", \"maxOutputTokensPerCall\"], \"workflow/v1 input.host\");\n\t\t\tif (host.model !== undefined) requireNonEmptyString(host.model, \"workflow/v1 input.host.model\");\n\t\t\tif (host.tools !== undefined) requireStringArray(host.tools, \"workflow/v1 input.host.tools\");\n\t\t\tif (host.maxOutputTokensPerCall !== undefined) {\n\t\t\t\tif (!Number.isSafeInteger(host.maxOutputTokensPerCall) || (host.maxOutputTokensPerCall as number) <= 0) {\n\t\t\t\t\tthrow new Error(\"workflow/v1 input.host.maxOutputTokensPerCall must be a positive safe integer\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn input as unknown as WorkflowV1Input;\n\t},\n\tvalidateOutput(value) {\n\t\tconst output = asRecord(jsonValue(value, \"workflow/v1 output\"), \"workflow/v1 output\");\n\t\trejectUnknownKeys(output, [\"result\"], \"workflow/v1 output\");\n\t\tif (!Object.hasOwn(output, \"result\")) throw new Error(\"workflow/v1 output.result is required\");\n\t\treturn { result: jsonValue(output.result, \"workflow/v1 output.result\") };\n\t},\n};\n\nexport function createDefaultEvoAbiRegistry(): EvoAbiRegistry {\n\tconst registry = new EvoAbiRegistry();\n\tregistry.register(COMPACTION_V1_ABI);\n\tregistry.register(CONTEXT_V1_ABI);\n\tregistry.register(GUARD_V1_ABI);\n\tregistry.register(INSTRUCTIONS_V1_ABI);\n\tregistry.register(GENERATION_V1_ABI);\n\tregistry.register(CONTROL_V1_ABI);\n\tregistry.register(TOOL_V1_ABI);\n\tregistry.register(MEMORY_V1_ABI);\n\tregistry.register(WORKFLOW_V1_ABI);\n\treturn registry;\n}\n"]}