memorix 1.9.2 → 1.9.4

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 (39) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/dist/cli/index.js +358 -146
  5. package/dist/index.js +281 -125
  6. package/dist/maintenance-runner.js +219 -97
  7. package/dist/media-audio-runner.js +219 -97
  8. package/dist/media-video-runner.js +219 -97
  9. package/dist/memcode-runtime/CHANGELOG.md +27 -0
  10. package/dist/sdk.js +280 -124
  11. package/dist/vector-backfill-runner.js +219 -97
  12. package/docs/AGENT_OPERATOR_PLAYBOOK.md +15 -0
  13. package/docs/ARCHITECTURE.md +23 -0
  14. package/docs/DEVELOPMENT.md +1 -1
  15. package/docs/PERFORMANCE.md +50 -0
  16. package/docs/README.md +1 -1
  17. package/package.json +1 -1
  18. package/plugins/antigravity/memorix/plugin.json +1 -1
  19. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  20. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  21. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  22. package/plugins/copilot/memorix/plugin.json +1 -1
  23. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  24. package/plugins/hermes/memorix/plugin.yaml +1 -1
  25. package/plugins/omp/memorix/package.json +1 -1
  26. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  27. package/plugins/pi/memorix/package.json +1 -1
  28. package/server.json +2 -2
  29. package/src/cli/commands/doctor.ts +78 -17
  30. package/src/cli/commands/media.ts +2 -0
  31. package/src/media/minimax.ts +26 -2
  32. package/src/media/video-jobs.ts +9 -1
  33. package/src/server.ts +3 -1
  34. package/src/store/mini-skill-store.ts +31 -22
  35. package/src/store/obs-store.ts +46 -30
  36. package/src/store/session-store.ts +35 -21
  37. package/src/store/sqlite-db.ts +16 -7
  38. package/src/store/sqlite-reliability.ts +87 -0
  39. package/src/store/sqlite-store.ts +4 -1
@@ -550,70 +550,79 @@ function getDatabase(dataDir) {
550
550
  loadBetterSqlite3();
551
551
  fs.mkdirSync(dataDir, { recursive: true });
552
552
  const dbPath = path3.join(dataDir, "memorix.db");
553
- const db2 = createDatabase(dbPath);
554
- db2.pragma("journal_mode = WAL");
555
- db2.pragma("busy_timeout = 5000");
556
- db2.pragma("foreign_keys = ON");
557
- db2.exec(CREATE_OBSERVATIONS_TABLE);
558
- db2.exec(CREATE_MINI_SKILLS_TABLE);
559
- db2.exec(CREATE_SESSIONS_TABLE);
560
- db2.exec(CREATE_META_TABLE);
561
- db2.exec(CREATE_TEAM_AGENTS_TABLE);
562
- db2.exec(CREATE_TEAM_TASKS_TABLE);
563
- db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
564
- db2.exec(CREATE_TEAM_MESSAGES_TABLE);
565
- db2.exec(CREATE_TEAM_LOCKS_TABLE);
566
- db2.exec(CREATE_TEAM_ROLES_TABLE);
567
- db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
568
- db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
569
- db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
570
- db2.exec(CREATE_CODE_FILES_TABLE);
571
- db2.exec(CREATE_CODE_SYMBOLS_TABLE);
572
- db2.exec(CREATE_CODE_EDGES_TABLE);
573
- db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
574
- db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
575
- db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
576
- db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
553
+ let db2;
577
554
  try {
578
- db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
579
- } catch {
580
- }
581
- try {
582
- db2.exec(`ALTER TABLE mini_skills ADD COLUMN updatedAt TEXT`);
583
- } catch {
584
- }
585
- try {
586
- db2.exec(`ALTER TABLE observations ADD COLUMN createdByAgentId TEXT`);
587
- } catch {
588
- }
589
- try {
590
- db2.exec(`ALTER TABLE observations ADD COLUMN writeGeneration INTEGER DEFAULT 0`);
591
- } catch {
592
- }
593
- try {
594
- db2.exec(`ALTER TABLE team_tasks ADD COLUMN required_role TEXT`);
595
- } catch {
596
- }
597
- try {
598
- db2.exec(`ALTER TABLE team_tasks ADD COLUMN preferred_role TEXT`);
599
- } catch {
600
- }
601
- try {
602
- db2.exec(`ALTER TABLE team_messages ADD COLUMN to_role TEXT`);
603
- } catch {
604
- }
605
- try {
606
- db2.exec(`ALTER TABLE team_messages ADD COLUMN handoff_status TEXT`);
607
- } catch {
555
+ db2 = createDatabase(dbPath);
556
+ db2.pragma("busy_timeout = 5000");
557
+ db2.pragma("journal_mode = WAL");
558
+ db2.pragma("foreign_keys = ON");
559
+ db2.exec(CREATE_OBSERVATIONS_TABLE);
560
+ db2.exec(CREATE_MINI_SKILLS_TABLE);
561
+ db2.exec(CREATE_SESSIONS_TABLE);
562
+ db2.exec(CREATE_META_TABLE);
563
+ db2.exec(CREATE_TEAM_AGENTS_TABLE);
564
+ db2.exec(CREATE_TEAM_TASKS_TABLE);
565
+ db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
566
+ db2.exec(CREATE_TEAM_MESSAGES_TABLE);
567
+ db2.exec(CREATE_TEAM_LOCKS_TABLE);
568
+ db2.exec(CREATE_TEAM_ROLES_TABLE);
569
+ db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
570
+ db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
571
+ db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
572
+ db2.exec(CREATE_CODE_FILES_TABLE);
573
+ db2.exec(CREATE_CODE_SYMBOLS_TABLE);
574
+ db2.exec(CREATE_CODE_EDGES_TABLE);
575
+ db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
576
+ db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
577
+ db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
578
+ db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
579
+ try {
580
+ db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
581
+ } catch {
582
+ }
583
+ try {
584
+ db2.exec(`ALTER TABLE mini_skills ADD COLUMN updatedAt TEXT`);
585
+ } catch {
586
+ }
587
+ try {
588
+ db2.exec(`ALTER TABLE observations ADD COLUMN createdByAgentId TEXT`);
589
+ } catch {
590
+ }
591
+ try {
592
+ db2.exec(`ALTER TABLE observations ADD COLUMN writeGeneration INTEGER DEFAULT 0`);
593
+ } catch {
594
+ }
595
+ try {
596
+ db2.exec(`ALTER TABLE team_tasks ADD COLUMN required_role TEXT`);
597
+ } catch {
598
+ }
599
+ try {
600
+ db2.exec(`ALTER TABLE team_tasks ADD COLUMN preferred_role TEXT`);
601
+ } catch {
602
+ }
603
+ try {
604
+ db2.exec(`ALTER TABLE team_messages ADD COLUMN to_role TEXT`);
605
+ } catch {
606
+ }
607
+ try {
608
+ db2.exec(`ALTER TABLE team_messages ADD COLUMN handoff_status TEXT`);
609
+ } catch {
610
+ }
611
+ applySchemaMigrations(db2);
612
+ db2.exec(CREATE_INDEXES);
613
+ initializeObservationLexicalIndex(db2);
614
+ db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
615
+ db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
616
+ db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
617
+ _dbCache.set(normalized, db2);
618
+ return db2;
619
+ } catch (error) {
620
+ try {
621
+ db2?.close();
622
+ } catch {
623
+ }
624
+ throw error;
608
625
  }
609
- applySchemaMigrations(db2);
610
- db2.exec(CREATE_INDEXES);
611
- initializeObservationLexicalIndex(db2);
612
- db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
613
- db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
614
- db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
615
- _dbCache.set(normalized, db2);
616
- return db2;
617
626
  }
618
627
  function closeAllDatabases() {
619
628
  for (const [key, db2] of _dbCache) {
@@ -2616,6 +2625,74 @@ var init_types = __esm({
2616
2625
  }
2617
2626
  });
2618
2627
 
2628
+ // src/store/sqlite-reliability.ts
2629
+ function isTransientSqliteError(error) {
2630
+ const code = error?.code;
2631
+ if (typeof code === "string") {
2632
+ return /^SQLITE_BUSY(?:_|$)/i.test(code);
2633
+ }
2634
+ return error instanceof Error && /\bdatabase is locked\b|\bdatabase is busy\b/i.test(error.message);
2635
+ }
2636
+ function isSqliteUnavailableError(error) {
2637
+ return error instanceof SqliteUnavailableError || error instanceof Error && /SQLite is not available|better-sqlite3.*failed|node:sqlite.*failed|bun:sqlite.*failed/i.test(error.message);
2638
+ }
2639
+ function degradedReadError(storeName) {
2640
+ return new Error(`[memorix] Cannot read ${storeName}: SQLite backend unavailable (memory is not loaded)`);
2641
+ }
2642
+ function degradedWriteError(storeName) {
2643
+ return new Error(`[memorix] Cannot write ${storeName}: SQLite backend unavailable (degraded mode; read-only)`);
2644
+ }
2645
+ function formatSqliteFailure(error) {
2646
+ return error instanceof Error && error.message ? error.message : String(error);
2647
+ }
2648
+ function delay(ms) {
2649
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
2650
+ }
2651
+ async function retrySqliteBusy(operation, label) {
2652
+ for (let attempt = 0; ; attempt++) {
2653
+ try {
2654
+ return await operation();
2655
+ } catch (error) {
2656
+ if (!isTransientSqliteError(error) || attempt >= SQLITE_BUSY_RETRY_DELAYS_MS.length) throw error;
2657
+ const waitMs = SQLITE_BUSY_RETRY_DELAYS_MS[attempt];
2658
+ console.error(
2659
+ `[memorix] ${label} SQLite busy (attempt ${attempt + 1}/${SQLITE_BUSY_RETRY_DELAYS_MS.length + 1}), retrying in ${waitMs}ms`
2660
+ );
2661
+ await delay(waitMs);
2662
+ }
2663
+ }
2664
+ }
2665
+ async function initializeSqliteStore(factory, dataDir, label) {
2666
+ try {
2667
+ loadBetterSqlite3();
2668
+ } catch (error) {
2669
+ throw new SqliteUnavailableError(error);
2670
+ }
2671
+ return retrySqliteBusy(async () => {
2672
+ const store = factory();
2673
+ await store.init(dataDir);
2674
+ return store;
2675
+ }, label);
2676
+ }
2677
+ var SQLITE_BUSY_RETRY_DELAYS_MS, SqliteUnavailableError;
2678
+ var init_sqlite_reliability = __esm({
2679
+ "src/store/sqlite-reliability.ts"() {
2680
+ "use strict";
2681
+ init_esm_shims();
2682
+ init_sqlite_db();
2683
+ SQLITE_BUSY_RETRY_DELAYS_MS = [50, 150, 400, 1e3, 2500];
2684
+ SqliteUnavailableError = class extends Error {
2685
+ code = "MEMORIX_SQLITE_UNAVAILABLE";
2686
+ constructor(cause) {
2687
+ super(
2688
+ cause instanceof Error && cause.message ? cause.message : "[memorix] SQLite is unavailable (install a supported SQLite runtime)"
2689
+ );
2690
+ this.name = "SqliteUnavailableError";
2691
+ }
2692
+ };
2693
+ }
2694
+ });
2695
+
2619
2696
  // src/store/file-lock.ts
2620
2697
  import { promises as fs2 } from "fs";
2621
2698
  import { randomUUID as randomUUID3 } from "crypto";
@@ -4539,10 +4616,10 @@ async function fetchWithRetry(url, apiKey, body, options = {}, attempt = 0, nati
4539
4616
  );
4540
4617
  }
4541
4618
  if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
4542
- const delay2 = BASE_DELAY_MS * Math.pow(2, attempt);
4619
+ const delay3 = BASE_DELAY_MS * Math.pow(2, attempt);
4543
4620
  const retryAfter = response.headers.get("retry-after");
4544
4621
  const parsedRetryAfter = retryAfter ? parseInt(retryAfter, 10) * 1e3 : NaN;
4545
- const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay2;
4622
+ const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay3;
4546
4623
  console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
4547
4624
  await waitForRetry(waitMs, options.signal);
4548
4625
  return fetchWithRetry(url, apiKey, body, options, attempt + 1, nativeGemini);
@@ -6574,6 +6651,7 @@ var init_sqlite_store = __esm({
6574
6651
  "use strict";
6575
6652
  init_esm_shims();
6576
6653
  init_sqlite_db();
6654
+ init_sqlite_reliability();
6577
6655
  init_sqlite_fts();
6578
6656
  SqliteBackend = class {
6579
6657
  db = null;
@@ -6851,7 +6929,9 @@ var init_sqlite_store = __esm({
6851
6929
  // ── Compound atomic operation ────────────────────────────────────
6852
6930
  async atomic(fn) {
6853
6931
  const run = this._atomicQueue.catch(() => void 0).then(async () => {
6854
- this.db.prepare("BEGIN IMMEDIATE").run();
6932
+ await retrySqliteBusy(async () => {
6933
+ this.db.prepare("BEGIN IMMEDIATE").run();
6934
+ }, "Observation atomic write");
6855
6935
  try {
6856
6936
  const tx = {
6857
6937
  loadAll: async () => this.rawLoadAll(),
@@ -6950,15 +7030,15 @@ function resetObservationStore() {
6950
7030
  async function createObservationStore(dataDir) {
6951
7031
  try {
6952
7032
  const { SqliteBackend: SqliteBackend2 } = await Promise.resolve().then(() => (init_sqlite_store(), sqlite_store_exports));
6953
- const store2 = new SqliteBackend2();
6954
- await store2.init(dataDir);
6955
- return store2;
7033
+ return await initializeSqliteStore(() => new SqliteBackend2(), dataDir, "Observation store");
6956
7034
  } catch (err) {
6957
- console.error(`[memorix] SQLite backend unavailable \u2014 degraded mode (read-only): ${err instanceof Error ? err.message : err}`);
7035
+ if (!isSqliteUnavailableError(err)) throw err;
7036
+ const reason = formatSqliteFailure(err);
7037
+ console.error(`[memorix] SQLite module unavailable \u2014 degraded mode (reads/writes disabled): ${reason}`);
7038
+ const degraded = new DegradedBackend(reason);
7039
+ await degraded.init(dataDir);
7040
+ return degraded;
6958
7041
  }
6959
- const store = new DegradedBackend();
6960
- await store.init(dataDir);
6961
- return store;
6962
7042
  }
6963
7043
  async function initObservationStore(dataDir) {
6964
7044
  if (_store2 && _storeDataDir === dataDir) {
@@ -6982,36 +7062,44 @@ var init_obs_store = __esm({
6982
7062
  "src/store/obs-store.ts"() {
6983
7063
  "use strict";
6984
7064
  init_esm_shims();
7065
+ init_sqlite_reliability();
6985
7066
  _store2 = null;
6986
7067
  _storeDataDir = null;
6987
7068
  DegradedBackend = class {
7069
+ constructor(reason = "SQLite runtime unavailable") {
7070
+ this.reason = reason;
7071
+ }
7072
+ reason;
6988
7073
  dataDir = "";
7074
+ unavailableRead() {
7075
+ return degradedReadError("observations");
7076
+ }
6989
7077
  async init(dataDir) {
6990
7078
  this.dataDir = dataDir;
6991
7079
  }
6992
7080
  async loadAll() {
6993
- return [];
7081
+ throw this.unavailableRead();
6994
7082
  }
6995
7083
  async loadByProject(_projectId, _options) {
6996
- return [];
7084
+ throw this.unavailableRead();
6997
7085
  }
6998
7086
  async countByProject(_projectId, _options) {
6999
- return 0;
7087
+ throw this.unavailableRead();
7000
7088
  }
7001
7089
  async getById(_id) {
7002
- return void 0;
7090
+ throw this.unavailableRead();
7003
7091
  }
7004
7092
  async loadIdCounter() {
7005
- return 1;
7093
+ throw this.unavailableRead();
7006
7094
  }
7007
7095
  async countAll() {
7008
- return 0;
7096
+ throw this.unavailableRead();
7009
7097
  }
7010
7098
  async listProjectIds() {
7011
- return [];
7099
+ throw this.unavailableRead();
7012
7100
  }
7013
7101
  async searchLexical(_options) {
7014
- return [];
7102
+ throw this.unavailableRead();
7015
7103
  }
7016
7104
  hasLexicalIndex() {
7017
7105
  return false;
@@ -7020,25 +7108,25 @@ var init_obs_store = __esm({
7020
7108
  return false;
7021
7109
  }
7022
7110
  async insert(_obs) {
7023
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7111
+ throw degradedWriteError("observations");
7024
7112
  }
7025
7113
  async update(_obs) {
7026
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7114
+ throw degradedWriteError("observations");
7027
7115
  }
7028
7116
  async remove(_id) {
7029
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7117
+ throw degradedWriteError("observations");
7030
7118
  }
7031
7119
  async bulkReplace(_obs) {
7032
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7120
+ throw degradedWriteError("observations");
7033
7121
  }
7034
7122
  async bulkRemoveByIds(_ids) {
7035
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7123
+ throw degradedWriteError("observations");
7036
7124
  }
7037
7125
  async saveIdCounter(_nextId) {
7038
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7126
+ throw degradedWriteError("observations");
7039
7127
  }
7040
7128
  async atomic(_fn) {
7041
- throw new Error("[memorix] Cannot write observations: SQLite backend unavailable (degraded mode)");
7129
+ throw degradedWriteError("observations");
7042
7130
  }
7043
7131
  async ensureFresh() {
7044
7132
  return false;
@@ -7051,6 +7139,9 @@ var init_obs_store = __esm({
7051
7139
  getBackendName() {
7052
7140
  return "degraded";
7053
7141
  }
7142
+ getBackendReason() {
7143
+ return this.reason;
7144
+ }
7054
7145
  };
7055
7146
  }
7056
7147
  });
@@ -55230,10 +55321,10 @@ var require_retry3 = __commonJS({
55230
55321
  if (!await shouldRetryFn(err)) {
55231
55322
  return { shouldRetry: false, config: err.config };
55232
55323
  }
55233
- const delay2 = getNextRetryDelay(config);
55324
+ const delay3 = getNextRetryDelay(config);
55234
55325
  err.config.retryConfig.currentRetryAttempt += 1;
55235
- const backoff = config.retryBackoff ? config.retryBackoff(err, delay2) : new Promise((resolve2) => {
55236
- setTimeout(resolve2, delay2);
55326
+ const backoff = config.retryBackoff ? config.retryBackoff(err, delay3) : new Promise((resolve2) => {
55327
+ setTimeout(resolve2, delay3);
55237
55328
  });
55238
55329
  if (config.onRetryAttempt) {
55239
55330
  await config.onRetryAttempt(err);
@@ -97019,7 +97110,7 @@ async function retryBackoff(fn, strategy) {
97019
97110
  retryInterval = initialInterval * Math.pow(x2, exponent) + Math.random() * 1e3;
97020
97111
  }
97021
97112
  const d = Math.min(retryInterval, maxInterval);
97022
- await delay(d);
97113
+ await delay2(d);
97023
97114
  x2++;
97024
97115
  }
97025
97116
  }
@@ -97040,8 +97131,8 @@ function retryIntervalFromResponse(res) {
97040
97131
  }
97041
97132
  return 0;
97042
97133
  }
97043
- async function delay(delay2) {
97044
- return new Promise((resolve2) => setTimeout(resolve2, delay2));
97134
+ async function delay2(delay3) {
97135
+ return new Promise((resolve2) => setTimeout(resolve2, delay3));
97045
97136
  }
97046
97137
  var defaultBackoff, PermanentError, TemporaryError, codeRangeRE2;
97047
97138
  var init_retries = __esm({
@@ -143318,7 +143409,20 @@ function normalizeMiniMaxVideoRequest(input) {
143318
143409
  if (ratio !== "adaptive" && ratio !== "16:9" && ratio !== "9:16" && ratio !== "1:1") {
143319
143410
  throw new Error("MiniMax video ratio must be adaptive, 16:9, 9:16, or 1:1");
143320
143411
  }
143321
- return { region, model, prompt, resolution, duration, ratio };
143412
+ let firstFrameImageUrl;
143413
+ if (input.firstFrameImageUrl !== void 0) {
143414
+ firstFrameImageUrl = input.firstFrameImageUrl.trim();
143415
+ let parsed;
143416
+ try {
143417
+ parsed = new URL(firstFrameImageUrl);
143418
+ } catch {
143419
+ throw new Error("MiniMax first-frame image must be a public HTTPS URL");
143420
+ }
143421
+ if (parsed.protocol !== "https:" || parsed.username || parsed.password || sanitizeCredentials(firstFrameImageUrl) !== firstFrameImageUrl) {
143422
+ throw new Error("MiniMax first-frame image must be an HTTPS URL without credentials");
143423
+ }
143424
+ }
143425
+ return { region, model, prompt, resolution, duration, ratio, ...firstFrameImageUrl ? { firstFrameImageUrl } : {} };
143322
143426
  }
143323
143427
  function videoRequestConfig(input) {
143324
143428
  const normalized = normalizeMiniMaxVideoRequest(input);
@@ -143395,7 +143499,14 @@ async function createMiniMaxVideoTask(input, dependencies = {}) {
143395
143499
  headers: videoHeaders(config.apiKey),
143396
143500
  body: JSON.stringify({
143397
143501
  model: config.model,
143398
- content: [{ type: "text", text: config.prompt }],
143502
+ content: [
143503
+ { type: "text", text: config.prompt },
143504
+ ...config.firstFrameImageUrl ? [{
143505
+ type: "image_url",
143506
+ image_url: { url: config.firstFrameImageUrl },
143507
+ role: "first_frame"
143508
+ }] : []
143509
+ ],
143399
143510
  resolution: config.resolution,
143400
143511
  duration: config.duration,
143401
143512
  ratio: config.ratio
@@ -143556,10 +143667,19 @@ function parseStoredRequest(value) {
143556
143667
  const duration = value.duration;
143557
143668
  const ratio = value.ratio;
143558
143669
  const maxBytes = value.maxBytes;
143559
- if (provider2 !== "minimax" && provider2 !== "minimax-cn" || region !== "global" && region !== "cn" || model !== "MiniMax-H3" || typeof prompt !== "string" || resolution !== "2K" || duration !== 5 && duration !== 10 || ratio !== "adaptive" && ratio !== "16:9" && ratio !== "9:16" && ratio !== "1:1" || typeof maxBytes !== "number" || !Number.isSafeInteger(maxBytes) || maxBytes < 1) {
143670
+ if (provider2 !== "minimax" && provider2 !== "minimax-cn" || region !== "global" && region !== "cn" || model !== "MiniMax-H3" || typeof prompt !== "string" || value.firstFrameImageUrl !== void 0 && typeof value.firstFrameImageUrl !== "string" || resolution !== "2K" || duration !== 5 && duration !== 10 || ratio !== "adaptive" && ratio !== "16:9" && ratio !== "9:16" && ratio !== "1:1" || typeof maxBytes !== "number" || !Number.isSafeInteger(maxBytes) || maxBytes < 1) {
143560
143671
  throw new Error("Media video job has an invalid request payload");
143561
143672
  }
143562
- return { provider: provider2, region, model, prompt, resolution, duration, ratio, maxBytes };
143673
+ const normalized = normalizeMiniMaxVideoRequest({
143674
+ region,
143675
+ model,
143676
+ prompt,
143677
+ resolution,
143678
+ duration,
143679
+ ratio,
143680
+ firstFrameImageUrl: value.firstFrameImageUrl
143681
+ });
143682
+ return { provider: provider2, ...normalized, maxBytes };
143563
143683
  }
143564
143684
  function mediaJobIdFromMaintenance(job) {
143565
143685
  const mediaJobId = job.payload.mediaJobId;
@@ -143571,6 +143691,7 @@ function mediaJobIdFromMaintenance(job) {
143571
143691
  function toVideoRequest(request) {
143572
143692
  return {
143573
143693
  prompt: request.prompt,
143694
+ firstFrameImageUrl: request.firstFrameImageUrl,
143574
143695
  model: request.model,
143575
143696
  region: request.region,
143576
143697
  resolution: request.resolution,
@@ -143662,6 +143783,7 @@ function queueMiniMaxVideoGeneration(input) {
143662
143783
  region: normalized.region,
143663
143784
  model: normalized.model,
143664
143785
  prompt: normalized.prompt,
143786
+ ...normalized.firstFrameImageUrl ? { firstFrameImageUrl: normalized.firstFrameImageUrl } : {},
143665
143787
  resolution: normalized.resolution,
143666
143788
  duration: normalized.duration,
143667
143789
  ratio: normalized.ratio,