| ... | @@ -159,11 +159,6 @@ import * as ProjectStore from "./orchestration-v2/ProjectStore.ts"; | ... | @@ -159,11 +159,6 @@ import * as ProjectStore from "./orchestration-v2/ProjectStore.ts"; |
| 159 | import * as ThreadSearch from "./orchestration-v2/ThreadSearch.ts"; | 159 | import * as ThreadSearch from "./orchestration-v2/ThreadSearch.ts"; |
| 160 | import * as OrchestrationEventStore from "./persistence/OrchestrationEventStore.ts"; | 160 | import * as OrchestrationEventStore from "./persistence/OrchestrationEventStore.ts"; |
| 161 | import { userFacingDispatchErrorMessage } from "./orchestration-v2/UserFacingErrors.ts"; | 161 | import { userFacingDispatchErrorMessage } from "./orchestration-v2/UserFacingErrors.ts"; |
| 162 | import { | | |
| 163 | observeRpcEffect, | | |
| 164 | observeRpcStream, | | |
| 165 | observeRpcStreamEffect, | | |
| 166 | } from "./observability/RpcInstrumentation.ts"; | | |
| 167 | import * as ProviderRegistry from "./provider/ProviderRegistry.ts"; | 162 | import * as ProviderRegistry from "./provider/ProviderRegistry.ts"; |
| 168 | import * as ProviderInstanceRegistry from "./provider/ProviderInstanceRegistry.ts"; | 163 | import * as ProviderInstanceRegistry from "./provider/ProviderInstanceRegistry.ts"; |
| 169 | import * as AcpRegistrySupport from "./provider/acp/AcpRegistrySupport.ts"; | 164 | import * as AcpRegistrySupport from "./provider/acp/AcpRegistrySupport.ts"; |
| ... | @@ -215,6 +210,7 @@ import * as BackgroundPolicy from "./background/BackgroundPolicy.ts"; | ... | @@ -215,6 +210,7 @@ import * as BackgroundPolicy from "./background/BackgroundPolicy.ts"; |
| 215 | import * as EnvironmentAuth from "./auth/EnvironmentAuth.ts"; | 210 | import * as EnvironmentAuth from "./auth/EnvironmentAuth.ts"; |
| 216 | import { requiredScopeForDeviceList, rpcAuthorizationError } from "./auth/RpcAuthorization.ts"; | 211 | import { requiredScopeForDeviceList, rpcAuthorizationError } from "./auth/RpcAuthorization.ts"; |
| 217 | import * as RpcAuthorization from "./auth/RpcAuthorization.ts"; | 212 | import * as RpcAuthorization from "./auth/RpcAuthorization.ts"; |
| | 213 | import { RpcInstrumentation, rpcInstrumentationLayer } from "./observability/RpcInstrumentation.ts"; |
| 218 | import * as ProcessDiagnostics from "./diagnostics/ProcessDiagnostics.ts"; | 214 | import * as ProcessDiagnostics from "./diagnostics/ProcessDiagnostics.ts"; |
| 219 | import * as ProcessResourceMonitor from "./diagnostics/ProcessResourceMonitor.ts"; | 215 | import * as ProcessResourceMonitor from "./diagnostics/ProcessResourceMonitor.ts"; |
| 220 | import * as ResourceTelemetry from "./resourceTelemetry/ResourceTelemetry.ts"; | 216 | import * as ResourceTelemetry from "./resourceTelemetry/ResourceTelemetry.ts"; |
| ... | @@ -541,7 +537,8 @@ function projectFileFailureContext( | ... | @@ -541,7 +537,8 @@ function projectFileFailureContext( |
| 541 | | 537 | |
| 542 | const PROVIDER_STATUS_DEBOUNCE_MS = 200; | 538 | const PROVIDER_STATUS_DEBOUNCE_MS = 200; |
| 543 | | 539 | |
| 544 | const ServerWsRpcGroup = WsRpcGroup; | 540 | // Middleware added later wraps middleware added earlier, so instrumentation wraps authorization. |
| | 541 | const ServerWsRpcGroup = WsRpcGroup.middleware(RpcInstrumentation); |
| 545 | // When a resuming client's cursor is more than this many events behind the | 542 | // When a resuming client's cursor is more than this many events behind the |
| 546 | // current head, skip the per-event catch-up replay and send a fresh shell | 543 | // current head, skip the per-event catch-up replay and send a fresh shell |
| 547 | // snapshot instead. Replaying each intervening event costs a shell refetch; | 544 | // snapshot instead. Replaying each intervening event costs a shell refetch; |
| ... | @@ -1808,851 +1805,595 @@ const layerWsRpc = ( | ... | @@ -1808,851 +1805,595 @@ const layerWsRpc = ( |
| 1808 | | 1805 | |
| 1809 | const handlers = ServerWsRpcGroup.of({ | 1806 | const handlers = ServerWsRpcGroup.of({ |
| 1810 | [ORCHESTRATION_V2_WS_METHODS.dispatchCommand]: (command) => | 1807 | [ORCHESTRATION_V2_WS_METHODS.dispatchCommand]: (command) => |
| 1811 | observeRpcEffect( | 1808 | Effect.annotateCurrentSpan({ |
| 1812 | ORCHESTRATION_V2_WS_METHODS.dispatchCommand, | 1809 | "orchestration_v2.command_id": command.commandId, |
| 1813 | startup | 1810 | "orchestration_v2.command_type": command.type, |
| 1814 | .enqueueCommand( | 1811 | "orchestration_v2.thread_id": |
| 1815 | // A retry also restarts the preparation work the launch owns. | 1812 | command.type === "thread.fork" || command.type === "thread.merge_back" |
| 1816 | (command.type === "prepared-run.retry" | 1813 | ? command.targetThreadId |
| 1817 | ? threadLaunch.retryPreparation(command) | 1814 | : command.type === "delegated_task.request" || |
| 1818 | : ThreadMessageIntake.dispatchCommand( | 1815 | command.type === "delegated_task.wake-policy" || |
| 1819 | ThreadManagementService.withCreationProvenance(command, { | 1816 | command.type === "delegated_task.completion-delivery.acknowledge" || |
| 1820 | createdBy: "user", | 1817 | command.type === "delegated_task.completion-delivery.dispose" || |
| 1821 | creationSource: | 1818 | command.type === "thread.created.record" |
| 1822 | "creationSource" in command ? command.creationSource : "web", | 1819 | ? command.parentThreadId |
| 1823 | }), | 1820 | : command.threadId, |
| 1824 | ) | 1821 | ...(command.type === "thread.fork" || command.type === "thread.merge_back" |
| 1825 | ).pipe(Effect.provide(intakeContext)), | 1822 | ? { "orchestration_v2.source_thread_id": command.sourceThreadId } |
| 1826 | ) | 1823 | : {}), |
| 1827 | .pipe( | 1824 | }).pipe( |
| 1828 | Effect.tap(() => recordClientCommandAnalytics(command)), | 1825 | Effect.andThen( |
| 1829 | Effect.map((result) => ({ sequence: result.sequence })), | 1826 | startup |
| 1830 | Effect.mapError((cause) => { | 1827 | .enqueueCommand( |
| 1831 | const detail = userFacingDispatchErrorMessage(cause); | 1828 | // A retry also restarts the preparation work the launch owns. |
| 1832 | return new OrchestrationV2DispatchCommandError({ | 1829 | (command.type === "prepared-run.retry" |
| 1833 | commandId: command.commandId, | 1830 | ? threadLaunch.retryPreparation(command) |
| 1834 | commandType: command.type, | 1831 | : ThreadMessageIntake.dispatchCommand( |
| 1835 | message: detail ?? "Failed to dispatch orchestration V2 command", | 1832 | ThreadManagementService.withCreationProvenance(command, { |
| 1836 | ...(detail === undefined ? {} : { detail }), | 1833 | createdBy: "user", |
| 1837 | cause, | 1834 | creationSource: |
| 1838 | }); | 1835 | "creationSource" in command ? command.creationSource : "web", |
| 1839 | }), | 1836 | }), |
| 1840 | ), | 1837 | ) |
| 1841 | { | 1838 | ).pipe(Effect.provide(intakeContext)), |
| 1842 | "rpc.aggregate": "orchestrationV2", | 1839 | ) |
| 1843 | "orchestration_v2.command_id": command.commandId, | 1840 | .pipe( |
| 1844 | "orchestration_v2.command_type": command.type, | 1841 | Effect.tap(() => recordClientCommandAnalytics(command)), |
| 1845 | "orchestration_v2.thread_id": | 1842 | Effect.map((result) => ({ sequence: result.sequence })), |
| 1846 | command.type === "thread.fork" || command.type === "thread.merge_back" | 1843 | Effect.mapError((cause) => { |
| 1847 | ? command.targetThreadId | 1844 | const detail = userFacingDispatchErrorMessage(cause); |
| 1848 | : command.type === "delegated_task.request" || | 1845 | return new OrchestrationV2DispatchCommandError({ |
| 1849 | command.type === "delegated_task.wake-policy" || | 1846 | commandId: command.commandId, |
| 1850 | command.type === "delegated_task.completion-delivery.acknowledge" || | 1847 | commandType: command.type, |
| 1851 | command.type === "delegated_task.completion-delivery.dispose" || | 1848 | message: detail ?? "Failed to dispatch orchestration V2 command", |
| 1852 | command.type === "thread.created.record" | 1849 | ...(detail === undefined ? {} : { detail }), |
| 1853 | ? command.parentThreadId | 1850 | cause, |
| 1854 | : command.threadId, | 1851 | }); |
| 1855 | ...(command.type === "thread.fork" || command.type === "thread.merge_back" | 1852 | }), |
| 1856 | ? { "orchestration_v2.source_thread_id": command.sourceThreadId } | 1853 | ), |
| 1857 | : {}), | 1854 | ), |
| 1858 | }, | | |
| 1859 | ), | 1855 | ), |
| 1860 | [ORCHESTRATION_V2_WS_METHODS.getWorkflowScript]: (input) => | 1856 | [ORCHESTRATION_V2_WS_METHODS.getWorkflowScript]: (input) => |
| 1861 | observeRpcEffect( | 1857 | readWorkflowScript({ scriptPath: input.scriptPath }), |
| 1862 | ORCHESTRATION_V2_WS_METHODS.getWorkflowScript, | | |
| 1863 | readWorkflowScript({ scriptPath: input.scriptPath }), | | |
| 1864 | { "rpc.aggregate": "orchestration" }, | | |
| 1865 | ), | | |
| 1866 | [ORCHESTRATION_V2_WS_METHODS.getTurnItem]: (input) => | 1858 | [ORCHESTRATION_V2_WS_METHODS.getTurnItem]: (input) => |
| 1867 | observeRpcEffect( | 1859 | threadManagement.getTurnItem(input).pipe( |
| 1868 | ORCHESTRATION_V2_WS_METHODS.getTurnItem, | 1860 | Effect.mapError( |
| 1869 | threadManagement.getTurnItem(input).pipe( | 1861 | (cause) => |
| 1870 | Effect.mapError( | 1862 | new OrchestrationV2GetThreadProjectionError({ |
| 1871 | (cause) => | 1863 | threadId: input.threadId, |
| 1872 | new OrchestrationV2GetThreadProjectionError({ | 1864 | message: "Failed to load turn item", |
| 1873 | threadId: input.threadId, | 1865 | cause, |
| 1874 | message: "Failed to load turn item", | 1866 | }), |
| 1875 | cause, | | |
| 1876 | }), | | |
| 1877 | ), | | |
| 1878 | ), | 1867 | ), |
| 1879 | { "rpc.aggregate": "orchestration" }, | | |
| 1880 | ), | 1868 | ), |
| 1881 | [ORCHESTRATION_V2_WS_METHODS.getTurnDiff]: (input) => | 1869 | [ORCHESTRATION_V2_WS_METHODS.getTurnDiff]: (input) => |
| 1882 | observeRpcEffect( | 1870 | checkpointDiffQuery.getTurnDiff(input).pipe( |
| 1883 | ORCHESTRATION_V2_WS_METHODS.getTurnDiff, | 1871 | Effect.mapError( |
| 1884 | checkpointDiffQuery.getTurnDiff(input).pipe( | 1872 | (cause) => |
| 1885 | Effect.mapError( | 1873 | new OrchestrationGetTurnDiffError({ |
| 1886 | (cause) => | 1874 | message: "Failed to load turn diff", |
| 1887 | new OrchestrationGetTurnDiffError({ | 1875 | cause, |
| 1888 | message: "Failed to load turn diff", | 1876 | }), |
| 1889 | cause, | | |
| 1890 | }), | | |
| 1891 | ), | | |
| 1892 | ), | 1877 | ), |
| 1893 | { "rpc.aggregate": "orchestration" }, | | |
| 1894 | ), | 1878 | ), |
| 1895 | [ORCHESTRATION_V2_WS_METHODS.getFullThreadDiff]: (input) => | 1879 | [ORCHESTRATION_V2_WS_METHODS.getFullThreadDiff]: (input) => |
| 1896 | observeRpcEffect( | 1880 | checkpointDiffQuery.getFullThreadDiff(input).pipe( |
| 1897 | ORCHESTRATION_V2_WS_METHODS.getFullThreadDiff, | 1881 | Effect.mapError( |
| 1898 | checkpointDiffQuery.getFullThreadDiff(input).pipe( | 1882 | (cause) => |
| 1899 | Effect.mapError( | 1883 | new OrchestrationGetFullThreadDiffError({ |
| 1900 | (cause) => | 1884 | message: "Failed to load full thread diff", |
| 1901 | new OrchestrationGetFullThreadDiffError({ | 1885 | cause, |
| 1902 | message: "Failed to load full thread diff", | 1886 | }), |
| 1903 | cause, | | |
| 1904 | }), | | |
| 1905 | ), | | |
| 1906 | ), | 1887 | ), |
| 1907 | { "rpc.aggregate": "orchestration" }, | | |
| 1908 | ), | 1888 | ), |
| 1909 | [ORCHESTRATION_V2_WS_METHODS.searchThreads]: (input) => | 1889 | [ORCHESTRATION_V2_WS_METHODS.searchThreads]: (input) => |
| 1910 | observeRpcEffect( | 1890 | threadSearch.search(input).pipe( |
| 1911 | ORCHESTRATION_V2_WS_METHODS.searchThreads, | 1891 | Effect.mapError( |
| 1912 | threadSearch.search(input).pipe( | 1892 | (cause) => |
| 1913 | Effect.mapError( | 1893 | new OrchestrationSearchThreadsError({ |
| 1914 | (cause) => | 1894 | message: "Failed to search threads", |
| 1915 | new OrchestrationSearchThreadsError({ | 1895 | cause, |
| 1916 | message: "Failed to search threads", | 1896 | }), |
| 1917 | cause, | | |
| 1918 | }), | | |
| 1919 | ), | | |
| 1920 | ), | 1897 | ), |
| 1921 | { "rpc.aggregate": "orchestration" }, | | |
| 1922 | ), | 1898 | ), |
| 1923 | [ORCHESTRATION_V2_WS_METHODS.getArchivedShellSnapshot]: (_input) => | 1899 | [ORCHESTRATION_V2_WS_METHODS.getArchivedShellSnapshot]: (_input) => |
| 1924 | observeRpcEffect( | 1900 | getOrchestrationV2ArchivedShellSnapshot, |
| 1925 | ORCHESTRATION_V2_WS_METHODS.getArchivedShellSnapshot, | | |
| 1926 | getOrchestrationV2ArchivedShellSnapshot, | | |
| 1927 | { "rpc.aggregate": "orchestration" }, | | |
| 1928 | ), | | |
| 1929 | [ORCHESTRATION_V2_WS_METHODS.getThreadProjection]: (input) => | 1901 | [ORCHESTRATION_V2_WS_METHODS.getThreadProjection]: (input) => |
| 1930 | observeRpcEffect( | 1902 | Effect.annotateCurrentSpan({ "orchestration_v2.thread_id": input.threadId }).pipe( |
| 1931 | ORCHESTRATION_V2_WS_METHODS.getThreadProjection, | 1903 | Effect.andThen( |
| 1932 | // Pre-pagination clients still call this compatibility endpoint. | 1904 | // Pre-pagination clients still call this compatibility endpoint. |
| 1933 | // Keep stale clients from materializing an unbounded transcript. | 1905 | // Keep stale clients from materializing an unbounded transcript. |
| 1934 | threadManagement | 1906 | threadManagement |
| 1935 | .getThreadSnapshotWindow(input.threadId, { | 1907 | .getThreadSnapshotWindow(input.threadId, { |
| 1936 | rowLimit: THREAD_HISTORY_SNAPSHOT_ROW_LIMIT, | 1908 | rowLimit: THREAD_HISTORY_SNAPSHOT_ROW_LIMIT, |
| 1937 | }) | 1909 | }) |
| 1938 | .pipe( | 1910 | .pipe( |
| 1939 | Effect.map((snapshot) => | 1911 | Effect.map((snapshot) => |
| 1940 | projectThreadProjectionForWire( | 1912 | projectThreadProjectionForWire( |
| 1941 | buildBoundedThreadProjection({ | 1913 | buildBoundedThreadProjection({ |
| 1942 | projection: snapshot.projection, | 1914 | projection: snapshot.projection, |
| 1943 | snapshotSequence: snapshot.snapshotSequence, | 1915 | snapshotSequence: snapshot.snapshotSequence, |
| 1944 | }).projection, | 1916 | }).projection, |
| | 1917 | ), |
| | 1918 | ), |
| | 1919 | Effect.mapError( |
| | 1920 | (cause) => |
| | 1921 | new OrchestrationV2GetThreadProjectionError({ |
| | 1922 | threadId: input.threadId, |
| | 1923 | message: `Failed to load orchestration V2 thread ${input.threadId}`, |
| | 1924 | cause, |
| | 1925 | }), |
| 1945 | ), | 1926 | ), |
| 1946 | ), | 1927 | ), |
| 1947 | Effect.mapError( | 1928 | ), |
| 1948 | (cause) => | | |
| 1949 | new OrchestrationV2GetThreadProjectionError({ | | |
| 1950 | threadId: input.threadId, | | |
| 1951 | message: `Failed to load orchestration V2 thread ${input.threadId}`, | | |
| 1952 | cause, | | |
| 1953 | }), | | |
| 1954 | ), | | |
| 1955 | ), | | |
| 1956 | { | | |
| 1957 | "rpc.aggregate": "orchestrationV2", | | |
| 1958 | "orchestration_v2.thread_id": input.threadId, | | |
| 1959 | }, | | |
| 1960 | ), | 1929 | ), |
| 1961 | [ORCHESTRATION_V2_WS_METHODS.launchThread]: (input) => | 1930 | [ORCHESTRATION_V2_WS_METHODS.launchThread]: (input) => |
| 1962 | observeRpcEffect( | 1931 | Effect.annotateCurrentSpan({ |
| 1963 | ORCHESTRATION_V2_WS_METHODS.launchThread, | 1932 | "orchestration_v2.command_id": input.commandId, |
| 1964 | startup | 1933 | "orchestration_v2.project_id": input.projectId, |
| 1965 | .enqueueCommand( | 1934 | }).pipe( |
| 1966 | ThreadMessageIntake.launchThread({ | 1935 | Effect.andThen( |
| 1967 | commandId: input.commandId, | 1936 | startup |
| 1968 | ...(input.threadId === undefined ? {} : { threadId: input.threadId }), | 1937 | .enqueueCommand( |
| 1969 | ...(input.reuseExistingThread === undefined | 1938 | ThreadMessageIntake.launchThread({ |
| 1970 | ? {} | 1939 | commandId: input.commandId, |
| 1971 | : { reuseExistingThread: input.reuseExistingThread }), | 1940 | ...(input.threadId === undefined ? {} : { threadId: input.threadId }), |
| 1972 | projectId: input.projectId, | 1941 | ...(input.reuseExistingThread === undefined |
| 1973 | title: input.title, | 1942 | ? {} |
| 1974 | ...(input.generateTitle === undefined | 1943 | : { reuseExistingThread: input.reuseExistingThread }), |
| 1975 | ? {} | 1944 | projectId: input.projectId, |
| 1976 | : { generateTitle: input.generateTitle }), | 1945 | title: input.title, |
| 1977 | modelSelection: input.modelSelection, | 1946 | ...(input.generateTitle === undefined |
| 1978 | runtimeMode: input.runtimeMode, | 1947 | ? {} |
| 1979 | interactionMode: input.interactionMode, | 1948 | : { generateTitle: input.generateTitle }), |
| 1980 | workspaceStrategy: input.workspaceStrategy, | 1949 | modelSelection: input.modelSelection, |
| 1981 | ...(input.initialMessage === undefined | 1950 | runtimeMode: input.runtimeMode, |
| 1982 | ? {} | 1951 | interactionMode: input.interactionMode, |
| 1983 | : { | 1952 | workspaceStrategy: input.workspaceStrategy, |
| 1984 | initialMessage: { | 1953 | ...(input.initialMessage === undefined |
| 1985 | ...(input.initialMessage.messageId === undefined | 1954 | ? {} |
| 1986 | ? {} | 1955 | : { |
| 1987 | : { messageId: input.initialMessage.messageId }), | 1956 | initialMessage: { |
| 1988 | text: input.initialMessage.text, | 1957 | ...(input.initialMessage.messageId === undefined |
| 1989 | attachments: input.initialMessage.attachments, | 1958 | ? {} |
| 1990 | ...(input.initialMessage.context === undefined | 1959 | : { messageId: input.initialMessage.messageId }), |
| 1991 | ? {} | 1960 | text: input.initialMessage.text, |
| 1992 | : { context: input.initialMessage.context }), | 1961 | attachments: input.initialMessage.attachments, |
| 1993 | }, | 1962 | ...(input.initialMessage.context === undefined |
| 1994 | }), | 1963 | ? {} |
| 1995 | createdBy: "user", | 1964 | : { context: input.initialMessage.context }), |
| 1996 | creationSource: input.creationSource ?? "web", | 1965 | }, |
| 1997 | }).pipe(Effect.provide(intakeContext)), | 1966 | }), |
| 1998 | ) | 1967 | createdBy: "user", |
| 1999 | .pipe( | 1968 | creationSource: input.creationSource ?? "web", |
| 2000 | Effect.tap(() => | 1969 | }).pipe(Effect.provide(intakeContext)), |
| 2001 | analytics | 1970 | ) |
| 2002 | .record("client.thread.started", originProps) | 1971 | .pipe( |
| 2003 | .pipe( | 1972 | Effect.tap(() => |
| 2004 | Effect.andThen( | 1973 | analytics |
| 2005 | input.initialMessage === undefined | 1974 | .record("client.thread.started", originProps) |
| 2006 | ? Effect.void | 1975 | .pipe( |
| 2007 | : analytics.record("client.turn.requested", originProps), | 1976 | Effect.andThen( |
| | 1977 | input.initialMessage === undefined |
| | 1978 | ? Effect.void |
| | 1979 | : analytics.record("client.turn.requested", originProps), |
| | 1980 | ), |
| | 1981 | Effect.ignore, |
| 2008 | ), | 1982 | ), |
| 2009 | Effect.ignore, | 1983 | ), |
| 2010 | ), | 1984 | Effect.map((result) => ({ |
| | 1985 | ...result, |
| | 1986 | projection: projectThreadProjectionForWire(result.projection), |
| | 1987 | })), |
| | 1988 | Effect.catchTags({ |
| | 1989 | AttachmentClaimError: (cause) => |
| | 1990 | new OrchestrationV2ThreadLaunchError({ |
| | 1991 | commandId: input.commandId, |
| | 1992 | projectId: input.projectId, |
| | 1993 | message: cause.message, |
| | 1994 | cause, |
| | 1995 | }), |
| | 1996 | ThreadLaunchError: (cause) => |
| | 1997 | new OrchestrationV2ThreadLaunchError({ |
| | 1998 | commandId: input.commandId, |
| | 1999 | projectId: input.projectId, |
| | 2000 | message: "Failed to launch thread", |
| | 2001 | cause, |
| | 2002 | }), |
| | 2003 | ServerRuntimeStartupError: (cause) => |
| | 2004 | new OrchestrationV2ThreadLaunchError({ |
| | 2005 | commandId: input.commandId, |
| | 2006 | projectId: input.projectId, |
| | 2007 | message: "Failed to launch thread", |
| | 2008 | cause, |
| | 2009 | }), |
| | 2010 | }), |
| 2011 | ), | 2011 | ), |
| 2012 | Effect.map((result) => ({ | 2012 | ), |
| 2013 | ...result, | | |
| 2014 | projection: projectThreadProjectionForWire(result.projection), | | |
| 2015 | })), | | |
| 2016 | Effect.catchTags({ | | |
| 2017 | AttachmentClaimError: (cause) => | | |
| 2018 | new OrchestrationV2ThreadLaunchError({ | | |
| 2019 | commandId: input.commandId, | | |
| 2020 | projectId: input.projectId, | | |
| 2021 | message: cause.message, | | |
| 2022 | cause, | | |
| 2023 | }), | | |
| 2024 | ThreadLaunchError: (cause) => | | |
| 2025 | new OrchestrationV2ThreadLaunchError({ | | |
| 2026 | commandId: input.commandId, | | |
| 2027 | projectId: input.projectId, | | |
| 2028 | message: "Failed to launch thread", | | |
| 2029 | cause, | | |
| 2030 | }), | | |
| 2031 | ServerRuntimeStartupError: (cause) => | | |
| 2032 | new OrchestrationV2ThreadLaunchError({ | | |
| 2033 | commandId: input.commandId, | | |
| 2034 | projectId: input.projectId, | | |
| 2035 | message: "Failed to launch thread", | | |
| 2036 | cause, | | |
| 2037 | }), | | |
| 2038 | }), | | |
| 2039 | ), | | |
| 2040 | { | | |
| 2041 | "rpc.aggregate": "orchestration", | | |
| 2042 | "orchestration_v2.command_id": input.commandId, | | |
| 2043 | "orchestration_v2.project_id": input.projectId, | | |
| 2044 | }, | | |
| 2045 | ), | 2013 | ), |
| 2046 | [ORCHESTRATION_V2_WS_METHODS.subscribeArchivedShell]: (_input) => | 2014 | [ORCHESTRATION_V2_WS_METHODS.subscribeArchivedShell]: (_input) => |
| 2047 | observeRpcStreamEffect( | 2015 | Stream.unwrap(subscribeOrchestrationV2ArchivedShell()), |
| 2048 | ORCHESTRATION_V2_WS_METHODS.subscribeArchivedShell, | | |
| 2049 | subscribeOrchestrationV2ArchivedShell(), | | |
| 2050 | { "rpc.aggregate": "orchestration" }, | | |
| 2051 | ), | | |
| 2052 | [ORCHESTRATION_V2_WS_METHODS.subscribeShell]: (input) => | 2016 | [ORCHESTRATION_V2_WS_METHODS.subscribeShell]: (input) => |
| 2053 | observeRpcStreamEffect( | 2017 | Stream.unwrap(subscribeOrchestrationV2Shell(input)), |
| 2054 | ORCHESTRATION_V2_WS_METHODS.subscribeShell, | | |
| 2055 | subscribeOrchestrationV2Shell(input), | | |
| 2056 | { | | |
| 2057 | "rpc.aggregate": "orchestrationV2", | | |
| 2058 | }, | | |
| 2059 | ), | | |
| 2060 | [ORCHESTRATION_V2_WS_METHODS.subscribeThread]: (input) => | 2018 | [ORCHESTRATION_V2_WS_METHODS.subscribeThread]: (input) => |
| 2061 | observeRpcStreamEffect( | 2019 | Stream.unwrap( |
| 2062 | ORCHESTRATION_V2_WS_METHODS.subscribeThread, | 2020 | Effect.annotateCurrentSpan({ "orchestration_v2.thread_id": input.threadId }).pipe( |
| 2063 | subscribeOrchestrationV2Thread(input), | 2021 | Effect.andThen(subscribeOrchestrationV2Thread(input)), |
| 2064 | { | 2022 | ), |
| 2065 | "rpc.aggregate": "orchestrationV2", | | |
| 2066 | "orchestration_v2.thread_id": input.threadId, | | |
| 2067 | }, | | |
| 2068 | ), | 2023 | ), |
| 2069 | [WS_METHODS.scheduledTasksList]: (_input) => | 2024 | [WS_METHODS.scheduledTasksList]: (_input) => |
| 2070 | observeRpcEffect( | 2025 | scheduledTasks.list().pipe(Effect.map(withVisibleWebhookUrls)), |
| 2071 | WS_METHODS.scheduledTasksList, | | |
| 2072 | scheduledTasks.list().pipe(Effect.map(withVisibleWebhookUrls)), | | |
| 2073 | { "rpc.aggregate": "scheduledTasks" }, | | |
| 2074 | ), | | |
| 2075 | [WS_METHODS.scheduledTasksSubscribe]: (_input) => | 2026 | [WS_METHODS.scheduledTasksSubscribe]: (_input) => |
| 2076 | observeRpcStream( | 2027 | scheduledTasks.subscribeList().pipe(Stream.map(withVisibleWebhookUrls)), |
| 2077 | WS_METHODS.scheduledTasksSubscribe, | 2028 | [WS_METHODS.scheduledTasksUpsert]: (input) => scheduledTasks.upsert(input), |
| 2078 | scheduledTasks.subscribeList().pipe(Stream.map(withVisibleWebhookUrls)), | | |
| 2079 | { "rpc.aggregate": "scheduledTasks" }, | | |
| 2080 | ), | | |
| 2081 | [WS_METHODS.scheduledTasksUpsert]: (input) => | | |
| 2082 | observeRpcEffect(WS_METHODS.scheduledTasksUpsert, scheduledTasks.upsert(input), { | | |
| 2083 | "rpc.aggregate": "scheduledTasks", | | |
| 2084 | }), | | |
| 2085 | [WS_METHODS.scheduledTasksSetEnabled]: (input) => | 2029 | [WS_METHODS.scheduledTasksSetEnabled]: (input) => |
| 2086 | observeRpcEffect(WS_METHODS.scheduledTasksSetEnabled, scheduledTasks.setEnabled(input), { | 2030 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2087 | "rpc.aggregate": "scheduledTasks", | 2031 | Effect.andThen(scheduledTasks.setEnabled(input)), |
| 2088 | "scheduled_task.id": input.id, | 2032 | ), |
| 2089 | }), | | |
| 2090 | [WS_METHODS.scheduledTasksDelete]: (input) => | 2033 | [WS_METHODS.scheduledTasksDelete]: (input) => |
| 2091 | observeRpcEffect(WS_METHODS.scheduledTasksDelete, scheduledTasks.delete(input), { | 2034 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2092 | "rpc.aggregate": "scheduledTasks", | 2035 | Effect.andThen(scheduledTasks.delete(input)), |
| 2093 | "scheduled_task.id": input.id, | 2036 | ), |
| 2094 | }), | | |
| 2095 | [WS_METHODS.scheduledTasksRunNow]: (input) => | 2037 | [WS_METHODS.scheduledTasksRunNow]: (input) => |
| 2096 | observeRpcEffect(WS_METHODS.scheduledTasksRunNow, scheduledTasks.runNow(input), { | 2038 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2097 | "rpc.aggregate": "scheduledTasks", | 2039 | Effect.andThen(scheduledTasks.runNow(input)), |
| 2098 | "scheduled_task.id": input.id, | 2040 | ), |
| 2099 | }), | | |
| 2100 | [WS_METHODS.scheduledTasksRotateWebhookToken]: (input) => | 2041 | [WS_METHODS.scheduledTasksRotateWebhookToken]: (input) => |
| 2101 | observeRpcEffect( | 2042 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2102 | WS_METHODS.scheduledTasksRotateWebhookToken, | 2043 | Effect.andThen(scheduledTasks.rotateWebhookToken(input)), |
| 2103 | scheduledTasks.rotateWebhookToken(input), | | |
| 2104 | { "rpc.aggregate": "scheduledTasks", "scheduled_task.id": input.id }, | | |
| 2105 | ), | 2044 | ), |
| 2106 | [WS_METHODS.secretsAnswerRequest]: (input) => | 2045 | [WS_METHODS.secretsAnswerRequest]: (input) => |
| 2107 | observeRpcEffect(WS_METHODS.secretsAnswerRequest, secretRequests.answer(input), { | 2046 | Effect.annotateCurrentSpan({ "orchestration_v2.thread_id": input.threadId }).pipe( |
| 2108 | "rpc.aggregate": "secrets", | 2047 | Effect.andThen(secretRequests.answer(input)), |
| 2109 | "orchestration_v2.thread_id": input.threadId, | 2048 | ), |
| 2110 | }), | | |
| 2111 | [WS_METHODS.scheduledTasksListWebhookDeliveries]: (input) => | 2049 | [WS_METHODS.scheduledTasksListWebhookDeliveries]: (input) => |
| 2112 | observeRpcEffect( | 2050 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2113 | WS_METHODS.scheduledTasksListWebhookDeliveries, | 2051 | Effect.andThen(scheduledTasks.listWebhookDeliveries(input)), |
| 2114 | scheduledTasks.listWebhookDeliveries(input), | | |
| 2115 | { "rpc.aggregate": "scheduledTasks", "scheduled_task.id": input.id }, | | |
| 2116 | ), | 2052 | ), |
| 2117 | [WS_METHODS.scheduledTasksGetWebhookDelivery]: (input) => | 2053 | [WS_METHODS.scheduledTasksGetWebhookDelivery]: (input) => |
| 2118 | observeRpcEffect( | 2054 | Effect.annotateCurrentSpan({ "scheduled_task.id": input.id }).pipe( |
| 2119 | WS_METHODS.scheduledTasksGetWebhookDelivery, | 2055 | Effect.andThen(scheduledTasks.getWebhookDelivery(input)), |
| 2120 | scheduledTasks.getWebhookDelivery(input), | | |
| 2121 | { "rpc.aggregate": "scheduledTasks", "scheduled_task.id": input.id }, | | |
| 2122 | ), | | |
| 2123 | [WS_METHODS.serverProbe]: (_input) => | | |
| 2124 | observeRpcEffect(WS_METHODS.serverProbe, Effect.succeed({}), { | | |
| 2125 | "rpc.aggregate": "server", | | |
| 2126 | }), | | |
| 2127 | [WS_METHODS.serverGetConfig]: (_input) => | | |
| 2128 | observeRpcEffect( | | |
| 2129 | WS_METHODS.serverGetConfig, | | |
| 2130 | loadServerConfig({ usageLimitsCommand: false }), | | |
| 2131 | { | | |
| 2132 | "rpc.aggregate": "server", | | |
| 2133 | }, | | |
| 2134 | ), | 2056 | ), |
| | 2057 | [WS_METHODS.serverProbe]: (_input) => Effect.succeed({}), |
| | 2058 | [WS_METHODS.serverGetConfig]: (_input) => loadServerConfig({ usageLimitsCommand: false }), |
| 2135 | [WS_METHODS.serverSearchAcpRegistry]: (input) => | 2059 | [WS_METHODS.serverSearchAcpRegistry]: (input) => |
| 2136 | observeRpcEffect( | 2060 | acpRegistryCatalog |
| 2137 | WS_METHODS.serverSearchAcpRegistry, | 2061 | .search(input) |
| 2138 | acpRegistryCatalog | 2062 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), |
| 2139 | .search(input) | | |
| 2140 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), | | |
| 2141 | { "rpc.aggregate": "server" }, | | |
| 2142 | ), | | |
| 2143 | [WS_METHODS.serverPrepareAcpRegistryAgent]: (input) => | 2063 | [WS_METHODS.serverPrepareAcpRegistryAgent]: (input) => |
| 2144 | observeRpcEffect( | 2064 | Effect.annotateCurrentSpan({ "acp_registry.agent_id": input.agentId }).pipe( |
| 2145 | WS_METHODS.serverPrepareAcpRegistryAgent, | 2065 | Effect.andThen( |
| 2146 | acpRegistryCatalog | 2066 | acpRegistryCatalog |
| 2147 | .prepare(input) | 2067 | .prepare(input) |
| 2148 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), | 2068 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), |
| 2149 | { | 2069 | ), |
| 2150 | "rpc.aggregate": "server", | | |
| 2151 | "acp_registry.agent_id": input.agentId, | | |
| 2152 | }, | | |
| 2153 | ), | 2070 | ), |
| 2154 | [WS_METHODS.serverUninstallAcpRegistryManagedBinary]: (input) => | 2071 | [WS_METHODS.serverUninstallAcpRegistryManagedBinary]: (input) => |
| 2155 | observeRpcEffect( | 2072 | Effect.annotateCurrentSpan({ "acp_registry.agent_id": input.agentId }).pipe( |
| 2156 | WS_METHODS.serverUninstallAcpRegistryManagedBinary, | 2073 | Effect.andThen( |
| 2157 | acpRegistryCatalog | 2074 | acpRegistryCatalog |
| 2158 | .uninstallManagedBinary(input) | 2075 | .uninstallManagedBinary(input) |
| 2159 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), | 2076 | .pipe(Effect.mapError(AcpRegistrySupport.toAcpRegistryOperationError)), |
| 2160 | { | 2077 | ), |
| 2161 | "rpc.aggregate": "server", | | |
| 2162 | "acp_registry.agent_id": input.agentId, | | |
| 2163 | }, | | |
| 2164 | ), | 2078 | ), |
| 2165 | [WS_METHODS.serverAcceptAcpRegistryUrlAuth]: (input) => | 2079 | [WS_METHODS.serverAcceptAcpRegistryUrlAuth]: (input) => |
| 2166 | observeRpcEffect( | 2080 | Effect.annotateCurrentSpan({ "provider.instance_id": input.instanceId }).pipe( |
| 2167 | WS_METHODS.serverAcceptAcpRegistryUrlAuth, | 2081 | Effect.andThen( |
| 2168 | acpRegistryRuntimeCoordinator | 2082 | acpRegistryRuntimeCoordinator |
| 2169 | .acceptUrlAuthentication(input) | 2083 | .acceptUrlAuthentication(input) |
| 2170 | .pipe(Effect.map((accepted) => ({ accepted }))), | 2084 | .pipe(Effect.map((accepted) => ({ accepted }))), |
| 2171 | { | 2085 | ), |
| 2172 | "rpc.aggregate": "server", | | |
| 2173 | "provider.instance_id": input.instanceId, | | |
| 2174 | }, | | |
| 2175 | ), | 2086 | ), |
| 2176 | [WS_METHODS.serverListAcpRegistrySessions]: (input) => | 2087 | [WS_METHODS.serverListAcpRegistrySessions]: (input) => |
| 2177 | observeRpcEffect( | 2088 | Effect.annotateCurrentSpan({ |
| 2178 | WS_METHODS.serverListAcpRegistrySessions, | 2089 | "provider.instance_id": input.instanceId, |
| 2179 | listAcpRegistrySessions(input), | 2090 | "project.id": input.projectId, |
| 2180 | { | 2091 | }).pipe(Effect.andThen(listAcpRegistrySessions(input))), |
| 2181 | "rpc.aggregate": "server", | | |
| 2182 | "provider.instance_id": input.instanceId, | | |
| 2183 | "project.id": input.projectId, | | |
| 2184 | }, | | |
| 2185 | ), | | |
| 2186 | [WS_METHODS.serverImportAcpRegistrySession]: (input) => | 2092 | [WS_METHODS.serverImportAcpRegistrySession]: (input) => |
| 2187 | observeRpcEffect( | 2093 | Effect.annotateCurrentSpan({ |
| 2188 | WS_METHODS.serverImportAcpRegistrySession, | 2094 | "provider.instance_id": input.instanceId, |
| 2189 | importAcpRegistrySession(input), | 2095 | "project.id": input.projectId, |
| 2190 | { | 2096 | }).pipe(Effect.andThen(importAcpRegistrySession(input))), |
| 2191 | "rpc.aggregate": "server", | | |
| 2192 | "provider.instance_id": input.instanceId, | | |
| 2193 | "project.id": input.projectId, | | |
| 2194 | }, | | |
| 2195 | ), | | |
| 2196 | [WS_METHODS.serverDeleteAcpRegistrySession]: (input) => | 2097 | [WS_METHODS.serverDeleteAcpRegistrySession]: (input) => |
| 2197 | observeRpcEffect( | 2098 | Effect.annotateCurrentSpan({ |
| 2198 | WS_METHODS.serverDeleteAcpRegistrySession, | 2099 | "provider.instance_id": input.instanceId, |
| 2199 | deleteAcpRegistrySession(input), | 2100 | "project.id": input.projectId, |
| 2200 | { | 2101 | }).pipe(Effect.andThen(deleteAcpRegistrySession(input))), |
| 2201 | "rpc.aggregate": "server", | | |
| 2202 | "provider.instance_id": input.instanceId, | | |
| 2203 | "project.id": input.projectId, | | |
| 2204 | }, | | |
| 2205 | ), | | |
| 2206 | [WS_METHODS.serverListAcpRegistryProviders]: (input) => | 2102 | [WS_METHODS.serverListAcpRegistryProviders]: (input) => |
| 2207 | observeRpcEffect( | 2103 | Effect.annotateCurrentSpan({ |
| 2208 | WS_METHODS.serverListAcpRegistryProviders, | 2104 | "provider.instance_id": input.instanceId, |
| 2209 | listAcpRegistryProviders(input), | 2105 | "project.id": input.projectId, |
| 2210 | { | 2106 | }).pipe(Effect.andThen(listAcpRegistryProviders(input))), |
| 2211 | "rpc.aggregate": "server", | | |
| 2212 | "provider.instance_id": input.instanceId, | | |
| 2213 | "project.id": input.projectId, | | |
| 2214 | }, | | |
| 2215 | ), | | |
| 2216 | [WS_METHODS.serverSetAcpRegistryProvider]: (input) => | 2107 | [WS_METHODS.serverSetAcpRegistryProvider]: (input) => |
| 2217 | observeRpcEffect(WS_METHODS.serverSetAcpRegistryProvider, setAcpRegistryProvider(input), { | 2108 | Effect.annotateCurrentSpan({ |
| 2218 | "rpc.aggregate": "server", | | |
| 2219 | "provider.instance_id": input.instanceId, | 2109 | "provider.instance_id": input.instanceId, |
| 2220 | "project.id": input.projectId, | 2110 | "project.id": input.projectId, |
| 2221 | }), | 2111 | }).pipe(Effect.andThen(setAcpRegistryProvider(input))), |
| 2222 | [WS_METHODS.serverDisableAcpRegistryProvider]: (input) => | 2112 | [WS_METHODS.serverDisableAcpRegistryProvider]: (input) => |
| 2223 | observeRpcEffect( | 2113 | Effect.annotateCurrentSpan({ |
| 2224 | WS_METHODS.serverDisableAcpRegistryProvider, | 2114 | "provider.instance_id": input.instanceId, |
| 2225 | disableAcpRegistryProvider(input), | 2115 | "project.id": input.projectId, |
| 2226 | { | 2116 | }).pipe(Effect.andThen(disableAcpRegistryProvider(input))), |
| 2227 | "rpc.aggregate": "server", | | |
| 2228 | "provider.instance_id": input.instanceId, | | |
| 2229 | "project.id": input.projectId, | | |
| 2230 | }, | | |
| 2231 | ), | | |
| 2232 | [WS_METHODS.serverLogoutAcpRegistry]: (input) => | 2117 | [WS_METHODS.serverLogoutAcpRegistry]: (input) => |
| 2233 | observeRpcEffect( | 2118 | Effect.annotateCurrentSpan({ "provider.instance_id": input.instanceId }).pipe( |
| 2234 | WS_METHODS.serverLogoutAcpRegistry, | 2119 | Effect.andThen( |
| 2235 | Effect.gen(function* () { | 2120 | Effect.gen(function* () { |
| 2236 | const { instance, manager } = yield* acpSessionManager(input.instanceId); | 2121 | const { instance, manager } = yield* acpSessionManager(input.instanceId); |
| 2237 | const snapshot = yield* instance.snapshot.getSnapshot; | 2122 | const snapshot = yield* instance.snapshot.getSnapshot; |
| 2238 | if (snapshot.auth.canLogout !== true) { | 2123 | if (snapshot.auth.canLogout !== true) { |
| 2239 | return yield* new AcpRegistryOperationError({ | 2124 | return yield* new AcpRegistryOperationError({ |
| 2240 | reason: "logout_unsupported", | 2125 | reason: "logout_unsupported", |
| 2241 | message: "The ACP agent does not advertise logout.", | 2126 | message: "The ACP agent does not advertise logout.", |
| 2242 | }); | 2127 | }); |
| 2243 | } | 2128 | } |
| 2244 | if (instance.auth) { | 2129 | if (instance.auth) { |
| 2245 | yield* providerAuth.logout(input).pipe( | 2130 | yield* providerAuth.logout(input).pipe( |
| 2246 | Effect.mapError( | 2131 | Effect.mapError( |
| 2247 | (cause) => | 2132 | (cause) => |
| 2248 | new AcpRegistryOperationError({ | 2133 | new AcpRegistryOperationError({ |
| 2249 | reason: "logout_failed", | 2134 | reason: "logout_failed", |
| 2250 | message: "Could not sign out of the ACP agent.", | 2135 | message: "Could not sign out of the ACP agent.", |
| 2251 | cause, | 2136 | cause, |
| 2252 | }), | 2137 | }), |
| 2253 | ), | 2138 | ), |
| 2254 | ); | 2139 | ); |
| 2255 | } else { | 2140 | } else { |
| 2256 | yield* providerSessionManager.closeInstance(input.instanceId).pipe( | 2141 | yield* providerSessionManager.closeInstance(input.instanceId).pipe( |
| 2257 | Effect.mapError( | | |
| 2258 | (cause) => | | |
| 2259 | new AcpRegistryOperationError({ | | |
| 2260 | reason: "logout_failed", | | |
| 2261 | message: "Could not stop live sessions before ACP logout.", | | |
| 2262 | cause, | | |
| 2263 | }), | | |
| 2264 | ), | | |
| 2265 | ); | | |
| 2266 | yield* manager.logout(config.cwd); | | |
| 2267 | } | | |
| 2268 | yield* providerRegistry.refreshInstance(input.instanceId); | | |
| 2269 | return { loggedOut: true } as const; | | |
| 2270 | }), | | |
| 2271 | { | | |
| 2272 | "rpc.aggregate": "server", | | |
| 2273 | "provider.instance_id": input.instanceId, | | |
| 2274 | }, | | |
| 2275 | ), | | |
| 2276 | [WS_METHODS.serverRefreshProviders]: (input) => | | |
| 2277 | observeRpcEffect( | | |
| 2278 | WS_METHODS.serverRefreshProviders, | | |
| 2279 | Effect.gen(function* () { | | |
| 2280 | // Only explicit catalog refreshes bypass T3's caches. Workspace | | |
| 2281 | // discovery and background status checks retain their timers. | | |
| 2282 | if (input.refreshModels) { | | |
| 2283 | yield* modelManifest.forceRefresh; | | |
| 2284 | const instances = yield* providerInstances.listInstances; | | |
| 2285 | yield* Effect.forEach( | | |
| 2286 | instances.filter( | | |
| 2287 | (instance) => | | |
| 2288 | input.instanceId === undefined || input.instanceId === instance.instanceId, | | |
| 2289 | ), | | |
| 2290 | (instance) => | | |
| 2291 | Effect.gen(function* () { | | |
| 2292 | yield* instance.invalidateCaches ?? Effect.void; | | |
| 2293 | const maintenance = yield* instance.snapshot.resolveMaintenance({ | | |
| 2294 | fresh: true, | | |
| 2295 | }); | | |
| 2296 | if (maintenance.packageName) | | |
| 2297 | providerVersionCache.delete(maintenance.packageName); | | |
| 2298 | }), | | |
| 2299 | { concurrency: "unbounded", discard: true }, | | |
| 2300 | ); | | |
| 2301 | } | | |
| 2302 | // An untargeted refresh is "re-read everything's status", which | | |
| 2303 | // includes quota from configured usage-limit sources. Awaited, | | |
| 2304 | // not forked: the RPC scope closes on return and would | | |
| 2305 | // interrupt a fork before the hub answered. | | |
| 2306 | if (input.instanceId === undefined) { | | |
| 2307 | yield* usageLimitSources.refresh; | | |
| 2308 | } | | |
| 2309 | let providers = yield* input.cwd !== undefined && input.instanceId !== undefined | | |
| 2310 | ? providerRegistry.refreshWorkspaceSnapshot({ | | |
| 2311 | instanceId: input.instanceId, | | |
| 2312 | cwd: input.cwd, | | |
| 2313 | fresh: input.fresh === true, | | |
| 2314 | }) | | |
| 2315 | : input.instanceId !== undefined | | |
| 2316 | ? providerRegistry.refreshInstance(input.instanceId) | | |
| 2317 | : providerRegistry.refresh(); | | |
| 2318 | if (input.refreshModels) { | | |
| 2319 | const instances = yield* providerInstances.listInstances; | | |
| 2320 | for (const instance of instances) { | | |
| 2321 | if ( | | |
| 2322 | !instance.refreshModels || | | |
| 2323 | (input.instanceId !== undefined && input.instanceId !== instance.instanceId) || | | |
| 2324 | !providers.some( | | |
| 2325 | (provider) => | | |
| 2326 | provider.instanceId === instance.instanceId && | | |
| 2327 | provider.enabled && | | |
| 2328 | provider.installed, | | |
| 2329 | ) | | |
| 2330 | ) | | |
| 2331 | continue; | | |
| 2332 | yield* instance.refreshModels().pipe( | | |
| 2333 | Effect.mapError( | 2142 | Effect.mapError( |
| 2334 | (error) => | 2143 | (cause) => |
| 2335 | new ProviderSetupError({ | 2144 | new AcpRegistryOperationError({ |
| 2336 | instanceId: instance.instanceId, | 2145 | reason: "logout_failed", |
| 2337 | operation: "refresh-models", | 2146 | message: "Could not stop live sessions before ACP logout.", |
| 2338 | detail: error.detail, | 2147 | cause, |
| 2339 | }), | 2148 | }), |
| 2340 | ), | 2149 | ), |
| 2341 | ); | 2150 | ); |
| 2342 | providers = yield* providerRegistry.refreshInstance(instance.instanceId); | 2151 | yield* manager.logout(config.cwd); |
| 2343 | } | 2152 | } |
| 2344 | } | 2153 | yield* providerRegistry.refreshInstance(input.instanceId); |
| 2345 | return { providers }; | 2154 | return { loggedOut: true } as const; |
| 2346 | }), | 2155 | }), |
| 2347 | { "rpc.aggregate": "server" }, | 2156 | ), |
| 2348 | ), | 2157 | ), |
| 2349 | [WS_METHODS.providerUploadFeedback]: (input) => | 2158 | [WS_METHODS.serverRefreshProviders]: (input) => |
| 2350 | observeRpcEffect( | 2159 | Effect.gen(function* () { |
| 2351 | WS_METHODS.providerUploadFeedback, | 2160 | // Only explicit catalog refreshes bypass T3's caches. Workspace |
| 2352 | Effect.gen(function* () { | 2161 | // discovery and background status checks retain their timers. |
| 2353 | const projection = yield* threadManagement.getThreadRecords(input.threadId, [ | 2162 | if (input.refreshModels) { |
| 2354 | "providerThreads", | 2163 | yield* modelManifest.forceRefresh; |
| 2355 | ]); | 2164 | const instances = yield* providerInstances.listInstances; |
| 2356 | const providerThread = | 2165 | yield* Effect.forEach( |
| 2357 | projection.providerThreads.find( | 2166 | instances.filter( |
| 2358 | (candidate) => candidate.id === projection.thread.activeProviderThreadId, | 2167 | (instance) => |
| 2359 | ) ?? projection.providerThreads.at(-1); | 2168 | input.instanceId === undefined || input.instanceId === instance.instanceId, |
| 2360 | const providerSessionId = providerThread?.providerSessionId ?? null; | 2169 | ), |
| 2361 | if (providerThread === undefined || providerSessionId === null) { | 2170 | (instance) => |
| 2362 | return yield* Effect.fail( | 2171 | Effect.gen(function* () { |
| 2363 | new ProviderUploadFeedbackError({ | 2172 | yield* instance.invalidateCaches ?? Effect.void; |
| 2364 | threadId: input.threadId, | 2173 | const maintenance = yield* instance.snapshot.resolveMaintenance({ |
| 2365 | cause: "No provider session has run in this thread yet.", | 2174 | fresh: true, |
| | 2175 | }); |
| | 2176 | if (maintenance.packageName) |
| | 2177 | providerVersionCache.delete(maintenance.packageName); |
| 2366 | }), | 2178 | }), |
| | 2179 | { concurrency: "unbounded", discard: true }, |
| | 2180 | ); |
| | 2181 | } |
| | 2182 | // An untargeted refresh is "re-read everything's status", which |
| | 2183 | // includes quota from configured usage-limit sources. Awaited, |
| | 2184 | // not forked: the RPC scope closes on return and would |
| | 2185 | // interrupt a fork before the hub answered. |
| | 2186 | if (input.instanceId === undefined) { |
| | 2187 | yield* usageLimitSources.refresh; |
| | 2188 | } |
| | 2189 | let providers = yield* input.cwd !== undefined && input.instanceId !== undefined |
| | 2190 | ? providerRegistry.refreshWorkspaceSnapshot({ |
| | 2191 | instanceId: input.instanceId, |
| | 2192 | cwd: input.cwd, |
| | 2193 | fresh: input.fresh === true, |
| | 2194 | }) |
| | 2195 | : input.instanceId !== undefined |
| | 2196 | ? providerRegistry.refreshInstance(input.instanceId) |
| | 2197 | : providerRegistry.refresh(); |
| | 2198 | if (input.refreshModels) { |
| | 2199 | const instances = yield* providerInstances.listInstances; |
| | 2200 | for (const instance of instances) { |
| | 2201 | if ( |
| | 2202 | !instance.refreshModels || |
| | 2203 | (input.instanceId !== undefined && input.instanceId !== instance.instanceId) || |
| | 2204 | !providers.some( |
| | 2205 | (provider) => |
| | 2206 | provider.instanceId === instance.instanceId && |
| | 2207 | provider.enabled && |
| | 2208 | provider.installed, |
| | 2209 | ) |
| | 2210 | ) |
| | 2211 | continue; |
| | 2212 | yield* instance.refreshModels().pipe( |
| | 2213 | Effect.mapError( |
| | 2214 | (error) => |
| | 2215 | new ProviderSetupError({ |
| | 2216 | instanceId: instance.instanceId, |
| | 2217 | operation: "refresh-models", |
| | 2218 | detail: error.detail, |
| | 2219 | }), |
| | 2220 | ), |
| 2367 | ); | 2221 | ); |
| | 2222 | providers = yield* providerRegistry.refreshInstance(instance.instanceId); |
| 2368 | } | 2223 | } |
| 2369 | const runtime = Option.getOrNull(yield* providerSessionsV2.get(providerSessionId)); | 2224 | } |
| 2370 | if (runtime === null) { | 2225 | return { providers }; |
| 2371 | return yield* Effect.fail( | 2226 | }), |
| 2372 | new ProviderUploadFeedbackError({ | 2227 | [WS_METHODS.providerUploadFeedback]: (input) => |
| | 2228 | Effect.gen(function* () { |
| | 2229 | const projection = yield* threadManagement.getThreadRecords(input.threadId, [ |
| | 2230 | "providerThreads", |
| | 2231 | ]); |
| | 2232 | const providerThread = |
| | 2233 | projection.providerThreads.find( |
| | 2234 | (candidate) => candidate.id === projection.thread.activeProviderThreadId, |
| | 2235 | ) ?? projection.providerThreads.at(-1); |
| | 2236 | const providerSessionId = providerThread?.providerSessionId ?? null; |
| | 2237 | if (providerThread === undefined || providerSessionId === null) { |
| | 2238 | return yield* Effect.fail( |
| | 2239 | new ProviderUploadFeedbackError({ |
| | 2240 | threadId: input.threadId, |
| | 2241 | cause: "No provider session has run in this thread yet.", |
| | 2242 | }), |
| | 2243 | ); |
| | 2244 | } |
| | 2245 | const runtime = Option.getOrNull(yield* providerSessionsV2.get(providerSessionId)); |
| | 2246 | if (runtime === null) { |
| | 2247 | return yield* Effect.fail( |
| | 2248 | new ProviderUploadFeedbackError({ |
| | 2249 | threadId: input.threadId, |
| | 2250 | cause: "The provider session is no longer running. Send a message first.", |
| | 2251 | }), |
| | 2252 | ); |
| | 2253 | } |
| | 2254 | if (runtime.uploadFeedback === undefined) { |
| | 2255 | return yield* Effect.fail( |
| | 2256 | new ProviderUploadFeedbackError({ |
| | 2257 | threadId: input.threadId, |
| | 2258 | cause: `Provider '${runtime.driver}' does not support feedback uploads.`, |
| | 2259 | }), |
| | 2260 | ); |
| | 2261 | } |
| | 2262 | return yield* runtime.uploadFeedback({ |
| | 2263 | providerThread, |
| | 2264 | ...(input.reason === undefined ? {} : { reason: input.reason }), |
| | 2265 | }); |
| | 2266 | }).pipe( |
| | 2267 | Effect.mapError((cause) => |
| | 2268 | isProviderUploadFeedbackError(cause) |
| | 2269 | ? cause |
| | 2270 | : new ProviderUploadFeedbackError({ |
| 2373 | threadId: input.threadId, | 2271 | threadId: input.threadId, |
| 2374 | cause: "The provider session is no longer running. Send a message first.", | 2272 | cause, |
| 2375 | }), | 2273 | }), |
| 2376 | ); | | |
| 2377 | } | | |
| 2378 | if (runtime.uploadFeedback === undefined) { | | |
| 2379 | return yield* Effect.fail( | | |
| 2380 | new ProviderUploadFeedbackError({ | | |
| 2381 | threadId: input.threadId, | | |
| 2382 | cause: `Provider '${runtime.driver}' does not support feedback uploads.`, | | |
| 2383 | }), | | |
| 2384 | ); | | |
| 2385 | } | | |
| 2386 | return yield* runtime.uploadFeedback({ | | |
| 2387 | providerThread, | | |
| 2388 | ...(input.reason === undefined ? {} : { reason: input.reason }), | | |
| 2389 | }); | | |
| 2390 | }).pipe( | | |
| 2391 | Effect.mapError((cause) => | | |
| 2392 | isProviderUploadFeedbackError(cause) | | |
| 2393 | ? cause | | |
| 2394 | : new ProviderUploadFeedbackError({ | | |
| 2395 | threadId: input.threadId, | | |
| 2396 | cause, | | |
| 2397 | }), | | |
| 2398 | ), | | |
| 2399 | ), | 2274 | ), |
| 2400 | { "rpc.aggregate": "provider" }, | | |
| 2401 | ), | 2275 | ), |
| 2402 | [WS_METHODS.serverUpdateProvider]: (input) => | 2276 | [WS_METHODS.serverUpdateProvider]: (input) => |
| 2403 | observeRpcEffect( | 2277 | providerMaintenanceRunner.updateProvider(input), |
| 2404 | WS_METHODS.serverUpdateProvider, | | |
| 2405 | providerMaintenanceRunner.updateProvider(input), | | |
| 2406 | { | | |
| 2407 | "rpc.aggregate": "server", | | |
| 2408 | }, | | |
| 2409 | ), | | |
| 2410 | [WS_METHODS.providerConsumeResetCredit]: (input) => | 2278 | [WS_METHODS.providerConsumeResetCredit]: (input) => |
| 2411 | observeRpcEffect( | 2279 | Effect.gen(function* () { |
| 2412 | WS_METHODS.providerConsumeResetCredit, | 2280 | if ("sourceId" in input) return yield* usageLimitSources.consumeResetCredit(input); |
| 2413 | Effect.gen(function* () { | 2281 | const instance = yield* providerInstances.getInstance(input.instanceId); |
| 2414 | if ("sourceId" in input) return yield* usageLimitSources.consumeResetCredit(input); | 2282 | // A disabled instance must not spend anything on its account. |
| 2415 | const instance = yield* providerInstances.getInstance(input.instanceId); | 2283 | if (instance === undefined || !instance.enabled) { |
| 2416 | // A disabled instance must not spend anything on its account. | 2284 | return yield* new ProviderSetupError({ |
| 2417 | if (instance === undefined || !instance.enabled) { | 2285 | instanceId: input.instanceId, |
| 2418 | return yield* new ProviderSetupError({ | 2286 | operation: "consume-reset-credit", |
| 2419 | instanceId: input.instanceId, | 2287 | detail: instance ? "This provider is disabled." : "Provider instance not found.", |
| 2420 | operation: "consume-reset-credit", | 2288 | }); |
| 2421 | detail: instance ? "This provider is disabled." : "Provider instance not found.", | 2289 | } |
| 2422 | }); | 2290 | if (instance.consumeResetCredit === undefined) { |
| 2423 | } | 2291 | return yield* new ProviderSetupError({ |
| 2424 | if (instance.consumeResetCredit === undefined) { | 2292 | instanceId: input.instanceId, |
| 2425 | return yield* new ProviderSetupError({ | 2293 | operation: "consume-reset-credit", |
| 2426 | instanceId: input.instanceId, | 2294 | detail: "This provider does not bank reset credits.", |
| 2427 | operation: "consume-reset-credit", | 2295 | }); |
| 2428 | detail: "This provider does not bank reset credits.", | 2296 | } |
| 2429 | }); | 2297 | const outcome = yield* instance.consumeResetCredit().pipe( |
| 2430 | } | 2298 | Effect.mapError( |
| 2431 | const outcome = yield* instance.consumeResetCredit().pipe( | 2299 | (error) => |
| 2432 | Effect.mapError( | 2300 | new ProviderSetupError({ |
| 2433 | (error) => | 2301 | instanceId: input.instanceId, |
| 2434 | new ProviderSetupError({ | 2302 | operation: "consume-reset-credit", |
| 2435 | instanceId: input.instanceId, | 2303 | detail: error.detail, |
| 2436 | operation: "consume-reset-credit", | 2304 | cause: error, |
| 2437 | detail: error.detail, | 2305 | }), |
| 2438 | cause: error, | 2306 | ), |
| 2439 | }), | 2307 | ); |
| 2440 | ), | 2308 | return { outcome }; |
| 2441 | ); | 2309 | }), |
| 2442 | return { outcome }; | 2310 | [WS_METHODS.providerAuthStart]: (input) => providerAuth.start(input, currentSessionId), |
| 2443 | }), | | |
| 2444 | { "rpc.aggregate": "provider" }, | | |
| 2445 | ), | | |
| 2446 | [WS_METHODS.providerAuthStart]: (input) => | | |
| 2447 | observeRpcEffect( | | |
| 2448 | WS_METHODS.providerAuthStart, | | |
| 2449 | providerAuth.start(input, currentSessionId), | | |
| 2450 | { "rpc.aggregate": "provider" }, | | |
| 2451 | ), | | |
| 2452 | [WS_METHODS.providerAuthRespond]: (input) => | 2311 | [WS_METHODS.providerAuthRespond]: (input) => |
| 2453 | observeRpcEffect( | 2312 | Effect.annotateCurrentSpan({ instanceId: input.instanceId }).pipe( |
| 2454 | WS_METHODS.providerAuthRespond, | 2313 | Effect.andThen(providerAuth.respond(input, currentSessionId)), |
| 2455 | providerAuth.respond(input, currentSessionId), | | |
| 2456 | { | | |
| 2457 | "rpc.aggregate": "provider", | | |
| 2458 | instanceId: input.instanceId, | | |
| 2459 | }, | | |
| 2460 | ), | 2314 | ), |
| 2461 | [WS_METHODS.providerAuthComplete]: (input) => | 2315 | [WS_METHODS.providerAuthComplete]: (input) => |
| 2462 | observeRpcEffect( | 2316 | providerAuth.complete(input, currentSessionId), |
| 2463 | WS_METHODS.providerAuthComplete, | | |
| 2464 | providerAuth.complete(input, currentSessionId), | | |
| 2465 | { "rpc.aggregate": "provider" }, | | |
| 2466 | ), | | |
| 2467 | [WS_METHODS.chatGptReconnectProfile]: (input) => providerAuth.reconnectProfile(input), | 2317 | [WS_METHODS.chatGptReconnectProfile]: (input) => providerAuth.reconnectProfile(input), |
| 2468 | [WS_METHODS.chatGptImportProfile]: (input) => providerAuth.importProfile(input), | 2318 | [WS_METHODS.chatGptImportProfile]: (input) => providerAuth.importProfile(input), |
| 2469 | [WS_METHODS.chatGptHandoffSubscribe]: (input) => | 2319 | [WS_METHODS.chatGptHandoffSubscribe]: (input) => |
| 2470 | subscribeChatGptHandoff(input, currentSessionId), | 2320 | subscribeChatGptHandoff(input, currentSessionId), |
| 2471 | [WS_METHODS.codexAuthCallbackSubscribe]: (input) => | 2321 | [WS_METHODS.codexAuthCallbackSubscribe]: (input) => subscribeCodexAuthCallback(input), |
| 2472 | observeRpcStream( | 2322 | [WS_METHODS.providerAuthCancel]: (input) => providerAuth.cancel(input, currentSessionId), |
| 2473 | WS_METHODS.codexAuthCallbackSubscribe, | 2323 | [WS_METHODS.providerAuthLogout]: (input) => providerAuth.logout(input), |
| 2474 | subscribeCodexAuthCallback(input), | | |
| 2475 | { | | |
| 2476 | "rpc.aggregate": "provider", | | |
| 2477 | }, | | |
| 2478 | ), | | |
| 2479 | [WS_METHODS.providerAuthCancel]: (input) => | | |
| 2480 | observeRpcEffect( | | |
| 2481 | WS_METHODS.providerAuthCancel, | | |
| 2482 | providerAuth.cancel(input, currentSessionId), | | |
| 2483 | { "rpc.aggregate": "provider" }, | | |
| 2484 | ), | | |
| 2485 | [WS_METHODS.providerAuthLogout]: (input) => | | |
| 2486 | observeRpcEffect(WS_METHODS.providerAuthLogout, providerAuth.logout(input), { | | |
| 2487 | "rpc.aggregate": "provider", | | |
| 2488 | }), | | |
| 2489 | [WS_METHODS.providerAuthSubscribe]: (input) => | 2324 | [WS_METHODS.providerAuthSubscribe]: (input) => |
| 2490 | observeRpcStream( | 2325 | providerAuth.subscribe(input, currentSessionId), |
| 2491 | WS_METHODS.providerAuthSubscribe, | 2326 | [WS_METHODS.providerInstallStart]: (input) => providerInstallation.start(input), |
| 2492 | providerAuth.subscribe(input, currentSessionId), | 2327 | [WS_METHODS.providerInstallCancel]: (input) => providerInstallation.cancel(input), |
| 2493 | { "rpc.aggregate": "provider" }, | 2328 | [WS_METHODS.providerInstallSubscribe]: (input) => providerInstallation.subscribe(input), |
| 2494 | ), | 2329 | [WS_METHODS.providerInstallRemove]: (input) => providerInstallation.remove(input), |
| 2495 | [WS_METHODS.providerInstallStart]: (input) => | 2330 | [WS_METHODS.serverUpdateServer]: (input) => serverSelfUpdate.update(input), |
| 2496 | observeRpcEffect(WS_METHODS.providerInstallStart, providerInstallation.start(input), { | | |
| 2497 | "rpc.aggregate": "provider", | | |
| 2498 | }), | | |
| 2499 | [WS_METHODS.providerInstallCancel]: (input) => | | |
| 2500 | observeRpcEffect(WS_METHODS.providerInstallCancel, providerInstallation.cancel(input), { | | |
| 2501 | "rpc.aggregate": "provider", | | |
| 2502 | }), | | |
| 2503 | [WS_METHODS.providerInstallSubscribe]: (input) => | | |
| 2504 | observeRpcStream( | | |
| 2505 | WS_METHODS.providerInstallSubscribe, | | |
| 2506 | providerInstallation.subscribe(input), | | |
| 2507 | { "rpc.aggregate": "provider" }, | | |
| 2508 | ), | | |
| 2509 | [WS_METHODS.providerInstallRemove]: (input) => | | |
| 2510 | observeRpcEffect(WS_METHODS.providerInstallRemove, providerInstallation.remove(input), { | | |
| 2511 | "rpc.aggregate": "provider", | | |
| 2512 | }), | | |
| 2513 | [WS_METHODS.serverUpdateServer]: (input) => | | |
| 2514 | observeRpcEffect(WS_METHODS.serverUpdateServer, serverSelfUpdate.update(input), { | | |
| 2515 | "rpc.aggregate": "server", | | |
| 2516 | }), | | |
| 2517 | [WS_METHODS.serverUpdateServerWithProgress]: (input) => | 2331 | [WS_METHODS.serverUpdateServerWithProgress]: (input) => |
| 2518 | observeRpcStream( | 2332 | Stream.callback<ServerSelfUpdateProgressEvent, ServerSelfUpdateError>((queue) => |
| 2519 | WS_METHODS.serverUpdateServerWithProgress, | 2333 | serverSelfUpdate |
| 2520 | Stream.callback<ServerSelfUpdateProgressEvent, ServerSelfUpdateError>((queue) => | 2334 | .update(input, (stage) => |
| 2521 | serverSelfUpdate | 2335 | Queue.offer(queue, { |
| 2522 | .update(input, (stage) => | 2336 | type: "progress", |
| | 2337 | stage, |
| | 2338 | }).pipe(Effect.asVoid), |
| | 2339 | ) |
| | 2340 | .pipe( |
| | 2341 | Effect.flatMap((result) => |
| 2523 | Queue.offer(queue, { | 2342 | Queue.offer(queue, { |
| 2524 | type: "progress", | 2343 | type: "complete", |
| 2525 | stage, | 2344 | result, |
| 2526 | }).pipe(Effect.asVoid), | | |
| 2527 | ) | | |
| 2528 | .pipe( | | |
| 2529 | Effect.flatMap((result) => | | |
| 2530 | Queue.offer(queue, { | | |
| 2531 | type: "complete", | | |
| 2532 | result, | | |
| 2533 | }), | | |
| 2534 | ), | | |
| 2535 | Effect.catchTags({ | | |
| 2536 | ServerSelfUpdateError: (error) => Queue.fail(queue, error), | | |
| 2537 | }), | 2345 | }), |
| 2538 | Effect.andThen(Queue.end(queue)), | | |
| 2539 | Effect.forkScoped, | | |
| 2540 | ), | 2346 | ), |
| 2541 | ), | 2347 | Effect.catchTags({ |
| 2542 | { "rpc.aggregate": "server" }, | 2348 | ServerSelfUpdateError: (error) => Queue.fail(queue, error), |
| | 2349 | }), |
| | 2350 | Effect.andThen(Queue.end(queue)), |
| | 2351 | Effect.forkScoped, |
| | 2352 | ), |
| 2543 | ), | 2353 | ), |
| 2544 | [WS_METHODS.serverCommitDesktopUpdate]: (input) => | 2354 | [WS_METHODS.serverCommitDesktopUpdate]: (input) => |
| 2545 | observeRpcEffect( | 2355 | serverSelfUpdate.commitDesktopUpdate(input.requestId), |
| 2546 | WS_METHODS.serverCommitDesktopUpdate, | | |
| 2547 | serverSelfUpdate.commitDesktopUpdate(input.requestId), | | |
| 2548 | { "rpc.aggregate": "server" }, | | |
| 2549 | ), | | |
| 2550 | [WS_METHODS.serverUpsertKeybinding]: (rule) => | 2356 | [WS_METHODS.serverUpsertKeybinding]: (rule) => |
| 2551 | observeRpcEffect( | 2357 | Effect.gen(function* () { |
| 2552 | WS_METHODS.serverUpsertKeybinding, | 2358 | const keybindingsConfig = yield* keybindings.upsertKeybindingRule(rule); |
| 2553 | Effect.gen(function* () { | 2359 | return { keybindings: keybindingsConfig, issues: [] }; |
| 2554 | const keybindingsConfig = yield* keybindings.upsertKeybindingRule(rule); | 2360 | }), |
| 2555 | return { keybindings: keybindingsConfig, issues: [] }; | | |
| 2556 | }), | | |
| 2557 | { "rpc.aggregate": "server" }, | | |
| 2558 | ), | | |
| 2559 | [WS_METHODS.serverRemoveKeybinding]: (rule) => | 2361 | [WS_METHODS.serverRemoveKeybinding]: (rule) => |
| 2560 | observeRpcEffect( | 2362 | Effect.gen(function* () { |
| 2561 | WS_METHODS.serverRemoveKeybinding, | 2363 | const keybindingsConfig = yield* keybindings.removeKeybindingRule(rule); |
| 2562 | Effect.gen(function* () { | 2364 | return { keybindings: keybindingsConfig, issues: [] }; |
| 2563 | const keybindingsConfig = yield* keybindings.removeKeybindingRule(rule); | 2365 | }), |
| 2564 | return { keybindings: keybindingsConfig, issues: [] }; | | |
| 2565 | }), | | |
| 2566 | { "rpc.aggregate": "server" }, | | |
| 2567 | ), | | |
| 2568 | [WS_METHODS.serverGetSettings]: (_input) => | 2366 | [WS_METHODS.serverGetSettings]: (_input) => |
| 2569 | observeRpcEffect( | 2367 | serverSettings.getSettings.pipe(Effect.map(ServerSettings.redactServerSettingsForClient)), |
| 2570 | WS_METHODS.serverGetSettings, | | |
| 2571 | serverSettings.getSettings.pipe( | | |
| 2572 | Effect.map(ServerSettings.redactServerSettingsForClient), | | |
| 2573 | ), | | |
| 2574 | { | | |
| 2575 | "rpc.aggregate": "server", | | |
| 2576 | }, | | |
| 2577 | ), | | |
| 2578 | [WS_METHODS.serverUpdateSettings]: ({ patch, providerInstanceMutation }) => | 2368 | [WS_METHODS.serverUpdateSettings]: ({ patch, providerInstanceMutation }) => |
| 2579 | observeRpcEffect( | 2369 | Effect.gen(function* () { |
| 2580 | WS_METHODS.serverUpdateSettings, | 2370 | const deviceHosts = patch.deviceHosts |
| 2581 | Effect.gen(function* () { | 2371 | ? yield* remoteSshDeviceHosts(patch.deviceHosts).pipe( |
| 2582 | const deviceHosts = patch.deviceHosts | 2372 | Effect.provide(deviceHostContext), |
| 2583 | ? yield* remoteSshDeviceHosts(patch.deviceHosts).pipe( | 2373 | ) |
| 2584 | Effect.provide(deviceHostContext), | 2374 | : undefined; |
| 2585 | ) | 2375 | const nextPatch = { ...patch, ...(deviceHosts ? { deviceHosts } : {}) }; |
| 2586 | : undefined; | 2376 | const settings = yield* providerInstanceMutation === undefined |
| 2587 | const nextPatch = { ...patch, ...(deviceHosts ? { deviceHosts } : {}) }; | 2377 | ? serverSettings.updateSettings(nextPatch) |
| 2588 | const settings = yield* providerInstanceMutation === undefined | 2378 | : serverSettings.updateProviderInstance(providerInstanceMutation, nextPatch); |
| 2589 | ? serverSettings.updateSettings(nextPatch) | 2379 | return ServerSettings.redactServerSettingsForClient(settings); |
| 2590 | : serverSettings.updateProviderInstance(providerInstanceMutation, nextPatch); | | |
| 2591 | return ServerSettings.redactServerSettingsForClient(settings); | | |
| 2592 | }), | | |
| 2593 | { | | |
| 2594 | "rpc.aggregate": "server", | | |
| 2595 | }, | | |
| 2596 | ), | | |
| 2597 | [WS_METHODS.serverDiscoverSourceControl]: (_input) => | | |
| 2598 | observeRpcEffect( | | |
| 2599 | WS_METHODS.serverDiscoverSourceControl, | | |
| 2600 | sourceControlDiscovery.discover, | | |
| 2601 | { | | |
| 2602 | "rpc.aggregate": "server", | | |
| 2603 | }, | | |
| 2604 | ), | | |
| 2605 | [WS_METHODS.serverGetTraceDiagnostics]: (_input) => | | |
| 2606 | observeRpcEffect( | | |
| 2607 | WS_METHODS.serverGetTraceDiagnostics, | | |
| 2608 | TraceDiagnostics.readTraceDiagnostics({ | | |
| 2609 | traceFilePath: config.serverTracePath, | | |
| 2610 | maxFiles: config.traceMaxFiles, | | |
| 2611 | }), | | |
| 2612 | { | | |
| 2613 | "rpc.aggregate": "server", | | |
| 2614 | }, | | |
| 2615 | ), | | |
| 2616 | [WS_METHODS.serverGetProcessDiagnostics]: (_input) => | | |
| 2617 | observeRpcEffect(WS_METHODS.serverGetProcessDiagnostics, processDiagnostics.read, { | | |
| 2618 | "rpc.aggregate": "server", | | |
| 2619 | }), | 2380 | }), |
| 2620 | [WS_METHODS.serverGetHostResources]: (_input) => | 2381 | [WS_METHODS.serverDiscoverSourceControl]: (_input) => sourceControlDiscovery.discover, |
| 2621 | observeRpcEffect(WS_METHODS.serverGetHostResources, hostResources.read, { | 2382 | [WS_METHODS.serverGetTraceDiagnostics]: (_input) => |
| 2622 | "rpc.aggregate": "server", | 2383 | TraceDiagnostics.readTraceDiagnostics({ |
| | 2384 | traceFilePath: config.serverTracePath, |
| | 2385 | maxFiles: config.traceMaxFiles, |
| 2623 | }), | 2386 | }), |
| | 2387 | [WS_METHODS.serverGetProcessDiagnostics]: (_input) => processDiagnostics.read, |
| | 2388 | [WS_METHODS.serverGetHostResources]: (_input) => hostResources.read, |
| 2624 | [WS_METHODS.serverGetProcessResourceHistory]: (input) => | 2389 | [WS_METHODS.serverGetProcessResourceHistory]: (input) => |
| 2625 | observeRpcEffect( | 2390 | processResourceMonitor.readHistory(input), |
| 2626 | WS_METHODS.serverGetProcessResourceHistory, | | |
| 2627 | processResourceMonitor.readHistory(input), | | |
| 2628 | { | | |
| 2629 | "rpc.aggregate": "server", | | |
| 2630 | }, | | |
| 2631 | ), | | |
| 2632 | [WS_METHODS.serverGetResourceTelemetryHistory]: (input) => | 2391 | [WS_METHODS.serverGetResourceTelemetryHistory]: (input) => |
| 2633 | observeRpcEffect( | 2392 | resourceTelemetry.readHistory(input), |
| 2634 | WS_METHODS.serverGetResourceTelemetryHistory, | 2393 | [WS_METHODS.serverGetUsageSummary]: (input) => usage.readSummary(input), |
| 2635 | resourceTelemetry.readHistory(input), | 2394 | [WS_METHODS.serverRefreshUsageRates]: (_input) => usage.refreshRates, |
| 2636 | { | 2395 | [WS_METHODS.serverRetryResourceTelemetry]: (_input) => resourceTelemetry.retry, |
| 2637 | "rpc.aggregate": "server", | 2396 | [WS_METHODS.serverSignalProcess]: (input) => processDiagnostics.signal(input), |
| 2638 | }, | | |
| 2639 | ), | | |
| 2640 | [WS_METHODS.serverGetUsageSummary]: (input) => | | |
| 2641 | observeRpcEffect(WS_METHODS.serverGetUsageSummary, usage.readSummary(input), { | | |
| 2642 | "rpc.aggregate": "server", | | |
| 2643 | }), | | |
| 2644 | [WS_METHODS.serverRefreshUsageRates]: (_input) => | | |
| 2645 | observeRpcEffect(WS_METHODS.serverRefreshUsageRates, usage.refreshRates, { | | |
| 2646 | "rpc.aggregate": "server", | | |
| 2647 | }), | | |
| 2648 | [WS_METHODS.serverRetryResourceTelemetry]: (_input) => | | |
| 2649 | observeRpcEffect(WS_METHODS.serverRetryResourceTelemetry, resourceTelemetry.retry, { | | |
| 2650 | "rpc.aggregate": "server", | | |
| 2651 | }), | | |
| 2652 | [WS_METHODS.serverSignalProcess]: (input) => | | |
| 2653 | observeRpcEffect(WS_METHODS.serverSignalProcess, processDiagnostics.signal(input), { | | |
| 2654 | "rpc.aggregate": "server", | | |
| 2655 | }), | | |
| 2656 | [WS_METHODS.serverReportClientActivity]: (input, metadata) => | 2397 | [WS_METHODS.serverReportClientActivity]: (input, metadata) => |
| 2657 | Ref.update(rpcClientIds, (clientIds) => { | 2398 | Ref.update(rpcClientIds, (clientIds) => { |
| 2658 | const next = new Set(clientIds); | 2399 | const next = new Set(clientIds); |
| ... | @@ -2660,583 +2401,303 @@ const layerWsRpc = ( | ... | @@ -2660,583 +2401,303 @@ const layerWsRpc = ( |
| 2660 | return next; | 2401 | return next; |
| 2661 | }).pipe( | 2402 | }).pipe( |
| 2662 | Effect.andThen( | 2403 | Effect.andThen( |
| 2663 | observeRpcEffect( | 2404 | backgroundPolicy.reportClientActivity( |
| 2664 | WS_METHODS.serverReportClientActivity, | 2405 | currentSessionId, |
| 2665 | backgroundPolicy.reportClientActivity( | 2406 | RpcClientId.make(metadata.client.id), |
| 2666 | currentSessionId, | 2407 | input, |
| 2667 | RpcClientId.make(metadata.client.id), | | |
| 2668 | input, | | |
| 2669 | ), | | |
| 2670 | { "rpc.aggregate": "server" }, | | |
| 2671 | ), | 2408 | ), |
| 2672 | ), | 2409 | ), |
| 2673 | ), | 2410 | ), |
| 2674 | [WS_METHODS.serverReportHostPowerState]: (input) => | 2411 | [WS_METHODS.serverReportHostPowerState]: (input) => |
| 2675 | observeRpcEffect( | 2412 | backgroundPolicy.reportHostPowerState(input), |
| 2676 | WS_METHODS.serverReportHostPowerState, | 2413 | [WS_METHODS.serverGetBackgroundPolicy]: (_input) => backgroundPolicy.snapshot, |
| 2677 | backgroundPolicy.reportHostPowerState(input), | 2414 | [WS_METHODS.cloudGetRelayClientStatus]: (_input) => relayClient.resolve, |
| 2678 | { "rpc.aggregate": "server" }, | | |
| 2679 | ), | | |
| 2680 | [WS_METHODS.serverGetBackgroundPolicy]: (_input) => | | |
| 2681 | observeRpcEffect(WS_METHODS.serverGetBackgroundPolicy, backgroundPolicy.snapshot, { | | |
| 2682 | "rpc.aggregate": "server", | | |
| 2683 | }), | | |
| 2684 | [WS_METHODS.cloudGetRelayClientStatus]: (_input) => | | |
| 2685 | observeRpcEffect(WS_METHODS.cloudGetRelayClientStatus, relayClient.resolve, { | | |
| 2686 | "rpc.aggregate": "cloud", | | |
| 2687 | }), | | |
| 2688 | [WS_METHODS.cloudInstallRelayClient]: (_input) => | 2415 | [WS_METHODS.cloudInstallRelayClient]: (_input) => |
| 2689 | observeRpcStream( | 2416 | Stream.callback<RelayClientInstallProgressEvent, RelayClientInstallFailedError>((queue) => |
| 2690 | WS_METHODS.cloudInstallRelayClient, | 2417 | relayClient |
| 2691 | Stream.callback<RelayClientInstallProgressEvent, RelayClientInstallFailedError>( | 2418 | .installWithProgress((event) => Queue.offer(queue, event).pipe(Effect.asVoid)) |
| 2692 | (queue) => | 2419 | .pipe( |
| 2693 | relayClient | 2420 | Effect.flatMap((status) => |
| 2694 | .installWithProgress((event) => Queue.offer(queue, event).pipe(Effect.asVoid)) | 2421 | Queue.offer(queue, { |
| 2695 | .pipe( | 2422 | type: "complete", |
| 2696 | Effect.flatMap((status) => | 2423 | status, |
| 2697 | Queue.offer(queue, { | 2424 | }), |
| 2698 | type: "complete", | 2425 | ), |
| 2699 | status, | 2426 | Effect.catchTags({ |
| | 2427 | RelayClientInstallError: (error) => |
| | 2428 | Queue.fail( |
| | 2429 | queue, |
| | 2430 | new RelayClientInstallFailedError({ |
| | 2431 | reason: error.reason, |
| | 2432 | message: error.message, |
| 2700 | }), | 2433 | }), |
| 2701 | ), | 2434 | ), |
| 2702 | Effect.catchTags({ | 2435 | }), |
| 2703 | RelayClientInstallError: (error) => | 2436 | Effect.andThen(Queue.end(queue)), |
| 2704 | Queue.fail( | 2437 | Effect.forkScoped, |
| 2705 | queue, | 2438 | ), |
| 2706 | new RelayClientInstallFailedError({ | | |
| 2707 | reason: error.reason, | | |
| 2708 | message: error.message, | | |
| 2709 | }), | | |
| 2710 | ), | | |
| 2711 | }), | | |
| 2712 | Effect.andThen(Queue.end(queue)), | | |
| 2713 | Effect.forkScoped, | | |
| 2714 | ), | | |
| 2715 | ), | | |
| 2716 | { "rpc.aggregate": "cloud" }, | | |
| 2717 | ), | | |
| 2718 | [WS_METHODS.pullRequestsList]: (input) => | | |
| 2719 | observeRpcEffect(WS_METHODS.pullRequestsList, pullRequests.list(input), { | | |
| 2720 | "rpc.aggregate": "pull-requests", | | |
| 2721 | }), | | |
| 2722 | [WS_METHODS.pullRequestsListStats]: (input) => | | |
| 2723 | observeRpcEffect(WS_METHODS.pullRequestsListStats, pullRequests.listStats(input), { | | |
| 2724 | "rpc.aggregate": "pull-requests", | | |
| 2725 | }), | | |
| 2726 | [WS_METHODS.pullRequestsRoutingIdentity]: (input) => | | |
| 2727 | observeRpcEffect( | | |
| 2728 | WS_METHODS.pullRequestsRoutingIdentity, | | |
| 2729 | pullRequests.routingIdentity(input), | | |
| 2730 | { | | |
| 2731 | "rpc.aggregate": "pull-requests", | | |
| 2732 | }, | | |
| 2733 | ), | 2439 | ), |
| 2734 | [WS_METHODS.pullRequestsRouting]: (input) => | 2440 | [WS_METHODS.pullRequestsList]: (input) => pullRequests.list(input), |
| 2735 | observeRpcEffect(WS_METHODS.pullRequestsRouting, pullRequests.routing(input), { | 2441 | [WS_METHODS.pullRequestsListStats]: (input) => pullRequests.listStats(input), |
| 2736 | "rpc.aggregate": "pull-requests", | 2442 | [WS_METHODS.pullRequestsRoutingIdentity]: (input) => pullRequests.routingIdentity(input), |
| 2737 | }), | 2443 | [WS_METHODS.pullRequestsRouting]: (input) => pullRequests.routing(input), |
| 2738 | [WS_METHODS.pullRequestsSummary]: (input) => | 2444 | [WS_METHODS.pullRequestsSummary]: (input) => |
| 2739 | observeRpcEffect( | 2445 | withPullRequestViewer(input, pullRequests.summary(input)), |
| 2740 | WS_METHODS.pullRequestsSummary, | | |
| 2741 | withPullRequestViewer(input, pullRequests.summary(input)), | | |
| 2742 | { | | |
| 2743 | "rpc.aggregate": "pull-requests", | | |
| 2744 | }, | | |
| 2745 | ), | | |
| 2746 | [WS_METHODS.pullRequestsStack]: (input) => | 2446 | [WS_METHODS.pullRequestsStack]: (input) => |
| 2747 | observeRpcEffect( | 2447 | withPullRequestViewer(input, pullRequests.stack(input)), |
| 2748 | WS_METHODS.pullRequestsStack, | | |
| 2749 | withPullRequestViewer(input, pullRequests.stack(input)), | | |
| 2750 | { | | |
| 2751 | "rpc.aggregate": "pull-requests", | | |
| 2752 | }, | | |
| 2753 | ), | | |
| 2754 | [WS_METHODS.pullRequestsLinkedThreads]: (input) => | 2448 | [WS_METHODS.pullRequestsLinkedThreads]: (input) => |
| 2755 | observeRpcEffect( | 2449 | resolvePullRequestSyncKey(input).pipe( |
| 2756 | WS_METHODS.pullRequestsLinkedThreads, | 2450 | Effect.flatMap((key) => |
| 2757 | resolvePullRequestSyncKey(input).pipe( | 2451 | key === null |
| 2758 | Effect.flatMap((key) => | 2452 | ? Effect.succeed({ threads: [] }) |
| 2759 | key === null | 2453 | : listLinkedPullRequestThreads(key).pipe( |
| 2760 | ? Effect.succeed({ threads: [] }) | 2454 | Effect.provideService(SqlClient.SqlClient, sql), |
| 2761 | : listLinkedPullRequestThreads(key).pipe( | 2455 | ), |
| 2762 | Effect.provideService(SqlClient.SqlClient, sql), | | |
| 2763 | ), | | |
| 2764 | ), | | |
| 2765 | ), | 2456 | ), |
| 2766 | { "rpc.aggregate": "pull-requests" }, | | |
| 2767 | ), | 2457 | ), |
| 2768 | [WS_METHODS.pullRequestsDetail]: (input) => | 2458 | [WS_METHODS.pullRequestsDetail]: (input) => |
| 2769 | observeRpcEffect( | 2459 | withPullRequestViewer(input, pullRequests.detail(input)), |
| 2770 | WS_METHODS.pullRequestsDetail, | | |
| 2771 | withPullRequestViewer(input, pullRequests.detail(input)), | | |
| 2772 | { | | |
| 2773 | "rpc.aggregate": "pull-requests", | | |
| 2774 | }, | | |
| 2775 | ), | | |
| 2776 | [WS_METHODS.pullRequestsPreview]: (input) => | 2460 | [WS_METHODS.pullRequestsPreview]: (input) => |
| 2777 | observeRpcEffect( | 2461 | withPullRequestViewer(input, pullRequests.preview(input)), |
| 2778 | WS_METHODS.pullRequestsPreview, | | |
| 2779 | withPullRequestViewer(input, pullRequests.preview(input)), | | |
| 2780 | { "rpc.aggregate": "pull-requests" }, | | |
| 2781 | ), | | |
| 2782 | [WS_METHODS.pullRequestsChecks]: (input) => | 2462 | [WS_METHODS.pullRequestsChecks]: (input) => |
| 2783 | observeRpcEffect( | 2463 | withPullRequestViewer(input, pullRequests.checks(input)), |
| 2784 | WS_METHODS.pullRequestsChecks, | | |
| 2785 | withPullRequestViewer(input, pullRequests.checks(input)), | | |
| 2786 | { "rpc.aggregate": "pull-requests" }, | | |
| 2787 | ), | | |
| 2788 | [WS_METHODS.pullRequestsActivity]: (input) => | 2464 | [WS_METHODS.pullRequestsActivity]: (input) => |
| 2789 | observeRpcEffect( | 2465 | withPullRequestViewer(input, pullRequests.activity(input)), |
| 2790 | WS_METHODS.pullRequestsActivity, | | |
| 2791 | withPullRequestViewer(input, pullRequests.activity(input)), | | |
| 2792 | { | | |
| 2793 | "rpc.aggregate": "pull-requests", | | |
| 2794 | }, | | |
| 2795 | ), | | |
| 2796 | [WS_METHODS.pullRequestsThreadComments]: (input) => | 2466 | [WS_METHODS.pullRequestsThreadComments]: (input) => |
| 2797 | observeRpcEffect( | 2467 | withPullRequestViewer(input, pullRequests.threadComments(input)), |
| 2798 | WS_METHODS.pullRequestsThreadComments, | | |
| 2799 | withPullRequestViewer(input, pullRequests.threadComments(input)), | | |
| 2800 | { | | |
| 2801 | "rpc.aggregate": "pull-requests", | | |
| 2802 | }, | | |
| 2803 | ), | | |
| 2804 | [WS_METHODS.pullRequestsDiffFileContents]: (input) => | 2468 | [WS_METHODS.pullRequestsDiffFileContents]: (input) => |
| 2805 | observeRpcEffect( | 2469 | withPullRequestViewer(input, pullRequests.diffFileContents(input)), |
| 2806 | WS_METHODS.pullRequestsDiffFileContents, | | |
| 2807 | withPullRequestViewer(input, pullRequests.diffFileContents(input)), | | |
| 2808 | { "rpc.aggregate": "pull-requests" }, | | |
| 2809 | ), | | |
| 2810 | [WS_METHODS.pullRequestsFilesViewed]: (input) => | 2470 | [WS_METHODS.pullRequestsFilesViewed]: (input) => |
| 2811 | observeRpcEffect( | 2471 | withPullRequestViewer(input, pullRequests.filesViewed(input)), |
| 2812 | WS_METHODS.pullRequestsFilesViewed, | | |
| 2813 | withPullRequestViewer(input, pullRequests.filesViewed(input)), | | |
| 2814 | { "rpc.aggregate": "pull-requests" }, | | |
| 2815 | ), | | |
| 2816 | [WS_METHODS.pullRequestsSetFilesViewed]: (input) => | 2472 | [WS_METHODS.pullRequestsSetFilesViewed]: (input) => |
| 2817 | observeRpcEffect( | 2473 | withPullRequestViewer(input, pullRequests.setFilesViewed(input)), |
| 2818 | WS_METHODS.pullRequestsSetFilesViewed, | | |
| 2819 | withPullRequestViewer(input, pullRequests.setFilesViewed(input)), | | |
| 2820 | { "rpc.aggregate": "pull-requests" }, | | |
| 2821 | ), | | |
| 2822 | [WS_METHODS.pullRequestsRunAction]: (input) => | 2474 | [WS_METHODS.pullRequestsRunAction]: (input) => |
| 2823 | observeRpcEffect( | 2475 | withPullRequestViewer(input, pullRequests.runAction(input)).pipe( |
| 2824 | WS_METHODS.pullRequestsRunAction, | 2476 | Effect.tap(() => |
| 2825 | withPullRequestViewer(input, pullRequests.runAction(input)).pipe( | 2477 | resolvePullRequestSyncKey(input).pipe( |
| 2826 | Effect.tap(() => | 2478 | Effect.flatMap((key) => |
| 2827 | resolvePullRequestSyncKey(input).pipe( | 2479 | key === null ? Effect.void : pullRequestSync.requestSync(key), |
| 2828 | Effect.flatMap((key) => | | |
| 2829 | key === null ? Effect.void : pullRequestSync.requestSync(key), | | |
| 2830 | ), | | |
| 2831 | ), | 2480 | ), |
| 2832 | ), | 2481 | ), |
| 2833 | ), | 2482 | ), |
| 2834 | { "rpc.aggregate": "pull-requests" }, | | |
| 2835 | ), | 2483 | ), |
| 2836 | [WS_METHODS.pullRequestsUpdate]: (input) => | 2484 | [WS_METHODS.pullRequestsUpdate]: (input) => |
| 2837 | observeRpcEffect( | 2485 | withPullRequestViewer(input, pullRequests.update(input)), |
| 2838 | WS_METHODS.pullRequestsUpdate, | | |
| 2839 | withPullRequestViewer(input, pullRequests.update(input)), | | |
| 2840 | { | | |
| 2841 | "rpc.aggregate": "pull-requests", | | |
| 2842 | }, | | |
| 2843 | ), | | |
| 2844 | [WS_METHODS.pullRequestsComment]: (input) => | 2486 | [WS_METHODS.pullRequestsComment]: (input) => |
| 2845 | observeRpcEffect( | 2487 | withPullRequestViewer(input, pullRequests.comment(input)), |
| 2846 | WS_METHODS.pullRequestsComment, | | |
| 2847 | withPullRequestViewer(input, pullRequests.comment(input)), | | |
| 2848 | { | | |
| 2849 | "rpc.aggregate": "pull-requests", | | |
| 2850 | }, | | |
| 2851 | ), | | |
| 2852 | [WS_METHODS.pullRequestsUpdateComment]: (input) => | 2488 | [WS_METHODS.pullRequestsUpdateComment]: (input) => |
| 2853 | observeRpcEffect( | 2489 | withPullRequestViewer(input, pullRequests.updateComment(input)), |
| 2854 | WS_METHODS.pullRequestsUpdateComment, | | |
| 2855 | withPullRequestViewer(input, pullRequests.updateComment(input)), | | |
| 2856 | { | | |
| 2857 | "rpc.aggregate": "pull-requests", | | |
| 2858 | }, | | |
| 2859 | ), | | |
| 2860 | [WS_METHODS.pullRequestsSubmitReview]: (input) => | 2490 | [WS_METHODS.pullRequestsSubmitReview]: (input) => |
| 2861 | observeRpcEffect( | 2491 | withPullRequestViewer(input, pullRequests.submitReview(input)), |
| 2862 | WS_METHODS.pullRequestsSubmitReview, | | |
| 2863 | withPullRequestViewer(input, pullRequests.submitReview(input)), | | |
| 2864 | { | | |
| 2865 | "rpc.aggregate": "pull-requests", | | |
| 2866 | }, | | |
| 2867 | ), | | |
| 2868 | [WS_METHODS.pullRequestsReplyToThread]: (input) => | 2492 | [WS_METHODS.pullRequestsReplyToThread]: (input) => |
| 2869 | observeRpcEffect( | 2493 | withPullRequestViewer(input, pullRequests.replyToThread(input)), |
| 2870 | WS_METHODS.pullRequestsReplyToThread, | | |
| 2871 | withPullRequestViewer(input, pullRequests.replyToThread(input)), | | |
| 2872 | { "rpc.aggregate": "pull-requests" }, | | |
| 2873 | ), | | |
| 2874 | [WS_METHODS.pullRequestsSetThreadResolution]: (input) => | 2494 | [WS_METHODS.pullRequestsSetThreadResolution]: (input) => |
| 2875 | observeRpcEffect( | 2495 | withPullRequestViewer(input, pullRequests.setThreadResolution(input)), |
| 2876 | WS_METHODS.pullRequestsSetThreadResolution, | | |
| 2877 | withPullRequestViewer(input, pullRequests.setThreadResolution(input)), | | |
| 2878 | { "rpc.aggregate": "pull-requests" }, | | |
| 2879 | ), | | |
| 2880 | [WS_METHODS.pullRequestsSetReaction]: (input) => | 2496 | [WS_METHODS.pullRequestsSetReaction]: (input) => |
| 2881 | observeRpcEffect( | 2497 | withPullRequestViewer(input, pullRequests.setReaction(input)), |
| 2882 | WS_METHODS.pullRequestsSetReaction, | | |
| 2883 | withPullRequestViewer(input, pullRequests.setReaction(input)), | | |
| 2884 | { | | |
| 2885 | "rpc.aggregate": "pull-requests", | | |
| 2886 | }, | | |
| 2887 | ), | | |
| 2888 | [WS_METHODS.pullRequestsInvalidate]: (input) => | 2498 | [WS_METHODS.pullRequestsInvalidate]: (input) => |
| 2889 | observeRpcEffect( | 2499 | pullRequests.invalidate(input, { notifyReaders: true }).pipe( |
| 2890 | WS_METHODS.pullRequestsInvalidate, | 2500 | // A reader asking for fresh host state also wants the thread badges it feeds to |
| 2891 | pullRequests.invalidate(input, { notifyReaders: true }).pipe( | 2501 | // catch up, including a merged link the sweep would otherwise never revisit. |
| 2892 | // A reader asking for fresh host state also wants the thread badges it feeds to | 2502 | Effect.andThen( |
| 2893 | // catch up, including a merged link the sweep would otherwise never revisit. | 2503 | input.reference === undefined || input.filesViewedOnly === true |
| 2894 | Effect.andThen( | 2504 | ? Effect.void |
| 2895 | input.reference === undefined || input.filesViewedOnly === true | 2505 | : resolvePullRequestSyncKey(input.reference).pipe( |
| 2896 | ? Effect.void | 2506 | Effect.flatMap((key) => |
| 2897 | : resolvePullRequestSyncKey(input.reference).pipe( | 2507 | key === null ? Effect.void : pullRequestSync.requestSync(key), |
| 2898 | Effect.flatMap((key) => | | |
| 2899 | key === null ? Effect.void : pullRequestSync.requestSync(key), | | |
| 2900 | ), | | |
| 2901 | ), | 2508 | ), |
| 2902 | ), | 2509 | ), |
| 2903 | ), | 2510 | ), |
| 2904 | { "rpc.aggregate": "pull-requests" }, | | |
| 2905 | ), | | |
| 2906 | [WS_METHODS.pullRequestsSubscribeRefreshes]: () => | | |
| 2907 | observeRpcStream( | | |
| 2908 | WS_METHODS.pullRequestsSubscribeRefreshes, | | |
| 2909 | pullRequests.subscribeRefreshes, | | |
| 2910 | { "rpc.aggregate": "pull-requests" }, | | |
| 2911 | ), | 2511 | ), |
| | 2512 | [WS_METHODS.pullRequestsSubscribeRefreshes]: () => pullRequests.subscribeRefreshes, |
| 2912 | [WS_METHODS.pullRequestsReviewerCandidates]: (input) => | 2513 | [WS_METHODS.pullRequestsReviewerCandidates]: (input) => |
| 2913 | observeRpcEffect( | 2514 | withPullRequestViewer(input, pullRequests.reviewerCandidates(input)), |
| 2914 | WS_METHODS.pullRequestsReviewerCandidates, | | |
| 2915 | withPullRequestViewer(input, pullRequests.reviewerCandidates(input)), | | |
| 2916 | { "rpc.aggregate": "pull-requests" }, | | |
| 2917 | ), | | |
| 2918 | [WS_METHODS.pullRequestsRequestReviewers]: (input) => | 2515 | [WS_METHODS.pullRequestsRequestReviewers]: (input) => |
| 2919 | observeRpcEffect( | 2516 | withPullRequestViewer(input, pullRequests.requestReviewers(input)), |
| 2920 | WS_METHODS.pullRequestsRequestReviewers, | | |
| 2921 | withPullRequestViewer(input, pullRequests.requestReviewers(input)), | | |
| 2922 | { "rpc.aggregate": "pull-requests" }, | | |
| 2923 | ), | | |
| 2924 | [WS_METHODS.pullRequestsLabelCandidates]: (input) => | 2517 | [WS_METHODS.pullRequestsLabelCandidates]: (input) => |
| 2925 | observeRpcEffect( | 2518 | withPullRequestViewer(input, pullRequests.labelCandidates(input)), |
| 2926 | WS_METHODS.pullRequestsLabelCandidates, | | |
| 2927 | withPullRequestViewer(input, pullRequests.labelCandidates(input)), | | |
| 2928 | { "rpc.aggregate": "pull-requests" }, | | |
| 2929 | ), | | |
| 2930 | [WS_METHODS.pullRequestsSetLabels]: (input) => | 2519 | [WS_METHODS.pullRequestsSetLabels]: (input) => |
| 2931 | observeRpcEffect( | 2520 | withPullRequestViewer(input, pullRequests.setLabels(input)), |
| 2932 | WS_METHODS.pullRequestsSetLabels, | | |
| 2933 | withPullRequestViewer(input, pullRequests.setLabels(input)), | | |
| 2934 | { | | |
| 2935 | "rpc.aggregate": "pull-requests", | | |
| 2936 | }, | | |
| 2937 | ), | | |
| 2938 | [WS_METHODS.sourceControlLookupRepository]: (input) => | 2521 | [WS_METHODS.sourceControlLookupRepository]: (input) => |
| 2939 | observeRpcEffect( | 2522 | sourceControlRepositories.lookupRepository(input), |
| 2940 | WS_METHODS.sourceControlLookupRepository, | | |
| 2941 | sourceControlRepositories.lookupRepository(input), | | |
| 2942 | { | | |
| 2943 | "rpc.aggregate": "source-control", | | |
| 2944 | }, | | |
| 2945 | ), | | |
| 2946 | [WS_METHODS.sourceControlCloneRepository]: (input) => | 2523 | [WS_METHODS.sourceControlCloneRepository]: (input) => |
| 2947 | observeRpcEffect( | 2524 | sourceControlRepositories.cloneRepository(input), |
| 2948 | WS_METHODS.sourceControlCloneRepository, | | |
| 2949 | sourceControlRepositories.cloneRepository(input), | | |
| 2950 | { | | |
| 2951 | "rpc.aggregate": "source-control", | | |
| 2952 | }, | | |
| 2953 | ), | | |
| 2954 | [WS_METHODS.projectCloneStart]: (input) => | 2525 | [WS_METHODS.projectCloneStart]: (input) => |
| 2955 | observeRpcEffect( | 2526 | projectCloneTracker.start(input, { |
| 2956 | WS_METHODS.projectCloneStart, | 2527 | createProject: (project) => |
| 2957 | projectCloneTracker.start(input, { | 2528 | projectService |
| 2958 | createProject: (project) => | 2529 | .create({ |
| 2959 | projectService | 2530 | commandId: CommandId.make(`project-clone-create:${project.projectId}`), |
| 2960 | .create({ | 2531 | projectId: project.projectId, |
| 2961 | commandId: CommandId.make(`project-clone-create:${project.projectId}`), | 2532 | title: project.title, |
| 2962 | projectId: project.projectId, | 2533 | workspaceRoot: project.workspaceRoot, |
| 2963 | title: project.title, | 2534 | createWorkspaceRootIfMissing: true, |
| 2964 | workspaceRoot: project.workspaceRoot, | 2535 | }) |
| 2965 | createWorkspaceRootIfMissing: true, | 2536 | .pipe( |
| 2966 | }) | 2537 | Effect.asVoid, |
| 2967 | .pipe( | 2538 | Effect.mapError( |
| 2968 | Effect.asVoid, | 2539 | (cause) => |
| 2969 | Effect.mapError( | 2540 | new OrchestrationDispatchCommandError({ |
| 2970 | (cause) => | 2541 | message: "Failed to create clone project.", |
| 2971 | new OrchestrationDispatchCommandError({ | 2542 | cause, |
| 2972 | message: "Failed to create clone project.", | 2543 | }), |
| 2973 | cause, | | |
| 2974 | }), | | |
| 2975 | ), | | |
| 2976 | ), | | |
| 2977 | onCloned: (project) => | | |
| 2978 | repositoryIdentityResolver.resolve(project.workspaceRoot, { refresh: true }).pipe( | | |
| 2979 | Effect.andThen( | | |
| 2980 | projectService.update({ | | |
| 2981 | commandId: CommandId.make(`project-clone-done:${project.projectId}`), | | |
| 2982 | projectId: project.projectId, | | |
| 2983 | }), | | |
| 2984 | ), | 2544 | ), |
| 2985 | Effect.andThen(refreshGitStatus(project.workspaceRoot)), | | |
| 2986 | Effect.ignoreCause({ log: true }), | | |
| 2987 | ), | 2545 | ), |
| 2988 | }), | 2546 | onCloned: (project) => |
| 2989 | { "rpc.aggregate": "source-control" }, | 2547 | repositoryIdentityResolver.resolve(project.workspaceRoot, { refresh: true }).pipe( |
| 2990 | ), | 2548 | Effect.andThen( |
| 2991 | [WS_METHODS.projectsEnsureScratch]: () => | 2549 | projectService.update({ |
| 2992 | observeRpcEffect( | 2550 | commandId: CommandId.make(`project-clone-done:${project.projectId}`), |
| 2993 | WS_METHODS.projectsEnsureScratch, | 2551 | projectId: project.projectId, |
| 2994 | managedFolders.ensureScratchProject.pipe( | 2552 | }), |
| 2995 | Effect.mapError( | 2553 | ), |
| 2996 | (cause) => new OrchestrationDispatchCommandError({ message: cause.message, cause }), | 2554 | Effect.andThen(refreshGitStatus(project.workspaceRoot)), |
| | 2555 | Effect.ignoreCause({ log: true }), |
| 2997 | ), | 2556 | ), |
| | 2557 | }), |
| | 2558 | [WS_METHODS.projectsEnsureScratch]: () => |
| | 2559 | managedFolders.ensureScratchProject.pipe( |
| | 2560 | Effect.mapError( |
| | 2561 | (cause) => new OrchestrationDispatchCommandError({ message: cause.message, cause }), |
| 2998 | ), | 2562 | ), |
| 2999 | { "rpc.aggregate": "orchestration" }, | | |
| 3000 | ), | 2563 | ), |
| 3001 | [WS_METHODS.projectsCreateNew]: (input) => | 2564 | [WS_METHODS.projectsCreateNew]: (input) => |
| 3002 | observeRpcEffect( | 2565 | managedFolders |
| 3003 | WS_METHODS.projectsCreateNew, | 2566 | .createNamedProject(input) |
| 3004 | managedFolders | 2567 | .pipe( |
| 3005 | .createNamedProject(input) | 2568 | Effect.mapError( |
| 3006 | .pipe( | 2569 | (cause) => new OrchestrationDispatchCommandError({ message: cause.message, cause }), |
| 3007 | Effect.mapError( | | |
| 3008 | (cause) => | | |
| 3009 | new OrchestrationDispatchCommandError({ message: cause.message, cause }), | | |
| 3010 | ), | | |
| 3011 | ), | 2570 | ), |
| 3012 | { "rpc.aggregate": "orchestration" }, | 2571 | ), |
| 3013 | ), | | |
| 3014 | [WS_METHODS.projectCloneCancel]: (input) => | 2572 | [WS_METHODS.projectCloneCancel]: (input) => |
| 3015 | observeRpcEffect( | 2573 | projectCloneTracker.cancel(input.projectId).pipe(Effect.map((applied) => ({ applied }))), |
| 3016 | WS_METHODS.projectCloneCancel, | | |
| 3017 | projectCloneTracker | | |
| 3018 | .cancel(input.projectId) | | |
| 3019 | .pipe(Effect.map((applied) => ({ applied }))), | | |
| 3020 | { "rpc.aggregate": "source-control" }, | | |
| 3021 | ), | | |
| 3022 | [WS_METHODS.projectCloneRetry]: (input) => | 2574 | [WS_METHODS.projectCloneRetry]: (input) => |
| 3023 | observeRpcEffect( | 2575 | projectCloneTracker.retry(input.projectId).pipe(Effect.map((applied) => ({ applied }))), |
| 3024 | WS_METHODS.projectCloneRetry, | 2576 | [WS_METHODS.subscribeProjectClones]: () => projectCloneTracker.stream, |
| 3025 | projectCloneTracker.retry(input.projectId).pipe(Effect.map((applied) => ({ applied }))), | | |
| 3026 | { "rpc.aggregate": "source-control" }, | | |
| 3027 | ), | | |
| 3028 | [WS_METHODS.subscribeProjectClones]: () => | | |
| 3029 | observeRpcStream(WS_METHODS.subscribeProjectClones, projectCloneTracker.stream, { | | |
| 3030 | "rpc.aggregate": "source-control", | | |
| 3031 | }), | | |
| 3032 | [WS_METHODS.sourceControlPublishRepository]: (input) => | 2577 | [WS_METHODS.sourceControlPublishRepository]: (input) => |
| 3033 | observeRpcEffect( | 2578 | sourceControlRepositories.publishRepository(input).pipe( |
| 3034 | WS_METHODS.sourceControlPublishRepository, | 2579 | // A new remote can change the cached identity. Only the `cwd` entry |
| 3035 | sourceControlRepositories.publishRepository(input).pipe( | 2580 | // refreshes, so after a publish from a linked worktree the project |
| 3036 | // A new remote can change the cached identity. Only the `cwd` entry | 2581 | // root entry waits for its TTL. |
| 3037 | // refreshes, so after a publish from a linked worktree the project | 2582 | Effect.tap(() => repositoryIdentityResolver.resolve(input.cwd, { refresh: true })), |
| 3038 | // root entry waits for its TTL. | 2583 | Effect.tap(() => refreshGitStatus(input.cwd)), |
| 3039 | Effect.tap(() => repositoryIdentityResolver.resolve(input.cwd, { refresh: true })), | | |
| 3040 | Effect.tap(() => refreshGitStatus(input.cwd)), | | |
| 3041 | ), | | |
| 3042 | { | | |
| 3043 | "rpc.aggregate": "source-control", | | |
| 3044 | }, | | |
| 3045 | ), | 2584 | ), |
| 3046 | [WS_METHODS.projectsSearchEntries]: (input) => | 2585 | [WS_METHODS.projectsSearchEntries]: (input) => |
| 3047 | observeRpcEffect( | 2586 | workspaceEntries.search(input).pipe( |
| 3048 | WS_METHODS.projectsSearchEntries, | 2587 | Effect.mapError( |
| 3049 | workspaceEntries.search(input).pipe( | 2588 | (cause) => |
| 3050 | Effect.mapError( | 2589 | new ProjectSearchEntriesError({ |
| 3051 | (cause) => | 2590 | cwd: input.cwd, |
| 3052 | new ProjectSearchEntriesError({ | 2591 | queryLength: input.query.length, |
| 3053 | cwd: input.cwd, | 2592 | limit: input.limit, |
| 3054 | queryLength: input.query.length, | 2593 | ...projectEntriesFailureContext(cause), |
| 3055 | limit: input.limit, | 2594 | cause, |
| 3056 | ...projectEntriesFailureContext(cause), | 2595 | }), |
| 3057 | cause, | | |
| 3058 | }), | | |
| 3059 | ), | | |
| 3060 | ), | 2596 | ), |
| 3061 | { "rpc.aggregate": "workspace" }, | | |
| 3062 | ), | 2597 | ), |
| 3063 | [WS_METHODS.projectsSearchContents]: (input) => | 2598 | [WS_METHODS.projectsSearchContents]: (input) => |
| 3064 | observeRpcEffect( | 2599 | workspaceEntries.searchContents(input).pipe( |
| 3065 | WS_METHODS.projectsSearchContents, | 2600 | Effect.mapError( |
| 3066 | workspaceEntries.searchContents(input).pipe( | 2601 | (cause) => |
| 3067 | Effect.mapError( | 2602 | new ProjectSearchContentsError({ |
| 3068 | (cause) => | 2603 | cwd: input.cwd, |
| 3069 | new ProjectSearchContentsError({ | 2604 | queryLength: input.query.length, |
| 3070 | cwd: input.cwd, | 2605 | limit: input.limit, |
| 3071 | queryLength: input.query.length, | 2606 | ...projectEntriesFailureContext(cause), |
| 3072 | limit: input.limit, | 2607 | cause, |
| 3073 | ...projectEntriesFailureContext(cause), | 2608 | }), |
| 3074 | cause, | | |
| 3075 | }), | | |
| 3076 | ), | | |
| 3077 | ), | 2609 | ), |
| 3078 | { "rpc.aggregate": "workspace" }, | | |
| 3079 | ), | 2610 | ), |
| 3080 | [WS_METHODS.projectsListEntries]: (input) => | 2611 | [WS_METHODS.projectsListEntries]: (input) => |
| 3081 | observeRpcEffect( | 2612 | workspaceEntries.list(input).pipe( |
| 3082 | WS_METHODS.projectsListEntries, | 2613 | Effect.mapError( |
| 3083 | workspaceEntries.list(input).pipe( | 2614 | (cause) => |
| 3084 | Effect.mapError( | 2615 | new ProjectListEntriesError({ |
| 3085 | (cause) => | 2616 | ...input, |
| 3086 | new ProjectListEntriesError({ | 2617 | ...projectEntriesFailureContext(cause), |
| 3087 | ...input, | 2618 | cause, |
| 3088 | ...projectEntriesFailureContext(cause), | 2619 | }), |
| 3089 | cause, | | |
| 3090 | }), | | |
| 3091 | ), | | |
| 3092 | ), | 2620 | ), |
| 3093 | { "rpc.aggregate": "workspace" }, | | |
| 3094 | ), | 2621 | ), |
| 3095 | [WS_METHODS.projectsReadFile]: (input) => | 2622 | [WS_METHODS.projectsReadFile]: (input) => |
| 3096 | observeRpcEffect( | 2623 | workspaceFileSystem.readFile(input).pipe( |
| 3097 | WS_METHODS.projectsReadFile, | 2624 | Effect.mapError( |
| 3098 | workspaceFileSystem.readFile(input).pipe( | 2625 | (cause) => |
| 3099 | Effect.mapError( | 2626 | new ProjectReadFileError({ |
| 3100 | (cause) => | 2627 | ...input, |
| 3101 | new ProjectReadFileError({ | 2628 | ...projectFileFailureContext(cause), |
| 3102 | ...input, | 2629 | cause, |
| 3103 | ...projectFileFailureContext(cause), | 2630 | }), |
| 3104 | cause, | | |
| 3105 | }), | | |
| 3106 | ), | | |
| 3107 | ), | 2631 | ), |
| 3108 | { "rpc.aggregate": "workspace" }, | | |
| 3109 | ), | 2632 | ), |
| 3110 | [WS_METHODS.projectsWriteFile]: (input) => | 2633 | [WS_METHODS.projectsWriteFile]: (input) => |
| 3111 | observeRpcEffect( | 2634 | workspaceFileSystem.writeFile(input).pipe( |
| 3112 | WS_METHODS.projectsWriteFile, | 2635 | Effect.mapError( |
| 3113 | workspaceFileSystem.writeFile(input).pipe( | 2636 | (cause) => |
| 3114 | Effect.mapError( | 2637 | new ProjectWriteFileError({ |
| 3115 | (cause) => | 2638 | cwd: input.cwd, |
| 3116 | new ProjectWriteFileError({ | 2639 | relativePath: input.relativePath, |
| 3117 | cwd: input.cwd, | 2640 | ...projectFileFailureContext(cause), |
| 3118 | relativePath: input.relativePath, | 2641 | cause, |
| 3119 | ...projectFileFailureContext(cause), | 2642 | }), |
| 3120 | cause, | | |
| 3121 | }), | | |
| 3122 | ), | | |
| 3123 | ), | 2643 | ), |
| 3124 | { "rpc.aggregate": "workspace" }, | | |
| 3125 | ), | 2644 | ), |
| 3126 | [WS_METHODS.projectsMutate]: (mutation) => | 2645 | [WS_METHODS.projectsMutate]: (mutation) => |
| 3127 | observeRpcEffect( | 2646 | startup.enqueueCommand(mutateProject(mutation)).pipe( |
| 3128 | WS_METHODS.projectsMutate, | 2647 | Effect.mapError( |
| 3129 | startup.enqueueCommand(mutateProject(mutation)).pipe( | 2648 | (cause) => |
| 3130 | Effect.mapError( | 2649 | new ProjectMutationError({ |
| 3131 | (cause) => | 2650 | commandId: mutation.commandId, |
| 3132 | new ProjectMutationError({ | 2651 | message: |
| 3133 | commandId: mutation.commandId, | 2652 | cause._tag === "ProjectNotEmptyError" |
| 3134 | message: | 2653 | ? cause.message |
| 3135 | cause._tag === "ProjectNotEmptyError" | 2654 | : "Failed to mutate project.", |
| 3136 | ? cause.message | 2655 | cause, |
| 3137 | : "Failed to mutate project.", | 2656 | }), |
| 3138 | cause, | | |
| 3139 | }), | | |
| 3140 | ), | | |
| 3141 | ), | 2657 | ), |
| 3142 | { "rpc.aggregate": "orchestration" }, | | |
| 3143 | ), | 2658 | ), |
| 3144 | [WS_METHODS.shellOpenInEditor]: (input) => | 2659 | [WS_METHODS.shellOpenInEditor]: (input) => externalLauncher.launchEditor(input), |
| 3145 | observeRpcEffect(WS_METHODS.shellOpenInEditor, externalLauncher.launchEditor(input), { | | |
| 3146 | "rpc.aggregate": "workspace", | | |
| 3147 | }), | | |
| 3148 | [WS_METHODS.filesystemBrowse]: (input) => | 2660 | [WS_METHODS.filesystemBrowse]: (input) => |
| 3149 | observeRpcEffect( | 2661 | workspaceEntries.browse(input).pipe( |
| 3150 | WS_METHODS.filesystemBrowse, | 2662 | Effect.mapError( |
| 3151 | workspaceEntries.browse(input).pipe( | 2663 | (cause) => |
| 3152 | Effect.mapError( | 2664 | new FilesystemBrowseError({ |
| 3153 | (cause) => | 2665 | ...input, |
| 3154 | new FilesystemBrowseError({ | 2666 | ...filesystemBrowseFailureContext(cause), |
| 3155 | ...input, | 2667 | cause, |
| 3156 | ...filesystemBrowseFailureContext(cause), | 2668 | }), |
| 3157 | cause, | | |
| 3158 | }), | | |
| 3159 | ), | | |
| 3160 | ), | 2669 | ), |
| 3161 | { "rpc.aggregate": "workspace" }, | | |
| 3162 | ), | 2670 | ), |
| 3163 | [WS_METHODS.attachmentsCreateUploadUrl]: (input) => | 2671 | [WS_METHODS.attachmentsCreateUploadUrl]: (input) => issueAttachmentUploadUrl(input), |
| 3164 | observeRpcEffect(WS_METHODS.attachmentsCreateUploadUrl, issueAttachmentUploadUrl(input), { | 2672 | [WS_METHODS.attachmentsDelete]: (input) => deletePendingAttachment(input.attachmentId), |
| 3165 | "rpc.aggregate": "workspace", | 2673 | [WS_METHODS.agentSessionsScan]: () => agentSessionScanner.scan, |
| 3166 | }), | | |
| 3167 | [WS_METHODS.attachmentsDelete]: (input) => | | |
| 3168 | observeRpcEffect( | | |
| 3169 | WS_METHODS.attachmentsDelete, | | |
| 3170 | deletePendingAttachment(input.attachmentId), | | |
| 3171 | { "rpc.aggregate": "workspace" }, | | |
| 3172 | ), | | |
| 3173 | [WS_METHODS.agentSessionsScan]: () => | | |
| 3174 | observeRpcEffect(WS_METHODS.agentSessionsScan, agentSessionScanner.scan, { | | |
| 3175 | "rpc.aggregate": "workspace", | | |
| 3176 | }), | | |
| 3177 | [WS_METHODS.agentSessionsImport]: (input) => | 2674 | [WS_METHODS.agentSessionsImport]: (input) => |
| 3178 | observeRpcEffect( | 2675 | agentSessionImporter.importRecentAgentThreads(input), |
| 3179 | WS_METHODS.agentSessionsImport, | | |
| 3180 | agentSessionImporter.importRecentAgentThreads(input), | | |
| 3181 | { "rpc.aggregate": "workspace" }, | | |
| 3182 | ), | | |
| 3183 | [WS_METHODS.assetsCreateUrl]: (input) => | 2676 | [WS_METHODS.assetsCreateUrl]: (input) => |
| 3184 | observeRpcEffect( | 2677 | Effect.gen(function* () { |
| 3185 | WS_METHODS.assetsCreateUrl, | 2678 | const path = yield* Path.Path; |
| 3186 | Effect.gen(function* () { | 2679 | // An absolute media path can be linked from a thread on another environment. |
| 3187 | const path = yield* Path.Path; | 2680 | if ( |
| 3188 | // An absolute media path can be linked from a thread on another environment. | 2681 | input.resource._tag === "attachment" || |
| 3189 | if ( | 2682 | input.resource._tag === "native-app-icon" || |
| 3190 | input.resource._tag === "attachment" || | 2683 | input.resource._tag === "tool-output-image" || |
| 3191 | input.resource._tag === "native-app-icon" || | 2684 | // GitHub media names the repository it authenticates through itself. |
| 3192 | input.resource._tag === "tool-output-image" || | 2685 | input.resource._tag === "github-media" || |
| 3193 | // GitHub media names the repository it authenticates through itself. | 2686 | (input.resource._tag === "media-file" && path.isAbsolute(input.resource.path)) |
| 3194 | input.resource._tag === "github-media" || | 2687 | ) { |
| 3195 | (input.resource._tag === "media-file" && path.isAbsolute(input.resource.path)) | 2688 | return yield* issueAssetUrl({ resource: input.resource }); |
| 3196 | ) { | 2689 | } |
| 3197 | return yield* issueAssetUrl({ resource: input.resource }); | 2690 | if (input.resource._tag === "draft-workspace-file") { |
| 3198 | } | 2691 | // A project draft names its workspace directly; there is no |
| 3199 | if (input.resource._tag === "draft-workspace-file") { | 2692 | // thread to resolve one from. |
| 3200 | // A project draft names its workspace directly; there is no | 2693 | return yield* issueAssetUrl({ |
| 3201 | // thread to resolve one from. | 2694 | resource: input.resource, |
| 3202 | return yield* issueAssetUrl({ | 2695 | workspaceRoot: input.resource.cwd, |
| 3203 | resource: input.resource, | 2696 | }); |
| 3204 | workspaceRoot: input.resource.cwd, | 2697 | } |
| 3205 | }); | 2698 | if (input.resource._tag === "project-favicon") { |
| 3206 | } | 2699 | const project = yield* projectStore |
| 3207 | if (input.resource._tag === "project-favicon") { | 2700 | .findActiveByWorkspaceRoot(input.resource.cwd) |
| 3208 | const project = yield* projectStore | | |
| 3209 | .findActiveByWorkspaceRoot(input.resource.cwd) | | |
| 3210 | .pipe( | | |
| 3211 | Effect.mapError( | | |
| 3212 | (cause) => | | |
| 3213 | new AssetWorkspaceContextResolutionError({ | | |
| 3214 | resource: input.resource, | | |
| 3215 | cause, | | |
| 3216 | }), | | |
| 3217 | ), | | |
| 3218 | ); | | |
| 3219 | if (Option.isNone(project)) { | | |
| 3220 | return yield* new AssetWorkspaceContextNotFoundError({ | | |
| 3221 | resource: input.resource, | | |
| 3222 | }); | | |
| 3223 | } | | |
| 3224 | // A cloned project exists before its files do. Clients ask again | | |
| 3225 | // when the clone lands (see createProjectFaviconUrlAtomFamily). | | |
| 3226 | const clone = yield* projectCloneTracker.get(project.value.projectId); | | |
| 3227 | return yield* issueAssetUrl({ | | |
| 3228 | resource: input.resource, | | |
| 3229 | ...(project.value.faviconPath | | |
| 3230 | ? { projectFaviconPath: project.value.faviconPath } | | |
| 3231 | : {}), | | |
| 3232 | projectCheckoutPending: | | |
| 3233 | clone !== null && | | |
| 3234 | clone.phase !== "done" && | | |
| 3235 | clone.destinationPath === project.value.workspaceRoot, | | |
| 3236 | }); | | |
| 3237 | } | | |
| 3238 | const thread = yield* threadManagement | | |
| 3239 | .getThreadRecords(input.resource.threadId, []) | | |
| 3240 | .pipe( | 2701 | .pipe( |
| 3241 | Effect.mapError( | 2702 | Effect.mapError( |
| 3242 | (cause) => | 2703 | (cause) => |
| ... | @@ -3246,7 +2707,28 @@ const layerWsRpc = ( | ... | @@ -3246,7 +2707,28 @@ const layerWsRpc = ( |
| 3246 | }), | 2707 | }), |
| 3247 | ), | 2708 | ), |
| 3248 | ); | 2709 | ); |
| 3249 | const project = yield* projectService.getById(thread.thread.projectId).pipe( | 2710 | if (Option.isNone(project)) { |
| | 2711 | return yield* new AssetWorkspaceContextNotFoundError({ |
| | 2712 | resource: input.resource, |
| | 2713 | }); |
| | 2714 | } |
| | 2715 | // A cloned project exists before its files do. Clients ask again |
| | 2716 | // when the clone lands (see createProjectFaviconUrlAtomFamily). |
| | 2717 | const clone = yield* projectCloneTracker.get(project.value.projectId); |
| | 2718 | return yield* issueAssetUrl({ |
| | 2719 | resource: input.resource, |
| | 2720 | ...(project.value.faviconPath |
| | 2721 | ? { projectFaviconPath: project.value.faviconPath } |
| | 2722 | : {}), |
| | 2723 | projectCheckoutPending: |
| | 2724 | clone !== null && |
| | 2725 | clone.phase !== "done" && |
| | 2726 | clone.destinationPath === project.value.workspaceRoot, |
| | 2727 | }); |
| | 2728 | } |
| | 2729 | const thread = yield* threadManagement |
| | 2730 | .getThreadRecords(input.resource.threadId, []) |
| | 2731 | .pipe( |
| 3250 | Effect.mapError( | 2732 | Effect.mapError( |
| 3251 | (cause) => | 2733 | (cause) => |
| 3252 | new AssetWorkspaceContextResolutionError({ | 2734 | new AssetWorkspaceContextResolutionError({ |
| ... | @@ -3255,357 +2737,187 @@ const layerWsRpc = ( | ... | @@ -3255,357 +2737,187 @@ const layerWsRpc = ( |
| 3255 | }), | 2737 | }), |
| 3256 | ), | 2738 | ), |
| 3257 | ); | 2739 | ); |
| 3258 | if (Option.isNone(project)) { | 2740 | const project = yield* projectService.getById(thread.thread.projectId).pipe( |
| 3259 | return yield* new AssetWorkspaceContextNotFoundError({ | 2741 | Effect.mapError( |
| 3260 | resource: input.resource, | 2742 | (cause) => |
| 3261 | }); | 2743 | new AssetWorkspaceContextResolutionError({ |
| 3262 | } | 2744 | resource: input.resource, |
| 3263 | return yield* issueAssetUrl({ | 2745 | cause, |
| | 2746 | }), |
| | 2747 | ), |
| | 2748 | ); |
| | 2749 | if (Option.isNone(project)) { |
| | 2750 | return yield* new AssetWorkspaceContextNotFoundError({ |
| 3264 | resource: input.resource, | 2751 | resource: input.resource, |
| 3265 | workspaceRoot: thread.thread.worktreePath ?? project.value.workspaceRoot, | | |
| 3266 | }); | 2752 | }); |
| 3267 | }), | 2753 | } |
| 3268 | { "rpc.aggregate": "workspace" }, | 2754 | return yield* issueAssetUrl({ |
| 3269 | ), | 2755 | resource: input.resource, |
| | 2756 | workspaceRoot: thread.thread.worktreePath ?? project.value.workspaceRoot, |
| | 2757 | }); |
| | 2758 | }), |
| 3270 | [WS_METHODS.assetsPersistChatAttachments]: (input) => | 2759 | [WS_METHODS.assetsPersistChatAttachments]: (input) => |
| 3271 | observeRpcEffect( | 2760 | persistChatAttachments(input).pipe(Effect.map((attachments) => ({ attachments }))), |
| 3272 | WS_METHODS.assetsPersistChatAttachments, | | |
| 3273 | persistChatAttachments(input).pipe(Effect.map((attachments) => ({ attachments }))), | | |
| 3274 | { "rpc.aggregate": "orchestration" }, | | |
| 3275 | ), | | |
| 3276 | [WS_METHODS.subscribeVcsStatus]: (input) => | 2761 | [WS_METHODS.subscribeVcsStatus]: (input) => |
| 3277 | observeRpcStream( | 2762 | vcsStatusBroadcaster.streamStatus(input, { |
| 3278 | WS_METHODS.subscribeVcsStatus, | 2763 | automaticRemoteRefreshInterval: automaticGitFetchInterval, |
| 3279 | vcsStatusBroadcaster.streamStatus(input, { | 2764 | }), |
| 3280 | automaticRemoteRefreshInterval: automaticGitFetchInterval, | 2765 | [WS_METHODS.subscribeWorktreeSetup]: (input) => worktreeSetupTracker.stream(input.threadId), |
| 3281 | }), | | |
| 3282 | { | | |
| 3283 | "rpc.aggregate": "vcs", | | |
| 3284 | }, | | |
| 3285 | ), | | |
| 3286 | [WS_METHODS.subscribeWorktreeSetup]: (input) => | | |
| 3287 | observeRpcStream( | | |
| 3288 | WS_METHODS.subscribeWorktreeSetup, | | |
| 3289 | worktreeSetupTracker.stream(input.threadId), | | |
| 3290 | { "rpc.aggregate": "vcs" }, | | |
| 3291 | ), | | |
| 3292 | [WS_METHODS.worktreeSetupCancel]: (input) => | 2766 | [WS_METHODS.worktreeSetupCancel]: (input) => |
| 3293 | observeRpcEffect( | 2767 | worktreeSetupTracker |
| 3294 | WS_METHODS.worktreeSetupCancel, | 2768 | .cancel(input.threadId) |
| 3295 | worktreeSetupTracker | 2769 | .pipe(Effect.map((cancelled) => ({ cancelled }))), |
| 3296 | .cancel(input.threadId) | 2770 | [WS_METHODS.vcsRefreshStatus]: (input) => vcsStatusBroadcaster.refreshStatus(input.cwd), |
| 3297 | .pipe(Effect.map((cancelled) => ({ cancelled }))), | | |
| 3298 | { "rpc.aggregate": "vcs" }, | | |
| 3299 | ), | | |
| 3300 | [WS_METHODS.vcsRefreshStatus]: (input) => | | |
| 3301 | observeRpcEffect( | | |
| 3302 | WS_METHODS.vcsRefreshStatus, | | |
| 3303 | vcsStatusBroadcaster.refreshStatus(input.cwd), | | |
| 3304 | { | | |
| 3305 | "rpc.aggregate": "vcs", | | |
| 3306 | }, | | |
| 3307 | ), | | |
| 3308 | [WS_METHODS.vcsPull]: (input) => | 2771 | [WS_METHODS.vcsPull]: (input) => |
| 3309 | observeRpcEffect( | 2772 | gitWorkflow.pullCurrentBranch(input.cwd).pipe( |
| 3310 | WS_METHODS.vcsPull, | 2773 | Effect.matchCauseEffect({ |
| 3311 | gitWorkflow.pullCurrentBranch(input.cwd).pipe( | 2774 | onFailure: (cause) => Effect.failCause(cause), |
| 3312 | Effect.matchCauseEffect({ | 2775 | onSuccess: (result) => |
| 3313 | onFailure: (cause) => Effect.failCause(cause), | 2776 | refreshGitStatus(input.cwd).pipe(Effect.ignore({ log: true }), Effect.as(result)), |
| 3314 | onSuccess: (result) => | 2777 | }), |
| 3315 | refreshGitStatus(input.cwd).pipe(Effect.ignore({ log: true }), Effect.as(result)), | | |
| 3316 | }), | | |
| 3317 | ), | | |
| 3318 | { "rpc.aggregate": "git" }, | | |
| 3319 | ), | 2778 | ), |
| 3320 | [WS_METHODS.gitRunStackedAction]: (input) => | 2779 | [WS_METHODS.gitRunStackedAction]: (input) => |
| 3321 | observeRpcStream( | 2780 | Stream.callback<GitActionProgressEvent, GitManagerServiceError>((queue) => |
| 3322 | WS_METHODS.gitRunStackedAction, | 2781 | gitWorkflow |
| 3323 | Stream.callback<GitActionProgressEvent, GitManagerServiceError>((queue) => | 2782 | .runStackedAction(input, { |
| 3324 | gitWorkflow | 2783 | actionId: input.actionId, |
| 3325 | .runStackedAction(input, { | 2784 | progressReporter: { |
| 3326 | actionId: input.actionId, | 2785 | publish: (event) => Queue.offer(queue, event).pipe(Effect.asVoid), |
| 3327 | progressReporter: { | 2786 | }, |
| 3328 | publish: (event) => Queue.offer(queue, event).pipe(Effect.asVoid), | 2787 | }) |
| 3329 | }, | 2788 | .pipe( |
| 3330 | }) | 2789 | Effect.matchCauseEffect({ |
| 3331 | .pipe( | 2790 | onFailure: (cause) => Queue.failCause(queue, cause), |
| 3332 | Effect.matchCauseEffect({ | 2791 | onSuccess: (result) => |
| 3333 | onFailure: (cause) => Queue.failCause(queue, cause), | 2792 | (input.threadId === undefined |
| 3334 | onSuccess: (result) => | 2793 | ? Effect.void |
| 3335 | (input.threadId === undefined | 2794 | : linkCreatedPullRequest({ |
| 3336 | ? Effect.void | 2795 | threadId: input.threadId, |
| 3337 | : linkCreatedPullRequest({ | 2796 | result, |
| 3338 | threadId: input.threadId, | 2797 | commandId: serverCommandId("pr-created-link"), |
| 3339 | result, | 2798 | }).pipe( |
| 3340 | commandId: serverCommandId("pr-created-link"), | 2799 | Effect.provideService(Orchestrator.OrchestratorV2, orchestrationEngine), |
| 3341 | }).pipe( | 2800 | Effect.provideService(ProjectService.ProjectService, projectService), |
| 3342 | Effect.provideService(Orchestrator.OrchestratorV2, orchestrationEngine), | 2801 | ) |
| 3343 | Effect.provideService(ProjectService.ProjectService, projectService), | 2802 | ).pipe( |
| 3344 | ) | 2803 | Effect.andThen( |
| 3345 | ).pipe( | 2804 | refreshPushedPullRequests(input, result).pipe( |
| 3346 | Effect.andThen( | 2805 | Effect.provideService(Orchestrator.OrchestratorV2, orchestrationEngine), |
| 3347 | refreshPushedPullRequests(input, result).pipe( | 2806 | Effect.provideService(ProjectStore.ProjectStoreV2, projectStore), |
| 3348 | Effect.provideService(Orchestrator.OrchestratorV2, orchestrationEngine), | 2807 | Effect.provideService( |
| 3349 | Effect.provideService(ProjectStore.ProjectStoreV2, projectStore), | 2808 | PullRequestService.PullRequestService, |
| 3350 | Effect.provideService( | 2809 | pullRequests, |
| 3351 | PullRequestService.PullRequestService, | | |
| 3352 | pullRequests, | | |
| 3353 | ), | | |
| 3354 | ), | 2810 | ), |
| 3355 | ), | 2811 | ), |
| 3356 | Effect.andThen(refreshGitStatus(input.cwd)), | | |
| 3357 | Effect.andThen(Queue.end(queue).pipe(Effect.asVoid)), | | |
| 3358 | ), | 2812 | ), |
| 3359 | }), | 2813 | Effect.andThen(refreshGitStatus(input.cwd)), |
| 3360 | ), | 2814 | Effect.andThen(Queue.end(queue).pipe(Effect.asVoid)), |
| 3361 | ), | 2815 | ), |
| 3362 | { "rpc.aggregate": "vcs" }, | 2816 | }), |
| 3363 | ), | 2817 | ), |
| 3364 | [WS_METHODS.gitResolvePullRequest]: (input) => | | |
| 3365 | observeRpcEffect( | | |
| 3366 | WS_METHODS.gitResolvePullRequest, | | |
| 3367 | gitWorkflow.resolvePullRequest(input), | | |
| 3368 | { | | |
| 3369 | "rpc.aggregate": "git", | | |
| 3370 | }, | | |
| 3371 | ), | 2818 | ), |
| | 2819 | [WS_METHODS.gitResolvePullRequest]: (input) => gitWorkflow.resolvePullRequest(input), |
| 3372 | [WS_METHODS.gitPreparePullRequestThread]: (input) => | 2820 | [WS_METHODS.gitPreparePullRequestThread]: (input) => |
| 3373 | observeRpcEffect( | 2821 | gitWorkflow |
| 3374 | WS_METHODS.gitPreparePullRequestThread, | 2822 | .preparePullRequestThread(input) |
| 3375 | gitWorkflow | 2823 | .pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3376 | .preparePullRequestThread(input) | 2824 | [WS_METHODS.vcsListRefs]: (input) => gitWorkflow.listRefs(input), |
| 3377 | .pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3378 | { "rpc.aggregate": "git" }, | | |
| 3379 | ), | | |
| 3380 | [WS_METHODS.vcsListRefs]: (input) => | | |
| 3381 | observeRpcEffect(WS_METHODS.vcsListRefs, gitWorkflow.listRefs(input), { | | |
| 3382 | "rpc.aggregate": "vcs", | | |
| 3383 | }), | | |
| 3384 | [WS_METHODS.vcsCreateWorktree]: (input) => | 2825 | [WS_METHODS.vcsCreateWorktree]: (input) => |
| 3385 | observeRpcEffect( | 2826 | gitWorkflow.createWorktree(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3386 | WS_METHODS.vcsCreateWorktree, | | |
| 3387 | gitWorkflow.createWorktree(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3388 | { "rpc.aggregate": "vcs" }, | | |
| 3389 | ), | | |
| 3390 | [WS_METHODS.vcsRemoveWorktree]: (input) => | 2827 | [WS_METHODS.vcsRemoveWorktree]: (input) => |
| 3391 | observeRpcEffect( | 2828 | gitWorkflow.removeWorktree(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3392 | WS_METHODS.vcsRemoveWorktree, | | |
| 3393 | gitWorkflow.removeWorktree(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3394 | { "rpc.aggregate": "vcs" }, | | |
| 3395 | ), | | |
| 3396 | [WS_METHODS.vcsCreateRef]: (input) => | 2829 | [WS_METHODS.vcsCreateRef]: (input) => |
| 3397 | observeRpcEffect( | 2830 | gitWorkflow.createRef(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3398 | WS_METHODS.vcsCreateRef, | | |
| 3399 | gitWorkflow.createRef(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3400 | { "rpc.aggregate": "vcs" }, | | |
| 3401 | ), | | |
| 3402 | [WS_METHODS.vcsSwitchRef]: (input) => | 2831 | [WS_METHODS.vcsSwitchRef]: (input) => |
| 3403 | observeRpcEffect( | 2832 | gitWorkflow.switchRef(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3404 | WS_METHODS.vcsSwitchRef, | | |
| 3405 | gitWorkflow.switchRef(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3406 | { "rpc.aggregate": "vcs" }, | | |
| 3407 | ), | | |
| 3408 | [WS_METHODS.vcsInit]: (input) => | 2833 | [WS_METHODS.vcsInit]: (input) => |
| 3409 | observeRpcEffect( | 2834 | vcsProvisioning.initRepository(input).pipe(Effect.tap(() => refreshGitStatus(input.cwd))), |
| 3410 | WS_METHODS.vcsInit, | 2835 | [WS_METHODS.reviewGetDiffPreview]: (input) => review.getDiffPreview(input), |
| 3411 | vcsProvisioning | 2836 | [WS_METHODS.reviewGetDiffFileContents]: (input) => review.getDiffFileContents(input), |
| 3412 | .initRepository(input) | 2837 | [WS_METHODS.terminalOpen]: (input) => terminalManager.open(input), |
| 3413 | .pipe(Effect.tap(() => refreshGitStatus(input.cwd))), | | |
| 3414 | { "rpc.aggregate": "vcs" }, | | |
| 3415 | ), | | |
| 3416 | [WS_METHODS.reviewGetDiffPreview]: (input) => | | |
| 3417 | observeRpcEffect(WS_METHODS.reviewGetDiffPreview, review.getDiffPreview(input), { | | |
| 3418 | "rpc.aggregate": "review", | | |
| 3419 | }), | | |
| 3420 | [WS_METHODS.reviewGetDiffFileContents]: (input) => | | |
| 3421 | observeRpcEffect( | | |
| 3422 | WS_METHODS.reviewGetDiffFileContents, | | |
| 3423 | review.getDiffFileContents(input), | | |
| 3424 | { "rpc.aggregate": "review" }, | | |
| 3425 | ), | | |
| 3426 | [WS_METHODS.terminalOpen]: (input) => | | |
| 3427 | observeRpcEffect(WS_METHODS.terminalOpen, terminalManager.open(input), { | | |
| 3428 | "rpc.aggregate": "terminal", | | |
| 3429 | }), | | |
| 3430 | [WS_METHODS.terminalAttach]: (input) => | 2838 | [WS_METHODS.terminalAttach]: (input) => |
| 3431 | observeRpcStream( | 2839 | Stream.callback<TerminalAttachStreamEvent, TerminalError>((queue) => |
| 3432 | WS_METHODS.terminalAttach, | 2840 | Effect.acquireRelease( |
| 3433 | Stream.callback<TerminalAttachStreamEvent, TerminalError>((queue) => | 2841 | terminalManager.attachStream(input, (event) => Queue.offer(queue, event)), |
| 3434 | Effect.acquireRelease( | 2842 | (unsubscribe) => Effect.sync(unsubscribe), |
| 3435 | terminalManager.attachStream(input, (event) => Queue.offer(queue, event)), | | |
| 3436 | (unsubscribe) => Effect.sync(unsubscribe), | | |
| 3437 | ), | | |
| 3438 | ), | 2843 | ), |
| 3439 | { "rpc.aggregate": "terminal" }, | | |
| 3440 | ), | 2844 | ), |
| 3441 | [WS_METHODS.terminalWrite]: (input) => | 2845 | [WS_METHODS.terminalWrite]: (input) => terminalManager.write(input), |
| 3442 | observeRpcEffect(WS_METHODS.terminalWrite, terminalManager.write(input), { | 2846 | [WS_METHODS.terminalResize]: (input) => terminalManager.resize(input), |
| 3443 | "rpc.aggregate": "terminal", | 2847 | [WS_METHODS.terminalClear]: (input) => terminalManager.clear(input), |
| 3444 | }), | 2848 | [WS_METHODS.terminalRestart]: (input) => terminalManager.restart(input), |
| 3445 | [WS_METHODS.terminalResize]: (input) => | 2849 | [WS_METHODS.terminalClose]: (input) => terminalManager.close(input), |
| 3446 | observeRpcEffect(WS_METHODS.terminalResize, terminalManager.resize(input), { | | |
| 3447 | "rpc.aggregate": "terminal", | | |
| 3448 | }), | | |
| 3449 | [WS_METHODS.terminalClear]: (input) => | | |
| 3450 | observeRpcEffect(WS_METHODS.terminalClear, terminalManager.clear(input), { | | |
| 3451 | "rpc.aggregate": "terminal", | | |
| 3452 | }), | | |
| 3453 | [WS_METHODS.terminalRestart]: (input) => | | |
| 3454 | observeRpcEffect(WS_METHODS.terminalRestart, terminalManager.restart(input), { | | |
| 3455 | "rpc.aggregate": "terminal", | | |
| 3456 | }), | | |
| 3457 | [WS_METHODS.terminalClose]: (input) => | | |
| 3458 | observeRpcEffect(WS_METHODS.terminalClose, terminalManager.close(input), { | | |
| 3459 | "rpc.aggregate": "terminal", | | |
| 3460 | }), | | |
| 3461 | [WS_METHODS.subscribeTerminalEvents]: (_input) => | 2850 | [WS_METHODS.subscribeTerminalEvents]: (_input) => |
| 3462 | observeRpcStream( | 2851 | Stream.callback<TerminalEvent>((queue) => |
| 3463 | WS_METHODS.subscribeTerminalEvents, | 2852 | Effect.acquireRelease( |
| 3464 | Stream.callback<TerminalEvent>((queue) => | 2853 | terminalManager.subscribe((event) => Queue.offer(queue, event)), |
| 3465 | Effect.acquireRelease( | 2854 | (unsubscribe) => Effect.sync(unsubscribe), |
| 3466 | terminalManager.subscribe((event) => Queue.offer(queue, event)), | | |
| 3467 | (unsubscribe) => Effect.sync(unsubscribe), | | |
| 3468 | ), | | |
| 3469 | ), | 2855 | ), |
| 3470 | { "rpc.aggregate": "terminal" }, | | |
| 3471 | ), | 2856 | ), |
| 3472 | [WS_METHODS.subscribeTerminalMetadata]: (_input) => | 2857 | [WS_METHODS.subscribeTerminalMetadata]: (_input) => |
| 3473 | observeRpcStream( | 2858 | Stream.callback<TerminalMetadataStreamEvent>((queue) => |
| 3474 | WS_METHODS.subscribeTerminalMetadata, | 2859 | Effect.acquireRelease( |
| 3475 | Stream.callback<TerminalMetadataStreamEvent>((queue) => | 2860 | terminalManager.subscribeMetadata((event) => Queue.offer(queue, event)), |
| 3476 | Effect.acquireRelease( | 2861 | (unsubscribe) => Effect.sync(unsubscribe), |
| 3477 | terminalManager.subscribeMetadata((event) => Queue.offer(queue, event)), | | |
| 3478 | (unsubscribe) => Effect.sync(unsubscribe), | | |
| 3479 | ), | | |
| 3480 | ), | 2862 | ), |
| 3481 | { "rpc.aggregate": "terminal" }, | | |
| 3482 | ), | 2863 | ), |
| 3483 | [WS_METHODS.previewOpen]: (input) => | 2864 | [WS_METHODS.previewOpen]: (input) => previewManager.open(input), |
| 3484 | observeRpcEffect(WS_METHODS.previewOpen, previewManager.open(input), { | 2865 | [WS_METHODS.previewNavigate]: (input) => previewManager.navigate(input), |
| 3485 | "rpc.aggregate": "preview", | 2866 | [WS_METHODS.previewResize]: (input) => previewManager.resize(input), |
| 3486 | }), | 2867 | [WS_METHODS.previewAdjust]: (input) => previewManager.adjust(input), |
| 3487 | [WS_METHODS.previewNavigate]: (input) => | 2868 | [WS_METHODS.previewRefresh]: (input) => previewManager.refresh(input), |
| 3488 | observeRpcEffect(WS_METHODS.previewNavigate, previewManager.navigate(input), { | 2869 | [WS_METHODS.previewClose]: (input) => previewManager.close(input), |
| 3489 | "rpc.aggregate": "preview", | 2870 | [WS_METHODS.previewList]: (input) => previewManager.list(input), |
| 3490 | }), | 2871 | [WS_METHODS.previewClearProfile]: (input) => serverBrowser.clearProfile(input.profileId), |
| 3491 | [WS_METHODS.previewResize]: (input) => | 2872 | [WS_METHODS.previewReportStatus]: (input) => previewManager.reportStatus(input), |
| 3492 | observeRpcEffect(WS_METHODS.previewResize, previewManager.resize(input), { | 2873 | [WS_METHODS.subscribePreviewEvents]: (_input) => previewManager.events, |
| 3493 | "rpc.aggregate": "preview", | 2874 | [WS_METHODS.deviceConfigure]: (input) => deviceService.configure(input), |
| 3494 | }), | 2875 | [WS_METHODS.deviceTestHost]: (input) => deviceService.testHost(input), |
| 3495 | [WS_METHODS.previewAdjust]: (input) => | | |
| 3496 | observeRpcEffect(WS_METHODS.previewAdjust, previewManager.adjust(input), { | | |
| 3497 | "rpc.aggregate": "preview", | | |
| 3498 | }), | | |
| 3499 | [WS_METHODS.previewRefresh]: (input) => | | |
| 3500 | observeRpcEffect(WS_METHODS.previewRefresh, previewManager.refresh(input), { | | |
| 3501 | "rpc.aggregate": "preview", | | |
| 3502 | }), | | |
| 3503 | [WS_METHODS.previewClose]: (input) => | | |
| 3504 | observeRpcEffect(WS_METHODS.previewClose, previewManager.close(input), { | | |
| 3505 | "rpc.aggregate": "preview", | | |
| 3506 | }), | | |
| 3507 | [WS_METHODS.previewList]: (input) => | | |
| 3508 | observeRpcEffect(WS_METHODS.previewList, previewManager.list(input), { | | |
| 3509 | "rpc.aggregate": "preview", | | |
| 3510 | }), | | |
| 3511 | [WS_METHODS.previewClearProfile]: (input) => | | |
| 3512 | observeRpcEffect( | | |
| 3513 | WS_METHODS.previewClearProfile, | | |
| 3514 | serverBrowser.clearProfile(input.profileId), | | |
| 3515 | { "rpc.aggregate": "preview" }, | | |
| 3516 | ), | | |
| 3517 | [WS_METHODS.previewReportStatus]: (input) => | | |
| 3518 | observeRpcEffect(WS_METHODS.previewReportStatus, previewManager.reportStatus(input), { | | |
| 3519 | "rpc.aggregate": "preview", | | |
| 3520 | }), | | |
| 3521 | [WS_METHODS.subscribePreviewEvents]: (_input) => | | |
| 3522 | observeRpcStream(WS_METHODS.subscribePreviewEvents, previewManager.events, { | | |
| 3523 | "rpc.aggregate": "preview", | | |
| 3524 | }), | | |
| 3525 | [WS_METHODS.deviceConfigure]: (input) => | | |
| 3526 | observeRpcEffect(WS_METHODS.deviceConfigure, deviceService.configure(input), { | | |
| 3527 | "rpc.aggregate": "device", | | |
| 3528 | }), | | |
| 3529 | [WS_METHODS.deviceTestHost]: (input) => | | |
| 3530 | observeRpcEffect(WS_METHODS.deviceTestHost, deviceService.testHost(input), { | | |
| 3531 | "rpc.aggregate": "device", | | |
| 3532 | }), | | |
| 3533 | [WS_METHODS.deviceList]: (input) => | 2876 | [WS_METHODS.deviceList]: (input) => |
| 3534 | observeRpcEffect( | 2877 | input.inspectOnly && !input.updateTool |
| 3535 | WS_METHODS.deviceList, | 2878 | ? deviceService.inspect |
| 3536 | input.inspectOnly && !input.updateTool | 2879 | : authorizeEffect( |
| 3537 | ? deviceService.inspect | 2880 | requiredScopeForDeviceList(input), |
| 3538 | : authorizeEffect( | 2881 | input.updateTool |
| 3539 | requiredScopeForDeviceList(input), | 2882 | ? deviceService.updateTool(input.updateTool) |
| 3540 | input.updateTool | 2883 | : input.retryHostId |
| 3541 | ? deviceService.updateTool(input.updateTool) | 2884 | ? deviceService.retryHost(input.retryHostId) |
| 3542 | : input.retryHostId | 2885 | : deviceService.list, |
| 3543 | ? deviceService.retryHost(input.retryHostId) | 2886 | ), |
| 3544 | : deviceService.list, | 2887 | [WS_METHODS.deviceOpen]: (input) => deviceService.open(input), |
| 3545 | ), | 2888 | [WS_METHODS.deviceClose]: (input) => deviceService.close(input), |
| 3546 | { | 2889 | [WS_METHODS.deviceShutdown]: (input) => deviceService.shutdown(input), |
| 3547 | "rpc.aggregate": "device", | 2890 | [WS_METHODS.deviceDetail]: (input) => deviceService.detail(input), |
| 3548 | }, | 2891 | [WS_METHODS.deviceAction]: (input) => deviceService.action(input), |
| 3549 | ), | 2892 | [WS_METHODS.subscribeDeviceState]: (_input) => DeviceService.stateStream(deviceService), |
| 3550 | [WS_METHODS.deviceOpen]: (input) => | | |
| 3551 | observeRpcEffect(WS_METHODS.deviceOpen, deviceService.open(input), { | | |
| 3552 | "rpc.aggregate": "device", | | |
| 3553 | }), | | |
| 3554 | [WS_METHODS.deviceClose]: (input) => | | |
| 3555 | observeRpcEffect(WS_METHODS.deviceClose, deviceService.close(input), { | | |
| 3556 | "rpc.aggregate": "device", | | |
| 3557 | }), | | |
| 3558 | [WS_METHODS.deviceShutdown]: (input) => | | |
| 3559 | observeRpcEffect(WS_METHODS.deviceShutdown, deviceService.shutdown(input), { | | |
| 3560 | "rpc.aggregate": "device", | | |
| 3561 | }), | | |
| 3562 | [WS_METHODS.deviceDetail]: (input) => | | |
| 3563 | observeRpcEffect(WS_METHODS.deviceDetail, deviceService.detail(input), { | | |
| 3564 | "rpc.aggregate": "device", | | |
| 3565 | }), | | |
| 3566 | [WS_METHODS.deviceAction]: (input) => | | |
| 3567 | observeRpcEffect(WS_METHODS.deviceAction, deviceService.action(input), { | | |
| 3568 | "rpc.aggregate": "device", | | |
| 3569 | }), | | |
| 3570 | [WS_METHODS.subscribeDeviceState]: (_input) => | | |
| 3571 | observeRpcStream( | | |
| 3572 | WS_METHODS.subscribeDeviceState, | | |
| 3573 | DeviceService.stateStream(deviceService), | | |
| 3574 | { "rpc.aggregate": "device" }, | | |
| 3575 | ), | | |
| 3576 | [WS_METHODS.subscribeDiscoveredLocalServers]: (input) => | 2893 | [WS_METHODS.subscribeDiscoveredLocalServers]: (input) => |
| 3577 | observeRpcStream( | 2894 | Stream.callback<DiscoveredLocalServerList>((queue) => |
| 3578 | WS_METHODS.subscribeDiscoveredLocalServers, | 2895 | Effect.gen(function* () { |
| 3579 | Stream.callback<DiscoveredLocalServerList>((queue) => | 2896 | const configuredUrls = input.configuredUrls ?? []; |
| 3580 | Effect.gen(function* () { | 2897 | yield* portDiscovery.retain; |
| 3581 | const configuredUrls = input.configuredUrls ?? []; | 2898 | const initial = yield* portDiscovery.scan(configuredUrls); |
| 3582 | yield* portDiscovery.retain; | 2899 | const initialScannedAt = DateTime.formatIso(yield* DateTime.now); |
| 3583 | const initial = yield* portDiscovery.scan(configuredUrls); | 2900 | yield* Queue.offer(queue, { |
| 3584 | const initialScannedAt = DateTime.formatIso(yield* DateTime.now); | 2901 | servers: initial, |
| 3585 | yield* Queue.offer(queue, { | 2902 | scannedAt: initialScannedAt, |
| 3586 | servers: initial, | 2903 | configuredUrlProbing: true, |
| 3587 | scannedAt: initialScannedAt, | 2904 | }); |
| 3588 | configuredUrlProbing: true, | 2905 | yield* portDiscovery.subscribe( |
| 3589 | }); | 2906 | { configuredUrls, initialSnapshot: initial }, |
| 3590 | yield* portDiscovery.subscribe( | 2907 | (servers) => |
| 3591 | { configuredUrls, initialSnapshot: initial }, | 2908 | Effect.gen(function* () { |
| 3592 | (servers) => | 2909 | const scannedAt = DateTime.formatIso(yield* DateTime.now); |
| 3593 | Effect.gen(function* () { | 2910 | yield* Queue.offer(queue, { |
| 3594 | const scannedAt = DateTime.formatIso(yield* DateTime.now); | 2911 | servers, |
| 3595 | yield* Queue.offer(queue, { | 2912 | scannedAt, |
| 3596 | servers, | 2913 | configuredUrlProbing: true, |
| 3597 | scannedAt, | 2914 | }); |
| 3598 | configuredUrlProbing: true, | 2915 | }), |
| 3599 | }); | 2916 | ); |
| 3600 | }), | 2917 | }), |
| 3601 | ); | | |
| 3602 | }), | | |
| 3603 | ), | | |
| 3604 | { "rpc.aggregate": "preview" }, | | |
| 3605 | ), | 2918 | ), |
| 3606 | [WS_METHODS.subscribeServerConfig]: (input) => | 2919 | [WS_METHODS.subscribeServerConfig]: (input) => |
| 3607 | observeRpcStreamEffect( | 2920 | Stream.unwrap( |
| 3608 | WS_METHODS.subscribeServerConfig, | | |
| 3609 | Effect.gen(function* () { | 2921 | Effect.gen(function* () { |
| 3610 | const usageLimitsCommand = input.usageLimitsCommand === true; | 2922 | const usageLimitsCommand = input.usageLimitsCommand === true; |
| 3611 | const config = yield* loadServerConfig({ usageLimitsCommand }); | 2923 | const config = yield* loadServerConfig({ usageLimitsCommand }); |
| ... | @@ -3705,11 +3017,9 @@ const layerWsRpc = ( | ... | @@ -3705,11 +3017,9 @@ const layerWsRpc = ( |
| 3705 | withLateEditorConfig(config, liveUpdates, externalLauncher), | 3017 | withLateEditorConfig(config, liveUpdates, externalLauncher), |
| 3706 | ); | 3018 | ); |
| 3707 | }), | 3019 | }), |
| 3708 | { "rpc.aggregate": "server" }, | | |
| 3709 | ), | 3020 | ), |
| 3710 | [WS_METHODS.subscribeServerLifecycle]: (_input) => | 3021 | [WS_METHODS.subscribeServerLifecycle]: (_input) => |
| 3711 | observeRpcStreamEffect( | 3022 | Stream.unwrap( |
| 3712 | WS_METHODS.subscribeServerLifecycle, | | |
| 3713 | Effect.gen(function* () { | 3023 | Effect.gen(function* () { |
| 3714 | const liveBuffer = yield* Queue.unbounded<ServerLifecycleStreamEvent>(); | 3024 | const liveBuffer = yield* Queue.unbounded<ServerLifecycleStreamEvent>(); |
| 3715 | yield* Effect.forkScoped( | 3025 | yield* Effect.forkScoped( |
| ... | @@ -3727,11 +3037,9 @@ const layerWsRpc = ( | ... | @@ -3727,11 +3037,9 @@ const layerWsRpc = ( |
| 3727 | ); | 3037 | ); |
| 3728 | return Stream.concat(rpcInitialItems(snapshotEvents), liveEvents); | 3038 | return Stream.concat(rpcInitialItems(snapshotEvents), liveEvents); |
| 3729 | }), | 3039 | }), |
| 3730 | { "rpc.aggregate": "server" }, | | |
| 3731 | ), | 3040 | ), |
| 3732 | [WS_METHODS.subscribeAuthAccess]: (_input) => | 3041 | [WS_METHODS.subscribeAuthAccess]: (_input) => |
| 3733 | observeRpcStreamEffect( | 3042 | Stream.unwrap( |
| 3734 | WS_METHODS.subscribeAuthAccess, | | |
| 3735 | Effect.gen(function* () { | 3043 | Effect.gen(function* () { |
| 3736 | const initialSnapshot = yield* loadAuthAccessSnapshot(); | 3044 | const initialSnapshot = yield* loadAuthAccessSnapshot(); |
| 3737 | const revisionRef = yield* Ref.make(1); | 3045 | const revisionRef = yield* Ref.make(1); |
| ... | @@ -3761,27 +3069,18 @@ const layerWsRpc = ( | ... | @@ -3761,27 +3069,18 @@ const layerWsRpc = ( |
| 3761 | liveEvents, | 3069 | liveEvents, |
| 3762 | ); | 3070 | ); |
| 3763 | }), | 3071 | }), |
| 3764 | { "rpc.aggregate": "auth" }, | | |
| 3765 | ), | 3072 | ), |
| 3766 | [WS_METHODS.subscribeBackgroundPolicy]: (_input) => | 3073 | [WS_METHODS.subscribeBackgroundPolicy]: (_input) => |
| 3767 | observeRpcStream( | 3074 | Stream.unwrap( |
| 3768 | WS_METHODS.subscribeBackgroundPolicy, | 3075 | Effect.map(backgroundPolicy.subscribe, ({ latest, changes }) => |
| 3769 | Stream.unwrap( | 3076 | Stream.concat(Stream.make(latest), changes), |
| 3770 | Effect.map(backgroundPolicy.subscribe, ({ latest, changes }) => | | |
| 3771 | Stream.concat(Stream.make(latest), changes), | | |
| 3772 | ), | | |
| 3773 | ), | 3077 | ), |
| 3774 | { "rpc.aggregate": "server" }, | | |
| 3775 | ), | 3078 | ), |
| 3776 | [WS_METHODS.subscribeResourceTelemetry]: (_input) => | 3079 | [WS_METHODS.subscribeResourceTelemetry]: (_input) => |
| 3777 | observeRpcStream( | 3080 | Stream.unwrap( |
| 3778 | WS_METHODS.subscribeResourceTelemetry, | 3081 | Effect.map(resourceTelemetry.subscribe, ({ latest, changes }) => |
| 3779 | Stream.unwrap( | 3082 | Stream.concat(Stream.make(latest), changes), |
| 3780 | Effect.map(resourceTelemetry.subscribe, ({ latest, changes }) => | | |
| 3781 | Stream.concat(Stream.make(latest), changes), | | |
| 3782 | ), | | |
| 3783 | ), | 3083 | ), |
| 3784 | { "rpc.aggregate": "server" }, | | |
| 3785 | ), | 3084 | ), |
| 3786 | }); | 3085 | }); |
| 3787 | return handlers; | 3086 | return handlers; |
| ... | @@ -3841,7 +3140,9 @@ export const layer = Layer.unwrap( | ... | @@ -3841,7 +3140,9 @@ export const layer = Layer.unwrap( |
| 3841 | const { protocol, httpEffect } = yield* RpcServer.makeProtocolWithHttpEffectWebsocket; | 3140 | const { protocol, httpEffect } = yield* RpcServer.makeProtocolWithHttpEffectWebsocket; |
| 3842 | yield* RpcServer.make(ServerWsRpcGroup, WS_RPC_SERVER_OPTIONS).pipe( | 3141 | yield* RpcServer.make(ServerWsRpcGroup, WS_RPC_SERVER_OPTIONS).pipe( |
| 3843 | Effect.provideService(RpcServer.Protocol, withTerminalOutputWindow(protocol)), | 3142 | Effect.provideService(RpcServer.Protocol, withTerminalOutputWindow(protocol)), |
| 3844 | Effect.provide(RpcAuthorization.layer(session.scopes)), | 3143 | Effect.provide( |
| | 3144 | Layer.merge(RpcAuthorization.layer(session.scopes), rpcInstrumentationLayer), |
| | 3145 | ), |
| 3845 | Effect.forkScoped, | 3146 | Effect.forkScoped, |
| 3846 | ); | 3147 | ); |
| 3847 | // @effect-diagnostics-next-line returnEffectInGen:off | 3148 | // @effect-diagnostics-next-line returnEffectInGen:off |