@copilotkit/runtime 1.72.1-canary.sp-longthread-perf → 1.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +49 -9
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +20 -7
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +19 -6
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +49 -9
- package/dist/agent/index.mjs.map +1 -1
- package/dist/agent/learned-skills.cjs +77 -0
- package/dist/agent/learned-skills.cjs.map +1 -0
- package/dist/agent/learned-skills.d.cts +16 -0
- package/dist/agent/learned-skills.d.cts.map +1 -0
- package/dist/agent/learned-skills.d.mts +16 -0
- package/dist/agent/learned-skills.d.mts.map +1 -0
- package/dist/agent/learned-skills.mjs +75 -0
- package/dist/agent/learned-skills.mjs.map +1 -0
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/internal/learned-skills.cjs +22 -0
- package/dist/internal/learned-skills.d.cts +10 -0
- package/dist/internal/learned-skills.d.mts +10 -0
- package/dist/internal/learned-skills.mjs +10 -0
- package/dist/lib/index.d.cts +2 -2
- package/dist/lib/index.d.mts +2 -2
- package/dist/lib/integrations/nextjs/app-router.cjs +1 -1
- package/dist/lib/integrations/nextjs/app-router.cjs.map +1 -1
- package/dist/lib/integrations/nextjs/app-router.mjs +1 -1
- package/dist/lib/integrations/nextjs/app-router.mjs.map +1 -1
- package/dist/lib/integrations/node-http/index.cjs +1 -1
- package/dist/lib/integrations/node-http/index.cjs.map +1 -1
- package/dist/lib/integrations/node-http/index.d.cts.map +1 -1
- package/dist/lib/integrations/node-http/index.d.mts.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +1 -1
- package/dist/lib/integrations/node-http/index.mjs.map +1 -1
- package/dist/lib/integrations/shared.cjs.map +1 -1
- package/dist/lib/integrations/shared.d.cts +1 -1
- package/dist/lib/integrations/shared.d.cts.map +1 -1
- package/dist/lib/integrations/shared.d.mts +1 -1
- package/dist/lib/integrations/shared.d.mts.map +1 -1
- package/dist/lib/integrations/shared.mjs.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +79 -37
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts +54 -4
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts +56 -6
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +79 -37
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/lib/runtime/mcp-client-cache.cjs +135 -0
- package/dist/lib/runtime/mcp-client-cache.cjs.map +1 -0
- package/dist/lib/runtime/mcp-client-cache.mjs +132 -0
- package/dist/lib/runtime/mcp-client-cache.mjs.map +1 -0
- package/dist/lib/runtime/telemetry-agent-runner.cjs.map +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.cts +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.mts +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.mjs.map +1 -1
- package/dist/package.cjs +15 -7
- package/dist/package.mjs +15 -7
- package/dist/service-adapters/anthropic/anthropic-adapter.cjs.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.d.cts.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.d.mts.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.mjs.map +1 -1
- package/dist/service-adapters/shared/sdk-client-utils.cjs.map +1 -1
- package/dist/service-adapters/shared/sdk-client-utils.d.cts.map +1 -1
- package/dist/service-adapters/shared/sdk-client-utils.d.mts.map +1 -1
- package/dist/service-adapters/shared/sdk-client-utils.mjs.map +1 -1
- package/dist/v2/index.cjs +9 -3
- package/dist/v2/index.d.cts +12 -11
- package/dist/v2/index.d.mts +12 -11
- package/dist/v2/index.mjs +5 -5
- package/dist/v2/runtime/core/channel-manager.cjs +1 -1
- package/dist/v2/runtime/core/channel-manager.d.cts +1 -1
- package/dist/v2/runtime/core/channel-manager.d.mts +1 -1
- package/dist/v2/runtime/core/channel-manager.mjs +1 -1
- package/dist/v2/runtime/core/fetch-handler.cjs +1 -0
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.cts +2 -2
- package/dist/v2/runtime/core/fetch-handler.d.mts +2 -2
- package/dist/v2/runtime/core/fetch-handler.mjs +1 -0
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/core/runtime.cjs +5 -0
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +18 -3
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +17 -2
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +5 -0
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/express-single.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/express-single.d.cts +2 -2
- package/dist/v2/runtime/endpoints/express-single.d.cts.map +1 -1
- package/dist/v2/runtime/endpoints/express-single.d.mts +2 -2
- package/dist/v2/runtime/endpoints/express-single.d.mts.map +1 -1
- package/dist/v2/runtime/endpoints/express-single.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.cjs +2 -3
- package/dist/v2/runtime/endpoints/express.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.d.cts +26 -7
- package/dist/v2/runtime/endpoints/express.d.cts.map +1 -1
- package/dist/v2/runtime/endpoints/express.d.mts +26 -7
- package/dist/v2/runtime/endpoints/express.d.mts.map +1 -1
- package/dist/v2/runtime/endpoints/express.mjs +2 -2
- package/dist/v2/runtime/endpoints/express.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/hono.d.cts +2 -2
- package/dist/v2/runtime/endpoints/hono.d.mts +2 -2
- package/dist/v2/runtime/endpoints/index.d.cts +3 -3
- package/dist/v2/runtime/endpoints/index.d.mts +3 -3
- package/dist/v2/runtime/endpoints/load-express.cjs +36 -0
- package/dist/v2/runtime/endpoints/load-express.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/load-express.mjs +35 -0
- package/dist/v2/runtime/endpoints/load-express.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-stop.cjs +18 -14
- package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-stop.mjs +18 -14
- package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-suggest.cjs +4 -3
- package/dist/v2/runtime/handlers/handle-suggest.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-suggest.mjs +5 -4
- package/dist/v2/runtime/handlers/handle-suggest.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +3 -4
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +1 -2
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-keep-alive.cjs +69 -0
- package/dist/v2/runtime/handlers/shared/sse-keep-alive.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/sse-keep-alive.mjs +67 -0
- package/dist/v2/runtime/handlers/shared/sse-keep-alive.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +5 -2
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +5 -2
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.cjs +1 -0
- package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.mjs +1 -0
- package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.cjs +1 -0
- package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.mjs +1 -0
- package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
- package/dist/v2/runtime/index.d.cts +9 -9
- package/dist/v2/runtime/index.d.mts +9 -9
- package/dist/v2/runtime/intelligence-platform/client.cjs +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.cjs +132 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.d.cts +11 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.d.mts +11 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.mjs +128 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/archive.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs +48 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts +27 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts +27 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs +48 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.cjs +11 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.d.cts +8 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.d.mts +8 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.mjs +11 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/errors.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.cts +8 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.mts +8 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs +132 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts +31 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts +31 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs +132 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.cjs +42 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.d.cts +13 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.d.mts +13 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.mjs +39 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/skill-content.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.cjs +93 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.d.cts +28 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.d.mts +28 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.mjs +92 -0
- package/dist/v2/runtime/intelligence-platform/skill-registry/snapshot.mjs.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.d.cts +1 -1
- package/dist/v2/runtime/runner/in-memory.d.cts +1 -1
- package/dist/v2/runtime/runner/index.d.cts +2 -2
- package/dist/v2/runtime/runner/index.d.mts +2 -2
- package/dist/v2/runtime/runner/index.mjs +2 -2
- package/dist/v2/runtime/runner/intelligence.d.cts +1 -1
- package/package.json +17 -7
- package/dist/v2/runtime/open-generative-ui-middleware.cjs +0 -286
- package/dist/v2/runtime/open-generative-ui-middleware.cjs.map +0 -1
- package/dist/v2/runtime/open-generative-ui-middleware.mjs +0 -284
- package/dist/v2/runtime/open-generative-ui-middleware.mjs.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import { LearnedSkillsErrorCode } from "../learned-skills.cjs";
|
|
3
|
+
import { SkillRegistryOptions } from "./config.cjs";
|
|
4
|
+
import { VerifiedSnapshot } from "./snapshot.cjs";
|
|
5
|
+
|
|
6
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/registry.d.ts
|
|
7
|
+
interface SkillRegistryStatus {
|
|
8
|
+
readonly initialized: boolean;
|
|
9
|
+
readonly revision?: string;
|
|
10
|
+
readonly mode: "latest" | "pinned";
|
|
11
|
+
/** ISO 8601 timestamp of the last successful 200 or matching 304 check. */
|
|
12
|
+
readonly lastCheckedAt?: string;
|
|
13
|
+
readonly stale: boolean;
|
|
14
|
+
readonly lastError?: Readonly<{
|
|
15
|
+
code: LearnedSkillsErrorCode;
|
|
16
|
+
message: string;
|
|
17
|
+
retryable: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/** Internal registry shared by framework adapters; public API is framework-native. */
|
|
21
|
+
declare class SkillRegistry {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(options?: SkillRegistryOptions);
|
|
24
|
+
initialize(): Promise<void>;
|
|
25
|
+
/** Capture exactly one immutable snapshot before model work begins. */
|
|
26
|
+
acquireSnapshot(): Promise<VerifiedSnapshot>;
|
|
27
|
+
get status(): SkillRegistryStatus;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { SkillRegistry, SkillRegistryStatus };
|
|
31
|
+
//# sourceMappingURL=registry.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.cts","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;;UAOiB,mBAAA;EAAA,SACN,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;;WAEA,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAwBS,aAAA;EAAA;cASC,OAAA,GAAS,oBAAA;EAIf,UAAA,CAAA,GAAc,OAAA;EArCT;EA0CX,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EAAA,IAoBvB,MAAA,CAAA,GAAU,mBAAA;AAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import { LearnedSkillsErrorCode } from "../learned-skills.mjs";
|
|
3
|
+
import { SkillRegistryOptions } from "./config.mjs";
|
|
4
|
+
import { VerifiedSnapshot } from "./snapshot.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/registry.d.ts
|
|
7
|
+
interface SkillRegistryStatus {
|
|
8
|
+
readonly initialized: boolean;
|
|
9
|
+
readonly revision?: string;
|
|
10
|
+
readonly mode: "latest" | "pinned";
|
|
11
|
+
/** ISO 8601 timestamp of the last successful 200 or matching 304 check. */
|
|
12
|
+
readonly lastCheckedAt?: string;
|
|
13
|
+
readonly stale: boolean;
|
|
14
|
+
readonly lastError?: Readonly<{
|
|
15
|
+
code: LearnedSkillsErrorCode;
|
|
16
|
+
message: string;
|
|
17
|
+
retryable: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/** Internal registry shared by framework adapters; public API is framework-native. */
|
|
21
|
+
declare class SkillRegistry {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(options?: SkillRegistryOptions);
|
|
24
|
+
initialize(): Promise<void>;
|
|
25
|
+
/** Capture exactly one immutable snapshot before model work begins. */
|
|
26
|
+
acquireSnapshot(): Promise<VerifiedSnapshot>;
|
|
27
|
+
get status(): SkillRegistryStatus;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { SkillRegistry, SkillRegistryStatus };
|
|
31
|
+
//# sourceMappingURL=registry.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.mts","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/registry.ts"],"mappings":";;;;;;UAOiB,mBAAA;EAAA,SACN,WAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;;WAEA,aAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA,GAAY,QAAA;IACnB,IAAA,EAAM,sBAAA;IACN,OAAA;IACA,SAAA;EAAA;AAAA;;cAwBS,aAAA;EAAA;cASC,OAAA,GAAS,oBAAA;EAIf,UAAA,CAAA,GAAc,OAAA;EArCT;EA0CX,eAAA,CAAA,GAAmB,OAAA,CAAQ,gBAAA;EAAA,IAoBvB,MAAA,CAAA,GAAU,mBAAA;AAAA"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { LearnedSkillsError } from "../learned-skills.mjs";
|
|
3
|
+
import { invalidSnapshot } from "./errors.mjs";
|
|
4
|
+
import { resolveRegistryConfig } from "./config.mjs";
|
|
5
|
+
import { validateSnapshot } from "./snapshot.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/registry.ts
|
|
8
|
+
function transient(error) {
|
|
9
|
+
return [
|
|
10
|
+
"NETWORK_ERROR",
|
|
11
|
+
"TIMEOUT",
|
|
12
|
+
"INVALID_SNAPSHOT",
|
|
13
|
+
"UNSUPPORTED_SERVER"
|
|
14
|
+
].includes(error.code);
|
|
15
|
+
}
|
|
16
|
+
function deliveryError(error) {
|
|
17
|
+
if (error instanceof LearnedSkillsError) return error;
|
|
18
|
+
return new LearnedSkillsError(error instanceof Error && error.name === "TimeoutError" ? "TIMEOUT" : "NETWORK_ERROR", true, error);
|
|
19
|
+
}
|
|
20
|
+
/** Internal registry shared by framework adapters; public API is framework-native. */
|
|
21
|
+
var SkillRegistry = class {
|
|
22
|
+
#config;
|
|
23
|
+
#snapshot;
|
|
24
|
+
#inFlight;
|
|
25
|
+
#lastCheckedAt;
|
|
26
|
+
#stale = false;
|
|
27
|
+
#lastError;
|
|
28
|
+
#blocked;
|
|
29
|
+
constructor(options = {}) {
|
|
30
|
+
this.#config = resolveRegistryConfig(options);
|
|
31
|
+
}
|
|
32
|
+
async initialize() {
|
|
33
|
+
await this.acquireSnapshot();
|
|
34
|
+
}
|
|
35
|
+
/** Capture exactly one immutable snapshot before model work begins. */
|
|
36
|
+
acquireSnapshot() {
|
|
37
|
+
if (this.#inFlight) return this.#inFlight;
|
|
38
|
+
if (this.#snapshot && !this.#blocked && this.#lastCheckedAt !== void 0 && Date.now() - this.#lastCheckedAt < this.#config.freshnessWindowMs) return Promise.resolve(this.#snapshot);
|
|
39
|
+
this.#inFlight = Promise.resolve().then(() => this.#refresh()).finally(() => {
|
|
40
|
+
this.#inFlight = void 0;
|
|
41
|
+
});
|
|
42
|
+
return this.#inFlight;
|
|
43
|
+
}
|
|
44
|
+
get status() {
|
|
45
|
+
const error = this.#lastError;
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
initialized: this.#snapshot !== void 0,
|
|
48
|
+
...this.#snapshot ? { revision: this.#snapshot.revision } : {},
|
|
49
|
+
mode: this.#config.revision === void 0 ? "latest" : "pinned",
|
|
50
|
+
...this.#lastCheckedAt !== void 0 ? { lastCheckedAt: new Date(this.#lastCheckedAt).toISOString() } : {},
|
|
51
|
+
stale: this.#stale,
|
|
52
|
+
...error ? { lastError: Object.freeze({
|
|
53
|
+
code: error.code,
|
|
54
|
+
message: error.message,
|
|
55
|
+
retryable: error.retryable
|
|
56
|
+
}) } : {}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async #refresh() {
|
|
60
|
+
const startedAt = Date.now();
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
let timer;
|
|
63
|
+
const deadline = new Promise((_, reject) => {
|
|
64
|
+
timer = setTimeout(() => {
|
|
65
|
+
const error = new LearnedSkillsError("TIMEOUT", true);
|
|
66
|
+
controller.abort(error);
|
|
67
|
+
timer = setTimeout(() => reject(error), 0);
|
|
68
|
+
}, this.#config.requestTimeoutMs);
|
|
69
|
+
});
|
|
70
|
+
const replacement = async () => {
|
|
71
|
+
const response = await this.#config.client.getLearnedSkillsSnapshot({
|
|
72
|
+
containerId: this.#config.containerId,
|
|
73
|
+
...this.#config.revision !== void 0 ? { revision: this.#config.revision } : {},
|
|
74
|
+
...this.#snapshot ? { ifNoneMatch: this.#snapshot.etag } : {},
|
|
75
|
+
signal: controller.signal
|
|
76
|
+
});
|
|
77
|
+
controller.signal.throwIfAborted();
|
|
78
|
+
if (!response || typeof response !== "object") throw invalidSnapshot();
|
|
79
|
+
if (response.status === "unchanged") {
|
|
80
|
+
if (!this.#snapshot || response.etag !== this.#snapshot.etag || response.revision !== this.#snapshot.revision) throw invalidSnapshot();
|
|
81
|
+
return this.#snapshot;
|
|
82
|
+
}
|
|
83
|
+
if (this.#config.revision !== void 0 && response.revision !== this.#config.revision) throw invalidSnapshot();
|
|
84
|
+
return validateSnapshot(response, controller.signal);
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
const snapshot = await Promise.race([replacement(), deadline]);
|
|
88
|
+
this.#snapshot = snapshot;
|
|
89
|
+
this.#lastCheckedAt = Date.now();
|
|
90
|
+
this.#stale = false;
|
|
91
|
+
this.#lastError = void 0;
|
|
92
|
+
this.#blocked = void 0;
|
|
93
|
+
this.#debug("refresh-success", startedAt);
|
|
94
|
+
return snapshot;
|
|
95
|
+
} catch (cause) {
|
|
96
|
+
const error = deliveryError(cause);
|
|
97
|
+
if (!transient(error)) {
|
|
98
|
+
this.#blocked = error;
|
|
99
|
+
this.#stale = false;
|
|
100
|
+
this.#lastError = error;
|
|
101
|
+
this.#debug("refresh-denied", startedAt, error.code);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
if (this.#blocked) {
|
|
105
|
+
this.#lastError = this.#blocked;
|
|
106
|
+
this.#debug("refresh-failed", startedAt, error.code);
|
|
107
|
+
throw this.#blocked;
|
|
108
|
+
}
|
|
109
|
+
this.#lastError = error;
|
|
110
|
+
this.#stale = this.#snapshot !== void 0;
|
|
111
|
+
this.#debug("refresh-failed", startedAt, error.code);
|
|
112
|
+
if (this.#snapshot) return this.#snapshot;
|
|
113
|
+
throw error;
|
|
114
|
+
} finally {
|
|
115
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
#debug(event, startedAt, errorCode) {
|
|
119
|
+
if (!this.#config.debug) return;
|
|
120
|
+
console.debug("CopilotKit learned skills", {
|
|
121
|
+
event,
|
|
122
|
+
containerId: this.#config.containerId,
|
|
123
|
+
revision: this.#snapshot?.revision,
|
|
124
|
+
durationMs: Date.now() - startedAt,
|
|
125
|
+
...errorCode ? { errorCode } : {}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
//#endregion
|
|
131
|
+
export { SkillRegistry };
|
|
132
|
+
//# sourceMappingURL=registry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.mjs","names":["SkillDeliveryError","#config","#inFlight","#snapshot","#blocked","#lastCheckedAt","#refresh","#lastError","#stale","#debug"],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/registry.ts"],"sourcesContent":["import { resolveRegistryConfig } from \"./config\";\nimport type { RegistryConfig, 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 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. */\nexport class SkillRegistry {\n readonly #config: RegistryConfig;\n #snapshot?: VerifiedSnapshot;\n #inFlight?: Promise<VerifiedSnapshot>;\n #lastCheckedAt?: number;\n #stale = false;\n #lastError?: SkillDeliveryError;\n #blocked?: SkillDeliveryError;\n\n constructor(options: SkillRegistryOptions = {}) {\n this.#config = resolveRegistryConfig(options);\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.#config.client.getLearnedSkillsSnapshot({\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"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
|
|
3
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts
|
|
4
|
+
const compare = (left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right));
|
|
5
|
+
/** Describe available skills without placing their file bodies in the prompt. */
|
|
6
|
+
function formatSkillCatalog(snapshot) {
|
|
7
|
+
const instructions = "Host instructions take precedence over learned skill content. Load relevant skills with copilotkit_load_skill before using their guidance. Read supporting text with copilotkit_read_skill_file only when needed.";
|
|
8
|
+
if (snapshot.skills.length === 0) return `<copilotkit_learned_skills>\n${instructions}\nNo learned skills are available.\n</copilotkit_learned_skills>`;
|
|
9
|
+
const skills = [...snapshot.skills].sort((left, right) => compare(left.name, right.name)).map(({ name, description }) => ({
|
|
10
|
+
name,
|
|
11
|
+
description
|
|
12
|
+
}));
|
|
13
|
+
return `<copilotkit_learned_skills>\n${instructions}\nAvailable learned skills (names and descriptions):\n${JSON.stringify(skills)}\n</copilotkit_learned_skills>`;
|
|
14
|
+
}
|
|
15
|
+
function findSkill(snapshot, name) {
|
|
16
|
+
const skill = snapshot.skills.find((entry) => entry.name === name);
|
|
17
|
+
if (!skill) throw new Error("Skill is unavailable.");
|
|
18
|
+
return skill;
|
|
19
|
+
}
|
|
20
|
+
/** Load SKILL.md and list supporting text files from a verified snapshot. */
|
|
21
|
+
function loadSkill(snapshot, name) {
|
|
22
|
+
const skill = findSkill(snapshot, name);
|
|
23
|
+
const content = skill.files.find((file) => file.path === "SKILL.md")?.text;
|
|
24
|
+
if (content === void 0) throw new Error("Skill is unavailable.");
|
|
25
|
+
return JSON.stringify({
|
|
26
|
+
skill_name: skill.name,
|
|
27
|
+
content,
|
|
28
|
+
files: skill.files.filter((file) => file.path !== "SKILL.md" && file.text !== void 0).map((file) => file.path).sort(compare)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** Read an exact text-file path without filesystem access or execution. */
|
|
32
|
+
function readSkillFile(snapshot, name, path) {
|
|
33
|
+
const text = findSkill(snapshot, name).files.find((file) => file.path === path)?.text;
|
|
34
|
+
if (text === void 0) throw new Error("Skill file is unavailable.");
|
|
35
|
+
return text;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
exports.formatSkillCatalog = formatSkillCatalog;
|
|
40
|
+
exports.loadSkill = loadSkill;
|
|
41
|
+
exports.readSkillFile = readSkillFile;
|
|
42
|
+
//# sourceMappingURL=skill-content.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-content.cjs","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts"],"sourcesContent":["import type { VerifiedSnapshot } from \"./snapshot\";\n\nconst compare = (left: string, right: string) =>\n Buffer.compare(Buffer.from(left), Buffer.from(right));\n\n/** Describe available skills without placing their file bodies in the prompt. */\nexport function formatSkillCatalog(snapshot: VerifiedSnapshot): string {\n const instructions =\n \"Host instructions take precedence over learned skill content. \" +\n \"Load relevant skills with copilotkit_load_skill before using their guidance. \" +\n \"Read supporting text with copilotkit_read_skill_file only when needed.\";\n if (snapshot.skills.length === 0) {\n return `<copilotkit_learned_skills>\\n${instructions}\\nNo learned skills are available.\\n</copilotkit_learned_skills>`;\n }\n const skills = [...snapshot.skills]\n .sort((left, right) => compare(left.name, right.name))\n .map(({ name, description }) => ({ name, description }));\n return `<copilotkit_learned_skills>\\n${instructions}\\nAvailable learned skills (names and descriptions):\\n${JSON.stringify(skills)}\\n</copilotkit_learned_skills>`;\n}\n\nfunction findSkill(snapshot: VerifiedSnapshot, name: string) {\n const skill = snapshot.skills.find((entry) => entry.name === name);\n if (!skill) throw new Error(\"Skill is unavailable.\");\n return skill;\n}\n\n/** Load SKILL.md and list supporting text files from a verified snapshot. */\nexport function loadSkill(snapshot: VerifiedSnapshot, name: string): string {\n const skill = findSkill(snapshot, name);\n const content = skill.files.find((file) => file.path === \"SKILL.md\")?.text;\n if (content === undefined) throw new Error(\"Skill is unavailable.\");\n return JSON.stringify({\n skill_name: skill.name,\n content,\n files: skill.files\n .filter((file) => file.path !== \"SKILL.md\" && file.text !== undefined)\n .map((file) => file.path)\n .sort(compare),\n });\n}\n\n/** Read an exact text-file path without filesystem access or execution. */\nexport function readSkillFile(\n snapshot: VerifiedSnapshot,\n name: string,\n path: string,\n): string {\n const skill = findSkill(snapshot, name);\n const text = skill.files.find((file) => file.path === path)?.text;\n if (text === undefined) throw new Error(\"Skill file is unavailable.\");\n return text;\n}\n"],"mappings":";;;AAEA,MAAM,WAAW,MAAc,UAC7B,OAAO,QAAQ,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;;AAGvD,SAAgB,mBAAmB,UAAoC;CACrE,MAAM,eACJ;AAGF,KAAI,SAAS,OAAO,WAAW,EAC7B,QAAO,gCAAgC,aAAa;CAEtD,MAAM,SAAS,CAAC,GAAG,SAAS,OAAO,CAChC,MAAM,MAAM,UAAU,QAAQ,KAAK,MAAM,MAAM,KAAK,CAAC,CACrD,KAAK,EAAE,MAAM,mBAAmB;EAAE;EAAM;EAAa,EAAE;AAC1D,QAAO,gCAAgC,aAAa,wDAAwD,KAAK,UAAU,OAAO,CAAC;;AAGrI,SAAS,UAAU,UAA4B,MAAc;CAC3D,MAAM,QAAQ,SAAS,OAAO,MAAM,UAAU,MAAM,SAAS,KAAK;AAClE,KAAI,CAAC,MAAO,OAAM,IAAI,MAAM,wBAAwB;AACpD,QAAO;;;AAIT,SAAgB,UAAU,UAA4B,MAAsB;CAC1E,MAAM,QAAQ,UAAU,UAAU,KAAK;CACvC,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,KAAK,SAAS,WAAW,EAAE;AACtE,KAAI,YAAY,OAAW,OAAM,IAAI,MAAM,wBAAwB;AACnE,QAAO,KAAK,UAAU;EACpB,YAAY,MAAM;EAClB;EACA,OAAO,MAAM,MACV,QAAQ,SAAS,KAAK,SAAS,cAAc,KAAK,SAAS,OAAU,CACrE,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,QAAQ;EACjB,CAAC;;;AAIJ,SAAgB,cACd,UACA,MACA,MACQ;CAER,MAAM,OADQ,UAAU,UAAU,KAAK,CACpB,MAAM,MAAM,SAAS,KAAK,SAAS,KAAK,EAAE;AAC7D,KAAI,SAAS,OAAW,OAAM,IAAI,MAAM,6BAA6B;AACrE,QAAO"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
import { VerifiedSnapshot } from "./snapshot.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/skill-content.d.ts
|
|
5
|
+
/** Describe available skills without placing their file bodies in the prompt. */
|
|
6
|
+
declare function formatSkillCatalog(snapshot: VerifiedSnapshot): string;
|
|
7
|
+
/** Load SKILL.md and list supporting text files from a verified snapshot. */
|
|
8
|
+
declare function loadSkill(snapshot: VerifiedSnapshot, name: string): string;
|
|
9
|
+
/** Read an exact text-file path without filesystem access or execution. */
|
|
10
|
+
declare function readSkillFile(snapshot: VerifiedSnapshot, name: string, path: string): string;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { formatSkillCatalog, loadSkill, readSkillFile };
|
|
13
|
+
//# sourceMappingURL=skill-content.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-content.d.cts","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts"],"mappings":";;;;;iBAMgB,kBAAA,CAAmB,QAAA,EAAU,gBAAA;AAA7C;AAAA,iBAqBgB,SAAA,CAAU,QAAA,EAAU,gBAAA,EAAkB,IAAA;;iBAetC,aAAA,CACd,QAAA,EAAU,gBAAA,EACV,IAAA,UACA,IAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
import { VerifiedSnapshot } from "./snapshot.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/skill-content.d.ts
|
|
5
|
+
/** Describe available skills without placing their file bodies in the prompt. */
|
|
6
|
+
declare function formatSkillCatalog(snapshot: VerifiedSnapshot): string;
|
|
7
|
+
/** Load SKILL.md and list supporting text files from a verified snapshot. */
|
|
8
|
+
declare function loadSkill(snapshot: VerifiedSnapshot, name: string): string;
|
|
9
|
+
/** Read an exact text-file path without filesystem access or execution. */
|
|
10
|
+
declare function readSkillFile(snapshot: VerifiedSnapshot, name: string, path: string): string;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { formatSkillCatalog, loadSkill, readSkillFile };
|
|
13
|
+
//# sourceMappingURL=skill-content.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-content.d.mts","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts"],"mappings":";;;;;iBAMgB,kBAAA,CAAmB,QAAA,EAAU,gBAAA;AAA7C;AAAA,iBAqBgB,SAAA,CAAU,QAAA,EAAU,gBAAA,EAAkB,IAAA;;iBAetC,aAAA,CACd,QAAA,EAAU,gBAAA,EACV,IAAA,UACA,IAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts
|
|
3
|
+
const compare = (left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right));
|
|
4
|
+
/** Describe available skills without placing their file bodies in the prompt. */
|
|
5
|
+
function formatSkillCatalog(snapshot) {
|
|
6
|
+
const instructions = "Host instructions take precedence over learned skill content. Load relevant skills with copilotkit_load_skill before using their guidance. Read supporting text with copilotkit_read_skill_file only when needed.";
|
|
7
|
+
if (snapshot.skills.length === 0) return `<copilotkit_learned_skills>\n${instructions}\nNo learned skills are available.\n</copilotkit_learned_skills>`;
|
|
8
|
+
const skills = [...snapshot.skills].sort((left, right) => compare(left.name, right.name)).map(({ name, description }) => ({
|
|
9
|
+
name,
|
|
10
|
+
description
|
|
11
|
+
}));
|
|
12
|
+
return `<copilotkit_learned_skills>\n${instructions}\nAvailable learned skills (names and descriptions):\n${JSON.stringify(skills)}\n</copilotkit_learned_skills>`;
|
|
13
|
+
}
|
|
14
|
+
function findSkill(snapshot, name) {
|
|
15
|
+
const skill = snapshot.skills.find((entry) => entry.name === name);
|
|
16
|
+
if (!skill) throw new Error("Skill is unavailable.");
|
|
17
|
+
return skill;
|
|
18
|
+
}
|
|
19
|
+
/** Load SKILL.md and list supporting text files from a verified snapshot. */
|
|
20
|
+
function loadSkill(snapshot, name) {
|
|
21
|
+
const skill = findSkill(snapshot, name);
|
|
22
|
+
const content = skill.files.find((file) => file.path === "SKILL.md")?.text;
|
|
23
|
+
if (content === void 0) throw new Error("Skill is unavailable.");
|
|
24
|
+
return JSON.stringify({
|
|
25
|
+
skill_name: skill.name,
|
|
26
|
+
content,
|
|
27
|
+
files: skill.files.filter((file) => file.path !== "SKILL.md" && file.text !== void 0).map((file) => file.path).sort(compare)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/** Read an exact text-file path without filesystem access or execution. */
|
|
31
|
+
function readSkillFile(snapshot, name, path) {
|
|
32
|
+
const text = findSkill(snapshot, name).files.find((file) => file.path === path)?.text;
|
|
33
|
+
if (text === void 0) throw new Error("Skill file is unavailable.");
|
|
34
|
+
return text;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { formatSkillCatalog, loadSkill, readSkillFile };
|
|
39
|
+
//# sourceMappingURL=skill-content.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-content.mjs","names":[],"sources":["../../../../../src/v2/runtime/intelligence-platform/skill-registry/skill-content.ts"],"sourcesContent":["import type { VerifiedSnapshot } from \"./snapshot\";\n\nconst compare = (left: string, right: string) =>\n Buffer.compare(Buffer.from(left), Buffer.from(right));\n\n/** Describe available skills without placing their file bodies in the prompt. */\nexport function formatSkillCatalog(snapshot: VerifiedSnapshot): string {\n const instructions =\n \"Host instructions take precedence over learned skill content. \" +\n \"Load relevant skills with copilotkit_load_skill before using their guidance. \" +\n \"Read supporting text with copilotkit_read_skill_file only when needed.\";\n if (snapshot.skills.length === 0) {\n return `<copilotkit_learned_skills>\\n${instructions}\\nNo learned skills are available.\\n</copilotkit_learned_skills>`;\n }\n const skills = [...snapshot.skills]\n .sort((left, right) => compare(left.name, right.name))\n .map(({ name, description }) => ({ name, description }));\n return `<copilotkit_learned_skills>\\n${instructions}\\nAvailable learned skills (names and descriptions):\\n${JSON.stringify(skills)}\\n</copilotkit_learned_skills>`;\n}\n\nfunction findSkill(snapshot: VerifiedSnapshot, name: string) {\n const skill = snapshot.skills.find((entry) => entry.name === name);\n if (!skill) throw new Error(\"Skill is unavailable.\");\n return skill;\n}\n\n/** Load SKILL.md and list supporting text files from a verified snapshot. */\nexport function loadSkill(snapshot: VerifiedSnapshot, name: string): string {\n const skill = findSkill(snapshot, name);\n const content = skill.files.find((file) => file.path === \"SKILL.md\")?.text;\n if (content === undefined) throw new Error(\"Skill is unavailable.\");\n return JSON.stringify({\n skill_name: skill.name,\n content,\n files: skill.files\n .filter((file) => file.path !== \"SKILL.md\" && file.text !== undefined)\n .map((file) => file.path)\n .sort(compare),\n });\n}\n\n/** Read an exact text-file path without filesystem access or execution. */\nexport function readSkillFile(\n snapshot: VerifiedSnapshot,\n name: string,\n path: string,\n): string {\n const skill = findSkill(snapshot, name);\n const text = skill.files.find((file) => file.path === path)?.text;\n if (text === undefined) throw new Error(\"Skill file is unavailable.\");\n return text;\n}\n"],"mappings":";;AAEA,MAAM,WAAW,MAAc,UAC7B,OAAO,QAAQ,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;;AAGvD,SAAgB,mBAAmB,UAAoC;CACrE,MAAM,eACJ;AAGF,KAAI,SAAS,OAAO,WAAW,EAC7B,QAAO,gCAAgC,aAAa;CAEtD,MAAM,SAAS,CAAC,GAAG,SAAS,OAAO,CAChC,MAAM,MAAM,UAAU,QAAQ,KAAK,MAAM,MAAM,KAAK,CAAC,CACrD,KAAK,EAAE,MAAM,mBAAmB;EAAE;EAAM;EAAa,EAAE;AAC1D,QAAO,gCAAgC,aAAa,wDAAwD,KAAK,UAAU,OAAO,CAAC;;AAGrI,SAAS,UAAU,UAA4B,MAAc;CAC3D,MAAM,QAAQ,SAAS,OAAO,MAAM,UAAU,MAAM,SAAS,KAAK;AAClE,KAAI,CAAC,MAAO,OAAM,IAAI,MAAM,wBAAwB;AACpD,QAAO;;;AAIT,SAAgB,UAAU,UAA4B,MAAsB;CAC1E,MAAM,QAAQ,UAAU,UAAU,KAAK;CACvC,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS,KAAK,SAAS,WAAW,EAAE;AACtE,KAAI,YAAY,OAAW,OAAM,IAAI,MAAM,wBAAwB;AACnE,QAAO,KAAK,UAAU;EACpB,YAAY,MAAM;EAClB;EACA,OAAO,MAAM,MACV,QAAQ,SAAS,KAAK,SAAS,cAAc,KAAK,SAAS,OAAU,CACrE,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,QAAQ;EACjB,CAAC;;;AAIJ,SAAgB,cACd,UACA,MACA,MACQ;CAER,MAAM,OADQ,UAAU,UAAU,KAAK,CACpB,MAAM,MAAM,SAAS,KAAK,SAAS,KAAK,EAAE;AAC7D,KAAI,SAAS,OAAW,OAAM,IAAI,MAAM,6BAA6B;AACrE,QAAO"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_learned_skills = require('../learned-skills.cjs');
|
|
4
|
+
const require_errors = require('./errors.cjs');
|
|
5
|
+
const require_archive = require('./archive.cjs');
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
7
|
+
|
|
8
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/snapshot.ts
|
|
9
|
+
function object(value) {
|
|
10
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
function sha256(bytes) {
|
|
13
|
+
return (0, node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
14
|
+
}
|
|
15
|
+
function utf8(bytes) {
|
|
16
|
+
try {
|
|
17
|
+
return new TextDecoder("utf-8", {
|
|
18
|
+
fatal: true,
|
|
19
|
+
ignoreBOM: true
|
|
20
|
+
}).decode(bytes);
|
|
21
|
+
} catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Validate a replacement fully before it can become an invocation snapshot. */
|
|
26
|
+
async function validateSnapshot(response, signal) {
|
|
27
|
+
try {
|
|
28
|
+
if (!object(response) || !(response.bytes instanceof Uint8Array) || typeof response.revision !== "string" || typeof response.etag !== "string" || typeof response.contentType !== "string") throw require_errors.invalidSnapshot();
|
|
29
|
+
const { revision, etag, contentType } = response;
|
|
30
|
+
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();
|
|
31
|
+
const bytes = Buffer.from(response.bytes);
|
|
32
|
+
if (`"${sha256(bytes)}"` !== etag) throw require_errors.invalidSnapshot();
|
|
33
|
+
const archive = await require_archive.readArchive(bytes, signal);
|
|
34
|
+
const manifestBytes = archive.get("manifest.json");
|
|
35
|
+
if (!manifestBytes) throw require_errors.invalidSnapshot();
|
|
36
|
+
const decoded = utf8(manifestBytes);
|
|
37
|
+
if (decoded === void 0) throw require_errors.invalidSnapshot();
|
|
38
|
+
const manifest = JSON.parse(decoded);
|
|
39
|
+
if (!object(manifest)) throw require_errors.invalidSnapshot();
|
|
40
|
+
if (typeof manifest.schemaVersion === "number" && manifest.schemaVersion !== 1) throw new require_learned_skills.LearnedSkillsError("UNSUPPORTED_SERVER", false);
|
|
41
|
+
if (manifest.schemaVersion !== 1 || manifest.revision !== revision || !Array.isArray(manifest.skills)) throw require_errors.invalidSnapshot();
|
|
42
|
+
const expected = new Set(["manifest.json"]);
|
|
43
|
+
let previousName;
|
|
44
|
+
const skills = [];
|
|
45
|
+
for (const skill of manifest.skills) {
|
|
46
|
+
if (!object(skill) || typeof skill.name !== "string" || !require_archive.safeRelativePath(skill.name) || skill.name.includes("/") || previousName !== void 0 && Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >= 0 || typeof skill.description !== "string" || !Array.isArray(skill.files)) throw require_errors.invalidSnapshot();
|
|
47
|
+
previousName = skill.name;
|
|
48
|
+
let previousPath;
|
|
49
|
+
let hasSkill = false;
|
|
50
|
+
const files = [];
|
|
51
|
+
for (const file of skill.files) {
|
|
52
|
+
if (!object(file) || typeof file.path !== "string" || !require_archive.safeRelativePath(file.path) || previousPath !== void 0 && Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >= 0 || typeof file.size !== "number" || !Number.isSafeInteger(file.size) || file.size < 0 || typeof file.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(file.sha256)) throw require_errors.invalidSnapshot();
|
|
53
|
+
previousPath = file.path;
|
|
54
|
+
const path = `${skill.name}/${file.path}`;
|
|
55
|
+
if (expected.has(path)) throw require_errors.invalidSnapshot();
|
|
56
|
+
expected.add(path);
|
|
57
|
+
const content = archive.get(path);
|
|
58
|
+
if (!content || content.length !== file.size || sha256(content) !== file.sha256) throw require_errors.invalidSnapshot();
|
|
59
|
+
const text = utf8(content);
|
|
60
|
+
if (file.path === "SKILL.md") {
|
|
61
|
+
if (text === void 0) throw require_errors.invalidSnapshot();
|
|
62
|
+
hasSkill = true;
|
|
63
|
+
}
|
|
64
|
+
files.push(Object.freeze({
|
|
65
|
+
path: file.path,
|
|
66
|
+
size: file.size,
|
|
67
|
+
sha256: file.sha256,
|
|
68
|
+
...text !== void 0 ? { text } : {}
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
if (!hasSkill) throw require_errors.invalidSnapshot();
|
|
72
|
+
skills.push(Object.freeze({
|
|
73
|
+
name: skill.name,
|
|
74
|
+
description: skill.description,
|
|
75
|
+
files: Object.freeze(files)
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
if (expected.size !== archive.size || [...archive.keys()].some((path) => !expected.has(path))) throw require_errors.invalidSnapshot();
|
|
79
|
+
return Object.freeze({
|
|
80
|
+
revision,
|
|
81
|
+
etag,
|
|
82
|
+
skills: Object.freeze(skills)
|
|
83
|
+
});
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (signal?.aborted) throw signal.reason;
|
|
86
|
+
if (error instanceof require_learned_skills.LearnedSkillsError) throw error;
|
|
87
|
+
throw require_errors.invalidSnapshot(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
exports.validateSnapshot = validateSnapshot;
|
|
93
|
+
//# sourceMappingURL=snapshot.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.cjs","names":["invalidSnapshot","MAX_SNAPSHOT_BYTES","readArchive","SkillDeliveryError","safeRelativePath"],"sources":["../../../../../src/v2/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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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
import { LearnedSkillsSnapshotResult } from "../learned-skills.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/snapshot.d.ts
|
|
5
|
+
interface SnapshotFile {
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly size: number;
|
|
8
|
+
readonly sha256: string;
|
|
9
|
+
/** Absent for supporting resources that cannot be decoded as UTF-8 text. */
|
|
10
|
+
readonly text?: string;
|
|
11
|
+
}
|
|
12
|
+
interface SnapshotSkill {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly description: string;
|
|
15
|
+
readonly files: readonly SnapshotFile[];
|
|
16
|
+
}
|
|
17
|
+
interface VerifiedSnapshot {
|
|
18
|
+
readonly revision: string;
|
|
19
|
+
readonly etag: string;
|
|
20
|
+
readonly skills: readonly SnapshotSkill[];
|
|
21
|
+
}
|
|
22
|
+
/** Validate a replacement fully before it can become an invocation snapshot. */
|
|
23
|
+
declare function validateSnapshot(response: Extract<LearnedSkillsSnapshotResult, {
|
|
24
|
+
status: "snapshot";
|
|
25
|
+
}>, signal?: AbortSignal): Promise<VerifiedSnapshot>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { SnapshotFile, SnapshotSkill, VerifiedSnapshot, validateSnapshot };
|
|
28
|
+
//# sourceMappingURL=snapshot.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.cts","names":[],"sources":["../../../../../src/v2/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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
import { LearnedSkillsSnapshotResult } from "../learned-skills.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/snapshot.d.ts
|
|
5
|
+
interface SnapshotFile {
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly size: number;
|
|
8
|
+
readonly sha256: string;
|
|
9
|
+
/** Absent for supporting resources that cannot be decoded as UTF-8 text. */
|
|
10
|
+
readonly text?: string;
|
|
11
|
+
}
|
|
12
|
+
interface SnapshotSkill {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly description: string;
|
|
15
|
+
readonly files: readonly SnapshotFile[];
|
|
16
|
+
}
|
|
17
|
+
interface VerifiedSnapshot {
|
|
18
|
+
readonly revision: string;
|
|
19
|
+
readonly etag: string;
|
|
20
|
+
readonly skills: readonly SnapshotSkill[];
|
|
21
|
+
}
|
|
22
|
+
/** Validate a replacement fully before it can become an invocation snapshot. */
|
|
23
|
+
declare function validateSnapshot(response: Extract<LearnedSkillsSnapshotResult, {
|
|
24
|
+
status: "snapshot";
|
|
25
|
+
}>, signal?: AbortSignal): Promise<VerifiedSnapshot>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { SnapshotFile, SnapshotSkill, VerifiedSnapshot, validateSnapshot };
|
|
28
|
+
//# sourceMappingURL=snapshot.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.mts","names":[],"sources":["../../../../../src/v2/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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { LearnedSkillsError } from "../learned-skills.mjs";
|
|
3
|
+
import { invalidSnapshot } from "./errors.mjs";
|
|
4
|
+
import { MAX_SNAPSHOT_BYTES, readArchive, safeRelativePath } from "./archive.mjs";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
|
|
7
|
+
//#region src/v2/runtime/intelligence-platform/skill-registry/snapshot.ts
|
|
8
|
+
function object(value) {
|
|
9
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function sha256(bytes) {
|
|
12
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
13
|
+
}
|
|
14
|
+
function utf8(bytes) {
|
|
15
|
+
try {
|
|
16
|
+
return new TextDecoder("utf-8", {
|
|
17
|
+
fatal: true,
|
|
18
|
+
ignoreBOM: true
|
|
19
|
+
}).decode(bytes);
|
|
20
|
+
} catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Validate a replacement fully before it can become an invocation snapshot. */
|
|
25
|
+
async function validateSnapshot(response, signal) {
|
|
26
|
+
try {
|
|
27
|
+
if (!object(response) || !(response.bytes instanceof Uint8Array) || typeof response.revision !== "string" || typeof response.etag !== "string" || typeof response.contentType !== "string") throw invalidSnapshot();
|
|
28
|
+
const { revision, etag, contentType } = response;
|
|
29
|
+
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();
|
|
30
|
+
const bytes = Buffer.from(response.bytes);
|
|
31
|
+
if (`"${sha256(bytes)}"` !== etag) throw invalidSnapshot();
|
|
32
|
+
const archive = await readArchive(bytes, signal);
|
|
33
|
+
const manifestBytes = archive.get("manifest.json");
|
|
34
|
+
if (!manifestBytes) throw invalidSnapshot();
|
|
35
|
+
const decoded = utf8(manifestBytes);
|
|
36
|
+
if (decoded === void 0) throw invalidSnapshot();
|
|
37
|
+
const manifest = JSON.parse(decoded);
|
|
38
|
+
if (!object(manifest)) throw invalidSnapshot();
|
|
39
|
+
if (typeof manifest.schemaVersion === "number" && manifest.schemaVersion !== 1) throw new LearnedSkillsError("UNSUPPORTED_SERVER", false);
|
|
40
|
+
if (manifest.schemaVersion !== 1 || manifest.revision !== revision || !Array.isArray(manifest.skills)) throw invalidSnapshot();
|
|
41
|
+
const expected = new Set(["manifest.json"]);
|
|
42
|
+
let previousName;
|
|
43
|
+
const skills = [];
|
|
44
|
+
for (const skill of manifest.skills) {
|
|
45
|
+
if (!object(skill) || typeof skill.name !== "string" || !safeRelativePath(skill.name) || skill.name.includes("/") || previousName !== void 0 && Buffer.compare(Buffer.from(previousName), Buffer.from(skill.name)) >= 0 || typeof skill.description !== "string" || !Array.isArray(skill.files)) throw invalidSnapshot();
|
|
46
|
+
previousName = skill.name;
|
|
47
|
+
let previousPath;
|
|
48
|
+
let hasSkill = false;
|
|
49
|
+
const files = [];
|
|
50
|
+
for (const file of skill.files) {
|
|
51
|
+
if (!object(file) || typeof file.path !== "string" || !safeRelativePath(file.path) || previousPath !== void 0 && Buffer.compare(Buffer.from(previousPath), Buffer.from(file.path)) >= 0 || typeof file.size !== "number" || !Number.isSafeInteger(file.size) || file.size < 0 || typeof file.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(file.sha256)) throw invalidSnapshot();
|
|
52
|
+
previousPath = file.path;
|
|
53
|
+
const path = `${skill.name}/${file.path}`;
|
|
54
|
+
if (expected.has(path)) throw invalidSnapshot();
|
|
55
|
+
expected.add(path);
|
|
56
|
+
const content = archive.get(path);
|
|
57
|
+
if (!content || content.length !== file.size || sha256(content) !== file.sha256) throw invalidSnapshot();
|
|
58
|
+
const text = utf8(content);
|
|
59
|
+
if (file.path === "SKILL.md") {
|
|
60
|
+
if (text === void 0) throw invalidSnapshot();
|
|
61
|
+
hasSkill = true;
|
|
62
|
+
}
|
|
63
|
+
files.push(Object.freeze({
|
|
64
|
+
path: file.path,
|
|
65
|
+
size: file.size,
|
|
66
|
+
sha256: file.sha256,
|
|
67
|
+
...text !== void 0 ? { text } : {}
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
if (!hasSkill) throw invalidSnapshot();
|
|
71
|
+
skills.push(Object.freeze({
|
|
72
|
+
name: skill.name,
|
|
73
|
+
description: skill.description,
|
|
74
|
+
files: Object.freeze(files)
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
if (expected.size !== archive.size || [...archive.keys()].some((path) => !expected.has(path))) throw invalidSnapshot();
|
|
78
|
+
return Object.freeze({
|
|
79
|
+
revision,
|
|
80
|
+
etag,
|
|
81
|
+
skills: Object.freeze(skills)
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (signal?.aborted) throw signal.reason;
|
|
85
|
+
if (error instanceof LearnedSkillsError) throw error;
|
|
86
|
+
throw invalidSnapshot(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
export { validateSnapshot };
|
|
92
|
+
//# sourceMappingURL=snapshot.mjs.map
|