openpond 0.0.68 → 0.0.69

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 (128) hide show
  1. package/dist/chunks/{actions-command-DLOKFA34.js → actions-command-6N5XWMR6.js} +4 -4
  2. package/dist/chunks/{app-layer-K7NAOLDL.js → app-layer-EXXOWJ5H.js} +7 -7
  3. package/dist/chunks/{app-server-runtime-OFZZIWAB.js → app-server-runtime-7FBQBE3C.js} +10 -10
  4. package/dist/chunks/{apps-5VSVJLM7.js → apps-RZSDOFAG.js} +7 -7
  5. package/dist/chunks/{chunk-N6FKRVAT.js → chunk-47EIAYI7.js} +2 -2
  6. package/dist/chunks/{chunk-7FW2CVYN.js → chunk-4L3ZJS2T.js} +426 -1
  7. package/dist/chunks/{chunk-OOJP442J.js → chunk-5TKZBMQM.js} +1 -1
  8. package/dist/chunks/{chunk-WEB37YVJ.js → chunk-7C4OIFOC.js} +1 -1
  9. package/dist/chunks/{chunk-MUS7KPXK.js → chunk-BLFIIAWZ.js} +1931 -19
  10. package/dist/chunks/{chunk-3KLQ52B2.js → chunk-BVY5JYM6.js} +4 -9
  11. package/dist/chunks/{chunk-DBHSOTYZ.js → chunk-D7BO5Y5J.js} +3 -24
  12. package/dist/chunks/chunk-DLQQIWN2.js +648 -0
  13. package/dist/chunks/{chunk-T55IL3GI.js → chunk-DNXBJZAU.js} +1 -1
  14. package/dist/chunks/{chunk-KLD7NT5J.js → chunk-F36ZVO6U.js} +3 -3
  15. package/dist/chunks/{chunk-TSDVA7QP.js → chunk-FEOLMLYU.js} +8 -12
  16. package/dist/chunks/{chunk-QETF6ILG.js → chunk-FQS2QL5F.js} +359 -841
  17. package/dist/chunks/{chunk-J2REM7LE.js → chunk-HFPUR4CQ.js} +5 -116
  18. package/dist/chunks/{chunk-JIEUB6OS.js → chunk-J3YDKJFD.js} +1 -1
  19. package/dist/chunks/{chunk-JGOP4GCK.js → chunk-JTHL5XJ2.js} +5 -25
  20. package/dist/chunks/{chunk-OQLYO7TA.js → chunk-MMRJNSWY.js} +34 -81
  21. package/dist/chunks/{chunk-HFQHD35D.js → chunk-NPNIL6SQ.js} +1 -1
  22. package/dist/chunks/{chunk-IG72OKNB.js → chunk-OOM2PHBE.js} +2080 -16400
  23. package/dist/chunks/{chunk-PSGEH4FC.js → chunk-QTN6HXOR.js} +3 -3
  24. package/dist/chunks/{chunk-HNY7OSDY.js → chunk-SFMNGWNO.js} +1 -1
  25. package/dist/chunks/{chunk-TBEBLKCQ.js → chunk-WBAZFKC7.js} +3 -3
  26. package/dist/chunks/{chunk-NA4L2HQM.js → chunk-Y57RTLVV.js} +33 -33
  27. package/dist/chunks/{chunk-Z2ZWHU7O.js → chunk-YVCYVDNP.js} +1 -1
  28. package/dist/chunks/{cli-6WFY2ULA.js → cli-HIXVXM72.js} +8 -8
  29. package/dist/chunks/{core-commands-HQ3HL34W.js → core-commands-34SVH6ZQ.js} +8 -8
  30. package/dist/chunks/{desktop-test-RU6SRARQ.js → desktop-test-66DPBNJX.js} +7 -7
  31. package/dist/chunks/{extension-4KFKWMC4.js → extension-ZMRHCDO3.js} +36 -87
  32. package/dist/chunks/{help-ZUCPOR22.js → help-COHCZEP2.js} +1 -1
  33. package/dist/chunks/{opchat-AZX7SYM7.js → opchat-2PGW2GNN.js} +10 -18
  34. package/dist/chunks/{organizations-GV6Z7G4J.js → organizations-NZ4OY56V.js} +9 -9
  35. package/dist/chunks/{profile-TSLGZPUI.js → profile-GEMTRPUG.js} +11 -11
  36. package/dist/chunks/{project-agent-SHIQZWPY.js → project-agent-NX6YBGWC.js} +10 -10
  37. package/dist/chunks/{sandbox-command-TRS66NUT.js → sandbox-command-UEY53OJO.js} +8 -8
  38. package/dist/chunks/{sandbox-template-RVWXD5O3.js → sandbox-template-YKYRB645.js} +10 -10
  39. package/dist/chunks/{src-VUJ6EBOU.js → src-IXYDKOBI.js} +799 -965
  40. package/dist/chunks/{src-Q3BOITLJ.js → src-LKJBD5AM.js} +5 -5
  41. package/dist/chunks/{teams-bot-CLCMGBW5.js → teams-bot-K6KZHZJV.js} +7 -7
  42. package/dist/chunks/{workspaces-IIPITOCV.js → workspaces-WXM72UZF.js} +2 -2
  43. package/dist/cli.js +13 -13
  44. package/dist/index.js +15 -56
  45. package/dist/web/assets/App-BF9L0JUv.js +171 -0
  46. package/dist/web/assets/{AppDialog-sLTPiFGX.js → AppDialog-DX-xs3KA.js} +1 -1
  47. package/dist/web/assets/{AppTerminalPanel-B0NCyY4L.js → AppTerminalPanel-CYVj_ITT.js} +2 -2
  48. package/dist/web/assets/{AppsView-DyDyktK2.js → AppsView-ByjyGog7.js} +1 -1
  49. package/dist/web/assets/{BrowserSidebar-C-PQxmQa.js → BrowserSidebar-BDwtMAZl.js} +1 -1
  50. package/dist/web/assets/{CartesianChart-CnerMhTr.js → CartesianChart-Dv6jJfPR.js} +1 -1
  51. package/dist/web/assets/{CollaborationTabs-DJEp6dux.js → CollaborationTabs-CC5AIhMh.js} +1 -1
  52. package/dist/web/assets/{CommandMenu-B5lGz8rG.js → CommandMenu-Ct0Sx7yP.js} +1 -1
  53. package/dist/web/assets/{CommunityView-DQJaHBa5.js → CommunityView-C_zVE0jg.js} +1 -1
  54. package/dist/web/assets/{ComposerCreateImproveStrip-7hBR2bdV.js → ComposerCreateImproveStrip-CNn4OywM.js} +1 -1
  55. package/dist/web/assets/{GetStartedView-l1Cz1e7g.js → GetStartedView-DRFpHDLd.js} +1 -1
  56. package/dist/web/assets/LabModelVersionDetailPage-BzF-IVXQ.js +1 -0
  57. package/dist/web/assets/{LabSkillSidebar-jlX5I_D5.js → LabSkillSidebar-B9jY4AgE.js} +1 -1
  58. package/dist/web/assets/{LabsRoute-D3w6nPSa.css → LabsRoute-CS_orT9s.css} +1 -1
  59. package/dist/web/assets/LabsRoute-Di1Zs4gZ.js +2 -0
  60. package/dist/web/assets/{MainChatThread-B1nXTMAf.js → MainChatThread-8VzlD8Hi.js} +2 -2
  61. package/dist/web/assets/{MainPane-DxVcMBFo.js → MainPane-StAOFINE.js} +3 -3
  62. package/dist/web/assets/{MarkdownText-B3njGyZS.js → MarkdownText-B8D_ftSJ.js} +1 -1
  63. package/dist/web/assets/{Messages-yBS4UHWl.js → Messages-TY62tiDp.js} +1 -1
  64. package/dist/web/assets/{NativeSkillSidebar-DaD52aW1.js → NativeSkillSidebar-DjebFRoi.js} +1 -1
  65. package/dist/web/assets/{NewExperienceSwitcher-C7X_K5Xl.js → NewExperienceSwitcher-C-bJxHxY.js} +1 -1
  66. package/dist/web/assets/{NewProjectDialog-NuPVF2Y7.js → NewProjectDialog-Cx8QcZm7.js} +1 -1
  67. package/dist/web/assets/{OutputsPage-Bmof4Tdv.js → OutputsPage-Y9HM-SHX.js} +1 -1
  68. package/dist/web/assets/{ProjectsPage-D7opg6ff.js → ProjectsPage-BBr58yKT.js} +1 -1
  69. package/dist/web/assets/{RightChatPanelStack-BzsNeSwx.js → RightChatPanelStack-DzUbDKwp.js} +1 -1
  70. package/dist/web/assets/{RightSidebarHomePanel-D8dAMHcp.js → RightSidebarHomePanel-Dx-1elSI.js} +1 -1
  71. package/dist/web/assets/{ScheduledWorkPage-Dkjhof6t.js → ScheduledWorkPage-BuXw_W8b.js} +1 -1
  72. package/dist/web/assets/SettingsView-DB_zPHYY.js +6 -0
  73. package/dist/web/assets/{TeamChatView-DIxvrgai.js → TeamChatView-Bkyhu40R.js} +1 -1
  74. package/dist/web/assets/{TerminalOverlay-Cd0Sp9LD.js → TerminalOverlay-CaCkZDzO.js} +1 -1
  75. package/dist/web/assets/{TrainingCreationPanel-DACYaOny.js → TrainingCreationPanel-Vvi41WNT.js} +1 -1
  76. package/dist/web/assets/{TrainingDraftPanel-DBWJW8ZD.js → TrainingDraftPanel-C2C3hffI.js} +1 -1
  77. package/dist/web/assets/{UsageSettingsSection-B3sbqaUV.js → UsageSettingsSection-DpPBd-ra.js} +1 -1
  78. package/dist/web/assets/{WorkSidebarPanel-D4yXQ64j.js → WorkSidebarPanel-CeWGboTh.js} +1 -1
  79. package/dist/web/assets/{WorkspaceDiffPanel-CBgPVF1P.js → WorkspaceDiffPanel-D_zKOW4K.js} +3 -3
  80. package/dist/web/assets/{WorkspaceEnvironmentMenu-Bp-9V7Jq.js → WorkspaceEnvironmentMenu-BTz9FISP.js} +3 -3
  81. package/dist/web/assets/{WorkspaceGitDialogs-BxU5Uhpz.js → WorkspaceGitDialogs-BnBRUYpS.js} +1 -1
  82. package/dist/web/assets/{WorkspaceMonacoEditor-Db_sWYFt.js → WorkspaceMonacoEditor--GOVrHFp.js} +3 -3
  83. package/dist/web/assets/{activity-BzKyRXbd.js → activity-DA5DNQwD.js} +1 -1
  84. package/dist/web/assets/{arrow-up-right-DaIxkG4K.js → arrow-up-right-BRZWXpqJ.js} +1 -1
  85. package/dist/web/assets/{chat-file-links-wORSEipQ.js → chat-file-links-CgFHK89C.js} +1 -1
  86. package/dist/web/assets/chevron-up-DSv2auz_.js +1 -0
  87. package/dist/web/assets/{clipboard-BTRsPPaK.js → clipboard-dPd_3lpG.js} +1 -1
  88. package/dist/web/assets/{cloud-upload-BYXHJoKd.js → cloud-upload-DOwvN4hp.js} +1 -1
  89. package/dist/web/assets/{cssMode-Be446Wgi.js → cssMode-BM4j9M0D.js} +1 -1
  90. package/dist/web/assets/{folder-open-KtKTXn4w.js → folder-open-DavjPCw4.js} +1 -1
  91. package/dist/web/assets/{folder-plus-9-Xcli22.js → folder-plus-Dyqast6G.js} +1 -1
  92. package/dist/web/assets/{git-branch-CLGxzDjJ.js → git-branch-zKnZdQiX.js} +1 -1
  93. package/dist/web/assets/{git-commit-horizontal-CmVYsUnh.js → git-commit-horizontal-s3X0cQlz.js} +1 -1
  94. package/dist/web/assets/{htmlMode-DTjTyBB_.js → htmlMode-Nlx7ckXa.js} +1 -1
  95. package/dist/web/assets/{index-DqWw2ymf.js → index-5-B6FIuE.js} +1 -1
  96. package/dist/web/assets/index-CQ3CPVHZ.css +1 -0
  97. package/dist/web/assets/index-CuoGlf-W.js +1 -0
  98. package/dist/web/assets/{info-BLmP4K0e.js → info-CVvrNOHr.js} +1 -1
  99. package/dist/web/assets/{jsonMode-Z-2iim-u.js → jsonMode-B7monA6g.js} +1 -1
  100. package/dist/web/assets/{lspLanguageFeatures-Cr2iCfG2.js → lspLanguageFeatures-CcJ9GDtK.js} +1 -1
  101. package/dist/web/assets/{minimize-2-CWA6iO3r.js → minimize-2-O1DnznGK.js} +1 -1
  102. package/dist/web/assets/{monaco.contribution-YhqlKmCp.js → monaco.contribution-2PozfA9g.js} +2 -2
  103. package/dist/web/assets/{monaco.contribution-BtMcDmCM.js → monaco.contribution-BMAF2bmO.js} +2 -2
  104. package/dist/web/assets/{monaco.contribution-Cac9eBUk.js → monaco.contribution-BSJ2jQTi.js} +2 -2
  105. package/dist/web/assets/{monaco.contribution-NtjNqMdv.js → monaco.contribution-QOOCizYq.js} +2 -2
  106. package/dist/web/assets/{play-DYSQH2rx.js → play-BpCc5ZbR.js} +1 -1
  107. package/dist/web/assets/{python-CNqOWXNv.js → python-BK41iew-.js} +1 -1
  108. package/dist/web/assets/{refresh-cw-DMysDKOA.js → refresh-cw-Csoy1ev1.js} +1 -1
  109. package/dist/web/assets/{save-HPZ4ZiDi.js → save-Dbztj0W7.js} +1 -1
  110. package/dist/web/assets/{square-D-mpY1a-.js → square-ju7fWa0W.js} +1 -1
  111. package/dist/web/assets/{toggleHighContrast-Bccdn3Qi.js → toggleHighContrast-DrmwDpyz.js} +1 -1
  112. package/dist/web/assets/{tsMode-BhcKJxhG.js → tsMode-CFgCMr7d.js} +1 -1
  113. package/dist/web/assets/{upload-DE7xaWVj.js → upload-C5nhiSMq.js} +1 -1
  114. package/dist/web/assets/{useLocalAgentSchedules-C0J--_MD.js → useLocalAgentSchedules-LAsobERb.js} +1 -1
  115. package/dist/web/assets/{wifi-off-CrCfhll9.js → wifi-off-BHxh2UbA.js} +1 -1
  116. package/dist/web/assets/{workers-DCaGzukk.js → workers-FKb-NyBI.js} +1 -1
  117. package/dist/web/assets/{yaml-CCfH63KB.js → yaml-C5DbF9S6.js} +1 -1
  118. package/dist/web/index.html +2 -2
  119. package/package.json +1 -1
  120. package/dist/api/vercel-protection.d.ts +0 -1
  121. package/dist/chunks/chunk-MLWNI3WG.js +0 -15395
  122. package/dist/web/assets/App-D7vhbyMO.js +0 -171
  123. package/dist/web/assets/LabModelVersionDetailPage-D2PfI3-r.js +0 -1
  124. package/dist/web/assets/LabsRoute-VOgPrf94.js +0 -2
  125. package/dist/web/assets/SettingsView-CWTAUy2b.js +0 -6
  126. package/dist/web/assets/chevron-up-C8-qSzck.js +0 -1
  127. package/dist/web/assets/index-AzqEDIEY.css +0 -1
  128. package/dist/web/assets/index-C5uP_Gug.js +0 -1
@@ -153,7 +153,7 @@ import {
153
153
  workspaceHasHead,
154
154
  workspaceToolExperienceBlocker,
155
155
  writeWorkspaceFile
156
- } from "./chunk-IG72OKNB.js";
156
+ } from "./chunk-OOM2PHBE.js";
157
157
  import {
158
158
  appWorkspacePaths,
159
159
  checkWorkspaceGitAvailability,
@@ -179,14 +179,14 @@ import {
179
179
  runCommand,
180
180
  startMacOSCommandLineToolsInstall,
181
181
  workspaceImageContentType
182
- } from "./chunk-WEB37YVJ.js";
182
+ } from "./chunk-7C4OIFOC.js";
183
183
  import {
184
184
  runOpenPondServerCli
185
- } from "./chunk-PSGEH4FC.js";
185
+ } from "./chunk-QTN6HXOR.js";
186
186
  import {
187
187
  createAppServer,
188
188
  runAgentCompaction
189
- } from "./chunk-OOJP442J.js";
189
+ } from "./chunk-5TKZBMQM.js";
190
190
  import {
191
191
  APP_PREFERENCES_CACHE_KEY,
192
192
  APP_PREFERENCES_CACHE_TYPE,
@@ -198,7 +198,7 @@ import {
198
198
  isCliEntrypoint,
199
199
  now,
200
200
  textFromUnknown
201
- } from "./chunk-HFQHD35D.js";
201
+ } from "./chunk-NPNIL6SQ.js";
202
202
  import {
203
203
  createOpenPondRepoApp,
204
204
  getBundledRuntimeVersion,
@@ -212,7 +212,7 @@ import {
212
212
  streamOpenPondHostedChatTurn,
213
213
  switchOpenPondAccount,
214
214
  updateOpenPondAccountConfig
215
- } from "./chunk-TSDVA7QP.js";
215
+ } from "./chunk-FEOLMLYU.js";
216
216
  import {
217
217
  AccountStateSchema,
218
218
  AdapterValidationReceiptSchema,
@@ -279,7 +279,6 @@ import {
279
279
  ModelBindingSchema,
280
280
  ModelEvaluationReceiptSchema,
281
281
  ModelProjectSchema,
282
- ModelRunDraftSchema,
283
282
  ModelRunSchema,
284
283
  ModelUsageRecordSchema,
285
284
  ModelVersionSchema,
@@ -374,6 +373,7 @@ import {
374
373
  TrainingExecutionStatusSchema,
375
374
  TrainingJobEventSchema,
376
375
  TrainingJobSchema,
376
+ TrainingJobSourceSnapshotSchema,
377
377
  TrainingPlanSchema,
378
378
  TrainingPreparedStartSchema,
379
379
  TrainingRecipeSchema,
@@ -453,8 +453,8 @@ import {
453
453
  workFormatCapabilityForContentType,
454
454
  workspacePathFromLocalPathWorkspaceId,
455
455
  writeSourceUploadCache
456
- } from "./chunk-OQLYO7TA.js";
457
- import "./chunk-QETF6ILG.js";
456
+ } from "./chunk-MMRJNSWY.js";
457
+ import "./chunk-DLQQIWN2.js";
458
458
  import {
459
459
  ArtifactManifestSchema,
460
460
  AttemptReceiptContentSchema,
@@ -462,15 +462,18 @@ import {
462
462
  BenchmarkDefinitionSchema,
463
463
  CONNECTED_APP_INTEGRATION_SKILLS,
464
464
  ComparisonAssignmentSchema,
465
+ DEFAULT_REFINER_MAX_OUTPUT_TOKENS,
465
466
  EvidenceArtifactRefSchema,
466
- MetricObservationSchema,
467
+ ImmutableAssetRefSchema,
468
+ ImmutableReleaseRefSchema,
467
469
  OPENPOND_MANIFEST_FILE_NAME,
470
+ OPENPOND_MODEL_PROJECT_MEDIA_TYPE,
471
+ OpenPondTrainingApiError,
468
472
  PreferenceComparisonReleaseSchema,
469
473
  PreferenceDatasetReleaseSchema,
470
474
  RewardModelQualificationReportSchema,
471
475
  RewardReceiptSchema,
472
476
  RunManifestSchema,
473
- RunTelemetryEventSchema,
474
477
  SANDBOX_TEMPLATE_BUILD_PLAN_FILE_NAME,
475
478
  SANDBOX_TEMPLATE_PREVIEW_PORT_MAX,
476
479
  SANDBOX_TEMPLATE_PREVIEW_PORT_MIN,
@@ -479,18 +482,22 @@ import {
479
482
  WorkFeedbackReasonCodeSchema,
480
483
  WorkFeedbackVerdictSchema,
481
484
  aggregateEvaluationReceipts,
485
+ canonicalJson,
482
486
  classifyWorkEvidence,
483
487
  compareBenchmarkRuns,
488
+ contentHash,
484
489
  createAttemptReceipt,
485
490
  createBenchmarkDefinition,
486
491
  createBenchmarkRunSummary,
487
492
  createComparisonAssignment,
493
+ createModelProjectsClient,
488
494
  createPreferenceCalibrationReport,
489
495
  createPreferenceComparisonRelease,
490
496
  createPreferenceReceipt,
491
497
  createPreferenceRewardComponents,
492
498
  createRewardModelQualificationReport,
493
499
  createSyntheticFixturePreferenceReceipt,
500
+ createTrainingClient,
494
501
  createWorkEvidenceReceipt,
495
502
  createWorkFeedbackReceipt,
496
503
  createWorkProcessTrace,
@@ -499,9 +506,14 @@ import {
499
506
  harnessRefinerBenchmarkAssets,
500
507
  harnessRefinerBenchmarkRelease,
501
508
  materializePreferenceDatasetRelease,
509
+ parseAndVerifyTrainingExecutionReceipt,
502
510
  sandboxTemplateBuildPlan,
503
511
  sandboxTemplateExecutableEntries,
504
512
  sandboxTemplateScaffoldFiles,
513
+ sha256,
514
+ trainingExecutionReceiptHash,
515
+ trainingInputArtifactUploadHash,
516
+ trainingJobSubmissionHash,
505
517
  validateComparisonAssignment,
506
518
  validateSandboxTemplateYaml,
507
519
  verifyArtifactManifest,
@@ -512,22 +524,14 @@ import {
512
524
  workEvidenceReceiptRef,
513
525
  workSourceOpaqueRef,
514
526
  workWorkspaceOpaqueRef
515
- } from "./chunk-MUS7KPXK.js";
527
+ } from "./chunk-BLFIIAWZ.js";
516
528
  import {
517
529
  yaml
518
530
  } from "./chunk-X7ZG4TSW.js";
531
+ import "./chunk-JTHL5XJ2.js";
519
532
  import {
520
- withVercelProtectionBypass
521
- } from "./chunk-JGOP4GCK.js";
522
- import {
523
- DEFAULT_REFINER_MAX_OUTPUT_TOKENS,
524
- ImmutableAssetRefSchema,
525
- ImmutableReleaseRefSchema,
526
- canonicalJson,
527
- contentHash,
528
- external_exports,
529
- sha256
530
- } from "./chunk-MLWNI3WG.js";
533
+ external_exports
534
+ } from "./chunk-FQS2QL5F.js";
531
535
  import {
532
536
  __commonJS,
533
537
  __require,
@@ -13381,7 +13385,7 @@ var require_dist = __commonJS({
13381
13385
 
13382
13386
  // ../server/src/index.ts
13383
13387
  import path64 from "node:path";
13384
- import { randomUUID as randomUUID24 } from "node:crypto";
13388
+ import { randomUUID as randomUUID25 } from "node:crypto";
13385
13389
  import { promises as fs26 } from "node:fs";
13386
13390
 
13387
13391
  // ../../packages/codex-provider/dist/client.js
@@ -28223,7 +28227,6 @@ async function handleTrainingRoutes({ deps, request, requestUrl, response }) {
28223
28227
  { method: "POST", path: "/v1/training/taskset-drafts", action: "init_taskset_draft", status: 201 },
28224
28228
  { method: "POST", path: "/v1/training/models/from-taskset", action: "create_model_from_taskset", status: 201 },
28225
28229
  { method: "PUT", path: "/v1/training/models", action: "save_model_project" },
28226
- { method: "PUT", path: "/v1/training/model-run-drafts", action: "save_model_run_draft" },
28227
28230
  { method: "POST", path: "/v1/training/miner/run", action: "run_miner", status: 202 },
28228
28231
  { method: "PUT", path: "/v1/training/miner/config", action: "configure_miner" },
28229
28232
  { method: "POST", path: "/v1/training/grade", action: "grade" },
@@ -28245,8 +28248,8 @@ async function handleTrainingRoutes({ deps, request, requestUrl, response }) {
28245
28248
  return true;
28246
28249
  }
28247
28250
  const dynamic = [
28248
- { pattern: /^\/v1\/training\/model-runs\/([^/]+)\/prepare$/, method: "POST", action: "prepare_model_run", key: "modelRunId" },
28249
- { pattern: /^\/v1\/training\/model-runs\/([^/]+)\/start$/, method: "POST", action: "start_model_run", key: "modelRunId" },
28251
+ { pattern: /^\/v1\/training\/model-projects\/([^/]+)\/training\/prepare$/, method: "POST", action: "prepare_model_run", key: "modelProjectId" },
28252
+ { pattern: /^\/v1\/training\/model-projects\/([^/]+)\/training\/start$/, method: "POST", action: "start_model_run", key: "modelProjectId" },
28250
28253
  { pattern: /^\/v1\/training\/model-runs\/([^/]+)\/status$/, method: "GET", action: "model_run_status", key: "modelRunId" },
28251
28254
  { pattern: /^\/v1\/training\/model-runs\/([^/]+)\/events$/, method: "GET", action: "model_run_events", key: "modelRunId" },
28252
28255
  { pattern: /^\/v1\/training\/model-runs\/([^/]+)\/logs$/, method: "GET", action: "model_run_logs", key: "modelRunId" },
@@ -28285,7 +28288,6 @@ async function handleTrainingRoutes({ deps, request, requestUrl, response }) {
28285
28288
  { pattern: /^\/v1\/training\/models\/([^/]+)\/harness-refiner-benchmark$/, method: "POST", action: "start_harness_refiner_benchmark", key: "modelId" },
28286
28289
  { pattern: /^\/v1\/training\/models\/([^/]+)\/sync$/, method: "POST", action: "sync_model_project", key: "modelId" },
28287
28290
  { pattern: /^\/v1\/training\/models\/([^/]+)\/tasksets\/([^/]+)\/publish$/, method: "POST", action: "publish_model_project_taskset", key: "modelId", assignmentKey: "tasksetId" },
28288
- { pattern: /^\/v1\/training\/model-run-drafts\/([^/]+)$/, method: "DELETE", action: "delete_model_run_draft", key: "draftId" },
28289
28291
  { pattern: /^\/v1\/training\/dataset-imports\/([^/]+)\/materialize$/, method: "POST", action: "materialize_dataset_import", key: "importId" },
28290
28292
  { pattern: /^\/v1\/training\/dataset-imports\/([^/]+)\/cancel$/, method: "POST", action: "cancel_dataset_import", key: "importId" },
28291
28293
  { pattern: /^\/v1\/training\/sources\/([^/]+)$/, method: "DELETE", action: "remove_source", key: "sourceId" },
@@ -39707,7 +39709,8 @@ import { randomUUID as randomUUID16 } from "node:crypto";
39707
39709
  import { access, lstat, mkdir as mkdir5, readFile as readFile7, readdir as readdir2, rename, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
39708
39710
  import path40 from "node:path";
39709
39711
  function buildTasksetTrainingBundle(input) {
39710
- const { taskset, modelRun, harnessRelease, tasksetRelease } = input;
39712
+ const { taskset, modelProject, harnessRelease, tasksetRelease } = input;
39713
+ const setup = modelProject.trainingSetup;
39711
39714
  const releasedHarness2 = ImmutableReleaseRefSchema2.parse(harnessRelease);
39712
39715
  const releasedTaskset = ImmutableReleaseRefSchema2.parse(tasksetRelease);
39713
39716
  void input.openpondRelease;
@@ -39716,7 +39719,7 @@ function buildTasksetTrainingBundle(input) {
39716
39719
  if (actualTasksetHash !== taskset.contentHash) {
39717
39720
  throw new Error("Taskset authoring state changed after its release was selected.");
39718
39721
  }
39719
- if (!modelRun.baseModel?.revision || !modelRun.baseModel.tokenizerRevision || !modelRun.baseModel.chatTemplateHash || !modelRun.recipe || !modelRun.tasksetRef || modelRun.tasksetRef.id !== taskset.id || modelRun.tasksetRef.contentHash !== taskset.contentHash) {
39722
+ if (!setup.baseModel?.revision || !setup.baseModel.tokenizerRevision || !setup.baseModel.chatTemplateHash || !setup.recipe || !setup.tasksetRef || setup.tasksetRef.id !== taskset.id || setup.tasksetRef.contentHash !== taskset.contentHash) {
39720
39723
  throw new Error("Model Run must bind an exact Taskset, Model revision, tokenizer, chat template, and Recipe.");
39721
39724
  }
39722
39725
  const profileRelease = taskset.profileRelease ?? {
@@ -39802,21 +39805,21 @@ function buildTasksetTrainingBundle(input) {
39802
39805
  });
39803
39806
  const manifestContent = HarnessRunManifestContentSchema.parse({
39804
39807
  schemaVersion: "openpond.harnessRunManifest.v1",
39805
- id: `manifest_${modelRun.id}_${input.approval.approvalHash.slice(0, 16)}`,
39808
+ id: `manifest_${input.modelRunId}_${input.approval.approvalHash.slice(0, 16)}`,
39806
39809
  harnessRelease,
39807
39810
  datasetRelease,
39808
39811
  evidenceSets: evidenceSetRelease ? [evidenceSetRelease] : [],
39809
39812
  model: {
39810
- source: modelRun.baseModel.modelId,
39811
- revision: modelRun.baseModel.revision,
39813
+ source: setup.baseModel.modelId,
39814
+ revision: setup.baseModel.revision,
39812
39815
  artifactHash: null,
39813
- tokenizerRevision: modelRun.baseModel.tokenizerRevision,
39814
- chatTemplateHash: modelRun.baseModel.chatTemplateHash
39816
+ tokenizerRevision: setup.baseModel.tokenizerRevision,
39817
+ chatTemplateHash: setup.baseModel.chatTemplateHash
39815
39818
  },
39816
39819
  recipe: {
39817
- method: modelRun.recipe.method,
39820
+ method: setup.recipe.method,
39818
39821
  version: "openpond.trainingRecipe.v1",
39819
- configHash: contentHash(modelRun.recipe)
39822
+ configHash: contentHash(setup.recipe)
39820
39823
  },
39821
39824
  runtimeTarget: input.runtime,
39822
39825
  computeTarget: input.compute,
@@ -39824,7 +39827,7 @@ function buildTasksetTrainingBundle(input) {
39824
39827
  resolvedBundleHash: resolvedBundleManifest.contentHash,
39825
39828
  secretLeaseRefs: input.secretLeaseRefs ?? [],
39826
39829
  approval: input.approval,
39827
- createdAt: modelRun.updatedAt
39830
+ createdAt: modelProject.updatedAt
39828
39831
  });
39829
39832
  const manifest = HarnessRunManifestSchema.parse({
39830
39833
  ...manifestContent,
@@ -41411,7 +41414,7 @@ var ManagedRlLocalRolloutExecutor = class {
41411
41414
  const requestUrl = `${this.input.access.apiBaseUrl}${path65}`;
41412
41415
  return requestJson(this.input.fetchImpl ?? fetch, requestUrl, {
41413
41416
  ...init,
41414
- headers: withVercelProtectionBypass(requestUrl, headers, this.input.env),
41417
+ headers,
41415
41418
  signal: this.abortController.signal
41416
41419
  });
41417
41420
  }
@@ -41427,7 +41430,7 @@ var ManagedRlLocalRolloutExecutor = class {
41427
41430
  requestUrl,
41428
41431
  {
41429
41432
  method: "POST",
41430
- headers: withVercelProtectionBypass(requestUrl, headers, this.input.env),
41433
+ headers,
41431
41434
  body: JSON.stringify(request),
41432
41435
  signal
41433
41436
  }
@@ -41468,547 +41471,117 @@ function delay(milliseconds) {
41468
41471
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
41469
41472
  }
41470
41473
 
41471
- // ../server/src/training/openpond-managed-run-evidence.ts
41472
- var OptionalTimestampSchema = external_exports.string().trim().min(1).nullable().optional();
41473
- var OptionalMoneySchema = external_exports.string().trim().min(1).nullable().optional();
41474
- var ManagedJobDetailSchema = external_exports.object({
41475
- job: external_exports.object({
41476
- id: external_exports.string().trim().min(1),
41477
- state: external_exports.string().trim().min(1),
41478
- targetGroups: external_exports.number().int().nonnegative().default(0),
41479
- completedGroups: external_exports.number().int().nonnegative().default(0),
41480
- currentPolicyVersion: external_exports.number().int().nonnegative().default(0),
41481
- accruedSpendUsd: OptionalMoneySchema,
41482
- canonicalPublishState: external_exports.string().trim().min(1).nullable().optional(),
41483
- canonicalAdapterArtifactId: external_exports.string().trim().min(1).nullable().optional(),
41484
- version: external_exports.number().int().positive().default(1),
41485
- terminalReason: external_exports.string().trim().min(1).nullable().optional(),
41486
- createdAt: external_exports.string().trim().min(1),
41487
- updatedAt: external_exports.string().trim().min(1),
41488
- completedAt: OptionalTimestampSchema,
41489
- inputBundle: external_exports.object({
41490
- harnessRelease: external_exports.object({ contentHash: external_exports.string().trim().min(1) }).optional(),
41491
- harnessRunManifest: external_exports.object({
41492
- harnessRelease: external_exports.object({ contentHash: external_exports.string().trim().min(1) }).optional(),
41493
- runtimeTarget: external_exports.object({
41494
- placement: external_exports.string().trim().min(1).optional()
41495
- }).optional()
41496
- }).optional()
41497
- }).optional()
41498
- }),
41499
- gpuLeases: external_exports.array(
41500
- external_exports.object({
41501
- id: external_exports.string().trim().min(1),
41502
- provider: external_exports.string().trim().min(1).default("openpond"),
41503
- state: external_exports.string().trim().min(1),
41504
- gpuType: external_exports.string().trim().min(1).nullable().optional(),
41505
- gpuCount: external_exports.number().int().nonnegative().nullable().optional(),
41506
- quotedHourlyUsd: OptionalMoneySchema,
41507
- observedHourlyUsd: OptionalMoneySchema,
41508
- readyAt: OptionalTimestampSchema,
41509
- terminatedAt: OptionalTimestampSchema
41510
- })
41511
- ).default([]),
41512
- rolloutGroups: external_exports.array(
41513
- external_exports.object({
41514
- id: external_exports.string().trim().min(1),
41515
- groupIndex: external_exports.number().int().nonnegative(),
41516
- policyVersion: external_exports.number().int().nonnegative(),
41517
- state: external_exports.string().trim().min(1),
41518
- eligibleTrajectoryCount: external_exports.number().int().nonnegative().default(0),
41519
- rewardMean: OptionalMoneySchema,
41520
- startedAt: OptionalTimestampSchema,
41521
- completedAt: OptionalTimestampSchema
41522
- })
41523
- ).default([]),
41524
- rollouts: external_exports.array(
41525
- external_exports.object({
41526
- id: external_exports.string().trim().min(1),
41527
- groupId: external_exports.string().trim().min(1),
41528
- workerSlot: external_exports.number().int().nonnegative(),
41529
- attempt: external_exports.number().int().positive().default(1),
41530
- state: external_exports.string().trim().min(1),
41531
- startedAt: OptionalTimestampSchema,
41532
- completedAt: OptionalTimestampSchema
41533
- })
41534
- ).default([]),
41535
- trajectories: external_exports.array(
41536
- external_exports.object({
41537
- id: external_exports.string().trim().min(1),
41538
- groupId: external_exports.string().trim().min(1),
41539
- rolloutId: external_exports.string().trim().min(1),
41540
- policyVersion: external_exports.number().int().nonnegative(),
41541
- rewardEligible: external_exports.boolean(),
41542
- reward: OptionalMoneySchema,
41543
- terminalClass: external_exports.string().trim().min(1).nullable().optional(),
41544
- rewardComponents: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
41545
- promptTokenCount: external_exports.number().int().nonnegative().nullable().optional(),
41546
- outputTokenCount: external_exports.number().int().nonnegative().nullable().optional(),
41547
- consumedTrainingStepId: external_exports.string().trim().min(1).nullable().optional(),
41548
- createdAt: external_exports.string().trim().min(1),
41549
- updatedAt: external_exports.string().trim().min(1)
41550
- })
41551
- ).default([]),
41552
- trainingSteps: external_exports.array(
41553
- external_exports.object({
41554
- id: external_exports.string().trim().min(1),
41555
- groupId: external_exports.string().trim().min(1),
41556
- stepIndex: external_exports.number().int().positive(),
41557
- inputPolicyVersion: external_exports.number().int().nonnegative(),
41558
- outputPolicyVersion: external_exports.number().int().nonnegative(),
41559
- state: external_exports.string().trim().min(1),
41560
- metrics: external_exports.record(
41561
- external_exports.string(),
41562
- external_exports.union([external_exports.number(), external_exports.string(), external_exports.boolean(), external_exports.null()])
41563
- ).default({}),
41564
- startedAt: OptionalTimestampSchema,
41565
- committedAt: OptionalTimestampSchema
41566
- })
41567
- ).default([]),
41568
- checkpoints: external_exports.array(
41569
- external_exports.object({
41570
- id: external_exports.string().trim().min(1),
41571
- policyVersion: external_exports.number().int().nonnegative(),
41572
- state: external_exports.string().trim().min(1),
41573
- adapterSha256: external_exports.string().trim().min(8).nullable().optional(),
41574
- sizeBytes: external_exports.number().int().nonnegative().nullable().optional(),
41575
- isLatest: external_exports.boolean().default(false),
41576
- isFinal: external_exports.boolean().default(false),
41577
- readyAt: OptionalTimestampSchema,
41578
- updatedAt: external_exports.string().trim().min(1)
41579
- })
41580
- ).default([]),
41581
- evaluations: external_exports.array(
41582
- external_exports.object({
41583
- id: external_exports.string().trim().min(1),
41584
- kind: external_exports.enum(["baseline", "candidate"]),
41585
- policyVersion: external_exports.number().int().nonnegative(),
41586
- state: external_exports.string().trim().min(1),
41587
- score: OptionalMoneySchema,
41588
- threshold: OptionalMoneySchema,
41589
- passed: external_exports.boolean().nullable().optional(),
41590
- createdAt: external_exports.string().trim().min(1)
41591
- })
41592
- ).default([]),
41593
- telemetry: external_exports.array(
41594
- external_exports.object({
41595
- id: external_exports.string().trim().min(1),
41596
- itemId: external_exports.string().trim().min(1),
41597
- sequence: external_exports.number().int().nonnegative(),
41598
- kind: external_exports.enum(["event", "observation"]),
41599
- event: RunTelemetryEventSchema.nullable().optional(),
41600
- observation: MetricObservationSchema.nullable().optional()
41601
- })
41602
- ).default([]),
41603
- commands: external_exports.array(
41604
- external_exports.object({
41605
- id: external_exports.string().trim().min(1),
41606
- commandType: external_exports.string().trim().min(1),
41607
- state: external_exports.string().trim().min(1),
41608
- errorCode: external_exports.string().trim().min(1).nullable().optional(),
41609
- createdAt: external_exports.string().trim().min(1),
41610
- updatedAt: external_exports.string().trim().min(1),
41611
- completedAt: OptionalTimestampSchema
41612
- })
41613
- ).default([]),
41614
- outbox: external_exports.array(
41615
- external_exports.object({
41616
- id: external_exports.string().trim().min(1),
41617
- commandType: external_exports.string().trim().min(1),
41618
- state: external_exports.string().trim().min(1),
41619
- attemptCount: external_exports.number().int().nonnegative().default(0),
41620
- lastErrorCode: external_exports.string().trim().min(1).nullable().optional(),
41621
- createdAt: external_exports.string().trim().min(1),
41622
- updatedAt: external_exports.string().trim().min(1),
41623
- completedAt: OptionalTimestampSchema
41624
- })
41625
- ).default([])
41626
- });
41627
- function parseManagedJobDetail(value) {
41628
- return ManagedJobDetailSchema.parse(value);
41629
- }
41630
- async function persistManagedRunEvidence(input) {
41631
- const job = await input.store.getTrainingJob(input.ref.runId);
41632
- if (!job) return null;
41633
- const plan = await input.store.getTrainingPlan(job.planId);
41634
- const learningRate = plan?.recipe.method === "grpo" ? plan.recipe.optimizer.learningRate : null;
41635
- const evidence = managedRunEvidence(input.detail, input.now?.() ?? /* @__PURE__ */ new Date());
41636
- const existingEvents = await input.store.listTrainingJobEvents(job.id);
41637
- const events = managedTrainingEvents({
41638
- detail: input.detail,
41639
- jobId: job.id,
41640
- learningRate,
41641
- existingEvents
41642
- });
41643
- for (const event2 of events) {
41644
- await input.store.saveTrainingJobEvent(event2);
41645
- }
41646
- await input.store.saveTrainingJob({
41647
- ...job,
41648
- metadata: {
41649
- ...job.metadata,
41650
- managedTrainingEvidence: evidence,
41651
- optimizerUpdatesObserved: evidence.progress.committedOptimizerSteps,
41652
- trainingMethod: plan?.recipe.method === "grpo" ? "grpo" : job.metadata.trainingMethod
41653
- }
41654
- });
41655
- return evidence;
41656
- }
41657
- function managedRunEvidence(detail, syncedAt) {
41658
- const eligible = detail.trajectories.filter(
41659
- (trajectory) => trajectory.rewardEligible
41660
- );
41661
- const committedSteps = detail.trainingSteps.filter(
41662
- (step) => step.state === "committed"
41474
+ // ../server/src/training/openpond-managed-training-adapter-projection.ts
41475
+ async function managedQualification(input) {
41476
+ if (!input.qualificationRef) return null;
41477
+ const lineage = input.taskset.metadata.harnessEvaluationLineage;
41478
+ if (!lineage || typeof lineage !== "object" || Array.isArray(lineage)) return null;
41479
+ const review = lineage.review;
41480
+ if (!review || typeof review !== "object" || Array.isArray(review)) return null;
41481
+ const workspaceId = review.workspaceId;
41482
+ if (typeof workspaceId !== "string" || !workspaceId) return null;
41483
+ const receipts = await input.store.listHarnessImprovementArtifacts(
41484
+ workspaceId,
41485
+ "training_qualification",
41486
+ 1e3
41663
41487
  );
41664
- const finalGroup = [...detail.rolloutGroups].filter((group) => group.rewardMean != null).sort((left, right) => left.groupIndex - right.groupIndex).at(-1);
41665
- const lease = [...detail.gpuLeases].sort((left, right) => left.id.localeCompare(right.id)).at(-1);
41666
- const checkpoint2 = [...detail.checkpoints].filter((candidate2) => candidate2.state === "ready").sort(
41667
- (left, right) => Number(right.isFinal) - Number(left.isFinal) || Number(right.isLatest) - Number(left.isLatest) || right.policyVersion - left.policyVersion
41668
- ).at(0);
41669
- return ManagedTrainingRunEvidenceSchema.parse({
41670
- schemaVersion: "openpond.managedTrainingRunEvidence.v1",
41671
- provider: "openpond",
41672
- providerRunId: detail.job.id,
41673
- state: detail.job.state,
41674
- progress: {
41675
- targetOptimizerSteps: detail.job.targetGroups,
41676
- committedOptimizerSteps: committedSteps.length
41677
- },
41678
- reward: {
41679
- finalMean: decimal(finalGroup?.rewardMean),
41680
- trajectoryCount: detail.trajectories.length,
41681
- eligibleTrajectoryCount: eligible.length
41682
- },
41683
- usage: {
41684
- inputTokens: sumNullableIntegers(
41685
- eligible.map((trajectory) => trajectory.promptTokenCount)
41686
- ),
41687
- outputTokens: sumNullableIntegers(
41688
- eligible.map((trajectory) => trajectory.outputTokenCount)
41689
- ),
41690
- environmentExecutions: detail.rollouts.length
41691
- },
41692
- resource: {
41693
- provider: "openpond",
41694
- gpuType: lease?.gpuType ?? null,
41695
- gpuCount: lease?.gpuCount ?? null,
41696
- hourlyCostUsd: decimal(
41697
- lease?.observedHourlyUsd ?? lease?.quotedHourlyUsd
41698
- )
41699
- },
41700
- cost: {
41701
- totalUsd: decimal(detail.job.accruedSpendUsd)
41702
- },
41703
- checkpoint: checkpoint2 ? {
41704
- id: checkpoint2.id,
41705
- policyVersion: checkpoint2.policyVersion,
41706
- sha256: checkpoint2.adapterSha256 ?? null,
41707
- sizeBytes: checkpoint2.sizeBytes ?? null
41708
- } : null,
41709
- evaluations: detail.evaluations.map((evaluation) => ({
41710
- kind: evaluation.kind,
41711
- policyVersion: evaluation.policyVersion,
41712
- score: decimal(evaluation.score),
41713
- threshold: decimal(evaluation.threshold),
41714
- passed: evaluation.passed ?? null
41715
- })),
41716
- canonicalPublication: {
41717
- state: detail.job.canonicalPublishState ?? null,
41718
- artifactId: detail.job.canonicalAdapterArtifactId ?? null
41488
+ return receipts.find(
41489
+ (receipt) => receipt.id === input.qualificationRef.id && receipt.contentHash === input.qualificationRef.contentHash
41490
+ ) ?? null;
41491
+ }
41492
+ function dateString(value) {
41493
+ return new Date(value).toISOString();
41494
+ }
41495
+ function toExecutionStatus(job) {
41496
+ const preparing = /* @__PURE__ */ new Set(["queued", "admitting", "provisioning"]);
41497
+ const state = job.state === "succeeded" ? "succeeded" : job.state === "cancelled" ? "cancelled" : job.state === "failed" ? "failed" : job.state === "cancelling" ? "cancelling" : preparing.has(job.state) ? "preparing" : "running";
41498
+ return {
41499
+ runId: job.id,
41500
+ state,
41501
+ phase: job.state,
41502
+ progress: job.progress,
41503
+ updatedAt: dateString(job.updatedAt),
41504
+ errorCode: state === "failed" ? (job.terminalReason?.trim() || "managed_training_failed").replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 191) : null
41505
+ };
41506
+ }
41507
+ function learnedRewardSource(binding) {
41508
+ return {
41509
+ kind: "learned_reward",
41510
+ rewardModelVersion: binding.rewardModelVersion,
41511
+ qualificationReport: binding.qualificationReport,
41512
+ scorerArtifact: {
41513
+ artifactRef: binding.checkpoint.objectRef,
41514
+ contentHash: binding.checkpoint.contentHash,
41515
+ executionReceipt: binding.executionReceipt
41719
41516
  },
41720
- syncedAt: syncedAt.toISOString()
41721
- });
41517
+ processorRelease: binding.processorRelease,
41518
+ rewardComposerRelease: binding.rewardComposerRelease
41519
+ };
41722
41520
  }
41723
- function managedTrainingEvents(input) {
41724
- const candidates = [];
41725
- const startedAt = input.detail.gpuLeases.flatMap((lease) => lease.readyAt ? [lease.readyAt] : []).sort().at(0) ?? input.detail.job.createdAt;
41726
- candidates.push({
41727
- identity: "start",
41728
- timestamp: startedAt,
41729
- type: "start",
41730
- payload: {
41731
- device: input.detail.gpuLeases.find((lease) => lease.gpuType)?.gpuType ?? "OpenPond Managed",
41732
- provider: input.detail.gpuLeases.find((lease) => lease.provider)?.provider ?? "openpond"
41733
- }
41734
- });
41735
- for (const lease of input.detail.gpuLeases) {
41736
- candidates.push({
41737
- identity: `gpu-lease:${lease.id}`,
41738
- timestamp: lease.terminatedAt ?? lease.readyAt ?? input.detail.job.updatedAt,
41739
- type: lease.state === "failed" ? "failure" : "progress",
41740
- payload: {
41741
- telemetryType: "gpu_worker_state",
41742
- telemetrySource: "control_plane",
41743
- message: `${providerLabel(lease.provider)} GPU worker ${humanLabel(lease.state)}`,
41744
- provider: lease.provider,
41745
- state: lease.state,
41746
- gpuType: lease.gpuType ?? null
41747
- }
41748
- });
41749
- }
41750
- const rolloutById = new Map(
41751
- input.detail.rollouts.map((rollout) => [rollout.id, rollout])
41752
- );
41753
- const orderedTrajectories = [...input.detail.trajectories].sort(
41754
- (left, right) => left.createdAt.localeCompare(right.createdAt) || left.rolloutId.localeCompare(right.rolloutId)
41755
- );
41756
- orderedTrajectories.forEach((trajectory, index) => {
41757
- const rollout = rolloutById.get(trajectory.rolloutId);
41758
- candidates.push({
41759
- identity: `rollout:${trajectory.id}`,
41760
- timestamp: rollout?.completedAt ?? trajectory.updatedAt,
41761
- type: "metric",
41762
- payload: {
41763
- metricKind: "rollout_trajectory",
41764
- rolloutIndex: index + 1,
41765
- rolloutId: trajectory.rolloutId,
41766
- rolloutGroupId: trajectory.groupId,
41767
- policyVersion: trajectory.policyVersion,
41768
- workerSlot: rollout?.workerSlot ?? null,
41769
- reward: decimal(trajectory.reward),
41770
- rewardEligible: trajectory.rewardEligible,
41771
- rewardComponents: trajectory.rewardComponents,
41772
- failureClass: trajectory.rewardEligible ? null : trajectory.terminalClass ?? "not_reward_eligible",
41773
- failureCode: trajectory.rewardEligible ? null : failureCode(trajectory.rewardComponents),
41774
- inputTokens: trajectory.promptTokenCount ?? 0,
41775
- outputTokens: trajectory.outputTokenCount ?? 0
41776
- }
41777
- });
41778
- });
41779
- for (const group of input.detail.rolloutGroups) {
41780
- candidates.push({
41781
- identity: `group:${group.id}`,
41782
- timestamp: group.completedAt ?? group.startedAt ?? input.detail.job.updatedAt,
41783
- type: group.state === "failed" ? "failure" : "progress",
41784
- payload: {
41785
- telemetryType: "rollout_group_state",
41786
- telemetrySource: "control_plane",
41787
- message: `Rollout group ${group.groupIndex + 1} ${humanLabel(group.state)}`,
41788
- groupIndex: group.groupIndex,
41789
- policyVersion: group.policyVersion,
41790
- eligibleAttempts: group.eligibleTrajectoryCount,
41791
- rewardMean: decimal(group.rewardMean)
41792
- }
41793
- });
41794
- }
41795
- for (const command of input.detail.outbox) {
41796
- candidates.push({
41797
- identity: `control-command:${command.id}`,
41798
- timestamp: command.updatedAt,
41799
- type: command.lastErrorCode ? "failure" : "progress",
41800
- payload: {
41801
- telemetryType: "control_plane_command",
41802
- telemetrySource: "control_plane",
41803
- message: `${humanLabel(command.commandType)} ${humanLabel(command.state)}`,
41804
- commandType: command.commandType,
41805
- state: command.state,
41806
- attempts: command.attemptCount,
41807
- errorCode: command.lastErrorCode ?? null
41808
- }
41809
- });
41810
- }
41811
- for (const command of input.detail.commands) {
41812
- candidates.push({
41813
- identity: `worker-command:${command.id}`,
41814
- timestamp: command.updatedAt,
41815
- type: command.errorCode ? "failure" : "progress",
41816
- payload: {
41817
- telemetryType: "worker_command",
41818
- telemetrySource: "runtime",
41819
- message: `${humanLabel(command.commandType)} ${humanLabel(command.state)}`,
41820
- commandType: command.commandType,
41821
- state: command.state,
41822
- errorCode: command.errorCode ?? null
41823
- }
41824
- });
41825
- }
41826
- const trajectoryByStep = /* @__PURE__ */ new Map();
41827
- for (const trajectory of input.detail.trajectories) {
41828
- if (!trajectory.consumedTrainingStepId) continue;
41829
- const current = trajectoryByStep.get(trajectory.consumedTrainingStepId);
41830
- if (current) current.push(trajectory);
41831
- else trajectoryByStep.set(trajectory.consumedTrainingStepId, [trajectory]);
41832
- }
41833
- const groupById = new Map(
41834
- input.detail.rolloutGroups.map((group) => [group.id, group])
41835
- );
41836
- const telemetryMetricsByStep = /* @__PURE__ */ new Map();
41837
- for (const item of input.detail.telemetry) {
41838
- if (item.kind !== "observation" || !item.observation) continue;
41839
- const step = item.observation.lineage.step;
41840
- if (step == null) continue;
41841
- const current = telemetryMetricsByStep.get(step) ?? {};
41842
- current[item.observation.metricId] = item.observation.value;
41843
- telemetryMetricsByStep.set(step, current);
41844
- }
41845
- for (const step of input.detail.trainingSteps.filter(
41846
- (candidate2) => candidate2.state === "committed"
41847
- )) {
41848
- const trajectories = trajectoryByStep.get(step.id) ?? [];
41849
- const group = groupById.get(step.groupId);
41850
- const telemetry = telemetryMetricsByStep.get(step.stepIndex) ?? {};
41851
- candidates.push({
41852
- identity: `optimizer:${step.id}`,
41853
- timestamp: step.committedAt ?? step.startedAt ?? input.detail.job.updatedAt,
41854
- type: "metric",
41855
- payload: {
41856
- schemaVersion: "openpond.policyOptimizationMetric.v1",
41857
- metricKind: "policy_optimization",
41858
- method: "grpo",
41859
- step: step.stepIndex,
41860
- timestamp: step.committedAt ?? step.startedAt ?? input.detail.job.updatedAt,
41861
- learningRate: input.learningRate,
41862
- policyLoss: metricNumber(step.metrics, "policyLoss") ?? metricNumber(telemetry, "optimizer.loss"),
41863
- valueLoss: metricNumber(step.metrics, "valueLoss"),
41864
- meanReward: metricNumber(step.metrics, "rewardMean") ?? decimal(group?.rewardMean),
41865
- meanReturn: metricNumber(step.metrics, "meanReturn"),
41866
- kl: metricNumber(step.metrics, "kl") ?? metricNumber(telemetry, "optimizer.kl"),
41867
- entropy: metricNumber(step.metrics, "entropy") ?? metricNumber(telemetry, "optimizer.entropy"),
41868
- policyClipFraction: metricNumber(
41869
- step.metrics,
41870
- "policyClipFraction"
41871
- ) ?? metricNumber(telemetry, "optimizer.clip_fraction"),
41872
- valueClipFraction: metricNumber(step.metrics, "valueClipFraction"),
41873
- explainedVariance: metricNumber(step.metrics, "explainedVariance"),
41874
- rolloutLearnerLag: 0,
41875
- inputTokens: sumNullableIntegers(
41876
- trajectories.map((trajectory) => trajectory.promptTokenCount)
41877
- ),
41878
- outputTokens: sumNullableIntegers(
41879
- trajectories.map((trajectory) => trajectory.outputTokenCount)
41880
- ),
41881
- environmentExecutions: trajectories.length,
41882
- costUsd: null,
41883
- inputPolicyVersion: step.inputPolicyVersion,
41884
- outputPolicyVersion: step.outputPolicyVersion
41885
- }
41886
- });
41887
- }
41888
- for (const item of input.detail.telemetry) {
41889
- if (item.kind === "event" && item.event) {
41890
- candidates.push({
41891
- identity: `telemetry-event:${item.itemId}`,
41892
- timestamp: item.event.occurredAt,
41893
- type: item.event.type === "run_failed" ? "failure" : item.event.type === "checkpoint_committed" ? "checkpoint" : item.event.type === "run_completed" ? "complete" : item.event.type === "run_started" ? "start" : "progress",
41894
- payload: {
41895
- telemetryType: item.event.type,
41896
- telemetrySource: item.event.source ?? "managed",
41897
- step: item.event.lineage.step ?? null,
41898
- ...item.event.attributes
41899
- }
41900
- });
41901
- continue;
41902
- }
41903
- if (item.kind === "observation" && item.observation) {
41904
- candidates.push({
41905
- identity: `telemetry-observation:${item.itemId}`,
41906
- timestamp: item.observation.observedAt,
41907
- type: "metric",
41908
- payload: {
41909
- metricKind: "managed_telemetry",
41910
- metricId: item.observation.metricId,
41911
- value: item.observation.value,
41912
- step: item.observation.lineage.step ?? null
41913
- }
41914
- });
41915
- }
41916
- }
41917
- for (const checkpoint2 of input.detail.checkpoints.filter(
41918
- (candidate2) => candidate2.state === "ready"
41919
- )) {
41920
- candidates.push({
41921
- identity: `checkpoint:${checkpoint2.id}`,
41922
- timestamp: checkpoint2.readyAt ?? checkpoint2.updatedAt,
41923
- type: "checkpoint",
41924
- payload: {
41925
- checkpointId: checkpoint2.id,
41926
- policyVersion: checkpoint2.policyVersion,
41927
- sha256: checkpoint2.adapterSha256 ?? null,
41928
- sizeBytes: checkpoint2.sizeBytes ?? null,
41929
- final: checkpoint2.isFinal
41930
- }
41931
- });
41932
- }
41933
- if (["completed", "cancelled", "budget_exhausted", "failed"].includes(
41934
- input.detail.job.state
41935
- )) {
41936
- candidates.push({
41937
- identity: "complete",
41938
- timestamp: input.detail.job.completedAt ?? input.detail.job.updatedAt,
41939
- type: input.detail.job.state === "completed" ? "complete" : input.detail.job.state === "cancelled" ? "cancel" : "failure",
41940
- payload: {
41941
- state: input.detail.job.state,
41942
- artifactCount: input.detail.checkpoints.filter(
41943
- (checkpoint2) => checkpoint2.state === "ready"
41944
- ).length,
41945
- optimizerUpdates: input.detail.trainingSteps.filter(
41946
- (step) => step.state === "committed"
41947
- ).length
41948
- }
41949
- });
41950
- }
41951
- const existingById = new Map(
41952
- input.existingEvents.map((event2) => [event2.id, event2])
41953
- );
41954
- let nextSequence = Math.max(-1, ...input.existingEvents.map((event2) => event2.sequence)) + 1;
41955
- return candidates.sort(
41956
- (left, right) => left.timestamp.localeCompare(right.timestamp) || left.identity.localeCompare(right.identity)
41957
- ).map((candidate2) => {
41958
- const id = managedEventId(input.jobId, candidate2.identity);
41959
- const existing = existingById.get(id);
41960
- return TrainingJobEventSchema.parse({
41961
- schemaVersion: "openpond.trainingJobEvent.v1",
41962
- id,
41963
- jobId: input.jobId,
41964
- sequence: existing?.sequence ?? nextSequence++,
41965
- type: candidate2.type,
41966
- timestamp: candidate2.timestamp,
41967
- payload: candidate2.payload
41968
- });
41969
- });
41521
+ function recordOrEmpty(value) {
41522
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
41970
41523
  }
41971
- function managedEventId(jobId, identity) {
41972
- return `managed_event_${contentHash({ jobId, identity }).slice(0, 32)}`;
41524
+ function managedJobFromPublic(job) {
41525
+ const state = job.state === "succeeded" ? "completed" : job.state === "queued" || job.state === "admitting" ? "admitted" : job.state === "provisioning" ? "provisioning_gpu" : job.state === "stopping" ? "stop_after_group" : job.state;
41526
+ return {
41527
+ id: job.id,
41528
+ state,
41529
+ version: job.version,
41530
+ terminalReason: job.terminalReason,
41531
+ createdAt: job.createdAt,
41532
+ updatedAt: job.updatedAt
41533
+ };
41973
41534
  }
41974
- function humanLabel(value) {
41975
- return value.replaceAll("_", " ");
41535
+ function requiredRecord(value, label) {
41536
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
41537
+ throw new Error(`${label} is invalid.`);
41538
+ }
41539
+ return value;
41976
41540
  }
41977
- function providerLabel(value) {
41978
- if (value.toLowerCase().includes("runpod")) return "RunPod";
41979
- if (value.toLowerCase().includes("prime")) return "Prime Intellect";
41541
+ function requiredStringValue(value, label) {
41542
+ if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is invalid.`);
41980
41543
  return value;
41981
41544
  }
41982
- function metricNumber(values, key) {
41983
- const value = values[key];
41984
- return typeof value === "number" && Number.isFinite(value) ? value : null;
41545
+ function requiredHash(value, label) {
41546
+ const parsed = requiredStringValue(value, label);
41547
+ if (!/^[a-f0-9]{64}$/.test(parsed)) throw new Error(`${label} is invalid.`);
41548
+ return parsed;
41985
41549
  }
41986
- function decimal(value) {
41987
- if (value == null) return null;
41988
- const parsed = Number(value);
41989
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
41550
+ function requiredFiniteNumber(value, label) {
41551
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
41552
+ throw new Error(`${label} is invalid.`);
41553
+ }
41554
+ return value;
41990
41555
  }
41991
- function failureCode(components) {
41992
- const value = components.failureCode;
41993
- return typeof value === "string" && value.trim().length ? value.slice(0, 191) : null;
41556
+ function requiredPositiveInteger(value, label) {
41557
+ if (typeof value !== "number" || !Number.isInteger(value) || value < 1) {
41558
+ throw new Error(`${label} is invalid.`);
41559
+ }
41560
+ return value;
41994
41561
  }
41995
- function sumNullableIntegers(values) {
41996
- return values.reduce((sum, value) => sum + (value ?? 0), 0);
41562
+ function requiredRef(value, label) {
41563
+ const record12 = requiredRecord(value, label);
41564
+ return {
41565
+ id: requiredStringValue(record12.id, `${label} id`),
41566
+ contentHash: requiredHash(record12.contentHash, `${label} hash`)
41567
+ };
41568
+ }
41569
+
41570
+ // ../server/src/training/openpond-managed-training-adapter-support.ts
41571
+ function localTrainingEventType(event2) {
41572
+ if (typeof event2.data.metricKind === "string") return "metric";
41573
+ if (event2.type.includes("checkpoint")) return "checkpoint";
41574
+ if (event2.type === "provision_gpu" || event2.type === "start_inference") return "start";
41575
+ if (event2.type === "cancel" || event2.type === "stop") return "cancel";
41576
+ if (event2.type === "complete") return "complete";
41577
+ if (event2.type === "failure") return "failure";
41578
+ return "progress";
41997
41579
  }
41998
41580
 
41999
41581
  // ../server/src/training/openpond-managed-training-adapter.ts
42000
41582
  var ADAPTER_ID = "sandbox-managed-rl";
42001
- var QUALIFIED_MODEL = {
42002
- source: "Qwen/Qwen3-0.6B",
42003
- revision: "c1899de289a04d12100db370d81485cdf75e47ca",
42004
- chatTemplateHash: "a55ee1b1660128b7098723e0abcd92caa0788061051c62d51cbe87d9cf1974d8"
42005
- };
42006
- var QUALIFIED_RECIPE = {
42007
- loraRank: 16,
42008
- rolloutGroupSize: 4,
42009
- rolloutConcurrency: 4,
42010
- maxPromptTokens: 4096
42011
- };
41583
+ var REMOTE_TRAINING_EVENT_SEQUENCE_BASE = 1e6;
41584
+ var ACTIVE_EVIDENCE_REFRESH_TTL_MS = 1500;
42012
41585
  var OpenPondManagedTrainingAdapter = class {
42013
41586
  constructor(dependencies) {
42014
41587
  this.dependencies = dependencies;
@@ -42022,6 +41595,8 @@ var OpenPondManagedTrainingAdapter = class {
42022
41595
  resolveAccess;
42023
41596
  readFileImpl;
42024
41597
  localExecutors = /* @__PURE__ */ new Map();
41598
+ evidenceRefreshes = /* @__PURE__ */ new Map();
41599
+ evidenceRefreshedAt = /* @__PURE__ */ new Map();
42025
41600
  async createCalibrationBatch(request) {
42026
41601
  return this.requestJson(
42027
41602
  "/v1/managed-rl/calibration-batches",
@@ -42036,70 +41611,172 @@ var OpenPondManagedTrainingAdapter = class {
42036
41611
  await this.resolveBoundAccess()
42037
41612
  );
42038
41613
  }
42039
- /** Uploads an immutable rendered artifact for a managed Reward Model run. */
42040
- async uploadRewardModelArtifact(input) {
42041
- const bytes2 = Buffer.from(input.bytes);
42042
- return this.requestJson(
42043
- "/v1/managed-rl/reward-model-artifacts",
42044
- {
42045
- method: "POST",
42046
- body: JSON.stringify({
42047
- contentBase64: bytes2.toString("base64"),
42048
- expectedSha256: sha256(bytes2),
42049
- idempotencyKey: input.idempotencyKey,
42050
- mediaType: input.mediaType
42051
- })
42052
- },
42053
- await this.resolveBoundAccess()
41614
+ async createRewardModelLaunch(input) {
41615
+ const request = requiredRecord(input.request, "Reward Model launch request");
41616
+ const requestHash = requiredHash(request.requestHash, "Reward Model request hash");
41617
+ const rewardModelTraining = requiredRecord(
41618
+ request.rewardModelTraining,
41619
+ "Reward Model training payload"
42054
41620
  );
42055
- }
42056
- async createRewardModelLaunch(request) {
42057
- return this.requestJson(
42058
- "/v1/managed-rl/reward-model-launches",
42059
- { method: "POST", body: JSON.stringify(request) },
42060
- await this.resolveBoundAccess()
41621
+ const taskset = requiredRecord(request.taskset, "Reward Model Taskset");
41622
+ const preferenceDataset = requiredRef(
41623
+ request.preferenceDatasetRelease,
41624
+ "Reward Model preference dataset"
42061
41625
  );
41626
+ const base = requiredRecord(rewardModelTraining.baseModel, "Reward Model base Model");
41627
+ const projectValue = await this.dependencies.store.getModelProject(input.modelProjectId);
41628
+ if (!projectValue) throw new Error("Reward Model Model Project was not found.");
41629
+ const access5 = await this.resolveBoundAccess();
41630
+ const project = await this.syncProjectForSubmission(projectValue, access5);
41631
+ if (!project.hosted || !project.trainingSetup.harnessRelease) {
41632
+ throw new Error("Reward Model training requires a synchronized Project Harness release.");
41633
+ }
41634
+ const tasksetRelease = project.trainingSetup.tasksetRelease;
41635
+ if (!tasksetRelease || tasksetRelease.id !== requiredStringValue(taskset.id, "Reward Model Taskset id") || tasksetRelease.contentHash !== requiredHash(taskset.contentHash, "Reward Model Taskset hash")) {
41636
+ throw new Error("Reward Model training does not match the Model Project Taskset release.");
41637
+ }
41638
+ const client = this.trainingClient(access5);
41639
+ const artifactContent = {
41640
+ schemaVersion: "openpond.trainingInputArtifactUpload.v2",
41641
+ kind: "reward_model_dataset",
41642
+ idempotencyKey: `stage:${requestHash}`,
41643
+ sourceManifest: {
41644
+ id: requiredStringValue(request.sourceRunRef, "Reward Model source Run"),
41645
+ contentHash: requestHash
41646
+ },
41647
+ payload: rewardModelTraining
41648
+ };
41649
+ const staged = await client.stageArtifact({
41650
+ ...artifactContent,
41651
+ contentHash: await trainingInputArtifactUploadHash(artifactContent)
41652
+ });
41653
+ const maximumSpendUsd = requiredFiniteNumber(
41654
+ request.maximumSpendUsd,
41655
+ "Reward Model maximum spend"
41656
+ );
41657
+ const approvalHash = contentHash({
41658
+ sourceRunRef: request.sourceRunRef,
41659
+ requestHash,
41660
+ maximumSpendUsd,
41661
+ approvedAt: input.approvedAt
41662
+ });
41663
+ const jobContent = {
41664
+ schemaVersion: "openpond.trainingJobSubmission.v2",
41665
+ idempotencyKey: requiredStringValue(request.idempotencyKey, "Reward Model idempotency key"),
41666
+ name: requiredStringValue(request.name, "Reward Model name").slice(0, 200),
41667
+ source: {
41668
+ modelProject: {
41669
+ id: project.hosted.projectId,
41670
+ portableProjectId: project.id,
41671
+ revision: project.revision,
41672
+ contentHash: project.hosted.etag
41673
+ },
41674
+ harnessRunManifest: artifactContent.sourceManifest,
41675
+ harnessRelease: project.trainingSetup.harnessRelease,
41676
+ taskset: {
41677
+ id: tasksetRelease.id,
41678
+ revision: requiredPositiveInteger(taskset.revision, "Reward Model Taskset revision"),
41679
+ contentHash: tasksetRelease.contentHash
41680
+ },
41681
+ tasksetRelease,
41682
+ dataset: { id: staged.artifactRef, contentHash: staged.contentHash },
41683
+ evidenceSets: [preferenceDataset]
41684
+ },
41685
+ job: {
41686
+ kind: "reward_model_train",
41687
+ baseModel: {
41688
+ schemaVersion: "openpond.baseModelPreference.v1",
41689
+ modelId: requiredStringValue(base.repoId, "Reward Model repository"),
41690
+ revision: requiredStringValue(base.revision, "Reward Model revision"),
41691
+ tokenizerRevision: requiredStringValue(base.revision, "Reward Model tokenizer revision"),
41692
+ chatTemplateHash: requiredHash(base.tokenizerHash, "Reward Model tokenizer hash"),
41693
+ modelAssetId: null,
41694
+ source: "managed"
41695
+ },
41696
+ preferenceDatasetRelease: preferenceDataset,
41697
+ processorRelease: input.processorRelease,
41698
+ recipe: input.recipe
41699
+ },
41700
+ requestedCapabilities: [
41701
+ { id: "managed_rl.reward_model", version: "1", required: true }
41702
+ ],
41703
+ budget: {
41704
+ maximumSpendUsd,
41705
+ maximumWallSeconds: Math.ceil(input.recipe.resourceLimits.wallTimeMs / 1e3)
41706
+ },
41707
+ approval: {
41708
+ approvalHash,
41709
+ approvedAt: input.approvedAt,
41710
+ exportApproved: true,
41711
+ maximumSpendUsd,
41712
+ retentionDays: project.trainingSetup.preferredRetentionDays,
41713
+ region: null
41714
+ }
41715
+ };
41716
+ const submission = {
41717
+ ...jobContent,
41718
+ contentHash: await trainingJobSubmissionHash(jobContent)
41719
+ };
41720
+ const job = await client.createJob(submission);
41721
+ return { job: managedJobFromPublic(job), requestHash: submission.contentHash };
42062
41722
  }
42063
41723
  async rewardModelJob(jobId) {
42064
- const payload = await this.requestJson(
42065
- `/v1/managed-rl/jobs/${encodeURIComponent(jobId)}`,
42066
- {},
42067
- await this.resolveBoundAccess()
42068
- );
42069
- return payload.job;
41724
+ const access5 = await this.resolveBoundAccess();
41725
+ const client = this.trainingClient(access5);
41726
+ const job = await client.getJob(jobId);
41727
+ const output = job.state === "succeeded" ? await client.outputs(jobId) : null;
41728
+ const scorer = output?.outputs.find((candidate2) => candidate2.kind === "scorer");
41729
+ return {
41730
+ job: {
41731
+ ...managedJobFromPublic(job),
41732
+ cleanupAttestation: output?.receipt?.cleanupComplete === true ? { complete: true } : null
41733
+ },
41734
+ resources: scorer ? [{
41735
+ kind: "artifact_upload",
41736
+ state: "consumed",
41737
+ metadata: {
41738
+ ...scorer.metadata,
41739
+ objectPrefix: scorer.artifactRef,
41740
+ artifactSha256: scorer.contentHash
41741
+ }
41742
+ }] : [],
41743
+ outputs: output,
41744
+ executionReceiptRef: output?.receipt ? {
41745
+ id: output.receipt.id,
41746
+ contentHash: await trainingExecutionReceiptHash(output.receipt)
41747
+ } : null
41748
+ };
42070
41749
  }
42071
41750
  async cancelRewardModelJob(jobId, expectedVersion) {
42072
- return this.requestJson(
42073
- `/v1/managed-rl/jobs/${encodeURIComponent(jobId)}/cancel`,
42074
- { method: "POST", body: JSON.stringify({ expectedVersion }) },
42075
- await this.resolveBoundAccess()
42076
- );
41751
+ const client = this.trainingClient(await this.resolveBoundAccess());
41752
+ return { job: managedJobFromPublic(await client.cancelJob(jobId, expectedVersion)) };
42077
41753
  }
42078
41754
  async capabilities() {
42079
- const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
41755
+ const access5 = await this.resolveBoundAccess();
41756
+ const capabilities = await this.trainingClient(access5).capabilities();
41757
+ const available = Date.parse(capabilities.expiresAt) > Date.now();
42080
41758
  return TrainingEngineCapabilitiesSchema.parse({
42081
41759
  schemaVersion: "openpond.trainingEngineCapabilities.v1",
42082
41760
  adapterId: this.id,
42083
- available: true,
42084
- methods: ["grpo"],
41761
+ available,
41762
+ methods: capabilities.methods,
42085
41763
  signalKinds: ["trajectory", "reward", "grader_evidence", "infrastructure_failure"],
42086
41764
  modelFamilies: ["transformers"],
42087
41765
  precisions: ["bf16"],
42088
- topologies: ["single_gpu_phased"],
42089
- workerProtocolVersion: "openpond.managedRlWorker.v2",
42090
- upstreamRevision: "e0d60e4d85ea636873acb2e7083e794740d20226",
41766
+ topologies: capabilities.placements.map((placement) => `managed_${placement}`),
41767
+ workerProtocolVersion: "openpond.training.v2",
41768
+ upstreamRevision: capabilities.capabilityHash,
42091
41769
  workerImageDigest: null,
42092
- capabilityReceipt: contentHash({
42093
- adapterId: this.id,
42094
- contract: "openpond.managedRlPortableSubmission.v1",
42095
- qualifiedModel: QUALIFIED_MODEL
42096
- }),
42097
- checkedAt,
42098
- unavailableReason: null
41770
+ capabilityReceipt: capabilities.capabilityHash,
41771
+ checkedAt: capabilities.checkedAt,
41772
+ unavailableReason: available ? null : "Managed Training capabilities expired."
42099
41773
  });
42100
41774
  }
42101
41775
  async validate(plan) {
42102
41776
  const issues = [];
41777
+ const publicCapabilities = await this.trainingClient(
41778
+ await this.resolveBoundAccess()
41779
+ ).capabilities();
42103
41780
  if (plan.engine.adapterId !== this.id || plan.compute.adapterId !== "openpond-managed" || !(plan.runtime.adapterId === "local-harness" && plan.runtime.placement === "local" && plan.runtime.dataPlane === null || plan.runtime.adapterId === "openpond-managed-harness" && plan.runtime.placement === "remote")) {
42104
41781
  issues.push({
42105
41782
  code: "managed_binding_mismatch",
@@ -42107,24 +41784,25 @@ var OpenPondManagedTrainingAdapter = class {
42107
41784
  message: "The resolved plan is not bound to OpenPond Managed."
42108
41785
  });
42109
41786
  }
42110
- if (plan.manifest.model.source !== QUALIFIED_MODEL.source || plan.manifest.model.revision !== QUALIFIED_MODEL.revision || plan.manifest.model.tokenizerRevision !== QUALIFIED_MODEL.revision || plan.manifest.model.chatTemplateHash !== QUALIFIED_MODEL.chatTemplateHash) {
41787
+ if (!publicCapabilities.methods.includes(plan.recipe.method)) {
42111
41788
  issues.push({
42112
- code: "managed_base_profile_unsupported",
42113
- path: "manifest.model",
42114
- message: "OpenPond Managed currently requires the qualified Qwen3-0.6B profile."
41789
+ code: "managed_method_unsupported",
41790
+ path: "recipe.method",
41791
+ message: `OpenPond Managed does not currently advertise ${plan.recipe.method}.`
42115
41792
  });
42116
41793
  }
42117
- if (plan.recipe.method !== "grpo") {
41794
+ if (!publicCapabilities.placements.includes(plan.runtime.placement)) {
42118
41795
  issues.push({
42119
- code: "managed_method_unsupported",
42120
- path: "recipe.method",
42121
- message: "OpenPond Managed currently accepts GRPO runs."
41796
+ code: "managed_placement_unsupported",
41797
+ path: "runtime.placement",
41798
+ message: `OpenPond Managed does not currently advertise ${plan.runtime.placement} rollout placement.`
42122
41799
  });
42123
- } else if (plan.recipe.lora.rank !== QUALIFIED_RECIPE.loraRank || plan.recipe.rollout.groupSize !== QUALIFIED_RECIPE.rolloutGroupSize || plan.recipe.rollout.concurrency !== QUALIFIED_RECIPE.rolloutConcurrency || plan.recipe.dataset.maxPromptTokens !== QUALIFIED_RECIPE.maxPromptTokens) {
41800
+ }
41801
+ if (plan.maximumSpendUsd === null || plan.maximumSpendUsd > publicCapabilities.limits.maximumSpendUsd) {
42124
41802
  issues.push({
42125
- code: "managed_recipe_profile_unsupported",
42126
- path: "recipe",
42127
- message: "OpenPond Managed requires the qualified 0.6B recipe profile: LoRA rank 16, group size 4, rollout concurrency 4, and 4096 prompt tokens."
41803
+ code: "managed_budget_unsupported",
41804
+ path: "maximumSpendUsd",
41805
+ message: "The approved spend exceeds the current managed-training capability."
42128
41806
  });
42129
41807
  }
42130
41808
  if (!plan.execution) {
@@ -42258,18 +41936,35 @@ var OpenPondManagedTrainingAdapter = class {
42258
41936
  };
42259
41937
  })
42260
41938
  );
42261
- const project = await this.dependencies.store.getModelProject(
41939
+ let project = await this.dependencies.store.getModelProject(
42262
41940
  trainingPlan.modelId
42263
41941
  );
42264
- const submission = {
41942
+ if (!project) {
41943
+ throw new Error("The managed Model Project is no longer available.");
41944
+ }
41945
+ const access5 = await this.resolveBoundAccess();
41946
+ project = await this.syncProjectForSubmission(project, access5);
41947
+ if (!project?.hosted || project.hosted.syncedSourceRevision !== project.revision || project.hosted.portableProjectId !== project.id) {
41948
+ throw new Error(
41949
+ "Sync the exact Model Project revision before creating managed training."
41950
+ );
41951
+ }
41952
+ if (plan.recipe.method !== "grpo" || plan.maximumSpendUsd === null) {
41953
+ throw new Error("Managed Training V2 requires GRPO and an approved spend ceiling.");
41954
+ }
41955
+ const baseModel = project.trainingSetup.baseModel;
41956
+ if (!baseModel || baseModel.modelId !== plan.manifest.model.source || baseModel.revision !== plan.manifest.model.revision || baseModel.tokenizerRevision !== plan.manifest.model.tokenizerRevision || baseModel.chatTemplateHash !== plan.manifest.model.chatTemplateHash) {
41957
+ throw new Error("The synced Model Project base Model does not match the Run manifest.");
41958
+ }
41959
+ const portableSubmission = {
42265
41960
  schemaVersion: "openpond.managedRlPortableSubmission.v1",
42266
41961
  sourceRunRef: `openpond:model-run:${plan.manifest.id}`,
42267
41962
  name: `OpenPond Managed \xB7 ${trainingPlan.modelId}`.slice(0, 191),
42268
41963
  idempotencyKey: `openpond-managed:${plan.manifest.contentHash}`.slice(0, 191),
42269
- modelProject: project?.hosted ? {
41964
+ modelProject: {
42270
41965
  id: project.hosted.projectId,
42271
41966
  portableProjectId: project.hosted.portableProjectId
42272
- } : null,
41967
+ },
42273
41968
  manifest: plan.manifest,
42274
41969
  sourceTaskset: {
42275
41970
  id: taskset.id,
@@ -42284,24 +41979,102 @@ var OpenPondManagedTrainingAdapter = class {
42284
41979
  },
42285
41980
  validationTasks
42286
41981
  };
42287
- const access5 = await this.resolveBoundAccess();
42288
- const response = await this.requestJson(
42289
- "/v1/managed-rl/portable-launches",
42290
- {
42291
- method: "POST",
42292
- body: JSON.stringify(submission)
41982
+ const client = this.trainingClient(access5);
41983
+ const stagedContent = {
41984
+ schemaVersion: "openpond.trainingInputArtifactUpload.v2",
41985
+ kind: "portable_training_bundle",
41986
+ idempotencyKey: `stage:${plan.manifest.contentHash}`,
41987
+ sourceManifest: {
41988
+ id: plan.manifest.id,
41989
+ contentHash: plan.manifest.contentHash
42293
41990
  },
42294
- access5
42295
- );
41991
+ payload: portableSubmission
41992
+ };
41993
+ const staged = {
41994
+ ...stagedContent,
41995
+ contentHash: await trainingInputArtifactUploadHash(stagedContent)
41996
+ };
41997
+ await client.stageArtifact(staged);
41998
+ const grader = taskset.graders[0];
41999
+ if (!grader) throw new Error("Managed training requires an immutable grader.");
42000
+ const learnedPreference = plan.recipe.reward.learnedPreference ?? null;
42001
+ const rewardSource = learnedPreference ? learnedRewardSource(learnedPreference) : {
42002
+ kind: "deterministic",
42003
+ grader: { id: grader.id, contentHash: contentHash(grader) },
42004
+ composer: null
42005
+ };
42006
+ const jobContent = {
42007
+ schemaVersion: "openpond.trainingJobSubmission.v2",
42008
+ idempotencyKey: `openpond-training-v2:${plan.manifest.contentHash}`,
42009
+ name: `OpenPond Managed \xB7 ${trainingPlan.modelId}`.slice(0, 200),
42010
+ source: {
42011
+ modelProject: {
42012
+ id: project.hosted.projectId,
42013
+ portableProjectId: project.hosted.portableProjectId,
42014
+ revision: project.revision,
42015
+ contentHash: project.hosted.etag
42016
+ },
42017
+ harnessRunManifest: {
42018
+ id: plan.manifest.id,
42019
+ contentHash: plan.manifest.contentHash
42020
+ },
42021
+ harnessRelease: plan.manifest.harnessRelease,
42022
+ taskset: {
42023
+ id: taskset.id,
42024
+ revision: taskset.revision,
42025
+ contentHash: taskset.contentHash
42026
+ },
42027
+ tasksetRelease: {
42028
+ id: taskset.id,
42029
+ contentHash: taskset.contentHash
42030
+ },
42031
+ dataset: bundleManifest.datasetRelease,
42032
+ evidenceSets: bundleManifest.evidenceSetRelease ? [bundleManifest.evidenceSetRelease] : []
42033
+ },
42034
+ job: {
42035
+ kind: "policy_optimize",
42036
+ baseModel,
42037
+ recipe: plan.recipe,
42038
+ rewardSource,
42039
+ resumeFrom: null
42040
+ },
42041
+ requestedCapabilities: [
42042
+ { id: "managed_rl.policy.grpo", version: "1", required: true },
42043
+ {
42044
+ id: `managed_rl.rollouts.${plan.runtime.placement}`,
42045
+ version: "1",
42046
+ required: true
42047
+ }
42048
+ ],
42049
+ budget: {
42050
+ maximumSpendUsd: plan.maximumSpendUsd,
42051
+ maximumWallSeconds: Math.ceil(plan.recipe.resourceLimits.wallTimeMs / 1e3)
42052
+ },
42053
+ approval: {
42054
+ approvalHash: plan.approvalHash,
42055
+ approvedAt: plan.manifest.approval.approvedAt,
42056
+ exportApproved: true,
42057
+ maximumSpendUsd: plan.maximumSpendUsd,
42058
+ retentionDays: trainingPlan.dataPolicy.retentionDays,
42059
+ region: trainingPlan.dataPolicy.region
42060
+ }
42061
+ };
42062
+ const publicSubmission = {
42063
+ ...jobContent,
42064
+ contentHash: await trainingJobSubmissionHash(jobContent)
42065
+ };
42066
+ const job = await client.createJob(publicSubmission);
42296
42067
  const ref = {
42297
- runId: response.job.id,
42068
+ runId: job.id,
42298
42069
  adapterId: this.id,
42299
- providerJobId: response.job.id,
42070
+ protocolVersion: "openpond.training.v2",
42071
+ routeFamily: "training_v2",
42072
+ providerJobId: job.id,
42300
42073
  tenantId: access5.teamId,
42301
42074
  leaseId: null,
42302
- manifestHash: response.sourceManifestHash,
42303
- inputBundleHash: response.submissionHash,
42304
- createdAt: dateString(response.job.createdAt)
42075
+ manifestHash: plan.manifest.contentHash,
42076
+ inputBundleHash: publicSubmission.contentHash,
42077
+ createdAt: dateString(job.createdAt)
42305
42078
  };
42306
42079
  if (plan.runtime.placement === "local") {
42307
42080
  this.ensureLocalExecutor(ref, access5, plan.manifest.harnessRelease.contentHash);
@@ -42312,75 +42085,117 @@ var OpenPondManagedTrainingAdapter = class {
42312
42085
  throw new Error("OpenPond Managed consumes the immutable submitted training bundle.");
42313
42086
  }
42314
42087
  async status(ref) {
42315
- const payload = await this.requestJson(
42316
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}`,
42317
- {},
42318
- await this.resolveBoundAccess(ref.tenantId)
42319
- );
42320
- const detail = parseManagedJobDetail(payload.job);
42321
- await persistManagedRunEvidence({
42322
- store: this.dependencies.store,
42323
- ref,
42324
- detail
42325
- }).catch(() => void 0);
42326
- const placement = detail.job.inputBundle?.harnessRunManifest?.runtimeTarget?.placement;
42088
+ const access5 = await this.resolveBoundAccess(ref.tenantId);
42089
+ const job = await this.trainingClient(access5).getJob(ref.runId);
42090
+ const localJob = await this.dependencies.store.getTrainingJob(ref.runId);
42091
+ const bindings = recordOrEmpty(localJob?.metadata.portableAdapterBindings);
42092
+ const runtime = recordOrEmpty(bindings.runtime);
42093
+ const placement = runtime.placement;
42327
42094
  if (placement === "local") {
42328
- const localJob = await this.dependencies.store.getTrainingJob(ref.runId);
42329
42095
  const storedHarnessHash = localJob?.metadata.harnessReleaseHash;
42330
42096
  this.ensureLocalExecutor(
42331
42097
  ref,
42332
- await this.resolveBoundAccess(ref.tenantId),
42333
- detail.job.inputBundle?.harnessRelease?.contentHash ?? detail.job.inputBundle?.harnessRunManifest?.harnessRelease?.contentHash ?? (typeof storedHarnessHash === "string" ? storedHarnessHash : void 0)
42098
+ access5,
42099
+ typeof storedHarnessHash === "string" ? storedHarnessHash : void 0
42334
42100
  );
42335
42101
  }
42336
- if (["completed", "cancelled", "budget_exhausted", "failed"].includes(
42337
- detail.job.state
42338
- )) {
42102
+ if (["succeeded", "cancelled", "failed"].includes(job.state)) {
42339
42103
  const executor = this.localExecutors.get(ref.runId);
42340
42104
  this.localExecutors.delete(ref.runId);
42341
42105
  void executor?.stop();
42342
42106
  }
42343
- return TrainingExecutionStatusSchema.parse(toExecutionStatus(detail.job));
42107
+ return TrainingExecutionStatusSchema.parse(toExecutionStatus(job));
42344
42108
  }
42345
42109
  async refreshEvidence(ref) {
42346
- const payload = await this.requestJson(
42347
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}`,
42348
- {},
42349
- await this.resolveBoundAccess(ref.tenantId)
42110
+ const localJob = await this.dependencies.store.getTrainingJob(ref.runId);
42111
+ const terminal = localJob ? ["succeeded", "failed", "cancelled"].includes(localJob.status) : false;
42112
+ const snapshot = recordOrEmpty(
42113
+ localJob?.metadata.managedEvidenceSnapshot
42350
42114
  );
42351
- await persistManagedRunEvidence({
42352
- store: this.dependencies.store,
42353
- ref,
42354
- detail: parseManagedJobDetail(payload.job)
42115
+ if (terminal && snapshot.syncedJobUpdatedAt === localJob?.updatedAt) {
42116
+ return;
42117
+ }
42118
+ const active = this.evidenceRefreshes.get(ref.runId);
42119
+ if (active) return active;
42120
+ const refreshedAt = this.evidenceRefreshedAt.get(ref.runId) ?? 0;
42121
+ if (!terminal && Date.now() - refreshedAt < ACTIVE_EVIDENCE_REFRESH_TTL_MS) return;
42122
+ const refresh = this.refreshEvidenceOnce(ref).finally(() => {
42123
+ if (this.evidenceRefreshes.get(ref.runId) === refresh) {
42124
+ this.evidenceRefreshes.delete(ref.runId);
42125
+ this.evidenceRefreshedAt.set(ref.runId, Date.now());
42126
+ }
42355
42127
  });
42128
+ this.evidenceRefreshes.set(ref.runId, refresh);
42129
+ return refresh;
42130
+ }
42131
+ async refreshEvidenceOnce(ref) {
42132
+ const storedEvents = await this.dependencies.store.listTrainingJobEvents(ref.runId);
42133
+ const client = this.trainingClient(await this.resolveBoundAccess(ref.tenantId));
42134
+ const events = await client.events(ref.runId);
42135
+ const storedById = new Map(storedEvents.map((event2) => [event2.id, event2]));
42136
+ const occupiedSequences = new Set(storedEvents.map((event2) => event2.sequence));
42137
+ let nextSequence = Math.max(
42138
+ REMOTE_TRAINING_EVENT_SEQUENCE_BASE - 1,
42139
+ ...storedEvents.map((event2) => event2.sequence)
42140
+ );
42141
+ for (const event2 of events) {
42142
+ const stored = storedById.get(event2.id);
42143
+ const projectedSequence = REMOTE_TRAINING_EVENT_SEQUENCE_BASE + event2.sequence;
42144
+ const sequence = stored?.sequence ?? (occupiedSequences.has(projectedSequence) ? ++nextSequence : projectedSequence);
42145
+ occupiedSequences.add(sequence);
42146
+ nextSequence = Math.max(nextSequence, sequence);
42147
+ await this.dependencies.store.saveTrainingJobEvent(TrainingJobEventSchema.parse({
42148
+ schemaVersion: "openpond.trainingJobEvent.v1",
42149
+ id: event2.id,
42150
+ jobId: ref.runId,
42151
+ sequence,
42152
+ type: localTrainingEventType(event2),
42153
+ timestamp: event2.createdAt,
42154
+ payload: {
42155
+ ...event2.data,
42156
+ remoteEventType: event2.type,
42157
+ remotePhase: event2.phase,
42158
+ ...event2.message ? { message: event2.message } : {}
42159
+ }
42160
+ }));
42161
+ }
42162
+ const refreshedJob = await this.dependencies.store.getTrainingJob(ref.runId);
42163
+ if (refreshedJob && ["succeeded", "failed", "cancelled"].includes(refreshedJob.status)) {
42164
+ await this.dependencies.store.saveTrainingJob({
42165
+ ...refreshedJob,
42166
+ metadata: {
42167
+ ...refreshedJob.metadata,
42168
+ managedEvidenceSnapshot: {
42169
+ schemaVersion: "openpond.managedEvidenceSnapshot.v1",
42170
+ syncedJobUpdatedAt: refreshedJob.updatedAt,
42171
+ eventCount: events.length,
42172
+ syncedAt: (/* @__PURE__ */ new Date()).toISOString()
42173
+ }
42174
+ }
42175
+ });
42176
+ }
42356
42177
  }
42357
42178
  async logs(ref, cursor) {
42358
- const query = cursor ? `?cursor=${encodeURIComponent(cursor)}` : "";
42359
- return this.requestJson(
42360
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}/logs${query}`,
42361
- {},
42179
+ const logs = await this.trainingClient(
42362
42180
  await this.resolveBoundAccess(ref.tenantId)
42363
- );
42181
+ ).logs(ref.runId);
42182
+ const after = cursor === void 0 ? -1 : Number.parseInt(cursor, 10);
42183
+ const entries = logs.filter((entry) => !Number.isFinite(after) || entry.sequence >= after).map((entry) => ({
42184
+ timestamp: entry.createdAt,
42185
+ level: entry.level,
42186
+ message: entry.message
42187
+ }));
42188
+ const next = logs.length === 0 ? Math.max(after, 0) : logs.at(-1).sequence + 1;
42189
+ return { cursor: String(next), entries };
42364
42190
  }
42365
42191
  async cancel(ref) {
42366
42192
  const executor = this.localExecutors.get(ref.runId);
42367
42193
  this.localExecutors.delete(ref.runId);
42368
42194
  void executor?.stop();
42369
42195
  const access5 = await this.resolveBoundAccess(ref.tenantId);
42370
- const current = await this.requestJson(
42371
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}`,
42372
- {},
42373
- access5
42374
- );
42375
- const detail = parseManagedJobDetail(current.job);
42376
- await this.requestJson(
42377
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}/cancel`,
42378
- {
42379
- method: "POST",
42380
- body: JSON.stringify({ expectedVersion: detail.job.version })
42381
- },
42382
- access5
42383
- );
42196
+ const client = this.trainingClient(access5);
42197
+ const current = await client.getJob(ref.runId);
42198
+ await client.cancelJob(ref.runId, current.version);
42384
42199
  }
42385
42200
  async close() {
42386
42201
  const executors = [...this.localExecutors.values()];
@@ -42388,23 +42203,32 @@ var OpenPondManagedTrainingAdapter = class {
42388
42203
  await Promise.all(executors.map((executor) => executor.stop()));
42389
42204
  }
42390
42205
  async collect(ref) {
42391
- const payload = await this.requestJson(
42392
- `/v1/managed-rl/jobs/${encodeURIComponent(ref.runId)}/artifacts`,
42393
- {},
42394
- await this.resolveBoundAccess(ref.tenantId)
42395
- );
42396
- const candidate2 = payload.candidateBundle;
42397
- if (!candidate2 || candidate2.jobId !== ref.runId || !candidate2.artifact.modelArtifactId.trim() || !candidate2.artifact.uri.startsWith("r2://") || !/^[a-f0-9]{64}$/.test(candidate2.artifact.sha256) || !Number.isSafeInteger(candidate2.artifact.sizeBytes) || candidate2.artifact.sizeBytes <= 0) {
42398
- throw new Error("Sandbox completed managed training without a valid candidate artifact.");
42399
- }
42400
- const artifacts = [
42401
- {
42402
- kind: "adapter",
42403
- objectRef: `sandbox-managed-rl://${encodeURIComponent(ref.runId)}/` + encodeURIComponent(candidate2.artifact.modelArtifactId),
42404
- sha256: candidate2.artifact.sha256,
42405
- sizeBytes: candidate2.artifact.sizeBytes
42406
- }
42407
- ];
42206
+ const access5 = await this.resolveBoundAccess(ref.tenantId);
42207
+ const output = await this.trainingClient(access5).outputs(ref.runId);
42208
+ if (!output.receipt) {
42209
+ throw new Error("Sandbox completed managed training without an execution receipt.");
42210
+ }
42211
+ const receiptOutput = output.outputs.find((candidate2) => candidate2.kind === "receipt");
42212
+ if (!receiptOutput) {
42213
+ throw new Error("Sandbox completed managed training without a receipt artifact.");
42214
+ }
42215
+ await parseAndVerifyTrainingExecutionReceipt(output.receipt, {
42216
+ id: output.receipt.id,
42217
+ contentHash: receiptOutput.contentHash,
42218
+ teamId: access5.teamId,
42219
+ jobId: ref.runId,
42220
+ requireCleanup: true
42221
+ });
42222
+ const adapterOutput = output.outputs.find((candidate2) => candidate2.kind === "adapter");
42223
+ if (!adapterOutput) {
42224
+ throw new Error("Sandbox completed managed training without an adapter artifact.");
42225
+ }
42226
+ const artifacts = output.outputs.filter((candidate2) => candidate2.kind !== "scorer").map((candidate2) => ({
42227
+ kind: candidate2.kind,
42228
+ objectRef: `sandbox-managed-rl://${encodeURIComponent(ref.runId)}/` + encodeURIComponent(candidate2.id),
42229
+ sha256: candidate2.contentHash,
42230
+ sizeBytes: candidate2.sizeBytes
42231
+ }));
42408
42232
  const base = {
42409
42233
  runId: ref.runId,
42410
42234
  manifestHash: ref.manifestHash ?? (() => {
@@ -42420,11 +42244,7 @@ var OpenPondManagedTrainingAdapter = class {
42420
42244
  async requestJson(pathname, init = {}, suppliedAccess) {
42421
42245
  const access5 = suppliedAccess ?? await this.resolveBoundAccess();
42422
42246
  const requestUrl = `${access5.apiBaseUrl}${pathname}`;
42423
- const headers = withVercelProtectionBypass(
42424
- requestUrl,
42425
- hostedApiAuthHeaders(access5.token),
42426
- this.dependencies.env
42427
- );
42247
+ const headers = hostedApiAuthHeaders(access5.token);
42428
42248
  headers.set("accept", "application/json");
42429
42249
  headers.set("x-openpond-team-id", access5.teamId);
42430
42250
  if (init.body) headers.set("content-type", "application/json");
@@ -42444,6 +42264,53 @@ var OpenPondManagedTrainingAdapter = class {
42444
42264
  }
42445
42265
  return access5;
42446
42266
  }
42267
+ trainingClient(access5) {
42268
+ const headers = hostedApiAuthHeaders(access5.token);
42269
+ headers.set("x-openpond-team-id", access5.teamId);
42270
+ return createTrainingClient({
42271
+ baseUrl: access5.apiBaseUrl,
42272
+ fetch: this.fetchImpl,
42273
+ headers
42274
+ });
42275
+ }
42276
+ async syncProjectForSubmission(project, access5) {
42277
+ const headers = hostedApiAuthHeaders(access5.token);
42278
+ headers.set("x-openpond-team-id", access5.teamId);
42279
+ const client = createModelProjectsClient({
42280
+ baseUrl: access5.apiBaseUrl,
42281
+ fetch: this.fetchImpl,
42282
+ headers
42283
+ });
42284
+ const hosted = await client.upsert({
42285
+ schemaVersion: "openpond.hostedModelProjectSync.v2",
42286
+ portableProjectId: project.id,
42287
+ name: project.name,
42288
+ objective: project.objective,
42289
+ defaultBaseModel: project.defaultBaseModel,
42290
+ defaultDestinationId: project.defaultDestinationId,
42291
+ trainingSetup: project.trainingSetup,
42292
+ sourceRevision: project.revision,
42293
+ sourceUpdatedAt: project.updatedAt,
42294
+ expectedEtag: project.hosted?.teamId === access5.teamId ? project.hosted.etag : null
42295
+ });
42296
+ const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
42297
+ const saved = ModelProjectSchema.parse({
42298
+ ...project,
42299
+ hosted: {
42300
+ schemaVersion: "openpond.hostedModelProjectLink.v1",
42301
+ teamId: access5.teamId,
42302
+ projectId: hosted.id,
42303
+ portableProjectId: hosted.portableProjectId,
42304
+ revision: hosted.revision,
42305
+ etag: hosted.etag,
42306
+ syncedSourceRevision: project.revision,
42307
+ syncedAt,
42308
+ tasksets: project.hosted?.teamId === access5.teamId ? project.hosted.tasksets : []
42309
+ }
42310
+ });
42311
+ await this.dependencies.store.saveModelProject(saved);
42312
+ return saved;
42313
+ }
42447
42314
  ensureLocalExecutor(ref, access5, harnessReleaseHash) {
42448
42315
  if (this.localExecutors.has(ref.runId)) return;
42449
42316
  if (!harnessReleaseHash) {
@@ -42468,46 +42335,6 @@ var OpenPondManagedTrainingAdapter = class {
42468
42335
  executor.start();
42469
42336
  }
42470
42337
  };
42471
- async function managedQualification(input) {
42472
- if (!input.qualificationRef) return null;
42473
- const lineage = input.taskset.metadata.harnessEvaluationLineage;
42474
- if (!lineage || typeof lineage !== "object" || Array.isArray(lineage)) return null;
42475
- const review = lineage.review;
42476
- if (!review || typeof review !== "object" || Array.isArray(review)) return null;
42477
- const workspaceId = review.workspaceId;
42478
- if (typeof workspaceId !== "string" || !workspaceId) return null;
42479
- const receipts = await input.store.listHarnessImprovementArtifacts(
42480
- workspaceId,
42481
- "training_qualification",
42482
- 1e3
42483
- );
42484
- return receipts.find(
42485
- (receipt) => receipt.id === input.qualificationRef.id && receipt.contentHash === input.qualificationRef.contentHash
42486
- ) ?? null;
42487
- }
42488
- function dateString(value) {
42489
- return new Date(value).toISOString();
42490
- }
42491
- function toExecutionStatus(job) {
42492
- const terminal = /* @__PURE__ */ new Set(["completed", "cancelled", "budget_exhausted", "failed"]);
42493
- const preparing = /* @__PURE__ */ new Set([
42494
- "draft",
42495
- "validating",
42496
- "admitted",
42497
- "provisioning_gpu",
42498
- "provisioning_rollouts"
42499
- ]);
42500
- const state = job.state === "completed" ? "succeeded" : job.state === "cancelled" ? "cancelled" : job.state === "failed" || job.state === "budget_exhausted" ? "failed" : job.state === "cancelling" ? "cancelling" : preparing.has(job.state) ? "preparing" : "running";
42501
- const progress2 = terminal.has(job.state) ? 1 : typeof job.completedGroups === "number" && typeof job.targetGroups === "number" && job.targetGroups > 0 ? job.completedGroups / job.targetGroups : null;
42502
- return {
42503
- runId: job.id,
42504
- state,
42505
- phase: job.state,
42506
- progress: progress2,
42507
- updatedAt: dateString(job.updatedAt),
42508
- errorCode: state === "failed" ? (job.terminalReason?.trim() || "managed_training_failed").replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 191) : null
42509
- };
42510
- }
42511
42338
 
42512
42339
  // ../server/src/training/managed-training-engine-registry.ts
42513
42340
  function createDestinationTrainingEngineRegistry(input) {
@@ -42527,7 +42354,6 @@ function createDestinationTrainingEngineRegistry(input) {
42527
42354
  };
42528
42355
  adapters2.createCalibrationBatch = (request) => managed.createCalibrationBatch(request);
42529
42356
  adapters2.calibrationBatch = (jobId) => managed.calibrationBatch(jobId);
42530
- adapters2.uploadRewardModelArtifact = (input2) => managed.uploadRewardModelArtifact(input2);
42531
42357
  adapters2.createRewardModelLaunch = (request) => managed.createRewardModelLaunch(request);
42532
42358
  adapters2.rewardModelJob = (jobId) => managed.rewardModelJob(jobId);
42533
42359
  adapters2.cancelRewardModelJob = (jobId, expectedVersion) => managed.cancelRewardModelJob(jobId, expectedVersion);
@@ -42536,6 +42362,7 @@ function createDestinationTrainingEngineRegistry(input) {
42536
42362
 
42537
42363
  // ../server/src/training/portable-model-run-service.ts
42538
42364
  import { mkdir as mkdir7, readFile as readFile12, writeFile as writeFile5 } from "node:fs/promises";
42365
+ import { randomUUID as randomUUID18 } from "node:crypto";
42539
42366
  import path49 from "node:path";
42540
42367
 
42541
42368
  // ../server/src/training/portable-model-run-artifacts.ts
@@ -42551,7 +42378,7 @@ async function importPortableModelRunArtifacts(input) {
42551
42378
  });
42552
42379
  if (provider === "sandbox") {
42553
42380
  const weights2 = artifacts.find((artifact) => artifact.metadata.managedRlCandidate === true);
42554
- if (!weights2 || artifacts.length !== 1) {
42381
+ if (!weights2 || artifacts.filter((artifact) => artifact.metadata.managedRlCandidate === true).length !== 1) {
42555
42382
  throw new Error(
42556
42383
  "Sandbox managed training completed without one canonical candidate receipt."
42557
42384
  );
@@ -42618,12 +42445,12 @@ async function persistPortableArtifacts(input) {
42618
42445
  const optimizerReceiptHash = input.portable.artifacts.find((artifact) => artifact.kind === "receipt")?.sha256 ?? input.portable.contentHash;
42619
42446
  const persisted = [];
42620
42447
  for (const portable of input.portable.artifacts) {
42621
- const managedCandidate = managedRlCandidateRef(portable.objectRef, input.executionRef.runId);
42622
- if (input.provider === "sandbox" && (!managedCandidate || portable.kind !== "adapter")) {
42623
- throw new Error("Sandbox managed training returned an invalid remote candidate receipt.");
42448
+ const managedOutput = managedRlOutputRef(portable.objectRef, input.executionRef.runId);
42449
+ if (input.provider === "sandbox" && !managedOutput) {
42450
+ throw new Error("Sandbox managed training returned an invalid remote output receipt.");
42624
42451
  }
42625
- const artifactPath2 = managedCandidate ? portable.objectRef : localArtifactPath(portable.objectRef);
42626
- if (!managedCandidate) {
42452
+ const artifactPath2 = managedOutput ? portable.objectRef : localArtifactPath(portable.objectRef);
42453
+ if (!managedOutput) {
42627
42454
  const info = await stat6(artifactPath2);
42628
42455
  if (!info.isFile() || info.size !== portable.sizeBytes) {
42629
42456
  throw new Error(`Portable artifact ${portable.objectRef} changed before import.`);
@@ -42640,7 +42467,7 @@ async function persistPortableArtifacts(input) {
42640
42467
  persisted.push(duplicate);
42641
42468
  continue;
42642
42469
  }
42643
- const providerFilename = managedCandidate ? "managed-rl-candidate" : portableFilenameFromRef(portable.objectRef);
42470
+ const providerFilename = managedOutput ? portable.kind === "adapter" ? "managed-rl-candidate" : `managed-rl-${portable.kind}` : portableFilenameFromRef(portable.objectRef);
42644
42471
  const isWeights = isAdapterWeights(providerFilename);
42645
42472
  const metadata = {
42646
42473
  provider: input.provider,
@@ -42648,14 +42475,14 @@ async function persistPortableArtifacts(input) {
42648
42475
  portableKind: portable.kind,
42649
42476
  manifestHash: input.portable.manifestHash,
42650
42477
  verified: true,
42651
- ...managedCandidate ? {
42652
- managedRlCandidate: true,
42653
- managedRlJobId: managedCandidate.jobId,
42654
- managedRlModelArtifactId: managedCandidate.modelArtifactId,
42478
+ ...managedOutput ? {
42479
+ managedRlCandidate: portable.kind === "adapter",
42480
+ managedRlJobId: managedOutput.jobId,
42481
+ managedRlOutputId: managedOutput.outputId,
42655
42482
  managedRlTeamId: input.executionRef.tenantId ?? null
42656
42483
  } : {}
42657
42484
  };
42658
- if (input.draft.method === "grpo" && isWeights) {
42485
+ if (input.source.method === "grpo" && isWeights) {
42659
42486
  metadata.groupedGrpoReceiptHash = optimizerReceiptHash;
42660
42487
  }
42661
42488
  const artifact = await input.store.saveTrainingArtifact(
@@ -42671,10 +42498,10 @@ async function persistPortableArtifacts(input) {
42671
42498
  path: artifactPath2,
42672
42499
  sha256: portable.sha256,
42673
42500
  sizeBytes: portable.sizeBytes,
42674
- baseModelId: input.draft.baseModel.modelId,
42675
- baseModelRevision: input.draft.baseModel.revision,
42676
- tokenizerRevision: input.draft.baseModel.tokenizerRevision,
42677
- chatTemplateHash: input.draft.baseModel.chatTemplateHash,
42501
+ baseModelId: input.source.baseModel.modelId,
42502
+ baseModelRevision: input.source.baseModel.revision,
42503
+ tokenizerRevision: input.source.baseModel.tokenizerRevision,
42504
+ chatTemplateHash: input.source.baseModel.chatTemplateHash,
42678
42505
  nonProduction: input.job.nonProduction,
42679
42506
  createdAt: input.completedAt,
42680
42507
  metadata
@@ -42691,13 +42518,13 @@ function localArtifactPath(objectRef2) {
42691
42518
  }
42692
42519
  return path47.resolve(objectRef2);
42693
42520
  }
42694
- function managedRlCandidateRef(objectRef2, expectedJobId) {
42521
+ function managedRlOutputRef(objectRef2, expectedJobId) {
42695
42522
  const match = objectRef2.match(/^sandbox-managed-rl:\/\/([^/]+)\/([^/?#]+)$/);
42696
42523
  if (!match) return null;
42697
42524
  try {
42698
42525
  const jobId = decodeURIComponent(match[1]);
42699
- const modelArtifactId = decodeURIComponent(match[2]);
42700
- return jobId === expectedJobId && modelArtifactId ? { jobId, modelArtifactId } : null;
42526
+ const outputId = decodeURIComponent(match[2]);
42527
+ return jobId === expectedJobId && outputId ? { jobId, outputId } : null;
42701
42528
  } catch {
42702
42529
  return null;
42703
42530
  }
@@ -42748,29 +42575,35 @@ function objectValue(value) {
42748
42575
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
42749
42576
  }
42750
42577
 
42578
+ // ../server/src/training/portable-model-run-terminal.ts
42579
+ function shouldCollectPortableTrainingArtifacts(state) {
42580
+ return state === "succeeded";
42581
+ }
42582
+
42751
42583
  // ../server/src/training/portable-model-run-lifecycle.ts
42752
42584
  import path48 from "node:path";
42753
42585
  async function preparePortableModelRunLifecycle(input) {
42754
- const baseModel = input.draft.baseModel;
42755
- const method = input.draft.method;
42756
- const destinationId = input.draft.destinationId;
42757
- if (!baseModel || !method || !destinationId || !input.draft.tasksetRef) {
42586
+ const setup = input.modelProject.trainingSetup;
42587
+ const baseModel = setup.baseModel;
42588
+ const method = setup.method;
42589
+ const destinationId = setup.destinationId;
42590
+ if (!baseModel || !method || !destinationId || !setup.tasksetRef) {
42758
42591
  throw new Error(
42759
42592
  "Portable Model Run lifecycle requires an exact saved run."
42760
42593
  );
42761
42594
  }
42762
- const existingRun = await input.store.getModelRun(input.draft.id);
42595
+ const existingRun = await input.store.getModelRun(input.modelRunId);
42763
42596
  if (existingRun) {
42764
42597
  throw new Error(
42765
- `Canonical Model Run ${input.draft.id} already exists with status ${existingRun.status}.`
42598
+ `Canonical Model Run ${input.modelRunId} already exists with status ${existingRun.status}.`
42766
42599
  );
42767
42600
  }
42768
42601
  const versions = await input.store.listModelVersions({
42769
- modelId: input.draft.modelId
42602
+ modelId: input.modelProject.id
42770
42603
  });
42771
42604
  const baseVersion = versions.find((version) => version.version === 0);
42772
42605
  if (baseVersion) {
42773
- if (baseVersion.kind !== "base_reference" || baseVersion.profileId !== input.draft.profileId || baseVersion.baseModel.modelId !== baseModel.modelId || baseVersion.baseModel.revision !== baseModel.revision || baseVersion.baseModel.tokenizerRevision !== baseModel.tokenizerRevision || baseVersion.baseModel.chatTemplateHash !== baseModel.chatTemplateHash) {
42606
+ if (baseVersion.kind !== "base_reference" || baseVersion.profileId !== input.modelProject.profileId || baseVersion.baseModel.modelId !== baseModel.modelId || baseVersion.baseModel.revision !== baseModel.revision || baseVersion.baseModel.tokenizerRevision !== baseModel.tokenizerRevision || baseVersion.baseModel.chatTemplateHash !== baseModel.chatTemplateHash) {
42774
42607
  throw new Error(
42775
42608
  "Existing base Model Version does not match this portable run."
42776
42609
  );
@@ -42778,14 +42611,14 @@ async function preparePortableModelRunLifecycle(input) {
42778
42611
  } else {
42779
42612
  const core = {
42780
42613
  schemaVersion: "openpond.modelVersion.v1",
42781
- id: modelVersionId(input.draft.modelId, 0),
42782
- modelId: input.draft.modelId,
42783
- profileId: input.draft.profileId,
42614
+ id: modelVersionId(input.modelProject.id, 0),
42615
+ modelId: input.modelProject.id,
42616
+ profileId: input.modelProject.profileId,
42784
42617
  version: 0,
42785
42618
  kind: "base_reference",
42786
42619
  status: "available",
42787
42620
  baseModel,
42788
- taskset: input.draft.tasksetRef,
42621
+ taskset: setup.tasksetRef,
42789
42622
  releaseGraph: input.releaseGraph,
42790
42623
  artifactLineageId: null,
42791
42624
  adapterStatus: "not_trained",
@@ -42799,7 +42632,7 @@ async function preparePortableModelRunLifecycle(input) {
42799
42632
  );
42800
42633
  }
42801
42634
  const modelRuns = await input.store.listModelRuns({
42802
- modelId: input.draft.modelId
42635
+ modelId: input.modelProject.id
42803
42636
  });
42804
42637
  const reservedIds = /* @__PURE__ */ new Set([
42805
42638
  ...versions.map((version) => version.id),
@@ -42807,26 +42640,26 @@ async function preparePortableModelRunLifecycle(input) {
42807
42640
  ]);
42808
42641
  let targetVersionNumber = 1;
42809
42642
  while (reservedIds.has(
42810
- modelVersionId(input.draft.modelId, targetVersionNumber)
42643
+ modelVersionId(input.modelProject.id, targetVersionNumber)
42811
42644
  )) {
42812
42645
  targetVersionNumber += 1;
42813
42646
  }
42814
42647
  const targetVersion = {
42815
- id: modelVersionId(input.draft.modelId, targetVersionNumber),
42648
+ id: modelVersionId(input.modelProject.id, targetVersionNumber),
42816
42649
  version: targetVersionNumber
42817
42650
  };
42818
42651
  const modelRun = await input.store.saveModelRun(
42819
42652
  ModelRunSchema.parse({
42820
42653
  schemaVersion: "openpond.modelRun.v1",
42821
- id: input.draft.id,
42822
- modelId: input.draft.modelId,
42654
+ id: input.modelRunId,
42655
+ modelId: input.modelProject.id,
42823
42656
  modelVersionId: targetVersion.id,
42824
- profileId: input.draft.profileId,
42657
+ profileId: input.modelProject.profileId,
42825
42658
  kind: "training",
42826
42659
  status: "prepared",
42827
42660
  method,
42828
42661
  destinationId,
42829
- taskset: input.draft.tasksetRef,
42662
+ taskset: setup.tasksetRef,
42830
42663
  harnessRelease: input.releaseGraph.harnessRelease,
42831
42664
  quote: {
42832
42665
  maximumSpendUsd: input.maximumSpendUsd ?? 0,
@@ -42841,7 +42674,18 @@ async function preparePortableModelRunLifecycle(input) {
42841
42674
  updatedAt: input.startedAt
42842
42675
  })
42843
42676
  );
42844
- return { modelRun, targetVersion };
42677
+ const sourceSnapshot = TrainingJobSourceSnapshotSchema.parse({
42678
+ schemaVersion: "openpond.trainingJobSourceSnapshot.v1",
42679
+ modelProjectId: input.modelProject.id,
42680
+ sourceProjectRevision: input.sourceProjectRevision,
42681
+ profileId: input.modelProject.profileId,
42682
+ taskset: setup.tasksetRef,
42683
+ tasksetRelease: setup.tasksetRelease,
42684
+ harnessRelease: setup.harnessRelease,
42685
+ baseModel,
42686
+ method
42687
+ });
42688
+ return { modelRun, targetVersion, sourceSnapshot };
42845
42689
  }
42846
42690
  async function markPortableModelRunRunning(input) {
42847
42691
  const modelRun = await requiredModelRun(input.store, input.modelRunId);
@@ -42907,16 +42751,6 @@ async function reconcilePortableModelRunLifecycle(input) {
42907
42751
  completedAt: completedAt2,
42908
42752
  error: failure
42909
42753
  });
42910
- if (input.status.state === "cancelled") {
42911
- const draft2 = await input.store.getModelRunDraft(input.modelRunId);
42912
- if (draft2) {
42913
- await input.store.saveModelRunDraft({
42914
- ...draft2,
42915
- status: "cancelled",
42916
- updatedAt: completedAt2
42917
- });
42918
- }
42919
- }
42920
42754
  return terminal2;
42921
42755
  }
42922
42756
  if (!input.artifacts) {
@@ -42924,17 +42758,17 @@ async function reconcilePortableModelRunLifecycle(input) {
42924
42758
  "Successful portable training requires collected artifacts."
42925
42759
  );
42926
42760
  }
42927
- const [draft, plan] = await Promise.all([
42928
- input.store.getModelRunDraft(input.modelRunId),
42761
+ const [source, plan] = await Promise.all([
42762
+ resolveTrainingJobSourceSnapshot(input.store, input.job, input.modelRunId),
42929
42763
  input.store.getTrainingPlan(input.job.planId)
42930
42764
  ]);
42931
- if (!draft || !draft.baseModel || !draft.tasksetRef || !plan) {
42765
+ if (!plan) {
42932
42766
  throw new Error(
42933
42767
  "Portable training lineage disappeared before artifact import."
42934
42768
  );
42935
42769
  }
42936
- const taskset = await input.store.getTaskset(draft.tasksetRef.id);
42937
- if (!taskset || taskset.contentHash !== draft.tasksetRef.contentHash) {
42770
+ const taskset = await input.store.getTaskset(source.taskset.id);
42771
+ if (!taskset || taskset.contentHash !== source.taskset.contentHash) {
42938
42772
  throw new Error(
42939
42773
  "Portable training Taskset changed before artifact import."
42940
42774
  );
@@ -42943,7 +42777,7 @@ async function reconcilePortableModelRunLifecycle(input) {
42943
42777
  const imported = await importPortableModelRunArtifacts({
42944
42778
  store: input.store,
42945
42779
  job: input.job,
42946
- draft: { ...draft, baseModel: draft.baseModel },
42780
+ source,
42947
42781
  executionRef: input.executionRef,
42948
42782
  completedAt,
42949
42783
  portable: input.artifacts
@@ -42958,11 +42792,11 @@ async function reconcilePortableModelRunLifecycle(input) {
42958
42792
  ModelArtifactLineageSchema.parse({
42959
42793
  schemaVersion: "openpond.modelArtifactLineage.v1",
42960
42794
  id: `model_lineage_${contentHash([
42961
- draft.modelId,
42795
+ source.modelProjectId,
42962
42796
  weights.sha256,
42963
42797
  plan.contentHash
42964
42798
  ]).slice(0, 24)}`,
42965
- modelId: draft.modelId,
42799
+ modelId: source.modelProjectId,
42966
42800
  artifactId: weights.id,
42967
42801
  jobId: input.job.id,
42968
42802
  tasksetId: taskset.id,
@@ -42994,13 +42828,13 @@ async function reconcilePortableModelRunLifecycle(input) {
42994
42828
  const versionCore = {
42995
42829
  schemaVersion: "openpond.modelVersion.v1",
42996
42830
  id: reservation.id,
42997
- modelId: draft.modelId,
42998
- profileId: draft.profileId,
42831
+ modelId: source.modelProjectId,
42832
+ profileId: source.profileId,
42999
42833
  version: reservation.version,
43000
42834
  kind: "lora_adapter",
43001
42835
  status: "available",
43002
- baseModel: draft.baseModel,
43003
- taskset: draft.tasksetRef,
42836
+ baseModel: source.baseModel,
42837
+ taskset: source.taskset,
43004
42838
  releaseGraph,
43005
42839
  artifactLineageId: lineage.id,
43006
42840
  adapterStatus: "trained",
@@ -43094,6 +42928,15 @@ async function requiredModelRun(store, id) {
43094
42928
  }
43095
42929
  return modelRun;
43096
42930
  }
42931
+ async function resolveTrainingJobSourceSnapshot(store, job, modelRunId) {
42932
+ const current = TrainingJobSourceSnapshotSchema.safeParse(
42933
+ job.metadata.sourceSnapshot
42934
+ );
42935
+ if (current.success) return current.data;
42936
+ void store;
42937
+ void modelRunId;
42938
+ throw new Error("Training Job source snapshot is missing or invalid.");
42939
+ }
43097
42940
  function engineMetadata(job, key, fallback) {
43098
42941
  const bindings = objectValue2(job.metadata.portableAdapterBindings);
43099
42942
  const engine = objectValue2(bindings.engine);
@@ -43345,10 +43188,10 @@ function trainingTargets(input) {
43345
43188
  }
43346
43189
  function preparePortableModelRun(input) {
43347
43190
  const model = input.catalog.models.find(
43348
- (candidate2) => candidate2.modelId === input.modelRun.baseModel?.modelId && candidate2.revision === input.modelRun.baseModel?.revision
43191
+ (candidate2) => candidate2.modelId === input.modelProject.trainingSetup.baseModel?.modelId && candidate2.revision === input.modelProject.trainingSetup.baseModel?.revision
43349
43192
  );
43350
43193
  const bindings = resolvePortableBindings({
43351
- modelRun: input.modelRun,
43194
+ modelProject: input.modelProject,
43352
43195
  catalog: input.catalog
43353
43196
  });
43354
43197
  const engine = bindings.engine ? input.catalog.engines.find(
@@ -43358,7 +43201,7 @@ function preparePortableModelRun(input) {
43358
43201
  (candidate2) => candidate2.adapterId === bindings.compute.adapterId
43359
43202
  ) ?? null : null;
43360
43203
  return prepareTrainingSelection({
43361
- modelRunId: input.modelRun.id,
43204
+ modelRunId: input.modelRunId ?? input.modelProject.id,
43362
43205
  modelCached: model?.cached ?? false,
43363
43206
  modelBytes: model?.expectedBytes ?? 0,
43364
43207
  engine,
@@ -43367,15 +43210,16 @@ function preparePortableModelRun(input) {
43367
43210
  maximumSpendUsd: input.maximumSpendUsd ?? null,
43368
43211
  quoteUsd: input.quoteUsd ?? null,
43369
43212
  retentionDays: input.retentionDays ?? null,
43370
- providerManaged: input.modelRun.destinationId === "openpond_managed"
43213
+ providerManaged: input.modelProject.trainingSetup.destinationId === "openpond_managed"
43371
43214
  });
43372
43215
  }
43373
43216
  function resolvePortableBindings(input) {
43374
- const destinationId = input.modelRun.destinationId;
43217
+ const setup = input.modelProject.trainingSetup;
43218
+ const destinationId = setup.destinationId;
43375
43219
  if (!destinationId) return { runtime: null, compute: null, engine: null };
43376
43220
  const computeId = computeIdForDestination(destinationId);
43377
43221
  const engineId = engineIdForDestination(destinationId);
43378
- const runtimeId = destinationId === "openpond_managed" ? input.environmentPlacement === "remote" || input.environmentPlacement === void 0 && input.modelRun.managedRolloutPlacement === "remote" ? "openpond-managed-harness" : "local-harness" : "local-harness";
43222
+ const runtimeId = destinationId === "openpond_managed" ? input.environmentPlacement === "remote" || input.environmentPlacement === void 0 && setup.managedRolloutPlacement === "remote" ? "openpond-managed-harness" : "local-harness" : "local-harness";
43379
43223
  const compute = input.catalog.compute.find((candidate2) => candidate2.adapterId === computeId);
43380
43224
  const engine = input.catalog.engines.find((candidate2) => candidate2.adapterId === engineId);
43381
43225
  const runtime = input.catalog.runtimes.find((candidate2) => candidate2.adapterId === runtimeId);
@@ -43514,29 +43358,36 @@ function createPortableModelRunService(deps) {
43514
43358
  let reconciliationInFlight = null;
43515
43359
  let lastReconciledAt = 0;
43516
43360
  async function start(input) {
43517
- const loadedModelRun = await deps.store.getModelRunDraft(input.modelRunId);
43518
- if (!loadedModelRun || loadedModelRun.status !== "ready_to_run") {
43519
- throw new Error("A ready saved Model Run is required.");
43520
- }
43521
- let modelRun = loadedModelRun;
43522
- if (!modelRun.tasksetRef || !modelRun.baseModel || !modelRun.recipe || !modelRun.destinationId) {
43523
- throw new Error("The saved Model Run is incomplete.");
43524
- }
43525
- const baseModel = modelRun.baseModel;
43526
- const tasksetRef = modelRun.tasksetRef;
43527
- const taskset = await deps.store.getTaskset(modelRun.tasksetRef.id);
43528
- if (!taskset || taskset.contentHash !== modelRun.tasksetRef.contentHash) {
43529
- throw new Error("The saved Model Run Taskset release is stale.");
43530
- }
43531
- const releasedHarness2 = await deps.resolveReleasedHarness({ taskset, modelRun });
43532
- modelRun = await deps.store.saveModelRunDraft({
43533
- ...modelRun,
43534
- harnessRelease: releasedHarness2.harnessRelease,
43535
- tasksetRelease: releasedHarness2.tasksetRelease,
43361
+ let sourceProject = await deps.store.getModelProject(input.modelProjectId);
43362
+ if (!sourceProject) throw new Error("A saved Model Project is required.");
43363
+ let setup = sourceProject.trainingSetup;
43364
+ if (!setup.tasksetRef || !setup.baseModel || !setup.recipe || !setup.destinationId) {
43365
+ throw new Error("The Model Project training setup is incomplete.");
43366
+ }
43367
+ const baseModel = setup.baseModel;
43368
+ const tasksetRef = setup.tasksetRef;
43369
+ const taskset = await deps.store.getTaskset(setup.tasksetRef.id);
43370
+ if (!taskset || taskset.contentHash !== setup.tasksetRef.contentHash) {
43371
+ throw new Error("The Model Project Taskset release is stale.");
43372
+ }
43373
+ const releasedHarness2 = await deps.resolveReleasedHarness({
43374
+ taskset,
43375
+ modelProject: sourceProject
43376
+ });
43377
+ sourceProject = await deps.store.saveModelProject({
43378
+ ...sourceProject,
43379
+ revision: sourceProject.revision + 1,
43380
+ trainingSetup: {
43381
+ ...setup,
43382
+ harnessRelease: releasedHarness2.harnessRelease,
43383
+ tasksetRelease: releasedHarness2.tasksetRelease
43384
+ },
43536
43385
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
43537
43386
  });
43387
+ setup = sourceProject.trainingSetup;
43388
+ const recipe = TrainingRecipeSchema.parse(setup.recipe);
43538
43389
  const preparation = await deps.prepare({
43539
- modelRunId: modelRun.id,
43390
+ modelProjectId: sourceProject.id,
43540
43391
  maximumSpendUsd: input.maximumSpendUsd,
43541
43392
  retentionDays: input.retentionDays
43542
43393
  });
@@ -43553,11 +43404,11 @@ function createPortableModelRunService(deps) {
43553
43404
  });
43554
43405
  }
43555
43406
  const prepared = await deps.prepareStart({
43556
- modelId: modelRun.modelId,
43407
+ modelId: sourceProject.id,
43557
43408
  tasksetId: tasksetRef.id,
43558
- destinationId: modelRun.destinationId,
43559
- recipe: modelRun.recipe,
43560
- environmentPlacement: modelRun.destinationId === "openpond_managed" ? modelRun.managedRolloutPlacement ?? "local" : void 0,
43409
+ destinationId: setup.destinationId,
43410
+ recipe,
43411
+ environmentPlacement: setup.destinationId === "openpond_managed" ? setup.managedRolloutPlacement : void 0,
43561
43412
  exportApproved: input.exportApproved,
43562
43413
  retentionDays: input.retentionDays,
43563
43414
  harnessRelease: releasedHarness2.harnessRelease
@@ -43568,16 +43419,18 @@ function createPortableModelRunService(deps) {
43568
43419
  maximumCostUsd: input.maximumSpendUsd
43569
43420
  });
43570
43421
  const bindings = resolvePortableBindings({
43571
- modelRun,
43422
+ modelProject: sourceProject,
43572
43423
  catalog: await deps.catalog(),
43573
43424
  environmentPlacement: prepared.plan.environmentPlacement
43574
43425
  });
43575
43426
  if (!bindings.runtime || !bindings.compute || !bindings.engine) {
43576
- throw new Error("The saved Model Run has no complete portable adapter binding.");
43427
+ throw new Error("The Model Project has no complete portable adapter binding.");
43577
43428
  }
43429
+ const modelRunId = `model_run_${randomUUID18()}`;
43578
43430
  const graph = buildTasksetTrainingBundle({
43579
43431
  taskset,
43580
- modelRun,
43432
+ modelProject: sourceProject,
43433
+ modelRunId,
43581
43434
  runtime: bindings.runtime,
43582
43435
  compute: bindings.compute,
43583
43436
  engine: bindings.engine,
@@ -43594,7 +43447,7 @@ function createPortableModelRunService(deps) {
43594
43447
  const resolvedPlanBase = {
43595
43448
  schemaVersion: "openpond.resolvedTrainingPlan.v1",
43596
43449
  manifest: graph.manifest,
43597
- recipe: modelRun.recipe,
43450
+ recipe,
43598
43451
  runtime: bindings.runtime,
43599
43452
  compute: bindings.compute,
43600
43453
  engine: bindings.engine,
@@ -43638,8 +43491,10 @@ function createPortableModelRunService(deps) {
43638
43491
  });
43639
43492
  const lifecycle = await preparePortableModelRunLifecycle({
43640
43493
  store: deps.store,
43641
- draft: modelRun,
43494
+ modelProject: sourceProject,
43495
+ modelRunId,
43642
43496
  taskset,
43497
+ sourceProjectRevision: sourceProject.revision,
43643
43498
  releaseGraph: portableReleaseGraph2,
43644
43499
  maximumSpendUsd: approval.maximumCostUsd,
43645
43500
  startedAt: approval.approvedAt
@@ -43650,7 +43505,7 @@ function createPortableModelRunService(deps) {
43650
43505
  } catch (error) {
43651
43506
  await failPreparedPortableModelRun({
43652
43507
  store: deps.store,
43653
- modelRunId: modelRun.id,
43508
+ modelRunId,
43654
43509
  error
43655
43510
  });
43656
43511
  throw error;
@@ -43661,7 +43516,7 @@ function createPortableModelRunService(deps) {
43661
43516
  planId: prepared.plan.id,
43662
43517
  bundleHash: prepared.bundle.contentHash,
43663
43518
  approvalId: approval.id,
43664
- destinationId: modelRun.destinationId,
43519
+ destinationId: setup.destinationId,
43665
43520
  status: "queued",
43666
43521
  nonProduction: false,
43667
43522
  workerPid: null,
@@ -43676,7 +43531,8 @@ function createPortableModelRunService(deps) {
43676
43531
  ...launched,
43677
43532
  metadata: {
43678
43533
  ...launched.metadata,
43679
- modelRunId: modelRun.id,
43534
+ modelRunId,
43535
+ modelProjectId: sourceProject.id,
43680
43536
  harnessRunManifestId: graph.manifest.id,
43681
43537
  harnessRunManifestHash: graph.manifest.contentHash,
43682
43538
  harnessReleaseHash: graph.harnessRelease.contentHash,
@@ -43688,19 +43544,15 @@ function createPortableModelRunService(deps) {
43688
43544
  portableExecutionRef: executionRef2,
43689
43545
  portableValidationReceipt: validation,
43690
43546
  portableModelVersion: portableModelVersionMetadata(lifecycle.targetVersion),
43691
- portableReleaseGraph: portableReleaseGraph2
43547
+ portableReleaseGraph: portableReleaseGraph2,
43548
+ sourceSnapshot: lifecycle.sourceSnapshot
43692
43549
  }
43693
43550
  });
43694
43551
  await markPortableModelRunRunning({
43695
43552
  store: deps.store,
43696
- modelRunId: modelRun.id,
43553
+ modelRunId,
43697
43554
  startedAt: executionRef2.createdAt
43698
43555
  });
43699
- await deps.store.saveModelRunDraft({
43700
- ...modelRun,
43701
- status: "launched",
43702
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
43703
- });
43704
43556
  return {
43705
43557
  preparation,
43706
43558
  manifest: graph.manifest,
@@ -43789,6 +43641,18 @@ function createPortableModelRunService(deps) {
43789
43641
  });
43790
43642
  return executionStatus;
43791
43643
  }
43644
+ if (!shouldCollectPortableTrainingArtifacts(executionStatus.state)) {
43645
+ const modelRun2 = await reconcilePortableModelRunLifecycle({
43646
+ store: deps.store,
43647
+ storeDir: deps.storeDir,
43648
+ modelRunId,
43649
+ job,
43650
+ executionRef: parsed.data,
43651
+ status: executionStatus,
43652
+ failure: executionStatus.errorCode
43653
+ });
43654
+ return portableStatusFromModelRun(modelRun2);
43655
+ }
43792
43656
  let artifacts2 = null;
43793
43657
  try {
43794
43658
  artifacts2 = await adapter.collect(parsed.data);
@@ -44004,15 +43868,15 @@ function createPortableTrainingServiceSupport(input) {
44004
43868
  });
44005
43869
  }
44006
43870
  async function prepare(inputPlan) {
44007
- const modelRun = await input.store.getModelRunDraft(
44008
- inputPlan.modelRunId
43871
+ const modelProject = await input.store.getModelProject(
43872
+ inputPlan.modelProjectId
44009
43873
  );
44010
- if (!modelRun || modelRun.status !== "ready_to_run") {
44011
- throw new Error("A ready saved Model Run is required.");
43874
+ if (!modelProject) {
43875
+ throw new Error("A saved Model Project is required.");
44012
43876
  }
44013
43877
  const trainingCatalog = await catalog();
44014
43878
  return preparePortableModelRun({
44015
- modelRun,
43879
+ modelProject,
44016
43880
  catalog: trainingCatalog,
44017
43881
  maximumSpendUsd: inputPlan.maximumSpendUsd,
44018
43882
  retentionDays: inputPlan.retentionDays
@@ -44733,7 +44597,7 @@ function managedRewardModelIdempotencyKey(input) {
44733
44597
  }
44734
44598
  async function buildManagedRewardModelLaunchInput(input) {
44735
44599
  if (input.recipe.tasksetRelease.id !== input.tasksetRelease.id || input.recipe.tasksetRelease.contentHash !== input.tasksetRelease.contentHash || input.dataset.tasksetRelease.id !== input.tasksetRelease.id || input.dataset.tasksetRelease.contentHash !== input.tasksetRelease.contentHash) {
44736
- throw new Error("Reward Model launch must use the exact Taskset release pinned by D0 and the recipe.");
44600
+ throw new Error("Reward Model launch must use the exact Taskset release pinned by the preference dataset and the recipe.");
44737
44601
  }
44738
44602
  if (input.recipe.preferenceDatasetRelease.id !== input.dataset.id || input.recipe.preferenceDatasetRelease.contentHash !== input.dataset.contentHash) {
44739
44603
  throw new Error("Reward Model recipe must pin the materialized preference dataset.");
@@ -44786,7 +44650,7 @@ async function buildManagedRewardModelLaunchInput(input) {
44786
44650
  })
44787
44651
  );
44788
44652
  if (!groups.some((group) => group.partition === "reward_train") || !groups.some((group) => group.partition === "reward_validation")) {
44789
- throw new Error("Reward Model launch requires D0 train and validation groups.");
44653
+ throw new Error("Reward Model launch requires preference-dataset train and validation groups.");
44790
44654
  }
44791
44655
  const content = {
44792
44656
  schemaVersion: "openpond.managedRlRewardModelLaunchRequest.v1",
@@ -44945,6 +44809,7 @@ function projectQualifiedRewardModel(input) {
44945
44809
  bucketHead: version.artifacts.bucketHead,
44946
44810
  processorRelease: version.artifacts.processorRelease,
44947
44811
  optimizerEvidence: ref(optimizer),
44812
+ managedExecutionReceipt: input.managedExecutionReceipt,
44948
44813
  parameterDeltaHash: contentHash({ before: input.evidence.parameterHashBefore, after: input.evidence.parameterHashAfter }),
44949
44814
  cleanup: input.cleanup
44950
44815
  };
@@ -45049,7 +44914,7 @@ function bindLearnedPreferenceReward(input) {
45049
44914
  runtime: input.version.runtime,
45050
44915
  processorRelease: input.version.artifacts.processorRelease,
45051
44916
  rewardComposerRelease: input.rewardComposerRelease,
45052
- qualificationKind: report.kind
44917
+ executionReceipt: input.executionReceipt
45053
44918
  });
45054
44919
  }
45055
44920
 
@@ -45196,7 +45061,7 @@ function createTrainingService(deps) {
45196
45061
  prepare: prepareModelRun,
45197
45062
  prepareStart,
45198
45063
  approve,
45199
- resolveReleasedHarness: async ({ taskset, modelRun }) => {
45064
+ resolveReleasedHarness: async ({ taskset, modelProject }) => {
45200
45065
  const releasedHarness2 = await deps.resolveReleasedHarness?.() ?? null;
45201
45066
  const profile = !releasedHarness2 && deps.loadProfileState ? await deps.loadProfileState() : null;
45202
45067
  const context = compileDesktopHarnessContext({
@@ -45205,7 +45070,7 @@ function createTrainingService(deps) {
45205
45070
  releasedHarness: releasedHarness2,
45206
45071
  model: {
45207
45072
  providerId: "openpond",
45208
- modelId: modelRun.baseModel.modelId
45073
+ modelId: modelProject.trainingSetup.baseModel.modelId
45209
45074
  }
45210
45075
  });
45211
45076
  if (profile?.sourcePath) {
@@ -45230,10 +45095,10 @@ function createTrainingService(deps) {
45230
45095
  void portableModelRuns.reconcileActive({ force: true });
45231
45096
  async function launchRewardModel(input) {
45232
45097
  if (input.recipe.tasksetRelease.id !== input.dataset.tasksetRelease.id || input.recipe.tasksetRelease.contentHash !== input.dataset.tasksetRelease.contentHash) {
45233
- throw new Error("Reward Model recipe and D0 must pin the same Taskset release.");
45098
+ throw new Error("Reward Model recipe and preference dataset must pin the same Taskset release.");
45234
45099
  }
45235
45100
  if (input.tasksetRelease.id !== input.dataset.tasksetRelease.id || input.tasksetRelease.contentHash !== input.dataset.tasksetRelease.contentHash) {
45236
- throw new Error("Reward Model Run must use the exact Taskset release pinned by D0.");
45101
+ throw new Error("Reward Model Run must use the exact Taskset release pinned by the preference dataset.");
45237
45102
  }
45238
45103
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
45239
45104
  const recipeHash = contentHash(input.recipe);
@@ -45293,7 +45158,13 @@ function createTrainingService(deps) {
45293
45158
  managedBaseModel: input.managedBaseModel,
45294
45159
  attempts
45295
45160
  });
45296
- const launched = await portableAdapters.createRewardModelLaunch(request);
45161
+ const launched = await portableAdapters.createRewardModelLaunch({
45162
+ request,
45163
+ modelProjectId: input.modelProject.id,
45164
+ processorRelease: input.recipe.processorRelease,
45165
+ recipe: input.recipe,
45166
+ approvedAt: prepared.startedAt
45167
+ });
45297
45168
  return deps.store.saveRewardModelRun({
45298
45169
  ...prepared,
45299
45170
  status: "running",
@@ -45301,11 +45172,12 @@ function createTrainingService(deps) {
45301
45172
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
45302
45173
  });
45303
45174
  } catch (error) {
45175
+ const failure = error instanceof OpenPondTrainingApiError ? `${error.message} (${error.code})` : error instanceof Error ? error.message : "Reward Model launch failed.";
45304
45176
  return deps.store.saveRewardModelRun({
45305
45177
  ...prepared,
45306
45178
  status: "failed",
45307
45179
  failureOwner: "authoring",
45308
- failure: error instanceof Error ? error.message : "Reward Model launch failed.",
45180
+ failure,
45309
45181
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
45310
45182
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
45311
45183
  });
@@ -45317,7 +45189,7 @@ function createTrainingService(deps) {
45317
45189
  throw new Error("Reward Model Version was not found for this Taskset.");
45318
45190
  }
45319
45191
  const run = (await deps.store.listRewardModelRuns({ tasksetId: input.tasksetId })).find((candidate2) => candidate2.rewardModelVersionId === version.id && candidate2.status === "succeeded");
45320
- if (!run?.qualificationReport) {
45192
+ if (!run?.qualificationReport || !run.receipt?.managedExecutionReceipt) {
45321
45193
  throw new Error("Reward Model Version has no immutable qualification report.");
45322
45194
  }
45323
45195
  const report = await loadRewardModelQualificationReport({
@@ -45341,7 +45213,8 @@ function createTrainingService(deps) {
45341
45213
  rewardComposerRelease: {
45342
45214
  id: `reward-composer:${rewardComposerHash.slice(0, 24)}`,
45343
45215
  contentHash: rewardComposerHash
45344
- }
45216
+ },
45217
+ executionReceipt: run.receipt.managedExecutionReceipt
45345
45218
  });
45346
45219
  }
45347
45220
  async function retryRewardModelQualification(runId, retryRunId) {
@@ -45404,7 +45277,8 @@ function createTrainingService(deps) {
45404
45277
  const upload = remote.resources.find(
45405
45278
  (resource) => resource.kind === "artifact_upload" && resource.state === "consumed"
45406
45279
  );
45407
- const evidence = upload?.metadata.evidence;
45280
+ const uploadMetadata = recordOrNull(upload?.metadata);
45281
+ const evidence = uploadMetadata?.evidence;
45408
45282
  const evidenceRecord = evidence && typeof evidence === "object" && !Array.isArray(evidence) ? evidence : null;
45409
45283
  const completedSteps = typeof evidenceRecord?.steps === "number" && Number.isInteger(evidenceRecord.steps) ? evidenceRecord.steps : run.progress.completedSteps;
45410
45284
  const latestLoss = typeof evidenceRecord?.loss === "number" && Number.isFinite(evidenceRecord.loss) ? evidenceRecord.loss : run.progress.latestLoss;
@@ -45428,17 +45302,15 @@ function createTrainingService(deps) {
45428
45302
  }
45429
45303
  if (remote.job.state === "completed") {
45430
45304
  try {
45431
- const resourceMetadata = upload?.metadata;
45305
+ const resourceMetadata = uploadMetadata;
45432
45306
  const inventory = Array.isArray(resourceMetadata?.inventory) ? resourceMetadata.inventory.filter(isInventoryFile) : [];
45433
45307
  const checkpointPrefix = typeof resourceMetadata?.objectPrefix === "string" ? resourceMetadata.objectPrefix : "";
45434
45308
  const artifactSha256 = typeof resourceMetadata?.artifactSha256 === "string" ? resourceMetadata.artifactSha256 : "";
45435
- const inputBundle = remote.job.inputBundle;
45436
- const rewardTraining = recordOrNull(inputBundle?.rewardModelTraining);
45437
- const rewardBase = recordOrNull(rewardTraining?.baseModel);
45438
- const rewardProcessor = recordOrNull(rewardTraining?.processor);
45439
- const harness = recordOrNull(inputBundle?.harnessRunManifest);
45309
+ const rewardBase = recordOrNull(resourceMetadata?.baseModel);
45310
+ const rewardProcessor = recordOrNull(resourceMetadata?.processor);
45311
+ const harness = recordOrNull(resourceMetadata?.harnessRunManifest);
45440
45312
  const taskset = await deps.store.getTaskset(run.taskset.id);
45441
- if (!taskset || !rewardBase || !rewardProcessor || !harness || !checkpointPrefix || !artifactSha256) {
45313
+ if (!taskset || !rewardBase || !rewardProcessor || !harness || !checkpointPrefix || !artifactSha256 || !remote.executionReceiptRef) {
45442
45314
  throw new Error("Completed managed Reward Model job is missing immutable launch lineage.");
45443
45315
  }
45444
45316
  const versionNumber = nextRewardModelVersionNumber(
@@ -45471,6 +45343,7 @@ function createTrainingService(deps) {
45471
45343
  computeReleased: remote.resources.every((resource) => resource.state !== "active"),
45472
45344
  providerTerminalObserved: remote.job.cleanupAttestation !== null && remote.job.cleanupAttestation !== void 0
45473
45345
  },
45346
+ managedExecutionReceipt: remote.executionReceiptRef,
45474
45347
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
45475
45348
  });
45476
45349
  await saveRewardModelQualificationReport({
@@ -45707,12 +45580,13 @@ function createModelProjectHostingService(input) {
45707
45580
  const project = await requireProject(input.store, projectId);
45708
45581
  const access5 = await input.resolveAccess();
45709
45582
  const syncBody = {
45710
- schemaVersion: "openpond.hostedModelProjectSync.v1",
45583
+ schemaVersion: "openpond.hostedModelProjectSync.v2",
45711
45584
  portableProjectId: project.id,
45712
45585
  name: project.name,
45713
45586
  objective: project.objective,
45714
45587
  defaultBaseModel: project.defaultBaseModel,
45715
45588
  defaultDestinationId: project.defaultDestinationId,
45589
+ trainingSetup: project.trainingSetup,
45716
45590
  sourceRevision: project.revision,
45717
45591
  sourceUpdatedAt: project.updatedAt
45718
45592
  };
@@ -45860,15 +45734,15 @@ function createModelProjectHostingService(input) {
45860
45734
  }
45861
45735
  async function requestJson2(request) {
45862
45736
  const url = `${request.access.apiBaseUrl}${request.pathname}`;
45863
- const headers = withVercelProtectionBypass(
45864
- url,
45865
- hostedApiAuthHeaders(request.access.token),
45866
- input.env ?? process.env
45737
+ const headers = hostedApiAuthHeaders(request.access.token);
45738
+ const isModelProjectRequest = request.pathname.startsWith("/v1/model-projects/");
45739
+ headers.set(
45740
+ "accept",
45741
+ isModelProjectRequest ? OPENPOND_MODEL_PROJECT_MEDIA_TYPE : "application/json"
45867
45742
  );
45868
- headers.set("accept", "application/json");
45869
45743
  headers.set(
45870
45744
  "content-type",
45871
- request.gzip ? PORTABLE_TASKSET_PUBLICATION_CONTENT_TYPE : "application/json"
45745
+ request.gzip ? PORTABLE_TASKSET_PUBLICATION_CONTENT_TYPE : isModelProjectRequest ? OPENPOND_MODEL_PROJECT_MEDIA_TYPE : "application/json"
45872
45746
  );
45873
45747
  headers.set("x-openpond-team-id", request.access.teamId);
45874
45748
  const response = await fetchImpl(url, {
@@ -45880,7 +45754,7 @@ function createModelProjectHostingService(input) {
45880
45754
  if (!response.ok) {
45881
45755
  const endpoint = new URL(url);
45882
45756
  throw new Error(
45883
- `${typeof payload.error === "string" ? payload.error : "Hosted Model Project request failed"} (${response.status} ${endpoint.origin}${endpoint.pathname}).`
45757
+ `${typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : "Hosted Model Project request failed"} (${response.status} ${endpoint.origin}${endpoint.pathname}).`
45884
45758
  );
45885
45759
  }
45886
45760
  return payload;
@@ -46278,10 +46152,10 @@ async function materializeSyntheticCollectionRun(input) {
46278
46152
  }
46279
46153
 
46280
46154
  // ../server/src/training/model-create-improve.ts
46281
- import { randomUUID as randomUUID18 } from "node:crypto";
46155
+ import { randomUUID as randomUUID19 } from "node:crypto";
46282
46156
  function createTasksetAuthoringCreateImproveRun(input) {
46283
46157
  const timestamp = input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
46284
- const id = `create_improve_${randomUUID18()}`;
46158
+ const id = `create_improve_${randomUUID19()}`;
46285
46159
  const evidenceSnapshot = createEvidenceSnapshot({
46286
46160
  objective: input.objective?.trim() || (input.resourceIntent === "dataset" ? "Create a Dataset from selected sources." : "Create a model from selected evidence."),
46287
46161
  sources: input.sources ?? [],
@@ -46387,7 +46261,7 @@ function createExistingTasksetModelCreateImproveRun(input) {
46387
46261
  sources: input.taskset.sourceRefs.filter(isTrainingSourceRef),
46388
46262
  targetIntent: {
46389
46263
  kind: "model",
46390
- id: input.modelId ?? `model_${randomUUID18()}`,
46264
+ id: input.modelId ?? `model_${randomUUID19()}`,
46391
46265
  displayName: input.taskset.name,
46392
46266
  operation: "create"
46393
46267
  },
@@ -46436,7 +46310,7 @@ function createExistingTasksetModelCreateImproveRun(input) {
46436
46310
  }
46437
46311
  function createModelTrainingCreateImproveRun(input) {
46438
46312
  const timestamp = input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
46439
- const runId = `create_improve_${randomUUID18()}`;
46313
+ const runId = `create_improve_${randomUUID19()}`;
46440
46314
  const target = {
46441
46315
  kind: "model",
46442
46316
  id: input.modelId,
@@ -46753,7 +46627,7 @@ function targetForIntent(intent, objective) {
46753
46627
  if (intent.kind === "model") {
46754
46628
  return {
46755
46629
  kind: "model",
46756
- id: intent.id ?? `model_draft_${randomUUID18()}`,
46630
+ id: intent.id ?? `model_draft_${randomUUID19()}`,
46757
46631
  displayName: displayName ?? "New model",
46758
46632
  trainingPlanId: null,
46759
46633
  trainingJobId: null,
@@ -47536,6 +47410,13 @@ function createTrainingApi(deps) {
47536
47410
  const tasksetId = requiredString10(input.tasksetId, "tasksetId");
47537
47411
  const datasetId = requiredString10(input.preferenceDatasetReleaseId, "preferenceDatasetReleaseId");
47538
47412
  const taskset = await requireTaskset(deps.store, tasksetId);
47413
+ const modelProject = await deps.store.getModelProject(
47414
+ requiredString10(input.modelProjectId, "modelProjectId")
47415
+ );
47416
+ if (!modelProject) throw new Error("Model Project was not found.");
47417
+ if (modelProject.trainingSetup.tasksetRef?.id !== taskset.id) {
47418
+ throw new Error("Reward Model Run must use the Taskset selected by the Model Project.");
47419
+ }
47539
47420
  const dataset = (await requirePreferenceComparisons(deps.preferenceComparisons).listPreferenceDatasets(tasksetId)).find((candidate2) => candidate2.id === datasetId);
47540
47421
  if (!dataset) throw new Error("Preference Dataset release was not found for this Taskset.");
47541
47422
  const comparisonRelease = await deps.store.getPreferenceComparisonRelease(
@@ -47554,6 +47435,7 @@ function createTrainingApi(deps) {
47554
47435
  return deps.training.launchRewardModel({
47555
47436
  id: requiredString10(input.id, "id"),
47556
47437
  rewardModelId: requiredString10(input.rewardModelId, "rewardModelId"),
47438
+ modelProject,
47557
47439
  taskset,
47558
47440
  tasksetRelease: comparisonRelease.tasksetRelease,
47559
47441
  dataset,
@@ -47665,42 +47547,6 @@ function createTrainingApi(deps) {
47665
47547
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
47666
47548
  });
47667
47549
  }
47668
- if (action === "save_model_run_draft") {
47669
- const draft = ModelRunDraftSchema.parse(input);
47670
- const existing = await deps.store.getModelRunDraft(draft.id);
47671
- if (existing && existing.profileId !== draft.profileId) {
47672
- throw new Error("Model run draft profile does not match the active Profile.");
47673
- }
47674
- if (existing && existing.modelId !== draft.modelId) {
47675
- throw new Error("A saved Model run draft cannot change Model identity.");
47676
- }
47677
- if (existing && (existing.status === "launched" || existing.status === "cancelled")) {
47678
- if (JSON.stringify(existing) !== JSON.stringify(draft)) {
47679
- throw new Error("Launched and cancelled Model runs are immutable.");
47680
- }
47681
- return existing;
47682
- }
47683
- const project = await deps.store.getModelProject(draft.modelId);
47684
- if (!project || project.profileId !== draft.profileId) {
47685
- throw new Error("Save the Model before saving its run draft.");
47686
- }
47687
- return deps.store.saveModelRunDraft({
47688
- ...draft,
47689
- createdAt: existing?.createdAt ?? draft.createdAt,
47690
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
47691
- });
47692
- }
47693
- if (action === "delete_model_run_draft") {
47694
- const draft = await deps.store.getModelRunDraft(
47695
- requiredString10(input.draftId, "draftId")
47696
- );
47697
- if (!draft) return { deleted: false };
47698
- if (draft.status === "launched") {
47699
- throw new Error("A launched Model run cannot be deleted.");
47700
- }
47701
- await deps.store.deleteModelRunDraft(draft.id);
47702
- return { deleted: true, draftId: draft.id };
47703
- }
47704
47550
  if (action === "add_source") return deps.taskCreator.addSessionSource({ profileId: requiredString10(input.profileId, "profileId"), sessionId: requiredString10(input.sessionId, "sessionId"), turnIds: stringArray5(input.turnIds), consentScope: input.consentScope === "selected_turns" ? "selected_turns" : "full_session" });
47705
47551
  if (action === "add_sources") {
47706
47552
  const profileId = requiredString10(input.profileId, "profileId");
@@ -48208,36 +48054,35 @@ function createTrainingApi(deps) {
48208
48054
  return { qualification, prepared };
48209
48055
  }
48210
48056
  if (action === "prepare_model_run") return deps.training.prepareModelRun({
48211
- modelRunId: requiredString10(input.modelRunId, "modelRunId"),
48057
+ modelProjectId: requiredString10(input.modelProjectId, "modelProjectId"),
48212
48058
  maximumSpendUsd: nullableNumber(input.maximumSpendUsd),
48213
48059
  retentionDays: nullableNumber(input.retentionDays)
48214
48060
  });
48215
48061
  if (action === "start_model_run") {
48216
- const modelRunId = requiredString10(input.modelRunId, "modelRunId");
48217
- const modelRun = await deps.store.getModelRunDraft(modelRunId);
48218
- if (!modelRun || modelRun.status !== "ready_to_run") {
48219
- throw new Error("A ready saved Model Run is required.");
48220
- }
48221
- if (modelRun.destinationId === "openpond_managed") {
48062
+ const modelProjectId = requiredString10(input.modelProjectId, "modelProjectId");
48063
+ const modelProject = await deps.store.getModelProject(modelProjectId);
48064
+ if (!modelProject) throw new Error("A saved Model Project is required.");
48065
+ const setup = modelProject.trainingSetup;
48066
+ if (setup.destinationId === "openpond_managed") {
48222
48067
  if (!deps.modelProjectHosting) {
48223
48068
  throw new Error("Managed runs require hosted Model Project sync.");
48224
48069
  }
48225
- if (!modelRun.tasksetRef) {
48226
- throw new Error("The saved Model Run has no Taskset.");
48070
+ if (!setup.tasksetRef) {
48071
+ throw new Error("The Model Project training setup has no Taskset.");
48227
48072
  }
48228
- const taskset = await requireTaskset(deps.store, modelRun.tasksetRef.id);
48073
+ const taskset = await requireTaskset(deps.store, setup.tasksetRef.id);
48229
48074
  const release = await requireReleasedTaskset(
48230
48075
  deps.benchmarkTasksets,
48231
48076
  taskset
48232
48077
  );
48233
48078
  await deps.modelProjectHosting.publishTaskset({
48234
- projectId: modelRun.modelId,
48079
+ projectId: modelProject.id,
48235
48080
  taskset,
48236
48081
  release
48237
48082
  });
48238
48083
  }
48239
48084
  return deps.training.startModelRun({
48240
- modelRunId,
48085
+ modelProjectId,
48241
48086
  maximumSpendUsd: nullableNumber(input.maximumSpendUsd),
48242
48087
  retentionDays: nullableNumber(input.retentionDays),
48243
48088
  exportApproved: input.exportApproved === true,
@@ -48393,7 +48238,6 @@ function createTrainingApi(deps) {
48393
48238
  minerConfig,
48394
48239
  minerRuns,
48395
48240
  modelProjects,
48396
- modelRunDrafts,
48397
48241
  modelVersions,
48398
48242
  modelRuns,
48399
48243
  modelTasksets,
@@ -48409,7 +48253,6 @@ function createTrainingApi(deps) {
48409
48253
  deps.taskMiner.config(profileId),
48410
48254
  deps.store.listTaskMinerRuns(profileId),
48411
48255
  deps.store.listModelProjects(),
48412
- deps.store.listModelRunDrafts(),
48413
48256
  deps.store.listModelVersions(),
48414
48257
  deps.store.listModelRuns(),
48415
48258
  deps.store.listTasksets(),
@@ -48450,7 +48293,6 @@ function createTrainingApi(deps) {
48450
48293
  minerConfig,
48451
48294
  minerRuns,
48452
48295
  modelProjects,
48453
- modelRunDrafts,
48454
48296
  modelVersions,
48455
48297
  modelRuns,
48456
48298
  modelTasksets,
@@ -49316,7 +49158,7 @@ async function runDatasetWorker(projectDir, args) {
49316
49158
  }
49317
49159
 
49318
49160
  // ../server/src/training/dataset-imports/import-service.ts
49319
- import { randomUUID as randomUUID21 } from "node:crypto";
49161
+ import { randomUUID as randomUUID22 } from "node:crypto";
49320
49162
  import {
49321
49163
  mkdir as mkdir11,
49322
49164
  readFile as readFile16,
@@ -49327,7 +49169,7 @@ import {
49327
49169
  import path55 from "node:path";
49328
49170
 
49329
49171
  // ../server/src/training/dataset-imports/hugging-face.ts
49330
- import { randomUUID as randomUUID19 } from "node:crypto";
49172
+ import { randomUUID as randomUUID20 } from "node:crypto";
49331
49173
  var HUB_HOSTS = /* @__PURE__ */ new Set(["huggingface.co", "www.huggingface.co"]);
49332
49174
  var METADATA_LIMIT_BYTES = 8 * 1024 * 1024;
49333
49175
  var REQUEST_TIMEOUT_MS = 25e3;
@@ -49446,7 +49288,7 @@ ${split.split}`) ?? {
49446
49288
  const title = typeof cardData?.pretty_name === "string" ? cardData.pretty_name : locator.repositoryId.split("/").at(-1);
49447
49289
  return HuggingFaceDatasetInspectionSchema.parse({
49448
49290
  schemaVersion: "openpond.huggingFaceDatasetInspection.v1",
49449
- id: `dataset_inspection_${randomUUID19()}`,
49291
+ id: `dataset_inspection_${randomUUID20()}`,
49450
49292
  locator,
49451
49293
  resolvedRevision,
49452
49294
  title,
@@ -49714,7 +49556,7 @@ function requiredString11(value, label) {
49714
49556
  }
49715
49557
 
49716
49558
  // ../server/src/training/dataset-imports/imported-taskset.ts
49717
- import { randomUUID as randomUUID20 } from "node:crypto";
49559
+ import { randomUUID as randomUUID21 } from "node:crypto";
49718
49560
  function buildImportedDatasetManifest(job, mapping, result) {
49719
49561
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
49720
49562
  const fields = mapping.bindings.map((binding) => ({
@@ -49726,7 +49568,7 @@ function buildImportedDatasetManifest(job, mapping, result) {
49726
49568
  }));
49727
49569
  const base = {
49728
49570
  schemaVersion: "openpond.datasetArtifact.v1",
49729
- id: `dataset_artifact_${randomUUID20()}`,
49571
+ id: `dataset_artifact_${randomUUID21()}`,
49730
49572
  tasksetId: job.tasksetId,
49731
49573
  tasksetRevision: job.tasksetRevision,
49732
49574
  format: "parquet",
@@ -50243,7 +50085,7 @@ function createDatasetImportService(deps) {
50243
50085
  const locator = normalizeHuggingFaceDatasetLocator(input.url);
50244
50086
  let job = DatasetImportJobSchema.parse({
50245
50087
  schemaVersion: "openpond.datasetImportJob.v1",
50246
- id: `dataset_import_${randomUUID21()}`,
50088
+ id: `dataset_import_${randomUUID22()}`,
50247
50089
  profileId: input.profileId,
50248
50090
  sourceKind: "huggingface",
50249
50091
  status: "inspecting",
@@ -53681,7 +53523,7 @@ function readableXmlText(value) {
53681
53523
  ).split(/\r?\n/).map((line) => line.replace(/[\t ]+/g, " ").trim()).filter(Boolean).join("\n");
53682
53524
  }
53683
53525
  function decodeXmlEntities(value) {
53684
- return value.replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCodePoint(Number.parseInt(hex, 16))).replace(/&#(\d+);/g, (_, decimal2) => String.fromCodePoint(Number.parseInt(decimal2, 10))).replaceAll("&quot;", '"').replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
53526
+ return value.replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCodePoint(Number.parseInt(hex, 16))).replace(/&#(\d+);/g, (_, decimal) => String.fromCodePoint(Number.parseInt(decimal, 10))).replaceAll("&quot;", '"').replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
53685
53527
  }
53686
53528
  function boundedText(value) {
53687
53529
  return value.length <= MAX_EXTRACTED_CHARS ? value : `${value.slice(0, MAX_EXTRACTED_CHARS)}
@@ -54491,7 +54333,7 @@ function isImageMediaType(mediaType) {
54491
54333
  }
54492
54334
 
54493
54335
  // ../server/src/training/harness-refiner-benchmark-model.ts
54494
- import { randomUUID as randomUUID22 } from "node:crypto";
54336
+ import { randomUUID as randomUUID23 } from "node:crypto";
54495
54337
  function createHarnessRefinerBenchmarkModelStream(streamOpenPondHostedChatTurn2) {
54496
54338
  return async function* ({
54497
54339
  model,
@@ -54502,7 +54344,7 @@ function createHarnessRefinerBenchmarkModelStream(streamOpenPondHostedChatTurn2)
54502
54344
  if (model.providerId !== "openpond") {
54503
54345
  throw new Error("Harness Refiner benchmark model must use the admitted OpenPond hosted provider.");
54504
54346
  }
54505
- const requestId = `harness-refiner-benchmark:${randomUUID22()}`;
54347
+ const requestId = `harness-refiner-benchmark:${randomUUID23()}`;
54506
54348
  for (let retry = 0; ; retry += 1) {
54507
54349
  let received = false;
54508
54350
  try {
@@ -54938,7 +54780,7 @@ function supplementaryModelJudge(release) {
54938
54780
 
54939
54781
  // ../server/src/training/local-taskset-work-runtime.ts
54940
54782
  import { execFile as execFile9 } from "node:child_process";
54941
- import { createHash as createHash16, randomUUID as randomUUID23 } from "node:crypto";
54783
+ import { createHash as createHash16, randomUUID as randomUUID24 } from "node:crypto";
54942
54784
  import { existsSync as existsSync12, promises as fs25 } from "node:fs";
54943
54785
  import os8 from "node:os";
54944
54786
  import path61 from "node:path";
@@ -55101,7 +54943,7 @@ async function executeLocalWorkspaceTool(input) {
55101
54943
  safeName2(input.session.id)
55102
54944
  );
55103
54945
  await fs25.mkdir(outputDir, { recursive: true, mode: 448 });
55104
- const destination = path61.join(outputDir, `001-${randomUUID23()}-${title}`);
54946
+ const destination = path61.join(outputDir, `001-${randomUUID24()}-${title}`);
55105
54947
  await fs25.writeFile(destination, bytes2, { mode: 384 });
55106
54948
  const outputRef = FileOutputRefSchema.parse({
55107
54949
  kind: "file",
@@ -55840,11 +55682,7 @@ function createManagedAdapterRegistryClient(dependencies = {}) {
55840
55682
  const access5 = await resolveAccess(teamId);
55841
55683
  assertResolvedTeam(access5.teamId, teamId);
55842
55684
  const requestUrl = `${access5.apiBaseUrl}${path65}`;
55843
- const headers = withVercelProtectionBypass(
55844
- requestUrl,
55845
- hostedApiAuthHeaders(access5.token),
55846
- dependencies.env
55847
- );
55685
+ const headers = hostedApiAuthHeaders(access5.token);
55848
55686
  headers.set("accept", "application/json");
55849
55687
  headers.set("x-openpond-team-id", access5.teamId);
55850
55688
  if (init.body) headers.set("content-type", "application/json");
@@ -55919,11 +55757,7 @@ function createManagedAdapterRegistryClient(dependencies = {}) {
55919
55757
  const access5 = await resolveInferenceAccess(input.teamId);
55920
55758
  assertResolvedTeam(access5.teamId, input.teamId);
55921
55759
  const requestUrl = `${access5.apiBaseUrl}/v1/chat/completions`;
55922
- const headers = withVercelProtectionBypass(
55923
- requestUrl,
55924
- hostedApiAuthHeaders(access5.token),
55925
- dependencies.env
55926
- );
55760
+ const headers = hostedApiAuthHeaders(access5.token);
55927
55761
  headers.set("accept", "text/event-stream");
55928
55762
  headers.set("content-type", "application/json");
55929
55763
  headers.set("x-openpond-team-id", access5.teamId);
@@ -56502,7 +56336,7 @@ async function createOpenPondServer(options = {}) {
56502
56336
  });
56503
56337
  const workEvidenceApi = createDesktopWorkEvidenceApi({ store, storeDir });
56504
56338
  const startedAt = now();
56505
- const serverId = randomUUID24();
56339
+ const serverId = randomUUID25();
56506
56340
  const workOutputService = createWorkOutputService({
56507
56341
  deviceId: serverId,
56508
56342
  storeDir,