@axiom-lattice/protocols 4.5.0 → 4.6.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.
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Canonical run-scope extraction.
3
+ *
4
+ * An execution runConfig carries the same scope twice: the parsed fields
5
+ * (`projectId`, `workspaceId`) and the header-shaped fields (`x-project-id`,
6
+ * `x-workspace-id`). Internal propagation has historically overwritten one
7
+ * without the other, so a reader that picks a single field can silently lose a
8
+ * real scope (and later fall back to the `"default"` sentinel). Readers must
9
+ * resolve scope through one shared rule instead.
10
+ */
11
+
12
+ /** Returns the first non-empty string among the candidates, else `undefined`. */
13
+ export function firstNonEmptyString(...values: unknown[]): string | undefined {
14
+ for (const value of values) {
15
+ if (typeof value === "string" && value.length > 0) return value;
16
+ }
17
+ return undefined;
18
+ }
19
+
20
+ /** Workspace/project execution scope; each field absent when not supplied. */
21
+ export interface RunScope {
22
+ workspaceId?: string;
23
+ projectId?: string;
24
+ }
25
+
26
+ /**
27
+ * Reads the authoritative execution scope from a runConfig bag.
28
+ *
29
+ * Prefers the parsed field and falls back to the header-shaped field for each
30
+ * of project and workspace. Missing or empty values resolve to `undefined`
31
+ * (never the `"default"` sentinel).
32
+ *
33
+ * @param runConfig - Untrusted execution runConfig bag.
34
+ * @returns Workspace/project scope, each absent when no non-empty value exists.
35
+ */
36
+ export function resolveRunScope(runConfig: unknown): RunScope {
37
+ const rc = runConfig && typeof runConfig === "object" && !Array.isArray(runConfig)
38
+ ? runConfig as Record<string, unknown>
39
+ : {};
40
+ return {
41
+ workspaceId: firstNonEmptyString(rc.workspaceId, rc["x-workspace-id"]),
42
+ projectId: firstNonEmptyString(rc.projectId, rc["x-project-id"]),
43
+ };
44
+ }
@@ -0,0 +1,38 @@
1
+ import { firstNonEmptyString, resolveRunScope } from "../RunScope";
2
+
3
+ describe("firstNonEmptyString", () => {
4
+ it("returns the first non-empty string", () => {
5
+ expect(firstNonEmptyString(undefined, "", null, 0, "a", "b")).toBe("a");
6
+ });
7
+
8
+ it("returns undefined when no candidate is a non-empty string", () => {
9
+ expect(firstNonEmptyString(undefined, "", null, 42, {})).toBeUndefined();
10
+ });
11
+ });
12
+
13
+ describe("resolveRunScope", () => {
14
+ it("prefers the parsed fields", () => {
15
+ expect(resolveRunScope({
16
+ projectId: "p", workspaceId: "w", "x-project-id": "px", "x-workspace-id": "wx",
17
+ })).toEqual({ projectId: "p", workspaceId: "w" });
18
+ });
19
+
20
+ it("falls back to the header-shaped fields when the parsed fields are missing", () => {
21
+ expect(resolveRunScope({ "x-project-id": "px", "x-workspace-id": "wx" }))
22
+ .toEqual({ projectId: "px", workspaceId: "wx" });
23
+ });
24
+
25
+ it("treats empty parsed fields as absent and uses the header-shaped fallback", () => {
26
+ expect(resolveRunScope({ projectId: "", "x-project-id": "px" }))
27
+ .toEqual({ projectId: "px", workspaceId: undefined });
28
+ });
29
+
30
+ it("never invents the default sentinel for missing scope", () => {
31
+ expect(resolveRunScope({})).toEqual({ projectId: undefined, workspaceId: undefined });
32
+ });
33
+
34
+ it("tolerates non-record input", () => {
35
+ expect(resolveRunScope("nope")).toEqual({ projectId: undefined, workspaceId: undefined });
36
+ expect(resolveRunScope(null)).toEqual({ projectId: undefined, workspaceId: undefined });
37
+ });
38
+ });
package/src/index.ts CHANGED
@@ -29,6 +29,7 @@ export * from "./ConnectionStoreProtocol";
29
29
  export * from "./ChannelInstallationStoreProtocol";
30
30
  export * from "./MetricsServerConfigStoreProtocol";
31
31
  export * from "./McpServerConfigStoreProtocol";
32
+ export * from "./ModelProviderProtocol";
32
33
  export * from "./UserStoreProtocol";
33
34
  export * from "./UserTenantLinkProtocol";
34
35
  export * from "./WorkflowTrackingStoreProtocol";
@@ -93,5 +94,6 @@ export * from "./SandboxPluginProtocol";
93
94
  // 导出通用类型
94
95
  export * from "./types";
95
96
  export * from "./TrustedRunContextProtocol";
97
+ export * from "./RunScope";
96
98
  export * from "./OpenProtocol";
97
99
  export * from "./McpUiProtocol";