@nodetool-ai/deploy 0.7.0-rc.11

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 (133) hide show
  1. package/dist/admin-client.d.ts +58 -0
  2. package/dist/admin-client.d.ts.map +1 -0
  3. package/dist/admin-client.js +275 -0
  4. package/dist/admin-client.js.map +1 -0
  5. package/dist/admin-operations.d.ts +197 -0
  6. package/dist/admin-operations.d.ts.map +1 -0
  7. package/dist/admin-operations.js +433 -0
  8. package/dist/admin-operations.js.map +1 -0
  9. package/dist/admin-routes.d.ts +306 -0
  10. package/dist/admin-routes.d.ts.map +1 -0
  11. package/dist/admin-routes.js +383 -0
  12. package/dist/admin-routes.js.map +1 -0
  13. package/dist/api-user-manager.d.ts +72 -0
  14. package/dist/api-user-manager.d.ts.map +1 -0
  15. package/dist/api-user-manager.js +89 -0
  16. package/dist/api-user-manager.js.map +1 -0
  17. package/dist/auth.d.ts +67 -0
  18. package/dist/auth.d.ts.map +1 -0
  19. package/dist/auth.js +142 -0
  20. package/dist/auth.js.map +1 -0
  21. package/dist/collection-routes.d.ts +37 -0
  22. package/dist/collection-routes.d.ts.map +1 -0
  23. package/dist/collection-routes.js +43 -0
  24. package/dist/collection-routes.js.map +1 -0
  25. package/dist/compose.d.ts +52 -0
  26. package/dist/compose.d.ts.map +1 -0
  27. package/dist/compose.js +153 -0
  28. package/dist/compose.js.map +1 -0
  29. package/dist/configure.d.ts +87 -0
  30. package/dist/configure.d.ts.map +1 -0
  31. package/dist/configure.js +104 -0
  32. package/dist/configure.js.map +1 -0
  33. package/dist/deploy-to-gcp.d.ts +67 -0
  34. package/dist/deploy-to-gcp.d.ts.map +1 -0
  35. package/dist/deploy-to-gcp.js +268 -0
  36. package/dist/deploy-to-gcp.js.map +1 -0
  37. package/dist/deploy-to-runpod.d.ts +53 -0
  38. package/dist/deploy-to-runpod.d.ts.map +1 -0
  39. package/dist/deploy-to-runpod.js +207 -0
  40. package/dist/deploy-to-runpod.js.map +1 -0
  41. package/dist/deploy.d.ts +54 -0
  42. package/dist/deploy.d.ts.map +1 -0
  43. package/dist/deploy.js +82 -0
  44. package/dist/deploy.js.map +1 -0
  45. package/dist/deployment-config.d.ts +1073 -0
  46. package/dist/deployment-config.d.ts.map +1 -0
  47. package/dist/deployment-config.js +536 -0
  48. package/dist/deployment-config.js.map +1 -0
  49. package/dist/docker-run.d.ts +85 -0
  50. package/dist/docker-run.d.ts.map +1 -0
  51. package/dist/docker-run.js +202 -0
  52. package/dist/docker-run.js.map +1 -0
  53. package/dist/docker.d.ts +98 -0
  54. package/dist/docker.d.ts.map +1 -0
  55. package/dist/docker.js +396 -0
  56. package/dist/docker.js.map +1 -0
  57. package/dist/fly.d.ts +40 -0
  58. package/dist/fly.d.ts.map +1 -0
  59. package/dist/fly.js +291 -0
  60. package/dist/fly.js.map +1 -0
  61. package/dist/gcp.d.ts +59 -0
  62. package/dist/gcp.d.ts.map +1 -0
  63. package/dist/gcp.js +339 -0
  64. package/dist/gcp.js.map +1 -0
  65. package/dist/google-cloud-run-api.d.ts +134 -0
  66. package/dist/google-cloud-run-api.d.ts.map +1 -0
  67. package/dist/google-cloud-run-api.js +532 -0
  68. package/dist/google-cloud-run-api.js.map +1 -0
  69. package/dist/huggingface.d.ts +69 -0
  70. package/dist/huggingface.d.ts.map +1 -0
  71. package/dist/huggingface.js +346 -0
  72. package/dist/huggingface.js.map +1 -0
  73. package/dist/image-builder.d.ts +35 -0
  74. package/dist/image-builder.d.ts.map +1 -0
  75. package/dist/image-builder.js +157 -0
  76. package/dist/image-builder.js.map +1 -0
  77. package/dist/image-spec.d.ts +41 -0
  78. package/dist/image-spec.d.ts.map +1 -0
  79. package/dist/image-spec.js +49 -0
  80. package/dist/image-spec.js.map +1 -0
  81. package/dist/index.d.ts +33 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +45 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/manager.d.ts +121 -0
  86. package/dist/manager.d.ts.map +1 -0
  87. package/dist/manager.js +225 -0
  88. package/dist/manager.js.map +1 -0
  89. package/dist/progress.d.ts +91 -0
  90. package/dist/progress.d.ts.map +1 -0
  91. package/dist/progress.js +262 -0
  92. package/dist/progress.js.map +1 -0
  93. package/dist/railway.d.ts +65 -0
  94. package/dist/railway.d.ts.map +1 -0
  95. package/dist/railway.js +284 -0
  96. package/dist/railway.js.map +1 -0
  97. package/dist/remote-users.d.ts +74 -0
  98. package/dist/remote-users.d.ts.map +1 -0
  99. package/dist/remote-users.js +172 -0
  100. package/dist/remote-users.js.map +1 -0
  101. package/dist/runpod-api.d.ts +206 -0
  102. package/dist/runpod-api.d.ts.map +1 -0
  103. package/dist/runpod-api.js +703 -0
  104. package/dist/runpod-api.js.map +1 -0
  105. package/dist/runpod.d.ts +82 -0
  106. package/dist/runpod.d.ts.map +1 -0
  107. package/dist/runpod.js +188 -0
  108. package/dist/runpod.js.map +1 -0
  109. package/dist/self-hosted.d.ts +157 -0
  110. package/dist/self-hosted.d.ts.map +1 -0
  111. package/dist/self-hosted.js +799 -0
  112. package/dist/self-hosted.js.map +1 -0
  113. package/dist/ssh.d.ts +166 -0
  114. package/dist/ssh.d.ts.map +1 -0
  115. package/dist/ssh.js +430 -0
  116. package/dist/ssh.js.map +1 -0
  117. package/dist/state.d.ts +83 -0
  118. package/dist/state.d.ts.map +1 -0
  119. package/dist/state.js +368 -0
  120. package/dist/state.js.map +1 -0
  121. package/dist/storage-routes.d.ts +55 -0
  122. package/dist/storage-routes.d.ts.map +1 -0
  123. package/dist/storage-routes.js +160 -0
  124. package/dist/storage-routes.js.map +1 -0
  125. package/dist/sync.d.ts +38 -0
  126. package/dist/sync.d.ts.map +1 -0
  127. package/dist/sync.js +130 -0
  128. package/dist/sync.js.map +1 -0
  129. package/dist/workflow-syncer.d.ts +51 -0
  130. package/dist/workflow-syncer.d.ts.map +1 -0
  131. package/dist/workflow-syncer.js +192 -0
  132. package/dist/workflow-syncer.js.map +1 -0
  133. package/package.json +58 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Storage route handlers for the NodeTool worker.
3
+ *
4
+ * Provides typed handler functions (not framework-specific) for:
5
+ * 1. Admin storage (full CRUD operations)
6
+ * 2. Public storage (read-only access)
7
+ *
8
+ * The caller is responsible for wiring these into their HTTP framework
9
+ * (Express, Fastify, etc.) and applying auth middleware.
10
+ */
11
+ import { extname } from "path";
12
+ /** Common content-type mappings by file extension. */
13
+ const EXTENSION_TO_CONTENT_TYPE = {
14
+ jpg: "image/jpeg",
15
+ jpeg: "image/jpeg",
16
+ png: "image/png",
17
+ gif: "image/gif",
18
+ webp: "image/webp",
19
+ svg: "image/svg+xml",
20
+ mp3: "audio/mpeg",
21
+ wav: "audio/wav",
22
+ ogg: "audio/ogg",
23
+ flac: "audio/flac",
24
+ mp4: "video/mp4",
25
+ webm: "video/webm",
26
+ avi: "video/x-msvideo",
27
+ mov: "video/quicktime",
28
+ pdf: "application/pdf",
29
+ json: "application/json",
30
+ txt: "text/plain",
31
+ csv: "text/csv",
32
+ html: "text/html",
33
+ css: "text/css",
34
+ js: "application/javascript",
35
+ xml: "application/xml",
36
+ zip: "application/zip",
37
+ tar: "application/x-tar",
38
+ gz: "application/gzip"
39
+ };
40
+ // ---------------------------------------------------------------------------
41
+ // Key validation
42
+ // ---------------------------------------------------------------------------
43
+ /**
44
+ * Validate and normalize a storage key, preventing traversal while allowing
45
+ * nested prefixes.
46
+ *
47
+ * @returns The normalized key (POSIX-style separators).
48
+ * @throws Error if validation fails (caller should map to HTTP 400).
49
+ */
50
+ export function validateKey(key) {
51
+ const normalized = key.replace(/\\/g, "/");
52
+ const parts = normalized
53
+ .split("/")
54
+ .filter((part) => part !== "" && part !== ".");
55
+ if (parts.length === 0) {
56
+ throw new Error("Invalid key: key must not be empty");
57
+ }
58
+ if (normalized.startsWith("/")) {
59
+ throw new Error("Invalid key: absolute paths are not allowed");
60
+ }
61
+ if (parts.some((part) => part === "..")) {
62
+ throw new Error("Invalid key: path traversal is not allowed");
63
+ }
64
+ return parts.join("/");
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Shared handler implementations
68
+ // ---------------------------------------------------------------------------
69
+ /**
70
+ * Return file metadata (HEAD request).
71
+ */
72
+ export async function headFile(storage, key) {
73
+ const safeKey = validateKey(key);
74
+ if (!(await storage.fileExists(safeKey))) {
75
+ return { status: 404, headers: {} };
76
+ }
77
+ const lastModified = await storage.getMtime(safeKey);
78
+ if (!lastModified) {
79
+ return { status: 404, headers: {} };
80
+ }
81
+ return {
82
+ status: 200,
83
+ headers: {
84
+ "Last-Modified": lastModified.toUTCString()
85
+ }
86
+ };
87
+ }
88
+ /**
89
+ * Return a file as a stream with range support (GET request).
90
+ */
91
+ export async function getFile(storage, key, request) {
92
+ const safeKey = validateKey(key);
93
+ if (!(await storage.fileExists(safeKey))) {
94
+ return { status: 404, headers: {} };
95
+ }
96
+ const lastModified = await storage.getMtime(safeKey);
97
+ if (!lastModified) {
98
+ return { status: 404, headers: {} };
99
+ }
100
+ // If-Modified-Since handling
101
+ const ifModifiedSince = request.headers["if-modified-since"];
102
+ if (ifModifiedSince) {
103
+ const ifModifiedDate = new Date(ifModifiedSince);
104
+ if (!isNaN(ifModifiedDate.getTime()) && ifModifiedDate >= lastModified) {
105
+ return { status: 304, headers: {} };
106
+ }
107
+ }
108
+ const ext = extname(safeKey).slice(1);
109
+ const mediaType = EXTENSION_TO_CONTENT_TYPE[ext] ?? "application/octet-stream";
110
+ const headers = {
111
+ "Last-Modified": lastModified.toUTCString(),
112
+ "Accept-Ranges": "bytes",
113
+ "Content-Type": mediaType
114
+ };
115
+ // Range request handling
116
+ const rangeHeader = request.headers["range"];
117
+ if (rangeHeader) {
118
+ const rangeMatch = rangeHeader.match(/^bytes=(\d+)-(\d*)$/);
119
+ if (rangeMatch) {
120
+ const start = parseInt(rangeMatch[1], 10);
121
+ const data = await storage.download(safeKey);
122
+ const end = rangeMatch[2] ? parseInt(rangeMatch[2], 10) : data.length - 1;
123
+ headers["Content-Range"] = `bytes ${start}-${end}/${data.length}`;
124
+ headers["Content-Length"] = String(end - start + 1);
125
+ return {
126
+ status: 206,
127
+ headers,
128
+ body: data.slice(start, end + 1)
129
+ };
130
+ }
131
+ // If range is invalid, fall through to full content
132
+ }
133
+ const size = await storage.getSize(safeKey);
134
+ headers["Content-Length"] = String(size);
135
+ return {
136
+ status: 200,
137
+ headers,
138
+ body: storage.downloadStream(safeKey)
139
+ };
140
+ }
141
+ /**
142
+ * Upload or update a file (PUT request).
143
+ */
144
+ export async function putFile(storage, key, data) {
145
+ const safeKey = validateKey(key);
146
+ await storage.upload(safeKey, data);
147
+ return { status: 200, headers: {}, body: null };
148
+ }
149
+ /**
150
+ * Delete a file (DELETE request).
151
+ */
152
+ export async function deleteFile(storage, key) {
153
+ const safeKey = validateKey(key);
154
+ if (!(await storage.fileExists(safeKey))) {
155
+ return { status: 404, headers: {} };
156
+ }
157
+ await storage.delete(safeKey);
158
+ return { status: 204, headers: {} };
159
+ }
160
+ //# sourceMappingURL=storage-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-routes.js","sourceRoot":"","sources":["../src/storage-routes.ts"],"names":[],"mappings":"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"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Workflow model extraction utilities.
3
+ *
4
+ * Extracts HuggingFace and Ollama model references from workflow graphs
5
+ * so they can be pre-downloaded before execution.
6
+ */
7
+ /** A model reference extracted from a workflow graph. */
8
+ export interface ExtractedModel {
9
+ type: string;
10
+ repo_id?: string;
11
+ path?: string | null;
12
+ variant?: string | null;
13
+ allow_patterns?: string[] | null;
14
+ ignore_patterns?: string[] | null;
15
+ provider?: string;
16
+ id?: string;
17
+ }
18
+ interface WorkflowNode {
19
+ data?: Record<string, unknown>;
20
+ type?: string;
21
+ }
22
+ interface WorkflowData {
23
+ graph?: {
24
+ nodes?: WorkflowNode[];
25
+ };
26
+ }
27
+ /**
28
+ * Extract both HuggingFace and Ollama models from a workflow graph.
29
+ *
30
+ * Scans through all nodes in the workflow graph to find models that need to be
31
+ * pre-downloaded. This includes:
32
+ * - HuggingFace models (type starts with "hf.")
33
+ * - Ollama language models (type="language_model" and provider="ollama")
34
+ * - llama_cpp language models (type="language_model" and provider="llama_cpp")
35
+ */
36
+ export declare function extractModels(workflowData: WorkflowData): ExtractedModel[];
37
+ export {};
38
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;KACxB,CAAC;CACH;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,cAAc,EAAE,CA0I1E"}
package/dist/sync.js ADDED
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Workflow model extraction utilities.
3
+ *
4
+ * Extracts HuggingFace and Ollama model references from workflow graphs
5
+ * so they can be pre-downloaded before execution.
6
+ */
7
+ /**
8
+ * Extract both HuggingFace and Ollama models from a workflow graph.
9
+ *
10
+ * Scans through all nodes in the workflow graph to find models that need to be
11
+ * pre-downloaded. This includes:
12
+ * - HuggingFace models (type starts with "hf.")
13
+ * - Ollama language models (type="language_model" and provider="ollama")
14
+ * - llama_cpp language models (type="language_model" and provider="llama_cpp")
15
+ */
16
+ export function extractModels(workflowData) {
17
+ const models = [];
18
+ const seenModels = new Set();
19
+ const nodes = workflowData.graph?.nodes;
20
+ if (!nodes) {
21
+ return models;
22
+ }
23
+ for (const node of nodes) {
24
+ if (!node.data) {
25
+ continue;
26
+ }
27
+ const nodeData = node.data;
28
+ // Check for model field containing HuggingFace or Ollama models
29
+ const model = nodeData["model"];
30
+ if (model && typeof model === "object" && !Array.isArray(model)) {
31
+ const m = model;
32
+ // HuggingFace models
33
+ if (typeof m["type"] === "string" &&
34
+ m["type"].startsWith("hf.") &&
35
+ typeof m["repo_id"] === "string" &&
36
+ m["repo_id"]) {
37
+ const modelKey = `hf|${m["type"]}|${m["repo_id"]}|${m["path"] ?? ""}|${m["variant"] ?? ""}`;
38
+ if (!seenModels.has(modelKey)) {
39
+ seenModels.add(modelKey);
40
+ models.push({
41
+ type: m["type"] || "hf.model",
42
+ repo_id: m["repo_id"],
43
+ path: m["path"] ?? null,
44
+ variant: m["variant"] ?? null,
45
+ allow_patterns: m["allow_patterns"] ?? null,
46
+ ignore_patterns: m["ignore_patterns"] ?? null
47
+ });
48
+ }
49
+ }
50
+ // Ollama language models
51
+ else if (m["type"] === "language_model" &&
52
+ m["provider"] === "ollama" &&
53
+ m["id"]) {
54
+ const modelKey = `ollama|${m["id"]}`;
55
+ if (!seenModels.has(modelKey)) {
56
+ seenModels.add(modelKey);
57
+ models.push({
58
+ type: "language_model",
59
+ provider: "ollama",
60
+ id: m["id"]
61
+ });
62
+ }
63
+ }
64
+ // llama_cpp language models (HuggingFace GGUF models)
65
+ else if (m["type"] === "language_model" &&
66
+ m["provider"] === "llama_cpp" &&
67
+ typeof m["id"] === "string") {
68
+ const modelId = m["id"];
69
+ if (modelId.includes(":")) {
70
+ const [repoId, filePath] = modelId.split(":", 2);
71
+ const modelKey = `hf|hf.gguf|${repoId}|${filePath}|`;
72
+ if (!seenModels.has(modelKey)) {
73
+ seenModels.add(modelKey);
74
+ models.push({
75
+ type: "hf.gguf",
76
+ repo_id: repoId,
77
+ path: filePath,
78
+ variant: null,
79
+ allow_patterns: null,
80
+ ignore_patterns: null
81
+ });
82
+ }
83
+ }
84
+ }
85
+ }
86
+ // Check for language models at the root level
87
+ if (nodeData["type"] === "language_model" &&
88
+ nodeData["provider"] === "ollama" &&
89
+ nodeData["id"]) {
90
+ const modelKey = `ollama|${nodeData["id"]}`;
91
+ if (!seenModels.has(modelKey)) {
92
+ seenModels.add(modelKey);
93
+ models.push({
94
+ type: "language_model",
95
+ provider: "ollama",
96
+ id: nodeData["id"]
97
+ });
98
+ }
99
+ }
100
+ // Check for nested model references (e.g., in arrays like loras)
101
+ for (const [, value] of Object.entries(nodeData)) {
102
+ if (Array.isArray(value)) {
103
+ for (const item of value) {
104
+ if (item && typeof item === "object" && !Array.isArray(item)) {
105
+ const it = item;
106
+ if (typeof it["type"] === "string" &&
107
+ it["type"].startsWith("hf.") &&
108
+ typeof it["repo_id"] === "string" &&
109
+ it["repo_id"]) {
110
+ const modelKey = `hf|${it["type"]}|${it["repo_id"]}|${it["path"] ?? ""}|${it["variant"] ?? ""}`;
111
+ if (!seenModels.has(modelKey)) {
112
+ seenModels.add(modelKey);
113
+ models.push({
114
+ type: it["type"] || "hf.model",
115
+ repo_id: it["repo_id"],
116
+ path: it["path"] ?? null,
117
+ variant: it["variant"] ?? null,
118
+ allow_patterns: it["allow_patterns"] ?? null,
119
+ ignore_patterns: it["ignore_patterns"] ?? null
120
+ });
121
+ }
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return models;
129
+ }
130
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * WorkflowSyncer — syncs workflows, assets, and required models
3
+ * to a remote NodeTool instance via the AdminHTTPClient.
4
+ */
5
+ import type { AdminHTTPClient } from "./admin-client.js";
6
+ /** Minimal asset representation for syncing. */
7
+ export interface AssetInfo {
8
+ id: string;
9
+ user_id: string;
10
+ name: string;
11
+ content_type: string;
12
+ parent_id?: string | null;
13
+ workflow_id?: string | null;
14
+ metadata?: Record<string, unknown> | null;
15
+ file_name?: string | null;
16
+ has_thumbnail?: boolean;
17
+ thumb_file_name?: string | null;
18
+ }
19
+ /** Storage interface for downloading asset data. */
20
+ export interface SyncerAssetStorage {
21
+ download(key: string): Promise<Uint8Array>;
22
+ }
23
+ /** Functions the caller must supply so WorkflowSyncer can resolve local data. */
24
+ export interface WorkflowSyncerDeps {
25
+ /** Retrieve a workflow by ID and return it as a serialisable dict. */
26
+ getWorkflowData(workflowId: string): Promise<Record<string, unknown> | null>;
27
+ /** Retrieve local asset metadata by ID. */
28
+ getAsset(assetId: string): Promise<AssetInfo | null>;
29
+ /** Get the local asset storage instance. */
30
+ getSyncerAssetStorage(): SyncerAssetStorage;
31
+ }
32
+ export declare class WorkflowSyncer {
33
+ private client;
34
+ private deps;
35
+ constructor(client: AdminHTTPClient, deps: WorkflowSyncerDeps);
36
+ /**
37
+ * Sync a workflow, its assets, and required models to the remote instance.
38
+ *
39
+ * @returns true if sync was successful, false otherwise.
40
+ */
41
+ syncWorkflow(workflowId: string): Promise<boolean>;
42
+ /**
43
+ * Extract model references from workflow and download them on remote.
44
+ */
45
+ private extractAndDownloadModels;
46
+ /**
47
+ * Extract asset references from workflow and sync them to remote.
48
+ */
49
+ private extractAndSyncAssets;
50
+ }
51
+ //# sourceMappingURL=workflow-syncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-syncer.d.ts","sourceRoot":"","sources":["../src/workflow-syncer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,gDAAgD;AAChD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAE7E,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAErD,4CAA4C;IAC5C,qBAAqB,IAAI,kBAAkB,CAAC;CAC7C;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,IAAI,CAAqB;gBAErB,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,kBAAkB;IAK7D;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6BxD;;OAEG;YACW,wBAAwB;IAuFtC;;OAEG;YACW,oBAAoB;CAqFnC"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * WorkflowSyncer — syncs workflows, assets, and required models
3
+ * to a remote NodeTool instance via the AdminHTTPClient.
4
+ */
5
+ import { extractModels } from "./sync.js";
6
+ export class WorkflowSyncer {
7
+ client;
8
+ deps;
9
+ constructor(client, deps) {
10
+ this.client = client;
11
+ this.deps = deps;
12
+ }
13
+ /**
14
+ * Sync a workflow, its assets, and required models to the remote instance.
15
+ *
16
+ * @returns true if sync was successful, false otherwise.
17
+ */
18
+ async syncWorkflow(workflowId) {
19
+ try {
20
+ const workflowData = await this.deps.getWorkflowData(workflowId);
21
+ if (!workflowData) {
22
+ console.error(`Workflow not found locally: ${workflowId}`);
23
+ return false;
24
+ }
25
+ // Sync assets first
26
+ const syncedAssets = await this.extractAndSyncAssets(workflowData);
27
+ if (syncedAssets > 0) {
28
+ console.log(`Synced ${syncedAssets} asset(s)`);
29
+ }
30
+ // Download models required by the workflow
31
+ const syncedModels = await this.extractAndDownloadModels(workflowData);
32
+ if (syncedModels > 0) {
33
+ console.log(`Downloaded ${syncedModels} model(s)`);
34
+ }
35
+ // Sync workflow
36
+ await this.client.updateWorkflow(workflowId, workflowData);
37
+ return true;
38
+ }
39
+ catch (e) {
40
+ console.error(`Failed to sync workflow: ${e}`);
41
+ return false;
42
+ }
43
+ }
44
+ /**
45
+ * Extract model references from workflow and download them on remote.
46
+ */
47
+ async extractAndDownloadModels(workflowData) {
48
+ const models = extractModels(workflowData);
49
+ if (models.length === 0) {
50
+ return 0;
51
+ }
52
+ console.log(`Found ${models.length} model(s) to download`);
53
+ let downloadedCount = 0;
54
+ for (const model of models) {
55
+ try {
56
+ const modelType = model.type ?? "";
57
+ // Handle HuggingFace models
58
+ if (modelType.startsWith("hf.")) {
59
+ const repoId = model.repo_id;
60
+ if (!repoId) {
61
+ console.error(" Error: repo_id is required for HF models");
62
+ continue;
63
+ }
64
+ console.log(` Downloading HF model: ${repoId}`);
65
+ let lastStatus;
66
+ for await (const progress of this.client.downloadHuggingfaceModel({
67
+ repoId,
68
+ filePath: model.path ?? undefined,
69
+ ignorePatterns: model.ignore_patterns ?? undefined,
70
+ allowPatterns: model.allow_patterns ?? undefined
71
+ })) {
72
+ lastStatus = progress["status"];
73
+ if (lastStatus === "downloading") {
74
+ const fileName = progress["file"] ?? "";
75
+ const percent = progress["percent"] ?? 0;
76
+ process.stdout.write(` ${fileName}: ${percent.toFixed(1)}%\r`);
77
+ }
78
+ else if (lastStatus === "complete") {
79
+ console.log(` Downloaded ${repoId}`);
80
+ }
81
+ }
82
+ if (lastStatus !== "complete") {
83
+ console.log(` Downloaded ${repoId}`);
84
+ }
85
+ downloadedCount++;
86
+ }
87
+ // Handle Ollama models
88
+ else if (modelType === "language_model" &&
89
+ model.provider === "ollama") {
90
+ const modelId = model.id;
91
+ if (!modelId) {
92
+ console.error(" Error: model id is required for Ollama models");
93
+ continue;
94
+ }
95
+ console.log(` Downloading Ollama model: ${modelId}`);
96
+ let lastStatus;
97
+ for await (const progress of this.client.downloadOllamaModel(modelId)) {
98
+ lastStatus = progress["status"];
99
+ if (lastStatus && lastStatus !== "success") {
100
+ process.stdout.write(` ${lastStatus}\r`);
101
+ }
102
+ else if (lastStatus === "success") {
103
+ console.log(` Downloaded ${modelId}`);
104
+ }
105
+ }
106
+ if (lastStatus !== "success") {
107
+ console.log(` Downloaded ${modelId}`);
108
+ }
109
+ downloadedCount++;
110
+ }
111
+ }
112
+ catch (e) {
113
+ console.error(` Failed to download model: ${e}`);
114
+ }
115
+ }
116
+ return downloadedCount;
117
+ }
118
+ /**
119
+ * Extract asset references from workflow and sync them to remote.
120
+ */
121
+ async extractAndSyncAssets(workflowData) {
122
+ const assetIds = new Set();
123
+ const graph = workflowData["graph"];
124
+ const nodes = graph?.nodes ?? [];
125
+ for (const node of nodes) {
126
+ const nodeType = node["type"] ?? "";
127
+ if (nodeType.startsWith("nodetool.constant.")) {
128
+ const data = node["data"];
129
+ const value = data?.["value"];
130
+ if (value && typeof value === "object" && !Array.isArray(value)) {
131
+ const assetId = value["asset_id"];
132
+ if (typeof assetId === "string" && assetId) {
133
+ assetIds.add(assetId);
134
+ }
135
+ }
136
+ }
137
+ }
138
+ if (assetIds.size === 0) {
139
+ return 0;
140
+ }
141
+ console.log(`Found ${assetIds.size} asset(s) to sync`);
142
+ const storage = this.deps.getSyncerAssetStorage();
143
+ let syncedCount = 0;
144
+ for (const assetId of assetIds) {
145
+ try {
146
+ const asset = await this.deps.getAsset(assetId);
147
+ if (!asset) {
148
+ console.warn(` Asset ${assetId} not found locally, skipping`);
149
+ continue;
150
+ }
151
+ console.log(` Syncing asset: ${asset.name}`);
152
+ // Check if asset already exists on remote
153
+ try {
154
+ await this.client.getAsset(assetId);
155
+ console.log(" Asset already exists on remote, skipping");
156
+ syncedCount++;
157
+ continue;
158
+ }
159
+ catch {
160
+ // Asset doesn't exist, continue with sync
161
+ }
162
+ // Create asset metadata on remote (preserve asset ID)
163
+ await this.client.createAsset({
164
+ id: asset.id,
165
+ userId: asset.user_id,
166
+ name: asset.name,
167
+ contentType: asset.content_type,
168
+ parentId: asset.parent_id ?? undefined,
169
+ workflowId: asset.workflow_id ?? undefined,
170
+ metadata: asset.metadata ?? undefined
171
+ });
172
+ // Upload asset file if it's not a folder
173
+ if (asset.content_type !== "folder" && asset.file_name) {
174
+ const fileData = await storage.download(asset.file_name);
175
+ await this.client.uploadAssetFile(asset.file_name, fileData);
176
+ // Upload thumbnail if exists
177
+ if (asset.has_thumbnail && asset.thumb_file_name) {
178
+ const thumbData = await storage.download(asset.thumb_file_name);
179
+ await this.client.uploadAssetFile(asset.thumb_file_name, thumbData);
180
+ }
181
+ }
182
+ console.log(` Synced ${asset.name}`);
183
+ syncedCount++;
184
+ }
185
+ catch (e) {
186
+ console.error(` Failed to sync asset ${assetId}: ${e}`);
187
+ }
188
+ }
189
+ return syncedCount;
190
+ }
191
+ }
192
+ //# sourceMappingURL=workflow-syncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-syncer.js","sourceRoot":"","sources":["../src/workflow-syncer.ts"],"names":[],"mappings":"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"}