@copilotkit/runtime 2.0.0-rc.2 → 2.0.0-rc.4

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.
Files changed (95) hide show
  1. package/dist/agent/index.cjs +14 -14
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts.map +1 -1
  4. package/dist/agent/index.d.mts.map +1 -1
  5. package/dist/agent/index.mjs +15 -15
  6. package/dist/agent/index.mjs.map +1 -1
  7. package/dist/agent/url-download.cjs +10 -11
  8. package/dist/agent/url-download.cjs.map +1 -1
  9. package/dist/agent/url-download.d.cts.map +1 -1
  10. package/dist/agent/url-download.d.mts.map +1 -1
  11. package/dist/agent/url-download.mjs +10 -11
  12. package/dist/agent/url-download.mjs.map +1 -1
  13. package/dist/runtime/core/channel-manager.cjs +4 -4
  14. package/dist/runtime/core/channel-manager.cjs.map +1 -1
  15. package/dist/runtime/core/channel-manager.mjs +4 -4
  16. package/dist/runtime/core/channel-manager.mjs.map +1 -1
  17. package/dist/runtime/core/debug-event-bus.cjs +3 -1
  18. package/dist/runtime/core/debug-event-bus.cjs.map +1 -1
  19. package/dist/runtime/core/debug-event-bus.d.cts.map +1 -1
  20. package/dist/runtime/core/debug-event-bus.d.mts.map +1 -1
  21. package/dist/runtime/core/debug-event-bus.mjs +3 -1
  22. package/dist/runtime/core/debug-event-bus.mjs.map +1 -1
  23. package/dist/runtime/core/logger.cjs +2 -1
  24. package/dist/runtime/core/logger.cjs.map +1 -1
  25. package/dist/runtime/core/logger.d.cts.map +1 -1
  26. package/dist/runtime/core/logger.d.mts.map +1 -1
  27. package/dist/runtime/core/logger.mjs +2 -1
  28. package/dist/runtime/core/logger.mjs.map +1 -1
  29. package/dist/runtime/core/package-info.cjs +1 -1
  30. package/dist/runtime/core/package-info.mjs +1 -1
  31. package/dist/runtime/core/runtime.cjs +19 -5
  32. package/dist/runtime/core/runtime.cjs.map +1 -1
  33. package/dist/runtime/core/runtime.d.cts +19 -3
  34. package/dist/runtime/core/runtime.d.cts.map +1 -1
  35. package/dist/runtime/core/runtime.d.mts +19 -3
  36. package/dist/runtime/core/runtime.d.mts.map +1 -1
  37. package/dist/runtime/core/runtime.mjs +20 -6
  38. package/dist/runtime/core/runtime.mjs.map +1 -1
  39. package/dist/runtime/core/web-crypto.cjs +22 -0
  40. package/dist/runtime/core/web-crypto.cjs.map +1 -0
  41. package/dist/runtime/core/web-crypto.mjs +20 -0
  42. package/dist/runtime/core/web-crypto.mjs.map +1 -0
  43. package/dist/runtime/handlers/get-runtime-info.cjs +7 -6
  44. package/dist/runtime/handlers/get-runtime-info.cjs.map +1 -1
  45. package/dist/runtime/handlers/get-runtime-info.mjs +7 -6
  46. package/dist/runtime/handlers/get-runtime-info.mjs.map +1 -1
  47. package/dist/runtime/handlers/intelligence/thread-names.cjs +3 -4
  48. package/dist/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
  49. package/dist/runtime/handlers/intelligence/thread-names.mjs +3 -4
  50. package/dist/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
  51. package/dist/runtime/handlers/shared/agent-utils.cjs +1 -1
  52. package/dist/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  53. package/dist/runtime/handlers/shared/agent-utils.mjs +2 -2
  54. package/dist/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  55. package/dist/runtime/intelligence-platform/client.cjs +1 -2
  56. package/dist/runtime/intelligence-platform/client.cjs.map +1 -1
  57. package/dist/runtime/intelligence-platform/client.d.cts.map +1 -1
  58. package/dist/runtime/intelligence-platform/client.d.mts.map +1 -1
  59. package/dist/runtime/intelligence-platform/client.mjs +1 -2
  60. package/dist/runtime/intelligence-platform/client.mjs.map +1 -1
  61. package/dist/runtime/intelligence-platform/skill-registry/config.cjs +3 -1
  62. package/dist/runtime/intelligence-platform/skill-registry/config.cjs.map +1 -1
  63. package/dist/runtime/intelligence-platform/skill-registry/config.d.cts.map +1 -1
  64. package/dist/runtime/intelligence-platform/skill-registry/config.d.mts.map +1 -1
  65. package/dist/runtime/intelligence-platform/skill-registry/config.mjs +2 -1
  66. package/dist/runtime/intelligence-platform/skill-registry/config.mjs.map +1 -1
  67. package/dist/runtime/intelligence-platform/skill-registry/registry.cjs +4 -5
  68. package/dist/runtime/intelligence-platform/skill-registry/registry.cjs.map +1 -1
  69. package/dist/runtime/intelligence-platform/skill-registry/registry.d.cts.map +1 -1
  70. package/dist/runtime/intelligence-platform/skill-registry/registry.d.mts.map +1 -1
  71. package/dist/runtime/intelligence-platform/skill-registry/registry.mjs +4 -4
  72. package/dist/runtime/intelligence-platform/skill-registry/registry.mjs.map +1 -1
  73. package/dist/runtime/intelligence-platform/skill-registry/snapshot.cjs +3 -7
  74. package/dist/runtime/intelligence-platform/skill-registry/snapshot.cjs.map +1 -1
  75. package/dist/runtime/intelligence-platform/skill-registry/snapshot.d.cts.map +1 -1
  76. package/dist/runtime/intelligence-platform/skill-registry/snapshot.d.mts.map +1 -1
  77. package/dist/runtime/intelligence-platform/skill-registry/snapshot.mjs +3 -6
  78. package/dist/runtime/intelligence-platform/skill-registry/snapshot.mjs.map +1 -1
  79. package/dist/runtime/runner/intelligence.cjs +1 -2
  80. package/dist/runtime/runner/intelligence.cjs.map +1 -1
  81. package/dist/runtime/runner/intelligence.d.cts.map +1 -1
  82. package/dist/runtime/runner/intelligence.d.mts.map +1 -1
  83. package/dist/runtime/runner/intelligence.mjs +1 -2
  84. package/dist/runtime/runner/intelligence.mjs.map +1 -1
  85. package/dist/runtime/telemetry/disclosure.cjs +3 -1
  86. package/dist/runtime/telemetry/disclosure.cjs.map +1 -1
  87. package/dist/runtime/telemetry/disclosure.mjs +3 -1
  88. package/dist/runtime/telemetry/disclosure.mjs.map +1 -1
  89. package/dist/runtime/telemetry/telemetry-client.cjs +2 -2
  90. package/dist/runtime/telemetry/telemetry-client.cjs.map +1 -1
  91. package/dist/runtime/telemetry/telemetry-client.d.cts.map +1 -1
  92. package/dist/runtime/telemetry/telemetry-client.d.mts.map +1 -1
  93. package/dist/runtime/telemetry/telemetry-client.mjs +3 -3
  94. package/dist/runtime/telemetry/telemetry-client.mjs.map +1 -1
  95. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs","names":["SkillDeliveryError","CopilotKitIntelligence"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"sourcesContent":["import { CopilotKitIntelligence } from \"../client\";\nimport { SkillDeliveryError } from \"./errors\";\n\nexport interface SkillRegistryCommonOptions {\n client?: CopilotKitIntelligence;\n apiKey?: string;\n apiUrl?: string;\n freshnessWindowMs?: number;\n requestTimeoutMs?: number;\n debug?: boolean;\n}\n/** One published container and an optional exact revision pin. */\nexport interface SkillRegistryContainer {\n readonly id: string;\n readonly revision?: string;\n}\n\n/** Legacy selection and explicit multi-container selection cannot be combined. */\nexport type SkillRegistryOptions = SkillRegistryCommonOptions &\n (\n | { containerId?: string; revision?: string; containers?: never }\n | {\n containers: readonly SkillRegistryContainer[];\n containerId?: never;\n revision?: never;\n }\n );\n\ninterface RegistryCommonConfig {\n readonly client: CopilotKitIntelligence;\n readonly freshnessWindowMs: number;\n readonly requestTimeoutMs: number;\n readonly debug: boolean;\n}\n\nexport type SingleContainerConfig = RegistryCommonConfig & {\n readonly containerId: string;\n readonly revision?: string;\n readonly containers?: never;\n};\n\nexport type RegistryConfig =\n | SingleContainerConfig\n | (RegistryCommonConfig & {\n readonly containers: readonly SkillRegistryContainer[];\n readonly containerId?: never;\n readonly revision?: never;\n });\n\n/** Resolve once. Never retain the options object, environment, or a second key. */\nexport function resolveRegistryConfig(\n options: SkillRegistryOptions = {},\n environment: NodeJS.ProcessEnv = process.env,\n): RegistryConfig {\n try {\n const multiple = options.containers !== undefined;\n if (\n multiple &&\n (options.containerId !== undefined || options.revision !== undefined)\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const containerId = multiple\n ? undefined\n : (options.containerId ??\n environment.CPK_INTELLIGENCE_LEARNING_CONTAINER_ID);\n const revision = multiple\n ? undefined\n : (options.revision ?? environment.CPK_INTELLIGENCE_SKILLS_REVISION);\n let containers: readonly SkillRegistryContainer[] | undefined;\n if (multiple) {\n if (\n !Array.isArray(options.containers) ||\n options.containers.length === 0 ||\n options.containers.length > 50\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const seen = new Set<string>();\n containers = Object.freeze(\n options.containers.map((source) => {\n if (\n !source ||\n typeof source.id !== \"string\" ||\n !source.id.trim() ||\n // Reject control characters in caller-provided container IDs.\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u001f\\u007f]/.test(source.id) ||\n seen.has(source.id) ||\n (source.revision !== undefined &&\n (typeof source.revision !== \"string\" || !source.revision.trim()))\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n // Reject malformed Unicode before constructing a qualified tool name.\n encodeURIComponent(source.id);\n seen.add(source.id);\n return Object.freeze({\n id: source.id,\n ...(source.revision !== undefined\n ? { revision: source.revision }\n : {}),\n });\n }),\n );\n }\n const freshnessWindowMs = options.freshnessWindowMs ?? 5_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n const debug = options.debug ?? false;\n if (\n (!multiple && (typeof containerId !== \"string\" || !containerId.trim())) ||\n (revision !== undefined &&\n (typeof revision !== \"string\" || revision.length === 0)) ||\n !Number.isSafeInteger(freshnessWindowMs) ||\n freshnessWindowMs < 0 ||\n !Number.isSafeInteger(requestTimeoutMs) ||\n requestTimeoutMs < 1 ||\n requestTimeoutMs > 2_147_483_647 ||\n typeof debug !== \"boolean\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n let client = options.client;\n if (client !== undefined) {\n if (\n !client ||\n typeof (multiple\n ? client.getLearnedSkillsSnapshots\n : client.getLearnedSkillsSnapshot) !== \"function\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n } else {\n const apiKey = options.apiKey ?? environment.CPK_INTELLIGENCE_API_KEY;\n const apiUrl = options.apiUrl ?? environment.INTELLIGENCE_API_URL;\n if (typeof apiKey !== \"string\" || !apiKey.trim())\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n if (apiUrl?.trim()) {\n const url = new URL(apiUrl);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n client = new CopilotKitIntelligence({\n apiKey,\n ...(apiUrl !== undefined ? { apiUrl } : {}),\n // This private helper client uses REST only. Explicitly retain the\n // canonical websocket default to prevent an irrelevant host warning.\n ...(apiUrl?.trim()\n ? { wsUrl: \"wss://realtime.intelligence.copilotkit.ai\" }\n : {}),\n });\n }\n return Object.freeze({\n client,\n ...(containers\n ? { containers }\n : {\n containerId: containerId!,\n ...(revision !== undefined ? { revision } : {}),\n }),\n freshnessWindowMs,\n requestTimeoutMs,\n debug,\n });\n } catch (error) {\n if (error instanceof SkillDeliveryError) throw error;\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false, error);\n }\n}\n"],"mappings":";;;;;AAkDA,SAAgB,sBACd,UAAgC,EAAE,EAClC,cAAiC,QAAQ,KACzB;AAChB,KAAI;EACF,MAAM,WAAW,QAAQ,eAAe;AACxC,MACE,aACC,QAAQ,gBAAgB,UAAa,QAAQ,aAAa,QAE3D,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;EAEvD,MAAM,cAAc,WAChB,SACC,QAAQ,eACT,YAAY;EAChB,MAAM,WAAW,WACb,SACC,QAAQ,YAAY,YAAY;EACrC,IAAI;AACJ,MAAI,UAAU;AACZ,OACE,CAAC,MAAM,QAAQ,QAAQ,WAAW,IAClC,QAAQ,WAAW,WAAW,KAC9B,QAAQ,WAAW,SAAS,GAE5B,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;GAEvD,MAAM,uBAAO,IAAI,KAAa;AAC9B,gBAAa,OAAO,OAClB,QAAQ,WAAW,KAAK,WAAW;AACjC,QACE,CAAC,UACD,OAAO,OAAO,OAAO,YACrB,CAAC,OAAO,GAAG,MAAM,IAGjB,wBAAwB,KAAK,OAAO,GAAG,IACvC,KAAK,IAAI,OAAO,GAAG,IAClB,OAAO,aAAa,WAClB,OAAO,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,MAAM,EAEjE,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;AAGvD,uBAAmB,OAAO,GAAG;AAC7B,SAAK,IAAI,OAAO,GAAG;AACnB,WAAO,OAAO,OAAO;KACnB,IAAI,OAAO;KACX,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,UAAU,GAC7B,EAAE;KACP,CAAC;KACF,CACH;;EAEH,MAAM,oBAAoB,QAAQ,qBAAqB;EACvD,MAAM,mBAAmB,QAAQ,oBAAoB;EACrD,MAAM,QAAQ,QAAQ,SAAS;AAC/B,MACG,CAAC,aAAa,OAAO,gBAAgB,YAAY,CAAC,YAAY,MAAM,KACpE,aAAa,WACX,OAAO,aAAa,YAAY,SAAS,WAAW,MACvD,CAAC,OAAO,cAAc,kBAAkB,IACxC,oBAAoB,KACpB,CAAC,OAAO,cAAc,iBAAiB,IACvC,mBAAmB,KACnB,mBAAmB,cACnB,OAAO,UAAU,UAEjB,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;EACvD,IAAI,SAAS,QAAQ;AACrB,MAAI,WAAW,QACb;OACE,CAAC,UACD,QAAQ,WACJ,OAAO,4BACP,OAAO,8BAA8B,WAEzC,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;SAClD;GACL,MAAM,SAAS,QAAQ,UAAU,YAAY;GAC7C,MAAM,SAAS,QAAQ,UAAU,YAAY;AAC7C,OAAI,OAAO,WAAW,YAAY,CAAC,OAAO,MAAM,CAC9C,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;AACvD,OAAI,QAAQ,MAAM,EAAE;IAClB,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QACE,CAAC,CAAC,SAAS,SAAS,CAAC,SAAS,IAAI,SAAS,IAC3C,IAAI,YACJ,IAAI,YACJ,IAAI,UACJ,IAAI,KAEJ,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;;AAEzD,YAAS,IAAIC,sCAAuB;IAClC;IACA,GAAI,WAAW,SAAY,EAAE,QAAQ,GAAG,EAAE;IAG1C,GAAI,QAAQ,MAAM,GACd,EAAE,OAAO,6CAA6C,GACtD,EAAE;IACP,CAAC;;AAEJ,SAAO,OAAO,OAAO;GACnB;GACA,GAAI,aACA,EAAE,YAAY,GACd;IACe;IACb,GAAI,aAAa,SAAY,EAAE,UAAU,GAAG,EAAE;IAC/C;GACL;GACA;GACA;GACD,CAAC;UACK,OAAO;AACd,MAAI,iBAAiBD,0CAAoB,OAAM;AAC/C,QAAM,IAAIA,0CAAmB,kBAAkB,OAAO,MAAM"}
1
+ {"version":3,"file":"config.cjs","names":["SkillDeliveryError","CopilotKitIntelligence"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"sourcesContent":["import { processEnv } from \"@copilotkit/shared\";\nimport { CopilotKitIntelligence } from \"../client\";\nimport { SkillDeliveryError } from \"./errors\";\n\nexport interface SkillRegistryCommonOptions {\n client?: CopilotKitIntelligence;\n apiKey?: string;\n apiUrl?: string;\n freshnessWindowMs?: number;\n requestTimeoutMs?: number;\n debug?: boolean;\n}\n/** One published container and an optional exact revision pin. */\nexport interface SkillRegistryContainer {\n readonly id: string;\n readonly revision?: string;\n}\n\n/** Legacy selection and explicit multi-container selection cannot be combined. */\nexport type SkillRegistryOptions = SkillRegistryCommonOptions &\n (\n | { containerId?: string; revision?: string; containers?: never }\n | {\n containers: readonly SkillRegistryContainer[];\n containerId?: never;\n revision?: never;\n }\n );\n\ninterface RegistryCommonConfig {\n readonly client: CopilotKitIntelligence;\n readonly freshnessWindowMs: number;\n readonly requestTimeoutMs: number;\n readonly debug: boolean;\n}\n\nexport type SingleContainerConfig = RegistryCommonConfig & {\n readonly containerId: string;\n readonly revision?: string;\n readonly containers?: never;\n};\n\nexport type RegistryConfig =\n | SingleContainerConfig\n | (RegistryCommonConfig & {\n readonly containers: readonly SkillRegistryContainer[];\n readonly containerId?: never;\n readonly revision?: never;\n });\n\n/** Resolve once. Never retain the options object, environment, or a second key. */\nexport function resolveRegistryConfig(\n options: SkillRegistryOptions = {},\n environment: NodeJS.ProcessEnv = processEnv(),\n): RegistryConfig {\n try {\n const multiple = options.containers !== undefined;\n if (\n multiple &&\n (options.containerId !== undefined || options.revision !== undefined)\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const containerId = multiple\n ? undefined\n : (options.containerId ??\n environment.CPK_INTELLIGENCE_LEARNING_CONTAINER_ID);\n const revision = multiple\n ? undefined\n : (options.revision ?? environment.CPK_INTELLIGENCE_SKILLS_REVISION);\n let containers: readonly SkillRegistryContainer[] | undefined;\n if (multiple) {\n if (\n !Array.isArray(options.containers) ||\n options.containers.length === 0 ||\n options.containers.length > 50\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const seen = new Set<string>();\n containers = Object.freeze(\n options.containers.map((source) => {\n if (\n !source ||\n typeof source.id !== \"string\" ||\n !source.id.trim() ||\n // Reject control characters in caller-provided container IDs.\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u001f\\u007f]/.test(source.id) ||\n seen.has(source.id) ||\n (source.revision !== undefined &&\n (typeof source.revision !== \"string\" || !source.revision.trim()))\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n // Reject malformed Unicode before constructing a qualified tool name.\n encodeURIComponent(source.id);\n seen.add(source.id);\n return Object.freeze({\n id: source.id,\n ...(source.revision !== undefined\n ? { revision: source.revision }\n : {}),\n });\n }),\n );\n }\n const freshnessWindowMs = options.freshnessWindowMs ?? 5_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n const debug = options.debug ?? false;\n if (\n (!multiple && (typeof containerId !== \"string\" || !containerId.trim())) ||\n (revision !== undefined &&\n (typeof revision !== \"string\" || revision.length === 0)) ||\n !Number.isSafeInteger(freshnessWindowMs) ||\n freshnessWindowMs < 0 ||\n !Number.isSafeInteger(requestTimeoutMs) ||\n requestTimeoutMs < 1 ||\n requestTimeoutMs > 2_147_483_647 ||\n typeof debug !== \"boolean\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n let client = options.client;\n if (client !== undefined) {\n if (\n !client ||\n typeof (multiple\n ? client.getLearnedSkillsSnapshots\n : client.getLearnedSkillsSnapshot) !== \"function\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n } else {\n const apiKey = options.apiKey ?? environment.CPK_INTELLIGENCE_API_KEY;\n const apiUrl = options.apiUrl ?? environment.INTELLIGENCE_API_URL;\n if (typeof apiKey !== \"string\" || !apiKey.trim())\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n if (apiUrl?.trim()) {\n const url = new URL(apiUrl);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n client = new CopilotKitIntelligence({\n apiKey,\n ...(apiUrl !== undefined ? { apiUrl } : {}),\n // This private helper client uses REST only. Explicitly retain the\n // canonical websocket default to prevent an irrelevant host warning.\n ...(apiUrl?.trim()\n ? { wsUrl: \"wss://realtime.intelligence.copilotkit.ai\" }\n : {}),\n });\n }\n return Object.freeze({\n client,\n ...(containers\n ? { containers }\n : {\n containerId: containerId!,\n ...(revision !== undefined ? { revision } : {}),\n }),\n freshnessWindowMs,\n requestTimeoutMs,\n debug,\n });\n } catch (error) {\n if (error instanceof SkillDeliveryError) throw error;\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false, error);\n }\n}\n"],"mappings":";;;;;;;AAmDA,SAAgB,sBACd,UAAgC,EAAE,EAClC,kDAA6C,EAC7B;AAChB,KAAI;EACF,MAAM,WAAW,QAAQ,eAAe;AACxC,MACE,aACC,QAAQ,gBAAgB,UAAa,QAAQ,aAAa,QAE3D,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;EAEvD,MAAM,cAAc,WAChB,SACC,QAAQ,eACT,YAAY;EAChB,MAAM,WAAW,WACb,SACC,QAAQ,YAAY,YAAY;EACrC,IAAI;AACJ,MAAI,UAAU;AACZ,OACE,CAAC,MAAM,QAAQ,QAAQ,WAAW,IAClC,QAAQ,WAAW,WAAW,KAC9B,QAAQ,WAAW,SAAS,GAE5B,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;GAEvD,MAAM,uBAAO,IAAI,KAAa;AAC9B,gBAAa,OAAO,OAClB,QAAQ,WAAW,KAAK,WAAW;AACjC,QACE,CAAC,UACD,OAAO,OAAO,OAAO,YACrB,CAAC,OAAO,GAAG,MAAM,IAGjB,wBAAwB,KAAK,OAAO,GAAG,IACvC,KAAK,IAAI,OAAO,GAAG,IAClB,OAAO,aAAa,WAClB,OAAO,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,MAAM,EAEjE,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;AAGvD,uBAAmB,OAAO,GAAG;AAC7B,SAAK,IAAI,OAAO,GAAG;AACnB,WAAO,OAAO,OAAO;KACnB,IAAI,OAAO;KACX,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,UAAU,GAC7B,EAAE;KACP,CAAC;KACF,CACH;;EAEH,MAAM,oBAAoB,QAAQ,qBAAqB;EACvD,MAAM,mBAAmB,QAAQ,oBAAoB;EACrD,MAAM,QAAQ,QAAQ,SAAS;AAC/B,MACG,CAAC,aAAa,OAAO,gBAAgB,YAAY,CAAC,YAAY,MAAM,KACpE,aAAa,WACX,OAAO,aAAa,YAAY,SAAS,WAAW,MACvD,CAAC,OAAO,cAAc,kBAAkB,IACxC,oBAAoB,KACpB,CAAC,OAAO,cAAc,iBAAiB,IACvC,mBAAmB,KACnB,mBAAmB,cACnB,OAAO,UAAU,UAEjB,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;EACvD,IAAI,SAAS,QAAQ;AACrB,MAAI,WAAW,QACb;OACE,CAAC,UACD,QAAQ,WACJ,OAAO,4BACP,OAAO,8BAA8B,WAEzC,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;SAClD;GACL,MAAM,SAAS,QAAQ,UAAU,YAAY;GAC7C,MAAM,SAAS,QAAQ,UAAU,YAAY;AAC7C,OAAI,OAAO,WAAW,YAAY,CAAC,OAAO,MAAM,CAC9C,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;AACvD,OAAI,QAAQ,MAAM,EAAE;IAClB,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QACE,CAAC,CAAC,SAAS,SAAS,CAAC,SAAS,IAAI,SAAS,IAC3C,IAAI,YACJ,IAAI,YACJ,IAAI,UACJ,IAAI,KAEJ,OAAM,IAAIA,0CAAmB,kBAAkB,MAAM;;AAEzD,YAAS,IAAIC,sCAAuB;IAClC;IACA,GAAI,WAAW,SAAY,EAAE,QAAQ,GAAG,EAAE;IAG1C,GAAI,QAAQ,MAAM,GACd,EAAE,OAAO,6CAA6C,GACtD,EAAE;IACP,CAAC;;AAEJ,SAAO,OAAO,OAAO;GACnB;GACA,GAAI,aACA,EAAE,YAAY,GACd;IACe;IACb,GAAI,aAAa,SAAY,EAAE,UAAU,GAAG,EAAE;IAC/C;GACL;GACA;GACA;GACD,CAAC;UACK,OAAO;AACd,MAAI,iBAAiBD,0CAAoB,OAAM;AAC/C,QAAM,IAAIA,0CAAmB,kBAAkB,OAAO,MAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"mappings":";;;UAGiB,0BAAA;EACf,MAAA,GAAS,sBAAA;EACT,MAAA;EACA,MAAA;EACA,iBAAA;EACA,gBAAA;EACA,KAAA;AAAA;;UAGe,sBAAA;EAAA,SACN,EAAA;EAAA,SACA,QAAA;AAAA;;KAIC,oBAAA,GAAuB,0BAAA;EAE3B,WAAA;EAAsB,QAAA;EAAmB,UAAA;AAAA;EAEzC,UAAA,WAAqB,sBAAA;EACrB,WAAA;EACA,QAAA;AAAA;AAAA,UAIE,oBAAA;EAAA,SACC,MAAA,EAAQ,sBAAA;EAAA,SACR,iBAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,oBAAA;EAAA,SACzB,WAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,cAAA,GACR,qBAAA,IACC,oBAAA;EAAA,SACU,UAAA,WAAqB,sBAAA;EAAA,SACrB,WAAA;EAAA,SACA,QAAA;AAAA;;iBAIC,qBAAA,CACd,OAAA,GAAS,oBAAA,EACT,WAAA,GAAa,MAAA,CAAO,UAAA,GACnB,cAAA"}
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"mappings":";;;UAIiB,0BAAA;EACf,MAAA,GAAS,sBAAA;EACT,MAAA;EACA,MAAA;EACA,iBAAA;EACA,gBAAA;EACA,KAAA;AAAA;;UAGe,sBAAA;EAAA,SACN,EAAA;EAAA,SACA,QAAA;AAAA;;KAIC,oBAAA,GAAuB,0BAAA;EAE3B,WAAA;EAAsB,QAAA;EAAmB,UAAA;AAAA;EAEzC,UAAA,WAAqB,sBAAA;EACrB,WAAA;EACA,QAAA;AAAA;AAAA,UAIE,oBAAA;EAAA,SACC,MAAA,EAAQ,sBAAA;EAAA,SACR,iBAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,oBAAA;EAAA,SACzB,WAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,cAAA,GACR,qBAAA,IACC,oBAAA;EAAA,SACU,UAAA,WAAqB,sBAAA;EAAA,SACrB,WAAA;EAAA,SACA,QAAA;AAAA;;iBAIC,qBAAA,CACd,OAAA,GAAS,oBAAA,EACT,WAAA,GAAa,MAAA,CAAO,UAAA,GACnB,cAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"mappings":";;;UAGiB,0BAAA;EACf,MAAA,GAAS,sBAAA;EACT,MAAA;EACA,MAAA;EACA,iBAAA;EACA,gBAAA;EACA,KAAA;AAAA;;UAGe,sBAAA;EAAA,SACN,EAAA;EAAA,SACA,QAAA;AAAA;;KAIC,oBAAA,GAAuB,0BAAA;EAE3B,WAAA;EAAsB,QAAA;EAAmB,UAAA;AAAA;EAEzC,UAAA,WAAqB,sBAAA;EACrB,WAAA;EACA,QAAA;AAAA;AAAA,UAIE,oBAAA;EAAA,SACC,MAAA,EAAQ,sBAAA;EAAA,SACR,iBAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,oBAAA;EAAA,SACzB,WAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,cAAA,GACR,qBAAA,IACC,oBAAA;EAAA,SACU,UAAA,WAAqB,sBAAA;EAAA,SACrB,WAAA;EAAA,SACA,QAAA;AAAA;;iBAIC,qBAAA,CACd,OAAA,GAAS,oBAAA,EACT,WAAA,GAAa,MAAA,CAAO,UAAA,GACnB,cAAA"}
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"mappings":";;;UAIiB,0BAAA;EACf,MAAA,GAAS,sBAAA;EACT,MAAA;EACA,MAAA;EACA,iBAAA;EACA,gBAAA;EACA,KAAA;AAAA;;UAGe,sBAAA;EAAA,SACN,EAAA;EAAA,SACA,QAAA;AAAA;;KAIC,oBAAA,GAAuB,0BAAA;EAE3B,WAAA;EAAsB,QAAA;EAAmB,UAAA;AAAA;EAEzC,UAAA,WAAqB,sBAAA;EACrB,WAAA;EACA,QAAA;AAAA;AAAA,UAIE,oBAAA;EAAA,SACC,MAAA,EAAQ,sBAAA;EAAA,SACR,iBAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA,GAAwB,oBAAA;EAAA,SACzB,WAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;AAAA;AAAA,KAGC,cAAA,GACR,qBAAA,IACC,oBAAA;EAAA,SACU,UAAA,WAAqB,sBAAA;EAAA,SACrB,WAAA;EAAA,SACA,QAAA;AAAA;;iBAIC,qBAAA,CACd,OAAA,GAAS,oBAAA,EACT,WAAA,GAAa,MAAA,CAAO,UAAA,GACnB,cAAA"}
@@ -1,9 +1,10 @@
1
1
  import { LearnedSkillsError } from "../learned-skills.mjs";
2
2
  import { CopilotKitIntelligence } from "../client.mjs";
3
+ import { processEnv } from "@copilotkit/shared";
3
4
 
4
5
  //#region src/runtime/intelligence-platform/skill-registry/config.ts
5
6
  /** Resolve once. Never retain the options object, environment, or a second key. */
6
- function resolveRegistryConfig(options = {}, environment = process.env) {
7
+ function resolveRegistryConfig(options = {}, environment = processEnv()) {
7
8
  try {
8
9
  const multiple = options.containers !== void 0;
9
10
  if (multiple && (options.containerId !== void 0 || options.revision !== void 0)) throw new LearnedSkillsError("INVALID_CONFIG", false);
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":["SkillDeliveryError"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"sourcesContent":["import { CopilotKitIntelligence } from \"../client\";\nimport { SkillDeliveryError } from \"./errors\";\n\nexport interface SkillRegistryCommonOptions {\n client?: CopilotKitIntelligence;\n apiKey?: string;\n apiUrl?: string;\n freshnessWindowMs?: number;\n requestTimeoutMs?: number;\n debug?: boolean;\n}\n/** One published container and an optional exact revision pin. */\nexport interface SkillRegistryContainer {\n readonly id: string;\n readonly revision?: string;\n}\n\n/** Legacy selection and explicit multi-container selection cannot be combined. */\nexport type SkillRegistryOptions = SkillRegistryCommonOptions &\n (\n | { containerId?: string; revision?: string; containers?: never }\n | {\n containers: readonly SkillRegistryContainer[];\n containerId?: never;\n revision?: never;\n }\n );\n\ninterface RegistryCommonConfig {\n readonly client: CopilotKitIntelligence;\n readonly freshnessWindowMs: number;\n readonly requestTimeoutMs: number;\n readonly debug: boolean;\n}\n\nexport type SingleContainerConfig = RegistryCommonConfig & {\n readonly containerId: string;\n readonly revision?: string;\n readonly containers?: never;\n};\n\nexport type RegistryConfig =\n | SingleContainerConfig\n | (RegistryCommonConfig & {\n readonly containers: readonly SkillRegistryContainer[];\n readonly containerId?: never;\n readonly revision?: never;\n });\n\n/** Resolve once. Never retain the options object, environment, or a second key. */\nexport function resolveRegistryConfig(\n options: SkillRegistryOptions = {},\n environment: NodeJS.ProcessEnv = process.env,\n): RegistryConfig {\n try {\n const multiple = options.containers !== undefined;\n if (\n multiple &&\n (options.containerId !== undefined || options.revision !== undefined)\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const containerId = multiple\n ? undefined\n : (options.containerId ??\n environment.CPK_INTELLIGENCE_LEARNING_CONTAINER_ID);\n const revision = multiple\n ? undefined\n : (options.revision ?? environment.CPK_INTELLIGENCE_SKILLS_REVISION);\n let containers: readonly SkillRegistryContainer[] | undefined;\n if (multiple) {\n if (\n !Array.isArray(options.containers) ||\n options.containers.length === 0 ||\n options.containers.length > 50\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const seen = new Set<string>();\n containers = Object.freeze(\n options.containers.map((source) => {\n if (\n !source ||\n typeof source.id !== \"string\" ||\n !source.id.trim() ||\n // Reject control characters in caller-provided container IDs.\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u001f\\u007f]/.test(source.id) ||\n seen.has(source.id) ||\n (source.revision !== undefined &&\n (typeof source.revision !== \"string\" || !source.revision.trim()))\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n // Reject malformed Unicode before constructing a qualified tool name.\n encodeURIComponent(source.id);\n seen.add(source.id);\n return Object.freeze({\n id: source.id,\n ...(source.revision !== undefined\n ? { revision: source.revision }\n : {}),\n });\n }),\n );\n }\n const freshnessWindowMs = options.freshnessWindowMs ?? 5_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n const debug = options.debug ?? false;\n if (\n (!multiple && (typeof containerId !== \"string\" || !containerId.trim())) ||\n (revision !== undefined &&\n (typeof revision !== \"string\" || revision.length === 0)) ||\n !Number.isSafeInteger(freshnessWindowMs) ||\n freshnessWindowMs < 0 ||\n !Number.isSafeInteger(requestTimeoutMs) ||\n requestTimeoutMs < 1 ||\n requestTimeoutMs > 2_147_483_647 ||\n typeof debug !== \"boolean\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n let client = options.client;\n if (client !== undefined) {\n if (\n !client ||\n typeof (multiple\n ? client.getLearnedSkillsSnapshots\n : client.getLearnedSkillsSnapshot) !== \"function\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n } else {\n const apiKey = options.apiKey ?? environment.CPK_INTELLIGENCE_API_KEY;\n const apiUrl = options.apiUrl ?? environment.INTELLIGENCE_API_URL;\n if (typeof apiKey !== \"string\" || !apiKey.trim())\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n if (apiUrl?.trim()) {\n const url = new URL(apiUrl);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n client = new CopilotKitIntelligence({\n apiKey,\n ...(apiUrl !== undefined ? { apiUrl } : {}),\n // This private helper client uses REST only. Explicitly retain the\n // canonical websocket default to prevent an irrelevant host warning.\n ...(apiUrl?.trim()\n ? { wsUrl: \"wss://realtime.intelligence.copilotkit.ai\" }\n : {}),\n });\n }\n return Object.freeze({\n client,\n ...(containers\n ? { containers }\n : {\n containerId: containerId!,\n ...(revision !== undefined ? { revision } : {}),\n }),\n freshnessWindowMs,\n requestTimeoutMs,\n debug,\n });\n } catch (error) {\n if (error instanceof SkillDeliveryError) throw error;\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false, error);\n }\n}\n"],"mappings":";;;;;AAkDA,SAAgB,sBACd,UAAgC,EAAE,EAClC,cAAiC,QAAQ,KACzB;AAChB,KAAI;EACF,MAAM,WAAW,QAAQ,eAAe;AACxC,MACE,aACC,QAAQ,gBAAgB,UAAa,QAAQ,aAAa,QAE3D,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;EAEvD,MAAM,cAAc,WAChB,SACC,QAAQ,eACT,YAAY;EAChB,MAAM,WAAW,WACb,SACC,QAAQ,YAAY,YAAY;EACrC,IAAI;AACJ,MAAI,UAAU;AACZ,OACE,CAAC,MAAM,QAAQ,QAAQ,WAAW,IAClC,QAAQ,WAAW,WAAW,KAC9B,QAAQ,WAAW,SAAS,GAE5B,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;GAEvD,MAAM,uBAAO,IAAI,KAAa;AAC9B,gBAAa,OAAO,OAClB,QAAQ,WAAW,KAAK,WAAW;AACjC,QACE,CAAC,UACD,OAAO,OAAO,OAAO,YACrB,CAAC,OAAO,GAAG,MAAM,IAGjB,wBAAwB,KAAK,OAAO,GAAG,IACvC,KAAK,IAAI,OAAO,GAAG,IAClB,OAAO,aAAa,WAClB,OAAO,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,MAAM,EAEjE,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;AAGvD,uBAAmB,OAAO,GAAG;AAC7B,SAAK,IAAI,OAAO,GAAG;AACnB,WAAO,OAAO,OAAO;KACnB,IAAI,OAAO;KACX,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,UAAU,GAC7B,EAAE;KACP,CAAC;KACF,CACH;;EAEH,MAAM,oBAAoB,QAAQ,qBAAqB;EACvD,MAAM,mBAAmB,QAAQ,oBAAoB;EACrD,MAAM,QAAQ,QAAQ,SAAS;AAC/B,MACG,CAAC,aAAa,OAAO,gBAAgB,YAAY,CAAC,YAAY,MAAM,KACpE,aAAa,WACX,OAAO,aAAa,YAAY,SAAS,WAAW,MACvD,CAAC,OAAO,cAAc,kBAAkB,IACxC,oBAAoB,KACpB,CAAC,OAAO,cAAc,iBAAiB,IACvC,mBAAmB,KACnB,mBAAmB,cACnB,OAAO,UAAU,UAEjB,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;EACvD,IAAI,SAAS,QAAQ;AACrB,MAAI,WAAW,QACb;OACE,CAAC,UACD,QAAQ,WACJ,OAAO,4BACP,OAAO,8BAA8B,WAEzC,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;SAClD;GACL,MAAM,SAAS,QAAQ,UAAU,YAAY;GAC7C,MAAM,SAAS,QAAQ,UAAU,YAAY;AAC7C,OAAI,OAAO,WAAW,YAAY,CAAC,OAAO,MAAM,CAC9C,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;AACvD,OAAI,QAAQ,MAAM,EAAE;IAClB,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QACE,CAAC,CAAC,SAAS,SAAS,CAAC,SAAS,IAAI,SAAS,IAC3C,IAAI,YACJ,IAAI,YACJ,IAAI,UACJ,IAAI,KAEJ,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;;AAEzD,YAAS,IAAI,uBAAuB;IAClC;IACA,GAAI,WAAW,SAAY,EAAE,QAAQ,GAAG,EAAE;IAG1C,GAAI,QAAQ,MAAM,GACd,EAAE,OAAO,6CAA6C,GACtD,EAAE;IACP,CAAC;;AAEJ,SAAO,OAAO,OAAO;GACnB;GACA,GAAI,aACA,EAAE,YAAY,GACd;IACe;IACb,GAAI,aAAa,SAAY,EAAE,UAAU,GAAG,EAAE;IAC/C;GACL;GACA;GACA;GACD,CAAC;UACK,OAAO;AACd,MAAI,iBAAiBA,mBAAoB,OAAM;AAC/C,QAAM,IAAIA,mBAAmB,kBAAkB,OAAO,MAAM"}
1
+ {"version":3,"file":"config.mjs","names":["SkillDeliveryError"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/config.ts"],"sourcesContent":["import { processEnv } from \"@copilotkit/shared\";\nimport { CopilotKitIntelligence } from \"../client\";\nimport { SkillDeliveryError } from \"./errors\";\n\nexport interface SkillRegistryCommonOptions {\n client?: CopilotKitIntelligence;\n apiKey?: string;\n apiUrl?: string;\n freshnessWindowMs?: number;\n requestTimeoutMs?: number;\n debug?: boolean;\n}\n/** One published container and an optional exact revision pin. */\nexport interface SkillRegistryContainer {\n readonly id: string;\n readonly revision?: string;\n}\n\n/** Legacy selection and explicit multi-container selection cannot be combined. */\nexport type SkillRegistryOptions = SkillRegistryCommonOptions &\n (\n | { containerId?: string; revision?: string; containers?: never }\n | {\n containers: readonly SkillRegistryContainer[];\n containerId?: never;\n revision?: never;\n }\n );\n\ninterface RegistryCommonConfig {\n readonly client: CopilotKitIntelligence;\n readonly freshnessWindowMs: number;\n readonly requestTimeoutMs: number;\n readonly debug: boolean;\n}\n\nexport type SingleContainerConfig = RegistryCommonConfig & {\n readonly containerId: string;\n readonly revision?: string;\n readonly containers?: never;\n};\n\nexport type RegistryConfig =\n | SingleContainerConfig\n | (RegistryCommonConfig & {\n readonly containers: readonly SkillRegistryContainer[];\n readonly containerId?: never;\n readonly revision?: never;\n });\n\n/** Resolve once. Never retain the options object, environment, or a second key. */\nexport function resolveRegistryConfig(\n options: SkillRegistryOptions = {},\n environment: NodeJS.ProcessEnv = processEnv(),\n): RegistryConfig {\n try {\n const multiple = options.containers !== undefined;\n if (\n multiple &&\n (options.containerId !== undefined || options.revision !== undefined)\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const containerId = multiple\n ? undefined\n : (options.containerId ??\n environment.CPK_INTELLIGENCE_LEARNING_CONTAINER_ID);\n const revision = multiple\n ? undefined\n : (options.revision ?? environment.CPK_INTELLIGENCE_SKILLS_REVISION);\n let containers: readonly SkillRegistryContainer[] | undefined;\n if (multiple) {\n if (\n !Array.isArray(options.containers) ||\n options.containers.length === 0 ||\n options.containers.length > 50\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n const seen = new Set<string>();\n containers = Object.freeze(\n options.containers.map((source) => {\n if (\n !source ||\n typeof source.id !== \"string\" ||\n !source.id.trim() ||\n // Reject control characters in caller-provided container IDs.\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u001f\\u007f]/.test(source.id) ||\n seen.has(source.id) ||\n (source.revision !== undefined &&\n (typeof source.revision !== \"string\" || !source.revision.trim()))\n ) {\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n // Reject malformed Unicode before constructing a qualified tool name.\n encodeURIComponent(source.id);\n seen.add(source.id);\n return Object.freeze({\n id: source.id,\n ...(source.revision !== undefined\n ? { revision: source.revision }\n : {}),\n });\n }),\n );\n }\n const freshnessWindowMs = options.freshnessWindowMs ?? 5_000;\n const requestTimeoutMs = options.requestTimeoutMs ?? 5_000;\n const debug = options.debug ?? false;\n if (\n (!multiple && (typeof containerId !== \"string\" || !containerId.trim())) ||\n (revision !== undefined &&\n (typeof revision !== \"string\" || revision.length === 0)) ||\n !Number.isSafeInteger(freshnessWindowMs) ||\n freshnessWindowMs < 0 ||\n !Number.isSafeInteger(requestTimeoutMs) ||\n requestTimeoutMs < 1 ||\n requestTimeoutMs > 2_147_483_647 ||\n typeof debug !== \"boolean\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n let client = options.client;\n if (client !== undefined) {\n if (\n !client ||\n typeof (multiple\n ? client.getLearnedSkillsSnapshots\n : client.getLearnedSkillsSnapshot) !== \"function\"\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n } else {\n const apiKey = options.apiKey ?? environment.CPK_INTELLIGENCE_API_KEY;\n const apiUrl = options.apiUrl ?? environment.INTELLIGENCE_API_URL;\n if (typeof apiKey !== \"string\" || !apiKey.trim())\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n if (apiUrl?.trim()) {\n const url = new URL(apiUrl);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n )\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false);\n }\n client = new CopilotKitIntelligence({\n apiKey,\n ...(apiUrl !== undefined ? { apiUrl } : {}),\n // This private helper client uses REST only. Explicitly retain the\n // canonical websocket default to prevent an irrelevant host warning.\n ...(apiUrl?.trim()\n ? { wsUrl: \"wss://realtime.intelligence.copilotkit.ai\" }\n : {}),\n });\n }\n return Object.freeze({\n client,\n ...(containers\n ? { containers }\n : {\n containerId: containerId!,\n ...(revision !== undefined ? { revision } : {}),\n }),\n freshnessWindowMs,\n requestTimeoutMs,\n debug,\n });\n } catch (error) {\n if (error instanceof SkillDeliveryError) throw error;\n throw new SkillDeliveryError(\"INVALID_CONFIG\", false, error);\n }\n}\n"],"mappings":";;;;;;AAmDA,SAAgB,sBACd,UAAgC,EAAE,EAClC,cAAiC,YAAY,EAC7B;AAChB,KAAI;EACF,MAAM,WAAW,QAAQ,eAAe;AACxC,MACE,aACC,QAAQ,gBAAgB,UAAa,QAAQ,aAAa,QAE3D,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;EAEvD,MAAM,cAAc,WAChB,SACC,QAAQ,eACT,YAAY;EAChB,MAAM,WAAW,WACb,SACC,QAAQ,YAAY,YAAY;EACrC,IAAI;AACJ,MAAI,UAAU;AACZ,OACE,CAAC,MAAM,QAAQ,QAAQ,WAAW,IAClC,QAAQ,WAAW,WAAW,KAC9B,QAAQ,WAAW,SAAS,GAE5B,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;GAEvD,MAAM,uBAAO,IAAI,KAAa;AAC9B,gBAAa,OAAO,OAClB,QAAQ,WAAW,KAAK,WAAW;AACjC,QACE,CAAC,UACD,OAAO,OAAO,OAAO,YACrB,CAAC,OAAO,GAAG,MAAM,IAGjB,wBAAwB,KAAK,OAAO,GAAG,IACvC,KAAK,IAAI,OAAO,GAAG,IAClB,OAAO,aAAa,WAClB,OAAO,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,MAAM,EAEjE,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;AAGvD,uBAAmB,OAAO,GAAG;AAC7B,SAAK,IAAI,OAAO,GAAG;AACnB,WAAO,OAAO,OAAO;KACnB,IAAI,OAAO;KACX,GAAI,OAAO,aAAa,SACpB,EAAE,UAAU,OAAO,UAAU,GAC7B,EAAE;KACP,CAAC;KACF,CACH;;EAEH,MAAM,oBAAoB,QAAQ,qBAAqB;EACvD,MAAM,mBAAmB,QAAQ,oBAAoB;EACrD,MAAM,QAAQ,QAAQ,SAAS;AAC/B,MACG,CAAC,aAAa,OAAO,gBAAgB,YAAY,CAAC,YAAY,MAAM,KACpE,aAAa,WACX,OAAO,aAAa,YAAY,SAAS,WAAW,MACvD,CAAC,OAAO,cAAc,kBAAkB,IACxC,oBAAoB,KACpB,CAAC,OAAO,cAAc,iBAAiB,IACvC,mBAAmB,KACnB,mBAAmB,cACnB,OAAO,UAAU,UAEjB,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;EACvD,IAAI,SAAS,QAAQ;AACrB,MAAI,WAAW,QACb;OACE,CAAC,UACD,QAAQ,WACJ,OAAO,4BACP,OAAO,8BAA8B,WAEzC,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;SAClD;GACL,MAAM,SAAS,QAAQ,UAAU,YAAY;GAC7C,MAAM,SAAS,QAAQ,UAAU,YAAY;AAC7C,OAAI,OAAO,WAAW,YAAY,CAAC,OAAO,MAAM,CAC9C,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;AACvD,OAAI,QAAQ,MAAM,EAAE;IAClB,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QACE,CAAC,CAAC,SAAS,SAAS,CAAC,SAAS,IAAI,SAAS,IAC3C,IAAI,YACJ,IAAI,YACJ,IAAI,UACJ,IAAI,KAEJ,OAAM,IAAIA,mBAAmB,kBAAkB,MAAM;;AAEzD,YAAS,IAAI,uBAAuB;IAClC;IACA,GAAI,WAAW,SAAY,EAAE,QAAQ,GAAG,EAAE;IAG1C,GAAI,QAAQ,MAAM,GACd,EAAE,OAAO,6CAA6C,GACtD,EAAE;IACP,CAAC;;AAEJ,SAAO,OAAO,OAAO;GACnB;GACA,GAAI,aACA,EAAE,YAAY,GACd;IACe;IACb,GAAI,aAAa,SAAY,EAAE,UAAU,GAAG,EAAE;IAC/C;GACL;GACA;GACA;GACD,CAAC;UACK,OAAO;AACd,MAAI,iBAAiBA,mBAAoB,OAAM;AAC/C,QAAM,IAAIA,mBAAmB,kBAAkB,OAAO,MAAM"}
@@ -1,9 +1,8 @@
1
- const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
2
1
  const require_learned_skills = require('../learned-skills.cjs');
2
+ const require_web_crypto = require('../../core/web-crypto.cjs');
3
3
  const require_errors = require('./errors.cjs');
4
4
  const require_config = require('./config.cjs');
5
5
  const require_snapshot = require('./snapshot.cjs');
6
- let node_crypto = require("node:crypto");
7
6
 
8
7
  //#region src/runtime/intelligence-platform/skill-registry/registry.ts
9
8
  function transient(error) {
@@ -199,13 +198,13 @@ var SkillRegistry = class {
199
198
  acquireSnapshot() {
200
199
  if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();
201
200
  if (this.#inFlight) return this.#inFlight;
202
- this.#inFlight = Promise.all(this.#sources.map(({ registry }) => registry.acquireSnapshot())).then((parts) => {
201
+ this.#inFlight = Promise.all(this.#sources.map(({ registry }) => registry.acquireSnapshot())).then(async (parts) => {
203
202
  if (this.#snapshot && parts.every((part, index) => part === this.#parts?.[index])) return this.#snapshot;
204
- const identity = (0, node_crypto.createHash)("sha256").update(JSON.stringify(parts.map((part, index) => [
203
+ const identity = await require_web_crypto.sha256Hex(JSON.stringify(parts.map((part, index) => [
205
204
  this.#sources[index].id,
206
205
  part.revision,
207
206
  part.etag
208
- ]))).digest("hex");
207
+ ])));
209
208
  const skills = Object.freeze(parts.flatMap((part, index) => part.skills.map((skill) => Object.freeze({
210
209
  ...skill,
211
210
  name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`
@@ -1 +1 @@
1
- {"version":3,"file":"registry.cjs","names":["SkillDeliveryError","#config","#inFlight","#snapshot","#blocked","#lastCheckedAt","#refresh","#lastError","#stale","invalidSnapshot","validateSnapshot","#debug","#sources","#multiple","resolveRegistryConfig","#parts"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../client\";\nimport type {\n GetLearnedSkillsSnapshotRequest,\n LearnedSkillsSnapshotResult,\n} from \"../learned-skills\";\nimport { createHash } from \"node:crypto\";\nimport { resolveRegistryConfig } from \"./config\";\nimport type { SingleContainerConfig, SkillRegistryOptions } from \"./config\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport type { SkillDeliveryErrorCode } from \"./errors\";\nimport { validateSnapshot } from \"./snapshot\";\nimport type { VerifiedSnapshot } from \"./snapshot\";\n\nexport interface SkillRegistryStatus {\n /** Present only for the explicit containers interface. */\n readonly containers?: readonly (SkillRegistryStatus & {\n readonly id: string;\n })[];\n readonly initialized: boolean;\n readonly revision?: string;\n readonly mode: \"latest\" | \"pinned\";\n /** ISO 8601 timestamp of the last successful 200 or matching 304 check. */\n readonly lastCheckedAt?: string;\n readonly stale: boolean;\n readonly lastError?: Readonly<{\n code: SkillDeliveryErrorCode;\n message: string;\n retryable: boolean;\n }>;\n}\n\nfunction transient(error: SkillDeliveryError): boolean {\n return [\n \"NETWORK_ERROR\",\n \"TIMEOUT\",\n \"INVALID_SNAPSHOT\",\n \"UNSUPPORTED_SERVER\",\n ].includes(error.code);\n}\nfunction deliveryError(error: unknown): SkillDeliveryError {\n if (error instanceof SkillDeliveryError) return error;\n return new SkillDeliveryError(\n error instanceof Error && error.name === \"TimeoutError\"\n ? \"TIMEOUT\"\n : \"NETWORK_ERROR\",\n true,\n error,\n );\n}\n\n/** Internal registry shared by framework adapters; public API is framework-native. */\nclass SingleContainerRegistry {\n readonly #config: SingleContainerConfig;\n #snapshot?: VerifiedSnapshot;\n #inFlight?: Promise<VerifiedSnapshot>;\n #lastCheckedAt?: number;\n #stale = false;\n #lastError?: SkillDeliveryError;\n #blocked?: SkillDeliveryError;\n\n constructor(\n config: SingleContainerConfig,\n private readonly fetchSnapshot = (\n request: GetLearnedSkillsSnapshotRequest,\n ) => config.client.getLearnedSkillsSnapshot(request),\n ) {\n this.#config = config;\n }\n\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture exactly one immutable snapshot before model work begins. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (this.#inFlight) return this.#inFlight;\n if (\n this.#snapshot &&\n !this.#blocked &&\n this.#lastCheckedAt !== undefined &&\n Date.now() - this.#lastCheckedAt < this.#config.freshnessWindowMs\n ) {\n return Promise.resolve(this.#snapshot);\n }\n // Defer work one microtask so reentrant and concurrent callers observe the\n // same promise before an injected client can start its request.\n this.#inFlight = Promise.resolve()\n .then(() => this.#refresh())\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n get status(): SkillRegistryStatus {\n const error = this.#lastError;\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n ...(this.#snapshot ? { revision: this.#snapshot.revision } : {}),\n mode: this.#config.revision === undefined ? \"latest\" : \"pinned\",\n ...(this.#lastCheckedAt !== undefined\n ? { lastCheckedAt: new Date(this.#lastCheckedAt).toISOString() }\n : {}),\n stale: this.#stale,\n ...(error\n ? {\n lastError: Object.freeze({\n code: error.code,\n message: error.message,\n retryable: error.retryable,\n }),\n }\n : {}),\n });\n }\n\n async #refresh(): Promise<VerifiedSnapshot> {\n const startedAt = Date.now();\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new SkillDeliveryError(\"TIMEOUT\", true);\n controller.abort(error);\n // Give a canonical client that already received denial headers one\n // event-loop turn to report that denial before the watchdog wins.\n timer = setTimeout(() => reject(error), 0);\n }, this.#config.requestTimeoutMs);\n });\n const replacement = async (): Promise<VerifiedSnapshot> => {\n const response = await this.fetchSnapshot({\n containerId: this.#config.containerId,\n ...(this.#config.revision !== undefined\n ? { revision: this.#config.revision }\n : {}),\n ...(this.#snapshot ? { ifNoneMatch: this.#snapshot.etag } : {}),\n signal: controller.signal,\n });\n controller.signal.throwIfAborted();\n if (!response || typeof response !== \"object\") throw invalidSnapshot();\n if (response.status === \"unchanged\") {\n if (\n !this.#snapshot ||\n response.etag !== this.#snapshot.etag ||\n response.revision !== this.#snapshot.revision\n )\n throw invalidSnapshot();\n return this.#snapshot;\n }\n if (\n this.#config.revision !== undefined &&\n response.revision !== this.#config.revision\n )\n throw invalidSnapshot();\n return validateSnapshot(response, controller.signal);\n };\n try {\n const snapshot = await Promise.race([replacement(), deadline]);\n // An abandoned parse never writes registry state: only the winning\n // complete replacement reaches this assignment.\n this.#snapshot = snapshot;\n this.#lastCheckedAt = Date.now();\n this.#stale = false;\n this.#lastError = undefined;\n this.#blocked = undefined;\n this.#debug(\"refresh-success\", startedAt);\n return snapshot;\n } catch (cause) {\n const error = deliveryError(cause);\n if (!transient(error)) {\n this.#blocked = error;\n this.#stale = false;\n this.#lastError = error;\n this.#debug(\"refresh-denied\", startedAt, error.code);\n throw error;\n }\n // A later unreachable server cannot undo an already confirmed denial.\n if (this.#blocked) {\n this.#lastError = this.#blocked;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n throw this.#blocked;\n }\n this.#lastError = error;\n this.#stale = this.#snapshot !== undefined;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n if (this.#snapshot) return this.#snapshot;\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n #debug(\n event: string,\n startedAt: number,\n errorCode?: SkillDeliveryErrorCode,\n ): void {\n if (!this.#config.debug) return;\n console.debug(\"CopilotKit learned skills\", {\n event,\n containerId: this.#config.containerId,\n revision: this.#snapshot?.revision,\n durationMs: Date.now() - startedAt,\n ...(errorCode ? { errorCode } : {}),\n });\n }\n}\n\n/** Coalesce refreshes from this registry into one request in the next microtask. */\nfunction batchLoader(client: CopilotKitIntelligence) {\n let pending: {\n request: GetLearnedSkillsSnapshotRequest;\n resolve: (value: LearnedSkillsSnapshotResult) => void;\n reject: (error: unknown) => void;\n }[] = [];\n return (\n request: GetLearnedSkillsSnapshotRequest,\n ): Promise<LearnedSkillsSnapshotResult> =>\n new Promise((resolve, reject) => {\n pending.push({ request, resolve, reject });\n if (pending.length !== 1) return;\n queueMicrotask(async () => {\n const batch = pending;\n pending = [];\n try {\n const results = await client.getLearnedSkillsSnapshots({\n containers: batch.map(\n ({ request: { signal: _signal, ...source } }) => source,\n ),\n signal: batch[0].request.signal,\n });\n if (\n !Array.isArray(results) ||\n results.length !== batch.length ||\n results.some(\n (result, index) =>\n result?.containerId !== batch[index].request.containerId,\n )\n )\n throw invalidSnapshot();\n for (let index = 0; index < batch.length; index++) {\n const result = results[index];\n if (result.status === \"error\") batch[index].reject(result.error);\n else batch[index].resolve(result);\n }\n } catch (error) {\n for (const item of batch) item.reject(error);\n }\n });\n });\n}\n\n/** Compose independent container caches into one immutable invocation snapshot. */\nexport class SkillRegistry {\n readonly #sources: readonly {\n readonly id: string;\n readonly registry: SingleContainerRegistry;\n }[];\n readonly #multiple: boolean;\n #snapshot?: VerifiedSnapshot;\n #parts?: readonly VerifiedSnapshot[];\n #inFlight?: Promise<VerifiedSnapshot>;\n\n constructor(options: SkillRegistryOptions = {}) {\n const config = resolveRegistryConfig(options);\n this.#multiple = config.containers !== undefined;\n const fetchBatch = batchLoader(config.client);\n this.#sources =\n config.containers !== undefined\n ? config.containers.map(({ id, revision }) => ({\n id,\n registry: new SingleContainerRegistry(\n Object.freeze({\n client: config.client,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n containerId: id,\n ...(revision !== undefined ? { revision } : {}),\n }),\n fetchBatch,\n ),\n }))\n : [\n {\n id: config.containerId!,\n registry: new SingleContainerRegistry({\n client: config.client,\n containerId: config.containerId!,\n revision: config.revision,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n }),\n },\n ];\n }\n\n /** Load every configured container before agent initialization completes. */\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture every container once; a failed source cannot yield a partial catalog. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();\n if (this.#inFlight) return this.#inFlight;\n this.#inFlight = Promise.all(\n this.#sources.map(({ registry }) => registry.acquireSnapshot()),\n )\n .then((parts) => {\n if (\n this.#snapshot &&\n parts.every((part, index) => part === this.#parts?.[index])\n ) {\n return this.#snapshot;\n }\n const identity = createHash(\"sha256\")\n .update(\n JSON.stringify(\n parts.map((part, index) => [\n this.#sources[index].id,\n part.revision,\n part.etag,\n ]),\n ),\n )\n .digest(\"hex\");\n const skills = Object.freeze(\n parts.flatMap((part, index) =>\n part.skills.map((skill) =>\n Object.freeze({\n ...skill,\n name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`,\n }),\n ),\n ),\n );\n this.#parts = parts;\n this.#snapshot = Object.freeze({\n revision: `multi:${identity}`,\n etag: `\"${identity}\"`,\n skills,\n });\n return this.#snapshot;\n })\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n /** Report each container's real revision; no aggregate server revision exists. */\n get status(): SkillRegistryStatus {\n if (!this.#multiple) return this.#sources[0].registry.status;\n const containers = Object.freeze(\n this.#sources.map(({ id, registry }) =>\n Object.freeze({ id, ...registry.status }),\n ),\n );\n const error =\n containers.find(\n (source) => source.lastError && !source.lastError.retryable,\n )?.lastError ?? containers.find((source) => source.lastError)?.lastError;\n const timestamps = containers.map((source) => source.lastCheckedAt);\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n mode: containers.every((source) => source.mode === \"pinned\")\n ? \"pinned\"\n : \"latest\",\n stale: containers.some((source) => source.stale),\n ...(timestamps.every((timestamp) => timestamp !== undefined)\n ? { lastCheckedAt: [...timestamps].sort()[0] }\n : {}),\n ...(error ? { lastError: error } : {}),\n containers,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.cjs","names":["SkillDeliveryError","#config","#inFlight","#snapshot","#blocked","#lastCheckedAt","#refresh","#lastError","#stale","invalidSnapshot","validateSnapshot","#debug","#sources","#multiple","resolveRegistryConfig","#parts","sha256Hex"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../client\";\nimport type {\n GetLearnedSkillsSnapshotRequest,\n LearnedSkillsSnapshotResult,\n} from \"../learned-skills\";\nimport { resolveRegistryConfig } from \"./config\";\nimport type { SingleContainerConfig, SkillRegistryOptions } from \"./config\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport type { SkillDeliveryErrorCode } from \"./errors\";\nimport { sha256Hex } from \"../../core/web-crypto\";\nimport { validateSnapshot } from \"./snapshot\";\nimport type { VerifiedSnapshot } from \"./snapshot\";\n\nexport interface SkillRegistryStatus {\n /** Present only for the explicit containers interface. */\n readonly containers?: readonly (SkillRegistryStatus & {\n readonly id: string;\n })[];\n readonly initialized: boolean;\n readonly revision?: string;\n readonly mode: \"latest\" | \"pinned\";\n /** ISO 8601 timestamp of the last successful 200 or matching 304 check. */\n readonly lastCheckedAt?: string;\n readonly stale: boolean;\n readonly lastError?: Readonly<{\n code: SkillDeliveryErrorCode;\n message: string;\n retryable: boolean;\n }>;\n}\n\nfunction transient(error: SkillDeliveryError): boolean {\n return [\n \"NETWORK_ERROR\",\n \"TIMEOUT\",\n \"INVALID_SNAPSHOT\",\n \"UNSUPPORTED_SERVER\",\n ].includes(error.code);\n}\nfunction deliveryError(error: unknown): SkillDeliveryError {\n if (error instanceof SkillDeliveryError) return error;\n return new SkillDeliveryError(\n error instanceof Error && error.name === \"TimeoutError\"\n ? \"TIMEOUT\"\n : \"NETWORK_ERROR\",\n true,\n error,\n );\n}\n\n/** Internal registry shared by framework adapters; public API is framework-native. */\nclass SingleContainerRegistry {\n readonly #config: SingleContainerConfig;\n #snapshot?: VerifiedSnapshot;\n #inFlight?: Promise<VerifiedSnapshot>;\n #lastCheckedAt?: number;\n #stale = false;\n #lastError?: SkillDeliveryError;\n #blocked?: SkillDeliveryError;\n\n constructor(\n config: SingleContainerConfig,\n private readonly fetchSnapshot = (\n request: GetLearnedSkillsSnapshotRequest,\n ) => config.client.getLearnedSkillsSnapshot(request),\n ) {\n this.#config = config;\n }\n\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture exactly one immutable snapshot before model work begins. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (this.#inFlight) return this.#inFlight;\n if (\n this.#snapshot &&\n !this.#blocked &&\n this.#lastCheckedAt !== undefined &&\n Date.now() - this.#lastCheckedAt < this.#config.freshnessWindowMs\n ) {\n return Promise.resolve(this.#snapshot);\n }\n // Defer work one microtask so reentrant and concurrent callers observe the\n // same promise before an injected client can start its request.\n this.#inFlight = Promise.resolve()\n .then(() => this.#refresh())\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n get status(): SkillRegistryStatus {\n const error = this.#lastError;\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n ...(this.#snapshot ? { revision: this.#snapshot.revision } : {}),\n mode: this.#config.revision === undefined ? \"latest\" : \"pinned\",\n ...(this.#lastCheckedAt !== undefined\n ? { lastCheckedAt: new Date(this.#lastCheckedAt).toISOString() }\n : {}),\n stale: this.#stale,\n ...(error\n ? {\n lastError: Object.freeze({\n code: error.code,\n message: error.message,\n retryable: error.retryable,\n }),\n }\n : {}),\n });\n }\n\n async #refresh(): Promise<VerifiedSnapshot> {\n const startedAt = Date.now();\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new SkillDeliveryError(\"TIMEOUT\", true);\n controller.abort(error);\n // Give a canonical client that already received denial headers one\n // event-loop turn to report that denial before the watchdog wins.\n timer = setTimeout(() => reject(error), 0);\n }, this.#config.requestTimeoutMs);\n });\n const replacement = async (): Promise<VerifiedSnapshot> => {\n const response = await this.fetchSnapshot({\n containerId: this.#config.containerId,\n ...(this.#config.revision !== undefined\n ? { revision: this.#config.revision }\n : {}),\n ...(this.#snapshot ? { ifNoneMatch: this.#snapshot.etag } : {}),\n signal: controller.signal,\n });\n controller.signal.throwIfAborted();\n if (!response || typeof response !== \"object\") throw invalidSnapshot();\n if (response.status === \"unchanged\") {\n if (\n !this.#snapshot ||\n response.etag !== this.#snapshot.etag ||\n response.revision !== this.#snapshot.revision\n )\n throw invalidSnapshot();\n return this.#snapshot;\n }\n if (\n this.#config.revision !== undefined &&\n response.revision !== this.#config.revision\n )\n throw invalidSnapshot();\n return validateSnapshot(response, controller.signal);\n };\n try {\n const snapshot = await Promise.race([replacement(), deadline]);\n // An abandoned parse never writes registry state: only the winning\n // complete replacement reaches this assignment.\n this.#snapshot = snapshot;\n this.#lastCheckedAt = Date.now();\n this.#stale = false;\n this.#lastError = undefined;\n this.#blocked = undefined;\n this.#debug(\"refresh-success\", startedAt);\n return snapshot;\n } catch (cause) {\n const error = deliveryError(cause);\n if (!transient(error)) {\n this.#blocked = error;\n this.#stale = false;\n this.#lastError = error;\n this.#debug(\"refresh-denied\", startedAt, error.code);\n throw error;\n }\n // A later unreachable server cannot undo an already confirmed denial.\n if (this.#blocked) {\n this.#lastError = this.#blocked;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n throw this.#blocked;\n }\n this.#lastError = error;\n this.#stale = this.#snapshot !== undefined;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n if (this.#snapshot) return this.#snapshot;\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n #debug(\n event: string,\n startedAt: number,\n errorCode?: SkillDeliveryErrorCode,\n ): void {\n if (!this.#config.debug) return;\n console.debug(\"CopilotKit learned skills\", {\n event,\n containerId: this.#config.containerId,\n revision: this.#snapshot?.revision,\n durationMs: Date.now() - startedAt,\n ...(errorCode ? { errorCode } : {}),\n });\n }\n}\n\n/** Coalesce refreshes from this registry into one request in the next microtask. */\nfunction batchLoader(client: CopilotKitIntelligence) {\n let pending: {\n request: GetLearnedSkillsSnapshotRequest;\n resolve: (value: LearnedSkillsSnapshotResult) => void;\n reject: (error: unknown) => void;\n }[] = [];\n return (\n request: GetLearnedSkillsSnapshotRequest,\n ): Promise<LearnedSkillsSnapshotResult> =>\n new Promise((resolve, reject) => {\n pending.push({ request, resolve, reject });\n if (pending.length !== 1) return;\n queueMicrotask(async () => {\n const batch = pending;\n pending = [];\n try {\n const results = await client.getLearnedSkillsSnapshots({\n containers: batch.map(\n ({ request: { signal: _signal, ...source } }) => source,\n ),\n signal: batch[0].request.signal,\n });\n if (\n !Array.isArray(results) ||\n results.length !== batch.length ||\n results.some(\n (result, index) =>\n result?.containerId !== batch[index].request.containerId,\n )\n )\n throw invalidSnapshot();\n for (let index = 0; index < batch.length; index++) {\n const result = results[index];\n if (result.status === \"error\") batch[index].reject(result.error);\n else batch[index].resolve(result);\n }\n } catch (error) {\n for (const item of batch) item.reject(error);\n }\n });\n });\n}\n\n/** Compose independent container caches into one immutable invocation snapshot. */\nexport class SkillRegistry {\n readonly #sources: readonly {\n readonly id: string;\n readonly registry: SingleContainerRegistry;\n }[];\n readonly #multiple: boolean;\n #snapshot?: VerifiedSnapshot;\n #parts?: readonly VerifiedSnapshot[];\n #inFlight?: Promise<VerifiedSnapshot>;\n\n constructor(options: SkillRegistryOptions = {}) {\n const config = resolveRegistryConfig(options);\n this.#multiple = config.containers !== undefined;\n const fetchBatch = batchLoader(config.client);\n this.#sources =\n config.containers !== undefined\n ? config.containers.map(({ id, revision }) => ({\n id,\n registry: new SingleContainerRegistry(\n Object.freeze({\n client: config.client,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n containerId: id,\n ...(revision !== undefined ? { revision } : {}),\n }),\n fetchBatch,\n ),\n }))\n : [\n {\n id: config.containerId!,\n registry: new SingleContainerRegistry({\n client: config.client,\n containerId: config.containerId!,\n revision: config.revision,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n }),\n },\n ];\n }\n\n /** Load every configured container before agent initialization completes. */\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture every container once; a failed source cannot yield a partial catalog. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();\n if (this.#inFlight) return this.#inFlight;\n this.#inFlight = Promise.all(\n this.#sources.map(({ registry }) => registry.acquireSnapshot()),\n )\n .then(async (parts) => {\n if (\n this.#snapshot &&\n parts.every((part, index) => part === this.#parts?.[index])\n ) {\n return this.#snapshot;\n }\n const identity = await sha256Hex(\n JSON.stringify(\n parts.map((part, index) => [\n this.#sources[index].id,\n part.revision,\n part.etag,\n ]),\n ),\n );\n const skills = Object.freeze(\n parts.flatMap((part, index) =>\n part.skills.map((skill) =>\n Object.freeze({\n ...skill,\n name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`,\n }),\n ),\n ),\n );\n this.#parts = parts;\n this.#snapshot = Object.freeze({\n revision: `multi:${identity}`,\n etag: `\"${identity}\"`,\n skills,\n });\n return this.#snapshot;\n })\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n /** Report each container's real revision; no aggregate server revision exists. */\n get status(): SkillRegistryStatus {\n if (!this.#multiple) return this.#sources[0].registry.status;\n const containers = Object.freeze(\n this.#sources.map(({ id, registry }) =>\n Object.freeze({ id, ...registry.status }),\n ),\n );\n const error =\n containers.find(\n (source) => source.lastError && !source.lastError.retryable,\n )?.lastError ?? containers.find((source) => source.lastError)?.lastError;\n const timestamps = containers.map((source) => source.lastCheckedAt);\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n mode: containers.every((source) => source.mode === \"pinned\")\n ? \"pinned\"\n : \"latest\",\n stale: containers.some((source) => source.stale),\n ...(timestamps.every((timestamp) => timestamp !== undefined)\n ? { lastCheckedAt: [...timestamps].sort()[0] }\n : {}),\n ...(error ? { lastError: error } : {}),\n containers,\n });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;UAaiB,mBAAA;;WAEN,UAAA,aAAuB,mBAAA;IAAA,SACrB,EAAA;EAAA;EAAA,SAEF,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAIoB;EAAA,SAFpB,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAkOS,aAAA;EAAA;cAUC,OAAA,GAAS,oBAAA;EA9Ob;EAkRF,UAAA,CAAA,GAAc,OAAA;EAhRlB;EAqRF,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EArRhB;EAAA,IAsUP,MAAA,CAAA,GAAU,mBAAA;AAAA"}
1
+ {"version":3,"file":"registry.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;UAaiB,mBAAA;;WAEN,UAAA,aAAuB,mBAAA;IAAA,SACrB,EAAA;EAAA;EAAA,SAEF,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAIoB;EAAA,SAFpB,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAkOS,aAAA;EAAA;cAUC,OAAA,GAAS,oBAAA;EA9Ob;EAkRF,UAAA,CAAA,GAAc,OAAA;EAhRlB;EAqRF,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EArRhB;EAAA,IAoUP,MAAA,CAAA,GAAU,mBAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;UAaiB,mBAAA;;WAEN,UAAA,aAAuB,mBAAA;IAAA,SACrB,EAAA;EAAA;EAAA,SAEF,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAIoB;EAAA,SAFpB,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAkOS,aAAA;EAAA;cAUC,OAAA,GAAS,oBAAA;EA9Ob;EAkRF,UAAA,CAAA,GAAc,OAAA;EAhRlB;EAqRF,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EArRhB;EAAA,IAsUP,MAAA,CAAA,GAAU,mBAAA;AAAA"}
1
+ {"version":3,"file":"registry.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;UAaiB,mBAAA;;WAEN,UAAA,aAAuB,mBAAA;IAAA,SACrB,EAAA;EAAA;EAAA,SAEF,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAIoB;EAAA,SAFpB,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAkOS,aAAA;EAAA;cAUC,OAAA,GAAS,oBAAA;EA9Ob;EAkRF,UAAA,CAAA,GAAc,OAAA;EAhRlB;EAqRF,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EArRhB;EAAA,IAoUP,MAAA,CAAA,GAAU,mBAAA;AAAA"}
@@ -1,8 +1,8 @@
1
1
  import { LearnedSkillsError } from "../learned-skills.mjs";
2
+ import { sha256Hex } from "../../core/web-crypto.mjs";
2
3
  import { invalidSnapshot } from "./errors.mjs";
3
4
  import { resolveRegistryConfig } from "./config.mjs";
4
5
  import { validateSnapshot } from "./snapshot.mjs";
5
- import { createHash } from "node:crypto";
6
6
 
7
7
  //#region src/runtime/intelligence-platform/skill-registry/registry.ts
8
8
  function transient(error) {
@@ -198,13 +198,13 @@ var SkillRegistry = class {
198
198
  acquireSnapshot() {
199
199
  if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();
200
200
  if (this.#inFlight) return this.#inFlight;
201
- this.#inFlight = Promise.all(this.#sources.map(({ registry }) => registry.acquireSnapshot())).then((parts) => {
201
+ this.#inFlight = Promise.all(this.#sources.map(({ registry }) => registry.acquireSnapshot())).then(async (parts) => {
202
202
  if (this.#snapshot && parts.every((part, index) => part === this.#parts?.[index])) return this.#snapshot;
203
- const identity = createHash("sha256").update(JSON.stringify(parts.map((part, index) => [
203
+ const identity = await sha256Hex(JSON.stringify(parts.map((part, index) => [
204
204
  this.#sources[index].id,
205
205
  part.revision,
206
206
  part.etag
207
- ]))).digest("hex");
207
+ ])));
208
208
  const skills = Object.freeze(parts.flatMap((part, index) => part.skills.map((skill) => Object.freeze({
209
209
  ...skill,
210
210
  name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`
@@ -1 +1 @@
1
- {"version":3,"file":"registry.mjs","names":["SkillDeliveryError","#config","#inFlight","#snapshot","#blocked","#lastCheckedAt","#refresh","#lastError","#stale","#debug","#sources","#multiple","#parts"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../client\";\nimport type {\n GetLearnedSkillsSnapshotRequest,\n LearnedSkillsSnapshotResult,\n} from \"../learned-skills\";\nimport { createHash } from \"node:crypto\";\nimport { resolveRegistryConfig } from \"./config\";\nimport type { SingleContainerConfig, SkillRegistryOptions } from \"./config\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport type { SkillDeliveryErrorCode } from \"./errors\";\nimport { validateSnapshot } from \"./snapshot\";\nimport type { VerifiedSnapshot } from \"./snapshot\";\n\nexport interface SkillRegistryStatus {\n /** Present only for the explicit containers interface. */\n readonly containers?: readonly (SkillRegistryStatus & {\n readonly id: string;\n })[];\n readonly initialized: boolean;\n readonly revision?: string;\n readonly mode: \"latest\" | \"pinned\";\n /** ISO 8601 timestamp of the last successful 200 or matching 304 check. */\n readonly lastCheckedAt?: string;\n readonly stale: boolean;\n readonly lastError?: Readonly<{\n code: SkillDeliveryErrorCode;\n message: string;\n retryable: boolean;\n }>;\n}\n\nfunction transient(error: SkillDeliveryError): boolean {\n return [\n \"NETWORK_ERROR\",\n \"TIMEOUT\",\n \"INVALID_SNAPSHOT\",\n \"UNSUPPORTED_SERVER\",\n ].includes(error.code);\n}\nfunction deliveryError(error: unknown): SkillDeliveryError {\n if (error instanceof SkillDeliveryError) return error;\n return new SkillDeliveryError(\n error instanceof Error && error.name === \"TimeoutError\"\n ? \"TIMEOUT\"\n : \"NETWORK_ERROR\",\n true,\n error,\n );\n}\n\n/** Internal registry shared by framework adapters; public API is framework-native. */\nclass SingleContainerRegistry {\n readonly #config: SingleContainerConfig;\n #snapshot?: VerifiedSnapshot;\n #inFlight?: Promise<VerifiedSnapshot>;\n #lastCheckedAt?: number;\n #stale = false;\n #lastError?: SkillDeliveryError;\n #blocked?: SkillDeliveryError;\n\n constructor(\n config: SingleContainerConfig,\n private readonly fetchSnapshot = (\n request: GetLearnedSkillsSnapshotRequest,\n ) => config.client.getLearnedSkillsSnapshot(request),\n ) {\n this.#config = config;\n }\n\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture exactly one immutable snapshot before model work begins. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (this.#inFlight) return this.#inFlight;\n if (\n this.#snapshot &&\n !this.#blocked &&\n this.#lastCheckedAt !== undefined &&\n Date.now() - this.#lastCheckedAt < this.#config.freshnessWindowMs\n ) {\n return Promise.resolve(this.#snapshot);\n }\n // Defer work one microtask so reentrant and concurrent callers observe the\n // same promise before an injected client can start its request.\n this.#inFlight = Promise.resolve()\n .then(() => this.#refresh())\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n get status(): SkillRegistryStatus {\n const error = this.#lastError;\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n ...(this.#snapshot ? { revision: this.#snapshot.revision } : {}),\n mode: this.#config.revision === undefined ? \"latest\" : \"pinned\",\n ...(this.#lastCheckedAt !== undefined\n ? { lastCheckedAt: new Date(this.#lastCheckedAt).toISOString() }\n : {}),\n stale: this.#stale,\n ...(error\n ? {\n lastError: Object.freeze({\n code: error.code,\n message: error.message,\n retryable: error.retryable,\n }),\n }\n : {}),\n });\n }\n\n async #refresh(): Promise<VerifiedSnapshot> {\n const startedAt = Date.now();\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new SkillDeliveryError(\"TIMEOUT\", true);\n controller.abort(error);\n // Give a canonical client that already received denial headers one\n // event-loop turn to report that denial before the watchdog wins.\n timer = setTimeout(() => reject(error), 0);\n }, this.#config.requestTimeoutMs);\n });\n const replacement = async (): Promise<VerifiedSnapshot> => {\n const response = await this.fetchSnapshot({\n containerId: this.#config.containerId,\n ...(this.#config.revision !== undefined\n ? { revision: this.#config.revision }\n : {}),\n ...(this.#snapshot ? { ifNoneMatch: this.#snapshot.etag } : {}),\n signal: controller.signal,\n });\n controller.signal.throwIfAborted();\n if (!response || typeof response !== \"object\") throw invalidSnapshot();\n if (response.status === \"unchanged\") {\n if (\n !this.#snapshot ||\n response.etag !== this.#snapshot.etag ||\n response.revision !== this.#snapshot.revision\n )\n throw invalidSnapshot();\n return this.#snapshot;\n }\n if (\n this.#config.revision !== undefined &&\n response.revision !== this.#config.revision\n )\n throw invalidSnapshot();\n return validateSnapshot(response, controller.signal);\n };\n try {\n const snapshot = await Promise.race([replacement(), deadline]);\n // An abandoned parse never writes registry state: only the winning\n // complete replacement reaches this assignment.\n this.#snapshot = snapshot;\n this.#lastCheckedAt = Date.now();\n this.#stale = false;\n this.#lastError = undefined;\n this.#blocked = undefined;\n this.#debug(\"refresh-success\", startedAt);\n return snapshot;\n } catch (cause) {\n const error = deliveryError(cause);\n if (!transient(error)) {\n this.#blocked = error;\n this.#stale = false;\n this.#lastError = error;\n this.#debug(\"refresh-denied\", startedAt, error.code);\n throw error;\n }\n // A later unreachable server cannot undo an already confirmed denial.\n if (this.#blocked) {\n this.#lastError = this.#blocked;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n throw this.#blocked;\n }\n this.#lastError = error;\n this.#stale = this.#snapshot !== undefined;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n if (this.#snapshot) return this.#snapshot;\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n #debug(\n event: string,\n startedAt: number,\n errorCode?: SkillDeliveryErrorCode,\n ): void {\n if (!this.#config.debug) return;\n console.debug(\"CopilotKit learned skills\", {\n event,\n containerId: this.#config.containerId,\n revision: this.#snapshot?.revision,\n durationMs: Date.now() - startedAt,\n ...(errorCode ? { errorCode } : {}),\n });\n }\n}\n\n/** Coalesce refreshes from this registry into one request in the next microtask. */\nfunction batchLoader(client: CopilotKitIntelligence) {\n let pending: {\n request: GetLearnedSkillsSnapshotRequest;\n resolve: (value: LearnedSkillsSnapshotResult) => void;\n reject: (error: unknown) => void;\n }[] = [];\n return (\n request: GetLearnedSkillsSnapshotRequest,\n ): Promise<LearnedSkillsSnapshotResult> =>\n new Promise((resolve, reject) => {\n pending.push({ request, resolve, reject });\n if (pending.length !== 1) return;\n queueMicrotask(async () => {\n const batch = pending;\n pending = [];\n try {\n const results = await client.getLearnedSkillsSnapshots({\n containers: batch.map(\n ({ request: { signal: _signal, ...source } }) => source,\n ),\n signal: batch[0].request.signal,\n });\n if (\n !Array.isArray(results) ||\n results.length !== batch.length ||\n results.some(\n (result, index) =>\n result?.containerId !== batch[index].request.containerId,\n )\n )\n throw invalidSnapshot();\n for (let index = 0; index < batch.length; index++) {\n const result = results[index];\n if (result.status === \"error\") batch[index].reject(result.error);\n else batch[index].resolve(result);\n }\n } catch (error) {\n for (const item of batch) item.reject(error);\n }\n });\n });\n}\n\n/** Compose independent container caches into one immutable invocation snapshot. */\nexport class SkillRegistry {\n readonly #sources: readonly {\n readonly id: string;\n readonly registry: SingleContainerRegistry;\n }[];\n readonly #multiple: boolean;\n #snapshot?: VerifiedSnapshot;\n #parts?: readonly VerifiedSnapshot[];\n #inFlight?: Promise<VerifiedSnapshot>;\n\n constructor(options: SkillRegistryOptions = {}) {\n const config = resolveRegistryConfig(options);\n this.#multiple = config.containers !== undefined;\n const fetchBatch = batchLoader(config.client);\n this.#sources =\n config.containers !== undefined\n ? config.containers.map(({ id, revision }) => ({\n id,\n registry: new SingleContainerRegistry(\n Object.freeze({\n client: config.client,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n containerId: id,\n ...(revision !== undefined ? { revision } : {}),\n }),\n fetchBatch,\n ),\n }))\n : [\n {\n id: config.containerId!,\n registry: new SingleContainerRegistry({\n client: config.client,\n containerId: config.containerId!,\n revision: config.revision,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n }),\n },\n ];\n }\n\n /** Load every configured container before agent initialization completes. */\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture every container once; a failed source cannot yield a partial catalog. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();\n if (this.#inFlight) return this.#inFlight;\n this.#inFlight = Promise.all(\n this.#sources.map(({ registry }) => registry.acquireSnapshot()),\n )\n .then((parts) => {\n if (\n this.#snapshot &&\n parts.every((part, index) => part === this.#parts?.[index])\n ) {\n return this.#snapshot;\n }\n const identity = createHash(\"sha256\")\n .update(\n JSON.stringify(\n parts.map((part, index) => [\n this.#sources[index].id,\n part.revision,\n part.etag,\n ]),\n ),\n )\n .digest(\"hex\");\n const skills = Object.freeze(\n parts.flatMap((part, index) =>\n part.skills.map((skill) =>\n Object.freeze({\n ...skill,\n name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`,\n }),\n ),\n ),\n );\n this.#parts = parts;\n this.#snapshot = Object.freeze({\n revision: `multi:${identity}`,\n etag: `\"${identity}\"`,\n skills,\n });\n return this.#snapshot;\n })\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n /** Report each container's real revision; no aggregate server revision exists. */\n get status(): SkillRegistryStatus {\n if (!this.#multiple) return this.#sources[0].registry.status;\n const containers = Object.freeze(\n this.#sources.map(({ id, registry }) =>\n Object.freeze({ id, ...registry.status }),\n ),\n );\n const error =\n containers.find(\n (source) => source.lastError && !source.lastError.retryable,\n )?.lastError ?? containers.find((source) => source.lastError)?.lastError;\n const timestamps = containers.map((source) => source.lastCheckedAt);\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n mode: containers.every((source) => source.mode === \"pinned\")\n ? \"pinned\"\n : \"latest\",\n stale: containers.some((source) => source.stale),\n ...(timestamps.every((timestamp) => timestamp !== undefined)\n ? { lastCheckedAt: [...timestamps].sort()[0] }\n : {}),\n ...(error ? { lastError: error } : {}),\n containers,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.mjs","names":["SkillDeliveryError","#config","#inFlight","#snapshot","#blocked","#lastCheckedAt","#refresh","#lastError","#stale","#debug","#sources","#multiple","#parts"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/registry.ts"],"sourcesContent":["import type { CopilotKitIntelligence } from \"../client\";\nimport type {\n GetLearnedSkillsSnapshotRequest,\n LearnedSkillsSnapshotResult,\n} from \"../learned-skills\";\nimport { resolveRegistryConfig } from \"./config\";\nimport type { SingleContainerConfig, SkillRegistryOptions } from \"./config\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport type { SkillDeliveryErrorCode } from \"./errors\";\nimport { sha256Hex } from \"../../core/web-crypto\";\nimport { validateSnapshot } from \"./snapshot\";\nimport type { VerifiedSnapshot } from \"./snapshot\";\n\nexport interface SkillRegistryStatus {\n /** Present only for the explicit containers interface. */\n readonly containers?: readonly (SkillRegistryStatus & {\n readonly id: string;\n })[];\n readonly initialized: boolean;\n readonly revision?: string;\n readonly mode: \"latest\" | \"pinned\";\n /** ISO 8601 timestamp of the last successful 200 or matching 304 check. */\n readonly lastCheckedAt?: string;\n readonly stale: boolean;\n readonly lastError?: Readonly<{\n code: SkillDeliveryErrorCode;\n message: string;\n retryable: boolean;\n }>;\n}\n\nfunction transient(error: SkillDeliveryError): boolean {\n return [\n \"NETWORK_ERROR\",\n \"TIMEOUT\",\n \"INVALID_SNAPSHOT\",\n \"UNSUPPORTED_SERVER\",\n ].includes(error.code);\n}\nfunction deliveryError(error: unknown): SkillDeliveryError {\n if (error instanceof SkillDeliveryError) return error;\n return new SkillDeliveryError(\n error instanceof Error && error.name === \"TimeoutError\"\n ? \"TIMEOUT\"\n : \"NETWORK_ERROR\",\n true,\n error,\n );\n}\n\n/** Internal registry shared by framework adapters; public API is framework-native. */\nclass SingleContainerRegistry {\n readonly #config: SingleContainerConfig;\n #snapshot?: VerifiedSnapshot;\n #inFlight?: Promise<VerifiedSnapshot>;\n #lastCheckedAt?: number;\n #stale = false;\n #lastError?: SkillDeliveryError;\n #blocked?: SkillDeliveryError;\n\n constructor(\n config: SingleContainerConfig,\n private readonly fetchSnapshot = (\n request: GetLearnedSkillsSnapshotRequest,\n ) => config.client.getLearnedSkillsSnapshot(request),\n ) {\n this.#config = config;\n }\n\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture exactly one immutable snapshot before model work begins. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (this.#inFlight) return this.#inFlight;\n if (\n this.#snapshot &&\n !this.#blocked &&\n this.#lastCheckedAt !== undefined &&\n Date.now() - this.#lastCheckedAt < this.#config.freshnessWindowMs\n ) {\n return Promise.resolve(this.#snapshot);\n }\n // Defer work one microtask so reentrant and concurrent callers observe the\n // same promise before an injected client can start its request.\n this.#inFlight = Promise.resolve()\n .then(() => this.#refresh())\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n get status(): SkillRegistryStatus {\n const error = this.#lastError;\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n ...(this.#snapshot ? { revision: this.#snapshot.revision } : {}),\n mode: this.#config.revision === undefined ? \"latest\" : \"pinned\",\n ...(this.#lastCheckedAt !== undefined\n ? { lastCheckedAt: new Date(this.#lastCheckedAt).toISOString() }\n : {}),\n stale: this.#stale,\n ...(error\n ? {\n lastError: Object.freeze({\n code: error.code,\n message: error.message,\n retryable: error.retryable,\n }),\n }\n : {}),\n });\n }\n\n async #refresh(): Promise<VerifiedSnapshot> {\n const startedAt = Date.now();\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n const error = new SkillDeliveryError(\"TIMEOUT\", true);\n controller.abort(error);\n // Give a canonical client that already received denial headers one\n // event-loop turn to report that denial before the watchdog wins.\n timer = setTimeout(() => reject(error), 0);\n }, this.#config.requestTimeoutMs);\n });\n const replacement = async (): Promise<VerifiedSnapshot> => {\n const response = await this.fetchSnapshot({\n containerId: this.#config.containerId,\n ...(this.#config.revision !== undefined\n ? { revision: this.#config.revision }\n : {}),\n ...(this.#snapshot ? { ifNoneMatch: this.#snapshot.etag } : {}),\n signal: controller.signal,\n });\n controller.signal.throwIfAborted();\n if (!response || typeof response !== \"object\") throw invalidSnapshot();\n if (response.status === \"unchanged\") {\n if (\n !this.#snapshot ||\n response.etag !== this.#snapshot.etag ||\n response.revision !== this.#snapshot.revision\n )\n throw invalidSnapshot();\n return this.#snapshot;\n }\n if (\n this.#config.revision !== undefined &&\n response.revision !== this.#config.revision\n )\n throw invalidSnapshot();\n return validateSnapshot(response, controller.signal);\n };\n try {\n const snapshot = await Promise.race([replacement(), deadline]);\n // An abandoned parse never writes registry state: only the winning\n // complete replacement reaches this assignment.\n this.#snapshot = snapshot;\n this.#lastCheckedAt = Date.now();\n this.#stale = false;\n this.#lastError = undefined;\n this.#blocked = undefined;\n this.#debug(\"refresh-success\", startedAt);\n return snapshot;\n } catch (cause) {\n const error = deliveryError(cause);\n if (!transient(error)) {\n this.#blocked = error;\n this.#stale = false;\n this.#lastError = error;\n this.#debug(\"refresh-denied\", startedAt, error.code);\n throw error;\n }\n // A later unreachable server cannot undo an already confirmed denial.\n if (this.#blocked) {\n this.#lastError = this.#blocked;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n throw this.#blocked;\n }\n this.#lastError = error;\n this.#stale = this.#snapshot !== undefined;\n this.#debug(\"refresh-failed\", startedAt, error.code);\n if (this.#snapshot) return this.#snapshot;\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n #debug(\n event: string,\n startedAt: number,\n errorCode?: SkillDeliveryErrorCode,\n ): void {\n if (!this.#config.debug) return;\n console.debug(\"CopilotKit learned skills\", {\n event,\n containerId: this.#config.containerId,\n revision: this.#snapshot?.revision,\n durationMs: Date.now() - startedAt,\n ...(errorCode ? { errorCode } : {}),\n });\n }\n}\n\n/** Coalesce refreshes from this registry into one request in the next microtask. */\nfunction batchLoader(client: CopilotKitIntelligence) {\n let pending: {\n request: GetLearnedSkillsSnapshotRequest;\n resolve: (value: LearnedSkillsSnapshotResult) => void;\n reject: (error: unknown) => void;\n }[] = [];\n return (\n request: GetLearnedSkillsSnapshotRequest,\n ): Promise<LearnedSkillsSnapshotResult> =>\n new Promise((resolve, reject) => {\n pending.push({ request, resolve, reject });\n if (pending.length !== 1) return;\n queueMicrotask(async () => {\n const batch = pending;\n pending = [];\n try {\n const results = await client.getLearnedSkillsSnapshots({\n containers: batch.map(\n ({ request: { signal: _signal, ...source } }) => source,\n ),\n signal: batch[0].request.signal,\n });\n if (\n !Array.isArray(results) ||\n results.length !== batch.length ||\n results.some(\n (result, index) =>\n result?.containerId !== batch[index].request.containerId,\n )\n )\n throw invalidSnapshot();\n for (let index = 0; index < batch.length; index++) {\n const result = results[index];\n if (result.status === \"error\") batch[index].reject(result.error);\n else batch[index].resolve(result);\n }\n } catch (error) {\n for (const item of batch) item.reject(error);\n }\n });\n });\n}\n\n/** Compose independent container caches into one immutable invocation snapshot. */\nexport class SkillRegistry {\n readonly #sources: readonly {\n readonly id: string;\n readonly registry: SingleContainerRegistry;\n }[];\n readonly #multiple: boolean;\n #snapshot?: VerifiedSnapshot;\n #parts?: readonly VerifiedSnapshot[];\n #inFlight?: Promise<VerifiedSnapshot>;\n\n constructor(options: SkillRegistryOptions = {}) {\n const config = resolveRegistryConfig(options);\n this.#multiple = config.containers !== undefined;\n const fetchBatch = batchLoader(config.client);\n this.#sources =\n config.containers !== undefined\n ? config.containers.map(({ id, revision }) => ({\n id,\n registry: new SingleContainerRegistry(\n Object.freeze({\n client: config.client,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n containerId: id,\n ...(revision !== undefined ? { revision } : {}),\n }),\n fetchBatch,\n ),\n }))\n : [\n {\n id: config.containerId!,\n registry: new SingleContainerRegistry({\n client: config.client,\n containerId: config.containerId!,\n revision: config.revision,\n freshnessWindowMs: config.freshnessWindowMs,\n requestTimeoutMs: config.requestTimeoutMs,\n debug: config.debug,\n }),\n },\n ];\n }\n\n /** Load every configured container before agent initialization completes. */\n async initialize(): Promise<void> {\n await this.acquireSnapshot();\n }\n\n /** Capture every container once; a failed source cannot yield a partial catalog. */\n acquireSnapshot(): Promise<VerifiedSnapshot> {\n if (!this.#multiple) return this.#sources[0].registry.acquireSnapshot();\n if (this.#inFlight) return this.#inFlight;\n this.#inFlight = Promise.all(\n this.#sources.map(({ registry }) => registry.acquireSnapshot()),\n )\n .then(async (parts) => {\n if (\n this.#snapshot &&\n parts.every((part, index) => part === this.#parts?.[index])\n ) {\n return this.#snapshot;\n }\n const identity = await sha256Hex(\n JSON.stringify(\n parts.map((part, index) => [\n this.#sources[index].id,\n part.revision,\n part.etag,\n ]),\n ),\n );\n const skills = Object.freeze(\n parts.flatMap((part, index) =>\n part.skills.map((skill) =>\n Object.freeze({\n ...skill,\n name: `${encodeURIComponent(this.#sources[index].id)}/${skill.name}`,\n }),\n ),\n ),\n );\n this.#parts = parts;\n this.#snapshot = Object.freeze({\n revision: `multi:${identity}`,\n etag: `\"${identity}\"`,\n skills,\n });\n return this.#snapshot;\n })\n .finally(() => {\n this.#inFlight = undefined;\n });\n return this.#inFlight;\n }\n\n /** Report each container's real revision; no aggregate server revision exists. */\n get status(): SkillRegistryStatus {\n if (!this.#multiple) return this.#sources[0].registry.status;\n const containers = Object.freeze(\n this.#sources.map(({ id, registry }) =>\n Object.freeze({ id, ...registry.status }),\n ),\n );\n const error =\n containers.find(\n (source) => source.lastError && !source.lastError.retryable,\n )?.lastError ?? containers.find((source) => source.lastError)?.lastError;\n const timestamps = containers.map((source) => source.lastCheckedAt);\n return Object.freeze({\n initialized: this.#snapshot !== undefined,\n mode: containers.every((source) => source.mode === \"pinned\")\n ? \"pinned\"\n : \"latest\",\n stale: containers.some((source) => source.stale),\n ...(timestamps.every((timestamp) => timestamp !== undefined)\n ? { lastCheckedAt: [...timestamps].sort()[0] }\n : {}),\n ...(error ? { lastError: error } : {}),\n containers,\n });\n }\n}\n"],"mappings":"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"}
@@ -1,16 +1,12 @@
1
- const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
2
1
  const require_learned_skills = require('../learned-skills.cjs');
2
+ const require_web_crypto = require('../../core/web-crypto.cjs');
3
3
  const require_errors = require('./errors.cjs');
4
4
  const require_archive = require('./archive.cjs');
5
- let node_crypto = require("node:crypto");
6
5
 
7
6
  //#region src/runtime/intelligence-platform/skill-registry/snapshot.ts
8
7
  function object(value) {
9
8
  return value !== null && typeof value === "object" && !Array.isArray(value);
10
9
  }
11
- function sha256(bytes) {
12
- return (0, node_crypto.createHash)("sha256").update(bytes).digest("hex");
13
- }
14
10
  function utf8(bytes) {
15
11
  try {
16
12
  return new TextDecoder("utf-8", {
@@ -28,7 +24,7 @@ async function validateSnapshot(response, signal) {
28
24
  const { revision, etag, contentType } = response;
29
25
  if (response.status !== "snapshot" || response.bytes.byteLength > require_archive.MAX_SNAPSHOT_BYTES || contentType.split(";", 1)[0]?.trim().toLowerCase() !== "application/zip" || !revision || !/^"[a-f0-9]{64}"$/.test(etag)) throw require_errors.invalidSnapshot();
30
26
  const bytes = Buffer.from(response.bytes);
31
- if (`"${sha256(bytes)}"` !== etag) throw require_errors.invalidSnapshot();
27
+ if (`"${await require_web_crypto.sha256Hex(bytes)}"` !== etag) throw require_errors.invalidSnapshot();
32
28
  const archive = await require_archive.readArchive(bytes, signal);
33
29
  const manifestBytes = archive.get("manifest.json");
34
30
  if (!manifestBytes) throw require_errors.invalidSnapshot();
@@ -54,7 +50,7 @@ async function validateSnapshot(response, signal) {
54
50
  if (expected.has(path)) throw require_errors.invalidSnapshot();
55
51
  expected.add(path);
56
52
  const content = archive.get(path);
57
- if (!content || content.length !== file.size || sha256(content) !== file.sha256) throw require_errors.invalidSnapshot();
53
+ if (!content || content.length !== file.size || await require_web_crypto.sha256Hex(content) !== file.sha256) throw require_errors.invalidSnapshot();
58
54
  const text = utf8(content);
59
55
  if (file.path === "SKILL.md") {
60
56
  if (text === void 0) throw require_errors.invalidSnapshot();
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.cjs","names":["invalidSnapshot","MAX_SNAPSHOT_BYTES","readArchive","SkillDeliveryError","safeRelativePath"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { LearnedSkillsSnapshotResult } from \"../learned-skills\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from \"./archive\";\n\nexport interface SnapshotFile {\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n /** Absent for supporting resources that cannot be decoded as UTF-8 text. */\n readonly text?: string;\n}\nexport interface SnapshotSkill {\n readonly name: string;\n readonly description: string;\n readonly files: readonly SnapshotFile[];\n}\nexport interface VerifiedSnapshot {\n readonly revision: string;\n readonly etag: string;\n readonly skills: readonly SnapshotSkill[];\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction sha256(bytes: Uint8Array): string {\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\nfunction utf8(bytes: Uint8Array): string | undefined {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n return undefined;\n }\n}\n\n/** Validate a replacement fully before it can become an invocation snapshot. */\nexport async function validateSnapshot(\n response: Extract<LearnedSkillsSnapshotResult, { status: \"snapshot\" }>,\n signal?: AbortSignal,\n): Promise<VerifiedSnapshot> {\n try {\n if (\n !object(response) ||\n !(response.bytes instanceof Uint8Array) ||\n typeof response.revision !== \"string\" ||\n typeof response.etag !== \"string\" ||\n typeof response.contentType !== \"string\"\n )\n throw invalidSnapshot();\n const { revision, etag, contentType } = response;\n if (\n response.status !== \"snapshot\" ||\n response.bytes.byteLength > MAX_SNAPSHOT_BYTES ||\n contentType.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/zip\" ||\n !revision ||\n !/^\"[a-f0-9]{64}\"$/.test(etag)\n )\n throw invalidSnapshot();\n // Own the bytes before asynchronous decompression so an injected client\n // cannot mutate an in-flight replacement after its digest is checked.\n const bytes = Buffer.from(response.bytes);\n if (`\"${sha256(bytes)}\"` !== etag) throw invalidSnapshot();\n const archive = await readArchive(bytes, signal);\n const manifestBytes = archive.get(\"manifest.json\");\n if (!manifestBytes) throw invalidSnapshot();\n const decoded = utf8(manifestBytes);\n if (decoded === undefined) throw invalidSnapshot();\n const manifest: unknown = JSON.parse(decoded);\n if (!object(manifest)) throw invalidSnapshot();\n if (\n typeof manifest.schemaVersion === \"number\" &&\n manifest.schemaVersion !== 1\n )\n throw new SkillDeliveryError(\"UNSUPPORTED_SERVER\", false);\n if (\n manifest.schemaVersion !== 1 ||\n manifest.revision !== revision ||\n !Array.isArray(manifest.skills)\n )\n throw invalidSnapshot();\n const expected = new Set([\"manifest.json\"]);\n let previousName: string | undefined;\n const skills: SnapshotSkill[] = [];\n for (const skill of manifest.skills) {\n if (\n !object(skill) ||\n typeof skill.name !== \"string\" ||\n !safeRelativePath(skill.name) ||\n skill.name.includes(\"/\") ||\n (previousName !== undefined &&\n Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >=\n 0) ||\n typeof skill.description !== \"string\" ||\n !Array.isArray(skill.files)\n )\n throw invalidSnapshot();\n previousName = skill.name;\n let previousPath: string | undefined;\n let hasSkill = false;\n const files: SnapshotFile[] = [];\n for (const file of skill.files) {\n if (\n !object(file) ||\n typeof file.path !== \"string\" ||\n !safeRelativePath(file.path) ||\n (previousPath !== undefined &&\n Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >=\n 0) ||\n typeof file.size !== \"number\" ||\n !Number.isSafeInteger(file.size) ||\n file.size < 0 ||\n typeof file.sha256 !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(file.sha256)\n )\n throw invalidSnapshot();\n previousPath = file.path;\n const path = `${skill.name}/${file.path}`;\n if (expected.has(path)) throw invalidSnapshot();\n expected.add(path);\n const content = archive.get(path);\n if (\n !content ||\n content.length !== file.size ||\n sha256(content) !== file.sha256\n )\n throw invalidSnapshot();\n const text = utf8(content);\n if (file.path === \"SKILL.md\") {\n if (text === undefined) throw invalidSnapshot();\n hasSkill = true;\n }\n files.push(\n Object.freeze({\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n ...(text !== undefined ? { text } : {}),\n }),\n );\n }\n if (!hasSkill) throw invalidSnapshot();\n skills.push(\n Object.freeze({\n name: skill.name,\n description: skill.description,\n files: Object.freeze(files),\n }),\n );\n }\n if (\n expected.size !== archive.size ||\n [...archive.keys()].some((path) => !expected.has(path))\n )\n throw invalidSnapshot();\n return Object.freeze({\n revision: revision,\n etag: etag,\n skills: Object.freeze(skills),\n });\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof SkillDeliveryError) throw error;\n throw invalidSnapshot(error);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.cjs","names":["invalidSnapshot","MAX_SNAPSHOT_BYTES","sha256Hex","readArchive","SkillDeliveryError","safeRelativePath"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"sourcesContent":["import type { LearnedSkillsSnapshotResult } from \"../learned-skills\";\nimport { sha256Hex } from \"../../core/web-crypto\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from \"./archive\";\n\nexport interface SnapshotFile {\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n /** Absent for supporting resources that cannot be decoded as UTF-8 text. */\n readonly text?: string;\n}\nexport interface SnapshotSkill {\n readonly name: string;\n readonly description: string;\n readonly files: readonly SnapshotFile[];\n}\nexport interface VerifiedSnapshot {\n readonly revision: string;\n readonly etag: string;\n readonly skills: readonly SnapshotSkill[];\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction utf8(bytes: Uint8Array): string | undefined {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n return undefined;\n }\n}\n\n/** Validate a replacement fully before it can become an invocation snapshot. */\nexport async function validateSnapshot(\n response: Extract<LearnedSkillsSnapshotResult, { status: \"snapshot\" }>,\n signal?: AbortSignal,\n): Promise<VerifiedSnapshot> {\n try {\n if (\n !object(response) ||\n !(response.bytes instanceof Uint8Array) ||\n typeof response.revision !== \"string\" ||\n typeof response.etag !== \"string\" ||\n typeof response.contentType !== \"string\"\n )\n throw invalidSnapshot();\n const { revision, etag, contentType } = response;\n if (\n response.status !== \"snapshot\" ||\n response.bytes.byteLength > MAX_SNAPSHOT_BYTES ||\n contentType.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/zip\" ||\n !revision ||\n !/^\"[a-f0-9]{64}\"$/.test(etag)\n )\n throw invalidSnapshot();\n // Own the bytes before asynchronous decompression so an injected client\n // cannot mutate an in-flight replacement after its digest is checked.\n const bytes = Buffer.from(response.bytes);\n if (`\"${await sha256Hex(bytes)}\"` !== etag) throw invalidSnapshot();\n const archive = await readArchive(bytes, signal);\n const manifestBytes = archive.get(\"manifest.json\");\n if (!manifestBytes) throw invalidSnapshot();\n const decoded = utf8(manifestBytes);\n if (decoded === undefined) throw invalidSnapshot();\n const manifest: unknown = JSON.parse(decoded);\n if (!object(manifest)) throw invalidSnapshot();\n if (\n typeof manifest.schemaVersion === \"number\" &&\n manifest.schemaVersion !== 1\n )\n throw new SkillDeliveryError(\"UNSUPPORTED_SERVER\", false);\n if (\n manifest.schemaVersion !== 1 ||\n manifest.revision !== revision ||\n !Array.isArray(manifest.skills)\n )\n throw invalidSnapshot();\n const expected = new Set([\"manifest.json\"]);\n let previousName: string | undefined;\n const skills: SnapshotSkill[] = [];\n for (const skill of manifest.skills) {\n if (\n !object(skill) ||\n typeof skill.name !== \"string\" ||\n !safeRelativePath(skill.name) ||\n skill.name.includes(\"/\") ||\n (previousName !== undefined &&\n Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >=\n 0) ||\n typeof skill.description !== \"string\" ||\n !Array.isArray(skill.files)\n )\n throw invalidSnapshot();\n previousName = skill.name;\n let previousPath: string | undefined;\n let hasSkill = false;\n const files: SnapshotFile[] = [];\n for (const file of skill.files) {\n if (\n !object(file) ||\n typeof file.path !== \"string\" ||\n !safeRelativePath(file.path) ||\n (previousPath !== undefined &&\n Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >=\n 0) ||\n typeof file.size !== \"number\" ||\n !Number.isSafeInteger(file.size) ||\n file.size < 0 ||\n typeof file.sha256 !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(file.sha256)\n )\n throw invalidSnapshot();\n previousPath = file.path;\n const path = `${skill.name}/${file.path}`;\n if (expected.has(path)) throw invalidSnapshot();\n expected.add(path);\n const content = archive.get(path);\n if (\n !content ||\n content.length !== file.size ||\n (await sha256Hex(content)) !== file.sha256\n )\n throw invalidSnapshot();\n const text = utf8(content);\n if (file.path === \"SKILL.md\") {\n if (text === undefined) throw invalidSnapshot();\n hasSkill = true;\n }\n files.push(\n Object.freeze({\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n ...(text !== undefined ? { text } : {}),\n }),\n );\n }\n if (!hasSkill) throw invalidSnapshot();\n skills.push(\n Object.freeze({\n name: skill.name,\n description: skill.description,\n files: Object.freeze(files),\n }),\n );\n }\n if (\n expected.size !== archive.size ||\n [...archive.keys()].some((path) => !expected.has(path))\n )\n throw invalidSnapshot();\n return Object.freeze({\n revision: revision,\n etag: etag,\n skills: Object.freeze(skills),\n });\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof SkillDeliveryError) throw error;\n throw invalidSnapshot(error);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;;WAEA,IAAA;AAAA;AAAA,UAEM,aAAA;EAAA,SACN,IAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA,WAAgB,YAAA;AAAA;AAAA,UAEV,gBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA,WAAiB,aAAA;AAAA;;iBAoBN,gBAAA,CACpB,QAAA,EAAU,OAAA,CAAQ,2BAAA;EAA+B,MAAA;AAAA,IACjD,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,gBAAA"}
1
+ {"version":3,"file":"snapshot.d.cts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;;WAEA,IAAA;AAAA;AAAA,UAEM,aAAA;EAAA,SACN,IAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA,WAAgB,YAAA;AAAA;AAAA,UAEV,gBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA,WAAiB,aAAA;AAAA;;iBAiBN,gBAAA,CACpB,QAAA,EAAU,OAAA,CAAQ,2BAAA;EAA+B,MAAA;AAAA,IACjD,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;;WAEA,IAAA;AAAA;AAAA,UAEM,aAAA;EAAA,SACN,IAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA,WAAgB,YAAA;AAAA;AAAA,UAEV,gBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA,WAAiB,aAAA;AAAA;;iBAoBN,gBAAA,CACpB,QAAA,EAAU,OAAA,CAAQ,2BAAA;EAA+B,MAAA;AAAA,IACjD,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,gBAAA"}
1
+ {"version":3,"file":"snapshot.d.mts","names":[],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"mappings":";;;UAKiB,YAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;;WAEA,IAAA;AAAA;AAAA,UAEM,aAAA;EAAA,SACN,IAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA,WAAgB,YAAA;AAAA;AAAA,UAEV,gBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA,WAAiB,aAAA;AAAA;;iBAiBN,gBAAA,CACpB,QAAA,EAAU,OAAA,CAAQ,2BAAA;EAA+B,MAAA;AAAA,IACjD,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,gBAAA"}
@@ -1,15 +1,12 @@
1
1
  import { LearnedSkillsError } from "../learned-skills.mjs";
2
+ import { sha256Hex } from "../../core/web-crypto.mjs";
2
3
  import { invalidSnapshot } from "./errors.mjs";
3
4
  import { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from "./archive.mjs";
4
- import { createHash } from "node:crypto";
5
5
 
6
6
  //#region src/runtime/intelligence-platform/skill-registry/snapshot.ts
7
7
  function object(value) {
8
8
  return value !== null && typeof value === "object" && !Array.isArray(value);
9
9
  }
10
- function sha256(bytes) {
11
- return createHash("sha256").update(bytes).digest("hex");
12
- }
13
10
  function utf8(bytes) {
14
11
  try {
15
12
  return new TextDecoder("utf-8", {
@@ -27,7 +24,7 @@ async function validateSnapshot(response, signal) {
27
24
  const { revision, etag, contentType } = response;
28
25
  if (response.status !== "snapshot" || response.bytes.byteLength > MAX_SNAPSHOT_BYTES || contentType.split(";", 1)[0]?.trim().toLowerCase() !== "application/zip" || !revision || !/^"[a-f0-9]{64}"$/.test(etag)) throw invalidSnapshot();
29
26
  const bytes = Buffer.from(response.bytes);
30
- if (`"${sha256(bytes)}"` !== etag) throw invalidSnapshot();
27
+ if (`"${await sha256Hex(bytes)}"` !== etag) throw invalidSnapshot();
31
28
  const archive = await readArchive(bytes, signal);
32
29
  const manifestBytes = archive.get("manifest.json");
33
30
  if (!manifestBytes) throw invalidSnapshot();
@@ -53,7 +50,7 @@ async function validateSnapshot(response, signal) {
53
50
  if (expected.has(path)) throw invalidSnapshot();
54
51
  expected.add(path);
55
52
  const content = archive.get(path);
56
- if (!content || content.length !== file.size || sha256(content) !== file.sha256) throw invalidSnapshot();
53
+ if (!content || content.length !== file.size || await sha256Hex(content) !== file.sha256) throw invalidSnapshot();
57
54
  const text = utf8(content);
58
55
  if (file.path === "SKILL.md") {
59
56
  if (text === void 0) throw invalidSnapshot();
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.mjs","names":["SkillDeliveryError"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { LearnedSkillsSnapshotResult } from \"../learned-skills\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from \"./archive\";\n\nexport interface SnapshotFile {\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n /** Absent for supporting resources that cannot be decoded as UTF-8 text. */\n readonly text?: string;\n}\nexport interface SnapshotSkill {\n readonly name: string;\n readonly description: string;\n readonly files: readonly SnapshotFile[];\n}\nexport interface VerifiedSnapshot {\n readonly revision: string;\n readonly etag: string;\n readonly skills: readonly SnapshotSkill[];\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction sha256(bytes: Uint8Array): string {\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\nfunction utf8(bytes: Uint8Array): string | undefined {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n return undefined;\n }\n}\n\n/** Validate a replacement fully before it can become an invocation snapshot. */\nexport async function validateSnapshot(\n response: Extract<LearnedSkillsSnapshotResult, { status: \"snapshot\" }>,\n signal?: AbortSignal,\n): Promise<VerifiedSnapshot> {\n try {\n if (\n !object(response) ||\n !(response.bytes instanceof Uint8Array) ||\n typeof response.revision !== \"string\" ||\n typeof response.etag !== \"string\" ||\n typeof response.contentType !== \"string\"\n )\n throw invalidSnapshot();\n const { revision, etag, contentType } = response;\n if (\n response.status !== \"snapshot\" ||\n response.bytes.byteLength > MAX_SNAPSHOT_BYTES ||\n contentType.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/zip\" ||\n !revision ||\n !/^\"[a-f0-9]{64}\"$/.test(etag)\n )\n throw invalidSnapshot();\n // Own the bytes before asynchronous decompression so an injected client\n // cannot mutate an in-flight replacement after its digest is checked.\n const bytes = Buffer.from(response.bytes);\n if (`\"${sha256(bytes)}\"` !== etag) throw invalidSnapshot();\n const archive = await readArchive(bytes, signal);\n const manifestBytes = archive.get(\"manifest.json\");\n if (!manifestBytes) throw invalidSnapshot();\n const decoded = utf8(manifestBytes);\n if (decoded === undefined) throw invalidSnapshot();\n const manifest: unknown = JSON.parse(decoded);\n if (!object(manifest)) throw invalidSnapshot();\n if (\n typeof manifest.schemaVersion === \"number\" &&\n manifest.schemaVersion !== 1\n )\n throw new SkillDeliveryError(\"UNSUPPORTED_SERVER\", false);\n if (\n manifest.schemaVersion !== 1 ||\n manifest.revision !== revision ||\n !Array.isArray(manifest.skills)\n )\n throw invalidSnapshot();\n const expected = new Set([\"manifest.json\"]);\n let previousName: string | undefined;\n const skills: SnapshotSkill[] = [];\n for (const skill of manifest.skills) {\n if (\n !object(skill) ||\n typeof skill.name !== \"string\" ||\n !safeRelativePath(skill.name) ||\n skill.name.includes(\"/\") ||\n (previousName !== undefined &&\n Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >=\n 0) ||\n typeof skill.description !== \"string\" ||\n !Array.isArray(skill.files)\n )\n throw invalidSnapshot();\n previousName = skill.name;\n let previousPath: string | undefined;\n let hasSkill = false;\n const files: SnapshotFile[] = [];\n for (const file of skill.files) {\n if (\n !object(file) ||\n typeof file.path !== \"string\" ||\n !safeRelativePath(file.path) ||\n (previousPath !== undefined &&\n Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >=\n 0) ||\n typeof file.size !== \"number\" ||\n !Number.isSafeInteger(file.size) ||\n file.size < 0 ||\n typeof file.sha256 !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(file.sha256)\n )\n throw invalidSnapshot();\n previousPath = file.path;\n const path = `${skill.name}/${file.path}`;\n if (expected.has(path)) throw invalidSnapshot();\n expected.add(path);\n const content = archive.get(path);\n if (\n !content ||\n content.length !== file.size ||\n sha256(content) !== file.sha256\n )\n throw invalidSnapshot();\n const text = utf8(content);\n if (file.path === \"SKILL.md\") {\n if (text === undefined) throw invalidSnapshot();\n hasSkill = true;\n }\n files.push(\n Object.freeze({\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n ...(text !== undefined ? { text } : {}),\n }),\n );\n }\n if (!hasSkill) throw invalidSnapshot();\n skills.push(\n Object.freeze({\n name: skill.name,\n description: skill.description,\n files: Object.freeze(files),\n }),\n );\n }\n if (\n expected.size !== archive.size ||\n [...archive.keys()].some((path) => !expected.has(path))\n )\n throw invalidSnapshot();\n return Object.freeze({\n revision: revision,\n etag: etag,\n skills: Object.freeze(skills),\n });\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof SkillDeliveryError) throw error;\n throw invalidSnapshot(error);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.mjs","names":["SkillDeliveryError"],"sources":["../../../../src/runtime/intelligence-platform/skill-registry/snapshot.ts"],"sourcesContent":["import type { LearnedSkillsSnapshotResult } from \"../learned-skills\";\nimport { sha256Hex } from \"../../core/web-crypto\";\nimport { SkillDeliveryError, invalidSnapshot } from \"./errors\";\nimport { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from \"./archive\";\n\nexport interface SnapshotFile {\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n /** Absent for supporting resources that cannot be decoded as UTF-8 text. */\n readonly text?: string;\n}\nexport interface SnapshotSkill {\n readonly name: string;\n readonly description: string;\n readonly files: readonly SnapshotFile[];\n}\nexport interface VerifiedSnapshot {\n readonly revision: string;\n readonly etag: string;\n readonly skills: readonly SnapshotSkill[];\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\nfunction utf8(bytes: Uint8Array): string | undefined {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(\n bytes,\n );\n } catch {\n return undefined;\n }\n}\n\n/** Validate a replacement fully before it can become an invocation snapshot. */\nexport async function validateSnapshot(\n response: Extract<LearnedSkillsSnapshotResult, { status: \"snapshot\" }>,\n signal?: AbortSignal,\n): Promise<VerifiedSnapshot> {\n try {\n if (\n !object(response) ||\n !(response.bytes instanceof Uint8Array) ||\n typeof response.revision !== \"string\" ||\n typeof response.etag !== \"string\" ||\n typeof response.contentType !== \"string\"\n )\n throw invalidSnapshot();\n const { revision, etag, contentType } = response;\n if (\n response.status !== \"snapshot\" ||\n response.bytes.byteLength > MAX_SNAPSHOT_BYTES ||\n contentType.split(\";\", 1)[0]?.trim().toLowerCase() !==\n \"application/zip\" ||\n !revision ||\n !/^\"[a-f0-9]{64}\"$/.test(etag)\n )\n throw invalidSnapshot();\n // Own the bytes before asynchronous decompression so an injected client\n // cannot mutate an in-flight replacement after its digest is checked.\n const bytes = Buffer.from(response.bytes);\n if (`\"${await sha256Hex(bytes)}\"` !== etag) throw invalidSnapshot();\n const archive = await readArchive(bytes, signal);\n const manifestBytes = archive.get(\"manifest.json\");\n if (!manifestBytes) throw invalidSnapshot();\n const decoded = utf8(manifestBytes);\n if (decoded === undefined) throw invalidSnapshot();\n const manifest: unknown = JSON.parse(decoded);\n if (!object(manifest)) throw invalidSnapshot();\n if (\n typeof manifest.schemaVersion === \"number\" &&\n manifest.schemaVersion !== 1\n )\n throw new SkillDeliveryError(\"UNSUPPORTED_SERVER\", false);\n if (\n manifest.schemaVersion !== 1 ||\n manifest.revision !== revision ||\n !Array.isArray(manifest.skills)\n )\n throw invalidSnapshot();\n const expected = new Set([\"manifest.json\"]);\n let previousName: string | undefined;\n const skills: SnapshotSkill[] = [];\n for (const skill of manifest.skills) {\n if (\n !object(skill) ||\n typeof skill.name !== \"string\" ||\n !safeRelativePath(skill.name) ||\n skill.name.includes(\"/\") ||\n (previousName !== undefined &&\n Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >=\n 0) ||\n typeof skill.description !== \"string\" ||\n !Array.isArray(skill.files)\n )\n throw invalidSnapshot();\n previousName = skill.name;\n let previousPath: string | undefined;\n let hasSkill = false;\n const files: SnapshotFile[] = [];\n for (const file of skill.files) {\n if (\n !object(file) ||\n typeof file.path !== \"string\" ||\n !safeRelativePath(file.path) ||\n (previousPath !== undefined &&\n Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >=\n 0) ||\n typeof file.size !== \"number\" ||\n !Number.isSafeInteger(file.size) ||\n file.size < 0 ||\n typeof file.sha256 !== \"string\" ||\n !/^[a-f0-9]{64}$/.test(file.sha256)\n )\n throw invalidSnapshot();\n previousPath = file.path;\n const path = `${skill.name}/${file.path}`;\n if (expected.has(path)) throw invalidSnapshot();\n expected.add(path);\n const content = archive.get(path);\n if (\n !content ||\n content.length !== file.size ||\n (await sha256Hex(content)) !== file.sha256\n )\n throw invalidSnapshot();\n const text = utf8(content);\n if (file.path === \"SKILL.md\") {\n if (text === undefined) throw invalidSnapshot();\n hasSkill = true;\n }\n files.push(\n Object.freeze({\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n ...(text !== undefined ? { text } : {}),\n }),\n );\n }\n if (!hasSkill) throw invalidSnapshot();\n skills.push(\n Object.freeze({\n name: skill.name,\n description: skill.description,\n files: Object.freeze(files),\n }),\n );\n }\n if (\n expected.size !== archive.size ||\n [...archive.keys()].some((path) => !expected.has(path))\n )\n throw invalidSnapshot();\n return Object.freeze({\n revision: revision,\n etag: etag,\n skills: Object.freeze(skills),\n });\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof SkillDeliveryError) throw error;\n throw invalidSnapshot(error);\n }\n}\n"],"mappings":"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"}
@@ -4,7 +4,6 @@ let _copilotkit_shared = require("@copilotkit/shared");
4
4
  let rxjs = require("rxjs");
5
5
  let _ag_ui_client = require("@ag-ui/client");
6
6
  let phoenix = require("phoenix");
7
- let node_crypto = require("node:crypto");
8
7
 
9
8
  //#region src/runtime/runner/intelligence.ts
10
9
  const MAX_CONSECUTIVE_SOCKET_ERRORS = 5;
@@ -95,7 +94,7 @@ var IntelligenceAgentRunner = class extends require_agent_runner.AgentRunner {
95
94
  const eventSeq = state.nextEventSeq++;
96
95
  eventRecord.metadata = {
97
96
  ...existingMetadata,
98
- cpki_event_id: typeof existingMetadata.cpki_event_id === "string" ? existingMetadata.cpki_event_id : (0, node_crypto.randomUUID)(),
97
+ cpki_event_id: typeof existingMetadata.cpki_event_id === "string" ? existingMetadata.cpki_event_id : globalThis.crypto.randomUUID(),
99
98
  cpki_event_seq: eventSeq
100
99
  };
101
100
  return eventRecord;