chainlesschain 0.165.3 → 0.165.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -29
- package/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-BiHNUlbU.js → AIOps-C__nnraW.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-D-UFjDRQ.js → ActionButton-CsKWHEZ-.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DazVsDgW.js → Analytics-BhIjfjWO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DXh9UfNJ.js → AppLayout-BjuXFzWZ.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CZ6tsceY.js → Artifacts-k6whDkZJ.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-RyxnBr_h.js → Audit-C4FBMYRh.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BWS51Q6X.js → BackgroundAgents-C_vRrSXk.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BRtPcUul.js → Backup-CngFZeVp.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CGd4vZYY.js → BaseInput-B_H9EBRm.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-h8ijVwCg.js → Chat-DLEC5kt7.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-NyF6dPl8.js → Checkbox-m3ClR4xh.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Ci4OOxr5.js → Codegen-CmLSFrgp.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CwTkc9BM.js → Col-DFGQteHN.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DW_tM82m.js → Community-EUUVORHE.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DEvHRV4S.js → Compact-2PSg0Yr7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BbjBEEfD.js → Compliance-CcKur7gB.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-10IXBaBa.js → Cowork-DK_Fezfa.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BZkbpd5I.js → Cron-Dbw89xl7.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CFQ8L_6v.js → Crosschain-CH66h_Ec.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BDF6AkXe.js → DID-D1igRb17.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CoOdWMi4.js → Dashboard-DVAsrobk.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DEsGmu8Y.js → Dropdown-Dl7W8AQs.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BS89SWlK.js → EmailListRenderer-D5tpaEQC.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C1FpCHiI.js → FamilyGuardDashboard-O_VQf8gq.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BzvpVmLA.js → Federation-BTVcgS9n.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BeC259PQ.js → FormItemContext-BRnkJAIz.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-azgG3bmV.js → GenericCardRenderer-8OWSCkDj.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BmSSowc5.js → Git-WXLYTQj2.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CTBCSyQZ.js → Governance-BezaUhtc.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DA5xyk4a.js → Inference-CuRay3Gu.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D1gPHNig.js → KnowledgeGraph-DfWLDW1m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BPmLf1AR.js → Logs-C55y2pPY.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-DtUFcR0E.js → Marketplace-Dk08Uycg.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DS_kqBv-.js → McpTools-C11fSB5V.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Fvh7XL7V.js → Memory-mr0eZc97.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C7itAP45.js → MobileBridge-C0iCSRbb.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-CY-xMG8Z.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B57MiNLK.js → Mtc-Bplqc_Wc.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BXfCUcM7.js → MtcAudit-BlzwsoSM.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-yaJ-ZcF6.js → Multisig-BBLmTty6.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CoaUCKrO.js → NLProgramming-DtT1uf1W.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BKLM_65R.js → Notes-DcqQAxTK.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DoDtK9uZ.js → NotificationSettings-cb0kWoZe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BJ28TGr-.js → OrderTableRenderer-kw9HZQNN.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-MuGsdoIb.js → Organization-DlTlbkUN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BLUN9J4R.js → Overflow-pp1qs-oY.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DWuoBUPd.js → P2P-BESLnyYz.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CUi37YPj.js → PdhVaultBrowser-B-J1mGuf.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYQg2pcr.js → Permissions-B36PeT1_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CAxoV2xu.js → PersonalDataHub-CTK2ad-3.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-B33wGvIO.js → Pipeline-zJNGXsac.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-A8yXTORP.js → Privacy-b9fz0Qf0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D49I2I1O.js → ProjectInit-DjZbZgiB.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Ci73jJDw.js → ProjectSettings-C-hHJXlD.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +1 -0
- package/src/assets/web-panel/assets/Providers-Dz-CAYYU.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-Brza0ykJ.js → QrScannerModal-A0yoQ3-3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DFydhjxL.js → QuickAsk-DrFgFJNC.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DLF8_NhA.js → Recommend-KC8hF1g4.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-dyuStW3x.js → RemoteSession-DGTPIk6u.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-5F3tA6yw.js → Reputation-QmbwM7Yk.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Ca2A57S5.js → Row-BxjJylia.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B0bxBkq_.js → RssFeed-B7Wda1J6.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CFNvHalZ.js → Search-_plQ_YSA.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DSoH3Hav.js → Security-CD2YJZfx.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BHpfEmBQ.js → Services-qQE7NmwE.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Dsh-QNmn.js → Skeleton-DgQqkFf7.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BhT1NkSU.js → Skills-C4C0oFFt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DY9snPeJ.js → Sla-Px2N2B5c.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CWaX0_Cx.js → SpeechSettings-DN6C3lQd.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B690y_TC.js → SyncSettings-jm5aH_m7.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-2N-w3zWd.js → Tasks-DlkJcv67.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BjwQOQYC.js → Templates-DyrTHUBs.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CUqHErxY.js → Tenant-mC434PtL.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-C13rXvNy.js → Terminal-o0_s3NgK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CpbWcya_.js → TimelineRenderer-DAGlAXOw.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BXHLGXYC.js → Tokens-BnulS_bs.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-1e5i65o3.js → Trigger-suQbVXYM.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-FLGqNHs5.js → Trust-DbIJAPo5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BbaR_LJB.js → UkeySign-CQNpbIHi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-NOp4RIov.js → VideoEditing-D8aWCERk.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-B7DW7bG4.js → Wallet-CuLpYfZc.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-BptSUWix.js → WebAuthn-CsfG8ZMc.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CAJnDOXS.js → WorkflowEditor-BYsEAZbd.js} +1 -1
- package/src/assets/web-panel/assets/{chat-I8LgG1-Z.js → chat-FT4Um3-I.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CWe7SOVD.js → colors-CKbS_Wlt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cx3u3CA3.js → compact-item-CFJtzuJM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CgD5ArwY.js → createContext-B9kSRW6K.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BfQWiXN8.js → hasIn-DR-x0Xpi.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAVy98u7.js → index-7jHr_A_k.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlIyt1qF.js → index-B3ZX81mK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWZ3REg6.js → index-B7osrXqy.js} +3 -3
- package/src/assets/web-panel/assets/{index-DGMYTN5W.js → index-BGbPnC5x.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFb-XIKy.js → index-BI5hP_qy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAUnl4Jv.js → index-BK3TiKVq.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUAR7RY-.js → index-BVPU43b1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd79NQAx.js → index-BW-t9n-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiI-xPRH.js → index-BfFCQHL3.js} +1 -1
- package/src/assets/web-panel/assets/index-Bizb4hkw.js +1 -0
- package/src/assets/web-panel/assets/{index-B6yChzt1.js → index-Bt4fS2eL.js} +1 -1
- package/src/assets/web-panel/assets/{index-e8BM1yY1.js → index-BwR7yc2h.js} +1 -1
- package/src/assets/web-panel/assets/{index-V-kIHzAV.js → index-Bzz0C1BZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bx7BNIRH.js → index-C2JvmYRc.js} +1 -1
- package/src/assets/web-panel/assets/{index-87gMxqhN.js → index-CGaXUsIs.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cy_cCJlr.js → index-CJmIQ9XR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1UjHdgZ.js → index-C_enk9I_.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bi24S7Dw.js → index-Cr2FLUsD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcX4FSPf.js → index-CvrCCqJt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmrdUwzU.js → index-D4LfPvWA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dcdm_Z2c.js → index-DMGmg497.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCJEY2T0.js → index-DShSkww-.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0ztiqtB.js → index-DTxNy0ZU.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-rIKccl.js → index-DW4BWjTk.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdRkCwm4.js → index-DWdqx7zI.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0nDKhWv.js → index-Dap9c3eD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQDKYbnv.js → index-DcfxhKXR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuEQSorC.js → index-DdkIhfi-.js} +1 -1
- package/src/assets/web-panel/assets/{index-3iKP9OTJ.js → index-DeSgw-WV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Doc0Ftpd.js → index-DiNUEpSQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BREnPKGo.js → index-DjEP7WkH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNYFQxAW.js → index-DtkFqPVA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DslTuqro.js → index-KqDaCApw.js} +1 -1
- package/src/assets/web-panel/assets/index-OHSl-xCh.js +1 -0
- package/src/assets/web-panel/assets/{index-CMu16vPC.js → index-OSzjTzGM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsQcURkA.js → index-QBSeNVO3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeizoQVZ.js → index-WE08gMJP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1cX4Rxu.js → index-r2VI1Ikk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmgtY58H.js → index-tqSEHPRT.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DiBszVdG.js → initDefaultProps-Dd7n7VgI.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BGIFFozv.js → motion-BwxouRw1.js} +1 -1
- package/src/assets/web-panel/assets/{move-D5W7mp7B.js → move-DObN0PG9.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-JFIlxJ7F.js → mtc-parser-B3nOUQc7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CQ3o6LIU.js → omit-o9WU2Nbl.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-R8MIlXo3.js → pickAttrs-CL_vvfQ_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-sW7ylSky.js → placementArrow-CYrM2tyK.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cnl39Vbz.js → responsiveObserve-k_06cQ96.js} +1 -1
- package/src/assets/web-panel/assets/{slide-sn8tFd14.js → slide-CPKG0pxS.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-IKKY_QxZ.js → statusUtils-BDDEeLTw.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BNpV4Nqs.js → styleChecker-Cmb7RTh7.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BWyT_eoU.js → useFlexGapSupport-e2IedC4N.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D09p6_U9.js → useFs-CE_gxVnm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CzW3TkJZ.js → usePersonalDataHub-BkMIIKMz.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-3s3WoAKB.js → vnode-DW886XV1.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Cjy_673s.js → zoom-Dwo_adaf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -35
- package/src/commands/artifacts.js +363 -33
- package/src/commands/cowork.js +202 -36
- package/src/commands/session-budget.js +155 -0
- package/src/commands/session-location.js +948 -0
- package/src/commands/session.js +72 -46
- package/src/data/changelog.json +13 -0
- package/src/gateways/ws/artifact-protocol.js +77 -13
- package/src/gateways/ws/session-protocol.js +391 -24
- package/src/gateways/ws/ws-agent-handler.js +191 -14
- package/src/gateways/ws/ws-server.js +14 -3
- package/src/gateways/ws/ws-session-gateway.js +101 -5
- package/src/harness/jsonl-session-store.js +1210 -0
- package/src/lib/agent-team/team-runner.js +43 -13
- package/src/lib/artifact-access-ledger.js +461 -0
- package/src/lib/artifact-cleanup-ledger.js +861 -0
- package/src/lib/artifact-deletion-ledger.js +677 -0
- package/src/lib/artifact-store.js +256 -51
- package/src/lib/command-lifecycle-report.js +8 -4
- package/src/lib/cowork-adapter.js +9 -5
- package/src/lib/cowork-task-runner.js +20 -0
- package/src/lib/cowork-workflow.js +178 -20
- package/src/lib/direct-model-usage.js +62 -22
- package/src/lib/dynamic-workflow-runtime.js +3184 -111
- package/src/lib/execution-location-result-apply.js +339 -0
- package/src/lib/execution-location-result-artifact.js +271 -0
- package/src/lib/execution-location-result-review.js +253 -0
- package/src/lib/execution-location-result-store.js +331 -0
- package/src/lib/execution-location-result.js +617 -0
- package/src/lib/execution-location-target.js +236 -1
- package/src/lib/managed-tool-checkpoint.js +47 -4
- package/src/lib/process-execution-broker/workspace-transaction.js +3 -0
- package/src/lib/session-budget-production-root.js +376 -0
- package/src/lib/session-budget-runtime.js +109 -18
- package/src/lib/session-budget-usage.js +63 -0
- package/src/lib/session-host-snapshot.js +19 -2
- package/src/lib/session-resource-budget.js +766 -105
- package/src/lib/sub-agent-context.js +69 -22
- package/src/lib/web-ui-server.js +12 -1
- package/src/repl/agent-repl.js +237 -16
- package/src/runtime/agent-core.js +123 -0
- package/src/runtime/headless-runner.js +135 -46
- package/src/runtime/headless-stream.js +133 -25
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-D7tcdDS9.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-SVLOg49H.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DGbP36-3.js +0 -1
- package/src/assets/web-panel/assets/Projects-CF-yD6Cn.js +0 -1
- package/src/assets/web-panel/assets/Providers-D-etEhg5.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DLv_872g.js +0 -1
- package/src/assets/web-panel/assets/index-CdiGCibe.js +0 -1
- package/src/assets/web-panel/assets/index-D_0z-gyz.js +0 -1
|
@@ -59,6 +59,9 @@ import { canonicalJson } from "./scheduler-kernel/contract.js";
|
|
|
59
59
|
/** Maximum number of items a single forEach step can expand into. */
|
|
60
60
|
export const MAX_FAN_OUT = 500;
|
|
61
61
|
|
|
62
|
+
/** Maximum declarative choices accepted by one durable stage input gate. */
|
|
63
|
+
export const MAX_STAGE_INPUT_OPTIONS = 32;
|
|
64
|
+
|
|
62
65
|
/** Absolute ceiling on a single loop step's iterations (infinite-loop guard). */
|
|
63
66
|
export const MAX_LOOP_ITERATIONS = 100;
|
|
64
67
|
export const COWORK_WORKFLOW_RUN_RECORD_SCHEMA = "cc-cowork-workflow-run/v1";
|
|
@@ -832,6 +835,53 @@ export function validateWorkflow(wf) {
|
|
|
832
835
|
if (s.when !== undefined && typeof s.when !== "string") {
|
|
833
836
|
errors.push(`steps[${i}].when must be a string expression`);
|
|
834
837
|
}
|
|
838
|
+
if (s.needsInput !== undefined) {
|
|
839
|
+
const input = s.needsInput;
|
|
840
|
+
const inputKeys =
|
|
841
|
+
input && typeof input === "object" && !Array.isArray(input)
|
|
842
|
+
? Object.keys(input)
|
|
843
|
+
: [];
|
|
844
|
+
if (
|
|
845
|
+
!input ||
|
|
846
|
+
typeof input !== "object" ||
|
|
847
|
+
Array.isArray(input) ||
|
|
848
|
+
inputKeys.some(
|
|
849
|
+
(key) => !["prompt", "options", "multiSelect"].includes(key),
|
|
850
|
+
) ||
|
|
851
|
+
typeof input.prompt !== "string" ||
|
|
852
|
+
input.prompt.trim() !== input.prompt ||
|
|
853
|
+
input.prompt.length === 0 ||
|
|
854
|
+
input.prompt.length > 4096
|
|
855
|
+
) {
|
|
856
|
+
errors.push(`steps[${i}].needsInput has an invalid prompt schema`);
|
|
857
|
+
} else {
|
|
858
|
+
if (
|
|
859
|
+
input.options !== undefined &&
|
|
860
|
+
(!Array.isArray(input.options) ||
|
|
861
|
+
input.options.length === 0 ||
|
|
862
|
+
input.options.length > MAX_STAGE_INPUT_OPTIONS ||
|
|
863
|
+
input.options.some(
|
|
864
|
+
(option) =>
|
|
865
|
+
typeof option !== "string" ||
|
|
866
|
+
option.trim() !== option ||
|
|
867
|
+
option.length === 0 ||
|
|
868
|
+
option.length > 512,
|
|
869
|
+
) ||
|
|
870
|
+
new Set(input.options).size !== input.options.length)
|
|
871
|
+
) {
|
|
872
|
+
errors.push(`steps[${i}].needsInput.options is invalid`);
|
|
873
|
+
}
|
|
874
|
+
if (
|
|
875
|
+
input.multiSelect !== undefined &&
|
|
876
|
+
typeof input.multiSelect !== "boolean"
|
|
877
|
+
) {
|
|
878
|
+
errors.push(`steps[${i}].needsInput.multiSelect must be boolean`);
|
|
879
|
+
}
|
|
880
|
+
if (input.multiSelect === true && !Array.isArray(input.options)) {
|
|
881
|
+
errors.push(`steps[${i}].needsInput.multiSelect requires options`);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
835
885
|
if (s.forEach !== undefined) {
|
|
836
886
|
const f = s.forEach;
|
|
837
887
|
const ok =
|
|
@@ -1076,6 +1126,69 @@ export function substitutePlaceholders(template, resultsById) {
|
|
|
1076
1126
|
);
|
|
1077
1127
|
}
|
|
1078
1128
|
|
|
1129
|
+
function normalizeResolvedStageInput(value, spec) {
|
|
1130
|
+
const answer = snapshotAdmittedCanonicalValue(
|
|
1131
|
+
value,
|
|
1132
|
+
"workflow stage input answer",
|
|
1133
|
+
{ maxNodes: 256, maxBytes: 64 * 1024 },
|
|
1134
|
+
);
|
|
1135
|
+
const options = Array.isArray(spec.options) ? spec.options : null;
|
|
1136
|
+
if (spec.multiSelect === true) {
|
|
1137
|
+
if (
|
|
1138
|
+
!Array.isArray(answer) ||
|
|
1139
|
+
answer.length === 0 ||
|
|
1140
|
+
answer.length > MAX_STAGE_INPUT_OPTIONS ||
|
|
1141
|
+
answer.some((item) => typeof item !== "string") ||
|
|
1142
|
+
new Set(answer).size !== answer.length ||
|
|
1143
|
+
answer.some((item) => !options.includes(item))
|
|
1144
|
+
) {
|
|
1145
|
+
throw runResultError("workflow stage input answer is invalid");
|
|
1146
|
+
}
|
|
1147
|
+
return answer;
|
|
1148
|
+
}
|
|
1149
|
+
if (
|
|
1150
|
+
typeof answer !== "string" ||
|
|
1151
|
+
answer.length === 0 ||
|
|
1152
|
+
answer.length > 64 * 1024 ||
|
|
1153
|
+
(options && !options.includes(answer))
|
|
1154
|
+
) {
|
|
1155
|
+
throw runResultError("workflow stage input answer is invalid");
|
|
1156
|
+
}
|
|
1157
|
+
return answer;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
async function resolveStageInputMessage(
|
|
1161
|
+
step,
|
|
1162
|
+
message,
|
|
1163
|
+
resultsById,
|
|
1164
|
+
resolveInput,
|
|
1165
|
+
) {
|
|
1166
|
+
if (step.needsInput === undefined) return message;
|
|
1167
|
+
if (typeof resolveInput !== "function") {
|
|
1168
|
+
const error = new Error(
|
|
1169
|
+
`workflow step '${step.id}' requires a durable input resolver`,
|
|
1170
|
+
);
|
|
1171
|
+
error.code = "COWORK_WORKFLOW_INPUT_RESOLVER_REQUIRED";
|
|
1172
|
+
throw error;
|
|
1173
|
+
}
|
|
1174
|
+
const spec = step.needsInput;
|
|
1175
|
+
const prompt = substitutePlaceholders(spec.prompt, resultsById);
|
|
1176
|
+
const answer = normalizeResolvedStageInput(
|
|
1177
|
+
await resolveInput(
|
|
1178
|
+
Object.freeze({
|
|
1179
|
+
stepId: step.id,
|
|
1180
|
+
prompt,
|
|
1181
|
+
options: Array.isArray(spec.options)
|
|
1182
|
+
? Object.freeze([...spec.options])
|
|
1183
|
+
: null,
|
|
1184
|
+
multiSelect: spec.multiSelect === true,
|
|
1185
|
+
}),
|
|
1186
|
+
),
|
|
1187
|
+
spec,
|
|
1188
|
+
);
|
|
1189
|
+
return `${message}\n\n## Bound user input for stage ${step.id}\n${canonicalJson(answer, "workflowStageInput")}`;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1079
1192
|
// ─── Persistence ─────────────────────────────────────────────────────────────
|
|
1080
1193
|
|
|
1081
1194
|
function _storedWorkflowError(message) {
|
|
@@ -1600,6 +1713,7 @@ export async function runStepNode(step, ctx) {
|
|
|
1600
1713
|
onStepComplete,
|
|
1601
1714
|
taskSemaphore,
|
|
1602
1715
|
runTask,
|
|
1716
|
+
resolveInput,
|
|
1603
1717
|
admitted = false,
|
|
1604
1718
|
} = ctx;
|
|
1605
1719
|
const recordId = step.id;
|
|
@@ -1620,9 +1734,20 @@ export async function runStepNode(step, ctx) {
|
|
|
1620
1734
|
}
|
|
1621
1735
|
if (!runThis) return single("skipped", "when-condition false");
|
|
1622
1736
|
|
|
1623
|
-
|
|
1737
|
+
const resolvedMessage = await resolveStageInputMessage(
|
|
1738
|
+
step,
|
|
1739
|
+
step.message,
|
|
1740
|
+
resultsById,
|
|
1741
|
+
resolveInput,
|
|
1742
|
+
);
|
|
1743
|
+
const activeStep =
|
|
1744
|
+
resolvedMessage === step.message
|
|
1745
|
+
? step
|
|
1746
|
+
: { ...step, message: resolvedMessage };
|
|
1747
|
+
|
|
1748
|
+
if (isLoopStep(activeStep)) {
|
|
1624
1749
|
const o = await runLoopStep({
|
|
1625
|
-
step,
|
|
1750
|
+
step: activeStep,
|
|
1626
1751
|
recordId,
|
|
1627
1752
|
cwd,
|
|
1628
1753
|
llmOptions,
|
|
@@ -1640,10 +1765,10 @@ export async function runStepNode(step, ctx) {
|
|
|
1640
1765
|
};
|
|
1641
1766
|
}
|
|
1642
1767
|
|
|
1643
|
-
if (
|
|
1768
|
+
if (activeStep.forEach !== undefined) {
|
|
1644
1769
|
let items;
|
|
1645
1770
|
try {
|
|
1646
|
-
items = resolveForEachItems(
|
|
1771
|
+
items = resolveForEachItems(activeStep.forEach, resultsById);
|
|
1647
1772
|
} catch (err) {
|
|
1648
1773
|
return single("failed", err.message);
|
|
1649
1774
|
}
|
|
@@ -1651,10 +1776,10 @@ export async function runStepNode(step, ctx) {
|
|
|
1651
1776
|
const children = await Promise.all(
|
|
1652
1777
|
items.map(async (item, k) => {
|
|
1653
1778
|
const childId = `${recordId}[${k}]`;
|
|
1654
|
-
const withItem = substituteItem(
|
|
1779
|
+
const withItem = substituteItem(activeStep.message, item);
|
|
1655
1780
|
const msg = substitutePlaceholders(withItem, resultsById);
|
|
1656
1781
|
const r = await runStepWithRetry({
|
|
1657
|
-
step,
|
|
1782
|
+
step: activeStep,
|
|
1658
1783
|
message: msg,
|
|
1659
1784
|
cwd,
|
|
1660
1785
|
llmOptions,
|
|
@@ -1687,9 +1812,9 @@ export async function runStepNode(step, ctx) {
|
|
|
1687
1812
|
};
|
|
1688
1813
|
}
|
|
1689
1814
|
|
|
1690
|
-
const message = substitutePlaceholders(
|
|
1815
|
+
const message = substitutePlaceholders(activeStep.message, resultsById);
|
|
1691
1816
|
const r = await runStepWithRetry({
|
|
1692
|
-
step,
|
|
1817
|
+
step: activeStep,
|
|
1693
1818
|
message,
|
|
1694
1819
|
cwd,
|
|
1695
1820
|
llmOptions,
|
|
@@ -1724,6 +1849,7 @@ export async function runPipeline({
|
|
|
1724
1849
|
onStepComplete,
|
|
1725
1850
|
taskSemaphore,
|
|
1726
1851
|
runTask = _deps.runTask,
|
|
1852
|
+
resolveInput,
|
|
1727
1853
|
admitted = false,
|
|
1728
1854
|
}) {
|
|
1729
1855
|
const limit = Math.max(1, Math.floor(maxParallel) || 1);
|
|
@@ -1787,6 +1913,7 @@ export async function runPipeline({
|
|
|
1787
1913
|
onStepComplete,
|
|
1788
1914
|
taskSemaphore,
|
|
1789
1915
|
runTask,
|
|
1916
|
+
resolveInput,
|
|
1790
1917
|
admitted,
|
|
1791
1918
|
});
|
|
1792
1919
|
} catch (err) {
|
|
@@ -1950,6 +2077,7 @@ function normalizeAdmittedRunRecord(
|
|
|
1950
2077
|
* @param {object} [options.llmOptions] - Forwarded to each task
|
|
1951
2078
|
* @param {function} [options.onStepStart]
|
|
1952
2079
|
* @param {function} [options.onStepComplete]
|
|
2080
|
+
* @param {function} [options.resolveInput] - Durable stage input resolver
|
|
1953
2081
|
* @param {object} [options.runAdmission] - Secret-free, digest-bound dynamic
|
|
1954
2082
|
* workflow admission. Production entry points require this even though the
|
|
1955
2083
|
* low-level executor keeps it optional for existing library callers.
|
|
@@ -1973,6 +2101,7 @@ export async function executeWorkflow(options = {}) {
|
|
|
1973
2101
|
onStepComplete,
|
|
1974
2102
|
pipeline,
|
|
1975
2103
|
runAdmission,
|
|
2104
|
+
resolveInput,
|
|
1976
2105
|
runTask: requestedRunTask,
|
|
1977
2106
|
} = options;
|
|
1978
2107
|
|
|
@@ -2019,6 +2148,16 @@ export async function executeWorkflow(options = {}) {
|
|
|
2019
2148
|
"cowork-workflow: runTask is not available (wire runCoworkTask before executing)",
|
|
2020
2149
|
);
|
|
2021
2150
|
}
|
|
2151
|
+
if (
|
|
2152
|
+
runtimeWorkflow.steps.some((step) => step.needsInput !== undefined) &&
|
|
2153
|
+
typeof resolveInput !== "function"
|
|
2154
|
+
) {
|
|
2155
|
+
const error = new Error(
|
|
2156
|
+
"workflow contains needsInput stages but no durable input resolver was provided",
|
|
2157
|
+
);
|
|
2158
|
+
error.code = "COWORK_WORKFLOW_INPUT_RESOLVER_REQUIRED";
|
|
2159
|
+
throw error;
|
|
2160
|
+
}
|
|
2022
2161
|
|
|
2023
2162
|
const taskSemaphore = createWorkflowTaskSemaphore(concurrencyLimit);
|
|
2024
2163
|
const resultsById = new Map();
|
|
@@ -2038,6 +2177,7 @@ export async function executeWorkflow(options = {}) {
|
|
|
2038
2177
|
onStepComplete,
|
|
2039
2178
|
taskSemaphore,
|
|
2040
2179
|
runTask: runtimeRunTask,
|
|
2180
|
+
resolveInput,
|
|
2041
2181
|
admitted: verifiedRunAdmission != null,
|
|
2042
2182
|
}));
|
|
2043
2183
|
} else {
|
|
@@ -2094,23 +2234,33 @@ export async function executeWorkflow(options = {}) {
|
|
|
2094
2234
|
preOutcomes.push(outcome);
|
|
2095
2235
|
continue;
|
|
2096
2236
|
}
|
|
2237
|
+
const resolvedMessage = await resolveStageInputMessage(
|
|
2238
|
+
step,
|
|
2239
|
+
step.message,
|
|
2240
|
+
resultsById,
|
|
2241
|
+
resolveInput,
|
|
2242
|
+
);
|
|
2243
|
+
const activeStep =
|
|
2244
|
+
resolvedMessage === step.message
|
|
2245
|
+
? step
|
|
2246
|
+
: { ...step, message: resolvedMessage };
|
|
2097
2247
|
// loop node — runs its body repeatedly; per-iteration substitution
|
|
2098
2248
|
// happens inside runLoopStep, so push the raw template.
|
|
2099
|
-
if (isLoopStep(
|
|
2249
|
+
if (isLoopStep(activeStep)) {
|
|
2100
2250
|
runnable.push({
|
|
2101
|
-
step,
|
|
2102
|
-
message:
|
|
2103
|
-
recordId:
|
|
2251
|
+
step: activeStep,
|
|
2252
|
+
message: activeStep.message,
|
|
2253
|
+
recordId: activeStep.id,
|
|
2104
2254
|
parentId: null,
|
|
2105
2255
|
isLoop: true,
|
|
2106
2256
|
});
|
|
2107
2257
|
continue;
|
|
2108
2258
|
}
|
|
2109
2259
|
// forEach-expansion
|
|
2110
|
-
if (
|
|
2260
|
+
if (activeStep.forEach !== undefined) {
|
|
2111
2261
|
let items;
|
|
2112
2262
|
try {
|
|
2113
|
-
items = resolveForEachItems(
|
|
2263
|
+
items = resolveForEachItems(activeStep.forEach, resultsById);
|
|
2114
2264
|
} catch (err) {
|
|
2115
2265
|
anyFailure = true;
|
|
2116
2266
|
const outcome = {
|
|
@@ -2135,20 +2285,28 @@ export async function executeWorkflow(options = {}) {
|
|
|
2135
2285
|
continue;
|
|
2136
2286
|
}
|
|
2137
2287
|
for (let k = 0; k < items.length; k++) {
|
|
2138
|
-
const childId = `${
|
|
2139
|
-
const withItem = substituteItem(
|
|
2288
|
+
const childId = `${activeStep.id}[${k}]`;
|
|
2289
|
+
const withItem = substituteItem(activeStep.message, items[k]);
|
|
2140
2290
|
const msg = substitutePlaceholders(withItem, resultsById);
|
|
2141
2291
|
runnable.push({
|
|
2142
|
-
step,
|
|
2292
|
+
step: activeStep,
|
|
2143
2293
|
message: msg,
|
|
2144
2294
|
recordId: childId,
|
|
2145
|
-
parentId:
|
|
2295
|
+
parentId: activeStep.id,
|
|
2146
2296
|
});
|
|
2147
2297
|
}
|
|
2148
2298
|
continue;
|
|
2149
2299
|
}
|
|
2150
|
-
const message = substitutePlaceholders(
|
|
2151
|
-
|
|
2300
|
+
const message = substitutePlaceholders(
|
|
2301
|
+
activeStep.message,
|
|
2302
|
+
resultsById,
|
|
2303
|
+
);
|
|
2304
|
+
runnable.push({
|
|
2305
|
+
step: activeStep,
|
|
2306
|
+
message,
|
|
2307
|
+
recordId: activeStep.id,
|
|
2308
|
+
parentId: null,
|
|
2309
|
+
});
|
|
2152
2310
|
}
|
|
2153
2311
|
|
|
2154
2312
|
const promises = runnable.map(
|
|
@@ -5,6 +5,13 @@ import {
|
|
|
5
5
|
projectRuntimeUsageBoundary,
|
|
6
6
|
runtimeUsageEventType,
|
|
7
7
|
} from "./runtime-usage-ledger.js";
|
|
8
|
+
import { sessionBudgetAdmissionError } from "./session-budget-production-root.js";
|
|
9
|
+
import {
|
|
10
|
+
beginSessionBudgetUsage,
|
|
11
|
+
markSessionBudgetUsageUnknown,
|
|
12
|
+
recordSessionBudgetUsage,
|
|
13
|
+
rejectSessionBudgetUsageUnknown,
|
|
14
|
+
} from "./session-budget-usage.js";
|
|
8
15
|
|
|
9
16
|
function asRuntimeLedgerPersistenceError(error) {
|
|
10
17
|
if (error && (typeof error === "object" || typeof error === "function")) {
|
|
@@ -47,36 +54,53 @@ export async function runMeteredDirectModelCall({
|
|
|
47
54
|
provider,
|
|
48
55
|
model,
|
|
49
56
|
source = "model",
|
|
57
|
+
sessionBudget = null,
|
|
50
58
|
call,
|
|
51
59
|
}) {
|
|
52
60
|
if (typeof call !== "function") {
|
|
53
61
|
throw new TypeError("metered direct model call requires a callback");
|
|
54
62
|
}
|
|
63
|
+
const callId = `direct-${randomUUID()}`;
|
|
64
|
+
if (typeof sessionBudget?.consumeTurn === "function") {
|
|
65
|
+
const admission = sessionBudget.consumeTurn({ id: callId });
|
|
66
|
+
if (!admission?.ok) {
|
|
67
|
+
throw sessionBudgetAdmissionError(
|
|
68
|
+
admission?.reason,
|
|
69
|
+
`direct model call ${source}`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
55
73
|
if (!sessionId) return call();
|
|
56
74
|
if (typeof persist !== "function") {
|
|
57
75
|
throw new TypeError("metered direct model call requires persistence");
|
|
58
76
|
}
|
|
59
|
-
const callId = `direct-${randomUUID()}`;
|
|
60
77
|
await persistUsageEvent(
|
|
61
78
|
persist,
|
|
62
79
|
runtimeUsageEventType("started"),
|
|
63
80
|
projectRuntimeUsageBoundary({ callId, provider, model, source }, "started"),
|
|
64
81
|
);
|
|
82
|
+
beginSessionBudgetUsage(
|
|
83
|
+
sessionBudget,
|
|
84
|
+
{ callId, provider, model, source },
|
|
85
|
+
`direct model call ${source}`,
|
|
86
|
+
);
|
|
65
87
|
let result;
|
|
66
88
|
try {
|
|
67
89
|
result = await call();
|
|
68
90
|
} catch (error) {
|
|
91
|
+
const unknown = unknownUsageEvent({
|
|
92
|
+
callId,
|
|
93
|
+
provider,
|
|
94
|
+
model,
|
|
95
|
+
source,
|
|
96
|
+
code: "provider_call_failed",
|
|
97
|
+
});
|
|
69
98
|
await persistUsageEvent(
|
|
70
99
|
persist,
|
|
71
100
|
runtimeUsageEventType("unknown"),
|
|
72
|
-
|
|
73
|
-
callId,
|
|
74
|
-
provider,
|
|
75
|
-
model,
|
|
76
|
-
source,
|
|
77
|
-
code: "provider_call_failed",
|
|
78
|
-
}),
|
|
101
|
+
unknown,
|
|
79
102
|
);
|
|
103
|
+
markSessionBudgetUsageUnknown(sessionBudget, unknown);
|
|
80
104
|
throw error;
|
|
81
105
|
}
|
|
82
106
|
if (result?.usage && typeof result.usage === "object") {
|
|
@@ -90,32 +114,48 @@ export async function runMeteredDirectModelCall({
|
|
|
90
114
|
usage: result.usage,
|
|
91
115
|
});
|
|
92
116
|
} catch {
|
|
117
|
+
const unknown = unknownUsageEvent({
|
|
118
|
+
callId,
|
|
119
|
+
provider,
|
|
120
|
+
model,
|
|
121
|
+
source,
|
|
122
|
+
code: "provider_usage_missing",
|
|
123
|
+
});
|
|
93
124
|
await persistUsageEvent(
|
|
94
125
|
persist,
|
|
95
126
|
runtimeUsageEventType("unknown"),
|
|
96
|
-
|
|
97
|
-
callId,
|
|
98
|
-
provider,
|
|
99
|
-
model,
|
|
100
|
-
source,
|
|
101
|
-
code: "provider_usage_missing",
|
|
102
|
-
}),
|
|
127
|
+
unknown,
|
|
103
128
|
);
|
|
129
|
+
if (markSessionBudgetUsageUnknown(sessionBudget, unknown)) {
|
|
130
|
+
rejectSessionBudgetUsageUnknown(
|
|
131
|
+
unknown,
|
|
132
|
+
`direct model call ${source}`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
104
135
|
return result;
|
|
105
136
|
}
|
|
106
137
|
await persistUsageEvent(persist, "token_usage", event);
|
|
138
|
+
recordSessionBudgetUsage(
|
|
139
|
+
sessionBudget,
|
|
140
|
+
event,
|
|
141
|
+
`direct model call ${source} usage settlement`,
|
|
142
|
+
);
|
|
107
143
|
} else {
|
|
144
|
+
const unknown = unknownUsageEvent({
|
|
145
|
+
callId,
|
|
146
|
+
provider,
|
|
147
|
+
model,
|
|
148
|
+
source,
|
|
149
|
+
code: "provider_usage_missing",
|
|
150
|
+
});
|
|
108
151
|
await persistUsageEvent(
|
|
109
152
|
persist,
|
|
110
153
|
runtimeUsageEventType("unknown"),
|
|
111
|
-
|
|
112
|
-
callId,
|
|
113
|
-
provider,
|
|
114
|
-
model,
|
|
115
|
-
source,
|
|
116
|
-
code: "provider_usage_missing",
|
|
117
|
-
}),
|
|
154
|
+
unknown,
|
|
118
155
|
);
|
|
156
|
+
if (markSessionBudgetUsageUnknown(sessionBudget, unknown)) {
|
|
157
|
+
rejectSessionBudgetUsageUnknown(unknown, `direct model call ${source}`);
|
|
158
|
+
}
|
|
119
159
|
}
|
|
120
160
|
return result;
|
|
121
161
|
}
|