@skaile/workspaces 5.1.3 → 5.2.0
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/CHANGELOG.md +32 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-C4X4RTZV.js → asset-feeds-WDIB3E6H.js} +11 -11
- package/dist/{asset-feeds-C4X4RTZV.js.map → asset-feeds-WDIB3E6H.js.map} +1 -1
- package/dist/asset-manager/catalog-deployer.js +8 -8
- package/dist/asset-manager/index.js +12 -12
- package/dist/asset-manager/installer.js +8 -8
- package/dist/asset-manager/src/index.d.ts +27 -1
- package/dist/asset-manager/src/index.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +14 -13
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +11 -10
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +10 -10
- package/dist/bridge/drivers/echo.js +3 -3
- package/dist/bridge/drivers/gemini.js +5 -5
- package/dist/bridge/drivers/goose.js +10 -10
- package/dist/bridge/drivers/omp.js +6 -5
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +10 -10
- package/dist/bridge/drivers/qwen.js +5 -5
- package/dist/bridge/index.js +13 -13
- package/dist/bridge/src/driver-capabilities.d.ts +66 -0
- package/dist/bridge/src/driver-capabilities.d.ts.map +1 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +1 -0
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/{chunk-WPWJRDR3.js → chunk-2MEMXBLC.js} +8 -7
- package/dist/chunk-2MEMXBLC.js.map +1 -0
- package/dist/{chunk-TVOODIZE.js → chunk-2QZG5VJQ.js} +3 -3
- package/dist/{chunk-TVOODIZE.js.map → chunk-2QZG5VJQ.js.map} +1 -1
- package/dist/{chunk-7SAWDPUT.js → chunk-37GBJLF5.js} +5 -55
- package/dist/chunk-37GBJLF5.js.map +1 -0
- package/dist/{chunk-ZD7CX25M.js → chunk-3E2TIPBZ.js} +56 -7
- package/dist/chunk-3E2TIPBZ.js.map +1 -0
- package/dist/{chunk-H4EGUQ7M.js → chunk-4YE7OYTB.js} +5 -5
- package/dist/chunk-4YE7OYTB.js.map +1 -0
- package/dist/{chunk-K5GBV4SA.js → chunk-5BEFNLOR.js} +6 -5
- package/dist/chunk-5BEFNLOR.js.map +1 -0
- package/dist/{chunk-BJZHNSQO.js → chunk-6OWIEFZ2.js} +5 -5
- package/dist/{chunk-BJZHNSQO.js.map → chunk-6OWIEFZ2.js.map} +1 -1
- package/dist/{chunk-O4U7OL6D.js → chunk-6ZCVROWW.js} +6 -6
- package/dist/{chunk-O4U7OL6D.js.map → chunk-6ZCVROWW.js.map} +1 -1
- package/dist/{chunk-RO4Z2CBP.js → chunk-77GKEZ2R.js} +21 -4
- package/dist/chunk-77GKEZ2R.js.map +1 -0
- package/dist/{chunk-TYUJB336.js → chunk-7Y43UXKA.js} +3 -3
- package/dist/{chunk-TYUJB336.js.map → chunk-7Y43UXKA.js.map} +1 -1
- package/dist/{chunk-YV4J7V53.js → chunk-ANWHAGM7.js} +3 -3
- package/dist/{chunk-YV4J7V53.js.map → chunk-ANWHAGM7.js.map} +1 -1
- package/dist/{chunk-SP47UJKE.js → chunk-B4J4RGNY.js} +231 -114
- package/dist/chunk-B4J4RGNY.js.map +1 -0
- package/dist/{chunk-IWCCZL7C.js → chunk-BIMEKYOE.js} +91 -25
- package/dist/chunk-BIMEKYOE.js.map +1 -0
- package/dist/{chunk-WCQMXBO5.js → chunk-BJQUSAGB.js} +4 -4
- package/dist/{chunk-WCQMXBO5.js.map → chunk-BJQUSAGB.js.map} +1 -1
- package/dist/{chunk-RDYI4MML.js → chunk-BNUZEYC3.js} +3 -3
- package/dist/{chunk-RDYI4MML.js.map → chunk-BNUZEYC3.js.map} +1 -1
- package/dist/{chunk-KVAI5DGL.js → chunk-BUNBKRJZ.js} +3 -3
- package/dist/{chunk-KVAI5DGL.js.map → chunk-BUNBKRJZ.js.map} +1 -1
- package/dist/{chunk-AZYIEK3F.js → chunk-BWOLP6KQ.js} +3 -3
- package/dist/{chunk-AZYIEK3F.js.map → chunk-BWOLP6KQ.js.map} +1 -1
- package/dist/chunk-BZXR6SW5.js +15 -0
- package/dist/{chunk-XUQBVK4R.js.map → chunk-BZXR6SW5.js.map} +1 -1
- package/dist/{chunk-Y6V6NUEV.js → chunk-DD3OZLRD.js} +3 -3
- package/dist/{chunk-Y6V6NUEV.js.map → chunk-DD3OZLRD.js.map} +1 -1
- package/dist/{chunk-2HR3RPWD.js → chunk-EOGNW74K.js} +9 -8
- package/dist/chunk-EOGNW74K.js.map +1 -0
- package/dist/{chunk-RNNUYFFD.js → chunk-FJTC5YFO.js} +3 -3
- package/dist/{chunk-RNNUYFFD.js.map → chunk-FJTC5YFO.js.map} +1 -1
- package/dist/{chunk-ZVKJNNME.js → chunk-IOUIC2ZD.js} +8 -8
- package/dist/{chunk-ZVKJNNME.js.map → chunk-IOUIC2ZD.js.map} +1 -1
- package/dist/{chunk-YMOZC2D3.js → chunk-JPR7EPIM.js} +4 -4
- package/dist/{chunk-YMOZC2D3.js.map → chunk-JPR7EPIM.js.map} +1 -1
- package/dist/{chunk-IDEA6CYI.js → chunk-K2K7OF4P.js} +95 -3
- package/dist/chunk-K2K7OF4P.js.map +1 -0
- package/dist/{chunk-AGWYBS2E.js → chunk-KGGT6MUM.js} +4 -4
- package/dist/{chunk-AGWYBS2E.js.map → chunk-KGGT6MUM.js.map} +1 -1
- package/dist/{chunk-BEOKEK3B.js → chunk-L257BENF.js} +73 -54
- package/dist/chunk-L257BENF.js.map +1 -0
- package/dist/{chunk-UVOJSWD2.js → chunk-LZ5RH6LD.js} +24 -13
- package/dist/chunk-LZ5RH6LD.js.map +1 -0
- package/dist/{chunk-M4ISBWXR.js → chunk-MGHUSFYQ.js} +2472 -2265
- package/dist/chunk-MGHUSFYQ.js.map +1 -0
- package/dist/{chunk-43ZBF3WH.js → chunk-OABIGSUY.js} +16 -3
- package/dist/chunk-OABIGSUY.js.map +1 -0
- package/dist/{chunk-QU4J5YSJ.js → chunk-OFNXRI4L.js} +4 -4
- package/dist/{chunk-QU4J5YSJ.js.map → chunk-OFNXRI4L.js.map} +1 -1
- package/dist/{chunk-MXXKTQXJ.js → chunk-P2EM6FNQ.js} +5 -5
- package/dist/{chunk-MXXKTQXJ.js.map → chunk-P2EM6FNQ.js.map} +1 -1
- package/dist/{chunk-DLLM4U6C.js → chunk-PHKFFJ4I.js} +3 -3
- package/dist/{chunk-DLLM4U6C.js.map → chunk-PHKFFJ4I.js.map} +1 -1
- package/dist/{chunk-YDJZRLGN.js → chunk-PU5VY7KF.js} +4 -4
- package/dist/{chunk-YDJZRLGN.js.map → chunk-PU5VY7KF.js.map} +1 -1
- package/dist/{chunk-KC3OF6B2.js → chunk-QMWMSZQ4.js} +3 -3
- package/dist/{chunk-KC3OF6B2.js.map → chunk-QMWMSZQ4.js.map} +1 -1
- package/dist/{chunk-RNOIDD3Y.js → chunk-R3QW7CA5.js} +5 -5
- package/dist/{chunk-RNOIDD3Y.js.map → chunk-R3QW7CA5.js.map} +1 -1
- package/dist/{chunk-UMSWQKCY.js → chunk-RXPC4KBW.js} +3 -3
- package/dist/{chunk-UMSWQKCY.js.map → chunk-RXPC4KBW.js.map} +1 -1
- package/dist/{chunk-IAGCOAIW.js → chunk-S6KNDUAU.js} +4 -4
- package/dist/{chunk-IAGCOAIW.js.map → chunk-S6KNDUAU.js.map} +1 -1
- package/dist/{chunk-I75CM2QF.js → chunk-TVJBJLXR.js} +14 -15
- package/dist/chunk-TVJBJLXR.js.map +1 -0
- package/dist/{chunk-WKIOWDLQ.js → chunk-UDBN3LZU.js} +4 -4
- package/dist/{chunk-WKIOWDLQ.js.map → chunk-UDBN3LZU.js.map} +1 -1
- package/dist/{chunk-5S4ZK75K.js → chunk-WMEPS6S4.js} +3 -3
- package/dist/{chunk-5S4ZK75K.js.map → chunk-WMEPS6S4.js.map} +1 -1
- package/dist/{chunk-KNC55536.js → chunk-XIYXBHLN.js} +5 -4
- package/dist/chunk-XIYXBHLN.js.map +1 -0
- package/dist/{chunk-VDJKWKH2.js → chunk-XOTJVCJB.js} +3 -3
- package/dist/{chunk-VDJKWKH2.js.map → chunk-XOTJVCJB.js.map} +1 -1
- package/dist/{chunk-DXUQCMVT.js → chunk-YANDJSMN.js} +3 -3
- package/dist/{chunk-DXUQCMVT.js.map → chunk-YANDJSMN.js.map} +1 -1
- package/dist/{chunk-AG44ZJ7W.js → chunk-YRF5CYHR.js} +5 -14
- package/dist/chunk-YRF5CYHR.js.map +1 -0
- package/dist/{chunk-KWP4RVTJ.js → chunk-ZSFTCMZL.js} +760 -642
- package/dist/chunk-ZSFTCMZL.js.map +1 -0
- package/dist/cli/index.js +506 -434
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/catalog.d.ts.map +1 -1
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
- package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
- package/dist/cli/src/commands/project.d.ts.map +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/commands/skailify-lib.d.ts +0 -45
- package/dist/cli/src/commands/skailify-lib.d.ts.map +1 -1
- package/dist/cli/src/commands/source.d.ts.map +1 -1
- package/dist/cli/src/commands/validate.d.ts.map +1 -1
- package/dist/cli/src/flow-discovery.d.ts +9 -0
- package/dist/cli/src/flow-discovery.d.ts.map +1 -1
- package/dist/cli/src/helpers.d.ts +13 -0
- package/dist/cli/src/helpers.d.ts.map +1 -1
- package/dist/cli/src/setup.d.ts.map +1 -1
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +17 -17
- package/dist/connectors/src/connector-manager.d.ts +8 -27
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +1 -1
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors/src/mount-ledger.d.ts +61 -0
- package/dist/connectors/src/mount-ledger.d.ts.map +1 -0
- package/dist/{connectors-BQXFKISC.js → connectors-GUN4MRWR.js} +20 -20
- package/dist/{connectors-BQXFKISC.js.map → connectors-GUN4MRWR.js.map} +1 -1
- package/dist/connectors-shared/index.js +2 -2
- package/dist/core/framework.js +1 -1
- package/dist/core/index.js +7 -7
- package/dist/core/manifest.js +2 -2
- package/dist/core/models.js +1 -1
- package/dist/core/publish-manifest.js +2 -2
- package/dist/core/ref.js +1 -1
- package/dist/core/runtime-assets.js +5 -5
- package/dist/core/src/framework.d.ts +7 -0
- package/dist/core/src/framework.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +4 -4
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/lock.d.ts +12 -0
- package/dist/core/src/lock.d.ts.map +1 -1
- package/dist/core/src/manifest-yaml-editor.d.ts +14 -6
- package/dist/core/src/manifest-yaml-editor.d.ts.map +1 -1
- package/dist/core/src/models.d.ts +15 -0
- package/dist/core/src/models.d.ts.map +1 -1
- package/dist/core/src/publish-manifest.d.ts +4 -6
- package/dist/core/src/publish-manifest.d.ts.map +1 -1
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/workspace-config.js +4 -4
- package/dist/deploy/index.js +7 -7
- package/dist/discovery/index.js +4 -4
- package/dist/discovery/src/discover-manifest.d.ts +5 -0
- package/dist/discovery/src/discover-manifest.d.ts.map +1 -1
- package/dist/discovery/src/index.d.ts +1 -1
- package/dist/discovery/src/index.d.ts.map +1 -1
- package/dist/{ensure-sources-CMHOTYFS.js → ensure-sources-VCPA762L.js} +15 -15
- package/dist/{ensure-sources-CMHOTYFS.js.map → ensure-sources-VCPA762L.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +17 -17
- package/dist/factory-assets/connectors/deploy.js +17 -17
- package/dist/factory-assets/connectors/devserver.js +17 -17
- package/dist/factory-assets/connectors/flow/adapter.d.ts +28 -4
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +17 -17
- package/dist/factory-assets/connectors/flow/engine.js +8 -8
- package/dist/factory-assets/connectors/flow/index.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +19 -19
- package/dist/factory-assets/connectors/flow.js +17 -17
- package/dist/factory-assets/connectors/git/checkout.d.ts +161 -0
- package/dist/factory-assets/connectors/git/checkout.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/config.d.ts +78 -0
- package/dist/factory-assets/connectors/git/config.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/credentials.d.ts +93 -0
- package/dist/factory-assets/connectors/git/credentials.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/driver.d.ts +39 -598
- package/dist/factory-assets/connectors/git/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/git/exec.d.ts +177 -0
- package/dist/factory-assets/connectors/git/exec.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/inspect.d.ts +120 -0
- package/dist/factory-assets/connectors/git/inspect.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/lifecycle.d.ts +107 -0
- package/dist/factory-assets/connectors/git/lifecycle.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git/repo.d.ts +496 -0
- package/dist/factory-assets/connectors/git/repo.d.ts.map +1 -0
- package/dist/factory-assets/connectors/git.js +17 -17
- package/dist/factory-assets/connectors/gmail.js +17 -17
- package/dist/factory-assets/connectors/googledrive.js +17 -17
- package/dist/factory-assets/connectors/local.js +17 -17
- package/dist/factory-assets/connectors/mattermost.js +17 -17
- package/dist/factory-assets/connectors/memory.js +17 -17
- package/dist/factory-assets/connectors/minio.js +17 -17
- package/dist/factory-assets/connectors/postgres.js +17 -17
- package/dist/factory-assets/connectors/s3.js +17 -17
- package/dist/factory-assets/connectors/sharepoint.js +17 -17
- package/dist/factory-assets/connectors/sqlite.js +17 -17
- package/dist/factory-assets/connectors/static-server.js +17 -17
- package/dist/factory-assets/connectors/tunnel.js +17 -17
- package/dist/factory-assets/connectors/webdav.js +17 -17
- package/dist/factory-assets/connectors/xstate-store.js +17 -17
- package/dist/factory-assets/connectors/xstate.js +17 -17
- package/dist/{flows-SVCCADGE.js → flows-BOB5YA5R.js} +12 -12
- package/dist/{flows-SVCCADGE.js.map → flows-BOB5YA5R.js.map} +1 -1
- package/dist/{helpers-R3GLTAER.js → helpers-ZGK4R5MZ.js} +15 -15
- package/dist/{helpers-R3GLTAER.js.map → helpers-ZGK4R5MZ.js.map} +1 -1
- package/dist/library/index.js +10 -10
- package/dist/library/install.js +2 -2
- package/dist/library/src/index.d.ts +6 -3
- package/dist/library/src/index.d.ts.map +1 -1
- package/dist/library/src/install/install-from-manifest.d.ts +21 -0
- package/dist/library/src/install/install-from-manifest.d.ts.map +1 -1
- package/dist/library/src/local/install-library-asset.d.ts +64 -0
- package/dist/library/src/local/install-library-asset.d.ts.map +1 -0
- package/dist/library/src/local/local-catalog-source.d.ts +30 -0
- package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
- package/dist/library/src/local/store-paths.d.ts +6 -0
- package/dist/library/src/local/store-paths.d.ts.map +1 -1
- package/dist/library/src/manifest-writer.d.ts +73 -0
- package/dist/library/src/manifest-writer.d.ts.map +1 -0
- package/dist/library/src/sync/manifest-writeback.d.ts +2 -17
- package/dist/library/src/sync/manifest-writeback.d.ts.map +1 -1
- package/dist/{library-publish-EL7VYICU.js → library-publish-RIP6NBYA.js} +20 -21
- package/dist/library-publish-RIP6NBYA.js.map +1 -0
- package/dist/{open-library-MTD34YX3.js → open-library-4IJTBVTR.js} +18 -18
- package/dist/{open-library-MTD34YX3.js.map → open-library-4IJTBVTR.js.map} +1 -1
- package/dist/{open-registry-CHCWKV5W.js → open-registry-G5DI4RPU.js} +14 -14
- package/dist/{open-registry-CHCWKV5W.js.map → open-registry-G5DI4RPU.js.map} +1 -1
- package/dist/paths-L5XLUC3D.js +22 -0
- package/dist/{paths-MKSI52PF.js.map → paths-L5XLUC3D.js.map} +1 -1
- package/dist/plugin-registry/src/targets.d.ts +3 -1
- package/dist/plugin-registry/src/targets.d.ts.map +1 -1
- package/dist/{plugin-store-SVYV7L4C.js → plugin-store-QENDYZ63.js} +9 -9
- package/dist/{plugin-store-SVYV7L4C.js.map → plugin-store-QENDYZ63.js.map} +1 -1
- package/dist/{project-HCNWJP7J.js → project-4INCIIZI.js} +16 -16
- package/dist/{project-HCNWJP7J.js.map → project-4INCIIZI.js.map} +1 -1
- package/dist/resolver/index.js +8 -8
- package/dist/runner/index.js +27 -27
- package/dist/runner/src/agent.d.ts +1 -1
- package/dist/runner/src/agent.d.ts.map +1 -1
- package/dist/runner/src/codex-init.d.ts.map +1 -1
- package/dist/runner/src/compaction-gate.d.ts +9 -33
- package/dist/runner/src/compaction-gate.d.ts.map +1 -1
- package/dist/runner/src/managed-codex-bootstrap.d.ts.map +1 -1
- package/dist/runner/src/pending-turns.d.ts +7 -2
- package/dist/runner/src/pending-turns.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +2 -2
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve-credentials.d.ts +2 -1
- package/dist/runner/src/serve-credentials.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +19 -35
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/turn-scheduler.d.ts +158 -0
- package/dist/runner/src/turn-scheduler.d.ts.map +1 -0
- package/dist/sdk/asset-manager.js +12 -12
- package/dist/sdk/bridge.js +13 -13
- package/dist/sdk/core.js +7 -7
- package/dist/sdk/flow.js +8 -8
- package/dist/sdk/index.js +27 -27
- package/dist/sdk/resolver.js +8 -8
- package/dist/sdk/runner.js +27 -27
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-HTXNR2CZ.js → setup-RG4PJJUW.js} +23 -23
- package/dist/setup-RG4PJJUW.js.map +1 -0
- package/dist/{skills-7K2YO3KN.js → skills-CL45F7AG.js} +13 -13
- package/dist/{skills-7K2YO3KN.js.map → skills-CL45F7AG.js.map} +1 -1
- package/dist/{source-UIFC2PFC.js → source-LJOI5AXU.js} +19 -19
- package/dist/{source-UIFC2PFC.js.map → source-LJOI5AXU.js.map} +1 -1
- package/dist/{source-manifest-publish-QKAKXDVH.js → source-manifest-publish-QEJML4VS.js} +21 -21
- package/dist/{source-manifest-publish-QKAKXDVH.js.map → source-manifest-publish-QEJML4VS.js.map} +1 -1
- package/dist/tui/index.js +28 -28
- package/dist/tui/index.js.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/src/delivery.d.ts +26 -0
- package/dist/types/src/delivery.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/runtime.d.ts +51 -0
- package/dist/types/src/runtime.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +24 -24
- package/dist/workspace-plugin/adapters/omp.js +18 -17
- package/dist/workspace-plugin/adapters/omp.js.map +1 -1
- package/dist/workspace-plugin/index.js +2 -1
- package/dist/workspace-plugin/src/adapters/mcp.d.ts.map +1 -1
- package/dist/workspace-plugin/src/adapters/omp.d.ts.map +1 -1
- package/dist/workspace-plugin/src/plugin.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2HR3RPWD.js.map +0 -1
- package/dist/chunk-43ZBF3WH.js.map +0 -1
- package/dist/chunk-7SAWDPUT.js.map +0 -1
- package/dist/chunk-AG44ZJ7W.js.map +0 -1
- package/dist/chunk-BEOKEK3B.js.map +0 -1
- package/dist/chunk-F7JHP7JV.js +0 -122
- package/dist/chunk-F7JHP7JV.js.map +0 -1
- package/dist/chunk-H4EGUQ7M.js.map +0 -1
- package/dist/chunk-I75CM2QF.js.map +0 -1
- package/dist/chunk-IDEA6CYI.js.map +0 -1
- package/dist/chunk-IWCCZL7C.js.map +0 -1
- package/dist/chunk-K5GBV4SA.js.map +0 -1
- package/dist/chunk-KNC55536.js.map +0 -1
- package/dist/chunk-KWP4RVTJ.js.map +0 -1
- package/dist/chunk-M4ISBWXR.js.map +0 -1
- package/dist/chunk-RO4Z2CBP.js.map +0 -1
- package/dist/chunk-SP47UJKE.js.map +0 -1
- package/dist/chunk-UVOJSWD2.js.map +0 -1
- package/dist/chunk-WPWJRDR3.js.map +0 -1
- package/dist/chunk-XUQBVK4R.js +0 -15
- package/dist/chunk-ZD7CX25M.js.map +0 -1
- package/dist/library-publish-EL7VYICU.js.map +0 -1
- package/dist/paths-MKSI52PF.js +0 -22
- package/dist/runner/src/flow-turn-dispatch.d.ts +0 -41
- package/dist/runner/src/flow-turn-dispatch.d.ts.map +0 -1
- package/dist/runner/src/reply-routing.d.ts +0 -54
- package/dist/runner/src/reply-routing.d.ts.map +0 -1
- package/dist/setup-HTXNR2CZ.js.map +0 -1
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { WorkspacePlugin } from './chunk-
|
|
2
|
-
import { buildWorkspaceToolDefs } from './chunk-
|
|
3
|
-
import { findAiAssetsRoot } from './chunk-
|
|
1
|
+
import { WorkspacePlugin } from './chunk-XIYXBHLN.js';
|
|
2
|
+
import { buildWorkspaceToolDefs } from './chunk-2MEMXBLC.js';
|
|
3
|
+
import { findAiAssetsRoot } from './chunk-7Y43UXKA.js';
|
|
4
4
|
import { WebSocketServerTransport } from './chunk-5LKOAX7I.js';
|
|
5
5
|
import { assembleSystemPrompt, buildCapabilitiesPromptSection } from './chunk-W3UDISS2.js';
|
|
6
6
|
import { prepareNativePolicy, codexInstanceEnvironment, parseCodexCredential, parseCodexRefreshInput, parseCodexRefreshResult } from './chunk-HCYS7GFP.js';
|
|
7
|
-
import { resolveFlowPath } from './chunk-
|
|
8
|
-
import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-
|
|
9
|
-
import { ConnectFailureCarryOver, registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, driveOrchestratorTurn, buildSdkFlowTools } from './chunk-
|
|
10
|
-
import { loadYamlConnectorDeclarations, withMaterializedConnectorDeclarations, SecretProviderChain, ConnectorStartupError, isKnownSecretRef, EnvSecretProvider, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, deriveSingleMaterializedConnectorDeclaration } from './chunk-
|
|
11
|
-
import { EventNormalizer } from './chunk-
|
|
12
|
-
import { probeResumeTranscript, transcriptStoreForRuntime } from './chunk-
|
|
7
|
+
import { resolveFlowPath } from './chunk-IOUIC2ZD.js';
|
|
8
|
+
import { findAiAssetsRoot as findAiAssetsRoot$1, deployCatalogEntry, undeployCatalogEntry } from './chunk-XOTJVCJB.js';
|
|
9
|
+
import { ConnectFailureCarryOver, registerBuiltinConnectors, buildConnectorPromptSection, findMissingPackages, installNpmPackages, ConnectorManager, buildSdkConnectorTools, buildLazySdkFlowTools, describeFlowOperations, buildConnectorToolDefs, buildFlowToolDefs, SessionNodeExecutor, SessionSubpromptRunner, ClassifierSubpromptRunner, SessionInlineSubFlowRunner, driveOrchestratorTurn, buildSdkFlowTools } from './chunk-MGHUSFYQ.js';
|
|
10
|
+
import { loadYamlConnectorDeclarations, withMaterializedConnectorDeclarations, SecretProviderChain, ConnectorStartupError, isKnownSecretRef, EnvSecretProvider, PreMintedSecretProvider, InMemorySecretProvider, resolvedConfigToDeclarations, deriveSingleMaterializedConnectorDeclaration } from './chunk-UDBN3LZU.js';
|
|
11
|
+
import { EventNormalizer } from './chunk-OFNXRI4L.js';
|
|
12
|
+
import { probeResumeTranscript, transcriptStoreForRuntime } from './chunk-2QZG5VJQ.js';
|
|
13
13
|
import { scopeReconfigureModel } from './chunk-EINLFFP6.js';
|
|
14
14
|
import { CodexNativeStateUnavailable } from './chunk-LOO5CB5M.js';
|
|
15
|
-
import { dispatchCapability } from './chunk-
|
|
15
|
+
import { dispatchCapability } from './chunk-BNUZEYC3.js';
|
|
16
16
|
import { classifyClaudeSdkError } from './chunk-XBSQ4KMC.js';
|
|
17
17
|
import { agentExecRequested } from './chunk-YROR332M.js';
|
|
18
|
-
import { toAgentEffort, createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS, AgentDriver } from './chunk-
|
|
19
|
-
import { loadFlow } from './chunk-
|
|
18
|
+
import { driverCapabilities, toAgentEffort, createDriver, catalogLayer, providerCredentialEnvName, toMergedRegistry, registryCredentialEnv, AI_PROVIDER_PRESETS, supportsLiveToolUpdates, AgentDriver } from './chunk-3E2TIPBZ.js';
|
|
19
|
+
import { loadFlow } from './chunk-RXPC4KBW.js';
|
|
20
20
|
import { parseFlowDefinition } from './chunk-QZLWJETK.js';
|
|
21
21
|
import { renderStimulusPrompt } from './chunk-XUUYAS3Z.js';
|
|
22
|
-
import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION } from './chunk-
|
|
23
|
-
import { resolveLibraryDir, resolveSettings, loadProviderRegistry } from './chunk-
|
|
24
|
-
import { resolveRuntimeAssets } from './chunk-
|
|
25
|
-
import { resolveDriverPaths } from './chunk-
|
|
26
|
-
import { resolveSkWorkspaceConfig, resolveAgentDir, loadMcpServerDeclarations, COMPACTION_DEFAULTS, resolveCompactionThresholdPercent, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration, stageMaterializedSkills, readSkillAllowList, isStagedSkillMarkerFor, unstageSkill, STAGED_SKILL_MARKER } from './chunk-
|
|
22
|
+
import { withActivityLabelJsonSchema, TOOL_ACTIVITY_PROMPT_SECTION, SESSION_ROOT_CONNECTOR_ID, PROTOCOL_VERSION, deliveryClassOf } from './chunk-K2K7OF4P.js';
|
|
23
|
+
import { resolveLibraryDir, resolveSettings, loadProviderRegistry } from './chunk-BIMEKYOE.js';
|
|
24
|
+
import { resolveRuntimeAssets } from './chunk-PU5VY7KF.js';
|
|
25
|
+
import { DEFAULT_DRIVER_ID, resolveDriverPaths } from './chunk-5BEFNLOR.js';
|
|
26
|
+
import { resolveSkWorkspaceConfig, resolveAgentDir, loadMcpServerDeclarations, COMPACTION_DEFAULTS, resolveCompactionThresholdPercent, validateAssetRecipeAttr, deriveSingleMaterializedMcpDeclaration, stageMaterializedSkills, readSkillAllowList, isStagedSkillMarkerFor, unstageSkill, STAGED_SKILL_MARKER } from './chunk-P2EM6FNQ.js';
|
|
27
27
|
import { globalSkaileDir } from './chunk-TLKM4M47.js';
|
|
28
|
-
import { withFsDeadline, FsDeadlineError, fsDeadlineMs, parseFrontmatter, tryWithFsDeadline } from './chunk-
|
|
29
|
-
import { parseAssetRef } from './chunk-
|
|
28
|
+
import { withFsDeadline, FsDeadlineError, fsDeadlineMs, parseFrontmatter, tryWithFsDeadline } from './chunk-YANDJSMN.js';
|
|
29
|
+
import { parseAssetRef } from './chunk-OABIGSUY.js';
|
|
30
30
|
import { resolveLogStoreConfig, createLogStoreFromConfig, OnLogBridgeSink, WsLogSink, resolveLogsRetention, enforceLogsRetention } from './chunk-JMKB7IB4.js';
|
|
31
31
|
import { pickRegistryEntries, registryEntries, resolveEntryBaseUrl, parseModelRef, isEntryEnabled, parseCredentialRef } from './chunk-MJHSLODD.js';
|
|
32
32
|
import { getLogStore, registerLogStore, createLogger, resetLogStore, isUnwritableStreamError, markStreamBroken, isBrokenPipeError, redactCredentials } from './chunk-BOFL7GIF.js';
|
|
@@ -2332,6 +2332,7 @@ function parsePresignResult(raw, op) {
|
|
|
2332
2332
|
// runner/src/resources.ts
|
|
2333
2333
|
async function buildAgentResources(projectDir, driverType, _onLog, watch, secretProvider, sessionMeta, tokenMediator, preMintedSecrets, deferFilesystemMounts, capabilityRegistry, fallbackConnectorDeclarations, extraMcpDeclarations, s3Presigner) {
|
|
2334
2334
|
const managedProjectMcp = sessionMeta?.managedCodex ? await resolveExternalMcpDeclarations(projectDir, sessionMeta.sessionId, true) : void 0;
|
|
2335
|
+
const inProcessMcp = driverCapabilities(driverType).inProcessMcpServers;
|
|
2335
2336
|
const resLog = createLogger({
|
|
2336
2337
|
kind: "runner",
|
|
2337
2338
|
subkind: "resources",
|
|
@@ -2415,7 +2416,7 @@ async function buildAgentResources(projectDir, driverType, _onLog, watch, secret
|
|
|
2415
2416
|
}
|
|
2416
2417
|
return externalMcpManager;
|
|
2417
2418
|
};
|
|
2418
|
-
if (
|
|
2419
|
+
if (inProcessMcp) {
|
|
2419
2420
|
const inProcess = await buildInProcessMcpServers(
|
|
2420
2421
|
resourceManager,
|
|
2421
2422
|
projectDir,
|
|
@@ -2442,7 +2443,7 @@ async function buildAgentResources(projectDir, driverType, _onLog, watch, secret
|
|
|
2442
2443
|
mcpSecretChain,
|
|
2443
2444
|
sessionMeta
|
|
2444
2445
|
);
|
|
2445
|
-
} else if (
|
|
2446
|
+
} else if (inProcessMcp) {
|
|
2446
2447
|
externalMcpDeclarations = await resolveExternalMcpDeclarations(
|
|
2447
2448
|
projectDir,
|
|
2448
2449
|
sessionMeta?.sessionId
|
|
@@ -2454,7 +2455,7 @@ async function buildAgentResources(projectDir, driverType, _onLog, watch, secret
|
|
|
2454
2455
|
sessionMeta
|
|
2455
2456
|
);
|
|
2456
2457
|
}
|
|
2457
|
-
if (!resourceManager &&
|
|
2458
|
+
if (!resourceManager && !inProcessMcp && !externalMcpManager?.hasServers() && !capabilityRegistry)
|
|
2458
2459
|
return noopResult;
|
|
2459
2460
|
let coalescer = null;
|
|
2460
2461
|
const startWatching = () => {
|
|
@@ -2724,7 +2725,7 @@ function toSdkMcpServerConfig(decl, secrets) {
|
|
|
2724
2725
|
// runner/src/session-builder.ts
|
|
2725
2726
|
async function createAgentSession(config) {
|
|
2726
2727
|
const managed = config.managedCodex;
|
|
2727
|
-
if (managed && (config.driver
|
|
2728
|
+
if (managed && (!driverCapabilities(config.driver).managedSession || !config.model || !config.aiProviderConfigId || !config.capabilityRegistry || !config.capabilities))
|
|
2728
2729
|
throw new Error("AI_PROFILE_INVALID");
|
|
2729
2730
|
const {
|
|
2730
2731
|
projectDir,
|
|
@@ -2763,7 +2764,7 @@ async function createAgentSession(config) {
|
|
|
2763
2764
|
driver: driverOverride,
|
|
2764
2765
|
model: modelOverride
|
|
2765
2766
|
});
|
|
2766
|
-
const driverType = managed ?
|
|
2767
|
+
const driverType = (managed ? config.driver : settings.driver) ?? DEFAULT_DRIVER_ID;
|
|
2767
2768
|
const model = managed ? config.model : settings.model;
|
|
2768
2769
|
const registry = loadSessionRegistry(projectDir, config.registry, config.providers, sessionLog);
|
|
2769
2770
|
const modelRef = config.modelRef?.trim() || model?.trim() || void 0;
|
|
@@ -2867,7 +2868,7 @@ async function createAgentSession(config) {
|
|
|
2867
2868
|
const maxTurns = maxTurnsOverride ?? manifest?.runtime?.max_turns;
|
|
2868
2869
|
let driver;
|
|
2869
2870
|
try {
|
|
2870
|
-
const extraMcpServers = driverType
|
|
2871
|
+
const extraMcpServers = driverCapabilities(driverType).inProcessMcpServers ? await config.extraInProcessMcpServers?.() : void 0;
|
|
2871
2872
|
const driverMcpServers = extraMcpServers ? { ...mcpServers, ...extraMcpServers } : mcpServers;
|
|
2872
2873
|
driver = await createSessionDriver({
|
|
2873
2874
|
config,
|
|
@@ -4502,7 +4503,7 @@ function validateCodexInit(cmd, supported, previous) {
|
|
|
4502
4503
|
if (requirements !== void 0 && (!Array.isArray(requirements) || requirements.some((item) => typeof item !== "string" || !supported.includes(item))))
|
|
4503
4504
|
throw new Error("Unsupported runtime: required features are unavailable");
|
|
4504
4505
|
const profile = cmd.resolvedConfig.agentConfig;
|
|
4505
|
-
const managed = profile
|
|
4506
|
+
const managed = profile !== void 0 && driverCapabilities(profile.driver).managedSession && (profile.authMode !== void 0 || requirements?.includes("codex-app-server-v1"));
|
|
4506
4507
|
if ((managed || cmd.credentials.ai !== void 0) && !supported.includes("codex-app-server-v1"))
|
|
4507
4508
|
throw new Error("Unsupported runtime: codex-app-server-v1 is unavailable");
|
|
4508
4509
|
if (!managed && cmd.credentials.ai === void 0) return;
|
|
@@ -4605,7 +4606,7 @@ function loadManagedCodexHostConfig(file, projectDir) {
|
|
|
4605
4606
|
function bindManagedCodexInit(host, cmd, refreshCredential) {
|
|
4606
4607
|
const profile = cmd.resolvedConfig.agentConfig;
|
|
4607
4608
|
const credential = parseCodexCredential(cmd.credentials.ai);
|
|
4608
|
-
if (!profile?.authMode || !["subscription", "api-key"].includes(profile.authMode) || cmd.identity.sessionId !== host.sessionId || profile
|
|
4609
|
+
if (!profile?.authMode || !["subscription", "api-key"].includes(profile.authMode) || cmd.identity.sessionId !== host.sessionId || !driverCapabilities(profile.driver).managedSession || !profile.model || !host.subpromptModels.available.includes(profile.model) || credential.configId !== cmd.resolvedConfig.aiProviderConfigId || profile.authMode === "subscription" !== (credential.kind === "codex-subscription"))
|
|
4609
4610
|
throw refused();
|
|
4610
4611
|
const reasoningEffort = profile.effort ?? host.reasoningEffort;
|
|
4611
4612
|
if (!["minimal", "low", "medium", "high", "xhigh"].includes(reasoningEffort)) throw refused();
|
|
@@ -5012,6 +5013,309 @@ function planRuntimeSessionEmit(input) {
|
|
|
5012
5013
|
return { type: "runtime_session", driverSessionId, model, capabilitySignature };
|
|
5013
5014
|
}
|
|
5014
5015
|
|
|
5016
|
+
// runner/src/init-build-hold.ts
|
|
5017
|
+
var DEFAULT_CONNECTOR_MUTATE_INIT_HOLD_MS = 1e4;
|
|
5018
|
+
function resolveConnectorMutateInitHoldMs(env = process.env) {
|
|
5019
|
+
const parsed = Number.parseInt(env.SKAILE_CONNECTOR_MUTATE_INIT_HOLD_MS ?? "", 10);
|
|
5020
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_CONNECTOR_MUTATE_INIT_HOLD_MS;
|
|
5021
|
+
}
|
|
5022
|
+
function createInitBuildHold(now = Date.now) {
|
|
5023
|
+
let current = null;
|
|
5024
|
+
let tail = Promise.resolve();
|
|
5025
|
+
let held = 0;
|
|
5026
|
+
const building = () => current !== null && !current.done;
|
|
5027
|
+
async function awaitNewestBuild() {
|
|
5028
|
+
for (; ; ) {
|
|
5029
|
+
const build = current;
|
|
5030
|
+
if (!build) return null;
|
|
5031
|
+
if (!build.done) await build.settled;
|
|
5032
|
+
if (current === build) return build.error;
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
return {
|
|
5036
|
+
beginBuild() {
|
|
5037
|
+
let resolve4;
|
|
5038
|
+
const build = {
|
|
5039
|
+
done: false,
|
|
5040
|
+
error: null,
|
|
5041
|
+
settled: new Promise((r) => {
|
|
5042
|
+
resolve4 = r;
|
|
5043
|
+
})
|
|
5044
|
+
};
|
|
5045
|
+
current = build;
|
|
5046
|
+
const settle = (error) => {
|
|
5047
|
+
if (build.done) return;
|
|
5048
|
+
build.done = true;
|
|
5049
|
+
build.error = error;
|
|
5050
|
+
resolve4();
|
|
5051
|
+
};
|
|
5052
|
+
return { succeed: () => settle(null), fail: (error) => settle(error) };
|
|
5053
|
+
},
|
|
5054
|
+
run(task, deadlineMs) {
|
|
5055
|
+
if (held === 0 && !building()) {
|
|
5056
|
+
if (current?.error) return task({ kind: "failed", error: current.error });
|
|
5057
|
+
return task({ kind: "ready", remainingMs: void 0 });
|
|
5058
|
+
}
|
|
5059
|
+
held++;
|
|
5060
|
+
const arrivedAt = now();
|
|
5061
|
+
const previous = tail;
|
|
5062
|
+
const turn = previous.then(awaitNewestBuild);
|
|
5063
|
+
let timer;
|
|
5064
|
+
const deadline = deadlineMs === void 0 ? null : new Promise((resolve4) => {
|
|
5065
|
+
timer = setTimeout(() => resolve4("timeout"), deadlineMs);
|
|
5066
|
+
timer.unref?.();
|
|
5067
|
+
});
|
|
5068
|
+
let markStarted;
|
|
5069
|
+
const started = new Promise((resolve4) => {
|
|
5070
|
+
markStarted = resolve4;
|
|
5071
|
+
});
|
|
5072
|
+
const result = (async () => {
|
|
5073
|
+
const first = deadline ? await Promise.race([turn, deadline]) : await turn;
|
|
5074
|
+
clearTimeout(timer);
|
|
5075
|
+
if (first === "timeout") {
|
|
5076
|
+
void turn.then(markStarted);
|
|
5077
|
+
return task({ kind: "timeout", waitedMs: now() - arrivedAt });
|
|
5078
|
+
}
|
|
5079
|
+
markStarted();
|
|
5080
|
+
if (first) return task({ kind: "failed", error: first });
|
|
5081
|
+
return task({
|
|
5082
|
+
kind: "ready",
|
|
5083
|
+
remainingMs: deadlineMs === void 0 ? void 0 : Math.max(0, deadlineMs - (now() - arrivedAt))
|
|
5084
|
+
});
|
|
5085
|
+
})();
|
|
5086
|
+
tail = started;
|
|
5087
|
+
void Promise.allSettled([turn, result]).then(() => {
|
|
5088
|
+
held--;
|
|
5089
|
+
});
|
|
5090
|
+
return result;
|
|
5091
|
+
},
|
|
5092
|
+
held: () => held
|
|
5093
|
+
};
|
|
5094
|
+
}
|
|
5095
|
+
|
|
5096
|
+
// runner/src/serial-lock.ts
|
|
5097
|
+
function createSerialLock() {
|
|
5098
|
+
let tail = Promise.resolve();
|
|
5099
|
+
return (fn) => {
|
|
5100
|
+
const run = tail.then(fn, fn);
|
|
5101
|
+
tail = run.catch(() => void 0);
|
|
5102
|
+
return run;
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
function createCoalescedTask(lock, fn) {
|
|
5106
|
+
let waiting = null;
|
|
5107
|
+
return (...args) => {
|
|
5108
|
+
if (waiting) return waiting;
|
|
5109
|
+
const run = lock(() => {
|
|
5110
|
+
waiting = null;
|
|
5111
|
+
return fn(...args);
|
|
5112
|
+
});
|
|
5113
|
+
waiting = run;
|
|
5114
|
+
return run;
|
|
5115
|
+
};
|
|
5116
|
+
}
|
|
5117
|
+
async function recordStagedSkills(staged, projectDir, skillsDir, names, timeoutMs) {
|
|
5118
|
+
for (const name of names) {
|
|
5119
|
+
const path6 = join(projectDir, skillsDir, name);
|
|
5120
|
+
const st = await tryWithFsDeadline(`lstat ${path6}`, () => lstat(path6), null, timeoutMs);
|
|
5121
|
+
staged.set(
|
|
5122
|
+
name,
|
|
5123
|
+
st?.isDirectory() && st.birthtimeMs > 0 ? { path: path6, dev: st.dev, ino: st.ino, birthtimeMs: st.birthtimeMs } : null
|
|
5124
|
+
);
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
5127
|
+
async function isStillOurs(record2, path6, timeoutMs) {
|
|
5128
|
+
if (!record2 || record2.path !== path6) return false;
|
|
5129
|
+
const st = await tryWithFsDeadline(`lstat ${path6}`, () => lstat(path6), null, timeoutMs);
|
|
5130
|
+
return st?.isDirectory() === true && st.dev === record2.dev && st.ino === record2.ino && st.birthtimeMs === record2.birthtimeMs;
|
|
5131
|
+
}
|
|
5132
|
+
async function recordLoadedSkillDigests(loaded, projectDir, skillsDir, names, opts) {
|
|
5133
|
+
for (const name of names) {
|
|
5134
|
+
if (opts.driverUp && opts.previouslyStaged.has(name)) continue;
|
|
5135
|
+
const path6 = join(projectDir, skillsDir, name);
|
|
5136
|
+
loaded.set(name, { path: path6, digest: await stagedSkillDigest(path6) });
|
|
5137
|
+
}
|
|
5138
|
+
}
|
|
5139
|
+
var DIGEST_DEADLINE_FACTOR = 4;
|
|
5140
|
+
var DIGEST_MAX_BYTES = 64 * 1024 * 1024;
|
|
5141
|
+
var DIGEST_CHUNK_BYTES = 64 * 1024;
|
|
5142
|
+
var DIGEST_OPEN_FLAGS = constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK;
|
|
5143
|
+
async function stagedSkillDigest(dir, timeoutMs) {
|
|
5144
|
+
return tryWithFsDeadline(
|
|
5145
|
+
`digest ${dir}`,
|
|
5146
|
+
async () => {
|
|
5147
|
+
const hash = createHash("sha256");
|
|
5148
|
+
let budget = DIGEST_MAX_BYTES;
|
|
5149
|
+
const hashFile = async (path6) => {
|
|
5150
|
+
const fh = await open(path6, DIGEST_OPEN_FLAGS);
|
|
5151
|
+
try {
|
|
5152
|
+
const st = await fh.stat();
|
|
5153
|
+
if (!st.isFile()) throw new Error(`not a regular file: ${path6}`);
|
|
5154
|
+
if (st.size > budget) throw new Error("skill too large to digest");
|
|
5155
|
+
const buf = Buffer.alloc(DIGEST_CHUNK_BYTES);
|
|
5156
|
+
let total = 0;
|
|
5157
|
+
for (; ; ) {
|
|
5158
|
+
const { bytesRead } = await fh.read(buf, 0, buf.length, null);
|
|
5159
|
+
if (bytesRead === 0) break;
|
|
5160
|
+
total += bytesRead;
|
|
5161
|
+
if (total > budget) throw new Error("skill too large to digest");
|
|
5162
|
+
hash.update(buf.subarray(0, bytesRead));
|
|
5163
|
+
}
|
|
5164
|
+
budget -= total;
|
|
5165
|
+
hash.update(`\0${total}\0`);
|
|
5166
|
+
} finally {
|
|
5167
|
+
await fh.close();
|
|
5168
|
+
}
|
|
5169
|
+
};
|
|
5170
|
+
const walk = async (rel) => {
|
|
5171
|
+
const here = rel ? join(dir, rel) : dir;
|
|
5172
|
+
if (rel && !(await lstat(here)).isDirectory()) throw new Error(`not a dir: ${here}`);
|
|
5173
|
+
const entries = await readdir(here, { withFileTypes: true });
|
|
5174
|
+
entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
5175
|
+
for (const entry of entries) {
|
|
5176
|
+
if (!rel && entry.name === STAGED_SKILL_MARKER) continue;
|
|
5177
|
+
const path6 = rel ? `${rel}/${entry.name}` : entry.name;
|
|
5178
|
+
if (entry.isDirectory()) {
|
|
5179
|
+
hash.update(`d\0${path6}\0`);
|
|
5180
|
+
await walk(path6);
|
|
5181
|
+
} else if (entry.isSymbolicLink()) {
|
|
5182
|
+
hash.update(`l\0${path6}\0${await readlink(join(dir, path6))}\0`);
|
|
5183
|
+
} else if (entry.isFile()) {
|
|
5184
|
+
hash.update(`f\0${path6}\0`);
|
|
5185
|
+
await hashFile(join(dir, path6));
|
|
5186
|
+
} else {
|
|
5187
|
+
hash.update(`o\0${path6}\0`);
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
};
|
|
5191
|
+
await walk("");
|
|
5192
|
+
return hash.digest("hex");
|
|
5193
|
+
},
|
|
5194
|
+
null,
|
|
5195
|
+
fsDeadlineMs() * DIGEST_DEADLINE_FACTOR
|
|
5196
|
+
);
|
|
5197
|
+
}
|
|
5198
|
+
async function attachStagedSkill(deps, name) {
|
|
5199
|
+
try {
|
|
5200
|
+
const skillsDir = deps.skillsDir();
|
|
5201
|
+
const dirName = name.includes("/") ? name.split("/").pop() : name;
|
|
5202
|
+
const { staged, unchanged } = await deps.withSkillFsLock(async () => {
|
|
5203
|
+
const dest = join(deps.projectDir, skillsDir, dirName);
|
|
5204
|
+
const loaded = deps.stagedSkillDirs.has(dirName) ? deps.loadedSkillDigests.get(dirName) : void 0;
|
|
5205
|
+
const names = await stageMaterializedSkills(deps.projectDir, skillsDir, { declared: [name] });
|
|
5206
|
+
let same = false;
|
|
5207
|
+
if (names.includes(dirName)) {
|
|
5208
|
+
const digest = await stagedSkillDigest(dest);
|
|
5209
|
+
same = digest !== null && loaded?.path === dest && loaded.digest === digest;
|
|
5210
|
+
if (!same) deps.loadedSkillDigests.set(dirName, { path: dest, digest });
|
|
5211
|
+
}
|
|
5212
|
+
await recordStagedSkills(deps.stagedSkillDirs, deps.projectDir, skillsDir, names);
|
|
5213
|
+
return { staged: names, unchanged: same ? dirName : null };
|
|
5214
|
+
});
|
|
5215
|
+
if (staged.length === 0) {
|
|
5216
|
+
return {
|
|
5217
|
+
ok: false,
|
|
5218
|
+
code: "skill_not_materialized",
|
|
5219
|
+
message: `no materialized skill matching "${name}" under .skaile/assets/skill`
|
|
5220
|
+
};
|
|
5221
|
+
}
|
|
5222
|
+
const live = deps.driverStarted();
|
|
5223
|
+
const toRestart = staged.filter((s) => s !== unchanged);
|
|
5224
|
+
if (toRestart.length === 0) {
|
|
5225
|
+
deps.log(
|
|
5226
|
+
`[serve] runner.attach_instance: skill ${staged.join(", ")} already staged and unchanged \u2014 no driver restart`
|
|
5227
|
+
);
|
|
5228
|
+
return { ok: true, id: name, live, toolCount: 0 };
|
|
5229
|
+
}
|
|
5230
|
+
deps.log(`[serve] runner.attach_instance staged skill(s): ${toRestart.join(", ")}`);
|
|
5231
|
+
deps.scheduleSkillRestart(toRestart.map((s) => ({ name: s, action: "add" })));
|
|
5232
|
+
return { ok: true, id: name, live, toolCount: 0 };
|
|
5233
|
+
} catch (err) {
|
|
5234
|
+
return {
|
|
5235
|
+
ok: false,
|
|
5236
|
+
code: "skill_attach_failed",
|
|
5237
|
+
message: err instanceof Error ? err.message : String(err)
|
|
5238
|
+
};
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
async function detachStagedSkill(deps, name) {
|
|
5242
|
+
try {
|
|
5243
|
+
const skillsDir = deps.skillsDir();
|
|
5244
|
+
const dirName = name.split("/").pop() ?? name;
|
|
5245
|
+
const result = await deps.withSkillFsLock(async () => {
|
|
5246
|
+
const knownStaged = await isStillOurs(
|
|
5247
|
+
deps.stagedSkillDirs.get(dirName),
|
|
5248
|
+
join(deps.projectDir, skillsDir, dirName)
|
|
5249
|
+
);
|
|
5250
|
+
return unstageSkill(deps.projectDir, skillsDir, name, { knownStaged });
|
|
5251
|
+
});
|
|
5252
|
+
const live = deps.driverStarted();
|
|
5253
|
+
if ("reason" in result) {
|
|
5254
|
+
deps.log(
|
|
5255
|
+
`[serve] runner.detach_instance: "${result.name}" exists but was not staged by the runner \u2014 left in place`
|
|
5256
|
+
);
|
|
5257
|
+
return { ok: true, id: result.name, removed: false, live, reason: result.reason };
|
|
5258
|
+
}
|
|
5259
|
+
const wasTracked = deps.stagedSkillDirs.delete(result.name);
|
|
5260
|
+
if (!result.removedStaged && !wasTracked) {
|
|
5261
|
+
deps.log(`[serve] runner.detach_instance: skill "${result.name}" was not staged`);
|
|
5262
|
+
return { ok: true, id: result.name, removed: result.removedAsset, live };
|
|
5263
|
+
}
|
|
5264
|
+
deps.log(`[serve] runner.detach_instance unstaged skill: ${result.name}`);
|
|
5265
|
+
deps.scheduleSkillRestart([{ name: result.name, action: "remove" }]);
|
|
5266
|
+
return { ok: true, id: result.name, removed: true, live };
|
|
5267
|
+
} catch (err) {
|
|
5268
|
+
return {
|
|
5269
|
+
ok: false,
|
|
5270
|
+
code: "skill_detach_failed",
|
|
5271
|
+
message: err instanceof Error ? err.message : String(err)
|
|
5272
|
+
};
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
async function pathState(path6) {
|
|
5276
|
+
try {
|
|
5277
|
+
await withFsDeadline(`lstat ${path6}`, () => lstat(path6));
|
|
5278
|
+
return "present";
|
|
5279
|
+
} catch (err) {
|
|
5280
|
+
return err?.code === "ENOENT" ? "absent" : "unknown";
|
|
5281
|
+
}
|
|
5282
|
+
}
|
|
5283
|
+
async function removeUnlistedStagedSkills(deps, skillsDir) {
|
|
5284
|
+
const allowed = await readSkillAllowList(deps.projectDir);
|
|
5285
|
+
if (!allowed) return [];
|
|
5286
|
+
const root = join(deps.projectDir, skillsDir);
|
|
5287
|
+
const entries = await tryWithFsDeadline(
|
|
5288
|
+
`readdir ${root}`,
|
|
5289
|
+
() => readdir(root, { withFileTypes: true }),
|
|
5290
|
+
[]
|
|
5291
|
+
);
|
|
5292
|
+
const removed = [];
|
|
5293
|
+
for (const entry of entries) {
|
|
5294
|
+
if (!entry.isDirectory() || allowed.has(entry.name)) continue;
|
|
5295
|
+
try {
|
|
5296
|
+
const dir = join(root, entry.name);
|
|
5297
|
+
if (await pathState(join(deps.projectDir, ".skaile/assets/skill", entry.name)) !== "absent") {
|
|
5298
|
+
continue;
|
|
5299
|
+
}
|
|
5300
|
+
const knownStaged = await isStillOurs(deps.stagedSkillDirs.get(entry.name), dir);
|
|
5301
|
+
if (!knownStaged && !await isStagedSkillMarkerFor(dir, entry.name).catch(() => false))
|
|
5302
|
+
continue;
|
|
5303
|
+
const result = await unstageSkill(deps.projectDir, skillsDir, entry.name, {
|
|
5304
|
+
knownStaged,
|
|
5305
|
+
keepAsset: true
|
|
5306
|
+
});
|
|
5307
|
+
if ("reason" in result || !result.removedStaged) continue;
|
|
5308
|
+
deps.stagedSkillDirs.delete(result.name);
|
|
5309
|
+
removed.push(result.name);
|
|
5310
|
+
} catch (err) {
|
|
5311
|
+
deps.log(
|
|
5312
|
+
`[serve] could not remove unlisted skill "${entry.name}" (left in place): ${err instanceof Error ? err.message : String(err)}`
|
|
5313
|
+
);
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
return removed;
|
|
5317
|
+
}
|
|
5318
|
+
|
|
5015
5319
|
// runner/src/compaction-gate.ts
|
|
5016
5320
|
var CompactionGate = class {
|
|
5017
5321
|
/**
|
|
@@ -5125,7 +5429,7 @@ async function claimDriverForCompaction(deps) {
|
|
|
5125
5429
|
released = true;
|
|
5126
5430
|
deps.gate.settle(hold);
|
|
5127
5431
|
};
|
|
5128
|
-
const timeoutMs = deps
|
|
5432
|
+
const { timeoutMs } = deps;
|
|
5129
5433
|
if (await raceDeadline(deps.awaitClaimedTurns(), timeoutMs) !== "opened") {
|
|
5130
5434
|
release2();
|
|
5131
5435
|
deps.log(
|
|
@@ -5133,30 +5437,30 @@ async function claimDriverForCompaction(deps) {
|
|
|
5133
5437
|
);
|
|
5134
5438
|
return null;
|
|
5135
5439
|
}
|
|
5136
|
-
if (deps.
|
|
5440
|
+
if (deps.isDriverReplaced()) {
|
|
5137
5441
|
release2();
|
|
5138
|
-
deps.log("[serve] compaction skipped:
|
|
5442
|
+
deps.log("[serve] compaction skipped: its driver is being or has been replaced");
|
|
5139
5443
|
return null;
|
|
5140
5444
|
}
|
|
5141
|
-
const endTurn = deps.claimTurnSlot
|
|
5445
|
+
const endTurn = deps.claimTurnSlot();
|
|
5142
5446
|
return () => {
|
|
5143
|
-
endTurn
|
|
5447
|
+
endTurn();
|
|
5144
5448
|
release2();
|
|
5145
5449
|
};
|
|
5146
5450
|
}
|
|
5147
5451
|
var TURN_COMPACTION_YIELD_ATTEMPTS = 3;
|
|
5148
|
-
async function beginTurnClearOfCompaction(deps
|
|
5149
|
-
for (let attempt = 0; attempt <
|
|
5452
|
+
async function beginTurnClearOfCompaction(deps) {
|
|
5453
|
+
for (let attempt = 0; attempt < TURN_COMPACTION_YIELD_ATTEMPTS; attempt += 1) {
|
|
5150
5454
|
if (!await deps.awaitIdle()) return null;
|
|
5151
5455
|
const endTurn = await deps.claimTurn();
|
|
5152
5456
|
if (deps.gate.isIdle()) return endTurn;
|
|
5153
5457
|
endTurn();
|
|
5154
5458
|
}
|
|
5155
|
-
throw new Error(`turn overtaken by a compaction ${
|
|
5459
|
+
throw new Error(`turn overtaken by a compaction ${TURN_COMPACTION_YIELD_ATTEMPTS} times running`);
|
|
5156
5460
|
}
|
|
5157
5461
|
var COMPACTION_GATE_TIMEOUT_MESSAGE = "The session is still compacting its history and could not take this message. Send it again in a moment.";
|
|
5158
5462
|
async function guardTurnAgainstCompaction(deps) {
|
|
5159
|
-
const outcome = await deps.gate.awaitIdle(
|
|
5463
|
+
const outcome = await deps.gate.awaitIdle(compactionGateTimeoutMs());
|
|
5160
5464
|
if (outcome === "waited") deps.log(`[serve] ${deps.what} released after compaction settled`);
|
|
5161
5465
|
if (outcome !== "timeout") return true;
|
|
5162
5466
|
deps.log(`[serve] ${deps.what} abandoned: a compaction has held the driver past its bound`);
|
|
@@ -5277,103 +5581,23 @@ var DriverSwapGate = class {
|
|
|
5277
5581
|
beginSwap(recreate) {
|
|
5278
5582
|
this.activeDriverSwap = recreate;
|
|
5279
5583
|
const clear = () => {
|
|
5280
|
-
if (this.activeDriverSwap === recreate) this.activeDriverSwap = null;
|
|
5281
|
-
};
|
|
5282
|
-
recreate.then(clear, clear);
|
|
5283
|
-
}
|
|
5284
|
-
/**
|
|
5285
|
-
* Await the in-flight swap before reading the live driver. Re-checks in a loop
|
|
5286
|
-
* so a second swap starting during the wait is also awaited.
|
|
5287
|
-
*/
|
|
5288
|
-
async awaitSwap() {
|
|
5289
|
-
while (this.activeDriverSwap) {
|
|
5290
|
-
try {
|
|
5291
|
-
await this.activeDriverSwap;
|
|
5292
|
-
} catch {
|
|
5293
|
-
}
|
|
5294
|
-
}
|
|
5295
|
-
}
|
|
5296
|
-
};
|
|
5297
|
-
|
|
5298
|
-
// runner/src/init-build-hold.ts
|
|
5299
|
-
var DEFAULT_CONNECTOR_MUTATE_INIT_HOLD_MS = 1e4;
|
|
5300
|
-
function resolveConnectorMutateInitHoldMs(env = process.env) {
|
|
5301
|
-
const parsed = Number.parseInt(env.SKAILE_CONNECTOR_MUTATE_INIT_HOLD_MS ?? "", 10);
|
|
5302
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_CONNECTOR_MUTATE_INIT_HOLD_MS;
|
|
5303
|
-
}
|
|
5304
|
-
function createInitBuildHold(now = Date.now) {
|
|
5305
|
-
let current = null;
|
|
5306
|
-
let tail = Promise.resolve();
|
|
5307
|
-
let held = 0;
|
|
5308
|
-
const building = () => current !== null && !current.done;
|
|
5309
|
-
async function awaitNewestBuild() {
|
|
5310
|
-
for (; ; ) {
|
|
5311
|
-
const build = current;
|
|
5312
|
-
if (!build) return null;
|
|
5313
|
-
if (!build.done) await build.settled;
|
|
5314
|
-
if (current === build) return build.error;
|
|
5315
|
-
}
|
|
5584
|
+
if (this.activeDriverSwap === recreate) this.activeDriverSwap = null;
|
|
5585
|
+
};
|
|
5586
|
+
recreate.then(clear, clear);
|
|
5316
5587
|
}
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
};
|
|
5327
|
-
current = build;
|
|
5328
|
-
const settle = (error) => {
|
|
5329
|
-
if (build.done) return;
|
|
5330
|
-
build.done = true;
|
|
5331
|
-
build.error = error;
|
|
5332
|
-
resolve4();
|
|
5333
|
-
};
|
|
5334
|
-
return { succeed: () => settle(null), fail: (error) => settle(error) };
|
|
5335
|
-
},
|
|
5336
|
-
run(task, deadlineMs) {
|
|
5337
|
-
if (held === 0 && !building()) {
|
|
5338
|
-
if (current?.error) return task({ kind: "failed", error: current.error });
|
|
5339
|
-
return task({ kind: "ready", remainingMs: void 0 });
|
|
5588
|
+
/**
|
|
5589
|
+
* Await the in-flight swap before reading the live driver. Re-checks in a loop
|
|
5590
|
+
* so a second swap starting during the wait is also awaited.
|
|
5591
|
+
*/
|
|
5592
|
+
async awaitSwap() {
|
|
5593
|
+
while (this.activeDriverSwap) {
|
|
5594
|
+
try {
|
|
5595
|
+
await this.activeDriverSwap;
|
|
5596
|
+
} catch {
|
|
5340
5597
|
}
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
const turn = previous.then(awaitNewestBuild);
|
|
5345
|
-
let timer;
|
|
5346
|
-
const deadline = deadlineMs === void 0 ? null : new Promise((resolve4) => {
|
|
5347
|
-
timer = setTimeout(() => resolve4("timeout"), deadlineMs);
|
|
5348
|
-
timer.unref?.();
|
|
5349
|
-
});
|
|
5350
|
-
let markStarted;
|
|
5351
|
-
const started = new Promise((resolve4) => {
|
|
5352
|
-
markStarted = resolve4;
|
|
5353
|
-
});
|
|
5354
|
-
const result = (async () => {
|
|
5355
|
-
const first = deadline ? await Promise.race([turn, deadline]) : await turn;
|
|
5356
|
-
clearTimeout(timer);
|
|
5357
|
-
if (first === "timeout") {
|
|
5358
|
-
void turn.then(markStarted);
|
|
5359
|
-
return task({ kind: "timeout", waitedMs: now() - arrivedAt });
|
|
5360
|
-
}
|
|
5361
|
-
markStarted();
|
|
5362
|
-
if (first) return task({ kind: "failed", error: first });
|
|
5363
|
-
return task({
|
|
5364
|
-
kind: "ready",
|
|
5365
|
-
remainingMs: deadlineMs === void 0 ? void 0 : Math.max(0, deadlineMs - (now() - arrivedAt))
|
|
5366
|
-
});
|
|
5367
|
-
})();
|
|
5368
|
-
tail = started;
|
|
5369
|
-
void Promise.allSettled([turn, result]).then(() => {
|
|
5370
|
-
held--;
|
|
5371
|
-
});
|
|
5372
|
-
return result;
|
|
5373
|
-
},
|
|
5374
|
-
held: () => held
|
|
5375
|
-
};
|
|
5376
|
-
}
|
|
5598
|
+
}
|
|
5599
|
+
}
|
|
5600
|
+
};
|
|
5377
5601
|
|
|
5378
5602
|
// runner/src/pending-turns.ts
|
|
5379
5603
|
var PendingTurns = class {
|
|
@@ -5397,9 +5621,15 @@ var PendingTurns = class {
|
|
|
5397
5621
|
}
|
|
5398
5622
|
};
|
|
5399
5623
|
}
|
|
5400
|
-
/**
|
|
5401
|
-
|
|
5402
|
-
|
|
5624
|
+
/**
|
|
5625
|
+
* Whether to report idle now, at the end of something that ran on the driver.
|
|
5626
|
+
* A `"turn"` end belongs to a counted turn, which is still counted when it
|
|
5627
|
+
* fires. A `"compaction"` end (the compaction turn, or the snapshot turn after
|
|
5628
|
+
* it) is no counted turn, so every counted turn is waiting behind it.
|
|
5629
|
+
*/
|
|
5630
|
+
shouldReportIdle(endedBy) {
|
|
5631
|
+
const own = endedBy === "turn" ? 1 : 0;
|
|
5632
|
+
if (this.count > own) {
|
|
5403
5633
|
this.idleOwed = true;
|
|
5404
5634
|
return false;
|
|
5405
5635
|
}
|
|
@@ -5467,248 +5697,298 @@ var PromptTurnQueue = class {
|
|
|
5467
5697
|
}
|
|
5468
5698
|
};
|
|
5469
5699
|
|
|
5470
|
-
// runner/src/
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5700
|
+
// runner/src/turn-scheduler.ts
|
|
5701
|
+
var FLOW_TURN_COMPACTION_TIMEOUT = "Flow turn abandoned: a compaction held the driver";
|
|
5702
|
+
var TurnScheduler = class {
|
|
5703
|
+
constructor(deps) {
|
|
5704
|
+
this.deps = deps;
|
|
5705
|
+
}
|
|
5706
|
+
deps;
|
|
5707
|
+
swaps = new DriverSwapGate();
|
|
5708
|
+
compactions = new CompactionGate();
|
|
5709
|
+
pending = new PendingTurns(() => this.sendIdle());
|
|
5710
|
+
queue = new PromptTurnQueue();
|
|
5711
|
+
/** The compaction that armed the event suppression; null while none runs. */
|
|
5712
|
+
suppressedBy = null;
|
|
5713
|
+
/** Compactions past their end callback and not yet settled: a snapshot turn may still run. */
|
|
5714
|
+
snapshotTurns = /* @__PURE__ */ new Set();
|
|
5715
|
+
/** Counts {@link compactionHooks} calls; only the latest hooks may start a compaction. */
|
|
5716
|
+
hooksGeneration = 0;
|
|
5717
|
+
/** Run a chat prompt: queue it, wait out swaps and compactions, claim the driver, dispatch. */
|
|
5718
|
+
prompt(turn) {
|
|
5719
|
+
return this.counted(async () => {
|
|
5720
|
+
const place = this.queue.join(turn.owner);
|
|
5721
|
+
try {
|
|
5722
|
+
if (place.queued) {
|
|
5723
|
+
turn.onQueued?.();
|
|
5724
|
+
const queuedAt = Date.now();
|
|
5725
|
+
await place.ready;
|
|
5726
|
+
this.deps.logPhase("prompt_queue_wait", queuedAt, { dropped: place.dropped });
|
|
5727
|
+
if (place.dropped) return;
|
|
5728
|
+
}
|
|
5729
|
+
await this.runPrompt(turn, place.leave);
|
|
5730
|
+
} finally {
|
|
5731
|
+
place.leave();
|
|
5732
|
+
}
|
|
5486
5733
|
});
|
|
5487
|
-
waiting = run;
|
|
5488
|
-
return run;
|
|
5489
|
-
};
|
|
5490
|
-
}
|
|
5491
|
-
async function recordStagedSkills(staged, projectDir, skillsDir, names, timeoutMs) {
|
|
5492
|
-
for (const name of names) {
|
|
5493
|
-
const path6 = join(projectDir, skillsDir, name);
|
|
5494
|
-
const st = await tryWithFsDeadline(`lstat ${path6}`, () => lstat(path6), null, timeoutMs);
|
|
5495
|
-
staged.set(
|
|
5496
|
-
name,
|
|
5497
|
-
st?.isDirectory() && st.birthtimeMs > 0 ? { path: path6, dev: st.dev, ino: st.ino, birthtimeMs: st.birthtimeMs } : null
|
|
5498
|
-
);
|
|
5499
5734
|
}
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5735
|
+
/**
|
|
5736
|
+
* Run a question reply. A paused question takes the answer at once, ahead of
|
|
5737
|
+
* every wait. A recreate waits for the paused turn, and that turn waits for
|
|
5738
|
+
* this answer, so gating the answer on the swap wedges the session for good.
|
|
5739
|
+
* Anything else is a fresh turn and queues like a prompt.
|
|
5740
|
+
*/
|
|
5741
|
+
reply(turn) {
|
|
5742
|
+
return this.counted(async () => {
|
|
5743
|
+
if (!await turn.admit()) return;
|
|
5744
|
+
const paused = this.deps.getDriver();
|
|
5745
|
+
if (paused.hasPendingQuestion()) {
|
|
5746
|
+
if (paused.answerQuestion(turn.answer, turn.question, turn.requestId)) {
|
|
5747
|
+
turn.onAnswered?.();
|
|
5748
|
+
return;
|
|
5749
|
+
}
|
|
5750
|
+
} else {
|
|
5751
|
+
await this.swaps.awaitSwap();
|
|
5752
|
+
}
|
|
5753
|
+
if (!this.deps.getDriver().acceptsReplyAsPrompt) {
|
|
5754
|
+
if (!this.deps.getDriver().hasPendingQuestion()) {
|
|
5755
|
+
this.deps.log("[serve] reply: driver takes no reply as a prompt; answer not delivered");
|
|
5756
|
+
this.deps.sendEvent({
|
|
5757
|
+
type: "error",
|
|
5758
|
+
message: "This question is no longer open, so the agent did not get your answer. Send it as a new message.",
|
|
5759
|
+
fatal: false
|
|
5760
|
+
});
|
|
5761
|
+
}
|
|
5762
|
+
return;
|
|
5763
|
+
}
|
|
5764
|
+
let endTurn;
|
|
5765
|
+
try {
|
|
5766
|
+
endTurn = await this.claim("reply", () => this.deps.ensureDriverStarted());
|
|
5767
|
+
} catch (err) {
|
|
5768
|
+
this.deps.sendEvent(replyFailed(err));
|
|
5769
|
+
return;
|
|
5770
|
+
}
|
|
5771
|
+
if (!endTurn) return;
|
|
5772
|
+
try {
|
|
5773
|
+
await this.deps.getDriver().prompt(freshTurnReplyPrompt(turn.answer, turn.question));
|
|
5774
|
+
} catch (err) {
|
|
5775
|
+
this.deps.sendEvent(replyFailed(err));
|
|
5776
|
+
} finally {
|
|
5777
|
+
endTurn();
|
|
5778
|
+
}
|
|
5779
|
+
});
|
|
5511
5780
|
}
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5781
|
+
/**
|
|
5782
|
+
* Run one flow turn and resolve on its `agent_end`.
|
|
5783
|
+
*
|
|
5784
|
+
* Waits out a pending swap, any compaction, and every turn already in flight.
|
|
5785
|
+
* The in-flight wait is what makes the `agent_end` listener safe: a flow
|
|
5786
|
+
* started from inside a chat turn would otherwise resolve on that turn's end.
|
|
5787
|
+
* The slot is held for the whole turn, never across a wait, which would stall
|
|
5788
|
+
* a swap behind a compaction.
|
|
5789
|
+
*/
|
|
5790
|
+
flowTurn(prompt, timeoutMs) {
|
|
5791
|
+
return this.counted(async () => {
|
|
5792
|
+
for (; ; ) {
|
|
5793
|
+
await this.swaps.awaitSwap();
|
|
5794
|
+
if (!await this.awaitCompactionIdle("flow turn"))
|
|
5795
|
+
throw new Error(FLOW_TURN_COMPACTION_TIMEOUT);
|
|
5796
|
+
const endTurn = await this.swaps.beginQueuedTurn();
|
|
5797
|
+
if (this.swaps.isSwapping() || !this.compactions.isIdle()) {
|
|
5798
|
+
endTurn();
|
|
5799
|
+
continue;
|
|
5800
|
+
}
|
|
5525
5801
|
try {
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
const buf = Buffer.alloc(DIGEST_CHUNK_BYTES);
|
|
5530
|
-
let total = 0;
|
|
5531
|
-
for (; ; ) {
|
|
5532
|
-
const { bytesRead } = await fh.read(buf, 0, buf.length, null);
|
|
5533
|
-
if (bytesRead === 0) break;
|
|
5534
|
-
total += bytesRead;
|
|
5535
|
-
if (total > budget) throw new Error("skill too large to digest");
|
|
5536
|
-
hash.update(buf.subarray(0, bytesRead));
|
|
5537
|
-
}
|
|
5538
|
-
budget -= total;
|
|
5539
|
-
hash.update(`\0${total}\0`);
|
|
5802
|
+
await this.deps.ensureDriverStarted();
|
|
5803
|
+
await awaitAgentEnd(this.deps.getDriver(), prompt, timeoutMs);
|
|
5804
|
+
return;
|
|
5540
5805
|
} finally {
|
|
5541
|
-
|
|
5542
|
-
}
|
|
5543
|
-
};
|
|
5544
|
-
const walk = async (rel) => {
|
|
5545
|
-
const here = rel ? join(dir, rel) : dir;
|
|
5546
|
-
if (rel && !(await lstat(here)).isDirectory()) throw new Error(`not a dir: ${here}`);
|
|
5547
|
-
const entries = await readdir(here, { withFileTypes: true });
|
|
5548
|
-
entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
5549
|
-
for (const entry of entries) {
|
|
5550
|
-
if (!rel && entry.name === STAGED_SKILL_MARKER) continue;
|
|
5551
|
-
const path6 = rel ? `${rel}/${entry.name}` : entry.name;
|
|
5552
|
-
if (entry.isDirectory()) {
|
|
5553
|
-
hash.update(`d\0${path6}\0`);
|
|
5554
|
-
await walk(path6);
|
|
5555
|
-
} else if (entry.isSymbolicLink()) {
|
|
5556
|
-
hash.update(`l\0${path6}\0${await readlink(join(dir, path6))}\0`);
|
|
5557
|
-
} else if (entry.isFile()) {
|
|
5558
|
-
hash.update(`f\0${path6}\0`);
|
|
5559
|
-
await hashFile(join(dir, path6));
|
|
5560
|
-
} else {
|
|
5561
|
-
hash.update(`o\0${path6}\0`);
|
|
5562
|
-
}
|
|
5806
|
+
endTurn();
|
|
5563
5807
|
}
|
|
5564
|
-
};
|
|
5565
|
-
await walk("");
|
|
5566
|
-
return hash.digest("hex");
|
|
5567
|
-
},
|
|
5568
|
-
null,
|
|
5569
|
-
fsDeadlineMs() * DIGEST_DEADLINE_FACTOR
|
|
5570
|
-
);
|
|
5571
|
-
}
|
|
5572
|
-
async function attachStagedSkill(deps, name) {
|
|
5573
|
-
try {
|
|
5574
|
-
const skillsDir = deps.skillsDir();
|
|
5575
|
-
const dirName = name.includes("/") ? name.split("/").pop() : name;
|
|
5576
|
-
const { staged, unchanged } = await deps.withSkillFsLock(async () => {
|
|
5577
|
-
const dest = join(deps.projectDir, skillsDir, dirName);
|
|
5578
|
-
const loaded = deps.stagedSkillDirs.has(dirName) ? deps.loadedSkillDigests.get(dirName) : void 0;
|
|
5579
|
-
const names = await stageMaterializedSkills(deps.projectDir, skillsDir, { declared: [name] });
|
|
5580
|
-
let same = false;
|
|
5581
|
-
if (names.includes(dirName)) {
|
|
5582
|
-
const digest = await stagedSkillDigest(dest);
|
|
5583
|
-
same = digest !== null && loaded?.path === dest && loaded.digest === digest;
|
|
5584
|
-
if (!same) deps.loadedSkillDigests.set(dirName, { path: dest, digest });
|
|
5585
5808
|
}
|
|
5586
|
-
await recordStagedSkills(deps.stagedSkillDirs, deps.projectDir, skillsDir, names);
|
|
5587
|
-
return { staged: names, unchanged: same ? dirName : null };
|
|
5588
5809
|
});
|
|
5589
|
-
if (staged.length === 0) {
|
|
5590
|
-
return {
|
|
5591
|
-
ok: false,
|
|
5592
|
-
code: "skill_not_materialized",
|
|
5593
|
-
message: `no materialized skill matching "${name}" under .skaile/assets/skill`
|
|
5594
|
-
};
|
|
5595
|
-
}
|
|
5596
|
-
const live = deps.driverStarted();
|
|
5597
|
-
const toRestart = staged.filter((s) => s !== unchanged);
|
|
5598
|
-
if (toRestart.length === 0) {
|
|
5599
|
-
deps.log(
|
|
5600
|
-
`[serve] runner.attach_instance: skill ${staged.join(", ")} already staged and unchanged \u2014 no driver restart`
|
|
5601
|
-
);
|
|
5602
|
-
return { ok: true, id: name, live, toolCount: 0 };
|
|
5603
|
-
}
|
|
5604
|
-
deps.log(`[serve] runner.attach_instance staged skill(s): ${toRestart.join(", ")}`);
|
|
5605
|
-
deps.scheduleSkillRestart(toRestart.map((s) => ({ name: s, action: "add" })));
|
|
5606
|
-
return { ok: true, id: name, live, toolCount: 0 };
|
|
5607
|
-
} catch (err) {
|
|
5608
|
-
return {
|
|
5609
|
-
ok: false,
|
|
5610
|
-
code: "skill_attach_failed",
|
|
5611
|
-
message: err instanceof Error ? err.message : String(err)
|
|
5612
|
-
};
|
|
5613
5810
|
}
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5811
|
+
/**
|
|
5812
|
+
* Run a driver swap (recreate): queued behind every earlier swap, then behind
|
|
5813
|
+
* every turn holding a slot. Prompts defer to it from the moment it is
|
|
5814
|
+
* registered. Never call from inside a swap: it would wait on itself.
|
|
5815
|
+
*/
|
|
5816
|
+
runSwap(swap) {
|
|
5817
|
+
return this.swaps.runSwap(swap);
|
|
5818
|
+
}
|
|
5819
|
+
/**
|
|
5820
|
+
* The driver ended a turn. Reports idle unless a compaction suppresses it, or
|
|
5821
|
+
* more turns are queued behind this one, in which case it is owed and goes
|
|
5822
|
+
* out when the last of them settles.
|
|
5823
|
+
*/
|
|
5824
|
+
reportTurnEnd() {
|
|
5825
|
+
this.reportIdleIfDrained(this.snapshotTurns.size > 0 ? "compaction" : "turn");
|
|
5826
|
+
}
|
|
5827
|
+
/**
|
|
5828
|
+
* Drop every prompt `senderId` has waiting, in queue order. The prompt whose
|
|
5829
|
+
* turn is running is not waiting, and a prompt with no sender is nobody's to drop.
|
|
5830
|
+
*/
|
|
5831
|
+
dropQueuedPromptsFrom(senderId) {
|
|
5832
|
+
return this.queue.dropQueuedFrom(senderId);
|
|
5833
|
+
}
|
|
5834
|
+
/** Turns taken on and not yet settled, waiting ones included. */
|
|
5835
|
+
get pendingTurns() {
|
|
5836
|
+
return this.pending.size;
|
|
5837
|
+
}
|
|
5838
|
+
/**
|
|
5839
|
+
* Whether a compaction is running, from its start until its end callback: the
|
|
5840
|
+
* host must not see the compaction turn's events, `status: idle` included.
|
|
5841
|
+
*/
|
|
5842
|
+
get isCompacting() {
|
|
5843
|
+
return this.suppressedBy !== null;
|
|
5844
|
+
}
|
|
5845
|
+
/**
|
|
5846
|
+
* The hooks one compaction orchestrator wires to take part in scheduling: it
|
|
5847
|
+
* claims the driver before it starts, holds user turns off from its start
|
|
5848
|
+
* until it has settled, and suppresses turn events from its start until its
|
|
5849
|
+
* end. Call once per orchestrator; a newer call retires the hooks before it,
|
|
5850
|
+
* so a stale orchestrator (its driver replaced by a swap) can no longer
|
|
5851
|
+
* start a compaction.
|
|
5852
|
+
*/
|
|
5853
|
+
compactionHooks() {
|
|
5854
|
+
const generation = ++this.hooksGeneration;
|
|
5855
|
+
const superseded = () => generation !== this.hooksGeneration;
|
|
5856
|
+
let hold = null;
|
|
5642
5857
|
return {
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5858
|
+
// A user turn that already holds a slot keeps the driver; the compaction
|
|
5859
|
+
// waits for it rather than prompting the driver under it. A platform call
|
|
5860
|
+
// waits briefly: a turn paused on a question can hold its slot for hours.
|
|
5861
|
+
claimDriver: async (trigger) => {
|
|
5862
|
+
if (superseded()) {
|
|
5863
|
+
this.deps.log("[serve] compaction skipped: its driver has been replaced");
|
|
5864
|
+
return null;
|
|
5865
|
+
}
|
|
5866
|
+
return claimDriverForCompaction({
|
|
5867
|
+
gate: this.compactions,
|
|
5868
|
+
awaitClaimedTurns: () => this.swaps.awaitActiveTurn(),
|
|
5869
|
+
isDriverReplaced: () => this.swaps.isSwapping() || superseded(),
|
|
5870
|
+
claimTurnSlot: () => this.swaps.beginTurn(),
|
|
5871
|
+
log: this.deps.log,
|
|
5872
|
+
timeoutMs: compactionTurnWaitFor(trigger)
|
|
5873
|
+
});
|
|
5874
|
+
},
|
|
5875
|
+
onCompactionStart: (trigger) => {
|
|
5876
|
+
hold = this.compactions.begin();
|
|
5877
|
+
this.suppressedBy = hold;
|
|
5878
|
+
this.deps.sendEvent({ type: "status", phase: "compacting" });
|
|
5879
|
+
this.deps.log(`[serve] compaction started (trigger=${trigger})`);
|
|
5880
|
+
},
|
|
5881
|
+
onCompactionEnd: () => {
|
|
5882
|
+
if (hold === null || this.suppressedBy !== hold) return;
|
|
5883
|
+
this.suppressedBy = null;
|
|
5884
|
+
this.snapshotTurns.add(hold);
|
|
5885
|
+
this.reportIdleIfDrained("compaction");
|
|
5886
|
+
},
|
|
5887
|
+
onCompactionSettled: () => {
|
|
5888
|
+
if (hold !== null && this.suppressedBy === hold) this.suppressedBy = null;
|
|
5889
|
+
if (hold !== null) this.snapshotTurns.delete(hold);
|
|
5890
|
+
this.compactions.settle(hold);
|
|
5891
|
+
hold = null;
|
|
5892
|
+
}
|
|
5646
5893
|
};
|
|
5647
5894
|
}
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
const root = join(deps.projectDir, skillsDir);
|
|
5661
|
-
const entries = await tryWithFsDeadline(
|
|
5662
|
-
`readdir ${root}`,
|
|
5663
|
-
() => readdir(root, { withFileTypes: true }),
|
|
5664
|
-
[]
|
|
5665
|
-
);
|
|
5666
|
-
const removed = [];
|
|
5667
|
-
for (const entry of entries) {
|
|
5668
|
-
if (!entry.isDirectory() || allowed.has(entry.name)) continue;
|
|
5669
|
-
try {
|
|
5670
|
-
const dir = join(root, entry.name);
|
|
5671
|
-
if (await pathState(join(deps.projectDir, ".skaile/assets/skill", entry.name)) !== "absent") {
|
|
5672
|
-
continue;
|
|
5895
|
+
async runPrompt(turn, leaveQueue) {
|
|
5896
|
+
if (!await turn.admit()) return;
|
|
5897
|
+
await this.swaps.awaitSwap();
|
|
5898
|
+
if (!await this.awaitCompactionIdle("prompt")) return;
|
|
5899
|
+
const handOff = await turn.route();
|
|
5900
|
+
if (handOff === false) return;
|
|
5901
|
+
if (handOff) {
|
|
5902
|
+
leaveQueue();
|
|
5903
|
+
try {
|
|
5904
|
+
await handOff();
|
|
5905
|
+
} finally {
|
|
5906
|
+
this.reportIdleIfDrained("turn");
|
|
5673
5907
|
}
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5908
|
+
return;
|
|
5909
|
+
}
|
|
5910
|
+
const startedAt = Date.now();
|
|
5911
|
+
let ok = false;
|
|
5912
|
+
let attempts = 0;
|
|
5913
|
+
let endTurn;
|
|
5914
|
+
try {
|
|
5915
|
+
endTurn = await this.claim("prompt", () => {
|
|
5916
|
+
attempts += 1;
|
|
5917
|
+
return this.deps.ensureDriverStarted();
|
|
5680
5918
|
});
|
|
5681
|
-
|
|
5682
|
-
deps.stagedSkillDirs.delete(result.name);
|
|
5683
|
-
removed.push(result.name);
|
|
5919
|
+
ok = endTurn !== null;
|
|
5684
5920
|
} catch (err) {
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5921
|
+
const message = errorMessage2(err);
|
|
5922
|
+
this.deps.log(`[serve] driver start failed: ${message}`);
|
|
5923
|
+
this.deps.sendEvent({
|
|
5924
|
+
type: "error",
|
|
5925
|
+
message: `Driver start failed: ${message}`,
|
|
5926
|
+
fatal: true
|
|
5927
|
+
});
|
|
5928
|
+
return;
|
|
5929
|
+
} finally {
|
|
5930
|
+
this.deps.logPhase("driver_start", startedAt, { ok, attempts });
|
|
5688
5931
|
}
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
await deps.gate.awaitSwap();
|
|
5698
|
-
if (!await deps.awaitCompactionIdle()) throw new Error(FLOW_TURN_COMPACTION_TIMEOUT);
|
|
5699
|
-
const endTurn = await deps.gate.beginQueuedTurn();
|
|
5700
|
-
if (deps.gate.isSwapping() || deps.isCompacting()) {
|
|
5932
|
+
if (!endTurn) return;
|
|
5933
|
+
try {
|
|
5934
|
+
await turn.dispatch();
|
|
5935
|
+
} catch (err) {
|
|
5936
|
+
const message = errorMessage2(err);
|
|
5937
|
+
this.deps.log(`[serve] prompt failed: ${message}`);
|
|
5938
|
+
this.deps.sendEvent({ type: "error", message: `Prompt failed: ${message}`, fatal: true });
|
|
5939
|
+
} finally {
|
|
5701
5940
|
endTurn();
|
|
5702
|
-
continue;
|
|
5703
5941
|
}
|
|
5942
|
+
}
|
|
5943
|
+
/** Claim a turn slot on a live driver no swap or compaction occupies. `null`: turn abandoned. */
|
|
5944
|
+
claim(what, prepare) {
|
|
5945
|
+
return beginTurnClearOfCompaction({
|
|
5946
|
+
gate: this.compactions,
|
|
5947
|
+
awaitIdle: () => this.awaitCompactionIdle(what),
|
|
5948
|
+
claimTurn: () => this.swaps.beginTurnOnLiveDriver(prepare)
|
|
5949
|
+
});
|
|
5950
|
+
}
|
|
5951
|
+
/** `false` when a compaction held the driver past its bound; the abandon is already reported. */
|
|
5952
|
+
awaitCompactionIdle(what) {
|
|
5953
|
+
return guardTurnAgainstCompaction({
|
|
5954
|
+
gate: this.compactions,
|
|
5955
|
+
what,
|
|
5956
|
+
log: this.deps.log,
|
|
5957
|
+
sendEvent: this.deps.sendEvent
|
|
5958
|
+
});
|
|
5959
|
+
}
|
|
5960
|
+
/** Count a turn from receipt until its handler settles, so waiting turns count as queued. */
|
|
5961
|
+
async counted(run) {
|
|
5962
|
+
const end = this.pending.begin();
|
|
5704
5963
|
try {
|
|
5705
|
-
await
|
|
5706
|
-
await awaitAgentEnd(deps.getDriver(), prompt, timeoutMs);
|
|
5707
|
-
return;
|
|
5964
|
+
return await run();
|
|
5708
5965
|
} finally {
|
|
5709
|
-
|
|
5966
|
+
end();
|
|
5710
5967
|
}
|
|
5711
5968
|
}
|
|
5969
|
+
/** Idle unless a compaction suppresses events or more turns are queued, in which case it is owed. */
|
|
5970
|
+
reportIdleIfDrained(endedBy) {
|
|
5971
|
+
if (this.suppressedBy) return;
|
|
5972
|
+
if (this.pending.shouldReportIdle(endedBy)) this.sendIdle();
|
|
5973
|
+
}
|
|
5974
|
+
/** The only `status: idle` emit site. Silent while a compaction suppresses turn events. */
|
|
5975
|
+
sendIdle() {
|
|
5976
|
+
if (this.suppressedBy) return;
|
|
5977
|
+
this.deps.sendEvent({ type: "status", phase: "idle" });
|
|
5978
|
+
}
|
|
5979
|
+
};
|
|
5980
|
+
function errorMessage2(err) {
|
|
5981
|
+
return err instanceof Error ? err.message : String(err);
|
|
5982
|
+
}
|
|
5983
|
+
function replyFailed(err) {
|
|
5984
|
+
return { type: "error", message: `Reply failed: ${errorMessage2(err)}`, fatal: false };
|
|
5985
|
+
}
|
|
5986
|
+
function freshTurnReplyPrompt(answer, question) {
|
|
5987
|
+
const asked = question?.replace(/\s+/g, " ").trim();
|
|
5988
|
+
if (!asked) return answer;
|
|
5989
|
+
return `${answer}
|
|
5990
|
+
|
|
5991
|
+
(The answer above is to your question "${asked}")`;
|
|
5712
5992
|
}
|
|
5713
5993
|
function awaitAgentEnd(driver, prompt, timeoutMs) {
|
|
5714
5994
|
return new Promise((resolve4, reject) => {
|
|
@@ -5737,25 +6017,6 @@ function awaitAgentEnd(driver, prompt, timeoutMs) {
|
|
|
5737
6017
|
});
|
|
5738
6018
|
}
|
|
5739
6019
|
|
|
5740
|
-
// runner/src/reply-routing.ts
|
|
5741
|
-
async function routeReply(deps) {
|
|
5742
|
-
const current = deps.getDriver();
|
|
5743
|
-
if (current.hasPendingQuestion()) {
|
|
5744
|
-
if (!current.answerQuestion(deps.answer, deps.question, deps.requestId)) return "fresh-turn";
|
|
5745
|
-
deps.onAnswered?.();
|
|
5746
|
-
return "answered";
|
|
5747
|
-
}
|
|
5748
|
-
await deps.awaitSwap();
|
|
5749
|
-
return "fresh-turn";
|
|
5750
|
-
}
|
|
5751
|
-
function freshTurnReplyPrompt(answer, question) {
|
|
5752
|
-
const asked = question?.replace(/\s+/g, " ").trim();
|
|
5753
|
-
if (!asked) return answer;
|
|
5754
|
-
return `${answer}
|
|
5755
|
-
|
|
5756
|
-
(The answer above is to your question "${asked}")`;
|
|
5757
|
-
}
|
|
5758
|
-
|
|
5759
6020
|
// runner/src/event-gap-buffer.ts
|
|
5760
6021
|
var EVENT_GAP_BUFFER_MAX_EVENTS = 1e4;
|
|
5761
6022
|
var EVENT_GAP_BUFFER_MAX_BYTES = 16 * 1024 * 1024;
|
|
@@ -6738,7 +6999,8 @@ function selectClaudeCodeCredentialsSecret(secrets, selection) {
|
|
|
6738
6999
|
const legacy = secrets[CLAUDE_CODE_CREDENTIALS_KEY];
|
|
6739
7000
|
if (legacy) return { key: CLAUDE_CODE_CREDENTIALS_KEY, value: legacy };
|
|
6740
7001
|
if (!selection?.registry) return void 0;
|
|
6741
|
-
if (selection.driver && selection.driver
|
|
7002
|
+
if (selection.driver && !driverCapabilities(selection.driver).claudeCodeCredentials)
|
|
7003
|
+
return void 0;
|
|
6742
7004
|
const entries = registryEntries(selection.registry).map(
|
|
6743
7005
|
([id, entry2]) => [id, { ...entry2, kind: entryKind(entry2) }]
|
|
6744
7006
|
);
|
|
@@ -8480,9 +8742,6 @@ function pickRepointedManager(next, current, disposed) {
|
|
|
8480
8742
|
if (current !== null && current === disposed) return null;
|
|
8481
8743
|
return current;
|
|
8482
8744
|
}
|
|
8483
|
-
function supportsLiveToolUpdates(driverType, managedCodex = false) {
|
|
8484
|
-
return driverType !== "claude-sdk" && !(driverType === "codex" && managedCodex);
|
|
8485
|
-
}
|
|
8486
8745
|
function buildResourcesAvailablePayload(manager, mcpManager, driverLive, bakedServerIds) {
|
|
8487
8746
|
const { mounts, connectors } = splitConnectorsForWire(manager);
|
|
8488
8747
|
const mcp_servers = (mcpManager?.listServers() ?? []).map((s) => ({
|
|
@@ -8491,19 +8750,16 @@ function buildResourcesAvailablePayload(manager, mcpManager, driverLive, bakedSe
|
|
|
8491
8750
|
}));
|
|
8492
8751
|
return { type: "resources_available", mounts, connectors, mcp_servers, sessionRoot: true };
|
|
8493
8752
|
}
|
|
8494
|
-
function isTerminalFlowStatus(status) {
|
|
8495
|
-
return status === "complete" || status === "cancelled";
|
|
8496
|
-
}
|
|
8497
8753
|
function hasNonTerminalFlow(flows) {
|
|
8498
8754
|
for (const f of flows) {
|
|
8499
|
-
if (!
|
|
8755
|
+
if (!f.adapter.turnRule(f.handle).terminal) return true;
|
|
8500
8756
|
}
|
|
8501
8757
|
return false;
|
|
8502
8758
|
}
|
|
8503
8759
|
function registerActiveFlow(flows, runId, entry) {
|
|
8504
8760
|
const removed = [];
|
|
8505
8761
|
for (const [key, existing] of flows) {
|
|
8506
|
-
if (
|
|
8762
|
+
if (existing.adapter.turnRule(existing.handle).terminal) {
|
|
8507
8763
|
flows.delete(key);
|
|
8508
8764
|
removed.push(key);
|
|
8509
8765
|
}
|
|
@@ -8515,21 +8771,18 @@ function pickFlowToolTarget(flows, manager) {
|
|
|
8515
8771
|
let latest;
|
|
8516
8772
|
for (const entry of flows) latest = entry;
|
|
8517
8773
|
if (!latest || !manager) return null;
|
|
8518
|
-
if (
|
|
8774
|
+
if (latest.adapter.turnRule(latest.handle).terminal) return null;
|
|
8519
8775
|
return { manager, connectorId: latest.connectorId };
|
|
8520
8776
|
}
|
|
8521
|
-
function flowRunDrivesTurns(execution) {
|
|
8522
|
-
return !(execution.done || execution.status === "failed" || isTerminalFlowStatus(execution.status));
|
|
8523
|
-
}
|
|
8524
8777
|
function pickChatFlowTarget(flows) {
|
|
8525
8778
|
let latest;
|
|
8526
8779
|
for (const entry of flows) latest = entry;
|
|
8527
8780
|
if (!latest) return null;
|
|
8528
|
-
if (!
|
|
8781
|
+
if (!latest.adapter.turnRule(latest.handle).acceptsTurn) return null;
|
|
8529
8782
|
return latest;
|
|
8530
8783
|
}
|
|
8531
8784
|
function flowStartNeedsDriverRestart(state) {
|
|
8532
|
-
return state.driverStarted && state.driverType
|
|
8785
|
+
return state.driverStarted && driverCapabilities(state.driverType).inProcessMcpServers && !state.flowToolsBaked;
|
|
8533
8786
|
}
|
|
8534
8787
|
async function setUpFlowConnector(deps) {
|
|
8535
8788
|
const recreated = await deps.recreateForFlowTools();
|
|
@@ -8540,8 +8793,8 @@ async function setUpFlowConnector(deps) {
|
|
|
8540
8793
|
async function recreateKeepingLiveFlows(flows, deps) {
|
|
8541
8794
|
const live = [];
|
|
8542
8795
|
for (const { runId, connectorId, flowDef, adapter, handle } of flows) {
|
|
8796
|
+
if (adapter.turnRule(handle).terminal) continue;
|
|
8543
8797
|
const execution = adapter.getExecution(handle);
|
|
8544
|
-
if (isTerminalFlowStatus(execution.status)) continue;
|
|
8545
8798
|
live.push({ runId, connectorId, flowDef, execution: structuredClone(execution) });
|
|
8546
8799
|
}
|
|
8547
8800
|
await deps.recreate();
|
|
@@ -8562,7 +8815,7 @@ async function recreateKeepingLiveFlows(flows, deps) {
|
|
|
8562
8815
|
return reconnected;
|
|
8563
8816
|
}
|
|
8564
8817
|
function reconnectedRunNeedsAgentTurn(state) {
|
|
8565
|
-
return state.cutDriverWork && state.
|
|
8818
|
+
return state.cutDriverWork && state.restoreKick === "agent_work" && !state.busHasTurn && !state.promptQueuedForRun;
|
|
8566
8819
|
}
|
|
8567
8820
|
var DRIVER_ACTIVITY_EVENTS = /* @__PURE__ */ new Set([
|
|
8568
8821
|
"message_start",
|
|
@@ -8965,11 +9218,11 @@ function toActiveFlowTarget(entry) {
|
|
|
8965
9218
|
runId: entry.runId,
|
|
8966
9219
|
connectorId: entry.connectorId,
|
|
8967
9220
|
hydratedStateChanged: entry.hydratedStateChanged,
|
|
8968
|
-
|
|
9221
|
+
restoreKick: entry.adapter.turnRule(entry.handle).restoreKick
|
|
8969
9222
|
};
|
|
8970
9223
|
}
|
|
8971
9224
|
function restoredRunHasWorkToResume(target) {
|
|
8972
|
-
return target.hydratedStateChanged === true || target.
|
|
9225
|
+
return target.hydratedStateChanged === true || target.restoreKick === "runtime_work";
|
|
8973
9226
|
}
|
|
8974
9227
|
async function executeConnectorMutate(cmd, deps) {
|
|
8975
9228
|
let acked = false;
|
|
@@ -9158,7 +9411,7 @@ async function applyConnectorMutate(cmd, deps, respond, connectorWaitMs) {
|
|
|
9158
9411
|
} else if (cmd.op === "hydrate") {
|
|
9159
9412
|
const active = deps.flowState().activeFlow;
|
|
9160
9413
|
const changed = typeof result === "string" && JSON.stringify(payload.state) !== result;
|
|
9161
|
-
if (active && (changed || active.
|
|
9414
|
+
if (active && (changed || active.restoreKick === "runtime_work")) {
|
|
9162
9415
|
deps.signalStimulus(active, { kind: "resumed_after_hibernation" });
|
|
9163
9416
|
}
|
|
9164
9417
|
}
|
|
@@ -9577,7 +9830,7 @@ async function startAgentServer(opts) {
|
|
|
9577
9830
|
return {
|
|
9578
9831
|
projectDir: opts.projectDir,
|
|
9579
9832
|
agentDir,
|
|
9580
|
-
driver: managedCodex ?
|
|
9833
|
+
driver: managedCodex ? wireAgentConfig?.driver : opts.driver ?? wireAgentConfig?.driver,
|
|
9581
9834
|
model: managedCodex ? wireAgentConfig?.model : opts.model ?? wireAgentConfig?.model,
|
|
9582
9835
|
// The control-plane registry layer, normalized to the bare `id → entry`
|
|
9583
9836
|
// map the session builder layers `providers.yml` under.
|
|
@@ -9893,18 +10146,17 @@ async function startAgentServer(opts) {
|
|
|
9893
10146
|
}
|
|
9894
10147
|
const normalizer = new EventNormalizer();
|
|
9895
10148
|
function forwardNormalizedEvent(event) {
|
|
9896
|
-
if (
|
|
10149
|
+
if (turnScheduler.isCompacting) return;
|
|
9897
10150
|
contextUsage.observeEvent(event);
|
|
9898
|
-
|
|
9899
|
-
if (!isTransient) {
|
|
10151
|
+
if (deliveryClassOf(event.type) === "persisted") {
|
|
9900
10152
|
eventSeq++;
|
|
9901
10153
|
compactionOrchestrator?.trackMessage(eventSeq);
|
|
9902
10154
|
}
|
|
9903
10155
|
if (event.type === "finished") {
|
|
9904
10156
|
scheduleContextUsageEmit("turn-end");
|
|
9905
|
-
if (!
|
|
10157
|
+
if (!turnScheduler.isCompacting && compactionOrchestrator?.shouldCompact()) {
|
|
9906
10158
|
const compactionTimer = setTimeout(() => {
|
|
9907
|
-
if (
|
|
10159
|
+
if (turnScheduler.isCompacting || !compactionOrchestrator?.shouldCompact()) return;
|
|
9908
10160
|
compactionOrchestrator.compact("threshold").catch((err) => {
|
|
9909
10161
|
log(
|
|
9910
10162
|
`[serve] auto-compaction failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -9927,12 +10179,13 @@ async function startAgentServer(opts) {
|
|
|
9927
10179
|
}
|
|
9928
10180
|
let driverStarted = false;
|
|
9929
10181
|
let driverStartInFlight = null;
|
|
9930
|
-
const
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
10182
|
+
const turnScheduler = new TurnScheduler({
|
|
10183
|
+
ensureDriverStarted,
|
|
10184
|
+
getDriver: () => driver,
|
|
10185
|
+
sendEvent,
|
|
10186
|
+
log,
|
|
10187
|
+
logPhase
|
|
9934
10188
|
});
|
|
9935
|
-
const promptTurns = new PromptTurnQueue();
|
|
9936
10189
|
let driverRestartChain = Promise.resolve();
|
|
9937
10190
|
let liveDriverActiveAfterTurn = false;
|
|
9938
10191
|
let driver = secretsMode === "env" ? agentSession.driver : void 0;
|
|
@@ -9975,8 +10228,6 @@ async function startAgentServer(opts) {
|
|
|
9975
10228
|
};
|
|
9976
10229
|
sendEvent(runtimeSessionEvent);
|
|
9977
10230
|
}
|
|
9978
|
-
let compacting = false;
|
|
9979
|
-
let suppressedBy = null;
|
|
9980
10231
|
let compactionOrchestrator = null;
|
|
9981
10232
|
const compactionConfig = wsConfig.compaction;
|
|
9982
10233
|
function scheduleContextUsageEmit(trigger) {
|
|
@@ -9991,18 +10242,13 @@ async function startAgentServer(opts) {
|
|
|
9991
10242
|
}
|
|
9992
10243
|
function rebuildCompactionOrchestrator() {
|
|
9993
10244
|
if (!driver) return;
|
|
9994
|
-
let gateHold = null;
|
|
9995
10245
|
compactionOrchestrator = new CompactionOrchestrator({
|
|
9996
10246
|
driver,
|
|
9997
10247
|
config: compactionConfig,
|
|
9998
10248
|
contextWindows,
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
suppressedBy = gateHold;
|
|
10003
|
-
sendEvent({ type: "status", phase: "compacting" });
|
|
10004
|
-
log(`[serve] compaction started (trigger=${trigger})`);
|
|
10005
|
-
},
|
|
10249
|
+
// Start, end, settled and the driver claim: the scheduler owns the holds,
|
|
10250
|
+
// the event suppression and the `status` phases around a compaction.
|
|
10251
|
+
...turnScheduler.compactionHooks(),
|
|
10006
10252
|
onSnapshot: (snapshot) => {
|
|
10007
10253
|
sendEvent(snapshot);
|
|
10008
10254
|
contextUsage.onCompaction(snapshot.summary);
|
|
@@ -10011,27 +10257,6 @@ async function startAgentServer(opts) {
|
|
|
10011
10257
|
onCompactionAttempt: (event) => {
|
|
10012
10258
|
sendEvent(event);
|
|
10013
10259
|
},
|
|
10014
|
-
onCompactionEnd: () => {
|
|
10015
|
-
if (suppressedBy !== gateHold) return;
|
|
10016
|
-
compacting = false;
|
|
10017
|
-
suppressedBy = null;
|
|
10018
|
-
sendEvent({ type: "status", phase: "idle" });
|
|
10019
|
-
},
|
|
10020
|
-
onCompactionSettled: () => {
|
|
10021
|
-
compactionGate.settle(gateHold);
|
|
10022
|
-
gateHold = null;
|
|
10023
|
-
},
|
|
10024
|
-
// A user turn that already holds a slot keeps the driver; the compaction
|
|
10025
|
-
// waits for it rather than prompting the driver under it. A platform call
|
|
10026
|
-
// waits briefly: a turn paused on a question can hold its slot for hours.
|
|
10027
|
-
claimDriver: (trigger) => claimDriverForCompaction({
|
|
10028
|
-
gate: compactionGate,
|
|
10029
|
-
awaitClaimedTurns: () => driverSwapGate.awaitActiveTurn(),
|
|
10030
|
-
isSwapping: () => driverSwapGate.isSwapping(),
|
|
10031
|
-
claimTurnSlot: () => driverSwapGate.beginTurn(),
|
|
10032
|
-
log,
|
|
10033
|
-
timeoutMs: compactionTurnWaitFor(trigger)
|
|
10034
|
-
}),
|
|
10035
10260
|
onLog: (line) => log(`[serve] ${line}`),
|
|
10036
10261
|
// Phase 3: stamp every CompactionAttemptEvent with the registry's
|
|
10037
10262
|
// current signature so wake-time tier-1 selection has the input it
|
|
@@ -10078,7 +10303,8 @@ async function startAgentServer(opts) {
|
|
|
10078
10303
|
const normalized = normalizer.normalize(event);
|
|
10079
10304
|
const turnEnded = event.type === "agent_end";
|
|
10080
10305
|
for (const e of normalized) {
|
|
10081
|
-
if (turnEnded &&
|
|
10306
|
+
if (turnEnded && e.type === "status" && e.phase === "idle") {
|
|
10307
|
+
turnScheduler.reportTurnEnd();
|
|
10082
10308
|
continue;
|
|
10083
10309
|
}
|
|
10084
10310
|
forwardNormalizedEvent(e);
|
|
@@ -10118,7 +10344,6 @@ async function startAgentServer(opts) {
|
|
|
10118
10344
|
const stimulus = stimulusFromMetas(metas);
|
|
10119
10345
|
await entry.adapter.drainRuntimeNodes(entry.handle);
|
|
10120
10346
|
const execution = entry.adapter.getExecution(entry.handle);
|
|
10121
|
-
if (!flowRunDrivesTurns(execution)) return;
|
|
10122
10347
|
if (!entry.adapter.shouldDriveAgentTurn(entry.handle, stimulus)) return;
|
|
10123
10348
|
await ensureFlowDriverStarted();
|
|
10124
10349
|
await driveOrchestratorTurn({
|
|
@@ -10126,42 +10351,13 @@ async function startAgentServer(opts) {
|
|
|
10126
10351
|
execution,
|
|
10127
10352
|
stimulus,
|
|
10128
10353
|
emit: sendEvent,
|
|
10129
|
-
deliver: (prompt) =>
|
|
10354
|
+
deliver: (prompt) => turnScheduler.flowTurn(prompt, FLOW_TURN_TIMEOUT_MS)
|
|
10130
10355
|
});
|
|
10131
10356
|
},
|
|
10132
10357
|
log: serverLog
|
|
10133
10358
|
});
|
|
10134
10359
|
return stimulusBus;
|
|
10135
10360
|
}
|
|
10136
|
-
function awaitFlowAgentEnd(prompt, timeoutMs) {
|
|
10137
|
-
return countPendingTurn(
|
|
10138
|
-
() => dispatchFlowTurn(
|
|
10139
|
-
{
|
|
10140
|
-
gate: driverSwapGate,
|
|
10141
|
-
awaitCompactionIdle: () => awaitCompactionIdle("flow turn"),
|
|
10142
|
-
isCompacting: () => !compactionGate.isIdle(),
|
|
10143
|
-
ensureDriverStarted,
|
|
10144
|
-
getDriver: () => driver
|
|
10145
|
-
},
|
|
10146
|
-
prompt,
|
|
10147
|
-
timeoutMs
|
|
10148
|
-
)
|
|
10149
|
-
);
|
|
10150
|
-
}
|
|
10151
|
-
function activeFlowWantsAgentTurn(runId) {
|
|
10152
|
-
const entry = activeFlows.get(runId);
|
|
10153
|
-
if (!entry) return false;
|
|
10154
|
-
if (!flowRunDrivesTurns(entry.adapter.getExecution(entry.handle))) return false;
|
|
10155
|
-
return entry.adapter.shouldDriveAgentTurn(entry.handle, { kind: "resumed_after_hibernation" });
|
|
10156
|
-
}
|
|
10157
|
-
async function countPendingTurn(run) {
|
|
10158
|
-
const end = pendingTurns.begin();
|
|
10159
|
-
try {
|
|
10160
|
-
return await run();
|
|
10161
|
-
} finally {
|
|
10162
|
-
end();
|
|
10163
|
-
}
|
|
10164
|
-
}
|
|
10165
10361
|
function ensureResourceManagerForFlow() {
|
|
10166
10362
|
if (!resourceManager) {
|
|
10167
10363
|
registerBuiltinConnectors();
|
|
@@ -10259,7 +10455,7 @@ async function startAgentServer(opts) {
|
|
|
10259
10455
|
execution,
|
|
10260
10456
|
stimulus,
|
|
10261
10457
|
emit: sendEvent,
|
|
10262
|
-
deliver: (prompt) =>
|
|
10458
|
+
deliver: (prompt) => turnScheduler.flowTurn(prompt, FLOW_TURN_TIMEOUT_MS)
|
|
10263
10459
|
});
|
|
10264
10460
|
}
|
|
10265
10461
|
});
|
|
@@ -10305,7 +10501,7 @@ async function startAgentServer(opts) {
|
|
|
10305
10501
|
execute: (op, args) => adapter.executeOp(handle, op, args),
|
|
10306
10502
|
mandatoryGates: () => adapter.getMandatoryAgentApprovalNodeIds(handle)
|
|
10307
10503
|
};
|
|
10308
|
-
if (agentSession?.driverType
|
|
10504
|
+
if (driverCapabilities(agentSession?.driverType).inProcessMcpServers) {
|
|
10309
10505
|
try {
|
|
10310
10506
|
const server = await buildSdkConnectorTools(manager, { z: z });
|
|
10311
10507
|
const flowServer = flowToolsBaked ? null : await buildSdkFlowTools(manager, connectorId, { z: z });
|
|
@@ -10327,7 +10523,7 @@ async function startAgentServer(opts) {
|
|
|
10327
10523
|
log(`[serve] failed to rebuild MCP tools for flow: ${errMsg}`);
|
|
10328
10524
|
}
|
|
10329
10525
|
}
|
|
10330
|
-
if (agentSession?.driverType
|
|
10526
|
+
if (driverCapabilities(agentSession?.driverType).managedSession && !driver.acceptsReplyAsPrompt) {
|
|
10331
10527
|
removeCodexFlowTools?.();
|
|
10332
10528
|
removeCodexFlowTools = registerCodexFlowTools(capabilityRegistry, manager, connectorId);
|
|
10333
10529
|
}
|
|
@@ -10592,7 +10788,7 @@ async function startAgentServer(opts) {
|
|
|
10592
10788
|
return { needsWireFallbackRecreate, needsWireAgentConfigRecreate };
|
|
10593
10789
|
}
|
|
10594
10790
|
async function recreateAgentSession(overrides) {
|
|
10595
|
-
return
|
|
10791
|
+
return turnScheduler.runSwap(async () => {
|
|
10596
10792
|
const resolved = typeof overrides === "function" ? overrides() : overrides;
|
|
10597
10793
|
if (!resolved) return false;
|
|
10598
10794
|
await recreateAgentSessionInner(resolved);
|
|
@@ -10616,10 +10812,10 @@ async function startAgentServer(opts) {
|
|
|
10616
10812
|
needsAgentTurn: (run) => {
|
|
10617
10813
|
const needed = reconnectedRunNeedsAgentTurn({
|
|
10618
10814
|
cutDriverWork,
|
|
10619
|
-
|
|
10815
|
+
restoreKick: run.restoreKick ?? null,
|
|
10620
10816
|
busHasTurn: stimulusBus?.hasTurn(run.connectorId) ?? false,
|
|
10621
10817
|
// Approximate: a waiting reply counts too. A prompt reaches one run only.
|
|
10622
|
-
promptQueuedForRun: pendingTurns
|
|
10818
|
+
promptQueuedForRun: turnScheduler.pendingTurns > 0 && pickChatFlowTarget(activeFlows.values())?.runId === run.runId
|
|
10623
10819
|
});
|
|
10624
10820
|
if (needed) redriven.push(run.runId);
|
|
10625
10821
|
return needed;
|
|
@@ -10822,7 +11018,7 @@ async function startAgentServer(opts) {
|
|
|
10822
11018
|
}
|
|
10823
11019
|
}
|
|
10824
11020
|
async function rebuildMcpToolsForNewStores(storesRegistered) {
|
|
10825
|
-
if (!(storesRegistered > 0 && !driverStarted && agentSession?.driverType
|
|
11021
|
+
if (!(storesRegistered > 0 && !driverStarted && driverCapabilities(agentSession?.driverType).inProcessMcpServers)) {
|
|
10826
11022
|
return;
|
|
10827
11023
|
}
|
|
10828
11024
|
try {
|
|
@@ -10974,13 +11170,15 @@ async function startAgentServer(opts) {
|
|
|
10974
11170
|
}
|
|
10975
11171
|
try {
|
|
10976
11172
|
validateCodexInit(cmd, supportedRuntimeFeatures, runtimeIdentity ?? void 0);
|
|
10977
|
-
const wantsManaged =
|
|
11173
|
+
const wantsManaged = driverCapabilities(
|
|
11174
|
+
cmd.resolvedConfig.agentConfig?.driver
|
|
11175
|
+
).managedSession;
|
|
10978
11176
|
if (managedHost && !wantsManaged) throw new Error("AI_PROFILE_INVALID");
|
|
10979
11177
|
if (managedHost && wantsManaged) {
|
|
10980
11178
|
if (managedBootstrapClosed || agentSession && !managedInitFingerprint || cmd.secrets && CLAUDE_CODE_CREDENTIALS_KEY in cmd.secrets)
|
|
10981
11179
|
throw new Error("AI_PROFILE_INVALID");
|
|
10982
11180
|
const profile2 = cmd.resolvedConfig.agentConfig;
|
|
10983
|
-
if (opts.driver && opts.driver !==
|
|
11181
|
+
if (opts.driver && opts.driver !== profile2.driver || opts.provider && opts.provider !== "openai" || opts.model && opts.model !== profile2.model)
|
|
10984
11182
|
throw new Error("AI_PROFILE_INVALID");
|
|
10985
11183
|
const initialCredential = parseCodexCredential(cmd.credentials.ai);
|
|
10986
11184
|
const binding = bindManagedCodexInit(managedHost, cmd, async (input, signal) => {
|
|
@@ -11089,7 +11287,7 @@ async function startAgentServer(opts) {
|
|
|
11089
11287
|
settings = { driver: driver2 ?? profile?.driver, model: model ?? profile?.model };
|
|
11090
11288
|
}
|
|
11091
11289
|
credentialsSelection = {
|
|
11092
|
-
driver: settings.driver ??
|
|
11290
|
+
driver: settings.driver ?? DEFAULT_DRIVER_ID,
|
|
11093
11291
|
registry: wireAgentConfig?.registry,
|
|
11094
11292
|
modelRef: wireAgentConfig?.modelRef?.trim() || settings.model?.trim() || void 0
|
|
11095
11293
|
};
|
|
@@ -11138,7 +11336,7 @@ async function startAgentServer(opts) {
|
|
|
11138
11336
|
let pendingResumeSessionId;
|
|
11139
11337
|
const cfgResumeSessionId = cfg.resumeSessionId;
|
|
11140
11338
|
const cfgExpectedSig = cfg.expectedCapabilitySignature;
|
|
11141
|
-
const resumeTargetDriver = managedCodex ?
|
|
11339
|
+
const resumeTargetDriver = (managedCodex ? void 0 : opts.driver) ?? wireAgentConfig?.driver ?? agentSession?.driverType;
|
|
11142
11340
|
if (cfgResumeSessionId) {
|
|
11143
11341
|
const currentSig = computeCapabilitySignature(capabilityRegistry.list());
|
|
11144
11342
|
if (cfgExpectedSig && cfgExpectedSig !== currentSig) {
|
|
@@ -11153,7 +11351,7 @@ async function startAgentServer(opts) {
|
|
|
11153
11351
|
resumeSessionId: cfgResumeSessionId,
|
|
11154
11352
|
reason: "signature_mismatch"
|
|
11155
11353
|
});
|
|
11156
|
-
} else if (resumeProbe === "jsonl_lost" && resumeTargetDriver
|
|
11354
|
+
} else if (resumeProbe === "jsonl_lost" && driverCapabilities(resumeTargetDriver).resumeNeedsTranscript) {
|
|
11157
11355
|
log(`[serve] tier-1 resume skipped: no transcript for ${cfgResumeSessionId}`);
|
|
11158
11356
|
sendEvent({
|
|
11159
11357
|
type: "resume_failed",
|
|
@@ -11250,129 +11448,88 @@ async function startAgentServer(opts) {
|
|
|
11250
11448
|
}
|
|
11251
11449
|
});
|
|
11252
11450
|
}
|
|
11253
|
-
const awaitCompactionIdle = (what) => guardTurnAgainstCompaction({ gate: compactionGate, what, log, sendEvent });
|
|
11254
11451
|
async function handlePrompt(cmd) {
|
|
11255
11452
|
if (cmd.messageId) sendEvent({ type: "prompt_ack", messageId: cmd.messageId });
|
|
11256
|
-
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
|
|
11263
|
-
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
|
|
11284
|
-
|
|
11285
|
-
|
|
11286
|
-
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11299
|
-
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
text: cmd.prompt,
|
|
11321
|
-
senderId: "user"
|
|
11453
|
+
await turnScheduler.prompt({
|
|
11454
|
+
owner: { senderId: cmd.senderId, messageId: cmd.messageId },
|
|
11455
|
+
// The turn ahead may be paused on a question it can only leave through
|
|
11456
|
+
// this driver's rule for a new prompt; apply it now, not after that turn.
|
|
11457
|
+
onQueued: () => driver?.supersedePendingQuestion?.(),
|
|
11458
|
+
admit: async () => {
|
|
11459
|
+
const promptReceivedAt = Date.now();
|
|
11460
|
+
const sessionIsReady = await awaitSessionReadyOrFail();
|
|
11461
|
+
logPhase("prompt_gate_wait", promptReceivedAt, { ready: sessionIsReady });
|
|
11462
|
+
if (!sessionIsReady) return false;
|
|
11463
|
+
if (!secretsProvisioned) {
|
|
11464
|
+
log("[serve] prompt received before secrets provisioned \u2014 rejecting");
|
|
11465
|
+
sendEvent({
|
|
11466
|
+
type: "error",
|
|
11467
|
+
message: "Secrets not yet provisioned \u2014 send provision_secrets first",
|
|
11468
|
+
fatal: false
|
|
11469
|
+
});
|
|
11470
|
+
return false;
|
|
11471
|
+
}
|
|
11472
|
+
log(`[serve] prompt: ${cmd.prompt.slice(0, 80)}...`);
|
|
11473
|
+
contextUsage.observeUserPrompt(cmd.prompt);
|
|
11474
|
+
return true;
|
|
11475
|
+
},
|
|
11476
|
+
route: async () => {
|
|
11477
|
+
await restageMaterializedSkills(true);
|
|
11478
|
+
try {
|
|
11479
|
+
await rebuildForLateMcpDeclarations({
|
|
11480
|
+
driverStarted: () => driverStarted,
|
|
11481
|
+
unloadedMcpDeclarationIds: () => agentSession.unloadedMcpDeclarationIds(),
|
|
11482
|
+
resumeSessionId: () => agentSession.resumeSessionId,
|
|
11483
|
+
recreate: (overrides) => recreateAgentSession(overrides),
|
|
11484
|
+
log,
|
|
11485
|
+
warn: (line) => serverLog.warn(line)
|
|
11486
|
+
});
|
|
11487
|
+
} catch (err) {
|
|
11488
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
11489
|
+
serverLog.warn(`[serve] session rebuild for late MCP servers failed: ${errMsg}`);
|
|
11490
|
+
sendEvent({ type: "error", message: `Session rebuild failed: ${errMsg}`, fatal: true });
|
|
11491
|
+
return false;
|
|
11492
|
+
}
|
|
11493
|
+
const activeFlow = pickChatFlowTarget(activeFlows.values());
|
|
11494
|
+
if (!activeFlow) return null;
|
|
11495
|
+
return async () => {
|
|
11496
|
+
sendEvent({ type: "status", phase: "thinking" });
|
|
11497
|
+
try {
|
|
11498
|
+
const bus = getOrCreateStimulusBus();
|
|
11499
|
+
const userStimulus = {
|
|
11500
|
+
kind: "user_message",
|
|
11501
|
+
text: cmd.prompt,
|
|
11502
|
+
senderId: "user"
|
|
11503
|
+
};
|
|
11504
|
+
await bus.signal(activeFlow.connectorId, {
|
|
11505
|
+
promptFragment: renderStimulusPrompt(userStimulus),
|
|
11506
|
+
meta: {
|
|
11507
|
+
kind: "user_message",
|
|
11508
|
+
runId: activeFlow.runId,
|
|
11509
|
+
text: cmd.prompt,
|
|
11510
|
+
senderId: "user"
|
|
11511
|
+
}
|
|
11512
|
+
});
|
|
11513
|
+
} catch (err) {
|
|
11514
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
11515
|
+
log(`[serve] flow user-message turn failed: ${errMsg}`);
|
|
11516
|
+
sendEvent({ type: "error", message: `Flow turn failed: ${errMsg}`, fatal: false });
|
|
11322
11517
|
}
|
|
11323
|
-
}
|
|
11324
|
-
}
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
} finally {
|
|
11329
|
-
if (pendingTurns.shouldReportIdle()) sendEvent({ type: "status", phase: "idle" });
|
|
11518
|
+
};
|
|
11519
|
+
},
|
|
11520
|
+
dispatch: async () => {
|
|
11521
|
+
sendEvent({ type: "status", phase: "thinking" });
|
|
11522
|
+
await driver.promptInput({ text: cmd.prompt, attachments: cmd.attachments });
|
|
11330
11523
|
}
|
|
11331
|
-
|
|
11332
|
-
}
|
|
11333
|
-
const driverStartStartedAt = Date.now();
|
|
11334
|
-
let driverStartOk = false;
|
|
11335
|
-
let driverStartAttempts = 0;
|
|
11336
|
-
let endTurn;
|
|
11337
|
-
try {
|
|
11338
|
-
endTurn = await beginTurnClearOfCompaction({
|
|
11339
|
-
gate: compactionGate,
|
|
11340
|
-
awaitIdle: () => awaitCompactionIdle("prompt"),
|
|
11341
|
-
claimTurn: () => driverSwapGate.beginTurnOnLiveDriver(() => {
|
|
11342
|
-
driverStartAttempts += 1;
|
|
11343
|
-
return ensureDriverStarted();
|
|
11344
|
-
})
|
|
11345
|
-
});
|
|
11346
|
-
driverStartOk = endTurn !== null;
|
|
11347
|
-
} catch (err) {
|
|
11348
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
11349
|
-
log(`[serve] driver start failed: ${errMsg}`);
|
|
11350
|
-
sendEvent({ type: "error", message: `Driver start failed: ${errMsg}`, fatal: true });
|
|
11351
|
-
return;
|
|
11352
|
-
} finally {
|
|
11353
|
-
logPhase("driver_start", driverStartStartedAt, {
|
|
11354
|
-
ok: driverStartOk,
|
|
11355
|
-
attempts: driverStartAttempts
|
|
11356
|
-
});
|
|
11357
|
-
}
|
|
11358
|
-
if (!endTurn) return;
|
|
11359
|
-
sendEvent({ type: "status", phase: "thinking" });
|
|
11360
|
-
try {
|
|
11361
|
-
await driver.promptInput({ text: cmd.prompt, attachments: cmd.attachments });
|
|
11362
|
-
} catch (err) {
|
|
11363
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
11364
|
-
log(`[serve] prompt failed: ${errMsg}`);
|
|
11365
|
-
sendEvent({ type: "error", message: `Prompt failed: ${errMsg}`, fatal: true });
|
|
11366
|
-
} finally {
|
|
11367
|
-
endTurn();
|
|
11368
|
-
}
|
|
11524
|
+
});
|
|
11369
11525
|
}
|
|
11370
11526
|
async function handleReply(cmd) {
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11527
|
+
await turnScheduler.reply({
|
|
11528
|
+
admit: async () => {
|
|
11529
|
+
if (!await awaitSessionReadyOrFail()) return false;
|
|
11530
|
+
log(`[serve] reply: ${cmd.answer.slice(0, 80)}...`);
|
|
11531
|
+
return true;
|
|
11532
|
+
},
|
|
11376
11533
|
answer: cmd.answer,
|
|
11377
11534
|
question: cmd.question,
|
|
11378
11535
|
requestId: cmd.requestId,
|
|
@@ -11385,49 +11542,10 @@ async function startAgentServer(opts) {
|
|
|
11385
11542
|
...cmd.requestId !== void 0 ? { requestId: cmd.requestId } : {}
|
|
11386
11543
|
})
|
|
11387
11544
|
});
|
|
11388
|
-
if (routed === "answered") return;
|
|
11389
|
-
if (!driver.acceptsReplyAsPrompt) {
|
|
11390
|
-
if (!driver.hasPendingQuestion()) {
|
|
11391
|
-
log("[serve] reply: driver takes no reply as a prompt; answer not delivered");
|
|
11392
|
-
sendEvent({
|
|
11393
|
-
type: "error",
|
|
11394
|
-
message: "This question is no longer open, so the agent did not get your answer. Send it as a new message.",
|
|
11395
|
-
fatal: false
|
|
11396
|
-
});
|
|
11397
|
-
}
|
|
11398
|
-
return;
|
|
11399
|
-
}
|
|
11400
|
-
let endTurn;
|
|
11401
|
-
try {
|
|
11402
|
-
endTurn = await beginTurnClearOfCompaction({
|
|
11403
|
-
gate: compactionGate,
|
|
11404
|
-
awaitIdle: () => awaitCompactionIdle("reply"),
|
|
11405
|
-
claimTurn: () => driverSwapGate.beginTurnOnLiveDriver(ensureDriverStarted)
|
|
11406
|
-
});
|
|
11407
|
-
} catch (err) {
|
|
11408
|
-
sendEvent({
|
|
11409
|
-
type: "error",
|
|
11410
|
-
message: `Reply failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
11411
|
-
fatal: false
|
|
11412
|
-
});
|
|
11413
|
-
return;
|
|
11414
|
-
}
|
|
11415
|
-
if (!endTurn) return;
|
|
11416
|
-
try {
|
|
11417
|
-
await driver.prompt(freshTurnReplyPrompt(cmd.answer, cmd.question));
|
|
11418
|
-
} catch (err) {
|
|
11419
|
-
sendEvent({
|
|
11420
|
-
type: "error",
|
|
11421
|
-
message: `Reply failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
11422
|
-
fatal: false
|
|
11423
|
-
});
|
|
11424
|
-
} finally {
|
|
11425
|
-
endTurn();
|
|
11426
|
-
}
|
|
11427
11545
|
}
|
|
11428
11546
|
async function handleCancel(cmd) {
|
|
11429
11547
|
if (cmd.senderId) {
|
|
11430
|
-
const dropped =
|
|
11548
|
+
const dropped = turnScheduler.dropQueuedPromptsFrom(cmd.senderId);
|
|
11431
11549
|
if (dropped.length > 0) {
|
|
11432
11550
|
log(`[serve] cancel dropped ${dropped.length} queued prompt(s) of the presser`);
|
|
11433
11551
|
sendEvent({
|
|
@@ -11703,10 +11821,10 @@ async function startAgentServer(opts) {
|
|
|
11703
11821
|
await handleSessionInit(cmd);
|
|
11704
11822
|
break;
|
|
11705
11823
|
case "prompt":
|
|
11706
|
-
await
|
|
11824
|
+
await handlePrompt(cmd);
|
|
11707
11825
|
break;
|
|
11708
11826
|
case "reply":
|
|
11709
|
-
await
|
|
11827
|
+
await handleReply(cmd);
|
|
11710
11828
|
break;
|
|
11711
11829
|
case "cancel":
|
|
11712
11830
|
await handleCancel(cmd);
|
|
@@ -11815,7 +11933,7 @@ async function startAgentServer(opts) {
|
|
|
11815
11933
|
}
|
|
11816
11934
|
function emitAvailability() {
|
|
11817
11935
|
if (resourceManager || agentSession?.getExternalMcpManager()) {
|
|
11818
|
-
const driverLive = agentSession?.driverType
|
|
11936
|
+
const driverLive = driverCapabilities(agentSession?.driverType).liveToolUpdates;
|
|
11819
11937
|
const payload = buildResourcesAvailablePayload(
|
|
11820
11938
|
resourceManager,
|
|
11821
11939
|
agentSession?.getExternalMcpManager() ?? null,
|
|
@@ -12015,6 +12133,6 @@ function touchSession(state) {
|
|
|
12015
12133
|
return { ...state, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
12016
12134
|
}
|
|
12017
12135
|
|
|
12018
|
-
export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CONNECTOR_MUTATE_NOT_READY, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_READ_MAX_CHUNK_BYTES, MOUNT_STAT_BUDGET_MS, MOUNT_STAT_MAX_ENTRIES, MOUNT_TREE_OP_DEADLINE_FACTOR, MOUNT_WRITE_MAX_CHUNK_BYTES, MarkdownStreamer, PreInitRingSink, ResourceOperationError, SESSION_ROOT_WRITABLE_DIRS, SESSION_ROOT_WRITABLE_FILES, WRITE_RANGE_PARTIAL_TTL_MS, WS_AUTH_TOKEN_ENV, WS_AUTH_TOKEN_FILE_ENV, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, capabilitySignatureInputs, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, computeDirectoryTotals, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchResourceRequest, dispatchRunnerCapabilityInvocation, driverActiveAfterTurnEnd, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt,
|
|
12019
|
-
//# sourceMappingURL=chunk-
|
|
12020
|
-
//# sourceMappingURL=chunk-
|
|
12136
|
+
export { CLAUDE_CODE_CREDENTIALS_KEY, COMPILE_MANIFEST_FILENAME, CONNECTOR_MUTATE_NOT_READY, CapabilityRegistry, DEFAULT_CAPABILITY_CALL_TIMEOUT_MS, DEFAULT_COALESCE_MS, DEFAULT_FLOW_MUTATE_CONNECTOR_WAIT_MS, MOUNT_LIST_MAX_DEPTH, MOUNT_LIST_MAX_ENTRIES, MOUNT_READ_DEADLINE_FACTOR, MOUNT_READ_MAX_CHUNK_BYTES, MOUNT_STAT_BUDGET_MS, MOUNT_STAT_MAX_ENTRIES, MOUNT_TREE_OP_DEADLINE_FACTOR, MOUNT_WRITE_MAX_CHUNK_BYTES, MarkdownStreamer, PreInitRingSink, ResourceOperationError, SESSION_ROOT_WRITABLE_DIRS, SESSION_ROOT_WRITABLE_FILES, WRITE_RANGE_PARTIAL_TTL_MS, WS_AUTH_TOKEN_ENV, WS_AUTH_TOKEN_FILE_ENV, agentDefinitionExists, bootstrapCapabilityRegistry, bootstrapRunnerLogStore, buildAgentResources, buildClientCapabilityHandler, buildConnectorTokenMediator, buildContextSection, buildEnvironmentSection, buildResourcesAvailablePayload, buildStoreSnapshotReplay, builtinCapabilities, capabilityLogInstance, capabilitySignatureInputs, clearPreInitRingSink, clearSession, compileComposition, computeCapabilitySignature, computeDirectoryTotals, connectorRefreshKind, createAgentSession, createFlowConnectorReadiness, createManagedCodexSubpromptDriver, createSessionStimulusBus, defineCapability, deleteSession, dispatchResourceRequest, dispatchRunnerCapabilityInvocation, driverActiveAfterTurnEnd, emitSystemPromptComposed, ensureClaudeSettingsDisablesConnectors, ensureGitConfigInclude, executeConnectorMutate, extractClaudeAiOauthExpiresAt, flowStartNeedsDriverRestart, getPreInitRingSink, handleMountResourceRequest, handleResourceRequest, handleSessionRootResourceRequest, hasNonTerminalFlow, hostOpResumeStimulus, installPreInitRingSink, isSessionRootPathAllowed, listSessions, loadAgentManifest, loadCompileManifest, loadCompileManifestFromDir, loadManagedCodexHostConfig, loadSession, loadSessionById, mcpAuthSecretKey, newSession, nulTailPaddingLength, pickChatFlowTarget, pickFlowToolTarget, pickRepointedManager, planFlowMutate, prepareCodexTools, reconcilePendingDecisions, reconnectedRunNeedsAgentTurn, recreateKeepingLiveFlows, registerActiveFlow, registerCompositionCapabilities, rejectCapabilityOnApprovalDeny, rejectPendingCapabilityCallsOnDisconnect, resetRunnerLogStore, resolveAgentComposition, resolveAgentMixins, resolveBinding, resolveCapabilityCallTimeoutMs, resolveCapabilityResult, resolveComposition, resolveFlowMutateConnectorWaitMs, resolveMixin, restoredRunHasWorkToResume, runAgentChat, saveSession, setCurrentSession, setUpFlowConnector, startAgentServer, stimulusFromMetas, takeRunnerWsAuthToken, toActiveFlowTarget, touchSession, validateInputResponse, writeClaudeCodeCredentialsFile, writeRangeChunk, writeRangePartialPath };
|
|
12137
|
+
//# sourceMappingURL=chunk-ZSFTCMZL.js.map
|
|
12138
|
+
//# sourceMappingURL=chunk-ZSFTCMZL.js.map
|