@skaile/workspaces 3.27.0 → 4.0.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 +480 -0
- package/dist/app-sdk/index.js +1 -1
- package/dist/{asset-feeds-AJOUKX55.js → asset-feeds-OPG6SUXU.js} +11 -9
- package/dist/asset-feeds-OPG6SUXU.js.map +1 -0
- package/dist/asset-manager/catalog-deployer.js +5 -3
- package/dist/asset-manager/index.js +11 -9
- package/dist/asset-manager/installer.js +8 -6
- package/dist/asset-manager/renderers.js +2 -2
- package/dist/asset-manager/src/renderers.d.ts.map +1 -1
- package/dist/bridge/drivers/claude-sdk.js +102 -55
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +178 -22
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +199 -7
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +10 -4
- package/dist/bridge/drivers/echo.js.map +1 -1
- package/dist/bridge/drivers/gemini.js +7 -4
- package/dist/bridge/drivers/goose.js +160 -7
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +321 -96
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +148 -13
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +41 -11
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +12 -9
- package/dist/bridge/src/cloud.d.ts +62 -71
- package/dist/bridge/src/cloud.d.ts.map +1 -1
- package/dist/bridge/src/codex/config-toml.d.ts +128 -0
- package/dist/bridge/src/codex/config-toml.d.ts.map +1 -0
- package/dist/bridge/src/codex/credentials.d.ts +26 -0
- package/dist/bridge/src/codex/credentials.d.ts.map +1 -1
- package/dist/bridge/src/codex/managed-driver.d.ts.map +1 -1
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts +9 -4
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +19 -11
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/codex.d.ts +26 -1
- package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
- package/dist/bridge/src/drivers/continue.d.ts +31 -5
- package/dist/bridge/src/drivers/continue.d.ts.map +1 -1
- package/dist/bridge/src/drivers/echo.d.ts.map +1 -1
- package/dist/bridge/src/drivers/gemini.d.ts +34 -3
- package/dist/bridge/src/drivers/gemini.d.ts.map +1 -1
- package/dist/bridge/src/drivers/goose.d.ts +26 -2
- package/dist/bridge/src/drivers/goose.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp-models-yml.d.ts +216 -0
- package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -0
- package/dist/bridge/src/drivers/omp.d.ts +26 -23
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/drivers/opencode.d.ts +28 -3
- package/dist/bridge/src/drivers/opencode.d.ts.map +1 -1
- package/dist/bridge/src/drivers/qwen.d.ts +10 -4
- package/dist/bridge/src/drivers/qwen.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +3 -1
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/models.d.ts +118 -19
- package/dist/bridge/src/models.d.ts.map +1 -1
- package/dist/bridge/src/provider-catalog.d.ts +188 -0
- package/dist/bridge/src/provider-catalog.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts +117 -0
- package/dist/bridge/src/provider-materialize/continue-config-yaml.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/credential-env.d.ts +103 -0
- package/dist/bridge/src/provider-materialize/credential-env.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/env-drivers.d.ts +209 -0
- package/dist/bridge/src/provider-materialize/env-drivers.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts +127 -0
- package/dist/bridge/src/provider-materialize/goose-custom-providers.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts +127 -0
- package/dist/bridge/src/provider-materialize/opencode-config.d.ts.map +1 -0
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts +63 -0
- package/dist/bridge/src/provider-materialize/session-config-home.d.ts.map +1 -0
- package/dist/bridge/src/provider-registry-derive.d.ts +59 -0
- package/dist/bridge/src/provider-registry-derive.d.ts.map +1 -0
- package/dist/bridge/src/registry.d.ts +19 -7
- package/dist/bridge/src/registry.d.ts.map +1 -1
- package/dist/bridge/src/runtime.d.ts.map +1 -1
- package/dist/bridge/src/types.d.ts +79 -60
- package/dist/bridge/src/types.d.ts.map +1 -1
- package/dist/bridge/src/validation.d.ts +2 -3
- package/dist/bridge/src/validation.d.ts.map +1 -1
- package/dist/{chunk-GURXUF2J.js → chunk-3ZTQY276.js} +95 -80
- package/dist/chunk-3ZTQY276.js.map +1 -0
- package/dist/{chunk-T3YLZQS4.js → chunk-45LLHKQ2.js} +24 -3
- package/dist/chunk-45LLHKQ2.js.map +1 -0
- package/dist/{chunk-UAEGKCE5.js → chunk-5IIHO2HI.js} +7 -7
- package/dist/{chunk-UAEGKCE5.js.map → chunk-5IIHO2HI.js.map} +1 -1
- package/dist/{chunk-HSRHO7SK.js → chunk-C3QLJTMB.js} +106 -150
- package/dist/chunk-C3QLJTMB.js.map +1 -0
- package/dist/chunk-CUU3AMGE.js +500 -0
- package/dist/chunk-CUU3AMGE.js.map +1 -0
- package/dist/{chunk-K6VZQNTR.js → chunk-DKCFWSVW.js} +3 -3
- package/dist/{chunk-K6VZQNTR.js.map → chunk-DKCFWSVW.js.map} +1 -1
- package/dist/{chunk-AEN2UFDN.js → chunk-DNGAA24M.js} +7 -7
- package/dist/{chunk-AEN2UFDN.js.map → chunk-DNGAA24M.js.map} +1 -1
- package/dist/{chunk-TCHEW3T2.js → chunk-EBHY23RZ.js} +6 -6
- package/dist/{chunk-TCHEW3T2.js.map → chunk-EBHY23RZ.js.map} +1 -1
- package/dist/{chunk-MQASB52N.js → chunk-FEFTOV2Y.js} +3 -3
- package/dist/{chunk-MQASB52N.js.map → chunk-FEFTOV2Y.js.map} +1 -1
- package/dist/{chunk-XMULHVKX.js → chunk-FODAC4RE.js} +17 -15
- package/dist/chunk-FODAC4RE.js.map +1 -0
- package/dist/{chunk-6H6HLMWG.js → chunk-G2F3ZCPK.js} +3 -3
- package/dist/{chunk-6H6HLMWG.js.map → chunk-G2F3ZCPK.js.map} +1 -1
- package/dist/{chunk-YLL65VXQ.js → chunk-HO2FQ76C.js} +175 -178
- package/dist/chunk-HO2FQ76C.js.map +1 -0
- package/dist/chunk-ILG4BXYE.js +936 -0
- package/dist/chunk-ILG4BXYE.js.map +1 -0
- package/dist/{chunk-E7HKNQTH.js → chunk-JXCUUZA3.js} +3 -4
- package/dist/chunk-JXCUUZA3.js.map +1 -0
- package/dist/{chunk-MBARHWMZ.js → chunk-K27T47OO.js} +79 -53
- package/dist/chunk-K27T47OO.js.map +1 -0
- package/dist/chunk-K3YR33F6.js +187 -0
- package/dist/chunk-K3YR33F6.js.map +1 -0
- package/dist/{chunk-7P6ASOFL.js → chunk-KIQGTAJ5.js} +3 -3
- package/dist/{chunk-7P6ASOFL.js.map → chunk-KIQGTAJ5.js.map} +1 -1
- package/dist/chunk-KSIRR5PL.js +142 -0
- package/dist/chunk-KSIRR5PL.js.map +1 -0
- package/dist/{chunk-SIREWRZE.js → chunk-KW7YIRYL.js} +3 -3
- package/dist/{chunk-SIREWRZE.js.map → chunk-KW7YIRYL.js.map} +1 -1
- package/dist/{chunk-3U3ZKYR7.js → chunk-LN2BQVRB.js} +139 -29
- package/dist/chunk-LN2BQVRB.js.map +1 -0
- package/dist/{chunk-DZ4UZOFB.js → chunk-M5H4DWIA.js} +3 -3
- package/dist/{chunk-DZ4UZOFB.js.map → chunk-M5H4DWIA.js.map} +1 -1
- package/dist/{chunk-JMYOJ3PA.js → chunk-MIP4IC3O.js} +3 -3
- package/dist/{chunk-JMYOJ3PA.js.map → chunk-MIP4IC3O.js.map} +1 -1
- package/dist/{chunk-O5JUZIVR.js → chunk-MJY2BO6N.js} +6 -6
- package/dist/{chunk-O5JUZIVR.js.map → chunk-MJY2BO6N.js.map} +1 -1
- package/dist/{chunk-AN6NAFRT.js → chunk-N7B3LZ7V.js} +31 -6
- package/dist/chunk-N7B3LZ7V.js.map +1 -0
- package/dist/{chunk-MX6TGDZ7.js → chunk-NBPL76HH.js} +5 -5
- package/dist/{chunk-MX6TGDZ7.js.map → chunk-NBPL76HH.js.map} +1 -1
- package/dist/{chunk-DY5GHUTC.js → chunk-NR6BPOW5.js} +2 -7
- package/dist/chunk-NR6BPOW5.js.map +1 -0
- package/dist/{chunk-F2GEM5B3.js → chunk-PCJF3XBH.js} +10 -10
- package/dist/{chunk-F2GEM5B3.js.map → chunk-PCJF3XBH.js.map} +1 -1
- package/dist/{chunk-NW65H5EV.js → chunk-PTETBRRC.js} +3 -3
- package/dist/{chunk-NW65H5EV.js.map → chunk-PTETBRRC.js.map} +1 -1
- package/dist/{chunk-UL4LD7KD.js → chunk-QQL3ET3J.js} +3 -3
- package/dist/{chunk-UL4LD7KD.js.map → chunk-QQL3ET3J.js.map} +1 -1
- package/dist/{chunk-IB4XKQMQ.js → chunk-REILIKVM.js} +3 -3
- package/dist/{chunk-IB4XKQMQ.js.map → chunk-REILIKVM.js.map} +1 -1
- package/dist/{chunk-N27DSFA7.js → chunk-RM4C5AU3.js} +27 -21
- package/dist/chunk-RM4C5AU3.js.map +1 -0
- package/dist/chunk-SG4D2UOK.js +843 -0
- package/dist/chunk-SG4D2UOK.js.map +1 -0
- package/dist/{chunk-AU4TUVHW.js → chunk-T7RHDVSY.js} +4 -4
- package/dist/{chunk-AU4TUVHW.js.map → chunk-T7RHDVSY.js.map} +1 -1
- package/dist/{chunk-773WLEXL.js → chunk-UKWEJPZZ.js} +3 -3
- package/dist/{chunk-773WLEXL.js.map → chunk-UKWEJPZZ.js.map} +1 -1
- package/dist/{chunk-3NCGSSCU.js → chunk-WLFRA5RM.js} +47 -45
- package/dist/chunk-WLFRA5RM.js.map +1 -0
- package/dist/{chunk-FFE7YLYO.js → chunk-XEVWRSLS.js} +7 -7
- package/dist/chunk-XEVWRSLS.js.map +1 -0
- package/dist/{chunk-5UWAOYDN.js → chunk-Y6E62LFB.js} +9 -12
- package/dist/chunk-Y6E62LFB.js.map +1 -0
- package/dist/{chunk-72DG6GSB.js → chunk-YS4XBN7O.js} +4 -4
- package/dist/{chunk-72DG6GSB.js.map → chunk-YS4XBN7O.js.map} +1 -1
- package/dist/chunk-YSJKLJD4.js +32 -0
- package/dist/chunk-YSJKLJD4.js.map +1 -0
- package/dist/cli/index.js +765 -334
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/src/commands/config.d.ts +17 -6
- package/dist/cli/src/commands/config.d.ts.map +1 -1
- package/dist/cli/src/commands/migrate-legacy-entry.d.ts +46 -0
- package/dist/cli/src/commands/migrate-legacy-entry.d.ts.map +1 -0
- package/dist/cli/src/commands/migrate-providers.d.ts +93 -0
- package/dist/cli/src/commands/migrate-providers.d.ts.map +1 -0
- package/dist/cli/src/commands/providers.d.ts +89 -0
- package/dist/cli/src/commands/providers.d.ts.map +1 -0
- package/dist/cli/src/commands/run.d.ts +1 -1
- package/dist/cli/src/commands/run.d.ts.map +1 -1
- package/dist/cli/src/setup.d.ts +46 -6
- package/dist/cli/src/setup.d.ts.map +1 -1
- package/dist/connectors/config.js +6 -4
- package/dist/connectors/index.js +15 -12
- package/dist/core/index.js +5 -3
- package/dist/core/provider-registry-credentials.d.ts +2 -0
- package/dist/core/provider-registry-credentials.js +5 -0
- package/dist/core/provider-registry-credentials.js.map +1 -0
- package/dist/core/provider-registry.d.ts +2 -0
- package/dist/core/provider-registry.js +4 -0
- package/dist/core/provider-registry.js.map +1 -0
- package/dist/core/runtime-assets.js +2 -2
- package/dist/core/src/index.d.ts +10 -4
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/provider-registry-credentials.d.ts +50 -0
- package/dist/core/src/provider-registry-credentials.d.ts.map +1 -0
- package/dist/core/src/provider-registry-files.d.ts +97 -0
- package/dist/core/src/provider-registry-files.d.ts.map +1 -0
- package/dist/core/src/provider-registry.d.ts +450 -0
- package/dist/core/src/provider-registry.d.ts.map +1 -0
- package/dist/core/src/settings.d.ts +18 -78
- package/dist/core/src/settings.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +31 -47
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/src/workspace-yaml-editor.d.ts.map +1 -1
- package/dist/core/workspace-config.js +1 -1
- package/dist/deploy/index.js +5 -3
- package/dist/deploy/index.js.map +1 -1
- package/dist/discovery/index.js +2 -2
- package/dist/{ensure-sources-DYGQNAJM.js → ensure-sources-QZAQ4SY2.js} +14 -12
- package/dist/ensure-sources-QZAQ4SY2.js.map +1 -0
- package/dist/factory-assets/connectors/box.js +15 -12
- package/dist/factory-assets/connectors/deploy.js +15 -12
- package/dist/factory-assets/connectors/devserver.js +15 -12
- package/dist/factory-assets/connectors/flow/adapter.js +15 -12
- package/dist/factory-assets/connectors/flow/engine.js +6 -4
- 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.d.ts +0 -3
- package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +16 -13
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts +31 -28
- package/dist/factory-assets/connectors/flow/subprompt-runner.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow.js +15 -12
- package/dist/factory-assets/connectors/git.js +15 -12
- package/dist/factory-assets/connectors/gmail.js +15 -12
- package/dist/factory-assets/connectors/googledrive.js +15 -12
- package/dist/factory-assets/connectors/local.js +15 -12
- package/dist/factory-assets/connectors/mattermost.js +15 -12
- package/dist/factory-assets/connectors/memory.js +15 -12
- package/dist/factory-assets/connectors/minio.js +15 -12
- package/dist/factory-assets/connectors/postgres.js +15 -12
- package/dist/factory-assets/connectors/s3.js +15 -12
- package/dist/factory-assets/connectors/sharepoint.js +15 -12
- package/dist/factory-assets/connectors/sqlite.js +15 -12
- package/dist/factory-assets/connectors/static-server.js +15 -12
- package/dist/factory-assets/connectors/tunnel.js +15 -12
- package/dist/factory-assets/connectors/webdav.js +15 -12
- package/dist/factory-assets/connectors/xstate-store.js +15 -12
- package/dist/factory-assets/connectors/xstate.js +15 -12
- package/dist/{flows-MI2VM5JZ.js → flows-4EIENFNT.js} +9 -7
- package/dist/{flows-MI2VM5JZ.js.map → flows-4EIENFNT.js.map} +1 -1
- package/dist/{helpers-G6XZPN6L.js → helpers-DISRVGRJ.js} +14 -12
- package/dist/{helpers-G6XZPN6L.js.map → helpers-DISRVGRJ.js.map} +1 -1
- package/dist/library/index.js +8 -6
- package/dist/library/install.js +5 -3
- package/dist/{library-publish-WHGKK7G5.js → library-publish-I2QYQSB4.js} +18 -16
- package/dist/library-publish-I2QYQSB4.js.map +1 -0
- package/dist/{open-library-4JSLGWL6.js → open-library-6LM4W4DR.js} +16 -14
- package/dist/{open-library-4JSLGWL6.js.map → open-library-6LM4W4DR.js.map} +1 -1
- package/dist/paths-P26QGQP5.js +18 -0
- package/dist/{paths-CZEH643M.js.map → paths-P26QGQP5.js.map} +1 -1
- package/dist/plugin-registry/src/targets.d.ts +16 -2
- package/dist/plugin-registry/src/targets.d.ts.map +1 -1
- package/dist/{plugin-store-QJNBPIQK.js → plugin-store-T2DJGKBW.js} +7 -5
- package/dist/plugin-store-T2DJGKBW.js.map +1 -0
- package/dist/{project-LISE6I5O.js → project-HP3IR7RW.js} +15 -13
- package/dist/{project-LISE6I5O.js.map → project-HP3IR7RW.js.map} +1 -1
- package/dist/resolver/index.js +5 -3
- package/dist/runner/index.js +25 -22
- package/dist/runner/src/agent.d.ts +0 -2
- 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/codex-resource-tools.d.ts.map +1 -1
- package/dist/runner/src/managed-codex-bootstrap.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +1 -2
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts +31 -35
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/runner/src/session.d.ts +0 -2
- package/dist/runner/src/session.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +11 -9
- package/dist/sdk/bridge.js +12 -9
- package/dist/sdk/core.js +5 -3
- package/dist/sdk/flow.js +6 -4
- package/dist/sdk/index.js +25 -22
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/resolver.js +5 -3
- package/dist/sdk/runner.js +25 -22
- package/dist/sdk/session.js +2 -2
- package/dist/sdk/types.js +1 -1
- package/dist/session/index.js +2 -2
- package/dist/setup-HLRSU3MR.js +435 -0
- package/dist/setup-HLRSU3MR.js.map +1 -0
- package/dist/{skills-IE3IWWB7.js → skills-QPYHHZ54.js} +7 -5
- package/dist/{skills-IE3IWWB7.js.map → skills-QPYHHZ54.js.map} +1 -1
- package/dist/{source-FKVEUOBQ.js → source-G2VCWPDU.js} +17 -15
- package/dist/{source-FKVEUOBQ.js.map → source-G2VCWPDU.js.map} +1 -1
- package/dist/{source-manifest-publish-LTRXO2OQ.js → source-manifest-publish-WYKCKJFC.js} +19 -17
- package/dist/source-manifest-publish-WYKCKJFC.js.map +1 -0
- package/dist/tui/index.js +25 -23
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/src/repl.d.ts +0 -2
- package/dist/tui/src/repl.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/manifests.js +1 -1
- package/dist/types/src/flow.d.ts +6 -1
- package/dist/types/src/flow.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/lifecycle.d.ts +35 -10
- package/dist/types/src/lifecycle.d.ts.map +1 -1
- package/dist/types/src/manifests/agent.d.ts +116 -22
- package/dist/types/src/manifests/agent.d.ts.map +1 -1
- package/dist/types/src/manifests/index.d.ts +2 -2
- package/dist/types/src/manifests/index.d.ts.map +1 -1
- package/dist/types/src/manifests/preset.d.ts +5 -5
- package/dist/types/src/runtime.d.ts +51 -5
- package/dist/types/src/runtime.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +18 -2
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/validator-P5ESKTW5.js +5 -0
- package/dist/{validator-RN64BKFW.js.map → validator-P5ESKTW5.js.map} +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +11 -9
- package/dist/workspace-plugin/adapters/omp.js +11 -11
- package/dist/workspace-plugin/adapters/omp.js.map +1 -1
- package/dist/workspace-plugin/index.js +1 -1
- package/dist/workspace-plugin/src/plugin.d.ts +1 -4
- package/dist/workspace-plugin/src/plugin.d.ts.map +1 -1
- package/dist/workspace-plugin/src/tools/validator.d.ts +4 -4
- package/dist/workspace-plugin/src/tools/validator.d.ts.map +1 -1
- package/package.json +13 -1
- package/dist/asset-feeds-AJOUKX55.js.map +0 -1
- package/dist/bridge/src/provider-endpoints.d.ts +0 -55
- package/dist/bridge/src/provider-endpoints.d.ts.map +0 -1
- package/dist/chunk-3NCGSSCU.js.map +0 -1
- package/dist/chunk-3U3ZKYR7.js.map +0 -1
- package/dist/chunk-5UWAOYDN.js.map +0 -1
- package/dist/chunk-AN6NAFRT.js.map +0 -1
- package/dist/chunk-AQW4BWNR.js +0 -324
- package/dist/chunk-AQW4BWNR.js.map +0 -1
- package/dist/chunk-DY5GHUTC.js.map +0 -1
- package/dist/chunk-E7HKNQTH.js.map +0 -1
- package/dist/chunk-FFE7YLYO.js.map +0 -1
- package/dist/chunk-FYIHH56K.js +0 -110
- package/dist/chunk-FYIHH56K.js.map +0 -1
- package/dist/chunk-GURXUF2J.js.map +0 -1
- package/dist/chunk-HSRHO7SK.js.map +0 -1
- package/dist/chunk-MBARHWMZ.js.map +0 -1
- package/dist/chunk-N27DSFA7.js.map +0 -1
- package/dist/chunk-T3YLZQS4.js.map +0 -1
- package/dist/chunk-XMULHVKX.js.map +0 -1
- package/dist/chunk-YLL65VXQ.js.map +0 -1
- package/dist/ensure-sources-DYGQNAJM.js.map +0 -1
- package/dist/library-publish-WHGKK7G5.js.map +0 -1
- package/dist/paths-CZEH643M.js +0 -16
- package/dist/plugin-store-QJNBPIQK.js.map +0 -1
- package/dist/runner/src/cloud-bundle.d.ts +0 -36
- package/dist/runner/src/cloud-bundle.d.ts.map +0 -1
- package/dist/setup-CIRH5BYB.js +0 -517
- package/dist/setup-CIRH5BYB.js.map +0 -1
- package/dist/source-manifest-publish-LTRXO2OQ.js.map +0 -1
- package/dist/validator-RN64BKFW.js +0 -5
|
@@ -1,12 +1,141 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { driverSessionConfigHome, removeSessionConfigFile, writeSessionConfigFile } from '../../chunk-YSJKLJD4.js';
|
|
2
|
+
import { SubprocessCliDriver, resolveEnvDriverSession, continueRoleBinding, credentialsForEveryProvider, extractText, extractCost, extractTokens, registryModelEntries, selectableEntries, entrySurface, backendProviderName, entryBaseUrl } from '../../chunk-LN2BQVRB.js';
|
|
2
3
|
import '../../chunk-GAH4YRCI.js';
|
|
3
|
-
import { BUILTIN_DRIVER_CATALOG, getBridgeLogger } from '../../chunk-
|
|
4
|
+
import { BUILTIN_DRIVER_CATALOG, getBridgeLogger, entryCredentialValue, registryDriverConfig, providerCredentialEnvName } from '../../chunk-SG4D2UOK.js';
|
|
4
5
|
import '../../chunk-6E6PKKAD.js';
|
|
6
|
+
import '../../chunk-C3QLJTMB.js';
|
|
7
|
+
import '../../chunk-REILIKVM.js';
|
|
8
|
+
import '../../chunk-F3HNW354.js';
|
|
9
|
+
import '../../chunk-K5GBV4SA.js';
|
|
10
|
+
import '../../chunk-QVZA2MDT.js';
|
|
11
|
+
import '../../chunk-K27T47OO.js';
|
|
12
|
+
import '../../chunk-MENCWIHW.js';
|
|
13
|
+
import '../../chunk-P4VHQA4N.js';
|
|
14
|
+
import '../../chunk-MKZOK4JU.js';
|
|
15
|
+
import '../../chunk-GEEW6SY2.js';
|
|
5
16
|
import '../../chunk-FTG7CRFD.js';
|
|
17
|
+
import '../../chunk-KSIRR5PL.js';
|
|
18
|
+
import { parseModelRef } from '../../chunk-ILG4BXYE.js';
|
|
6
19
|
import '../../chunk-W4IPN3DD.js';
|
|
7
20
|
import '../../chunk-NSBPE2FW.js';
|
|
8
21
|
import * as z from 'zod';
|
|
22
|
+
import { stringify } from 'yaml';
|
|
9
23
|
|
|
24
|
+
var CONTINUE_PROVIDER_CLASS = {
|
|
25
|
+
"anthropic-messages": "anthropic",
|
|
26
|
+
"openai-completions": "openai",
|
|
27
|
+
"openai-responses": "openai",
|
|
28
|
+
"google-generative-ai": "gemini"
|
|
29
|
+
};
|
|
30
|
+
var ENV_DELIVERED_CREDENTIALS = {
|
|
31
|
+
api_key_header: true,
|
|
32
|
+
bearer: true,
|
|
33
|
+
command: true
|
|
34
|
+
};
|
|
35
|
+
var CONTINUE_ROLES = {
|
|
36
|
+
chat: true,
|
|
37
|
+
edit: true,
|
|
38
|
+
apply: true,
|
|
39
|
+
autocomplete: true,
|
|
40
|
+
embed: true,
|
|
41
|
+
rerank: true,
|
|
42
|
+
summarize: true
|
|
43
|
+
};
|
|
44
|
+
var CONTINUE_CONFIG_FILENAME = "config.yaml";
|
|
45
|
+
function renderContinueModel(providerId, entry, model, roles) {
|
|
46
|
+
const surface = entrySurface(entry);
|
|
47
|
+
const providerClass = surface ? CONTINUE_PROVIDER_CLASS[surface] : void 0;
|
|
48
|
+
if (!providerClass)
|
|
49
|
+
return {
|
|
50
|
+
skipped: surface ? `Continue has no provider class for surface '${surface}'` : "entry declares no surface"
|
|
51
|
+
};
|
|
52
|
+
const row = {
|
|
53
|
+
name: `${backendProviderName(providerId, entry)}/${model}`,
|
|
54
|
+
provider: providerClass,
|
|
55
|
+
model,
|
|
56
|
+
roles
|
|
57
|
+
};
|
|
58
|
+
const baseUrl = entryBaseUrl(entry);
|
|
59
|
+
if (baseUrl) row.apiBase = baseUrl;
|
|
60
|
+
const credentialKind = entry.credential?.kind;
|
|
61
|
+
if (credentialKind && ENV_DELIVERED_CREDENTIALS[credentialKind])
|
|
62
|
+
row.apiKey = `\${{ secrets.${providerCredentialEnvName(providerId)} }}`;
|
|
63
|
+
if (entry.headers && Object.keys(entry.headers).length > 0)
|
|
64
|
+
row.requestOptions = { headers: { ...entry.headers } };
|
|
65
|
+
return { row };
|
|
66
|
+
}
|
|
67
|
+
function buildContinueConfigDocument(session) {
|
|
68
|
+
const warnings = [];
|
|
69
|
+
const models = [];
|
|
70
|
+
const document = {
|
|
71
|
+
name: "Skaile session",
|
|
72
|
+
version: "0.0.1",
|
|
73
|
+
schema: "v1",
|
|
74
|
+
models
|
|
75
|
+
};
|
|
76
|
+
const targets = [];
|
|
77
|
+
for (const [name, selector] of Object.entries(session.roles ?? {})) {
|
|
78
|
+
const role = CONTINUE_ROLES[name] ? name : name === "default" ? "chat" : void 0;
|
|
79
|
+
if (!role) {
|
|
80
|
+
warnings.push(`role '${name}' is not a Continue role \u2014 dropped`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const trimmed = selector.trim();
|
|
84
|
+
if (!trimmed) continue;
|
|
85
|
+
const resolved = parseModelRef(trimmed, session.registry);
|
|
86
|
+
if (!resolved?.providerModelId) {
|
|
87
|
+
warnings.push(`role '${name}' ('${selector}') resolves to no model in this registry`);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
targets.push({ role, providerId: resolved.providerId, model: resolved.providerModelId });
|
|
91
|
+
}
|
|
92
|
+
const chat = continueRoleBinding(session);
|
|
93
|
+
if (chat?.model && (session.modelRef || !targets.some((t) => t.role === "chat"))) {
|
|
94
|
+
const existing = targets.findIndex((t) => t.role === "chat");
|
|
95
|
+
const bound = { role: "chat", providerId: chat.providerId, model: chat.model };
|
|
96
|
+
if (existing >= 0) targets[existing] = bound;
|
|
97
|
+
else targets.unshift(bound);
|
|
98
|
+
}
|
|
99
|
+
const entries = new Map(selectableEntries(session.registry));
|
|
100
|
+
const rowByModel = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const target of targets) {
|
|
102
|
+
const entry = entries.get(target.providerId);
|
|
103
|
+
if (!entry) {
|
|
104
|
+
warnings.push(`role '${target.role}' names disabled or unknown entry '${target.providerId}'`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const key = `${target.providerId}/${target.model}`;
|
|
108
|
+
const already = rowByModel.get(key);
|
|
109
|
+
if (already) {
|
|
110
|
+
if (!already.roles.includes(target.role)) already.roles.push(target.role);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const rendered = renderContinueModel(target.providerId, entry, target.model, [target.role]);
|
|
114
|
+
if ("skipped" in rendered) {
|
|
115
|
+
warnings.push(`role '${target.role}' on '${target.providerId}': ${rendered.skipped}`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
rowByModel.set(key, rendered.row);
|
|
119
|
+
models.push(rendered.row);
|
|
120
|
+
}
|
|
121
|
+
return { document, warnings };
|
|
122
|
+
}
|
|
123
|
+
function materializeContinueConfig(session, config) {
|
|
124
|
+
const build = buildContinueConfigDocument(session);
|
|
125
|
+
const home = driverSessionConfigHome("continue", config);
|
|
126
|
+
if (build.document.models.length === 0) {
|
|
127
|
+
removeSessionConfigFile(home, CONTINUE_CONFIG_FILENAME);
|
|
128
|
+
return { ...build, env: {} };
|
|
129
|
+
}
|
|
130
|
+
const path = writeSessionConfigFile(
|
|
131
|
+
home,
|
|
132
|
+
CONTINUE_CONFIG_FILENAME,
|
|
133
|
+
stringify(build.document)
|
|
134
|
+
);
|
|
135
|
+
return { ...build, env: { CONTINUE_GLOBAL_DIR: home }, path };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// bridge/src/drivers/continue.ts
|
|
10
139
|
var ContinueDriver = class extends SubprocessCliDriver {
|
|
11
140
|
driverInfo = {
|
|
12
141
|
id: "continue",
|
|
@@ -19,18 +148,72 @@ var ContinueDriver = class extends SubprocessCliDriver {
|
|
|
19
148
|
productName = "Continue CLI";
|
|
20
149
|
envPrefix = "CONTINUE";
|
|
21
150
|
mode = "buffered";
|
|
151
|
+
providers;
|
|
152
|
+
/** This session's AI providers, resolved once from the config. */
|
|
153
|
+
providerSession() {
|
|
154
|
+
this.providers ??= resolveEnvDriverSession(this.config);
|
|
155
|
+
return this.providers;
|
|
156
|
+
}
|
|
157
|
+
/** The entry + model bound to Continue's `chat` role for this session. */
|
|
158
|
+
roleBinding() {
|
|
159
|
+
return continueRoleBinding(this.providerSession());
|
|
160
|
+
}
|
|
161
|
+
reconfigure(patch) {
|
|
162
|
+
super.reconfigure(patch);
|
|
163
|
+
if (patch.model !== void 0) this.providers = void 0;
|
|
164
|
+
}
|
|
165
|
+
getModel() {
|
|
166
|
+
return this.roleBinding()?.model ?? this.config.model;
|
|
167
|
+
}
|
|
168
|
+
async start() {
|
|
169
|
+
const role = this.roleBinding();
|
|
170
|
+
if (role) {
|
|
171
|
+
this.log.debug("bound Continue's chat role to an AI provider entry", {
|
|
172
|
+
providerId: role.providerId,
|
|
173
|
+
provider: role.provider,
|
|
174
|
+
model: role.model,
|
|
175
|
+
apiKeyEnv: role.apiKeyEnv
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
await super.start();
|
|
179
|
+
}
|
|
22
180
|
buildArgs(message, resumeId) {
|
|
23
181
|
const args = ["-p", message, "--format", "json", "--silent"];
|
|
24
|
-
const slug = this.config.model;
|
|
182
|
+
const slug = this.roleBinding() ? void 0 : this.config.model;
|
|
25
183
|
if (slug) args.push("--config", slug);
|
|
26
184
|
if (resumeId) args.push("--resume");
|
|
27
185
|
return args;
|
|
28
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Base env plus one credential variable per enabled registry entry. The
|
|
189
|
+
* Continue Hub key is its own credential, not an endpoint's: a registry
|
|
190
|
+
* entry with the reserved id `continue` supplies it, otherwise an ambient
|
|
191
|
+
* `CONTINUE_API_KEY` (or a `cn login`) does.
|
|
192
|
+
*
|
|
193
|
+
* This is also where the session's role bindings are rendered into a
|
|
194
|
+
* private `config.yaml`. It runs once per spawn, so a `reconfigure()`
|
|
195
|
+
* between turns re-renders rather than leaving `cn` bound to the previous
|
|
196
|
+
* selection.
|
|
197
|
+
*/
|
|
29
198
|
buildEnv() {
|
|
199
|
+
const session = this.providerSession();
|
|
30
200
|
const env = this.baseEnv(["CONTINUE_API_KEY"]);
|
|
31
|
-
const
|
|
201
|
+
const hub = session.registry.providers.continue;
|
|
202
|
+
const key = (hub ? entryCredentialValue("continue", hub, { env: session.lookupEnv }) : void 0) ?? session.lookupEnv.CONTINUE_API_KEY;
|
|
32
203
|
if (key) env.CONTINUE_API_KEY = key;
|
|
33
|
-
|
|
204
|
+
const materialized = materializeContinueConfig(session, this.config);
|
|
205
|
+
for (const warning of materialized.warnings)
|
|
206
|
+
this.log.warn("Continue role binding", { warning });
|
|
207
|
+
if (materialized.path)
|
|
208
|
+
this.log.debug("rendered Continue assistant", {
|
|
209
|
+
path: materialized.path,
|
|
210
|
+
models: materialized.document.models.map((m) => `${m.name} [${m.roles.join(", ")}]`)
|
|
211
|
+
});
|
|
212
|
+
return {
|
|
213
|
+
...env,
|
|
214
|
+
...credentialsForEveryProvider(session),
|
|
215
|
+
...materialized.env
|
|
216
|
+
};
|
|
34
217
|
}
|
|
35
218
|
installHint() {
|
|
36
219
|
return "Continue CLI is not installed or not on your PATH. Install it with `npm i -g @continuedev/cli`.";
|
|
@@ -58,8 +241,12 @@ var ContinueDriver = class extends SubprocessCliDriver {
|
|
|
58
241
|
summary: text || "Task completed"
|
|
59
242
|
});
|
|
60
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Continue resolves models through its `config.yaml` / Hub assistant, not
|
|
246
|
+
* through an endpoint, so the session's registry is the list.
|
|
247
|
+
*/
|
|
61
248
|
async listModels() {
|
|
62
|
-
return
|
|
249
|
+
return registryModelEntries(this.providerSession());
|
|
63
250
|
}
|
|
64
251
|
};
|
|
65
252
|
function parseLastJsonObject(raw) {
|
|
@@ -96,7 +283,12 @@ var continueDriverTarget = {
|
|
|
96
283
|
displayName: BUILTIN_DRIVER_CATALOG.continue?.name ?? "Continue CLI",
|
|
97
284
|
apiVersion: 1,
|
|
98
285
|
configSchema: z.custom(() => true),
|
|
99
|
-
create: async (config, _ctx) => new ContinueDriver(config)
|
|
286
|
+
create: async (config, _ctx) => new ContinueDriver(config),
|
|
287
|
+
listModels: async (registry, options) => new ContinueDriver({
|
|
288
|
+
cwd: process.cwd(),
|
|
289
|
+
sessionId: "model-list",
|
|
290
|
+
...registryDriverConfig(registry, options)
|
|
291
|
+
}).listModels()
|
|
100
292
|
};
|
|
101
293
|
|
|
102
294
|
export { ContinueDriver, continueDriverTarget };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../bridge/src/drivers/continue.ts"],"names":["text"],"mappings":"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","file":"continue.js","sourcesContent":["import type { DriverTarget } from \"@skaile/workspaces/plugin-registry\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport type { ModelEntry } from \"../models.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig, DriverInfo } from \"../types.js\";\nimport {\n extractCost,\n extractText,\n extractTokens,\n mapApiKeysToEnv,\n SubprocessCliDriver,\n} from \"./_subprocess-cli.js\";\n\n/**\n * Agent driver for the **Continue CLI** (`cn`), the model-agnostic agent backed\n * by Continue Hub / `config.yaml` assistants.\n *\n * Unlike the other CLI drivers, `cn -p \"<prompt>\" --format json` emits a single\n * **final-result JSON wrapper**, not a streaming event log. This driver runs in\n * `mode: \"buffered\"`: the base accumulates all stdout and {@link handleBuffered}\n * parses it once on exit — so there are no incremental deltas or per-tool\n * events, only a final assistant message plus a result.\n *\n * @remarks\n * - Auth via `CONTINUE_API_KEY` / `cn login`; provider keys flow through the\n * environment and the selected `config.yaml`.\n * - `--config <slug>` selects the assistant; session resume via `--resume`\n * (last session only — Continue has no resume-by-id in headless mode).\n *\n * @see https://docs.continue.dev/guides/cli\n * @docLink packages/bridge/drivers#continue-driver\n */\nexport class ContinueDriver extends SubprocessCliDriver {\n readonly driverInfo: DriverInfo = {\n id: \"continue\",\n name: \"Continue CLI\",\n modelAgnostic: true,\n supportsInBandAbort: false,\n };\n\n protected readonly log: Logger = getBridgeLogger(\"continue\");\n protected readonly defaultBin = \"cn\";\n protected readonly productName = \"Continue CLI\";\n protected readonly envPrefix = \"CONTINUE\";\n protected override readonly mode = \"buffered\" as const;\n\n protected buildArgs(message: string, resumeId: string | undefined): string[] {\n const args = [\"-p\", message, \"--format\", \"json\", \"--silent\"];\n const slug = this.config.model; // Continue selects assistants/models by config slug.\n if (slug) args.push(\"--config\", slug);\n if (resumeId) args.push(\"--resume\");\n return args;\n }\n\n protected buildEnv(): Record<string, string> {\n const env = this.baseEnv([\"CONTINUE_API_KEY\"]);\n const key =\n this.config.apiKeys?.continue ??\n this.config.env?.CONTINUE_API_KEY ??\n process.env.CONTINUE_API_KEY;\n if (key) env.CONTINUE_API_KEY = key;\n return { ...env, ...mapApiKeysToEnv(this.config.apiKeys) };\n }\n\n protected installHint(): string {\n return \"Continue CLI is not installed or not on your PATH. Install it with `npm i -g @continuedev/cli`.\";\n }\n\n protected handleBuffered(raw: string): void {\n const json = parseLastJsonObject(raw);\n if (!json) {\n // No structured wrapper — surface the raw stdout as the assistant reply.\n const text = raw.trim();\n if (text) {\n this.pushAssistantDelta(text);\n this.pushAssistantEnd(text);\n }\n this.pushResult({ summary: text || \"Task completed\" });\n return;\n }\n this.captureSession(json.sessionId ?? json.session_id ?? json.id);\n const text = extractText(json) || (typeof json.output === \"string\" ? json.output : \"\");\n if (text) {\n this.pushAssistantDelta(text);\n this.pushAssistantEnd(text);\n }\n this.pushResult({\n tokens: extractTokens(json),\n costUsd: extractCost(json),\n summary: text || \"Task completed\",\n });\n }\n\n override async listModels(): Promise<ModelEntry[]> {\n return [];\n }\n}\n\n/**\n * Parse the last balanced top-level JSON object in `raw`. Continue may print\n * log lines before the final `--format json` blob; we want the wrapper, which\n * is the last `{...}` in the output.\n */\nfunction parseLastJsonObject(raw: string): any | null {\n const end = raw.lastIndexOf(\"}\");\n if (end < 0) return null;\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let i = end; i >= 0; i--) {\n const ch = raw[i];\n if (inString) {\n if (escaped) escaped = false;\n else if (ch === \"\\\\\") escaped = true;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') inString = true;\n else if (ch === \"}\") depth++;\n else if (ch === \"{\") {\n depth--;\n if (depth === 0) {\n try {\n return JSON.parse(raw.slice(i, end + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\n/**\n * `DriverTarget` wrapper for the continue driver. Registered into the plugin\n * registry by `registerBuiltinDrivers()`.\n */\nexport const continueDriverTarget: DriverTarget<AgentConfig> = {\n id: \"continue\",\n displayName: BUILTIN_DRIVER_CATALOG.continue?.name ?? \"Continue CLI\",\n apiVersion: 1,\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new ContinueDriver(config),\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../bridge/src/provider-materialize/continue-config-yaml.ts","../../../bridge/src/drivers/continue.ts"],"names":["stringifyYaml","text"],"mappings":"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","file":"continue.js","sourcesContent":["/**\n * Continue's `config.yaml` adapter — the file half of the Continue row (§2.3).\n *\n * `cn` has no model flag. Its assistant is a document, and the document binds\n * models to **roles** (`chat`, `edit`, `apply`, `autocomplete`, `embed`,\n * `rerank`, `summarize`); a headless `cn -p` turn runs as `chat`. So unlike\n * OpenCode and Goose, Continue needs a file for *every* endpoint, stock or\n * custom — it has no built-in provider table keyed by vendor names to fall\n * back on:\n *\n * ```yaml\n * name: Skaile session\n * version: 0.0.1\n * schema: v1\n * models:\n * - name: corp-gateway/corp-fast-1\n * provider: openai\n * model: corp-fast-1\n * apiBase: https://llm.corp.example/v1\n * apiKey: ${{ secrets.SKAILE_AIP_CORP_GATEWAY_KEY }}\n * roles:\n * - chat\n * ```\n *\n * `provider` is Continue's *adapter class*, not an endpoint name — the\n * endpoint is `apiBase`. The row's `name` carries the identity instead, and it\n * is `backendProviderName`/`backendModelSelector` verbatim, so a model reads\n * the same here as in every other adapter.\n *\n * **Credentials never enter the file.** `apiKey` holds Continue's own\n * `${{ secrets.NAME }}` indirection; the CLI resolves a secret from the\n * process environment before it asks Continue Hub, so `SKAILE_AIP_<ID>_KEY`\n * in the child env is what authenticates the request.\n *\n * **Roles.** The session's `roles` table is the source: every entry whose key\n * is one of Continue's roles becomes that role's binding (`default` is read as\n * `chat`, matching how the rest of the programme spells the fallback), and the\n * session's own model selection wins `chat` when it named one.\n *\n * @see https://docs.continue.dev/reference\n * @docLink packages/bridge/drivers#one-shot-cli-drivers-gemini-qwen-opencode-goose-continue\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n parseModelRef,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport { stringify as stringifyYaml } from \"yaml\";\nimport { providerCredentialEnvName } from \"./credential-env.js\";\nimport {\n backendProviderName,\n continueRoleBinding,\n entryBaseUrl,\n entrySurface,\n type EnvDriverSession,\n selectableEntries,\n} from \"./env-drivers.js\";\nimport {\n driverSessionConfigHome,\n removeSessionConfigFile,\n writeSessionConfigFile,\n} from \"./session-config-home.js\";\n\n/**\n * `surface` → Continue's provider class. Continue's `openai` adapter is the\n * OpenAI adapter, so both OpenAI-flavoured surfaces resolve to it; the\n * surfaces Continue has no adapter for are reported instead of guessed at.\n */\nconst CONTINUE_PROVIDER_CLASS: Partial<Record<AIProviderSurface, string>> = {\n \"anthropic-messages\": \"anthropic\",\n \"openai-completions\": \"openai\",\n \"openai-responses\": \"openai\",\n \"google-generative-ai\": \"gemini\",\n};\n\n/** Credential kinds whose value the adapter hands over in an env var. */\nconst ENV_DELIVERED_CREDENTIALS: Record<string, true> = {\n api_key_header: true,\n bearer: true,\n command: true,\n};\n\n/** Roles a Continue `config.yaml` can bind a model to. */\nconst CONTINUE_ROLES: Record<string, true> = {\n chat: true,\n edit: true,\n apply: true,\n autocomplete: true,\n embed: true,\n rerank: true,\n summarize: true,\n};\n\n/** Filename Continue reads its local assistant from, under the global dir. */\nexport const CONTINUE_CONFIG_FILENAME = \"config.yaml\";\n\n/** One `models[]` row. */\nexport interface ContinueModelRow {\n /** `<backendProviderName>/<providerModelId>` — the programme-wide model id. */\n name: string;\n /** Continue adapter class: `openai`, `anthropic`, `gemini`. */\n provider: string;\n /** Provider-side model id. */\n model: string;\n apiBase?: string;\n /** Continue's `${{ secrets.NAME }}` indirection — never a secret. */\n apiKey?: string;\n roles: string[];\n requestOptions?: { headers: Record<string, string> };\n}\n\n/** The `config.yaml` document this adapter owns. */\nexport interface ContinueConfigDocument {\n name: string;\n version: string;\n schema: string;\n models: ContinueModelRow[];\n}\n\n/** Result of {@link buildContinueConfigDocument}. */\nexport interface ContinueConfigBuild {\n document: ContinueConfigDocument;\n /** Role bindings that resolved to nothing Continue can run. */\n warnings: string[];\n}\n\n/** One resolved role → endpoint + model. */\ninterface RoleTarget {\n role: string;\n providerId: string;\n model: string;\n}\n\n/**\n * Render one entry + model as a `models[]` row, or explain why Continue cannot\n * run it.\n */\nexport function renderContinueModel(\n providerId: string,\n entry: AIProviderLlmEntry,\n model: string,\n roles: string[],\n): { row: ContinueModelRow } | { skipped: string } {\n const surface = entrySurface(entry);\n const providerClass = surface ? CONTINUE_PROVIDER_CLASS[surface] : undefined;\n if (!providerClass)\n return {\n skipped: surface\n ? `Continue has no provider class for surface '${surface}'`\n : \"entry declares no surface\",\n };\n\n const row: ContinueModelRow = {\n name: `${backendProviderName(providerId, entry)}/${model}`,\n provider: providerClass,\n model,\n roles,\n };\n const baseUrl = entryBaseUrl(entry);\n if (baseUrl) row.apiBase = baseUrl;\n const credentialKind = entry.credential?.kind;\n if (credentialKind && ENV_DELIVERED_CREDENTIALS[credentialKind])\n row.apiKey = `\\${{ secrets.${providerCredentialEnvName(providerId)} }}`;\n if (entry.headers && Object.keys(entry.headers).length > 0)\n row.requestOptions = { headers: { ...entry.headers } };\n return { row };\n}\n\n/**\n * Build the document for a session: one `models[]` row per distinct endpoint +\n * model a role binds, with every role that binds it.\n *\n * Only bound models are rendered. Continue defaults an omitted `roles` to\n * `[chat, edit, apply, summarize]`, so listing the registry's other models\n * would silently make each of them a chat candidate — the document says\n * exactly what the session decided and nothing else.\n *\n * An empty registry renders nothing — `cn` then runs on whatever its own\n * `config.yaml` or Hub login provides.\n */\nexport function buildContinueConfigDocument(session: EnvDriverSession): ContinueConfigBuild {\n const warnings: string[] = [];\n const models: ContinueModelRow[] = [];\n const document: ContinueConfigDocument = {\n name: \"Skaile session\",\n version: \"0.0.1\",\n schema: \"v1\",\n models,\n };\n const targets: RoleTarget[] = [];\n\n for (const [name, selector] of Object.entries(session.roles ?? {})) {\n const role = CONTINUE_ROLES[name] ? name : name === \"default\" ? \"chat\" : undefined;\n if (!role) {\n warnings.push(`role '${name}' is not a Continue role — dropped`);\n continue;\n }\n const trimmed = selector.trim();\n if (!trimmed) continue;\n // Roles do not chain: each value is a plain selector, never another `@role`.\n const resolved = parseModelRef(trimmed, session.registry);\n if (!resolved?.providerModelId) {\n warnings.push(`role '${name}' ('${selector}') resolves to no model in this registry`);\n continue;\n }\n targets.push({ role, providerId: resolved.providerId, model: resolved.providerModelId });\n }\n\n // The session's own selection is more specific than the roles table, and an\n // absent `chat` has to come from somewhere: the env half's chat binding is\n // the same resolution `cn` would otherwise have had no way to express.\n const chat = continueRoleBinding(session);\n if (chat?.model && (session.modelRef || !targets.some((t) => t.role === \"chat\"))) {\n const existing = targets.findIndex((t) => t.role === \"chat\");\n const bound: RoleTarget = { role: \"chat\", providerId: chat.providerId, model: chat.model };\n if (existing >= 0) targets[existing] = bound;\n else targets.unshift(bound);\n }\n\n const entries = new Map(selectableEntries(session.registry));\n const rowByModel = new Map<string, ContinueModelRow>();\n for (const target of targets) {\n const entry = entries.get(target.providerId);\n if (!entry) {\n warnings.push(`role '${target.role}' names disabled or unknown entry '${target.providerId}'`);\n continue;\n }\n const key = `${target.providerId}/${target.model}`;\n const already = rowByModel.get(key);\n if (already) {\n if (!already.roles.includes(target.role)) already.roles.push(target.role);\n continue;\n }\n const rendered = renderContinueModel(target.providerId, entry, target.model, [target.role]);\n if (\"skipped\" in rendered) {\n warnings.push(`role '${target.role}' on '${target.providerId}': ${rendered.skipped}`);\n continue;\n }\n rowByModel.set(key, rendered.row);\n models.push(rendered.row);\n }\n\n return { document, warnings };\n}\n\n/** What {@link materializeContinueConfig} handed the driver. */\nexport interface ContinueMaterialization extends ContinueConfigBuild {\n /** Child env fragment: `CONTINUE_GLOBAL_DIR`, or empty when nothing was written. */\n env: Record<string, string>;\n /** Absolute path of the rendered file, when one was written. */\n path?: string;\n}\n\n/**\n * Render the session's role bindings and point the child at them.\n *\n * A session that bound no model writes nothing and leaves\n * `CONTINUE_GLOBAL_DIR` alone, so `cn` keeps resolving its Hub assistant (or\n * the developer's own `~/.continue/config.yaml`) exactly as before. A file\n * left by an earlier render of the same session is removed in that case.\n */\nexport function materializeContinueConfig(\n session: EnvDriverSession,\n config: { cwd: string; sessionId?: string },\n): ContinueMaterialization {\n const build = buildContinueConfigDocument(session);\n const home = driverSessionConfigHome(\"continue\", config);\n if (build.document.models.length === 0) {\n removeSessionConfigFile(home, CONTINUE_CONFIG_FILENAME);\n return { ...build, env: {} };\n }\n const path = writeSessionConfigFile(\n home,\n CONTINUE_CONFIG_FILENAME,\n stringifyYaml(build.document),\n );\n return { ...build, env: { CONTINUE_GLOBAL_DIR: home }, path };\n}\n","import type { DriverTarget } from \"@skaile/workspaces/plugin-registry\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport type { ModelEntry } from \"../models.js\";\nimport { materializeContinueConfig } from \"../provider-materialize/continue-config-yaml.js\";\nimport { entryCredentialValue } from \"../provider-materialize/credential-env.js\";\nimport {\n type ContinueRoleBinding,\n continueRoleBinding,\n credentialsForEveryProvider,\n type EnvDriverSession,\n registryModelEntries,\n resolveEnvDriverSession,\n} from \"../provider-materialize/env-drivers.js\";\nimport { registryDriverConfig } from \"../provider-registry-derive.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig, DriverInfo } from \"../types.js\";\nimport { extractCost, extractText, extractTokens, SubprocessCliDriver } from \"./_subprocess-cli.js\";\n\n/**\n * Agent driver for the **Continue CLI** (`cn`), the model-agnostic agent backed\n * by Continue Hub / `config.yaml` assistants.\n *\n * Unlike the other CLI drivers, `cn -p \"<prompt>\" --format json` emits a single\n * **final-result JSON wrapper**, not a streaming event log. This driver runs in\n * `mode: \"buffered\"`: the base accumulates all stdout and {@link handleBuffered}\n * parses it once on exit — so there are no incremental deltas or per-tool\n * events, only a final assistant message plus a result.\n *\n * @remarks\n * - Auth via `CONTINUE_API_KEY` / `cn login`. A `credentials-n` backend\n * (§2.3): every enabled AI provider entry's credential reaches the child\n * environment, and the active model is a **role binding** — `cn` has no\n * `--model` flag, its `config.yaml` binds models to roles — so the session's\n * selector resolves to {@link ContinueRoleBinding} rather than a flag.\n * - `--config <slug>` selects a Continue Hub assistant; session resume via\n * `--resume` (last session only — Continue has no resume-by-id in headless\n * mode).\n * @see https://docs.continue.dev/guides/cli\n * @docLink packages/bridge/drivers#continue-driver\n */\nexport class ContinueDriver extends SubprocessCliDriver {\n readonly driverInfo: DriverInfo = {\n id: \"continue\",\n name: \"Continue CLI\",\n modelAgnostic: true,\n supportsInBandAbort: false,\n };\n\n protected readonly log: Logger = getBridgeLogger(\"continue\");\n protected readonly defaultBin = \"cn\";\n protected readonly productName = \"Continue CLI\";\n protected readonly envPrefix = \"CONTINUE\";\n protected override readonly mode = \"buffered\" as const;\n\n private providers?: EnvDriverSession;\n\n /** This session's AI providers, resolved once from the config. */\n private providerSession(): EnvDriverSession {\n this.providers ??= resolveEnvDriverSession(this.config);\n return this.providers;\n }\n\n /** The entry + model bound to Continue's `chat` role for this session. */\n private roleBinding(): ContinueRoleBinding | undefined {\n return continueRoleBinding(this.providerSession());\n }\n\n override reconfigure(patch: Partial<Pick<AgentConfig, \"model\" | \"thinking\" | \"effort\">>): void {\n super.reconfigure(patch);\n if (patch.model !== undefined) this.providers = undefined;\n }\n\n override getModel(): string | undefined {\n return this.roleBinding()?.model ?? this.config.model;\n }\n\n override async start(): Promise<void> {\n const role = this.roleBinding();\n if (role) {\n this.log.debug(\"bound Continue's chat role to an AI provider entry\", {\n providerId: role.providerId,\n provider: role.provider,\n model: role.model,\n apiKeyEnv: role.apiKeyEnv,\n });\n }\n await super.start();\n }\n\n protected buildArgs(message: string, resumeId: string | undefined): string[] {\n const args = [\"-p\", message, \"--format\", \"json\", \"--silent\"];\n // `--config` names a Continue Hub assistant; `cn` has no model flag. A\n // selector the registry resolves is a *model*, so it must never be passed\n // here — that would point `cn` at an assistant slug that does not exist.\n const slug = this.roleBinding() ? undefined : this.config.model;\n if (slug) args.push(\"--config\", slug);\n if (resumeId) args.push(\"--resume\");\n return args;\n }\n\n /**\n * Base env plus one credential variable per enabled registry entry. The\n * Continue Hub key is its own credential, not an endpoint's: a registry\n * entry with the reserved id `continue` supplies it, otherwise an ambient\n * `CONTINUE_API_KEY` (or a `cn login`) does.\n *\n * This is also where the session's role bindings are rendered into a\n * private `config.yaml`. It runs once per spawn, so a `reconfigure()`\n * between turns re-renders rather than leaving `cn` bound to the previous\n * selection.\n */\n protected buildEnv(): Record<string, string> {\n const session = this.providerSession();\n const env = this.baseEnv([\"CONTINUE_API_KEY\"]);\n const hub = session.registry.providers.continue;\n const key =\n (hub ? entryCredentialValue(\"continue\", hub, { env: session.lookupEnv }) : undefined) ??\n session.lookupEnv.CONTINUE_API_KEY;\n if (key) env.CONTINUE_API_KEY = key;\n const materialized = materializeContinueConfig(session, this.config);\n for (const warning of materialized.warnings)\n this.log.warn(\"Continue role binding\", { warning });\n if (materialized.path)\n this.log.debug(\"rendered Continue assistant\", {\n path: materialized.path,\n models: materialized.document.models.map((m) => `${m.name} [${m.roles.join(\", \")}]`),\n });\n return {\n ...env,\n ...credentialsForEveryProvider(session),\n ...materialized.env,\n };\n }\n\n protected installHint(): string {\n return \"Continue CLI is not installed or not on your PATH. Install it with `npm i -g @continuedev/cli`.\";\n }\n\n protected handleBuffered(raw: string): void {\n const json = parseLastJsonObject(raw);\n if (!json) {\n // No structured wrapper — surface the raw stdout as the assistant reply.\n const text = raw.trim();\n if (text) {\n this.pushAssistantDelta(text);\n this.pushAssistantEnd(text);\n }\n this.pushResult({ summary: text || \"Task completed\" });\n return;\n }\n this.captureSession(json.sessionId ?? json.session_id ?? json.id);\n const text = extractText(json) || (typeof json.output === \"string\" ? json.output : \"\");\n if (text) {\n this.pushAssistantDelta(text);\n this.pushAssistantEnd(text);\n }\n this.pushResult({\n tokens: extractTokens(json),\n costUsd: extractCost(json),\n summary: text || \"Task completed\",\n });\n }\n\n /**\n * Continue resolves models through its `config.yaml` / Hub assistant, not\n * through an endpoint, so the session's registry is the list.\n */\n override async listModels(): Promise<ModelEntry[]> {\n return registryModelEntries(this.providerSession());\n }\n}\n\n/**\n * Parse the last balanced top-level JSON object in `raw`. Continue may print\n * log lines before the final `--format json` blob; we want the wrapper, which\n * is the last `{...}` in the output.\n */\nfunction parseLastJsonObject(raw: string): any | null {\n const end = raw.lastIndexOf(\"}\");\n if (end < 0) return null;\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let i = end; i >= 0; i--) {\n const ch = raw[i];\n if (inString) {\n if (escaped) escaped = false;\n else if (ch === \"\\\\\") escaped = true;\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') inString = true;\n else if (ch === \"}\") depth++;\n else if (ch === \"{\") {\n depth--;\n if (depth === 0) {\n try {\n return JSON.parse(raw.slice(i, end + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\n/**\n * `DriverTarget` wrapper for the continue driver. Registered into the plugin\n * registry by `registerBuiltinDrivers()`.\n */\nexport const continueDriverTarget: DriverTarget<AgentConfig> = {\n id: \"continue\",\n displayName: BUILTIN_DRIVER_CATALOG.continue?.name ?? \"Continue CLI\",\n apiVersion: 1,\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new ContinueDriver(config),\n listModels: async (registry, options) =>\n new ContinueDriver({\n cwd: process.cwd(),\n sessionId: \"model-list\",\n ...registryDriverConfig(registry, options),\n }).listModels(),\n};\n"]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { dispatchCapability } from '../../chunk-
|
|
2
|
-
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-
|
|
1
|
+
import { dispatchCapability } from '../../chunk-QQL3ET3J.js';
|
|
2
|
+
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger, registryDriverConfig } from '../../chunk-SG4D2UOK.js';
|
|
3
3
|
import '../../chunk-6E6PKKAD.js';
|
|
4
|
-
import '../../chunk-
|
|
4
|
+
import '../../chunk-YS4XBN7O.js';
|
|
5
5
|
import '../../chunk-FTG7CRFD.js';
|
|
6
|
+
import '../../chunk-KSIRR5PL.js';
|
|
7
|
+
import '../../chunk-ILG4BXYE.js';
|
|
6
8
|
import '../../chunk-W4IPN3DD.js';
|
|
7
9
|
import '../../chunk-NSBPE2FW.js';
|
|
8
10
|
import * as z from 'zod';
|
|
@@ -424,7 +426,11 @@ var echoDriverTarget = {
|
|
|
424
426
|
// Drivers take AgentConfig; passthrough — full schema validation is out of scope.
|
|
425
427
|
configSchema: z.custom(() => true),
|
|
426
428
|
create: async (config, _ctx) => new EchoDriver(config),
|
|
427
|
-
listModels: async (
|
|
429
|
+
listModels: async (registry, options) => new EchoDriver({
|
|
430
|
+
cwd: process.cwd(),
|
|
431
|
+
sessionId: "model-list",
|
|
432
|
+
...registryDriverConfig(registry, options)
|
|
433
|
+
}).listModels()
|
|
428
434
|
};
|
|
429
435
|
|
|
430
436
|
export { EchoDriver, echoDriverTarget };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../bridge/src/drivers/flow-script.ts","../../../bridge/src/drivers/echo.ts"],"names":["events"],"mappings":"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","file":"echo.js","sourcesContent":["/**\n * Scripted-flow decision logic for the echo driver.\n *\n * Pure, deterministic policy that maps a live {@link FlowExecution} snapshot\n * (plus an optional per-node script) to the single next flow-adapter mutation\n * the driver should emit this iteration. The echo driver calls this in a loop\n * per turn (see `echo.ts`), executing each returned action against the\n * runner-injected {@link FlowTestDriverHook} until it yields (`null`) or emits\n * a turn-ending action.\n *\n * The policy mirrors what a real LLM orchestrator would do, but without an\n * LLM: it reacts to state each turn, so a host can drive a flow to `complete`,\n * park it at an approval/input gate, and exercise the reject/recover path\n * simply by applying host mutations (`applyApproval`, `applyInput`, …) between\n * turns. No new protocol, no flow-contract change — it only calls the existing\n * FlowAdapter agent-tool operations.\n *\n * @docLink packages/bridge/drivers#scripted-flow\n * @since 3.6.0\n */\n\nimport type { FlowExecution, NodeExecution } from \"@skaile/workspaces/types\";\n\n/**\n * What the scripted driver should do when a node reaches its decision point.\n *\n * - `auto` (default): follow the flow's `autonomousMode` — `complete_node`\n * when autonomous, else `request_approval`. A mandatory approval gate always\n * resolves to `request_approval`, even when autonomous (it cannot be skipped).\n * - `complete`: always `complete_node` (autonomous-style, even if the flow's\n * autonomousMode is false — the adapter allows it only when autonomous, so\n * use with autonomous flows).\n * - `approve`: always `request_approval` (park at an approval gate).\n * - `input`: `request_input` once; after the host applies input, fall back to\n * `auto` behaviour.\n * - `skip`: `skip_node` (optional nodes only).\n * - `fail`: `fail_node`. With `recoverable: false` (default) this is terminal.\n * With `recoverable: true` the node returns to `available`; the driver\n * re-emits the recoverable failure `failCount` times (default 1) and then\n * proceeds as `auto` — it never deadlocks on a recoverable fail.\n */\nexport type OnRun = \"auto\" | \"complete\" | \"approve\" | \"input\" | \"skip\" | \"fail\";\n\n/**\n * What to do when a node returns to `available` after a rejection.\n *\n * - `retry` (default): re-drive it — `start_node` again, then its `onRun`.\n * - `fail`: `fail_node(recoverable: false)` — exercises the terminal path.\n */\nexport type OnReject = \"retry\" | \"fail\";\n\n/** Per-node scripting directive. All fields optional. */\nexport interface FlowNodeDirective {\n onRun?: OnRun;\n onReject?: OnReject;\n /** For `onRun: \"input\"` — the input request shown to the host. */\n input?: { prompt?: string; schema?: unknown };\n /** For `onRun: \"fail\"` — whether the failure is recoverable. Default false. */\n recoverable?: boolean;\n /**\n * For `onRun: \"fail\"` with `recoverable: true` — how many recoverable\n * failures to emit before the node proceeds as `auto`. Default 1. Counted\n * from the node's own `errorHistory`, so the policy stays a pure function of\n * state (no driver-instance bookkeeping) and never deadlocks.\n */\n failCount?: number;\n /** Summary text used for `complete_node` / `request_approval` / failures. */\n summary?: string;\n}\n\n/**\n * A scripted-flow program. Empty (`{}`) means \"canonical policy\": start each\n * available node, then complete (autonomous) or request approval (interactive)\n * — enough to drive the autonomous-complete, approval-gate, and reject/recover\n * scenarios with no per-node scripting at all.\n */\nexport interface FlowScript {\n /** Per-node overrides, keyed by node id. */\n nodes?: Record<string, FlowNodeDirective>;\n /** Fallback directive for any node without its own entry. */\n default?: FlowNodeDirective;\n}\n\n/** A single flow-adapter mutation the driver will execute. */\nexport type FlowAction =\n | { op: \"start_node\"; nodeId: string }\n | { op: \"complete_node\"; nodeId: string; summary: string }\n | { op: \"request_approval\"; nodeId: string; summary: string }\n | { op: \"request_input\"; nodeId: string; prompt: string; schema: string }\n | { op: \"skip_node\"; nodeId: string }\n | { op: \"fail_node\"; nodeId: string; message: string; recoverable: boolean };\n\n/** Ops that end the agent turn (the runner yields until the host acts). */\nconst TURN_ENDING: ReadonlySet<FlowAction[\"op\"]> = new Set([\n \"request_approval\",\n \"request_input\",\n \"fail_node\",\n]);\n\n/** Whether an action ends the turn (driver stops looping after emitting it). */\nexport function isTurnEnding(action: FlowAction): boolean {\n return TURN_ENDING.has(action.op);\n}\n\n/** Map a {@link FlowAction} to the `executeOp` argument bag the adapter expects. */\nexport function actionArgs(action: FlowAction): Record<string, unknown> {\n switch (action.op) {\n case \"start_node\":\n case \"skip_node\":\n return { nodeId: action.nodeId };\n case \"complete_node\":\n return { nodeId: action.nodeId, summary: action.summary };\n case \"request_approval\":\n return { nodeId: action.nodeId, summary: action.summary };\n case \"request_input\":\n return { nodeId: action.nodeId, prompt: action.prompt, schema: action.schema };\n case \"fail_node\":\n return {\n nodeId: action.nodeId,\n message: action.message,\n recoverable: String(action.recoverable),\n };\n }\n}\n\nfunction summaryFor(d: FlowNodeDirective, n: NodeExecution): string {\n return d.summary ?? `Scripted output for ${n.id}`;\n}\n\n/**\n * Decide the single next flow action for the current state, or `null` to yield\n * (nothing to do this iteration — wait for a host mutation).\n *\n * Priority order: resolve approved gates → advance running nodes → start (or\n * skip / terminally-fail) available nodes. Terminal flow states and gates with\n * no decision / input yet yield.\n *\n * Pure — the fail bookkeeping (how many recoverable failures a node has already\n * emitted) is read from the node's own `errorHistory`, so no external counter is\n * needed and a recoverable `fail` directive can never deadlock.\n */\nexport function decideFlowAction(\n state: FlowExecution,\n script: FlowScript,\n mandatoryGates: ReadonlySet<string> = new Set(),\n): FlowAction | null {\n // Terminal flow — never fight a completed/failed/cancelled run.\n if (state.status === \"complete\" || state.status === \"failed\" || state.status === \"cancelled\") {\n return null;\n }\n\n const dir = (id: string): FlowNodeDirective => script.nodes?.[id] ?? script.default ?? {};\n const nodes = Object.values(state.nodes);\n // A mandatory gate can never auto-complete — `auto` resolves to `approve`\n // regardless of autonomousMode so the host can drive it deterministically.\n const canAutoComplete = (id: string): boolean => state.autonomousMode && !mandatoryGates.has(id);\n\n // 1. Approved gate → complete.\n for (const n of nodes) {\n if (n.status === \"awaiting_approval\" && n.approval?.decision === \"approved\") {\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(dir(n.id), n) };\n }\n }\n\n // 2. Running node → per directive.\n for (const n of nodes) {\n if (n.status !== \"running\") continue;\n const d = dir(n.id);\n const onRun: OnRun = d.onRun ?? \"auto\";\n const resolved: OnRun =\n onRun === \"auto\" ? (canAutoComplete(n.id) ? \"complete\" : \"approve\") : onRun;\n\n if (resolved === \"complete\") {\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n if (resolved === \"approve\") {\n return { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n if (resolved === \"input\") {\n const lastInput = n.inputHistory[n.inputHistory.length - 1];\n if (lastInput && lastInput.response !== undefined) {\n // Input already provided — proceed as if `auto`.\n return canAutoComplete(n.id)\n ? { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) }\n : { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n return {\n op: \"request_input\",\n nodeId: n.id,\n prompt: d.input?.prompt ?? `Provide input for ${n.id}`,\n schema: JSON.stringify(d.input?.schema ?? { kind: \"text\" }),\n };\n }\n if (resolved === \"fail\") {\n const recoverable = d.recoverable ?? false;\n if (!recoverable) {\n // Terminal fail — the adapter marks node + flow `failed`, so the\n // terminal-status guard above stops any re-fire on later turns.\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Scripted failure for ${n.id}`,\n recoverable: false,\n };\n }\n // Recoverable fail — emit up to `failCount` times (counting the node's\n // own recorded recoverable errors), then proceed as `auto` so the node\n // is not stranded in a re-drive loop.\n const emitted = n.errorHistory.filter((e) => e.recoverable).length;\n const failCount = Math.max(1, d.failCount ?? 1);\n if (emitted < failCount) {\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Scripted recoverable failure for ${n.id}`,\n recoverable: true,\n };\n }\n return canAutoComplete(n.id)\n ? { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) }\n : { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n // `skip` while running is illegal; complete instead to avoid a deadlock.\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n\n // 3. Available node → terminally-fail (post-reject), skip, or start.\n for (const n of nodes) {\n if (n.status !== \"available\") continue;\n const d = dir(n.id);\n const lastApproval = n.approvalHistory[n.approvalHistory.length - 1];\n if (lastApproval?.decision === \"rejected\" && d.onReject === \"fail\") {\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Rejected and not recoverable: ${n.id}`,\n recoverable: false,\n };\n }\n if (d.onRun === \"skip\") {\n return { op: \"skip_node\", nodeId: n.id };\n }\n return { op: \"start_node\", nodeId: n.id };\n }\n\n // 4. Nothing actionable — awaiting_approval (no decision), awaiting_input\n // (no response), or fully drained. Yield.\n return null;\n}\n\n/**\n * Parse a `[test-flow]` sentinel body into a {@link FlowScript}. An empty body\n * yields the canonical (empty) script. Malformed JSON is a hard error so tests\n * fail loudly rather than silently running the wrong policy.\n */\nexport function parseFlowScript(body: string): FlowScript {\n const trimmed = body.trim();\n if (trimmed.length === 0) return {};\n const parsed: unknown = JSON.parse(trimmed);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"flow script must be a JSON object\");\n }\n return parsed as FlowScript;\n}\n","import type { DriverTarget } from \"@skaile/workspaces/plugin-registry\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport {\n type AgentConfig,\n AgentDriver,\n type AgentEvent,\n type BridgeCapabilityTool,\n type DriverInfo,\n} from \"../types.js\";\nimport {\n actionArgs,\n type FlowScript,\n decideFlowAction,\n isTurnEnding,\n parseFlowScript,\n} from \"./flow-script.js\";\n\n/**\n * Echo/mock driver for E2E testing in docker mode.\n *\n * Runs inside a real Docker container with real WebSocket transport and\n * session lifecycle, but generates deterministic keyword-triggered responses\n * instead of calling the Anthropic API. This lets E2E tests exercise the\n * full infrastructure (containers, WebSocket, session management, message\n * persistence) without needing real AI credentials.\n *\n * Keyword triggers match the MockAgentClient in\n * `platform/backend/libs/agent-gateway/src/mock-agent-client.ts` — the\n * same test messages (\"test toolcall\", \"test question\", etc.) produce\n * the same events.\n *\n * Enable by setting `SKAILE_AGENT_DRIVER=echo` in the container env,\n * or by passing `{ driver: 'echo' }` in the runner config.\n *\n * @docLink packages/bridge/drivers#echo-driver\n */\nexport class EchoDriver extends AgentDriver {\n readonly driverInfo: DriverInfo = {\n id: \"echo\",\n name: \"Echo (E2E mock)\",\n modelAgnostic: true,\n supportsInBandAbort: false,\n };\n\n private readonly log: Logger = getBridgeLogger(\"echo\");\n private running = false;\n private readonly config: AgentConfig;\n\n /**\n * Scripted-flow mode state (workspaces#396). Enabled by a `[test-flow]`\n * sentinel chat message; once on, orchestrator-prompt turns are driven\n * deterministically against `config.flowTestDriver`. `null` script ⇒ mode\n * off (default echo behaviour, unchanged).\n */\n private flowScript: FlowScript | null = null;\n\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Test surface: returns the tool list the LLM would see for this turn.\n * Composition: the registry hooks (Protocol v2) take precedence; legacy\n * `mcpServers` is not enumerated here (the echo driver never exposed MCP\n * tools to the LLM by name).\n */\n listCapabilityTools(): BridgeCapabilityTool[] {\n return this.config.capabilities?.composeTools() ?? [];\n }\n\n /**\n * Test surface: invoke a registered capability through the dispatch\n * helper. Mirrors what a real driver would do when the LLM produced a\n * tool_use for the given name — applies fire-and-forget, render emission,\n * and fallback text. Returns the structured dispatch result so tests can\n * assert immediate-vs-background resolution.\n */\n async invokeCapabilityForTest(\n name: string,\n input: unknown,\n ): Promise<{ result: unknown; background: boolean }> {\n const hooks = this.config.capabilities;\n if (!hooks) throw new Error(\"EchoDriver: no capability hooks configured\");\n const callId = `echo-cap-${Date.now()}`;\n const out = await dispatchCapability(hooks, callId, name, input, (err) =>\n this.log.warn(\"background capability handler failed\", {\n name,\n error: String(err),\n }),\n );\n return out;\n }\n\n async start(): Promise<void> {\n this.running = true;\n this.log.info(\"driver started\");\n }\n\n async prompt(message: string): Promise<void> {\n if (!this.running) return;\n const content = message.toLowerCase();\n this.log.info(\"received prompt\", { preview: message.slice(0, 80), length: message.length });\n\n // Small delay to simulate real agent processing\n await new Promise((resolve) => setTimeout(resolve, 200));\n\n // Scripted-flow test seam (workspaces#396) — a `[test-flow]` sentinel\n // arms deterministic flow driving for this session and (optionally)\n // carries a JSON script. Format: `[test-flow] {json}`; empty body ⇒\n // canonical policy. Must be handled before the flow-turn branch below.\n //\n // Detection is LINE-anchored, not message-anchored (workspaces#401): hosts\n // decorate user messages (e.g. a prepended `<SESSION_MEMBERS>` block and a\n // wake-restoration preamble), so the sentinel is rarely at the start of the\n // composed prompt. We match `[test-flow]` at the start of ANY line (only\n // leading whitespace allowed), which is decoration-independent yet still\n // impossible to arm from ordinary prose — a line must BEGIN with the exact\n // token. The optional JSON script must sit on that same line.\n const flowMatch = /^[ \\t]*\\[test-flow\\][ \\t]*(.*)$/m.exec(message);\n if (flowMatch) {\n let summary: string;\n try {\n this.flowScript = parseFlowScript(flowMatch[1] ?? \"\");\n summary = \"echo[test-flow]: scripted-flow mode armed\";\n } catch (err) {\n this.flowScript = null;\n summary = `echo[test-flow]: invalid script — ${err instanceof Error ? err.message : String(err)}`;\n this.emit(\"agent-event\", { type: \"error\", error: summary, fatal: false });\n }\n for (const event of textAndResult(summary)) this.emit(\"agent-event\", event);\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n // Scripted-flow turn — the runner reassembles the orchestrator prompt on\n // every flow turn; when scripted-flow mode is armed and a flow driver hook\n // is present, drive nodes deterministically instead of echoing text.\n if (this.flowScript && this.config.flowTestDriver && isFlowTurn(message)) {\n await this.runScriptedFlowTurn();\n return;\n }\n\n // Phase 7B test seam — explicit capability invocation keyword. Lets E2E\n // tests drive `dispatchCapability` from a chat prompt without a real LLM.\n // Format: `[test-cap:<name>] {json}`, LINE-anchored like `[test-flow]` above\n // because hosts decorate user messages. Both flags are load-bearing and are\n // pinned by tests: no `s` (dotAll swallows the host's closing tag into the\n // JSON body), and `[ \\t]` not `\\s` (`\\s` un-anchors the token from its line).\n const capMatch = /^[ \\t]*\\[test-cap:([\\w.\\-_]+)\\][ \\t]*(.*)$/m.exec(message);\n if (capMatch) {\n const name = capMatch[1] ?? \"\";\n const rawInput = (capMatch[2] ?? \"\").trim();\n let input: unknown = {};\n if (rawInput.length > 0) {\n try {\n input = JSON.parse(rawInput);\n } catch (err) {\n this.log.warn(\"test-cap input was not valid JSON; defaulting to {}\", {\n error: String(err),\n preview: rawInput.slice(0, 80),\n });\n }\n }\n const events = await this.runCapabilityKeyword(name, input);\n for (const event of events) {\n this.emit(\"agent-event\", event);\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n const events = buildEchoEvents(content, message);\n for (const event of events) {\n this.emit(\"agent-event\", event);\n // Small gap between events to let the transport process each one\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n // Signal turn completion — the runner waits for this before accepting\n // the next prompt. Without it, the runner stays stuck after the first message.\n this.emit(\"agent-event\", { type: \"agent_end\" });\n }\n\n /**\n * Phase 7B helper — drive a single capability through the dispatcher and\n * surface the structured outcome as a result event the LLM-side test code\n * can assert against. Used exclusively by the `[test-cap:<name>]` prompt\n * keyword above; never wired into normal chat flow.\n */\n private async runCapabilityKeyword(name: string, input: unknown): Promise<AgentEvent[]> {\n const events: AgentEvent[] = [];\n if (!this.config.capabilities) {\n return textAndResult(`echo[test-cap]: no capability hooks configured (skipping ${name})`);\n }\n try {\n const out = await this.invokeCapabilityForTest(name, input);\n const summary = `echo[test-cap]: invoked ${name} input=${safeStringify(input)} background=${String(out.background)} result=${safeStringify(out.result)}`;\n events.push(...textAndResult(summary));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n events.push({\n type: \"error\",\n error: `echo[test-cap]: ${name} failed: ${msg}`,\n fatal: false,\n });\n events.push(...textAndResult(`echo[test-cap]: ${name} errored (${msg})`));\n }\n return events;\n }\n\n /**\n * Scripted-flow turn (workspaces#396). Reads the live flow state via the\n * runner-injected `flowTestDriver` hook and executes the scripted next\n * action(s) until the policy yields or emits a turn-ending action. Each\n * mutation fires the adapter's `onChange` (→ host `state_changed`) and, when\n * the runner wires the stimulus bus, queues the follow-up turn — so the\n * driver advances one step at a time exactly like a real LLM orchestrator.\n */\n private async runScriptedFlowTurn(): Promise<void> {\n const hook = this.config.flowTestDriver;\n const script = this.flowScript;\n if (!hook || !script) {\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n const executed: string[] = [];\n // Hard cap — the policy is monotonic, but never let a bug spin forever.\n const MAX_STEPS = 200;\n for (let i = 0; i < MAX_STEPS; i++) {\n const state = hook.getState();\n if (!state) break;\n const mandatoryGates = new Set(hook.mandatoryGates?.() ?? []);\n const action = decideFlowAction(state, script, mandatoryGates);\n if (!action) break;\n\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: action.op,\n tool: { name: action.op },\n input: action.nodeId,\n });\n try {\n await hook.execute(action.op, actionArgs(action));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.log.warn(\"scripted flow op failed\", {\n op: action.op,\n nodeId: action.nodeId,\n error: msg,\n });\n this.emit(\"agent-event\", {\n type: \"error\",\n error: `echo[test-flow]: ${action.op}(${action.nodeId}) failed: ${msg}`,\n fatal: false,\n });\n break;\n }\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: action.op });\n executed.push(`${action.op}(${action.nodeId})`);\n if (isTurnEnding(action)) break;\n }\n\n const summary =\n executed.length > 0\n ? `echo[test-flow]: ${executed.join(\" → \")}`\n : \"echo[test-flow]: no action (yielding to host)\";\n for (const event of textAndResult(summary)) this.emit(\"agent-event\", event);\n this.emit(\"agent-event\", { type: \"agent_end\" });\n }\n\n async abort(): Promise<void> {\n this.log.info(\"abort requested\");\n }\n\n kill(): void {\n this.running = false;\n this.log.info(\"killed\");\n }\n\n async resetSession(): Promise<void> {\n this.log.info(\"session reset\");\n }\n\n get isRunning(): boolean {\n return this.running;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Echo response generation — mirrors MockAgentClient.buildMockEvents\n// ---------------------------------------------------------------------------\n\n/**\n * A flow turn is recognised by the orchestrator prompt's stable header\n * (`buildOrchestratorPrompt` in the flow connector). Detection is header-only —\n * the driver reads live state through the injected hook, never by parsing the\n * prompt body.\n */\nfunction isFlowTurn(message: string): boolean {\n return message.startsWith(\"# Flow Execution Context\");\n}\n\nfunction safeStringify(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\nfunction textAndResult(summary: string): AgentEvent[] {\n return [\n {\n type: \"message_start\",\n message: { role: \"assistant\", content: summary },\n },\n {\n type: \"message_end\",\n message: { role: \"assistant\", content: summary },\n },\n {\n type: \"result\",\n subtype: \"success\",\n summary,\n costUsd: 0,\n },\n ];\n}\n\nfunction buildEchoEvents(content: string, originalPrompt: string): AgentEvent[] {\n const events: AgentEvent[] = [];\n\n if (content.includes(\"test all\")) {\n events.push(\n { type: \"tool_call\", name: \"Read\", tool: { name: \"Read\" }, input: \"prisma/schema.prisma\" },\n { type: \"tool_execution_end\", toolName: \"Read\" },\n {\n type: \"tool_call\",\n name: \"Write\",\n tool: { name: \"Write\" },\n input: \"src/modules/sprint/sprint.service.ts\",\n },\n { type: \"tool_execution_end\", toolName: \"Write\" },\n );\n events.push(\n ...textAndResult(\n \"All operations completed successfully. Created sprint service, updated schema, started dev server, and ran E2E tests.\",\n ),\n );\n } else if (content.includes(\"test toolcall\")) {\n events.push(\n {\n type: \"tool_call\",\n name: \"Read\",\n tool: { name: \"Read\" },\n input: \"platform/prisma/schema.prisma\",\n },\n { type: \"tool_execution_end\", toolName: \"Read\" },\n );\n events.push(\n ...textAndResult(\n \"I've read the schema and found 42 models. The data model looks well-structured.\",\n ),\n );\n } else if (content.includes(\"test question\")) {\n // Emit a message that asks the user a question (the runner normalizer\n // converts this to a `question` AgentEvent for the transport layer)\n events.push(\n ...textAndResult(\n \"The blueprint calls for a relational database. Which engine should I target? \" +\n \"This will affect the Prisma provider, Docker Compose setup, and the connection string.\\n\\n\" +\n \"Options: PostgreSQL, MySQL, SQLite\",\n ),\n );\n } else if (content.includes(\"test error\")) {\n events.push({\n type: \"error\",\n error:\n \"AI provider returned HTTP 429 — rate limit exceeded. The request will be retried automatically in 35 seconds.\",\n fatal: false,\n });\n } else if (content.includes(\"test fatal\")) {\n events.push({\n type: \"error\",\n error:\n \"Session agent was killed by the container runtime (OOM — memory limit 2 GB exceeded). The session cannot continue.\",\n fatal: true,\n });\n } else {\n // Default echo response\n const summary =\n `I received your message: \"${originalPrompt}\". I'm the Skaile AI assistant running in echo mode. ` +\n `This is a deterministic mock response for E2E testing.`;\n events.push(...textAndResult(summary));\n }\n\n return events;\n}\n\n/**\n * `DriverTarget` wrapper for the echo driver. Registered into the plugin\n * registry by `registerBuiltinDrivers()`.\n */\nexport const echoDriverTarget: DriverTarget<AgentConfig> = {\n id: \"echo\",\n displayName: BUILTIN_DRIVER_CATALOG.echo?.name ?? \"Echo (E2E mock)\",\n apiVersion: 1,\n // Drivers take AgentConfig; passthrough — full schema validation is out of scope.\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new EchoDriver(config),\n listModels: async (apiKeys) =>\n new EchoDriver({ cwd: process.cwd(), sessionId: \"model-list\", apiKeys }).listModels(),\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../bridge/src/drivers/flow-script.ts","../../../bridge/src/drivers/echo.ts"],"names":["events"],"mappings":"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","file":"echo.js","sourcesContent":["/**\n * Scripted-flow decision logic for the echo driver.\n *\n * Pure, deterministic policy that maps a live {@link FlowExecution} snapshot\n * (plus an optional per-node script) to the single next flow-adapter mutation\n * the driver should emit this iteration. The echo driver calls this in a loop\n * per turn (see `echo.ts`), executing each returned action against the\n * runner-injected {@link FlowTestDriverHook} until it yields (`null`) or emits\n * a turn-ending action.\n *\n * The policy mirrors what a real LLM orchestrator would do, but without an\n * LLM: it reacts to state each turn, so a host can drive a flow to `complete`,\n * park it at an approval/input gate, and exercise the reject/recover path\n * simply by applying host mutations (`applyApproval`, `applyInput`, …) between\n * turns. No new protocol, no flow-contract change — it only calls the existing\n * FlowAdapter agent-tool operations.\n *\n * @docLink packages/bridge/drivers#scripted-flow\n * @since 3.6.0\n */\n\nimport type { FlowExecution, NodeExecution } from \"@skaile/workspaces/types\";\n\n/**\n * What the scripted driver should do when a node reaches its decision point.\n *\n * - `auto` (default): follow the flow's `autonomousMode` — `complete_node`\n * when autonomous, else `request_approval`. A mandatory approval gate always\n * resolves to `request_approval`, even when autonomous (it cannot be skipped).\n * - `complete`: always `complete_node` (autonomous-style, even if the flow's\n * autonomousMode is false — the adapter allows it only when autonomous, so\n * use with autonomous flows).\n * - `approve`: always `request_approval` (park at an approval gate).\n * - `input`: `request_input` once; after the host applies input, fall back to\n * `auto` behaviour.\n * - `skip`: `skip_node` (optional nodes only).\n * - `fail`: `fail_node`. With `recoverable: false` (default) this is terminal.\n * With `recoverable: true` the node returns to `available`; the driver\n * re-emits the recoverable failure `failCount` times (default 1) and then\n * proceeds as `auto` — it never deadlocks on a recoverable fail.\n */\nexport type OnRun = \"auto\" | \"complete\" | \"approve\" | \"input\" | \"skip\" | \"fail\";\n\n/**\n * What to do when a node returns to `available` after a rejection.\n *\n * - `retry` (default): re-drive it — `start_node` again, then its `onRun`.\n * - `fail`: `fail_node(recoverable: false)` — exercises the terminal path.\n */\nexport type OnReject = \"retry\" | \"fail\";\n\n/** Per-node scripting directive. All fields optional. */\nexport interface FlowNodeDirective {\n onRun?: OnRun;\n onReject?: OnReject;\n /** For `onRun: \"input\"` — the input request shown to the host. */\n input?: { prompt?: string; schema?: unknown };\n /** For `onRun: \"fail\"` — whether the failure is recoverable. Default false. */\n recoverable?: boolean;\n /**\n * For `onRun: \"fail\"` with `recoverable: true` — how many recoverable\n * failures to emit before the node proceeds as `auto`. Default 1. Counted\n * from the node's own `errorHistory`, so the policy stays a pure function of\n * state (no driver-instance bookkeeping) and never deadlocks.\n */\n failCount?: number;\n /** Summary text used for `complete_node` / `request_approval` / failures. */\n summary?: string;\n}\n\n/**\n * A scripted-flow program. Empty (`{}`) means \"canonical policy\": start each\n * available node, then complete (autonomous) or request approval (interactive)\n * — enough to drive the autonomous-complete, approval-gate, and reject/recover\n * scenarios with no per-node scripting at all.\n */\nexport interface FlowScript {\n /** Per-node overrides, keyed by node id. */\n nodes?: Record<string, FlowNodeDirective>;\n /** Fallback directive for any node without its own entry. */\n default?: FlowNodeDirective;\n}\n\n/** A single flow-adapter mutation the driver will execute. */\nexport type FlowAction =\n | { op: \"start_node\"; nodeId: string }\n | { op: \"complete_node\"; nodeId: string; summary: string }\n | { op: \"request_approval\"; nodeId: string; summary: string }\n | { op: \"request_input\"; nodeId: string; prompt: string; schema: string }\n | { op: \"skip_node\"; nodeId: string }\n | { op: \"fail_node\"; nodeId: string; message: string; recoverable: boolean };\n\n/** Ops that end the agent turn (the runner yields until the host acts). */\nconst TURN_ENDING: ReadonlySet<FlowAction[\"op\"]> = new Set([\n \"request_approval\",\n \"request_input\",\n \"fail_node\",\n]);\n\n/** Whether an action ends the turn (driver stops looping after emitting it). */\nexport function isTurnEnding(action: FlowAction): boolean {\n return TURN_ENDING.has(action.op);\n}\n\n/** Map a {@link FlowAction} to the `executeOp` argument bag the adapter expects. */\nexport function actionArgs(action: FlowAction): Record<string, unknown> {\n switch (action.op) {\n case \"start_node\":\n case \"skip_node\":\n return { nodeId: action.nodeId };\n case \"complete_node\":\n return { nodeId: action.nodeId, summary: action.summary };\n case \"request_approval\":\n return { nodeId: action.nodeId, summary: action.summary };\n case \"request_input\":\n return { nodeId: action.nodeId, prompt: action.prompt, schema: action.schema };\n case \"fail_node\":\n return {\n nodeId: action.nodeId,\n message: action.message,\n recoverable: String(action.recoverable),\n };\n }\n}\n\nfunction summaryFor(d: FlowNodeDirective, n: NodeExecution): string {\n return d.summary ?? `Scripted output for ${n.id}`;\n}\n\n/**\n * Decide the single next flow action for the current state, or `null` to yield\n * (nothing to do this iteration — wait for a host mutation).\n *\n * Priority order: resolve approved gates → advance running nodes → start (or\n * skip / terminally-fail) available nodes. Terminal flow states and gates with\n * no decision / input yet yield.\n *\n * Pure — the fail bookkeeping (how many recoverable failures a node has already\n * emitted) is read from the node's own `errorHistory`, so no external counter is\n * needed and a recoverable `fail` directive can never deadlock.\n */\nexport function decideFlowAction(\n state: FlowExecution,\n script: FlowScript,\n mandatoryGates: ReadonlySet<string> = new Set(),\n): FlowAction | null {\n // Terminal flow — never fight a completed/failed/cancelled run.\n if (state.status === \"complete\" || state.status === \"failed\" || state.status === \"cancelled\") {\n return null;\n }\n\n const dir = (id: string): FlowNodeDirective => script.nodes?.[id] ?? script.default ?? {};\n const nodes = Object.values(state.nodes);\n // A mandatory gate can never auto-complete — `auto` resolves to `approve`\n // regardless of autonomousMode so the host can drive it deterministically.\n const canAutoComplete = (id: string): boolean => state.autonomousMode && !mandatoryGates.has(id);\n\n // 1. Approved gate → complete.\n for (const n of nodes) {\n if (n.status === \"awaiting_approval\" && n.approval?.decision === \"approved\") {\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(dir(n.id), n) };\n }\n }\n\n // 2. Running node → per directive.\n for (const n of nodes) {\n if (n.status !== \"running\") continue;\n const d = dir(n.id);\n const onRun: OnRun = d.onRun ?? \"auto\";\n const resolved: OnRun =\n onRun === \"auto\" ? (canAutoComplete(n.id) ? \"complete\" : \"approve\") : onRun;\n\n if (resolved === \"complete\") {\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n if (resolved === \"approve\") {\n return { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n if (resolved === \"input\") {\n const lastInput = n.inputHistory[n.inputHistory.length - 1];\n if (lastInput && lastInput.response !== undefined) {\n // Input already provided — proceed as if `auto`.\n return canAutoComplete(n.id)\n ? { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) }\n : { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n return {\n op: \"request_input\",\n nodeId: n.id,\n prompt: d.input?.prompt ?? `Provide input for ${n.id}`,\n schema: JSON.stringify(d.input?.schema ?? { kind: \"text\" }),\n };\n }\n if (resolved === \"fail\") {\n const recoverable = d.recoverable ?? false;\n if (!recoverable) {\n // Terminal fail — the adapter marks node + flow `failed`, so the\n // terminal-status guard above stops any re-fire on later turns.\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Scripted failure for ${n.id}`,\n recoverable: false,\n };\n }\n // Recoverable fail — emit up to `failCount` times (counting the node's\n // own recorded recoverable errors), then proceed as `auto` so the node\n // is not stranded in a re-drive loop.\n const emitted = n.errorHistory.filter((e) => e.recoverable).length;\n const failCount = Math.max(1, d.failCount ?? 1);\n if (emitted < failCount) {\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Scripted recoverable failure for ${n.id}`,\n recoverable: true,\n };\n }\n return canAutoComplete(n.id)\n ? { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) }\n : { op: \"request_approval\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n // `skip` while running is illegal; complete instead to avoid a deadlock.\n return { op: \"complete_node\", nodeId: n.id, summary: summaryFor(d, n) };\n }\n\n // 3. Available node → terminally-fail (post-reject), skip, or start.\n for (const n of nodes) {\n if (n.status !== \"available\") continue;\n const d = dir(n.id);\n const lastApproval = n.approvalHistory[n.approvalHistory.length - 1];\n if (lastApproval?.decision === \"rejected\" && d.onReject === \"fail\") {\n return {\n op: \"fail_node\",\n nodeId: n.id,\n message: d.summary ?? `Rejected and not recoverable: ${n.id}`,\n recoverable: false,\n };\n }\n if (d.onRun === \"skip\") {\n return { op: \"skip_node\", nodeId: n.id };\n }\n return { op: \"start_node\", nodeId: n.id };\n }\n\n // 4. Nothing actionable — awaiting_approval (no decision), awaiting_input\n // (no response), or fully drained. Yield.\n return null;\n}\n\n/**\n * Parse a `[test-flow]` sentinel body into a {@link FlowScript}. An empty body\n * yields the canonical (empty) script. Malformed JSON is a hard error so tests\n * fail loudly rather than silently running the wrong policy.\n */\nexport function parseFlowScript(body: string): FlowScript {\n const trimmed = body.trim();\n if (trimmed.length === 0) return {};\n const parsed: unknown = JSON.parse(trimmed);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"flow script must be a JSON object\");\n }\n return parsed as FlowScript;\n}\n","import type { DriverTarget } from \"@skaile/workspaces/plugin-registry\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { registryDriverConfig } from \"../provider-registry-derive.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport {\n type AgentConfig,\n AgentDriver,\n type AgentEvent,\n type BridgeCapabilityTool,\n type DriverInfo,\n} from \"../types.js\";\nimport {\n actionArgs,\n type FlowScript,\n decideFlowAction,\n isTurnEnding,\n parseFlowScript,\n} from \"./flow-script.js\";\n\n/**\n * Echo/mock driver for E2E testing in docker mode.\n *\n * Runs inside a real Docker container with real WebSocket transport and\n * session lifecycle, but generates deterministic keyword-triggered responses\n * instead of calling the Anthropic API. This lets E2E tests exercise the\n * full infrastructure (containers, WebSocket, session management, message\n * persistence) without needing real AI credentials.\n *\n * Keyword triggers match the MockAgentClient in\n * `platform/backend/libs/agent-gateway/src/mock-agent-client.ts` — the\n * same test messages (\"test toolcall\", \"test question\", etc.) produce\n * the same events.\n *\n * Enable by setting `SKAILE_AGENT_DRIVER=echo` in the container env,\n * or by passing `{ driver: 'echo' }` in the runner config.\n *\n * @docLink packages/bridge/drivers#echo-driver\n */\nexport class EchoDriver extends AgentDriver {\n readonly driverInfo: DriverInfo = {\n id: \"echo\",\n name: \"Echo (E2E mock)\",\n modelAgnostic: true,\n supportsInBandAbort: false,\n };\n\n private readonly log: Logger = getBridgeLogger(\"echo\");\n private running = false;\n private readonly config: AgentConfig;\n\n /**\n * Scripted-flow mode state (workspaces#396). Enabled by a `[test-flow]`\n * sentinel chat message; once on, orchestrator-prompt turns are driven\n * deterministically against `config.flowTestDriver`. `null` script ⇒ mode\n * off (default echo behaviour, unchanged).\n */\n private flowScript: FlowScript | null = null;\n\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Test surface: returns the tool list the LLM would see for this turn.\n * Composition: the registry hooks (Protocol v2) take precedence; legacy\n * `mcpServers` is not enumerated here (the echo driver never exposed MCP\n * tools to the LLM by name).\n */\n listCapabilityTools(): BridgeCapabilityTool[] {\n return this.config.capabilities?.composeTools() ?? [];\n }\n\n /**\n * Test surface: invoke a registered capability through the dispatch\n * helper. Mirrors what a real driver would do when the LLM produced a\n * tool_use for the given name — applies fire-and-forget, render emission,\n * and fallback text. Returns the structured dispatch result so tests can\n * assert immediate-vs-background resolution.\n */\n async invokeCapabilityForTest(\n name: string,\n input: unknown,\n ): Promise<{ result: unknown; background: boolean }> {\n const hooks = this.config.capabilities;\n if (!hooks) throw new Error(\"EchoDriver: no capability hooks configured\");\n const callId = `echo-cap-${Date.now()}`;\n const out = await dispatchCapability(hooks, callId, name, input, (err) =>\n this.log.warn(\"background capability handler failed\", {\n name,\n error: String(err),\n }),\n );\n return out;\n }\n\n async start(): Promise<void> {\n this.running = true;\n this.log.info(\"driver started\");\n }\n\n async prompt(message: string): Promise<void> {\n if (!this.running) return;\n const content = message.toLowerCase();\n this.log.info(\"received prompt\", { preview: message.slice(0, 80), length: message.length });\n\n // Small delay to simulate real agent processing\n await new Promise((resolve) => setTimeout(resolve, 200));\n\n // Scripted-flow test seam (workspaces#396) — a `[test-flow]` sentinel\n // arms deterministic flow driving for this session and (optionally)\n // carries a JSON script. Format: `[test-flow] {json}`; empty body ⇒\n // canonical policy. Must be handled before the flow-turn branch below.\n //\n // Detection is LINE-anchored, not message-anchored (workspaces#401): hosts\n // decorate user messages (e.g. a prepended `<SESSION_MEMBERS>` block and a\n // wake-restoration preamble), so the sentinel is rarely at the start of the\n // composed prompt. We match `[test-flow]` at the start of ANY line (only\n // leading whitespace allowed), which is decoration-independent yet still\n // impossible to arm from ordinary prose — a line must BEGIN with the exact\n // token. The optional JSON script must sit on that same line.\n const flowMatch = /^[ \\t]*\\[test-flow\\][ \\t]*(.*)$/m.exec(message);\n if (flowMatch) {\n let summary: string;\n try {\n this.flowScript = parseFlowScript(flowMatch[1] ?? \"\");\n summary = \"echo[test-flow]: scripted-flow mode armed\";\n } catch (err) {\n this.flowScript = null;\n summary = `echo[test-flow]: invalid script — ${err instanceof Error ? err.message : String(err)}`;\n this.emit(\"agent-event\", { type: \"error\", error: summary, fatal: false });\n }\n for (const event of textAndResult(summary)) this.emit(\"agent-event\", event);\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n // Scripted-flow turn — the runner reassembles the orchestrator prompt on\n // every flow turn; when scripted-flow mode is armed and a flow driver hook\n // is present, drive nodes deterministically instead of echoing text.\n if (this.flowScript && this.config.flowTestDriver && isFlowTurn(message)) {\n await this.runScriptedFlowTurn();\n return;\n }\n\n // Phase 7B test seam — explicit capability invocation keyword. Lets E2E\n // tests drive `dispatchCapability` from a chat prompt without a real LLM.\n // Format: `[test-cap:<name>] {json}`, LINE-anchored like `[test-flow]` above\n // because hosts decorate user messages. Both flags are load-bearing and are\n // pinned by tests: no `s` (dotAll swallows the host's closing tag into the\n // JSON body), and `[ \\t]` not `\\s` (`\\s` un-anchors the token from its line).\n const capMatch = /^[ \\t]*\\[test-cap:([\\w.\\-_]+)\\][ \\t]*(.*)$/m.exec(message);\n if (capMatch) {\n const name = capMatch[1] ?? \"\";\n const rawInput = (capMatch[2] ?? \"\").trim();\n let input: unknown = {};\n if (rawInput.length > 0) {\n try {\n input = JSON.parse(rawInput);\n } catch (err) {\n this.log.warn(\"test-cap input was not valid JSON; defaulting to {}\", {\n error: String(err),\n preview: rawInput.slice(0, 80),\n });\n }\n }\n const events = await this.runCapabilityKeyword(name, input);\n for (const event of events) {\n this.emit(\"agent-event\", event);\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n const events = buildEchoEvents(content, message);\n for (const event of events) {\n this.emit(\"agent-event\", event);\n // Small gap between events to let the transport process each one\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n // Signal turn completion — the runner waits for this before accepting\n // the next prompt. Without it, the runner stays stuck after the first message.\n this.emit(\"agent-event\", { type: \"agent_end\" });\n }\n\n /**\n * Phase 7B helper — drive a single capability through the dispatcher and\n * surface the structured outcome as a result event the LLM-side test code\n * can assert against. Used exclusively by the `[test-cap:<name>]` prompt\n * keyword above; never wired into normal chat flow.\n */\n private async runCapabilityKeyword(name: string, input: unknown): Promise<AgentEvent[]> {\n const events: AgentEvent[] = [];\n if (!this.config.capabilities) {\n return textAndResult(`echo[test-cap]: no capability hooks configured (skipping ${name})`);\n }\n try {\n const out = await this.invokeCapabilityForTest(name, input);\n const summary = `echo[test-cap]: invoked ${name} input=${safeStringify(input)} background=${String(out.background)} result=${safeStringify(out.result)}`;\n events.push(...textAndResult(summary));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n events.push({\n type: \"error\",\n error: `echo[test-cap]: ${name} failed: ${msg}`,\n fatal: false,\n });\n events.push(...textAndResult(`echo[test-cap]: ${name} errored (${msg})`));\n }\n return events;\n }\n\n /**\n * Scripted-flow turn (workspaces#396). Reads the live flow state via the\n * runner-injected `flowTestDriver` hook and executes the scripted next\n * action(s) until the policy yields or emits a turn-ending action. Each\n * mutation fires the adapter's `onChange` (→ host `state_changed`) and, when\n * the runner wires the stimulus bus, queues the follow-up turn — so the\n * driver advances one step at a time exactly like a real LLM orchestrator.\n */\n private async runScriptedFlowTurn(): Promise<void> {\n const hook = this.config.flowTestDriver;\n const script = this.flowScript;\n if (!hook || !script) {\n this.emit(\"agent-event\", { type: \"agent_end\" });\n return;\n }\n\n const executed: string[] = [];\n // Hard cap — the policy is monotonic, but never let a bug spin forever.\n const MAX_STEPS = 200;\n for (let i = 0; i < MAX_STEPS; i++) {\n const state = hook.getState();\n if (!state) break;\n const mandatoryGates = new Set(hook.mandatoryGates?.() ?? []);\n const action = decideFlowAction(state, script, mandatoryGates);\n if (!action) break;\n\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: action.op,\n tool: { name: action.op },\n input: action.nodeId,\n });\n try {\n await hook.execute(action.op, actionArgs(action));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.log.warn(\"scripted flow op failed\", {\n op: action.op,\n nodeId: action.nodeId,\n error: msg,\n });\n this.emit(\"agent-event\", {\n type: \"error\",\n error: `echo[test-flow]: ${action.op}(${action.nodeId}) failed: ${msg}`,\n fatal: false,\n });\n break;\n }\n this.emit(\"agent-event\", { type: \"tool_execution_end\", toolName: action.op });\n executed.push(`${action.op}(${action.nodeId})`);\n if (isTurnEnding(action)) break;\n }\n\n const summary =\n executed.length > 0\n ? `echo[test-flow]: ${executed.join(\" → \")}`\n : \"echo[test-flow]: no action (yielding to host)\";\n for (const event of textAndResult(summary)) this.emit(\"agent-event\", event);\n this.emit(\"agent-event\", { type: \"agent_end\" });\n }\n\n async abort(): Promise<void> {\n this.log.info(\"abort requested\");\n }\n\n kill(): void {\n this.running = false;\n this.log.info(\"killed\");\n }\n\n async resetSession(): Promise<void> {\n this.log.info(\"session reset\");\n }\n\n get isRunning(): boolean {\n return this.running;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Echo response generation — mirrors MockAgentClient.buildMockEvents\n// ---------------------------------------------------------------------------\n\n/**\n * A flow turn is recognised by the orchestrator prompt's stable header\n * (`buildOrchestratorPrompt` in the flow connector). Detection is header-only —\n * the driver reads live state through the injected hook, never by parsing the\n * prompt body.\n */\nfunction isFlowTurn(message: string): boolean {\n return message.startsWith(\"# Flow Execution Context\");\n}\n\nfunction safeStringify(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\nfunction textAndResult(summary: string): AgentEvent[] {\n return [\n {\n type: \"message_start\",\n message: { role: \"assistant\", content: summary },\n },\n {\n type: \"message_end\",\n message: { role: \"assistant\", content: summary },\n },\n {\n type: \"result\",\n subtype: \"success\",\n summary,\n costUsd: 0,\n },\n ];\n}\n\nfunction buildEchoEvents(content: string, originalPrompt: string): AgentEvent[] {\n const events: AgentEvent[] = [];\n\n if (content.includes(\"test all\")) {\n events.push(\n { type: \"tool_call\", name: \"Read\", tool: { name: \"Read\" }, input: \"prisma/schema.prisma\" },\n { type: \"tool_execution_end\", toolName: \"Read\" },\n {\n type: \"tool_call\",\n name: \"Write\",\n tool: { name: \"Write\" },\n input: \"src/modules/sprint/sprint.service.ts\",\n },\n { type: \"tool_execution_end\", toolName: \"Write\" },\n );\n events.push(\n ...textAndResult(\n \"All operations completed successfully. Created sprint service, updated schema, started dev server, and ran E2E tests.\",\n ),\n );\n } else if (content.includes(\"test toolcall\")) {\n events.push(\n {\n type: \"tool_call\",\n name: \"Read\",\n tool: { name: \"Read\" },\n input: \"platform/prisma/schema.prisma\",\n },\n { type: \"tool_execution_end\", toolName: \"Read\" },\n );\n events.push(\n ...textAndResult(\n \"I've read the schema and found 42 models. The data model looks well-structured.\",\n ),\n );\n } else if (content.includes(\"test question\")) {\n // Emit a message that asks the user a question (the runner normalizer\n // converts this to a `question` AgentEvent for the transport layer)\n events.push(\n ...textAndResult(\n \"The blueprint calls for a relational database. Which engine should I target? \" +\n \"This will affect the Prisma provider, Docker Compose setup, and the connection string.\\n\\n\" +\n \"Options: PostgreSQL, MySQL, SQLite\",\n ),\n );\n } else if (content.includes(\"test error\")) {\n events.push({\n type: \"error\",\n error:\n \"AI provider returned HTTP 429 — rate limit exceeded. The request will be retried automatically in 35 seconds.\",\n fatal: false,\n });\n } else if (content.includes(\"test fatal\")) {\n events.push({\n type: \"error\",\n error:\n \"Session agent was killed by the container runtime (OOM — memory limit 2 GB exceeded). The session cannot continue.\",\n fatal: true,\n });\n } else {\n // Default echo response\n const summary =\n `I received your message: \"${originalPrompt}\". I'm the Skaile AI assistant running in echo mode. ` +\n `This is a deterministic mock response for E2E testing.`;\n events.push(...textAndResult(summary));\n }\n\n return events;\n}\n\n/**\n * `DriverTarget` wrapper for the echo driver. Registered into the plugin\n * registry by `registerBuiltinDrivers()`.\n */\nexport const echoDriverTarget: DriverTarget<AgentConfig> = {\n id: \"echo\",\n displayName: BUILTIN_DRIVER_CATALOG.echo?.name ?? \"Echo (E2E mock)\",\n apiVersion: 1,\n // Drivers take AgentConfig; passthrough — full schema validation is out of scope.\n configSchema: z.custom<AgentConfig>(() => true),\n create: async (config, _ctx) => new EchoDriver(config),\n listModels: async (registry, options) =>\n new EchoDriver({\n cwd: process.cwd(),\n sessionId: \"model-list\",\n ...registryDriverConfig(registry, options),\n }).listModels(),\n};\n"]}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
export { GeminiDriver, GeminiFamilyDriver, geminiDriverTarget } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
3
|
-
import '../../chunk-
|
|
1
|
+
export { GeminiDriver, GeminiFamilyDriver, geminiDriverTarget } from '../../chunk-K3YR33F6.js';
|
|
2
|
+
import '../../chunk-LN2BQVRB.js';
|
|
3
|
+
import '../../chunk-3ZTQY276.js';
|
|
4
4
|
import '../../chunk-GAH4YRCI.js';
|
|
5
|
-
import '../../chunk-
|
|
5
|
+
import '../../chunk-SG4D2UOK.js';
|
|
6
6
|
import '../../chunk-6E6PKKAD.js';
|
|
7
7
|
import '../../chunk-FTG7CRFD.js';
|
|
8
|
+
import '../../chunk-KSIRR5PL.js';
|
|
9
|
+
import '../../chunk-ILG4BXYE.js';
|
|
8
10
|
import '../../chunk-W4IPN3DD.js';
|
|
11
|
+
import '../../chunk-N7B3LZ7V.js';
|
|
9
12
|
import '../../chunk-NSBPE2FW.js';
|
|
10
13
|
//# sourceMappingURL=gemini.js.map
|
|
11
14
|
//# sourceMappingURL=gemini.js.map
|