ryco-cli 0.1.14 → 0.1.15
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/dist/{AcpNativeLogging-vLtnq5f1.cjs → AcpNativeLogging-OhEq3XNp.cjs} +1 -1
- package/dist/{AcpNativeLogging-D3fe64a6.mjs → AcpNativeLogging-qZgtIa5K.mjs} +2 -2
- package/dist/{AzureDevOpsSourceControlProvider-WNUDtsur.mjs → AzureDevOpsSourceControlProvider-B0YsaJyI.mjs} +3 -3
- package/dist/{AzureDevOpsSourceControlProvider-BtezW57t.cjs → AzureDevOpsSourceControlProvider-Dyu8KQ_S.cjs} +2 -2
- package/dist/{BitbucketSourceControlProvider-BWzNM0jW.cjs → BitbucketSourceControlProvider-3VHGKSl1.cjs} +2 -2
- package/dist/{BitbucketSourceControlProvider-tbbUFKz3.mjs → BitbucketSourceControlProvider-B8IPx2Ad.mjs} +3 -3
- package/dist/{ClaudeDriver-BTvdJvam.cjs → ClaudeDriver-CBCy0_WX.cjs} +8 -6
- package/dist/{ClaudeDriver-CG5ngU5z.mjs → ClaudeDriver-DsW8yDj9.mjs} +9 -7
- package/dist/{CodexDriver-CFxwJNXx.cjs → CodexDriver-3TZPgrGk.cjs} +3 -3
- package/dist/{CodexDriver-49o7TA-C.mjs → CodexDriver-DLwPz5sk.mjs} +4 -4
- package/dist/{CodexTextGeneration-C0t4xcPO.mjs → CodexTextGeneration-D1vV8grr.mjs} +2 -2
- package/dist/{CodexTextGeneration-CedcXf9a.cjs → CodexTextGeneration-DLHSW4Mz.cjs} +1 -1
- package/dist/{CopilotDriver-B8J_ovCX.cjs → CopilotDriver-C7a8IhyK.cjs} +3 -3
- package/dist/{CopilotDriver-Cu1B1skB.mjs → CopilotDriver-DXvGBv-s.mjs} +4 -4
- package/dist/{CursorDriver-P_A8uQki.mjs → CursorDriver-CeB_vMKJ.mjs} +4 -4
- package/dist/{CursorDriver-zlKHPy1_.cjs → CursorDriver-uNsDetA3.cjs} +3 -3
- package/dist/{ForgejoSourceControlProvider-szJ-dvsD.cjs → ForgejoSourceControlProvider-CJLksvL_.cjs} +2 -2
- package/dist/{ForgejoSourceControlProvider-DLhJZtq9.mjs → ForgejoSourceControlProvider-Ds0rU_PN.mjs} +3 -3
- package/dist/{GitHubSourceControlProvider-D5MQQPCJ.mjs → GitHubSourceControlProvider-C7CJAslU.mjs} +3 -3
- package/dist/{GitHubSourceControlProvider-3ofb6HsF.cjs → GitHubSourceControlProvider-CrYNFu8S.cjs} +2 -2
- package/dist/{GitLabSourceControlProvider-DkupZH5G.cjs → GitLabSourceControlProvider-jbX5M34A.cjs} +2 -2
- package/dist/{GitLabSourceControlProvider-DLkxeob5.mjs → GitLabSourceControlProvider-u-Y-e8PV.mjs} +3 -3
- package/dist/{GrokDriver-CTUNclwp.cjs → GrokDriver-BJ00ZiYg.cjs} +3 -3
- package/dist/{GrokDriver-D8KoMY76.mjs → GrokDriver-CFgjwnvE.mjs} +4 -4
- package/dist/{OpenCodeDriver-pXM8bSct.cjs → OpenCodeDriver-BTxd2Q3Q.cjs} +424 -209
- package/dist/{OpenCodeDriver-B7htxutj.mjs → OpenCodeDriver-DNApoGdu.mjs} +424 -209
- package/dist/{SourceControlProviderDiscoveryCatalog-Bj_sZfmB.cjs → SourceControlProviderDiscoveryCatalog-CPO3a9_U.cjs} +1 -1
- package/dist/{SourceControlProviderDiscoveryCatalog-C6Fn7rZE.mjs → SourceControlProviderDiscoveryCatalog-hXWNwRMn.mjs} +1 -1
- package/dist/bin.cjs +226 -43
- package/dist/bin.mjs +225 -44
- package/dist/client/assets/{AccountSettings-CinnQaX-.js → AccountSettings-Cey-16wq.js} +1 -1
- package/dist/client/assets/{AiFocusSettings-UbXOywZg.js → AiFocusSettings-CaHQXDaQ.js} +1 -1
- package/dist/client/assets/{AnimatedHeight-DCad8EQ2.js → AnimatedHeight-BC-qaTJY.js} +1 -1
- package/dist/client/assets/{AppearanceSettings-CTh8Z8nz.js → AppearanceSettings-B6UaU-_a.js} +1 -1
- package/dist/client/assets/{BranchToolbar.logic-37EnknDD.js → BranchToolbar.logic-DILAA3Cz.js} +1 -1
- package/dist/client/assets/{ChatRightPanel-DUwLYKbp.js → ChatRightPanel-D-AL07IU.js} +6 -6
- package/dist/client/assets/{ChatThreadRouteView-C43W0PEz.js → ChatThreadRouteView-tEo-zoCf.js} +1 -1
- package/dist/client/assets/{CommandPaletteDialog-IHOe0hOG.js → CommandPaletteDialog-s7yf5Y2S.js} +1 -1
- package/dist/client/assets/{CompositeItem-ClLCuzeJ.js → CompositeItem-97y1QiiT.js} +1 -1
- package/dist/client/assets/{CompositeRoot-Bdsr9eHn.js → CompositeRoot-C7Mz4Y_2.js} +1 -1
- package/dist/client/assets/{ConnectionsSettings-tmBjGOPj.js → ConnectionsSettings-B0-Hkwof.js} +1 -1
- package/dist/client/assets/{DiagnosticsSettings-CbCEgaau.js → DiagnosticsSettings-DX5LH9Bt.js} +1 -1
- package/dist/client/assets/{DialogHandle-CitVLvYq.js → DialogHandle-Cl9dQBJp.js} +1 -1
- package/dist/client/assets/{DialogPopup-CfaEr9jv.js → DialogPopup-a1M74u16.js} +1 -1
- package/dist/client/assets/DialogRoot-C_DO1gtO.js +1 -0
- package/dist/client/assets/{DialogTitle-BUkU0qXf.js → DialogTitle-Bk-w3xLJ.js} +1 -1
- package/dist/client/assets/{DialogTrigger-CEjWue7M.js → DialogTrigger-D9nkMFu2.js} +1 -1
- package/dist/client/assets/{DialogViewport-Cyc_ye5w.js → DialogViewport-tgJz2Lwn.js} +1 -1
- package/dist/client/assets/{DraftChatThreadRouteView-BSA67nKa.js → DraftChatThreadRouteView-BU2IGTR6.js} +1 -1
- package/dist/client/assets/{ExternalIdentityWeb.logic-BqdBjAua.js → ExternalIdentityWeb.logic-Bn1HigS9.js} +1 -1
- package/dist/client/assets/{GlassSurface-B3cq28tB.js → GlassSurface-CDok2tTN.js} +1 -1
- package/dist/client/assets/{HostedConnectionControls-S2Wr9fiZ.js → HostedConnectionControls-Cux_sRCM.js} +1 -1
- package/dist/client/assets/{HostedHubRoot-DK9zP4tJ.js → HostedHubRoot-CyySCdJV.js} +1 -1
- package/dist/client/assets/{HostedNativeAuthorizationRoute-CKnLbCOH.js → HostedNativeAuthorizationRoute-490iDXmk.js} +1 -1
- package/dist/client/assets/{HostedRelayTrustNotice-CbF_SOpf.js → HostedRelayTrustNotice-CcDOAwgS.js} +1 -1
- package/dist/client/assets/{Icons-DZpTOLIb.js → Icons-BEtED8P8.js} +1 -1
- package/dist/client/assets/{IntegrationsSettingsPanel-BdBEGIyL.js → IntegrationsSettingsPanel-BFTAvxtn.js} +1 -1
- package/dist/client/assets/{KeybindingsSettings-Bye1H9Sx.js → KeybindingsSettings-VYgbhiZF.js} +1 -1
- package/dist/client/assets/{McpServersSettings-D0U0g2q7.js → McpServersSettings-DSDCjoTn.js} +1 -1
- package/dist/client/assets/{MobileSheet-BPvuTPR6.js → MobileSheet-BDvnUC5W.js} +1 -1
- package/dist/client/assets/{NewWorktreeDialog-C_xJCZWF.js → NewWorktreeDialog-C65Aifeb.js} +1 -1
- package/dist/client/assets/{NoActiveThreadState-Cfn_Wwnf.js → NoActiveThreadState-DehHNgAp.js} +1 -1
- package/dist/client/assets/{NodeSecuritySettings-DUQNZJqJ.js → NodeSecuritySettings-DW9GJ-kU.js} +1 -1
- package/dist/client/assets/{OpinionatedPluginsSettings-D44efcv7.js → OpinionatedPluginsSettings-DbxPOokL.js} +1 -1
- package/dist/client/assets/{PhoneGetAppInterstitial-CzduFI4-.js → PhoneGetAppInterstitial-CbyVrtDn.js} +1 -1
- package/dist/client/assets/{PhoneGetAppInterstitialBackdrop-CJ44QRCp.js → PhoneGetAppInterstitialBackdrop-BA4R225F.js} +1 -1
- package/dist/client/assets/{PhoneHome-BLEJm5TG.js → PhoneHome-c0j_TBEC.js} +1 -1
- package/dist/client/assets/{PhoneSettingsSurface-CqetLTIm.js → PhoneSettingsSurface-5LFRIx_5.js} +1 -1
- package/dist/client/assets/{ProjectFavicon-DrBXI2cH.js → ProjectFavicon-CeVJCQCy.js} +1 -1
- package/dist/client/assets/{ProviderModelPicker-CyID3P1C.js → ProviderModelPicker-MFRYAv_3.js} +1 -1
- package/dist/client/assets/{ProviderUpdateLaunchNotification.logic-C6VoLD-w.js → ProviderUpdateLaunchNotification.logic-CywRitn3.js} +1 -1
- package/dist/client/assets/{ProvidersSettingsPanel-BHmpXUIM.js → ProvidersSettingsPanel-FYBEqSr_.js} +1 -1
- package/dist/client/assets/{RedactedSensitiveText-CZwFEoNn.js → RedactedSensitiveText-BuWSWty8.js} +1 -1
- package/dist/client/assets/{RootAppShell-BVXRShhe.js → RootAppShell-5HrP6N8H.js} +2 -2
- package/dist/client/assets/{RycoLetterMark-C-fvI9UB.js → RycoLetterMark-CZYntY8t.js} +1 -1
- package/dist/client/assets/{SettingsDialog-CnETTu23.js → SettingsDialog-CpwoqGS8.js} +1 -1
- package/dist/client/assets/{SettingsPanels-C3HDrmQq.js → SettingsPanels-COWRB29-.js} +1 -1
- package/dist/client/assets/{SettingsPanels.editor-DI8Z5rsl.js → SettingsPanels.editor-lbLEbllb.js} +1 -1
- package/dist/client/assets/{SourceControlSettings-BG4tsvql.js → SourceControlSettings-DvBNelcO.js} +1 -1
- package/dist/client/assets/{StatisticsPage-dy_aYqvS.js → StatisticsPage-DxAKqvVX.js} +1 -1
- package/dist/client/assets/{StatisticsPanel-CeRJBu65.js → StatisticsPanel-C0xGLlMA.js} +1 -1
- package/dist/client/assets/{StatisticsSettingsLink-ChlwCDG0.js → StatisticsSettingsLink-B7SZerf3.js} +1 -1
- package/dist/client/assets/{ThreadStatusIndicators-D-ioX09X.js → ThreadStatusIndicators-CIOM98q2.js} +0 -0
- package/dist/client/assets/{ThreadTerminalDrawer-BvGaRxBP.js → ThreadTerminalDrawer-DRelLlEP.js} +1 -1
- package/dist/client/assets/{ThreadWorkspacePanel-BAWm7mGl.js → ThreadWorkspacePanel-CktVSliZ.js} +2 -2
- package/dist/client/assets/{ToolbarRootContext-k-_m5nCN.js → ToolbarRootContext-B1g8IP6k.js} +1 -1
- package/dist/client/assets/{WorkItemsTab-Q2V2EuvK.js → WorkItemsTab-CahU_t_S.js} +1 -1
- package/dist/client/assets/{alert-BymbRVPf.js → alert-DomE7dAt.js} +1 -1
- package/dist/client/assets/{alert-dialog-Gym8_p4Q.js → alert-dialog-9Jyh0e8u.js} +1 -1
- package/dist/client/assets/{authorization-BwQZHweJ.js → authorization-D8lJzXTE.js} +1 -1
- package/dist/client/assets/{badge-BQI7J3Sg.js → badge-w43sx8eF.js} +1 -1
- package/dist/client/assets/{branding-DqHDcyzW.js → branding-B7DcCXjn.js} +1 -1
- package/dist/client/assets/{button-Wf_1nfeu.js → button-DG8WqjNn.js} +1 -1
- package/dist/client/assets/{capabilities-BrllgEYz.js → capabilities-B1FHGoov.js} +1 -1
- package/dist/client/assets/{chatThreadActions-BGkJmj6T.js → chatThreadActions-BZvyhfKr.js} +1 -1
- package/dist/client/assets/{collapsible-GOpRckDq.js → collapsible-EhAEe5S9.js} +1 -1
- package/dist/client/assets/{command-Dx5YM54H.js → command-Cyn6yIEa.js} +1 -1
- package/dist/client/assets/{composerDraftStore-DC2r8dcu.js → composerDraftStore-TYv9j3vY.js} +2 -2
- package/dist/client/assets/{data-list-BSiCZBKn.js → data-list-DTdqWMGN.js} +1 -1
- package/dist/client/assets/{desktopUpdateAtoms-DkmoIGr0.js → desktopUpdateAtoms-CPlZiFRm.js} +1 -1
- package/dist/client/assets/{desktopWorkspace-Ddm531g5.js → desktopWorkspace-DEZ30LlY.js} +1 -1
- package/dist/client/assets/device-CHdXzvhB.js +168 -0
- package/dist/client/assets/{dialog-CUxw5AxI.js → dialog-BNmFD6Nh.js} +1 -1
- package/dist/client/assets/{draft-input-CpfrGQ1h.js → draft-input-dP7F8odz.js} +1 -1
- package/dist/client/assets/{editorPreferences-SOMXdQpi.js → editorPreferences-B4GvqMiF.js} +1 -1
- package/dist/client/assets/{empty-D420OZA9.js → empty-Ccxhyvdf.js} +1 -1
- package/dist/client/assets/{env-Bf33qXdb.js → env-Bcq9YR3B.js} +1 -1
- package/dist/client/assets/{getPseudoElementBounds-nDGTWECG.js → getPseudoElementBounds-CO5HJT7x.js} +1 -1
- package/dist/client/assets/{group-Cq4Llttm.js → group-CzdKmc45.js} +1 -1
- package/dist/client/assets/{index-BL8_ra0g.js → index-Gre6bNC8.js} +2 -2
- package/dist/client/assets/{input-Dl4N9ZfE.js → input-BZz4eLRl.js} +1 -1
- package/dist/client/assets/{kbd-CqoZVQfv.js → kbd-DbvN3zTb.js} +1 -1
- package/dist/client/assets/{keybindings-DQzcPjMv.js → keybindings-BPE3eEAM.js} +1 -1
- package/dist/client/assets/{label-x5DgpBI_.js → label-DZf4lbNF.js} +1 -1
- package/dist/client/assets/{lib-BXIqHSZx.js → lib-DgOYoged.js} +1 -1
- package/dist/client/assets/{logging-CZlHfeu2.js → logging-81iP6Hps.js} +1 -1
- package/dist/client/assets/main-DlGNPwsH.css +2 -0
- package/dist/client/assets/{main-J4YlUJad.js → main-Dz0zookE.js} +2 -2
- package/dist/client/assets/{menu-BuDpxm_Q.js → menu-B6UEFcn0.js} +1 -1
- package/dist/client/assets/{popover-DuprDUaB.js → popover-BuYzXGwl.js} +1 -1
- package/dist/client/assets/{primary-CJx2nSkc.js → primary-CiDY2oUi.js} +1 -1
- package/dist/client/assets/{projectPaths-DrelgodZ.js → projectPaths-D6fHIU1b.js} +1 -1
- package/dist/client/assets/{providerDriverMeta-D27Koh7Q.js → providerDriverMeta-sBwZhQoN.js} +1 -1
- package/dist/client/assets/{providerIconUtils-CtOHwjWL.js → providerIconUtils-DiDJeNtT.js} +1 -1
- package/dist/client/assets/providerInstances-vd2eZtHx.js +1 -0
- package/dist/client/assets/providerModels-vd2eZtHx.js +1 -0
- package/dist/client/assets/{qr-code-BVfzPOP3.js → qr-code-Ie92aZvE.js} +1 -1
- package/dist/client/assets/{radio-group-rgmJqPI7.js → radio-group-BuuTEtdC.js} +1 -1
- package/dist/client/assets/{resolveAriaLabelledBy-l4SuqStl.js → resolveAriaLabelledBy-0FA0k4xp.js} +1 -1
- package/dist/client/assets/{rightPanelRouteSearch-DmpObL1z.js → rightPanelRouteSearch-BS8CkNS6.js} +1 -1
- package/dist/client/assets/{runtime-DYzjhL5M.js → runtime-CPM0EUhb.js} +1 -1
- package/dist/client/assets/{scroll-area-DMs8l4bb.js → scroll-area-C0yF015F.js} +1 -1
- package/dist/client/assets/{scrollEdges-DWTOweRb.js → scrollEdges-DI5Y3mtR.js} +1 -1
- package/dist/client/assets/{select-Djwp8HDm.js → select-CZukJlTn.js} +1 -1
- package/dist/client/assets/{separator-rjtf5Q3V.js → separator-D4ckGtPe.js} +1 -1
- package/dist/client/assets/session-logic-BalPN1Sc.js +4 -0
- package/dist/client/assets/{settingsDialogStore-Dbykwvfs.js → settingsDialogStore-LxRFC5hh.js} +1 -1
- package/dist/client/assets/{settingsLayout-C7bl9Xi4.js → settingsLayout-CHJT5wtl.js} +1 -1
- package/dist/client/assets/{sheet-CQIQYfOM.js → sheet-BNfImQ-7.js} +1 -1
- package/dist/client/assets/{sidebar-BdDOvXe8.js → sidebar-CFGg5Tkr.js} +1 -1
- package/dist/client/assets/{sidebarProjectFolders-D_Me0oJ8.js → sidebarProjectFolders-bhNsO9Z_.js} +1 -1
- package/dist/client/assets/{sidebarStatusText-BF6odB03.js → sidebarStatusText-C8QBhZhZ.js} +1 -1
- package/dist/client/assets/{skeleton-Mgh4Gx9x.js → skeleton-DOgQaVXv.js} +1 -1
- package/dist/client/assets/{spinner-CzzUdFeE.js → spinner-ClQu8SdC.js} +1 -1
- package/dist/client/assets/{src-Ca7Gag3m.js → src-DmPIm3ie.js} +1 -1
- package/dist/client/assets/storeSelectors-Cf2WDMfx.js +1 -0
- package/dist/client/assets/{switch-CntUxI1A.js → switch-BZjA7VT9.js} +1 -1
- package/dist/client/assets/{terminal-links-CUFISn8U.js → terminal-links-CzJomeox.js} +1 -1
- package/dist/client/assets/{textarea-C8QxddDb.js → textarea-DHdmRD1r.js} +1 -1
- package/dist/client/assets/{threadPinning-BIV4KXZU.js → threadPinning-BLqwZebi.js} +1 -1
- package/dist/client/assets/{threadPriorityRefreshRuntime-B-pVYK_y.js → threadPriorityRefreshRuntime-BoNAlBXK.js} +1 -1
- package/dist/client/assets/{toast-Cw7bXJzg.js → toast-C-0Ft2jD.js} +1 -1
- package/dist/client/assets/{toggle-Bi9uP4Hb.js → toggle-DsnOFDbJ.js} +1 -1
- package/dist/client/assets/{toggle-group-LcgyMgj5.js → toggle-group-Chxh9G6t.js} +1 -1
- package/dist/client/assets/{tooltip-t3Nrleyq.js → tooltip-C_-9XEfA.js} +1 -1
- package/dist/client/assets/types-Cf2WDMfx.js +1 -0
- package/dist/client/assets/{uiStateStore-BW2WnK4k.js → uiStateStore-DzUrk2GS.js} +1 -1
- package/dist/client/assets/{useAtlassian-a-MaAd0k.js → useAtlassian-CoHKzu-e.js} +0 -0
- package/dist/client/assets/{useButton-DUuWgIMw.js → useButton-BmvYhoMC.js} +1 -1
- package/dist/client/assets/{useCompositeListItem-CL5mJqCb.js → useCompositeListItem-D0PvH4nv.js} +1 -1
- package/dist/client/assets/{useDebouncedValue-jDDWNjgt.js → useDebouncedValue-s0BC8Yyp.js} +1 -1
- package/dist/client/assets/{useFloatingRootContext-C4I8IxtL.js → useFloatingRootContext-CLCaQEJk.js} +1 -1
- package/dist/client/assets/{useHandleNewThread-820pBJCC.js → useHandleNewThread-Bw460iXT.js} +1 -1
- package/dist/client/assets/{useLabelableId-KX33mhBC.js → useLabelableId-CB_9OReR.js} +1 -1
- package/dist/client/assets/{useLocation-B4QlXdMt.js → useLocation-DGJMt6gP.js} +1 -1
- package/dist/client/assets/{useOpenInteractionType-DjM9MBY7.js → useOpenInteractionType-BSSI2GzS.js} +1 -1
- package/dist/client/assets/{usePhoneThreadActions-DxxWMYgC.js → usePhoneThreadActions-BIDUSWSI.js} +1 -1
- package/dist/client/assets/{usePopupViewport-CAMlnyaP.js → usePopupViewport-8F-J1h5f.js} +1 -1
- package/dist/client/assets/{useScrollLock-CAPfesBT.js → useScrollLock-CBz-5_MX.js} +1 -1
- package/dist/client/assets/{useStatistics-CWasDzsV.js → useStatistics-B91973jb.js} +1 -1
- package/dist/client/assets/{useSwipeDismiss-BZsYSBgq.js → useSwipeDismiss-D22_vuiH.js} +1 -1
- package/dist/client/assets/{useThreadActions-MOjDrEnS.js → useThreadActions-BCH01d6u.js} +1 -1
- package/dist/client/assets/{useTriggerFocusGuards-D5z439rn.js → useTriggerFocusGuards-f7afwACm.js} +1 -1
- package/dist/client/assets/{useValueChanged-D0CHQQwP.js → useValueChanged-EkWF0C3k.js} +1 -1
- package/dist/client/assets/{utils-B76_2Yk7.js → utils-CV2fJJxC.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/{collectUint8StreamText-B9B7bGv9.cjs → collectUint8StreamText-Dsbmrw73.cjs} +2 -0
- package/dist/{collectUint8StreamText-RzKEq2NY.mjs → collectUint8StreamText-oFvWyN3_.mjs} +2 -0
- package/dist/{makeManagedServerProvider-BF1eBatf.cjs → makeManagedServerProvider-CANTNAsz.cjs} +9 -2
- package/dist/{makeManagedServerProvider-BuG2fLP8.mjs → makeManagedServerProvider-PLtJj7EV.mjs} +10 -3
- package/package.json +1 -1
- package/dist/client/assets/DialogRoot-CyEOjgGH.js +0 -1
- package/dist/client/assets/device-B0aqBYM1.js +0 -168
- package/dist/client/assets/main-B7T7on1T.css +0 -2
- package/dist/client/assets/providerInstances-BPwEwwpF.js +0 -1
- package/dist/client/assets/providerModels-BPwEwwpF.js +0 -1
- package/dist/client/assets/session-logic-DLEAZb3K.js +0 -4
- package/dist/client/assets/storeSelectors-D7HbqO4E.js +0 -1
- package/dist/client/assets/types-D7HbqO4E.js +0 -1
|
@@ -1,17 +1,78 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { Ba as ProviderDriverKind, Bo as EventId, Jo as RuntimeRequestId, Ko as ProviderItemId, Pn as TextGenerationError, Va as ProviderInstanceId, Xo as RuntimeSubagentId, ar as OpenCodeSettings, bi as PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES, es as TurnId, qo as RuntimeItemId } from "./collectUint8StreamText-
|
|
3
|
+
import { Ba as ProviderDriverKind, Bo as EventId, Jo as RuntimeRequestId, Ko as ProviderItemId, Pn as TextGenerationError, Va as ProviderInstanceId, Xo as RuntimeSubagentId, ar as OpenCodeSettings, bi as PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES, es as TurnId, qo as RuntimeItemId } from "./collectUint8StreamText-oFvWyN3_.mjs";
|
|
4
4
|
import { nt as sanitizeFeatureBranchName, st as ServerConfig, tt as sanitizeBranchFragment } from "./Metrics-BP9YjxZB.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { $ as parseGenericCliVersion, A as buildThreadTitlePrompt, C as validateRankInboxThreadsResult, D as buildIssueContentTitlePrompt, E as buildIssueContentPolishPrompt, F as sanitizeThreadTitle, Fn as resolveProviderMaintenanceCapabilitiesEffect, Hn as createModelCapabilities, In as compareCliVersions, J as buildServerProvider, Ln as ServerSettingsService, N as sanitizeCommitSubject, O as buildPrContentPrompt, P as sanitizePrTitle, Pn as normalizeCommandPath, Q as nonEmptyTrimmed, Rn as readPersistedAttachment, T as buildCommitMessagePrompt, V as mergeProviderInstanceEnvironment, Wn as getModelSelectionStringOptionValue, _ as toOpenCodeQuestionAnswers, b as makeEventNdjsonLogger, c as OpenCodeRuntime, ct as ProviderAdapterProcessError, d as openCodeQuestionId, dt as ProviderAdapterSessionNotFoundError, et as providerModelsFromSettings, f as openCodeRuntimeErrorDetail, ft as ProviderAdapterValidationError, g as toOpenCodePermissionReply, h as toOpenCodeFileParts, j as extractJsonObject, jn as makePackageManagedProviderMaintenanceResolver, k as buildThreadPriorityPrompt, kn as enrichProviderSnapshotWithVersionAdvisory, l as OpenCodeRuntimeError, lt as ProviderAdapterRequestError, m as runOpenCodeSdk, p as parseOpenCodeModelSlug, pt as ProviderDriverError, rt as agentControlHostContext, s as MINIMUM_OPENCODE_VERSION, st as createProcessDeviceToolBinding, t as makeServerQueueMetrics, u as buildOpenCodePermissionRules, ut as ProviderAdapterSessionClosedError, v as verifyOpenCodeServerVersion, w as buildBranchNamePrompt, y as ProviderEventLoggers } from "./bin.mjs";
|
|
6
6
|
import { t as formatSourceControlContextsForAgent } from "./sourceControlContextFormatter-DEwpnVAH.mjs";
|
|
7
|
-
import { n as requireRuntimeSessionId, r as stampRuntimeEvent, t as makeManagedServerProvider } from "./makeManagedServerProvider-
|
|
7
|
+
import { n as requireRuntimeSessionId, r as stampRuntimeEvent, t as makeManagedServerProvider } from "./makeManagedServerProvider-PLtJj7EV.mjs";
|
|
8
8
|
import { t as defaultProviderContinuationIdentity } from "./ProviderDriver-kCV60GKk.mjs";
|
|
9
|
-
import { Cause, Data, Effect, Exit, Fiber, Queue, Ref, Schema, Scope, Stream } from "effect";
|
|
9
|
+
import { Cause, Data, Effect, Exit, Fiber, Queue, Ref, Schema, Scope, Semaphore, Stream } from "effect";
|
|
10
10
|
import { HttpClient } from "effect/unstable/http";
|
|
11
11
|
import "effect/unstable/process";
|
|
12
12
|
import * as Semaphore$1 from "effect/Semaphore";
|
|
13
|
+
//#region src/provider/OpenCodeServerOwner.ts
|
|
14
|
+
const OPENCODE_MANAGED_SERVER_IDLE_TTL = "30 seconds";
|
|
15
|
+
const makeOpenCodeServerOwner = Effect.fn("makeOpenCodeServerOwner")(function* (settings, environment = process.env) {
|
|
16
|
+
const runtime = yield* OpenCodeRuntime;
|
|
17
|
+
const ownerScope = yield* Effect.scope;
|
|
18
|
+
const mutex = yield* Semaphore$1.make(1);
|
|
19
|
+
let owned = null;
|
|
20
|
+
const closeOwned = (record) => Effect.gen(function* () {
|
|
21
|
+
if (owned === record) owned = null;
|
|
22
|
+
const idleFiber = record.idleCloseFiber;
|
|
23
|
+
record.idleCloseFiber = null;
|
|
24
|
+
if (idleFiber !== null) yield* Fiber.interrupt(idleFiber).pipe(Effect.ignore);
|
|
25
|
+
yield* Scope.close(record.scope, Exit.void).pipe(Effect.ignore);
|
|
26
|
+
});
|
|
27
|
+
const cancelIdleClose = (record) => Effect.gen(function* () {
|
|
28
|
+
const fiber = record.idleCloseFiber;
|
|
29
|
+
record.idleCloseFiber = null;
|
|
30
|
+
if (fiber !== null) yield* Fiber.interrupt(fiber).pipe(Effect.ignore);
|
|
31
|
+
});
|
|
32
|
+
const acquireProcess = mutex.withPermit(Effect.gen(function* () {
|
|
33
|
+
if (owned !== null) {
|
|
34
|
+
yield* cancelIdleClose(owned);
|
|
35
|
+
owned.leases += 1;
|
|
36
|
+
return owned.process;
|
|
37
|
+
}
|
|
38
|
+
return yield* Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
39
|
+
const processScope = yield* Scope.make();
|
|
40
|
+
const started = yield* Effect.exit(restore(runtime.startOpenCodeServerProcess({
|
|
41
|
+
binaryPath: settings.binaryPath,
|
|
42
|
+
...settings.serverPassword ? { serverPassword: settings.serverPassword } : {},
|
|
43
|
+
environment
|
|
44
|
+
}).pipe(Effect.provideService(Scope.Scope, processScope))));
|
|
45
|
+
if (Exit.isFailure(started)) {
|
|
46
|
+
yield* Scope.close(processScope, Exit.void).pipe(Effect.ignore);
|
|
47
|
+
return yield* Effect.failCause(started.cause);
|
|
48
|
+
}
|
|
49
|
+
owned = {
|
|
50
|
+
process: started.value,
|
|
51
|
+
scope: processScope,
|
|
52
|
+
leases: 1,
|
|
53
|
+
idleCloseFiber: null
|
|
54
|
+
};
|
|
55
|
+
return started.value;
|
|
56
|
+
}));
|
|
57
|
+
}));
|
|
58
|
+
const releaseProcess = (process) => mutex.withPermit(Effect.gen(function* () {
|
|
59
|
+
const record = owned;
|
|
60
|
+
if (record === null || record.process !== process) return;
|
|
61
|
+
record.leases = Math.max(0, record.leases - 1);
|
|
62
|
+
if (record.leases > 0 || record.idleCloseFiber !== null) return;
|
|
63
|
+
record.idleCloseFiber = yield* Effect.sleep(OPENCODE_MANAGED_SERVER_IDLE_TTL).pipe(Effect.andThen(mutex.withPermit(Effect.gen(function* () {
|
|
64
|
+
if (owned !== record || record.leases > 0) return;
|
|
65
|
+
record.idleCloseFiber = null;
|
|
66
|
+
yield* closeOwned(record);
|
|
67
|
+
}))), Effect.forkIn(ownerScope));
|
|
68
|
+
}));
|
|
69
|
+
yield* Effect.addFinalizer(() => mutex.withPermit(Effect.gen(function* () {
|
|
70
|
+
if (owned !== null) yield* closeOwned(owned);
|
|
71
|
+
})));
|
|
72
|
+
return { acquire: Effect.acquireRelease(acquireProcess, releaseProcess) };
|
|
73
|
+
});
|
|
74
|
+
//#endregion
|
|
13
75
|
//#region src/textGeneration/OpenCodeTextGeneration.ts
|
|
14
|
-
const OPENCODE_TEXT_GENERATION_IDLE_TTL = "30 seconds";
|
|
15
76
|
function getOpenCodePromptErrorMessage(error) {
|
|
16
77
|
if (!error || typeof error !== "object") return null;
|
|
17
78
|
const message = "data" in error && error.data && typeof error.data === "object" && "message" in error.data && typeof error.data.message === "string" ? error.data.message.trim() : "";
|
|
@@ -30,82 +91,10 @@ function getOpenCodeTextResponse(parts) {
|
|
|
30
91
|
return [part.text];
|
|
31
92
|
}).join("").trim();
|
|
32
93
|
}
|
|
33
|
-
const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(function* (openCodeSettings, environment = process.env) {
|
|
94
|
+
const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(function* (openCodeSettings, environment = process.env, options) {
|
|
34
95
|
const serverConfig = yield* ServerConfig;
|
|
35
96
|
const openCodeRuntime = yield* OpenCodeRuntime;
|
|
36
|
-
const
|
|
37
|
-
const sharedServerMutex = yield* Semaphore$1.make(1);
|
|
38
|
-
const sharedServerState = {
|
|
39
|
-
server: null,
|
|
40
|
-
serverScope: null,
|
|
41
|
-
binaryPath: null,
|
|
42
|
-
activeRequests: 0,
|
|
43
|
-
idleCloseFiber: null
|
|
44
|
-
};
|
|
45
|
-
const closeSharedServer = Effect.fn("closeSharedServer")(function* () {
|
|
46
|
-
const scope = sharedServerState.serverScope;
|
|
47
|
-
sharedServerState.server = null;
|
|
48
|
-
sharedServerState.serverScope = null;
|
|
49
|
-
sharedServerState.binaryPath = null;
|
|
50
|
-
if (scope !== null) yield* Scope.close(scope, Exit.void).pipe(Effect.ignore);
|
|
51
|
-
});
|
|
52
|
-
const cancelIdleCloseFiber = Effect.fn("cancelIdleCloseFiber")(function* () {
|
|
53
|
-
const idleCloseFiber = sharedServerState.idleCloseFiber;
|
|
54
|
-
sharedServerState.idleCloseFiber = null;
|
|
55
|
-
if (idleCloseFiber !== null) yield* Fiber.interrupt(idleCloseFiber).pipe(Effect.ignore);
|
|
56
|
-
});
|
|
57
|
-
const scheduleIdleClose = Effect.fn("scheduleIdleClose")(function* (server) {
|
|
58
|
-
yield* cancelIdleCloseFiber();
|
|
59
|
-
const fiber = yield* Effect.sleep(OPENCODE_TEXT_GENERATION_IDLE_TTL).pipe(Effect.andThen(sharedServerMutex.withPermit(Effect.gen(function* () {
|
|
60
|
-
if (sharedServerState.server !== server || sharedServerState.activeRequests > 0) return;
|
|
61
|
-
sharedServerState.idleCloseFiber = null;
|
|
62
|
-
yield* closeSharedServer();
|
|
63
|
-
}))), Effect.forkIn(idleFiberScope));
|
|
64
|
-
sharedServerState.idleCloseFiber = fiber;
|
|
65
|
-
});
|
|
66
|
-
const acquireSharedServer = (input) => sharedServerMutex.withPermit(Effect.gen(function* () {
|
|
67
|
-
yield* cancelIdleCloseFiber();
|
|
68
|
-
const existingServer = sharedServerState.server;
|
|
69
|
-
if (existingServer !== null) {
|
|
70
|
-
if (sharedServerState.binaryPath !== input.binaryPath && sharedServerState.activeRequests === 0) yield* closeSharedServer();
|
|
71
|
-
else {
|
|
72
|
-
if (sharedServerState.binaryPath !== input.binaryPath) yield* Effect.logWarning("OpenCode shared server binary path mismatch: requested " + input.binaryPath + " but active server uses " + sharedServerState.binaryPath + "; reusing existing server because there are active requests");
|
|
73
|
-
sharedServerState.activeRequests += 1;
|
|
74
|
-
return existingServer;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return yield* Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
78
|
-
const serverScope = yield* Scope.make();
|
|
79
|
-
const startedExit = yield* Effect.exit(restore(openCodeRuntime.startOpenCodeServerProcess({
|
|
80
|
-
binaryPath: input.binaryPath,
|
|
81
|
-
environment
|
|
82
|
-
}).pipe(Effect.provideService(Scope.Scope, serverScope), Effect.mapError((cause) => new TextGenerationError({
|
|
83
|
-
operation: input.operation,
|
|
84
|
-
detail: openCodeRuntimeErrorDetail(cause),
|
|
85
|
-
cause
|
|
86
|
-
})))));
|
|
87
|
-
if (startedExit._tag === "Failure") {
|
|
88
|
-
yield* Scope.close(serverScope, Exit.void).pipe(Effect.ignore);
|
|
89
|
-
return yield* Effect.failCause(startedExit.cause);
|
|
90
|
-
}
|
|
91
|
-
const server = startedExit.value;
|
|
92
|
-
sharedServerState.server = server;
|
|
93
|
-
sharedServerState.serverScope = serverScope;
|
|
94
|
-
sharedServerState.binaryPath = input.binaryPath;
|
|
95
|
-
sharedServerState.activeRequests = 1;
|
|
96
|
-
return server;
|
|
97
|
-
}));
|
|
98
|
-
}));
|
|
99
|
-
const releaseSharedServer = (server) => sharedServerMutex.withPermit(Effect.gen(function* () {
|
|
100
|
-
if (sharedServerState.server !== server) return;
|
|
101
|
-
sharedServerState.activeRequests = Math.max(0, sharedServerState.activeRequests - 1);
|
|
102
|
-
if (sharedServerState.activeRequests === 0) yield* scheduleIdleClose(server);
|
|
103
|
-
}));
|
|
104
|
-
yield* Effect.addFinalizer(() => sharedServerMutex.withPermit(Effect.gen(function* () {
|
|
105
|
-
yield* cancelIdleCloseFiber();
|
|
106
|
-
sharedServerState.activeRequests = 0;
|
|
107
|
-
yield* closeSharedServer();
|
|
108
|
-
})));
|
|
97
|
+
const serverOwner = options?.serverOwner ?? (openCodeSettings.serverUrl.trim().length === 0 ? yield* makeOpenCodeServerOwner(openCodeSettings, environment) : void 0);
|
|
109
98
|
const runOpenCodeJson = Effect.fn("runOpenCodeJson")(function* (input) {
|
|
110
99
|
const parsedModel = parseOpenCodeModelSlug(input.modelSelection.model);
|
|
111
100
|
if (!parsedModel) return yield* new TextGenerationError({
|
|
@@ -143,12 +132,17 @@ const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(funct
|
|
|
143
132
|
const client = yield* openCodeRuntime.createOpenCodeSdkClient({
|
|
144
133
|
baseUrl: server.url,
|
|
145
134
|
directory: input.cwd,
|
|
146
|
-
...
|
|
135
|
+
...server.serverPassword ? { serverPassword: server.serverPassword } : {}
|
|
147
136
|
}).pipe(Effect.mapError((cause) => new TextGenerationError({
|
|
148
137
|
operation: input.operation,
|
|
149
138
|
detail: openCodeRuntimeErrorDetail(cause),
|
|
150
139
|
cause
|
|
151
140
|
})));
|
|
141
|
+
yield* verifyOpenCodeServerVersion(client).pipe(Effect.mapError((cause) => new TextGenerationError({
|
|
142
|
+
operation: input.operation,
|
|
143
|
+
detail: openCodeRuntimeErrorDetail(cause),
|
|
144
|
+
cause
|
|
145
|
+
})));
|
|
152
146
|
return yield* Effect.tryPromise({
|
|
153
147
|
try: async () => {
|
|
154
148
|
const session = await client.session.create({
|
|
@@ -186,10 +180,14 @@ const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(funct
|
|
|
186
180
|
})
|
|
187
181
|
});
|
|
188
182
|
});
|
|
189
|
-
const rawOutput = openCodeSettings.serverUrl.length > 0 ? yield* runAgainstServer({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
})
|
|
183
|
+
const rawOutput = openCodeSettings.serverUrl.length > 0 ? yield* runAgainstServer({
|
|
184
|
+
url: openCodeSettings.serverUrl,
|
|
185
|
+
...openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
|
|
186
|
+
}) : yield* Effect.scoped(serverOwner.acquire.pipe(Effect.mapError((cause) => new TextGenerationError({
|
|
187
|
+
operation: input.operation,
|
|
188
|
+
detail: openCodeRuntimeErrorDetail(cause),
|
|
189
|
+
cause
|
|
190
|
+
})), Effect.flatMap(runAgainstServer)));
|
|
193
191
|
return yield* Schema.decodeEffect(Schema.fromJsonString(input.outputSchemaJson))(extractJsonObject(rawOutput)).pipe(Effect.catchTag("SchemaError", (cause) => Effect.fail(new TextGenerationError({
|
|
194
192
|
operation: input.operation,
|
|
195
193
|
detail: "OpenCode returned invalid structured output.",
|
|
@@ -312,6 +310,7 @@ const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration")(funct
|
|
|
312
310
|
//#endregion
|
|
313
311
|
//#region src/provider/Layers/OpenCodeAdapter.ts
|
|
314
312
|
const PROVIDER$1 = ProviderDriverKind.make("opencode");
|
|
313
|
+
const OPENCODE_RESUME_VERSION = 1;
|
|
315
314
|
function nowIso() {
|
|
316
315
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
317
316
|
}
|
|
@@ -319,6 +318,15 @@ function nonEmptyString(value) {
|
|
|
319
318
|
const trimmed = value?.trim();
|
|
320
319
|
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
321
320
|
}
|
|
321
|
+
function parseOpenCodeResume(value) {
|
|
322
|
+
if (!value || typeof value !== "object") return;
|
|
323
|
+
const cursor = value;
|
|
324
|
+
return cursor.schemaVersion === OPENCODE_RESUME_VERSION && typeof cursor.sessionId === "string" && cursor.sessionId.trim().length > 0 ? { sessionId: cursor.sessionId } : void 0;
|
|
325
|
+
}
|
|
326
|
+
function isOpenCodeNotFound(error) {
|
|
327
|
+
const cause = error.cause;
|
|
328
|
+
return typeof cause === "object" && cause !== null && "response" in cause && cause.response?.status === 404;
|
|
329
|
+
}
|
|
322
330
|
function scopedOpenCodeId(sessionId, id) {
|
|
323
331
|
return `${sessionId}:${id}`;
|
|
324
332
|
}
|
|
@@ -331,6 +339,9 @@ function subagentKey(subagentId) {
|
|
|
331
339
|
function statusFromOpenCodeSubagentState(status) {
|
|
332
340
|
return status;
|
|
333
341
|
}
|
|
342
|
+
function isOpenCodeRequestEvent(event) {
|
|
343
|
+
return event.type === "permission.asked" || event.type === "permission.replied" || event.type === "question.asked" || event.type === "question.replied" || event.type === "question.rejected";
|
|
344
|
+
}
|
|
334
345
|
function subagentCompletionStatus(status) {
|
|
335
346
|
return status;
|
|
336
347
|
}
|
|
@@ -340,6 +351,7 @@ function metadataWithEntries(entries) {
|
|
|
340
351
|
}
|
|
341
352
|
function makeSubtaskSubagentRef(part) {
|
|
342
353
|
const description = nonEmptyString(part.description) ?? nonEmptyString(part.prompt);
|
|
354
|
+
const model = part.model ? `${part.model.providerID}/${part.model.modelID}` : void 0;
|
|
343
355
|
const label = nonEmptyString(part.agent) ?? nonEmptyString(part.command) ?? (description ? "OpenCode subtask" : void 0);
|
|
344
356
|
return {
|
|
345
357
|
subagentId: openCodeSubagentId("subtask", part.id),
|
|
@@ -347,6 +359,7 @@ function makeSubtaskSubagentRef(part) {
|
|
|
347
359
|
capability: "summary",
|
|
348
360
|
...label ? { label } : {},
|
|
349
361
|
...description ? { description } : {},
|
|
362
|
+
...model ? { model } : {},
|
|
350
363
|
parentProviderItemId: ProviderItemId.make(part.id),
|
|
351
364
|
metadata: metadataWithEntries([
|
|
352
365
|
["source", "opencode.subtask"],
|
|
@@ -365,6 +378,8 @@ function mergeOpenCodeChildSessionRef(existing, session, parentSessionId) {
|
|
|
365
378
|
capability: "transcript",
|
|
366
379
|
label,
|
|
367
380
|
...existing?.description ? { description: existing.description } : {},
|
|
381
|
+
...existing?.model ? { model: existing.model } : {},
|
|
382
|
+
...existing?.effort ? { effort: existing.effort } : {},
|
|
368
383
|
providerSessionId: session.id,
|
|
369
384
|
providerThreadId: session.id,
|
|
370
385
|
...existing?.parentProviderItemId && { parentProviderItemId: existing.parentProviderItemId },
|
|
@@ -401,6 +416,13 @@ const toProcessError = (threadId, cause) => new ProviderAdapterProcessError({
|
|
|
401
416
|
detail: OpenCodeRuntimeError.is(cause) ? cause.detail : openCodeRuntimeErrorDetail(cause),
|
|
402
417
|
cause
|
|
403
418
|
});
|
|
419
|
+
const abortOpenCodeSession = (context, sessionID) => runOpenCodeSdk("session.abort", (signal) => context.client.session.abort({ sessionID }, { signal })).pipe(Effect.timeoutOrElse({
|
|
420
|
+
duration: "2 seconds",
|
|
421
|
+
orElse: () => Effect.fail(new OpenCodeRuntimeError({
|
|
422
|
+
operation: "session.abort",
|
|
423
|
+
detail: `Timed out aborting OpenCode session '${sessionID}'.`
|
|
424
|
+
}))
|
|
425
|
+
}));
|
|
404
426
|
const buildEventBase = (input) => Effect.sync(() => crypto.randomUUID()).pipe(Effect.map((uuid) => ({
|
|
405
427
|
eventId: EventId.make(uuid),
|
|
406
428
|
provider: PROVIDER$1,
|
|
@@ -560,7 +582,12 @@ function updateProviderSession(context, patch, options) {
|
|
|
560
582
|
}
|
|
561
583
|
const stopOpenCodeContext = Effect.fn("stopOpenCodeContext")(function* (context) {
|
|
562
584
|
if (yield* Ref.getAndSet(context.stopped, true)) return false;
|
|
563
|
-
|
|
585
|
+
const pendingPrompt = context.pendingPrompt;
|
|
586
|
+
if (pendingPrompt) {
|
|
587
|
+
context.pendingPrompt = void 0;
|
|
588
|
+
yield* Fiber.interrupt(pendingPrompt.fiber).pipe(Effect.ignore);
|
|
589
|
+
}
|
|
590
|
+
yield* Effect.forEach([context.openCodeSessionId, ...context.childSessionIds], (sessionID) => abortOpenCodeSession(context, sessionID).pipe(Effect.ignore({ log: true })), { discard: true });
|
|
564
591
|
yield* Scope.close(context.sessionScope, Exit.void);
|
|
565
592
|
return true;
|
|
566
593
|
});
|
|
@@ -675,8 +702,8 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
675
702
|
return context.subagentBySubtaskPartId.get(partKey);
|
|
676
703
|
};
|
|
677
704
|
const registerOpenCodeChildSession = Effect.fn("registerOpenCodeChildSession")(function* (context, session, raw) {
|
|
678
|
-
if (session.parentID !== context.openCodeSessionId) return;
|
|
679
|
-
const subagent = mergeOpenCodeChildSessionRef(context.subagentBySessionId.get(session.id) ?? takeUnboundOpenCodeSubtask(context), session, context.openCodeSessionId);
|
|
705
|
+
if (session.parentID !== context.openCodeSessionId && (session.parentID === void 0 || !context.childSessionIds.has(session.parentID))) return;
|
|
706
|
+
const subagent = mergeOpenCodeChildSessionRef(context.subagentBySessionId.get(session.id) ?? takeUnboundOpenCodeSubtask(context), session, session.parentID ?? context.openCodeSessionId);
|
|
680
707
|
const known = context.childSessionIds.has(session.id);
|
|
681
708
|
context.childSessionIds.add(session.id);
|
|
682
709
|
context.subagentBySessionId.set(session.id, subagent);
|
|
@@ -720,6 +747,89 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
720
747
|
child
|
|
721
748
|
});
|
|
722
749
|
});
|
|
750
|
+
const isRelatedOpenCodeSession = Effect.fn("isRelatedOpenCodeSession")(function* (context, candidateSessionId) {
|
|
751
|
+
if (candidateSessionId === context.openCodeSessionId || context.childSessionIds.has(candidateSessionId)) return true;
|
|
752
|
+
const seen = /* @__PURE__ */ new Set();
|
|
753
|
+
let sessionId = candidateSessionId;
|
|
754
|
+
for (let depth = 0; sessionId !== void 0 && depth < 32; depth += 1) {
|
|
755
|
+
if (sessionId === context.openCodeSessionId || context.childSessionIds.has(sessionId)) {
|
|
756
|
+
for (const relatedId of seen) context.childSessionIds.add(relatedId);
|
|
757
|
+
return true;
|
|
758
|
+
}
|
|
759
|
+
if (seen.has(sessionId)) return false;
|
|
760
|
+
seen.add(sessionId);
|
|
761
|
+
const currentSessionId = sessionId;
|
|
762
|
+
const response = yield* runOpenCodeSdk("session.get", () => context.client.session.get({ sessionID: currentSessionId })).pipe(Effect.catchIf(isOpenCodeNotFound, () => Effect.succeed(void 0)));
|
|
763
|
+
if (!response?.data) return false;
|
|
764
|
+
sessionId = response.data.parentID;
|
|
765
|
+
}
|
|
766
|
+
return false;
|
|
767
|
+
});
|
|
768
|
+
const recoverPendingOpenCodeRequests = Effect.fn("recoverPendingOpenCodeRequests")(function* (context) {
|
|
769
|
+
for (let attempt = 0; attempt < 5; attempt += 1) {
|
|
770
|
+
if (yield* Ref.get(context.stopped)) return;
|
|
771
|
+
const result = yield* Effect.all({
|
|
772
|
+
permissions: runOpenCodeSdk("permission.list", () => context.client.permission.list()),
|
|
773
|
+
questions: runOpenCodeSdk("question.list", () => context.client.question.list())
|
|
774
|
+
}).pipe(Effect.exit);
|
|
775
|
+
if (Exit.isFailure(result)) {
|
|
776
|
+
if (attempt === 4) {
|
|
777
|
+
yield* emitForContext(context, {
|
|
778
|
+
...yield* buildEventBase({ threadId: context.session.threadId }),
|
|
779
|
+
type: "runtime.warning",
|
|
780
|
+
payload: {
|
|
781
|
+
message: "OpenCode pending request recovery failed.",
|
|
782
|
+
detail: openCodeRuntimeErrorDetail(Cause.squash(result.cause))
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
yield* Effect.sleep(`${250 * 2 ** attempt} millis`);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
for (const request of result.value.permissions.data ?? []) {
|
|
791
|
+
if (context.resolvedRequestIds.has(request.id) || context.pendingPermissions.has(request.id) || !(yield* isRelatedOpenCodeSession(context, request.sessionID))) continue;
|
|
792
|
+
context.pendingPermissions.set(request.id, request);
|
|
793
|
+
yield* emitForContext(context, {
|
|
794
|
+
...yield* buildEventBase({
|
|
795
|
+
threadId: context.session.threadId,
|
|
796
|
+
turnId: context.activeTurnId,
|
|
797
|
+
requestId: request.id,
|
|
798
|
+
raw: {
|
|
799
|
+
type: "permission.asked",
|
|
800
|
+
properties: request,
|
|
801
|
+
recovered: true
|
|
802
|
+
}
|
|
803
|
+
}),
|
|
804
|
+
type: "request.opened",
|
|
805
|
+
payload: {
|
|
806
|
+
requestType: mapPermissionToRequestType(request.permission),
|
|
807
|
+
detail: request.patterns.length > 0 ? request.patterns.join("\n") : request.permission,
|
|
808
|
+
args: request.metadata
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
for (const request of result.value.questions.data ?? []) {
|
|
813
|
+
if (context.resolvedRequestIds.has(request.id) || context.pendingQuestions.has(request.id) || !(yield* isRelatedOpenCodeSession(context, request.sessionID))) continue;
|
|
814
|
+
context.pendingQuestions.set(request.id, request);
|
|
815
|
+
yield* emitForContext(context, {
|
|
816
|
+
...yield* buildEventBase({
|
|
817
|
+
threadId: context.session.threadId,
|
|
818
|
+
turnId: context.activeTurnId,
|
|
819
|
+
requestId: request.id,
|
|
820
|
+
raw: {
|
|
821
|
+
type: "question.asked",
|
|
822
|
+
properties: request,
|
|
823
|
+
recovered: true
|
|
824
|
+
}
|
|
825
|
+
}),
|
|
826
|
+
type: "user-input.requested",
|
|
827
|
+
payload: { questions: normalizeQuestionRequest(request) }
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
});
|
|
723
833
|
const emitUnexpectedExit = Effect.fn("emitUnexpectedExit")(function* (context, message) {
|
|
724
834
|
if (yield* Ref.getAndSet(context.stopped, true)) return;
|
|
725
835
|
const turnId = context.activeTurnId;
|
|
@@ -822,8 +932,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
822
932
|
const eventSessionId = typeof payloadSessionId === "string" ? payloadSessionId : void 0;
|
|
823
933
|
const isRootSessionEvent = eventSessionId === context.openCodeSessionId;
|
|
824
934
|
const isKnownChildSessionEvent = eventSessionId !== void 0 && context.childSessionIds.has(eventSessionId);
|
|
825
|
-
const isChildSessionCreatedEvent = event.type === "session.created" && event.properties.info.parentID === context.openCodeSessionId;
|
|
826
|
-
|
|
935
|
+
const isChildSessionCreatedEvent = event.type === "session.created" && (event.properties.info.parentID === context.openCodeSessionId || event.properties.info.parentID !== void 0 && context.childSessionIds.has(event.properties.info.parentID));
|
|
936
|
+
const isRelatedRequestEvent = eventSessionId !== void 0 && isOpenCodeRequestEvent(event) && (yield* isRelatedOpenCodeSession(context, eventSessionId).pipe(Effect.orElseSucceed(() => false)));
|
|
937
|
+
if (!isRootSessionEvent && !isKnownChildSessionEvent && !isChildSessionCreatedEvent && !isRelatedRequestEvent) return;
|
|
827
938
|
const turnId = context.activeTurnId;
|
|
828
939
|
yield* writeNativeEventBestEffort(context.session.threadId, {
|
|
829
940
|
observedAt: nowIso(),
|
|
@@ -946,6 +1057,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
946
1057
|
break;
|
|
947
1058
|
}
|
|
948
1059
|
case "permission.asked":
|
|
1060
|
+
if (context.resolvedRequestIds.has(event.properties.id) || context.pendingPermissions.has(event.properties.id)) break;
|
|
949
1061
|
context.pendingPermissions.set(event.properties.id, event.properties);
|
|
950
1062
|
yield* emitForContext(context, {
|
|
951
1063
|
...yield* buildEventBase({
|
|
@@ -963,6 +1075,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
963
1075
|
});
|
|
964
1076
|
break;
|
|
965
1077
|
case "permission.replied":
|
|
1078
|
+
context.resolvedRequestIds.add(event.properties.requestID);
|
|
966
1079
|
context.pendingPermissions.delete(event.properties.requestID);
|
|
967
1080
|
yield* emitForContext(context, {
|
|
968
1081
|
...yield* buildEventBase({
|
|
@@ -979,6 +1092,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
979
1092
|
});
|
|
980
1093
|
break;
|
|
981
1094
|
case "question.asked":
|
|
1095
|
+
if (context.resolvedRequestIds.has(event.properties.id) || context.pendingQuestions.has(event.properties.id)) break;
|
|
982
1096
|
context.pendingQuestions.set(event.properties.id, event.properties);
|
|
983
1097
|
yield* emitForContext(context, {
|
|
984
1098
|
...yield* buildEventBase({
|
|
@@ -992,6 +1106,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
992
1106
|
});
|
|
993
1107
|
break;
|
|
994
1108
|
case "question.replied": {
|
|
1109
|
+
context.resolvedRequestIds.add(event.properties.requestID);
|
|
995
1110
|
const request = context.pendingQuestions.get(event.properties.requestID);
|
|
996
1111
|
context.pendingQuestions.delete(event.properties.requestID);
|
|
997
1112
|
const answers = Object.fromEntries((request?.questions ?? []).map((question, index) => [openCodeQuestionId(index, question), event.properties.answers[index]?.join(", ") ?? ""]));
|
|
@@ -1008,6 +1123,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1008
1123
|
break;
|
|
1009
1124
|
}
|
|
1010
1125
|
case "question.rejected":
|
|
1126
|
+
context.resolvedRequestIds.add(event.properties.requestID);
|
|
1011
1127
|
context.pendingQuestions.delete(event.properties.requestID);
|
|
1012
1128
|
yield* emitForContext(context, {
|
|
1013
1129
|
...yield* buildEventBase({
|
|
@@ -1059,7 +1175,13 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1059
1175
|
break;
|
|
1060
1176
|
}
|
|
1061
1177
|
if (event.properties.status.type === "idle" && turnId) {
|
|
1178
|
+
if (context.pendingPrompt?.turnId === turnId) {
|
|
1179
|
+
context.pendingPrompt.idleEvent = event;
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1062
1182
|
context.activeTurnId = void 0;
|
|
1183
|
+
context.activeAgent = void 0;
|
|
1184
|
+
context.activeVariant = void 0;
|
|
1063
1185
|
updateProviderSession(context, { status: "ready" }, { clearActiveTurnId: true });
|
|
1064
1186
|
yield* emitForContext(context, {
|
|
1065
1187
|
...yield* buildEventBase({
|
|
@@ -1095,7 +1217,14 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1095
1217
|
break;
|
|
1096
1218
|
}
|
|
1097
1219
|
const activeTurnId = context.activeTurnId;
|
|
1220
|
+
const pendingPrompt = context.pendingPrompt;
|
|
1221
|
+
if (pendingPrompt && pendingPrompt.turnId === activeTurnId) {
|
|
1222
|
+
context.pendingPrompt = void 0;
|
|
1223
|
+
yield* Fiber.interrupt(pendingPrompt.fiber).pipe(Effect.ignore);
|
|
1224
|
+
}
|
|
1098
1225
|
context.activeTurnId = void 0;
|
|
1226
|
+
context.activeAgent = void 0;
|
|
1227
|
+
context.activeVariant = void 0;
|
|
1099
1228
|
updateProviderSession(context, {
|
|
1100
1229
|
status: "error",
|
|
1101
1230
|
lastError: message
|
|
@@ -1160,6 +1289,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1160
1289
|
const serverUrl = openCodeSettings.serverUrl;
|
|
1161
1290
|
const serverPassword = openCodeSettings.serverPassword;
|
|
1162
1291
|
const directory = input.cwd ?? serverConfig.cwd;
|
|
1292
|
+
const resumeSessionId = input.resumePolicy === "fresh" ? void 0 : parseOpenCodeResume(input.resumeCursor)?.sessionId;
|
|
1163
1293
|
const existing = sessions.get(input.threadId);
|
|
1164
1294
|
if (existing) {
|
|
1165
1295
|
if (existing.session.runtimeSessionId === runtimeSessionId) return existing.session;
|
|
@@ -1178,16 +1308,23 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1178
1308
|
const sessionScope = yield* Scope.make();
|
|
1179
1309
|
if (deviceToolBinding) yield* Scope.addFinalizer(sessionScope, Effect.sync(() => deviceToolBinding.dispose()));
|
|
1180
1310
|
const startedExit = yield* Effect.exit(Effect.gen(function* () {
|
|
1181
|
-
const server = yield*
|
|
1311
|
+
const server = options?.serverOwner ? yield* options.serverOwner.acquire.pipe(Effect.map((process) => ({
|
|
1312
|
+
url: process.url,
|
|
1313
|
+
...process.serverPassword ? { serverPassword: process.serverPassword } : {},
|
|
1314
|
+
exitCode: process.exitCode,
|
|
1315
|
+
external: false
|
|
1316
|
+
}))) : yield* openCodeRuntime.connectToOpenCodeServer({
|
|
1182
1317
|
binaryPath,
|
|
1183
1318
|
serverUrl,
|
|
1319
|
+
...serverPassword ? { serverPassword } : {},
|
|
1184
1320
|
...options?.environment ? { environment: options.environment } : {}
|
|
1185
1321
|
});
|
|
1186
1322
|
const client = yield* openCodeRuntime.createOpenCodeSdkClient({
|
|
1187
1323
|
baseUrl: server.url,
|
|
1188
1324
|
directory,
|
|
1189
|
-
...server.
|
|
1325
|
+
...server.serverPassword ? { serverPassword: server.serverPassword } : {}
|
|
1190
1326
|
});
|
|
1327
|
+
yield* verifyOpenCodeServerVersion(client);
|
|
1191
1328
|
if (deviceToolBinding) yield* runOpenCodeSdk("mcp.add", () => client.mcp.add({
|
|
1192
1329
|
directory,
|
|
1193
1330
|
name: `ryco_device_${runtimeSessionId}`,
|
|
@@ -1199,13 +1336,18 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1199
1336
|
enabled: true
|
|
1200
1337
|
}
|
|
1201
1338
|
}));
|
|
1202
|
-
const
|
|
1339
|
+
const adoptedSession = resumeSessionId ? yield* runOpenCodeSdk("session.get", () => client.session.get({ sessionID: resumeSessionId })).pipe(Effect.map((response) => response.data), Effect.catchIf(isOpenCodeNotFound, () => Effect.succeed(void 0))) : void 0;
|
|
1340
|
+
if (adoptedSession) yield* runOpenCodeSdk("session.update", () => client.session.update({
|
|
1341
|
+
sessionID: adoptedSession.id,
|
|
1342
|
+
permission: buildOpenCodePermissionRules(input.runtimeMode)
|
|
1343
|
+
}));
|
|
1344
|
+
const openCodeSession = adoptedSession ? { data: adoptedSession } : yield* runOpenCodeSdk("session.create", () => client.session.create({
|
|
1203
1345
|
title: `Ryco ${input.threadId}`,
|
|
1204
1346
|
permission: buildOpenCodePermissionRules(input.runtimeMode)
|
|
1205
1347
|
}));
|
|
1206
1348
|
if (!openCodeSession.data) return yield* new OpenCodeRuntimeError({
|
|
1207
|
-
operation: "session.create",
|
|
1208
|
-
detail: "OpenCode session.create returned no session payload."
|
|
1349
|
+
operation: adoptedSession ? "session.get" : "session.create",
|
|
1350
|
+
detail: adoptedSession ? "OpenCode session.get returned no session payload." : "OpenCode session.create returned no session payload."
|
|
1209
1351
|
});
|
|
1210
1352
|
return {
|
|
1211
1353
|
sessionScope,
|
|
@@ -1238,6 +1380,10 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1238
1380
|
cwd: directory,
|
|
1239
1381
|
...input.modelSelection ? { model: input.modelSelection.model } : {},
|
|
1240
1382
|
threadId: input.threadId,
|
|
1383
|
+
resumeCursor: {
|
|
1384
|
+
schemaVersion: OPENCODE_RESUME_VERSION,
|
|
1385
|
+
sessionId: started.openCodeSession.id
|
|
1386
|
+
},
|
|
1241
1387
|
createdAt,
|
|
1242
1388
|
updatedAt: createdAt
|
|
1243
1389
|
};
|
|
@@ -1249,6 +1395,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1249
1395
|
openCodeSessionId: started.openCodeSession.id,
|
|
1250
1396
|
pendingPermissions: /* @__PURE__ */ new Map(),
|
|
1251
1397
|
pendingQuestions: /* @__PURE__ */ new Map(),
|
|
1398
|
+
resolvedRequestIds: /* @__PURE__ */ new Set(),
|
|
1252
1399
|
partById: /* @__PURE__ */ new Map(),
|
|
1253
1400
|
emittedTextByPartId: /* @__PURE__ */ new Map(),
|
|
1254
1401
|
messageRoleById: /* @__PURE__ */ new Map(),
|
|
@@ -1263,6 +1410,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1263
1410
|
activeTurnId: void 0,
|
|
1264
1411
|
activeAgent: void 0,
|
|
1265
1412
|
activeVariant: void 0,
|
|
1413
|
+
promptSemaphore: yield* Semaphore.make(1),
|
|
1414
|
+
pendingPrompt: void 0,
|
|
1415
|
+
promptGeneration: 0,
|
|
1266
1416
|
agentControlHostContextDelivered: false,
|
|
1267
1417
|
stopped: yield* Ref.make(false),
|
|
1268
1418
|
sessionScope: started.sessionScope
|
|
@@ -1280,138 +1430,193 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
1280
1430
|
payload: { providerThreadId: started.openCodeSession.id }
|
|
1281
1431
|
});
|
|
1282
1432
|
yield* startEventPump(context);
|
|
1283
|
-
yield*
|
|
1433
|
+
yield* Effect.gen(function* () {
|
|
1434
|
+
yield* hydrateOpenCodeChildSessions(context);
|
|
1435
|
+
yield* recoverPendingOpenCodeRequests(context);
|
|
1436
|
+
}).pipe(Effect.forkIn(context.sessionScope));
|
|
1284
1437
|
return session;
|
|
1285
1438
|
});
|
|
1286
1439
|
const sendTurn = Effect.fn("sendTurn")(function* (input) {
|
|
1287
1440
|
const context = ensureSessionContext(sessions, input.threadId);
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
} : void 0);
|
|
1293
|
-
if (modelSelection !== void 0 && modelSelection.instanceId !== boundInstanceId) return yield* new ProviderAdapterValidationError({
|
|
1294
|
-
provider: PROVIDER$1,
|
|
1295
|
-
operation: "sendTurn",
|
|
1296
|
-
issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
|
|
1297
|
-
});
|
|
1298
|
-
const parsedModel = parseOpenCodeModelSlug(modelSelection?.model);
|
|
1299
|
-
if (!parsedModel) return yield* new ProviderAdapterValidationError({
|
|
1300
|
-
provider: PROVIDER$1,
|
|
1301
|
-
operation: "sendTurn",
|
|
1302
|
-
issue: "OpenCode model selection must use the 'provider/model' format."
|
|
1303
|
-
});
|
|
1304
|
-
const formatted = formatSourceControlContextsForAgent(input.sourceControlContexts ?? []);
|
|
1305
|
-
let text = formatted ? formatted + "\n\n" + (input.input?.trim() ?? "") : input.input?.trim();
|
|
1306
|
-
const attachmentUrlById = /* @__PURE__ */ new Map();
|
|
1307
|
-
const declaredAttachmentBytes = (input.attachments ?? []).reduce((total, attachment) => total + attachment.sizeBytes, 0);
|
|
1308
|
-
if (declaredAttachmentBytes > 52428800) return yield* new ProviderAdapterRequestError({
|
|
1309
|
-
provider: PROVIDER$1,
|
|
1310
|
-
method: "session.prompt",
|
|
1311
|
-
detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
|
|
1312
|
-
});
|
|
1313
|
-
let attachmentTotalBytes = 0;
|
|
1314
|
-
for (const attachment of input.attachments ?? []) {
|
|
1315
|
-
const persisted = readPersistedAttachment({
|
|
1316
|
-
attachmentsDir: serverConfig.attachmentsDir,
|
|
1317
|
-
attachment
|
|
1441
|
+
return yield* context.promptSemaphore.withPermits(1)(Effect.gen(function* () {
|
|
1442
|
+
if (sessions.get(input.threadId) !== context || (yield* Ref.get(context.stopped))) return yield* new ProviderAdapterSessionClosedError({
|
|
1443
|
+
provider: PROVIDER$1,
|
|
1444
|
+
threadId: input.threadId
|
|
1318
1445
|
});
|
|
1319
|
-
|
|
1446
|
+
const turnId = TurnId.make(`opencode-turn-${yield* Effect.sync(() => crypto.randomUUID())}`);
|
|
1447
|
+
const modelSelection = input.modelSelection ?? (context.session.model ? {
|
|
1448
|
+
instanceId: boundInstanceId,
|
|
1449
|
+
model: context.session.model
|
|
1450
|
+
} : void 0);
|
|
1451
|
+
if (modelSelection !== void 0 && modelSelection.instanceId !== boundInstanceId) return yield* new ProviderAdapterValidationError({
|
|
1320
1452
|
provider: PROVIDER$1,
|
|
1321
|
-
|
|
1322
|
-
|
|
1453
|
+
operation: "sendTurn",
|
|
1454
|
+
issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
|
|
1323
1455
|
});
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1456
|
+
const parsedModel = parseOpenCodeModelSlug(modelSelection?.model);
|
|
1457
|
+
if (!parsedModel) return yield* new ProviderAdapterValidationError({
|
|
1458
|
+
provider: PROVIDER$1,
|
|
1459
|
+
operation: "sendTurn",
|
|
1460
|
+
issue: "OpenCode model selection must use the 'provider/model' format."
|
|
1461
|
+
});
|
|
1462
|
+
const formatted = formatSourceControlContextsForAgent(input.sourceControlContexts ?? []);
|
|
1463
|
+
let text = formatted ? formatted + "\n\n" + (input.input?.trim() ?? "") : input.input?.trim();
|
|
1464
|
+
const attachmentUrlById = /* @__PURE__ */ new Map();
|
|
1465
|
+
const declaredAttachmentBytes = (input.attachments ?? []).reduce((total, attachment) => total + attachment.sizeBytes, 0);
|
|
1466
|
+
if (declaredAttachmentBytes > 52428800) return yield* new ProviderAdapterRequestError({
|
|
1327
1467
|
provider: PROVIDER$1,
|
|
1328
1468
|
method: "session.prompt",
|
|
1329
|
-
detail: `Attachments total ${
|
|
1469
|
+
detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
|
|
1330
1470
|
});
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
context.activeVariant = variant;
|
|
1350
|
-
updateProviderSession(context, {
|
|
1351
|
-
status: "running",
|
|
1352
|
-
activeTurnId: turnId,
|
|
1353
|
-
model: modelSelection?.model ?? context.session.model
|
|
1354
|
-
}, { clearLastError: true });
|
|
1355
|
-
yield* emitForContext(context, {
|
|
1356
|
-
...yield* buildEventBase({
|
|
1357
|
-
threadId: input.threadId,
|
|
1358
|
-
turnId
|
|
1359
|
-
}),
|
|
1360
|
-
type: "turn.started",
|
|
1361
|
-
payload: {
|
|
1362
|
-
model: modelSelection?.model ?? context.session.model,
|
|
1363
|
-
...variant ? { effort: variant } : {}
|
|
1471
|
+
let attachmentTotalBytes = 0;
|
|
1472
|
+
for (const attachment of input.attachments ?? []) {
|
|
1473
|
+
const persisted = readPersistedAttachment({
|
|
1474
|
+
attachmentsDir: serverConfig.attachmentsDir,
|
|
1475
|
+
attachment
|
|
1476
|
+
});
|
|
1477
|
+
if (!persisted.ok) return yield* new ProviderAdapterRequestError({
|
|
1478
|
+
provider: PROVIDER$1,
|
|
1479
|
+
method: "session.prompt",
|
|
1480
|
+
detail: persisted.reason
|
|
1481
|
+
});
|
|
1482
|
+
attachmentUrlById.set(attachment.id, `data:${attachment.mimeType};base64,${persisted.bytes.toString("base64")}`);
|
|
1483
|
+
attachmentTotalBytes += persisted.sizeBytes;
|
|
1484
|
+
if (attachmentTotalBytes > 52428800) return yield* new ProviderAdapterRequestError({
|
|
1485
|
+
provider: PROVIDER$1,
|
|
1486
|
+
method: "session.prompt",
|
|
1487
|
+
detail: `Attachments total ${attachmentTotalBytes} bytes; limit is ${PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
|
|
1488
|
+
});
|
|
1364
1489
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1490
|
+
const fileParts = toOpenCodeFileParts({
|
|
1491
|
+
attachments: input.attachments,
|
|
1492
|
+
resolveAttachmentUrl: (attachment) => attachmentUrlById.get(attachment.id) ?? null
|
|
1493
|
+
});
|
|
1494
|
+
if ((!text || text.length === 0) && fileParts.length === 0) return yield* new ProviderAdapterValidationError({
|
|
1495
|
+
provider: PROVIDER$1,
|
|
1496
|
+
operation: "sendTurn",
|
|
1497
|
+
issue: "OpenCode turns require text input or at least one attachment."
|
|
1498
|
+
});
|
|
1499
|
+
if (!context.agentControlHostContextDelivered) {
|
|
1500
|
+
text = `<ryco_host_context>${agentControlHostContext(false)}</ryco_host_context>${text ? `\n\n${text}` : ""}`;
|
|
1501
|
+
context.agentControlHostContextDelivered = true;
|
|
1502
|
+
}
|
|
1503
|
+
const agent = getModelSelectionStringOptionValue(modelSelection, "agent");
|
|
1504
|
+
const variant = getModelSelectionStringOptionValue(modelSelection, "variant");
|
|
1505
|
+
context.activeTurnId = turnId;
|
|
1506
|
+
context.activeAgent = agent ?? (input.interactionMode === "plan" || input.interactionMode === "ask" ? "plan" : void 0);
|
|
1507
|
+
context.activeVariant = variant;
|
|
1379
1508
|
updateProviderSession(context, {
|
|
1380
|
-
status: "
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
}, {
|
|
1509
|
+
status: "running",
|
|
1510
|
+
activeTurnId: turnId,
|
|
1511
|
+
model: modelSelection?.model ?? context.session.model
|
|
1512
|
+
}, { clearLastError: true });
|
|
1384
1513
|
yield* emitForContext(context, {
|
|
1385
1514
|
...yield* buildEventBase({
|
|
1386
1515
|
threadId: input.threadId,
|
|
1387
1516
|
turnId
|
|
1388
1517
|
}),
|
|
1389
|
-
type: "turn.
|
|
1390
|
-
payload: {
|
|
1518
|
+
type: "turn.started",
|
|
1519
|
+
payload: {
|
|
1520
|
+
model: modelSelection?.model ?? context.session.model,
|
|
1521
|
+
...variant ? { effort: variant } : {}
|
|
1522
|
+
}
|
|
1391
1523
|
});
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1524
|
+
context.promptGeneration += 1;
|
|
1525
|
+
const generation = context.promptGeneration;
|
|
1526
|
+
const promptFiber = yield* runOpenCodeSdk("session.promptAsync", (signal) => context.client.session.promptAsync({
|
|
1527
|
+
sessionID: context.openCodeSessionId,
|
|
1528
|
+
model: parsedModel,
|
|
1529
|
+
...context.activeAgent ? { agent: context.activeAgent } : {},
|
|
1530
|
+
...context.activeVariant ? { variant: context.activeVariant } : {},
|
|
1531
|
+
parts: [...text ? [{
|
|
1532
|
+
type: "text",
|
|
1533
|
+
text
|
|
1534
|
+
}] : [], ...fileParts]
|
|
1535
|
+
}, { signal })).pipe(Effect.mapError(toRequestError), Effect.tapError((requestError) => context.activeTurnId === turnId && context.promptGeneration === generation ? Effect.gen(function* () {
|
|
1536
|
+
context.activeTurnId = void 0;
|
|
1537
|
+
context.activeAgent = void 0;
|
|
1538
|
+
context.activeVariant = void 0;
|
|
1539
|
+
updateProviderSession(context, {
|
|
1540
|
+
status: "ready",
|
|
1541
|
+
model: modelSelection?.model ?? context.session.model,
|
|
1542
|
+
lastError: requestError.detail
|
|
1543
|
+
}, { clearActiveTurnId: true });
|
|
1544
|
+
yield* emitForContext(context, {
|
|
1545
|
+
...yield* buildEventBase({
|
|
1546
|
+
threadId: input.threadId,
|
|
1547
|
+
turnId
|
|
1548
|
+
}),
|
|
1549
|
+
type: "turn.aborted",
|
|
1550
|
+
payload: { reason: requestError.detail }
|
|
1551
|
+
});
|
|
1552
|
+
}) : Effect.void)).pipe(Effect.forkIn(context.sessionScope));
|
|
1553
|
+
const pendingPrompt = {
|
|
1554
|
+
turnId,
|
|
1555
|
+
fiber: promptFiber
|
|
1556
|
+
};
|
|
1557
|
+
context.pendingPrompt = pendingPrompt;
|
|
1558
|
+
yield* Fiber.join(promptFiber).pipe(Effect.ensuring(Effect.sync(() => {
|
|
1559
|
+
if (context.pendingPrompt?.fiber === promptFiber) context.pendingPrompt = void 0;
|
|
1560
|
+
})));
|
|
1561
|
+
const completedDuringAdmission = pendingPrompt.idleEvent !== void 0;
|
|
1562
|
+
if (completedDuringAdmission && context.activeTurnId === turnId) {
|
|
1563
|
+
context.activeTurnId = void 0;
|
|
1564
|
+
context.activeAgent = void 0;
|
|
1565
|
+
context.activeVariant = void 0;
|
|
1566
|
+
updateProviderSession(context, { status: "ready" }, { clearActiveTurnId: true });
|
|
1567
|
+
yield* emitForContext(context, {
|
|
1568
|
+
...yield* buildEventBase({
|
|
1569
|
+
threadId: context.session.threadId,
|
|
1570
|
+
turnId,
|
|
1571
|
+
raw: pendingPrompt.idleEvent
|
|
1572
|
+
}),
|
|
1573
|
+
type: "turn.completed",
|
|
1574
|
+
payload: { state: "completed" }
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
if (sessions.get(input.threadId) !== context || (yield* Ref.get(context.stopped)) || !completedDuringAdmission && context.activeTurnId !== turnId || context.promptGeneration !== generation) return yield* Effect.interrupt;
|
|
1578
|
+
return {
|
|
1579
|
+
threadId: input.threadId,
|
|
1580
|
+
turnId,
|
|
1581
|
+
resumeCursor: context.session.resumeCursor
|
|
1582
|
+
};
|
|
1583
|
+
}));
|
|
1397
1584
|
});
|
|
1398
1585
|
const interruptTurn = Effect.fn("interruptTurn")(function* (threadId, turnId) {
|
|
1399
1586
|
const context = ensureSessionContext(sessions, threadId);
|
|
1400
|
-
const
|
|
1401
|
-
|
|
1587
|
+
const interruptedTurnId = turnId ?? context.activeTurnId;
|
|
1588
|
+
if (turnId !== void 0 && context.activeTurnId !== void 0 && turnId !== context.activeTurnId) return;
|
|
1589
|
+
const pendingPrompt = context.pendingPrompt;
|
|
1590
|
+
if (pendingPrompt && pendingPrompt.turnId === interruptedTurnId) {
|
|
1591
|
+
context.pendingPrompt = void 0;
|
|
1592
|
+
yield* Fiber.interrupt(pendingPrompt.fiber).pipe(Effect.ignore);
|
|
1593
|
+
}
|
|
1594
|
+
const rootAbortExit = yield* abortOpenCodeSession(context, context.openCodeSessionId).pipe(Effect.mapError(toRequestError), Effect.exit);
|
|
1595
|
+
yield* Effect.forEach(context.childSessionIds, (sessionID) => abortOpenCodeSession(context, sessionID).pipe(Effect.ignore({ log: true })), { discard: true });
|
|
1402
1596
|
yield* emitStoppedOpenCodeChildren(context, {
|
|
1403
1597
|
method: "session.abort",
|
|
1404
1598
|
reason: "turn-interrupted"
|
|
1405
1599
|
});
|
|
1406
1600
|
if (Exit.isFailure(rootAbortExit)) return yield* Effect.failCause(rootAbortExit.cause);
|
|
1407
|
-
if (
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1601
|
+
if (interruptedTurnId) {
|
|
1602
|
+
if (context.activeTurnId === interruptedTurnId) {
|
|
1603
|
+
context.activeTurnId = void 0;
|
|
1604
|
+
context.activeAgent = void 0;
|
|
1605
|
+
context.activeVariant = void 0;
|
|
1606
|
+
updateProviderSession(context, { status: "ready" }, {
|
|
1607
|
+
clearActiveTurnId: true,
|
|
1608
|
+
clearLastError: true
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1611
|
+
yield* emitForContext(context, {
|
|
1612
|
+
...yield* buildEventBase({
|
|
1613
|
+
threadId,
|
|
1614
|
+
turnId: interruptedTurnId
|
|
1615
|
+
}),
|
|
1616
|
+
type: "turn.aborted",
|
|
1617
|
+
payload: { reason: "Interrupted by user." }
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1415
1620
|
});
|
|
1416
1621
|
const respondToRequest = Effect.fn("respondToRequest")(function* (threadId, requestId, decision) {
|
|
1417
1622
|
const context = ensureSessionContext(sessions, threadId);
|
|
@@ -1520,7 +1725,6 @@ const OPENCODE_PRESENTATION = {
|
|
|
1520
1725
|
displayName: "OpenCode",
|
|
1521
1726
|
showInteractionModeToggle: false
|
|
1522
1727
|
};
|
|
1523
|
-
const MINIMUM_OPENCODE_VERSION = "1.14.19";
|
|
1524
1728
|
var OpenCodeProbeError = class extends Data.TaggedError("OpenCodeProbeError") {};
|
|
1525
1729
|
function normalizeProbeMessage(message) {
|
|
1526
1730
|
const trimmed = message.trim();
|
|
@@ -1736,7 +1940,7 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
1736
1940
|
if (versionExit._tag === "Failure") return fallback(Cause.squash(versionExit.cause));
|
|
1737
1941
|
version = parseGenericCliVersion(versionExit.value.stdout) ?? null;
|
|
1738
1942
|
if (!version) return fallback(/* @__PURE__ */ new Error(`Unable to determine OpenCode version from \`opencode --version\` output. Ryco requires OpenCode v${MINIMUM_OPENCODE_VERSION} or newer.`), null);
|
|
1739
|
-
if (compareCliVersions(version,
|
|
1943
|
+
if (compareCliVersions(version, "1.14.19") < 0) return buildServerProvider({
|
|
1740
1944
|
presentation: OPENCODE_PRESENTATION,
|
|
1741
1945
|
enabled: openCodeSettings.enabled,
|
|
1742
1946
|
checkedAt,
|
|
@@ -1754,6 +1958,7 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
1754
1958
|
const server = yield* openCodeRuntime.connectToOpenCodeServer({
|
|
1755
1959
|
binaryPath: openCodeSettings.binaryPath,
|
|
1756
1960
|
serverUrl: openCodeSettings.serverUrl,
|
|
1961
|
+
...openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {},
|
|
1757
1962
|
environment
|
|
1758
1963
|
}).pipe(Effect.mapError((cause) => new OpenCodeProbeError({
|
|
1759
1964
|
cause,
|
|
@@ -1762,19 +1967,27 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
1762
1967
|
const client = yield* openCodeRuntime.createOpenCodeSdkClient({
|
|
1763
1968
|
baseUrl: server.url,
|
|
1764
1969
|
directory: cwd,
|
|
1765
|
-
...
|
|
1970
|
+
...server.serverPassword ? { serverPassword: server.serverPassword } : {}
|
|
1766
1971
|
}).pipe(Effect.mapError((cause) => new OpenCodeProbeError({
|
|
1767
1972
|
cause,
|
|
1768
1973
|
detail: openCodeRuntimeErrorDetail(cause)
|
|
1769
1974
|
})));
|
|
1770
|
-
|
|
1975
|
+
const serverVersion = yield* verifyOpenCodeServerVersion(client).pipe(Effect.mapError((cause) => new OpenCodeProbeError({
|
|
1771
1976
|
cause,
|
|
1772
1977
|
detail: openCodeRuntimeErrorDetail(cause)
|
|
1773
1978
|
})));
|
|
1979
|
+
return {
|
|
1980
|
+
inventory: yield* openCodeRuntime.loadOpenCodeInventory(client).pipe(Effect.mapError((cause) => new OpenCodeProbeError({
|
|
1981
|
+
cause,
|
|
1982
|
+
detail: openCodeRuntimeErrorDetail(cause)
|
|
1983
|
+
}))),
|
|
1984
|
+
serverVersion
|
|
1985
|
+
};
|
|
1774
1986
|
})));
|
|
1775
1987
|
if (inventoryExit._tag === "Failure") return fallback(Cause.squash(inventoryExit.cause), version);
|
|
1776
|
-
|
|
1777
|
-
const
|
|
1988
|
+
version = inventoryExit.value.serverVersion;
|
|
1989
|
+
const models = providerModelsFromSettings(flattenOpenCodeModels(inventoryExit.value.inventory), PROVIDER, customModels, DEFAULT_OPENCODE_MODEL_CAPABILITIES);
|
|
1990
|
+
const connectedCount = new Set(inventoryExit.value.inventory.providerList.connected).size;
|
|
1778
1991
|
return buildServerProvider({
|
|
1779
1992
|
presentation: OPENCODE_PRESENTATION,
|
|
1780
1993
|
enabled: true,
|
|
@@ -1803,8 +2016,7 @@ const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatus")(fun
|
|
|
1803
2016
|
*
|
|
1804
2017
|
* Two instances with different `serverUrl`s therefore talk to independent
|
|
1805
2018
|
* OpenCode servers; when no `serverUrl` is set, the adapter + text-generation
|
|
1806
|
-
* shares
|
|
1807
|
-
* processes are released when the registry scope closes.
|
|
2019
|
+
* shares reuse one scoped child process owned by the provider instance.
|
|
1808
2020
|
*
|
|
1809
2021
|
* @module provider/Drivers/OpenCodeDriver
|
|
1810
2022
|
*/
|
|
@@ -1865,12 +2077,14 @@ const OpenCodeDriver = {
|
|
|
1865
2077
|
binaryPath: effectiveConfig.binaryPath,
|
|
1866
2078
|
env: processEnv
|
|
1867
2079
|
});
|
|
2080
|
+
const serverOwner = effectiveConfig.serverUrl.trim().length === 0 ? yield* makeOpenCodeServerOwner(effectiveConfig, processEnv) : void 0;
|
|
1868
2081
|
const adapter = yield* makeOpenCodeAdapter(effectiveConfig, {
|
|
1869
2082
|
instanceId,
|
|
1870
2083
|
environment: processEnv,
|
|
2084
|
+
...serverOwner ? { serverOwner } : {},
|
|
1871
2085
|
...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}
|
|
1872
2086
|
});
|
|
1873
|
-
const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv);
|
|
2087
|
+
const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv, serverOwner ? { serverOwner } : void 0);
|
|
1874
2088
|
const checkProvider = checkOpenCodeProviderStatus(effectiveConfig, serverConfig.cwd, processEnv).pipe(Effect.map(stampIdentity), Effect.provideService(OpenCodeRuntime, openCodeRuntime));
|
|
1875
2089
|
const snapshot = yield* makeManagedServerProvider({
|
|
1876
2090
|
maintenanceCapabilities,
|
|
@@ -1880,6 +2094,7 @@ const OpenCodeDriver = {
|
|
|
1880
2094
|
initialSnapshot: (settings) => stampIdentity(makePendingOpenCodeProvider(settings)),
|
|
1881
2095
|
checkProvider,
|
|
1882
2096
|
enrichSnapshot: ({ snapshot, publishSnapshot }) => enrichProviderSnapshotWithVersionAdvisory(snapshot, maintenanceCapabilities).pipe(Effect.provideService(HttpClient.HttpClient, httpClient), Effect.provideService(ServerSettingsService, serverSettings), Effect.flatMap((enrichedSnapshot) => publishSnapshot(enrichedSnapshot))),
|
|
2097
|
+
retainInventoryOnError: true,
|
|
1883
2098
|
refreshInterval: null
|
|
1884
2099
|
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
1885
2100
|
driver: DRIVER_KIND,
|