@mevdragon/vidfarm-devcli 0.2.7 → 0.2.9

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 (98) hide show
  1. package/.env.example +9 -0
  2. package/GETTING_STARTED.developers.md +1 -30
  3. package/README.md +22 -5
  4. package/SKILL.developer.md +464 -12
  5. package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +475 -0
  6. package/auto-create-templates/extractor-system-prompt.md +113 -0
  7. package/auto-create-templates/production-graph.schema.json +276 -0
  8. package/auto-create-templates/runbook.md +140 -0
  9. package/auto-create-templates/template-plan.schema.json +230 -0
  10. package/auto-create-templates/template-planner-prompt.md +75 -0
  11. package/dist/src/account-pages-legacy.js +9064 -0
  12. package/dist/src/account-pages.js +41 -620
  13. package/dist/src/app.js +7173 -494
  14. package/dist/src/cli.js +525 -29
  15. package/dist/src/config.js +14 -7
  16. package/dist/src/context.js +51 -35
  17. package/dist/src/db.js +1049 -55
  18. package/dist/src/dev-app-legacy.js +693 -0
  19. package/dist/src/dev-app.js +4 -904
  20. package/dist/src/domain.js +1 -1
  21. package/dist/src/editor-chat-history.js +72 -0
  22. package/dist/src/editor-chat.js +202 -0
  23. package/dist/src/frontend/flockposter-cache-store.js +116 -0
  24. package/dist/src/frontend/homepage-client.js +114 -0
  25. package/dist/src/frontend/homepage-shared.js +3 -0
  26. package/dist/src/frontend/homepage-store.js +27 -0
  27. package/dist/src/frontend/homepage-view.js +147 -0
  28. package/dist/src/frontend/page-runtime-client.js +100 -0
  29. package/dist/src/frontend/page-runtime-store.js +8 -0
  30. package/dist/src/frontend/template-editor-chat.js +2261 -0
  31. package/dist/src/homepage.js +695 -339
  32. package/dist/src/lib/template-paths.js +10 -4
  33. package/dist/src/lib/template-style-options.js +95 -15
  34. package/dist/src/page-runtime.js +1 -0
  35. package/dist/src/page-shell.js +941 -0
  36. package/dist/src/primitive-context.js +163 -0
  37. package/dist/src/primitive-registry.js +340 -0
  38. package/dist/src/primitive-sdk.js +3 -0
  39. package/dist/src/primitives/remotion/html-image.js +28 -0
  40. package/dist/src/react-page-shell.js +34 -0
  41. package/dist/src/ready-post-schedule-component.js +1514 -0
  42. package/dist/src/registry.js +44 -18
  43. package/dist/src/runtime.js +6 -1
  44. package/dist/src/services/api-call-history.js +245 -0
  45. package/dist/src/services/auth.js +27 -9
  46. package/dist/src/services/billing.js +248 -9
  47. package/dist/src/services/chat-threads.js +88 -0
  48. package/dist/src/services/job-logs.js +10 -3
  49. package/dist/src/services/jobs.js +13 -2
  50. package/dist/src/services/providers.js +944 -55
  51. package/dist/src/services/rate-limits.js +236 -0
  52. package/dist/src/services/remotion.js +143 -16
  53. package/dist/src/services/storage.js +23 -8
  54. package/dist/src/services/template-certification.js +26 -3
  55. package/dist/src/services/template-loader.js +19 -1
  56. package/dist/src/services/template-sources.js +316 -7
  57. package/dist/src/template-editor-pages.js +2309 -0
  58. package/dist/src/template-editor-shell.js +1507 -0
  59. package/dist/src/worker.js +120 -22
  60. package/package.json +30 -6
  61. package/public/assets/homepage-app.js +54 -0
  62. package/public/assets/homepage-client-app.js +54 -0
  63. package/public/assets/page-runtime-client-app.js +68 -0
  64. package/dist/templates/template_0000/src/lib/images.js +0 -202
  65. package/dist/templates/template_0000/src/remotion/Root.js +0 -33
  66. package/dist/templates/template_0000/src/remotion/index.js +0 -3
  67. package/dist/templates/template_0000/src/sdk.js +0 -3
  68. package/dist/templates/template_0000/src/style-options.js +0 -51
  69. package/dist/templates/template_0000/src/template-dna.js +0 -9
  70. package/dist/templates/template_0000/src/template.js +0 -1441
  71. package/templates/template_0000/README.md +0 -77
  72. package/templates/template_0000/SKILL.md +0 -225
  73. package/templates/template_0000/assets/Abel-Regular.ttf +0 -0
  74. package/templates/template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
  75. package/templates/template_0000/assets/Montserrat[wght].ttf +0 -0
  76. package/templates/template_0000/assets/SourceCodePro[wght].ttf +0 -0
  77. package/templates/template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
  78. package/templates/template_0000/assets/Yesteryear-Regular.ttf +0 -0
  79. package/templates/template_0000/composition.json +0 -11
  80. package/templates/template_0000/package.json +0 -28
  81. package/templates/template_0000/research/preview/.gitkeep +0 -1
  82. package/templates/template_0000/research/source_notes.md +0 -7
  83. package/templates/template_0000/src/lib/images.js +0 -202
  84. package/templates/template_0000/src/lib/images.ts +0 -241
  85. package/templates/template_0000/src/remotion/Root.js +0 -33
  86. package/templates/template_0000/src/remotion/Root.tsx +0 -75
  87. package/templates/template_0000/src/remotion/index.js +0 -3
  88. package/templates/template_0000/src/remotion/index.tsx +0 -4
  89. package/templates/template_0000/src/sdk.js +0 -3
  90. package/templates/template_0000/src/sdk.ts +0 -122
  91. package/templates/template_0000/src/style-options.js +0 -51
  92. package/templates/template_0000/src/style-options.ts +0 -60
  93. package/templates/template_0000/src/template-dna.js +0 -9
  94. package/templates/template_0000/src/template-dna.ts +0 -15
  95. package/templates/template_0000/src/template.js +0 -1441
  96. package/templates/template_0000/src/template.ts +0 -2042
  97. package/templates/template_0000/template.config.json +0 -21
  98. package/templates/template_0000/tsconfig.json +0 -19
@@ -1,10 +1,12 @@
1
1
  import { config } from "./config.js";
2
2
  import { createTemplateJobContext } from "./context.js";
3
3
  import { database } from "./db.js";
4
+ import { createPrimitiveJobContext } from "./primitive-context.js";
5
+ import { primitiveRegistry } from "./primitive-registry.js";
4
6
  import { templateRegistry } from "./registry.js";
5
7
  import { BillingService } from "./services/billing.js";
6
8
  import { JobsService } from "./services/jobs.js";
7
- import { ProviderAuthError, ProviderKeyUnavailableError, ProviderRateLimitError, ProviderService } from "./services/providers.js";
9
+ import { ProviderAuthError, ProviderKeyUnavailableError, ProviderLeaseTimeoutError, ProviderRateLimitError, ProviderService } from "./services/providers.js";
8
10
  import { RemotionService } from "./services/remotion.js";
9
11
  import { StorageService } from "./services/storage.js";
10
12
  import { WebhookService } from "./services/webhooks.js";
@@ -36,7 +38,7 @@ export class Worker {
36
38
  try {
37
39
  const availableSlots = Math.max(0, config.WORKER_MAX_CONCURRENT_JOBS - this.activeJobs);
38
40
  if (availableSlots > 0) {
39
- const runnable = database.listRunnableJobs(Math.min(config.WORKER_BATCH_SIZE, availableSlots));
41
+ const runnable = this.selectRunnableJobs(Math.min(config.WORKER_BATCH_SIZE, availableSlots));
40
42
  const executions = runnable.map(async (job) => {
41
43
  this.activeJobs += 1;
42
44
  try {
@@ -62,39 +64,61 @@ export class Worker {
62
64
  }
63
65
  const customer = database.getCustomerById(job.customerId);
64
66
  const template = templateRegistry.get(job.templateId);
65
- if (!customer || !template) {
66
- this.jobs.failJob(job.id, { message: "Missing customer or template." });
67
+ const primitive = template ? null : primitiveRegistry.get(job.templateId);
68
+ if (!customer || (!template && !primitive)) {
69
+ this.jobs.failJob(job.id, { message: "Missing customer, template, or primitive." });
67
70
  return;
68
71
  }
69
- const workflow = template.jobs[job.workflowName];
70
- if (!workflow) {
71
- this.jobs.failJob(job.id, { message: `Unknown workflow ${job.workflowName}` });
72
- return;
72
+ if (template) {
73
+ const wallet = await this.billing.getWalletSummary(customer.id);
74
+ if (wallet.balanceUsd <= 0) {
75
+ this.jobs.failJob(job.id, {
76
+ message: "Wallet balance must be greater than $0.00 USD before starting a template job.",
77
+ type: "insufficient_wallet_balance"
78
+ });
79
+ await this.emitWebhookIfNeeded("job.failed", job.id);
80
+ return;
81
+ }
73
82
  }
74
83
  this.jobs.markRunning(job.id);
75
84
  await this.emitWebhookIfNeeded("job.running", job.id);
76
- const ctx = createTemplateJobContext({
77
- customer,
78
- job,
79
- template,
80
- workerId: this.workerId,
81
- storage: this.storage,
82
- jobs: this.jobs,
83
- billing: this.billing,
84
- providers: this.providers,
85
- remotion: this.remotion
86
- });
87
85
  try {
88
- const result = await workflow(ctx, job.payload);
86
+ const result = template
87
+ ? await runTemplateWorkflow({
88
+ customer,
89
+ job,
90
+ template,
91
+ workerId: this.workerId,
92
+ storage: this.storage,
93
+ jobs: this.jobs,
94
+ billing: this.billing,
95
+ providers: this.providers,
96
+ remotion: this.remotion
97
+ })
98
+ : await runPrimitiveWorkflow({
99
+ customer,
100
+ job,
101
+ primitive: primitive,
102
+ workerId: this.workerId,
103
+ storage: this.storage,
104
+ billing: this.billing,
105
+ providers: this.providers,
106
+ remotion: this.remotion
107
+ });
89
108
  this.jobs.succeedJob(job.id, result.output ?? {}, result.progress ?? 1);
90
109
  await this.emitWebhookIfNeeded("job.succeeded", job.id);
91
110
  }
92
111
  catch (error) {
93
- if (error instanceof ProviderKeyUnavailableError) {
94
- this.jobs.requeueJob(job, config.DEFAULT_JOB_DELAY_SECONDS, { message: error.message, type: "provider_key_unavailable" });
112
+ if (error instanceof ProviderLeaseTimeoutError) {
113
+ this.jobs.requeueJob(job, error.retryAfterSeconds, { message: error.message, type: "provider_key_wait_timeout" });
95
114
  await this.emitWebhookIfNeeded("job.queued", job.id);
96
115
  return;
97
116
  }
117
+ if (error instanceof ProviderKeyUnavailableError) {
118
+ this.jobs.failJob(job.id, { message: error.message, type: "provider_key_unavailable" });
119
+ await this.emitWebhookIfNeeded("job.failed", job.id);
120
+ return;
121
+ }
98
122
  if (error instanceof ProviderRateLimitError) {
99
123
  this.jobs.requeueJob(job, error.retryAfterSeconds, { message: error.message, type: "provider_rate_limited" });
100
124
  await this.emitWebhookIfNeeded("job.queued", job.id);
@@ -131,4 +155,78 @@ export class Worker {
131
155
  })
132
156
  });
133
157
  }
158
+ selectRunnableJobs(limit) {
159
+ const candidateLimit = Math.max(limit * 10, config.WORKER_BATCH_SIZE * 5, 25);
160
+ const candidates = database.listRunnableJobs(candidateLimit);
161
+ const providerCapacity = this.buildProviderCapacityMap();
162
+ const selected = [];
163
+ for (const job of candidates) {
164
+ if (selected.length >= limit) {
165
+ break;
166
+ }
167
+ const providerHint = parseProviderHint(job.payload._providerHint);
168
+ if (!providerHint) {
169
+ selected.push(job);
170
+ continue;
171
+ }
172
+ const available = providerCapacity.get(this.providerCapacityKey(job.customerId, providerHint)) ?? 0;
173
+ if (available <= 0) {
174
+ continue;
175
+ }
176
+ providerCapacity.set(this.providerCapacityKey(job.customerId, providerHint), available - 1);
177
+ selected.push(job);
178
+ }
179
+ return selected;
180
+ }
181
+ buildProviderCapacityMap() {
182
+ const map = new Map();
183
+ for (const entry of database.listAvailableProviderKeyCounts()) {
184
+ map.set(this.providerCapacityKey(entry.customerId, entry.provider), entry.availableCount);
185
+ }
186
+ return map;
187
+ }
188
+ providerCapacityKey(customerId, provider) {
189
+ return `${customerId}:${provider}`;
190
+ }
191
+ }
192
+ async function runTemplateWorkflow(input) {
193
+ const workflow = input.template.jobs[input.job.workflowName];
194
+ if (!workflow) {
195
+ throw new Error(`Unknown workflow ${input.job.workflowName}`);
196
+ }
197
+ const ctx = createTemplateJobContext({
198
+ customer: input.customer,
199
+ job: input.job,
200
+ template: input.template,
201
+ workerId: input.workerId,
202
+ storage: input.storage,
203
+ jobs: input.jobs,
204
+ billing: input.billing,
205
+ providers: input.providers,
206
+ remotion: input.remotion
207
+ });
208
+ return workflow(ctx, input.job.payload);
209
+ }
210
+ async function runPrimitiveWorkflow(input) {
211
+ const workflow = input.primitive.jobs[input.job.workflowName];
212
+ if (!workflow) {
213
+ throw new Error(`Unknown workflow ${input.job.workflowName}`);
214
+ }
215
+ const ctx = createPrimitiveJobContext({
216
+ customer: input.customer,
217
+ job: input.job,
218
+ primitive: input.primitive,
219
+ workerId: input.workerId,
220
+ storage: input.storage,
221
+ billing: input.billing,
222
+ providers: input.providers,
223
+ remotion: input.remotion
224
+ });
225
+ return workflow(ctx, input.job.payload);
226
+ }
227
+ function parseProviderHint(value) {
228
+ if (value === "openai" || value === "gemini" || value === "openrouter" || value === "perplexity") {
229
+ return value;
230
+ }
231
+ return null;
134
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mevdragon/vidfarm-devcli",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Developer CLI for running the Vidfarm local template platform.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,12 +9,20 @@
9
9
  },
10
10
  "files": [
11
11
  "dist/src",
12
- "dist/templates/template_0000",
13
- "templates/template_0000",
12
+ "public/assets",
13
+ "auto-create-templates/AUTO_CREATE_TEMPLATES.md",
14
+ "auto-create-templates/extractor-system-prompt.md",
15
+ "auto-create-templates/production-graph.schema.json",
16
+ "auto-create-templates/runbook.md",
17
+ "auto-create-templates/template-plan.schema.json",
18
+ "auto-create-templates/template-planner-prompt.md",
19
+ "dist/templates/vidfarm_template_0000",
20
+ "templates/vidfarm_template_0000",
14
21
  "README.md",
15
22
  "SKILL.developer.md",
16
23
  "GETTING_STARTED.developers.md",
17
- ".env.example"
24
+ ".env.example",
25
+ "!readme.secret.md"
18
26
  ],
19
27
  "publishConfig": {
20
28
  "access": "restricted"
@@ -28,10 +36,13 @@
28
36
  },
29
37
  "scripts": {
30
38
  "dev": "tsx watch src/index.ts",
39
+ "dev:frontend": "node scripts/build-homepage-client.mjs --watch",
31
40
  "dev:cli": "tsx src/cli.ts dev",
41
+ "build:frontend": "node scripts/build-homepage-client.mjs",
42
+ "operator:template-artifact": "node scripts/platform-operator-template-artifact.mjs",
32
43
  "deploy:prod-inplace": "bash scripts/deploy-prod-inplace.sh",
33
44
  "rollback:prod-inplace": "bash scripts/rollback-prod-inplace.sh",
34
- "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json",
45
+ "build": "npm run build:frontend && node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json",
35
46
  "start": "node dist/src/index.js",
36
47
  "check": "tsc -p tsconfig.json --noEmit",
37
48
  "cdk:synth": "npm run build && npx aws-cdk synth --app 'node dist/infra/cdk/bin/vidfarm-prod.js'",
@@ -39,12 +50,23 @@
39
50
  "prepack": "npm run build"
40
51
  },
41
52
  "dependencies": {
53
+ "@ai-sdk/google": "^3.0.79",
54
+ "@ai-sdk/openai": "^3.0.65",
55
+ "@ai-sdk/openai-compatible": "^2.0.48",
56
+ "@assistant-ui/react": "^0.14.8",
57
+ "@assistant-ui/react-data-stream": "^0.12.14",
58
+ "@aws-sdk/client-dynamodb": "^3.1056.0",
42
59
  "@aws-sdk/client-s3": "^3.787.0",
43
60
  "@aws-sdk/s3-request-presigner": "^3.787.0",
61
+ "@fontsource/libre-baskerville": "^5.2.10",
62
+ "@fontsource/montserrat": "^5.2.8",
63
+ "@fontsource/source-code-pro": "^5.2.7",
64
+ "@fontsource/tiktok-sans": "^5.2.4",
44
65
  "@hono/node-server": "^1.14.4",
45
66
  "@remotion/bundler": "4.0.355",
46
67
  "@remotion/lambda": "4.0.355",
47
68
  "@remotion/renderer": "4.0.355",
69
+ "ai": "^6.0.191",
48
70
  "better-sqlite3": "^12.1.1",
49
71
  "dotenv": "^16.5.0",
50
72
  "hono": "^4.8.3",
@@ -61,7 +83,9 @@
61
83
  "@types/react-dom": "^18.3.7",
62
84
  "aws-cdk-lib": "^2.196.0",
63
85
  "constructs": "^10.4.2",
86
+ "esbuild": "^0.28.0",
64
87
  "tsx": "^4.19.4",
65
- "typescript": "^5.8.3"
88
+ "typescript": "^5.8.3",
89
+ "zustand": "^5.0.13"
66
90
  }
67
91
  }