@treeseed/sdk 0.13.0-rc.47 → 0.13.0-rc.49

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.
@@ -3,6 +3,10 @@ const identifier = z.string().regex(/^[a-z][a-z0-9.-]{1,63}$/u);
3
3
  const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/u);
4
4
  const gitCommit = z.string().regex(/^[a-f0-9]{40}$/u);
5
5
  const packageVersion = z.string().min(1).regex(/^[0-9][0-9A-Za-z.+:~-]*$/u);
6
+ const ociRepository = z.string().min(1).max(255).regex(
7
+ /^(?:(?:localhost|[a-z0-9]+(?:[.-][a-z0-9]+)+)(?::[1-9][0-9]{0,4})?\/)?[a-z0-9]+(?:[._-][a-z0-9]+)*(?:\/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$/u,
8
+ "OCI repositories must be normalized lowercase names without a scheme, tag, digest, credentials, or traversal."
9
+ );
6
10
  const localAlias = z.string().regex(
7
11
  /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.localhost$/u,
8
12
  "Host aliases must use the .localhost namespace."
@@ -146,7 +150,7 @@ const packageRuntimeSchema = z.object({
146
150
  if (new Set(endpointIds).size !== endpointIds.length) context.addIssue({ code: z.ZodIssueCode.custom, path: ["services"], message: "Endpoint identities must be unique within a component." });
147
151
  });
148
152
  const catalogPackageSchema = z.object({ name: z.string().regex(/^treeseed(?:-[a-z0-9-]+)?$/u), version: packageVersion, architecture: z.enum(["amd64", "all"]), origin: z.literal("TreeSeed Deployment"), order: z.number().int().nonnegative() }).strict();
149
- const catalogImageSchema = z.object({ role: identifier, repository: z.string().regex(/^treeseed\/[a-z0-9-]+$/u), digest, platforms: z.array(z.enum(["linux/amd64", "linux/arm64"])).min(1), consumers: z.array(identifier).min(1) }).strict();
153
+ const catalogImageSchema = z.object({ role: identifier, repository: ociRepository, digest, platforms: z.array(z.enum(["linux/amd64", "linux/arm64"])).min(1), consumers: z.array(identifier).min(1) }).strict();
150
154
  const componentReleaseSchema = z.object({
151
155
  schemaVersion: z.literal("treeseed.component-release/v1"),
152
156
  componentId: identifier,
@@ -8,6 +8,7 @@ const local = (handlerId) => ({ kind: "local", handlerId });
8
8
  const field = (target, name, source, sourceName = name, required = false, transform = "identity") => ({ target, field: name, source, name: sourceName, required, transform });
9
9
  const operation = (operationId, input = []) => ({ kind: "operation", operationId, input });
10
10
  const page = () => [field("query", "status", "option"), field("query", "limit", "option", "limit", false, "integer"), field("query", "cursor", "option")];
11
+ const aiNode = () => field("path", "nodeId", "context", "node", true);
11
12
  const operationBindings = {
12
13
  "auth login": protocol("protocol.oauth.device.login"),
13
14
  "auth logout": protocol("protocol.oauth.revoke"),
@@ -110,6 +111,21 @@ const operationBindings = {
110
111
  "projects treedx workspaces list": operation("treedx.workspaces.list", [field("path", "projectId", "argument", "project", true), ...page()]),
111
112
  "projects treedx workspaces show": operation("treedx.workspaces.show", [field("path", "projectId", "context", "project", true), field("path", "workspaceId", "argument", "workspace", true)]),
112
113
  "projects treedx workspaces abandon": operation("treedx.workspaces.abandon", [field("path", "projectId", "context", "project", true), field("path", "workspaceId", "argument", "workspace", true)]),
114
+ "ai status": operation("treeai.qualification.get.status", [aiNode()]),
115
+ "ai mode show": operation("treeai.qualification.get.mode", [aiNode()]),
116
+ "ai mode set": operation("treeai.qualification.post.mode", [aiNode(), field("body", "mode", "argument", "mode", true)]),
117
+ "ai inference models": operation("treeai.inference.get.models", [aiNode()]),
118
+ "ai inference jobs": operation("treeai.inference.get.jobs", [aiNode()]),
119
+ "ai inference rollback": operation("treeai.inference.post.deployments.rollback", [aiNode()]),
120
+ "ai training libraries": operation("treeai.training.get.libraries", [aiNode()]),
121
+ "ai training jobs": operation("treeai.training.get.jobs", [aiNode()]),
122
+ "ai training runs": operation("treeai.training.get.library.runs", [aiNode()]),
123
+ "ai lab status": operation("treeai.lab.get.status", [aiNode()]),
124
+ "ai lab agents": operation("treeai.lab.get.agents", [aiNode()]),
125
+ "ai lab libraries": operation("treeai.lab.get.libraries", [aiNode()]),
126
+ "ai qualify status": operation("treeai.qualification.get.qualification.profile", [aiNode()]),
127
+ "ai qualify run": operation("treeai.qualification.post.qualification.campaigns", [aiNode()]),
128
+ "ai qualify campaigns": operation("treeai.qualification.get.qualification.campaigns", [aiNode()]),
113
129
  "library show": local("local.library.show"),
114
130
  "library status": local("local.library.status"),
115
131
  "library paths": local("local.library.paths"),
@@ -299,6 +315,14 @@ const commandTree = {
299
315
  leaf("capabilities", "read", "project"),
300
316
  branch("workspaces", [leaf("list", "read", "project"), leaf("show", "read", "workspace"), leaf("abandon", "mutation", "workspace", "destructive")])
301
317
  ])]),
318
+ branch("ai", [
319
+ leaf("status"),
320
+ branch("mode", [leaf("show"), leaf("set", "mutation", "mode", "authority")]),
321
+ branch("inference", [leaf("models"), leaf("jobs"), leaf("rollback", "mutation", void 0, "destructive")]),
322
+ branch("training", [leaf("libraries"), leaf("jobs"), leaf("runs")]),
323
+ branch("lab", [leaf("status"), leaf("agents"), leaf("libraries")]),
324
+ branch("qualify", [leaf("status"), leaf("run", "mutation", void 0, "authority"), leaf("campaigns")])
325
+ ]),
302
326
  branch("library", [
303
327
  libraryRead("show"),
304
328
  libraryRead("status"),
@@ -0,0 +1,14 @@
1
+ import type { ControlPlaneOperationBinding } from '../control-plane-operation.js';
2
+ export declare const TREEAI_OPENAPI_DIGESTS: {
3
+ readonly inference: "sha256:3a00f1d91635d87d0aad2c6d329f495ff210f393bc9851570aa3e3ad1f5c1db4";
4
+ readonly training: "sha256:89dc70cecc85079853e4f177827d681e66f4b24b93ef17713051b99f07c2fe00";
5
+ readonly lab: "sha256:bccafa27b00a63b9fb22b132b850f9af6e77d44047dbc8966344088266d65898";
6
+ readonly qualification: "sha256:3f68b78845ec19c5de389663f1cb677ab4df0683ecd113c4f5780885a89370b7";
7
+ };
8
+ export declare const TREEAI_CONTROL_PLANE_OPERATION_LIST: readonly ControlPlaneOperationBinding<{
9
+ nodeId: string;
10
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>[];
11
+ export declare const TREEAI_CONTROL_PLANE_OPERATIONS: Readonly<Record<string, ControlPlaneOperationBinding<any, any, any, any>>>;
12
+ export declare function treeAiControlPlaneOperation(upstreamOperationId: string): ControlPlaneOperationBinding<{
13
+ nodeId: string;
14
+ }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ import { defineOperation } from "../operation-builder.js";
3
+ import { TREEAI_UPSTREAM_OPERATIONS } from "../../treeai/generated/upstream.js";
4
+ const TREEAI_OPENAPI_DIGESTS = {
5
+ inference: "sha256:3a00f1d91635d87d0aad2c6d329f495ff210f393bc9851570aa3e3ad1f5c1db4",
6
+ training: "sha256:89dc70cecc85079853e4f177827d681e66f4b24b93ef17713051b99f07c2fe00",
7
+ lab: "sha256:bccafa27b00a63b9fb22b132b850f9af6e77d44047dbc8966344088266d65898",
8
+ qualification: "sha256:3f68b78845ec19c5de389663f1cb677ab4df0683ecd113c4f5780885a89370b7"
9
+ };
10
+ function treeSeedOperationId(operation) {
11
+ return `treeai.${operation.operationId.toLowerCase().replace(/[^a-z0-9]+/gu, ".").replace(/^\.|\.$/gu, "")}`;
12
+ }
13
+ function risk(operation) {
14
+ if (/rollback|cancel|disable/u.test(operation.operationId)) return "destructive";
15
+ if (operation.kind === "mutation" && (/promot|enable|activate|campaigns/u.test(operation.operationId) || /(?:^|\.)mode(?:\.|$)/u.test(operation.operationId))) return "authority";
16
+ return "ordinary";
17
+ }
18
+ function pathShape(path) {
19
+ return Object.fromEntries([...path.matchAll(/\{([^}]+)\}/gu)].map((match) => [match[1], z.string().min(1)]));
20
+ }
21
+ function binding(operation) {
22
+ const method = operation.method;
23
+ const kind = operation.kind;
24
+ const riskClass = risk(operation);
25
+ const path = `/v1/ai/nodes/{nodeId}/${operation.service}${operation.path}`;
26
+ return defineOperation({
27
+ operationId: treeSeedOperationId(operation),
28
+ description: `${operation.summary} through a node-scoped TreeAI proxy.`,
29
+ rest: { method, path },
30
+ parameters: `treeseed.${treeSeedOperationId(operation)}.parameters/v1`,
31
+ capability: `treeai.${operation.service}.${kind}`,
32
+ authentication: "oauth_or_provider",
33
+ oauthScopes: kind === "read" ? ["treeseed:read"] : ["treeseed:execution"],
34
+ kind,
35
+ riskClass,
36
+ confirmation: riskClass === "ordinary" ? "never" : "input_required",
37
+ idempotencyRequired: kind === "mutation",
38
+ surfaces: ["rest", "cli"],
39
+ cacheScope: kind === "read" ? "principal" : "none",
40
+ pagination: "none",
41
+ redactedPaths: ["headers.authorization"],
42
+ upstream: { service: "treeai", operationId: operation.operationId, contractVersion: "3.1.1", contractDigest: TREEAI_OPENAPI_DIGESTS[operation.service] }
43
+ }, {
44
+ path: z.object({ nodeId: z.string().min(1), ...pathShape(operation.path) }).strict(),
45
+ query: kind === "read" ? z.record(z.unknown()) : z.object({}).strict(),
46
+ body: kind === "read" ? z.undefined() : z.record(z.unknown()),
47
+ output: z.record(z.unknown())
48
+ });
49
+ }
50
+ const TREEAI_CONTROL_PLANE_OPERATION_LIST = Object.freeze(TREEAI_UPSTREAM_OPERATIONS.map(binding));
51
+ const TREEAI_CONTROL_PLANE_OPERATIONS = Object.freeze(Object.fromEntries(TREEAI_CONTROL_PLANE_OPERATION_LIST.map((item) => [item.descriptor.operationId, item])));
52
+ function treeAiControlPlaneOperation(upstreamOperationId) {
53
+ const operation = TREEAI_CONTROL_PLANE_OPERATION_LIST.find((item) => item.descriptor.upstream?.operationId === upstreamOperationId);
54
+ if (!operation) throw new Error(`Unknown TreeAI operation ${upstreamOperationId}.`);
55
+ return operation;
56
+ }
57
+ export {
58
+ TREEAI_CONTROL_PLANE_OPERATIONS,
59
+ TREEAI_CONTROL_PLANE_OPERATION_LIST,
60
+ TREEAI_OPENAPI_DIGESTS,
61
+ treeAiControlPlaneOperation
62
+ };
@@ -28,7 +28,7 @@ export interface ControlPlaneConcurrencyContract {
28
28
  writeHeader: 'If-Match';
29
29
  }
30
30
  export interface ControlPlaneUpstreamBinding {
31
- service: 'treedx';
31
+ service: 'treedx' | 'treeai';
32
32
  operationId: string;
33
33
  contractVersion: string;
34
34
  contractDigest: `sha256:${string}`;
@@ -1,5 +1,6 @@
1
1
  import { type ControlPlaneOperationBinding, type ControlPlaneOperationDescriptor } from './control-plane-operation.js';
2
2
  export declare const CONTROL_PLANE_OPERATIONS: {
3
+ readonly treeai: Readonly<Record<string, ControlPlaneOperationBinding<any, any, any, any>>>;
3
4
  readonly status: {
4
5
  readonly show: ControlPlaneOperationBinding<{}, {}, undefined, Record<string, unknown>>;
5
6
  };
@@ -999,8 +1000,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
999
1000
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1000
1001
  readonly node: ControlPlaneOperationBinding<{
1001
1002
  projectId: string;
1002
- repoId: string;
1003
1003
  nodeId: string;
1004
+ repoId: string;
1004
1005
  }, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1005
1006
  readonly related: ControlPlaneOperationBinding<{
1006
1007
  projectId: string;
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { defineOperation as define, defineTreeDxProxyOperation as treedxProxy } from "./operation-builder.js";
3
3
  import { communicationOperations, providerDiscussionResponseOperation } from "./catalog/communication-operations.js";
4
4
  import { adminAccountOperations, adminTeamOperations } from "./catalog/admin-account-team-operations.js";
5
+ import { TREEAI_CONTROL_PLANE_OPERATIONS } from "./catalog/treeai-operations.js";
5
6
  const empty = z.object({}).strict();
6
7
  const none = z.undefined();
7
8
  const record = z.record(z.unknown());
@@ -96,6 +97,7 @@ function resource(operationId, method, path, pathShape, options = { capability:
96
97
  }, { path: z.object(pathShape).strict(), query: kind === "read" ? record : empty, body: kind === "read" ? none : record, output: payload });
97
98
  }
98
99
  const CONTROL_PLANE_OPERATIONS = {
100
+ treeai: TREEAI_CONTROL_PLANE_OPERATIONS,
99
101
  status: {
100
102
  show: read("status.show", "/v1/status", "status.read", ["rest", "cli", "mcp_tool", "mcp_resource"])
101
103
  },
@@ -0,0 +1 @@
1
+ export * from '../operator-contracts/catalog/treeai-operations.js';
@@ -0,0 +1 @@
1
+ export * from "../operator-contracts/catalog/treeai-operations.js";