nolo-cli 0.1.30 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-runtime/agentRecordConfig.ts +0 -2
- package/agent-runtime/hostAdapter.ts +0 -1
- package/agent-runtime/hostRuntimeCapabilities.ts +7 -0
- package/agent-runtime/hostRuntimeConfig.ts +86 -0
- package/agent-runtime/index.ts +13 -0
- package/agent-runtime/localToolPolicy.ts +13 -6
- package/agent-runtime/localWorkspaceTools.ts +333 -30
- package/agent-runtime/platformChatProvider.ts +4 -1
- package/agent-runtime/runtimeToolPolicy.ts +32 -47
- package/agent-runtime/shellCommandPolicy.ts +117 -0
- package/agent-runtime/toolGate.ts +38 -0
- package/agentRecordCommands.ts +1 -1
- package/agentRecordHelpers.ts +35 -20
- package/agentRunParsing.ts +18 -5
- package/agentRuntimeLocal.ts +10 -0
- package/ai/agent/agentRunDialogLineage.ts +56 -0
- package/ai/agent/agentSlice.ts +45 -10
- package/ai/agent/avatarUtils.ts +1 -1
- package/ai/agent/buildSystemPrompt.ts +1 -2
- package/ai/agent/cliExecutor.ts +330 -19
- package/ai/agent/createAgentSchema.ts +22 -0
- package/ai/agent/hooks/fetchPublicAgents.ts +14 -39
- package/ai/agent/hooks/usePublicAgents.ts +90 -192
- package/ai/agent/publicAgentCatalog.ts +359 -0
- package/ai/agent/publicAgentIdentity.ts +76 -0
- package/ai/agent/server/fetchPublicAgents.ts +21 -46
- package/ai/agent/serverOrigin.ts +7 -0
- package/ai/agent/streamAgentChatTurn.ts +23 -21
- package/ai/agent/streamAgentChatTurnUtils.ts +292 -6
- package/ai/agent/types.ts +2 -0
- package/ai/agent/web/agentDisplayUtils.ts +171 -0
- package/ai/agent/web/useAgentModelAvatarComponent.ts +32 -0
- package/ai/ai.locale.ts +8 -0
- package/ai/chat/sendOpenAICompletionsRequest.native.ts +15 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +93 -1
- package/ai/chat/sendOpenAIResponseRequest.ts +86 -9
- package/ai/chat/updateTotalUsage.ts +7 -0
- package/ai/llm/deepinfra.ts +30 -15
- package/ai/llm/mistral.ts +3 -4
- package/ai/llm/providers.ts +2 -0
- package/ai/llm/types.ts +15 -0
- package/ai/memory/capture.ts +3 -3
- package/ai/memory/consolidate.ts +2 -2
- package/ai/memory/delete.ts +4 -3
- package/ai/memory/query.ts +3 -3
- package/ai/memory/remember.ts +2 -2
- package/ai/memory/store.ts +3 -3
- package/ai/memory/storeShared.ts +3 -2
- package/ai/policy/commercialMultiplier.ts +16 -0
- package/ai/token/billingAdminAuditEvent.ts +68 -0
- package/ai/token/billingAdminAuditEventWriter.ts +41 -0
- package/ai/token/billingAnomaly.ts +90 -0
- package/ai/token/billingAnomalyLifecycle.ts +54 -0
- package/ai/token/billingAnomalyLifecycleWriter.ts +44 -0
- package/ai/token/billingAnomalyWriter.ts +41 -0
- package/ai/token/calculatePrice.ts +3 -2
- package/ai/token/deepinfraReconciliation.ts +153 -0
- package/ai/token/deepinfraRequestIdQuery.ts +92 -0
- package/ai/token/externalToolCost.ts +54 -41
- package/ai/token/missingUsageEstimate.ts +12 -3
- package/ai/token/normalizeUsage.ts +45 -5
- package/ai/token/openaiReconciliation.ts +188 -0
- package/ai/token/providerBillableEvent.ts +84 -0
- package/ai/token/providerBillableEventWriter.ts +36 -0
- package/ai/token/providerBillingAnomalyDrilldown.ts +308 -0
- package/ai/token/providerBillingDrilldown.ts +361 -0
- package/ai/token/providerBillingHealthReport.ts +366 -0
- package/ai/token/providerCall.ts +144 -0
- package/ai/token/providerCallSweeper.ts +168 -0
- package/ai/token/providerCallWriter.ts +33 -0
- package/ai/token/providerCredential.ts +89 -0
- package/ai/token/providerCredentialAnomaly.ts +154 -0
- package/ai/token/providerCredentialLifecycle.ts +59 -0
- package/ai/token/providerCredentialLifecycleWriter.ts +44 -0
- package/ai/token/providerCredentialRegistry.ts +83 -0
- package/ai/token/providerCredentialRegistryCommand.ts +97 -0
- package/ai/token/providerCredentialRegistryList.ts +124 -0
- package/ai/token/providerCredentialRegistryResolver.ts +150 -0
- package/ai/token/providerCredentialRegistryWriter.ts +41 -0
- package/ai/token/providerCredentialRotationCommand.ts +102 -0
- package/ai/token/providerCredentialRuntime.ts +56 -0
- package/ai/token/providerDispatchIntent.ts +67 -0
- package/ai/token/providerDispatchIntentWriter.ts +36 -0
- package/ai/token/providerGateway.ts +260 -0
- package/ai/token/providerReconciliation.ts +148 -0
- package/ai/token/providerReconciliationLocal.ts +97 -0
- package/ai/token/providerReconciliationRunner.ts +165 -0
- package/ai/token/providerReconciliationWriter.ts +41 -0
- package/ai/token/ratingResult.ts +202 -0
- package/ai/token/ratingResultWriter.ts +33 -0
- package/ai/token/serverDialogProjection.ts +5 -3
- package/ai/token/serverTokenWriter.ts +11 -3
- package/ai/token/types.ts +10 -0
- package/ai/tools/agent/callAgentTool.ts +3 -4
- package/ai/tools/agent/presets/appBuilderPreset.ts +5 -7
- package/ai/tools/agent/runStreamingAgentTool.ts +1 -2
- package/ai/tools/agent/streamParallelAgentsTool.ts +2 -3
- package/ai/tools/readXPostTool.ts +1 -5
- package/app/admin/adminPages.ts +9 -0
- package/app/i18n/i18n.config.ts +5 -0
- package/app/i18n/translations/pricing.locale.ts +397 -0
- package/app/utils/desktopAgentRuntimeStatusClient.ts +5 -4
- package/app/utils/desktopAgentRuntimeTurnClient.ts +4 -1
- package/app/utils/imageUtils.ts +64 -34
- package/auth/adminPermissions.ts +18 -0
- package/auth/authSlice.ts +26 -12
- package/auth/hooks/useFetchUsers.ts +3 -0
- package/auth/routes.ts +46 -0
- package/auth/server/accessActivity.ts +4 -3
- package/auth/server/adminPermissions.ts +43 -0
- package/auth/server/adminUsageReport.ts +375 -0
- package/auth/server/billingAnomalies.ts +235 -0
- package/auth/server/billingUsageReport.ts +41 -2
- package/auth/server/creatorEarningCreditConversion.ts +10 -2
- package/auth/server/deduct.ts +14 -7
- package/auth/server/delete.ts +10 -2
- package/auth/server/disable.ts +4 -3
- package/auth/server/emailAutomation.ts +7 -5
- package/auth/server/emailDbConfig.ts +4 -2
- package/auth/server/emailDelivery.ts +24 -20
- package/auth/server/emailDeliveryGuards.ts +10 -7
- package/auth/server/emailPreferences.ts +6 -4
- package/auth/server/emailReport.ts +6 -4
- package/auth/server/emailRuntimeConfig.ts +3 -3
- package/auth/server/emailScenarioNotifications.ts +9 -8
- package/auth/server/enable.ts +4 -3
- package/auth/server/getRechargeHistory.ts +3 -2
- package/auth/server/getUser.ts +3 -2
- package/auth/server/gptProAccess.ts +44 -0
- package/auth/server/inviteReward.ts +10 -7
- package/auth/server/listusers.ts +6 -4
- package/auth/server/login.ts +2 -2
- package/auth/server/productEntitlements.ts +7 -4
- package/auth/server/productPurchase.ts +10 -2
- package/auth/server/providerBillingDrilldown.ts +47 -0
- package/auth/server/providerBillingHealth.ts +71 -0
- package/auth/server/providerCredentials.ts +136 -0
- package/auth/server/recharge.ts +14 -8
- package/auth/server/revokeSessions.ts +4 -3
- package/auth/server/route.ts +77 -0
- package/auth/server/sendEmail.ts +5 -4
- package/auth/server/signup.ts +10 -3
- package/auth/server/token.ts +53 -55
- package/auth/server/tokenUsageBilling.ts +18 -7
- package/auth/server/usageManagementAccess.ts +43 -0
- package/auth/server/usageReport.ts +59 -0
- package/auth/types.ts +12 -0
- package/auth/utils.ts +24 -22
- package/authCommands.ts +36 -2
- package/buildPublish.ts +3 -1
- package/buildPublishArtifactAssembly.ts +62 -1
- package/buildPublishImportAnalysis.ts +21 -16
- package/chat/dialog/dialogLaunchScope.ts +32 -0
- package/chat/dialog/objectAssistantRegistry.ts +2 -2
- package/chat/dialog/useCreateDialog.ts +1 -1
- package/chat/hooks/useChatInput.ts +41 -10
- package/chat/messages/messageSlice.ts +5 -1
- package/chat/messages/pendingAttachmentParts.ts +28 -2
- package/chat/messages/sendFirstMessage.ts +76 -79
- package/chat/messages/types.ts +9 -0
- package/chat/messages/web/streamingMarkdownModel.ts +41 -0
- package/chat/messages/web/useStreamingReveal.ts +91 -0
- package/chat/web/messageInputAgentUi.ts +94 -6
- package/cliEnvHelpers.ts +8 -0
- package/cliRuntimeDoctorReport.ts +193 -0
- package/client/agentConfigResolver.test.ts +0 -2
- package/client/agentRun.test.ts +171 -10
- package/client/agentRun.ts +44 -637
- package/client/agentRunInput.ts +10 -0
- package/client/agentRunLocalExecutor.ts +179 -0
- package/client/agentRunServerTransport.ts +394 -0
- package/client/agentRunTaskRunRecorder.ts +176 -0
- package/client/localRuntimeAdapter.test.ts +236 -9
- package/client/localRuntimeAdapter.ts +221 -23
- package/client/localToolPolicy.test.ts +28 -4
- package/connector-experimental/daemonLauncher.ts +38 -4
- package/connectorRunArtifact.ts +34 -10
- package/connectorWebSocketTarget.ts +9 -5
- package/core/builtinAgents.ts +155 -11
- package/create/space/contentLabels.ts +1 -1
- package/create/space/contentTypeMeta.ts +3 -2
- package/create/space/sidebarVisibleTypes.ts +27 -0
- package/create/space/space.locale.ts +76 -4
- package/database/actions/agentReadResolution.ts +2 -8
- package/database/actions/read.ts +11 -9
- package/database/actions/readAndWait.ts +10 -5
- package/database/server/agentDelegation.ts +3 -2
- package/database/server/authorityStoreConformance.ts +209 -0
- package/database/server/authorityStoreTypes.ts +31 -0
- package/database/server/coreDataProxy.ts +1 -1
- package/database/server/dataHandlers.ts +13 -5
- package/database/server/db.ts +15 -34
- package/database/server/delete.ts +88 -71
- package/database/server/emailRepository.ts +11 -9
- package/database/server/fileService.ts +2 -1
- package/database/server/legacyServerDb.ts +58 -0
- package/database/server/levelAuthorityStore.ts +75 -0
- package/database/server/memoryAuthorityStore.ts +133 -0
- package/database/server/patch.ts +13 -12
- package/database/server/query.ts +3 -2
- package/database/server/read.ts +33 -30
- package/database/server/resourceAccess.ts +7 -5
- package/database/server/serverStoreFactory.ts +124 -0
- package/database/server/spaceMemberAuthority.ts +3 -2
- package/database/server/storeBatchCompat.ts +37 -0
- package/database/server/testAuthorityStore.ts +76 -0
- package/database/server/write.ts +29 -27
- package/integrations/anthropic/anthropicModels.ts +12 -12
- package/integrations/deepseek/models.ts +67 -67
- package/integrations/google/models.ts +111 -53
- package/integrations/openai/models.ts +22 -22
- package/integrations/xai/models.ts +1 -1
- package/localRuntimeDb.ts +39 -2
- package/machineCommandPrompts.ts +2 -0
- package/machineCommands.ts +193 -63
- package/machineWsRunDispatch.ts +80 -15
- package/machineWsSession.ts +39 -2
- package/noloReadBridgePrompt.ts +16 -0
- package/package.json +99 -6
- package/render/layout/mainLayoutViewMode.ts +25 -0
- package/render/page/server/createPage.ts +3 -1
- package/render/page/server/handleCreatePage.ts +2 -11
- package/runtimeDoctorCommands.ts +15 -66
- package/server/api/methods.ts +34 -12
- package/server/api/tableHandlers.ts +6 -3
- package/server/authenticateToken.ts +47 -2
- package/server/billingLedgerRoutes.ts +15 -0
- package/server/buildManifest.ts +54 -0
- package/server/coreReadiness.ts +34 -25
- package/server/coreRuntime.ts +15 -10
- package/server/handlers/activityStatsHandler.ts +5 -2
- package/server/handlers/agentEmailRegistrationE2EHandler.ts +25 -23
- package/server/handlers/agentRun/agentLookup.ts +1 -7
- package/server/handlers/agentRun/autonomousRuntime.ts +11 -10
- package/server/handlers/agentRun/builtinAgents.ts +12 -88
- package/server/handlers/agentRun/continueDialogContext.ts +15 -3
- package/server/handlers/agentRun/{inheritedDialogPrompt.ts → conversationReference.ts} +3 -3
- package/server/handlers/agentRun/dialogLookup.ts +4 -3
- package/server/handlers/agentRun/index.ts +864 -404
- package/server/handlers/agentRun/localRuntimeBootstrap.ts +17 -1
- package/server/handlers/agentRun/loop.ts +920 -508
- package/server/handlers/agentRun/machineConnector.ts +56 -8
- package/server/handlers/agentRun/machineRunAudit.ts +3 -2
- package/server/handlers/agentRun/modelUsageToolHandlers.ts +13 -10
- package/server/handlers/agentRun/requestContext.ts +12 -8
- package/server/handlers/agentRun/runtimeExecutionContext.ts +15 -3
- package/server/handlers/agentRun/runtimePreparation.ts +26 -24
- package/server/handlers/agentRun/runtimeRouting.ts +25 -40
- package/server/handlers/agentRun/runtimeSystemMessages.ts +65 -0
- package/server/handlers/agentRun/saveDialog.ts +97 -87
- package/server/handlers/agentRun/taskRunToolHandler.ts +9 -7
- package/server/handlers/agentRun/toolExecutor.ts +42 -78
- package/server/handlers/agentRun/types.ts +2 -1
- package/server/handlers/appDeployStatusStore.ts +17 -10
- package/server/handlers/appDomainHandler.ts +21 -15
- package/server/handlers/appLegacyInfraCleanup.ts +5 -2
- package/server/handlers/appSandboxHandler.ts +29 -8
- package/server/handlers/appSpaceAccess.ts +15 -8
- package/server/handlers/chatHandler.ts +22 -2
- package/server/handlers/chatUpstreamRetry.ts +225 -2
- package/server/handlers/connector/connectorConnectionRegistry.ts +55 -7
- package/server/handlers/connector/connectorWebSocket.ts +14 -10
- package/server/handlers/desktopAgentRuntimeAdapter.ts +4 -4
- package/server/handlers/desktopAgentRuntimeHostCapabilities.ts +25 -0
- package/server/handlers/desktopAgentRuntimeReadiness.ts +62 -0
- package/server/handlers/desktopAgentRuntimeStatusHandler.ts +38 -30
- package/server/handlers/desktopAgentRuntimeTurnHandler.ts +7 -3
- package/server/handlers/desktopAgentRuntimeTurnService.ts +39 -45
- package/server/handlers/desktopLlamaRuntimeHandler.ts +85 -51
- package/server/handlers/desktopUpdaterHandler.ts +132 -24
- package/server/handlers/favoriteHandlers.ts +8 -2
- package/server/handlers/getDialogBillingHandler.ts +4 -3
- package/server/handlers/getTransactionsHandler.ts +5 -2
- package/server/handlers/machines/machineBinding.ts +1 -0
- package/server/handlers/machines/machineHandlers.ts +0 -14
- package/server/handlers/machines/machineInstallAssets.ts +4 -2
- package/server/handlers/notificationEmitter.ts +5 -3
- package/server/handlers/notificationsHandler.ts +5 -2
- package/server/handlers/providerCallsRecentHandler.ts +234 -0
- package/server/handlers/providerReconciliationRunHandler.ts +180 -0
- package/server/handlers/providerRequestIdsHandler.ts +105 -0
- package/server/handlers/tableAccess.ts +6 -2
- package/server/handlers/tableToolHandlers.ts +28 -14
- package/server/handlers/userSecretsHandler.ts +17 -6
- package/server/handlers/versionHandler.ts +9 -4
- package/server/handlers/versionStore.ts +18 -10
- package/server/html/ssrPreload.ts +5 -3
- package/server/payments/crypto/cryptoUsdcBasePaymentProvider.ts +11 -8
- package/server/payments/crypto/cryptoUsdcBaseScanner.ts +12 -7
- package/server/payments/crypto/cryptoUsdtTronPaymentProvider.ts +11 -8
- package/server/payments/crypto/cryptoUsdtTronScanner.ts +9 -7
- package/server/payments/waffo/waffoPaymentProvider.ts +12 -9
- package/server/runtimeRole.ts +15 -0
- package/server/scheduler/scheduledTaskRuntime.ts +4 -2
- package/server/scheduler/schedulerService.ts +2 -2
- package/server/taskRunBridgeRoutes.ts +8 -5
- package/share/server/fetchCommunityShares.ts +1 -1
- package/share/server/helpers.ts +19 -17
- package/share/server/importShare.ts +9 -13
- package/share/server/listCommunityShares.ts +4 -4
- package/share/server/purchaseDoc.ts +8 -16
- package/share/server/readCommunityShareCover.ts +3 -2
- package/share/server/readSharedTable.ts +14 -13
- package/share/server/tableReplication.ts +42 -39
- package/spaceAttachCommands.ts +135 -0
- package/spaceInternalCommandEntries.ts +2 -0
- package/ai/agent/runtimeServerBase.ts +0 -37
- package/server/handlers/desktopAgentRuntimeHostFacts.ts +0 -40
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentRuntimeMessageContent } from "../../agent-runtime";
|
|
2
|
+
import { normalizeAgentRunDialogLineage } from "../../ai/agent/agentRunDialogLineage";
|
|
2
3
|
import { parseToken } from "../../auth/token";
|
|
3
4
|
import { WEB_AUTH_TOKEN_COOKIE } from "../../auth/tokenCookie";
|
|
4
5
|
import {
|
|
@@ -7,7 +8,7 @@ import {
|
|
|
7
8
|
type DesktopTextOnlyAgentRuntimeTurnInput,
|
|
8
9
|
} from "./desktopAgentRuntimeTurnService";
|
|
9
10
|
import type { DesktopAgentRuntimeRecordStore } from "./desktopAgentRuntimeAdapter";
|
|
10
|
-
import type { DesktopAgentRuntimeEnv } from "./
|
|
11
|
+
import type { DesktopAgentRuntimeEnv } from "./desktopAgentRuntimeHostCapabilities";
|
|
11
12
|
|
|
12
13
|
type DesktopAgentRuntimeTurnBody = {
|
|
13
14
|
agentRef: string;
|
|
@@ -87,11 +88,14 @@ function parseDesktopAgentRuntimeTurnBody(body: unknown): DesktopAgentRuntimeTur
|
|
|
87
88
|
const record = body as Record<string, unknown>;
|
|
88
89
|
if (typeof record.agentRef !== "string" || !record.agentRef.trim()) return null;
|
|
89
90
|
if (!isAgentRuntimeMessageContent(record.input)) return null;
|
|
91
|
+
const dialogLineage = normalizeAgentRunDialogLineage({
|
|
92
|
+
continueDialogId: record.continueDialogId,
|
|
93
|
+
});
|
|
90
94
|
return {
|
|
91
95
|
agentRef: record.agentRef.trim(),
|
|
92
96
|
input: record.input,
|
|
93
|
-
...(
|
|
94
|
-
? { continueDialogId:
|
|
97
|
+
...(dialogLineage.continueDialogId
|
|
98
|
+
? { continueDialogId: dialogLineage.continueDialogId }
|
|
95
99
|
: {}),
|
|
96
100
|
...(typeof record.maxToolRounds === "number" && Number.isFinite(record.maxToolRounds)
|
|
97
101
|
? { maxToolRounds: Math.max(0, Math.floor(record.maxToolRounds)) }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AgentRuntimeAgentConfig,
|
|
3
|
+
HostRuntimeConfig,
|
|
3
4
|
AgentRuntimeMessageContent,
|
|
4
5
|
AgentRuntimeProvider,
|
|
5
6
|
AgentRuntimeToolCallInput,
|
|
@@ -13,11 +14,14 @@ import {
|
|
|
13
14
|
createWorkspaceSession,
|
|
14
15
|
executeLocalToolWithPolicy,
|
|
15
16
|
prepareGitTaskWorkspace,
|
|
17
|
+
resolveHostRuntimeConfigFromEnv,
|
|
18
|
+
resolveRequestedRuntimeToolNames,
|
|
16
19
|
runLocalAgentTurn,
|
|
17
20
|
} from "../../agent-runtime";
|
|
18
21
|
import {
|
|
19
22
|
buildLocalWorkspaceOpenAiTools,
|
|
20
23
|
buildLocalWorkspacePolicyToolNames,
|
|
24
|
+
resolveLocalWorkspaceShellToolExposure,
|
|
21
25
|
buildLocalWorkspaceToolset,
|
|
22
26
|
createLocalWorkspaceToolExecutors,
|
|
23
27
|
} from "../../agent-runtime/localWorkspaceTools";
|
|
@@ -28,10 +32,11 @@ import {
|
|
|
28
32
|
type DesktopAgentRuntimeActions,
|
|
29
33
|
type DesktopAgentRuntimeRecordStore,
|
|
30
34
|
} from "./desktopAgentRuntimeAdapter";
|
|
31
|
-
import type { DesktopAgentRuntimeEnv } from "./
|
|
35
|
+
import type { DesktopAgentRuntimeEnv } from "./desktopAgentRuntimeHostCapabilities";
|
|
32
36
|
|
|
33
37
|
type DesktopAgentRuntimeBaseTurnInput = {
|
|
34
38
|
env: DesktopAgentRuntimeEnv;
|
|
39
|
+
hostRuntimeConfig?: HostRuntimeConfig;
|
|
35
40
|
store: DesktopAgentRuntimeRecordStore;
|
|
36
41
|
agentRef: string;
|
|
37
42
|
input: AgentRuntimeMessageContent;
|
|
@@ -75,8 +80,8 @@ export function createDesktopAgentRuntimeDialogId() {
|
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
function buildDesktopOpenAiTools(args: {
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
requestedToolNames?: string[];
|
|
84
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
80
85
|
}) {
|
|
81
86
|
const toolset = buildDesktopLocalWorkspaceToolset(args);
|
|
82
87
|
return buildLocalWorkspaceOpenAiTools({
|
|
@@ -86,29 +91,31 @@ function buildDesktopOpenAiTools(args: {
|
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
function buildDesktopLocalWorkspaceToolset(args: {
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
requestedToolNames?: string[];
|
|
95
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
91
96
|
}) {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
const requestedToolNames = args.requestedToolNames ?? [];
|
|
98
|
+
const exposeShellTools = resolveLocalWorkspaceShellToolExposure({
|
|
99
|
+
declaredToolNames: requestedToolNames,
|
|
100
|
+
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
101
|
+
});
|
|
95
102
|
const toolset = buildLocalWorkspaceToolset({
|
|
96
|
-
declaredToolNames:
|
|
97
|
-
exposeShellTools
|
|
103
|
+
declaredToolNames: requestedToolNames,
|
|
104
|
+
exposeShellTools,
|
|
98
105
|
});
|
|
99
106
|
return toolset;
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
function buildDesktopLocalPolicyToolNames(args: {
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
requestedToolNames?: string[];
|
|
111
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
105
112
|
}) {
|
|
106
|
-
const shellModeEnabled = ["worktree", "dangerous", "1", "true"].includes(
|
|
107
|
-
args.env.NOLO_LOCAL_SHELL_MODE || ""
|
|
108
|
-
);
|
|
109
113
|
return buildLocalWorkspacePolicyToolNames({
|
|
110
|
-
declaredToolNames: args.
|
|
111
|
-
exposeShellTools:
|
|
114
|
+
declaredToolNames: args.requestedToolNames,
|
|
115
|
+
exposeShellTools: resolveLocalWorkspaceShellToolExposure({
|
|
116
|
+
declaredToolNames: args.requestedToolNames,
|
|
117
|
+
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
118
|
+
}),
|
|
112
119
|
});
|
|
113
120
|
}
|
|
114
121
|
|
|
@@ -120,23 +127,6 @@ function buildDesktopLocalToolExecutors(args: {
|
|
|
120
127
|
};
|
|
121
128
|
}
|
|
122
129
|
|
|
123
|
-
function resolveDesktopRuntimePolicyEnv(args: {
|
|
124
|
-
env: DesktopAgentRuntimeEnv;
|
|
125
|
-
agentConfig: AgentRuntimeAgentConfig;
|
|
126
|
-
}): DesktopAgentRuntimeEnv {
|
|
127
|
-
const policy = args.agentConfig.runtimeToolPolicy;
|
|
128
|
-
const shellPolicy = policy?.shell;
|
|
129
|
-
const enablesWorktreeShell =
|
|
130
|
-
shellPolicy?.enabled === true && shellPolicy.mode === "worktree";
|
|
131
|
-
if (!enablesWorktreeShell || args.env.NOLO_LOCAL_SHELL_MODE) {
|
|
132
|
-
return args.env;
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
...args.env,
|
|
136
|
-
NOLO_LOCAL_SHELL_MODE: "worktree",
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
130
|
function resolveDesktopRuntimeWorkspaceMode(args: {
|
|
141
131
|
agentConfig: AgentRuntimeAgentConfig;
|
|
142
132
|
hasExplicitCwd: boolean;
|
|
@@ -236,6 +226,7 @@ export function createDesktopTextOnlyAgentRuntimeActions(args: {
|
|
|
236
226
|
|
|
237
227
|
export function createDesktopAgentRuntimeActions(args: {
|
|
238
228
|
env: DesktopAgentRuntimeEnv;
|
|
229
|
+
hostRuntimeConfig?: HostRuntimeConfig;
|
|
239
230
|
store: DesktopAgentRuntimeRecordStore;
|
|
240
231
|
now: () => number;
|
|
241
232
|
createId: () => string;
|
|
@@ -244,7 +235,11 @@ export function createDesktopAgentRuntimeActions(args: {
|
|
|
244
235
|
prepareTaskWorkspace?: PrepareTaskWorkspace;
|
|
245
236
|
}): DesktopAgentRuntimeActions {
|
|
246
237
|
let activeAgentToolNames: string[] = [];
|
|
247
|
-
|
|
238
|
+
const hostRuntimeConfig = args.hostRuntimeConfig ?? resolveHostRuntimeConfigFromEnv({
|
|
239
|
+
env: args.env,
|
|
240
|
+
surface: "desktop",
|
|
241
|
+
workspaceBinding: args.cwd ? "explicit-cwd" : "default-cwd",
|
|
242
|
+
});
|
|
248
243
|
let workspaceSession = createWorkspaceSession({ cwd: args.cwd });
|
|
249
244
|
let executors = buildDesktopLocalToolExecutors({ workspaceRoot: workspaceSession.workspaceRoot });
|
|
250
245
|
return createDesktopAgentRuntimeRecordStoreActions({
|
|
@@ -254,13 +249,10 @@ export function createDesktopAgentRuntimeActions(args: {
|
|
|
254
249
|
createId: args.createId,
|
|
255
250
|
getWorkspaceRoot: () => workspaceSession.workspaceRoot,
|
|
256
251
|
resolveProvider: async (agentConfig) => {
|
|
257
|
-
|
|
258
|
-
env: args.env,
|
|
259
|
-
agentConfig,
|
|
260
|
-
});
|
|
252
|
+
const requestedToolNames = resolveRequestedRuntimeToolNames({ agentConfig });
|
|
261
253
|
activeAgentToolNames = buildDesktopLocalPolicyToolNames({
|
|
262
|
-
|
|
263
|
-
|
|
254
|
+
requestedToolNames,
|
|
255
|
+
hostRuntimeConfig,
|
|
264
256
|
});
|
|
265
257
|
const workspaceMode = resolveDesktopRuntimeWorkspaceMode({
|
|
266
258
|
agentConfig,
|
|
@@ -272,7 +264,7 @@ export function createDesktopAgentRuntimeActions(args: {
|
|
|
272
264
|
workspaceSession = await activateWorkspaceSession(activationSession, {
|
|
273
265
|
agentKey: agentConfig.key,
|
|
274
266
|
mode: workspaceMode,
|
|
275
|
-
env:
|
|
267
|
+
env: args.env,
|
|
276
268
|
prepareTaskWorkspace: args.prepareTaskWorkspace ?? ((prepareArgs) => prepareGitTaskWorkspace({
|
|
277
269
|
...prepareArgs,
|
|
278
270
|
cwd: args.cwd,
|
|
@@ -286,13 +278,14 @@ export function createDesktopAgentRuntimeActions(args: {
|
|
|
286
278
|
agentConfig,
|
|
287
279
|
fetchImpl: args.fetchImpl,
|
|
288
280
|
tools: buildDesktopOpenAiTools({
|
|
289
|
-
|
|
290
|
-
|
|
281
|
+
requestedToolNames,
|
|
282
|
+
hostRuntimeConfig,
|
|
291
283
|
}),
|
|
292
284
|
});
|
|
293
285
|
},
|
|
294
286
|
executeTool: (call) => executeLocalToolWithPolicy({
|
|
295
|
-
env:
|
|
287
|
+
env: args.env,
|
|
288
|
+
hostRuntimeConfig,
|
|
296
289
|
agentToolNames: activeAgentToolNames,
|
|
297
290
|
call,
|
|
298
291
|
executors,
|
|
@@ -329,6 +322,7 @@ export async function runDesktopAgentRuntimeTurn(
|
|
|
329
322
|
): Promise<LocalAgentTurnResult> {
|
|
330
323
|
const actions = createDesktopAgentRuntimeActions({
|
|
331
324
|
env: input.env,
|
|
325
|
+
hostRuntimeConfig: input.hostRuntimeConfig,
|
|
332
326
|
store: input.store,
|
|
333
327
|
now: input.now ?? Date.now,
|
|
334
328
|
createId: input.createId ?? createDesktopAgentRuntimeDialogId,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, posix, win32 } from "node:path";
|
|
3
4
|
|
|
4
5
|
import { isPidRunning } from "../../../scripts/helpers/devProcessGuard";
|
|
5
6
|
import {
|
|
@@ -22,10 +23,12 @@ const JSON_HEADERS = {
|
|
|
22
23
|
"content-type": "application/json; charset=utf-8",
|
|
23
24
|
};
|
|
24
25
|
|
|
25
|
-
type DesktopLlamaRuntimeResponse = Omit<DesktopLlamaRuntimeSnapshot, "state"> & {
|
|
26
|
-
state: DesktopLlamaRuntimeSnapshot["state"] | "starting";
|
|
27
|
-
accepted?: boolean;
|
|
28
|
-
};
|
|
26
|
+
type DesktopLlamaRuntimeResponse = Omit<DesktopLlamaRuntimeSnapshot, "state"> & {
|
|
27
|
+
state: DesktopLlamaRuntimeSnapshot["state"] | "starting";
|
|
28
|
+
accepted?: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type DesktopProviderRuntimeSnapshot = DesktopLlamaRuntimeResponse;
|
|
29
32
|
|
|
30
33
|
type DesktopLlamaRuntimeHandlerController = {
|
|
31
34
|
status: () => Promise<DesktopLlamaRuntimeSnapshot>;
|
|
@@ -36,12 +39,13 @@ type DesktopLlamaRuntimeHandlerController = {
|
|
|
36
39
|
}>;
|
|
37
40
|
};
|
|
38
41
|
|
|
39
|
-
type DesktopLlamaRuntimeHandlerDeps = {
|
|
40
|
-
isDesktopMode?: () => boolean;
|
|
41
|
-
controller?: DesktopLlamaRuntimeHandlerController;
|
|
42
|
-
logger?: Pick<Console, "error">;
|
|
43
|
-
repoRoot?: string;
|
|
44
|
-
|
|
42
|
+
type DesktopLlamaRuntimeHandlerDeps = {
|
|
43
|
+
isDesktopMode?: () => boolean;
|
|
44
|
+
controller?: DesktopLlamaRuntimeHandlerController;
|
|
45
|
+
logger?: Pick<Console, "error">;
|
|
46
|
+
repoRoot?: string;
|
|
47
|
+
env?: NodeJS.ProcessEnv;
|
|
48
|
+
};
|
|
45
49
|
|
|
46
50
|
const json = (data: unknown, status = 200) =>
|
|
47
51
|
new Response(JSON.stringify(data), {
|
|
@@ -49,7 +53,7 @@ const json = (data: unknown, status = 200) =>
|
|
|
49
53
|
headers: JSON_HEADERS,
|
|
50
54
|
});
|
|
51
55
|
|
|
52
|
-
const defaultIsDesktopMode = () => process.env.NOLO_DESKTOP === "1";
|
|
56
|
+
const defaultIsDesktopMode = () => process.env.NOLO_DESKTOP === "1";
|
|
53
57
|
|
|
54
58
|
const notDesktopResponse = () =>
|
|
55
59
|
json({ error: "Desktop llama runtime is only available inside Nolo Desktop." }, 404);
|
|
@@ -66,11 +70,21 @@ export function configureDesktopLocalProviderEnv(config: Pick<LlamaLaunchConfig,
|
|
|
66
70
|
function formatError(error: unknown, fallback: string): string {
|
|
67
71
|
return error instanceof Error ? error.message : fallback;
|
|
68
72
|
}
|
|
69
|
-
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
)
|
|
73
|
-
const
|
|
73
|
+
|
|
74
|
+
export function resolveDesktopLlamaSupervisorLogDir(env: NodeJS.ProcessEnv): string | null {
|
|
75
|
+
const dbPath = env.NOLO_SERVER_DB_PATH?.trim();
|
|
76
|
+
if (!dbPath) return null;
|
|
77
|
+
const pathApi = dbPath.includes("\\") ? win32 : posix;
|
|
78
|
+
const channelDir = pathApi.dirname(pathApi.dirname(dbPath));
|
|
79
|
+
return pathApi.join(channelDir, "logs", "llama-supervisor");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function createDesktopLlamaRuntimeController(
|
|
83
|
+
repoRoot = process.cwd(),
|
|
84
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
85
|
+
): DesktopLlamaRuntimeHandlerController {
|
|
86
|
+
const desktopLogDir = resolveDesktopLlamaSupervisorLogDir(env);
|
|
87
|
+
const paths = resolveLlamaSupervisorPaths(desktopLogDir ? { logDir: desktopLogDir } : repoRoot);
|
|
74
88
|
|
|
75
89
|
const ensureLogDir = async () => {
|
|
76
90
|
await mkdir(paths.logDir, { recursive: true });
|
|
@@ -168,9 +182,24 @@ function createDesktopLlamaRuntimeController(
|
|
|
168
182
|
return config;
|
|
169
183
|
};
|
|
170
184
|
|
|
171
|
-
const probeHealth = (
|
|
172
|
-
config: Pick<LlamaLaunchConfig, "host" | "port" | "healthPath" | "modelsPath">,
|
|
173
|
-
) => probeLlamaHealth(config);
|
|
185
|
+
const probeHealth = (
|
|
186
|
+
config: Pick<LlamaLaunchConfig, "host" | "port" | "healthPath" | "modelsPath">,
|
|
187
|
+
) => probeLlamaHealth(config);
|
|
188
|
+
|
|
189
|
+
const resolveConfiguredLaunchConfig = async (): Promise<LlamaLaunchConfig | null> => {
|
|
190
|
+
const storedState = await readStoredState();
|
|
191
|
+
const localConfig = await readLocalConfigFile();
|
|
192
|
+
const config = resolveLlamaLaunchConfig({
|
|
193
|
+
storedConfig: {
|
|
194
|
+
...(storedState?.launchConfig ?? {}),
|
|
195
|
+
...(localConfig ?? {}),
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
if (config) {
|
|
199
|
+
configureDesktopLocalProviderEnv(config);
|
|
200
|
+
}
|
|
201
|
+
return config;
|
|
202
|
+
};
|
|
174
203
|
|
|
175
204
|
const stopManagedServer = () =>
|
|
176
205
|
stopManagedLlamaServer({
|
|
@@ -189,9 +218,9 @@ function createDesktopLlamaRuntimeController(
|
|
|
189
218
|
logFilePath: paths.logFile,
|
|
190
219
|
});
|
|
191
220
|
|
|
192
|
-
const runtimeController = createLlamaRuntimeController({
|
|
193
|
-
readStoredState,
|
|
194
|
-
readLocalConfigFile,
|
|
221
|
+
const runtimeController = createLlamaRuntimeController({
|
|
222
|
+
readStoredState,
|
|
223
|
+
readLocalConfigFile,
|
|
195
224
|
readManagedPid,
|
|
196
225
|
readWatchPid,
|
|
197
226
|
isPidRunning,
|
|
@@ -200,14 +229,17 @@ function createDesktopLlamaRuntimeController(
|
|
|
200
229
|
readLogTail: () => readLogTail(40),
|
|
201
230
|
});
|
|
202
231
|
|
|
203
|
-
return {
|
|
204
|
-
status: () =>
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
232
|
+
return {
|
|
233
|
+
status: async () => {
|
|
234
|
+
await resolveConfiguredLaunchConfig();
|
|
235
|
+
return runtimeController.status();
|
|
236
|
+
},
|
|
237
|
+
stop: () => runtimeController.stop(),
|
|
238
|
+
start: () =>
|
|
239
|
+
startLlamaRuntime({
|
|
240
|
+
resolveLaunchConfigOrThrow,
|
|
241
|
+
writeStoredState,
|
|
242
|
+
probeHealth,
|
|
211
243
|
readManagedPid,
|
|
212
244
|
isPidRunning,
|
|
213
245
|
stopManagedServer,
|
|
@@ -249,13 +281,13 @@ function buildResponseSnapshot(
|
|
|
249
281
|
return snapshot;
|
|
250
282
|
}
|
|
251
283
|
|
|
252
|
-
export function createDesktopLlamaRuntimeHandlers(
|
|
253
|
-
deps: DesktopLlamaRuntimeHandlerDeps = {},
|
|
254
|
-
) {
|
|
255
|
-
const isDesktopMode = deps.isDesktopMode ?? defaultIsDesktopMode;
|
|
256
|
-
const runtimeController =
|
|
257
|
-
deps.controller ?? createDesktopLlamaRuntimeController(deps.repoRoot);
|
|
258
|
-
const logger = deps.logger ?? console;
|
|
284
|
+
export function createDesktopLlamaRuntimeHandlers(
|
|
285
|
+
deps: DesktopLlamaRuntimeHandlerDeps = {},
|
|
286
|
+
) {
|
|
287
|
+
const isDesktopMode = deps.isDesktopMode ?? defaultIsDesktopMode;
|
|
288
|
+
const runtimeController =
|
|
289
|
+
deps.controller ?? createDesktopLlamaRuntimeController(deps.repoRoot, deps.env);
|
|
290
|
+
const logger = deps.logger ?? console;
|
|
259
291
|
|
|
260
292
|
let activeStartTask: Promise<void> | null = null;
|
|
261
293
|
let activeStartToken = 0;
|
|
@@ -267,8 +299,8 @@ export function createDesktopLlamaRuntimeHandlers(
|
|
|
267
299
|
lastStartError = null;
|
|
268
300
|
};
|
|
269
301
|
|
|
270
|
-
const readSnapshot = async () =>
|
|
271
|
-
buildResponseSnapshot(await runtimeController.status(), activeStartTask, lastStartError);
|
|
302
|
+
const readSnapshot = async () =>
|
|
303
|
+
buildResponseSnapshot(await runtimeController.status(), activeStartTask, lastStartError);
|
|
272
304
|
|
|
273
305
|
const trackStartTask = (task: Promise<void>) => {
|
|
274
306
|
const taskToken = ++activeStartToken;
|
|
@@ -348,13 +380,15 @@ export function createDesktopLlamaRuntimeHandlers(
|
|
|
348
380
|
return json({ error: "Unsupported action" }, 400);
|
|
349
381
|
};
|
|
350
382
|
|
|
351
|
-
return {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
export const
|
|
383
|
+
return {
|
|
384
|
+
readSnapshot,
|
|
385
|
+
handleGet,
|
|
386
|
+
handlePost,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const defaultHandlers = createDesktopLlamaRuntimeHandlers();
|
|
391
|
+
|
|
392
|
+
export const readDesktopProviderRuntimeSnapshot = defaultHandlers.readSnapshot;
|
|
393
|
+
export const handleDesktopLlamaRuntimeGet = defaultHandlers.handleGet;
|
|
394
|
+
export const handleDesktopLlamaRuntimePost = defaultHandlers.handlePost;
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeDesktopReleaseManifest,
|
|
3
|
+
type DesktopReleasePlatform,
|
|
4
|
+
} from "../../app/constants/desktopReleaseManifest";
|
|
5
|
+
import { createDesktopUpdaterSnapshot } from "../../desktop/desktopUpdaterState";
|
|
6
|
+
import type { DesktopUpdaterReleaseArtifact } from "../../desktop/desktopUpdatePolicy";
|
|
7
|
+
|
|
1
8
|
const JSON_HEADERS = {
|
|
2
9
|
"content-type": "application/json; charset=utf-8",
|
|
3
10
|
};
|
|
4
11
|
|
|
5
12
|
let activeOperation: "check" | "download" | "apply" | null = null;
|
|
6
13
|
let activeTask: Promise<void> | null = null;
|
|
14
|
+
const DESKTOP_MANIFEST_CACHE_TTL_MS = 30_000;
|
|
15
|
+
const manifestCache = new Map<
|
|
16
|
+
string,
|
|
17
|
+
{
|
|
18
|
+
fetchedAt: number;
|
|
19
|
+
artifact: DesktopUpdaterReleaseArtifact | null;
|
|
20
|
+
error: string | null;
|
|
21
|
+
}
|
|
22
|
+
>();
|
|
7
23
|
|
|
8
24
|
const isDesktopMode = () => process.env.NOLO_DESKTOP === "1";
|
|
9
25
|
|
|
@@ -17,12 +33,70 @@ const notDesktopResponse = () =>
|
|
|
17
33
|
json({ error: "Desktop updater is only available inside Nolo Desktop." }, 404);
|
|
18
34
|
|
|
19
35
|
const loadDesktopRuntime = async () => import("electrobun/bun");
|
|
36
|
+
type DesktopRuntimeModule = Awaited<ReturnType<typeof loadDesktopRuntime>>;
|
|
37
|
+
type UpdaterInstance = DesktopRuntimeModule["Updater"];
|
|
38
|
+
|
|
39
|
+
const resolveDesktopReleasePlatform = (): DesktopReleasePlatform =>
|
|
40
|
+
process.platform === "win32"
|
|
41
|
+
? "windows"
|
|
42
|
+
: process.platform === "darwin"
|
|
43
|
+
? "macos"
|
|
44
|
+
: "linux";
|
|
45
|
+
|
|
46
|
+
const resolveDesktopManifestUrl = (baseUrl: string) =>
|
|
47
|
+
`${baseUrl.replace(/\/+$/, "")}/desktop-release-manifest.json`;
|
|
20
48
|
|
|
21
49
|
const latestStatus = (Updater: Awaited<ReturnType<typeof loadDesktopRuntime>>["Updater"]) => {
|
|
22
50
|
const history = Updater.getStatusHistory();
|
|
23
51
|
return history.length > 0 ? history[history.length - 1] : null;
|
|
24
52
|
};
|
|
25
53
|
|
|
54
|
+
const readPublishedReleaseArtifact = async (
|
|
55
|
+
baseUrl: string,
|
|
56
|
+
platform: DesktopReleasePlatform
|
|
57
|
+
) => {
|
|
58
|
+
const cacheKey = `${platform}:${baseUrl.replace(/\/+$/, "")}`;
|
|
59
|
+
const cached = manifestCache.get(cacheKey);
|
|
60
|
+
if (cached && Date.now() - cached.fetchedAt < DESKTOP_MANIFEST_CACHE_TTL_MS) {
|
|
61
|
+
return cached;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch(resolveDesktopManifestUrl(baseUrl), {
|
|
66
|
+
method: "GET",
|
|
67
|
+
headers: {
|
|
68
|
+
accept: "application/json",
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
throw new Error(`HTTP ${response.status}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const manifest = normalizeDesktopReleaseManifest(await response.json());
|
|
76
|
+
if (!manifest) {
|
|
77
|
+
throw new Error("invalid manifest payload");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const artifact = manifest.artifacts[platform];
|
|
81
|
+
const result = {
|
|
82
|
+
fetchedAt: Date.now(),
|
|
83
|
+
artifact: artifact ? { platform, ...artifact } : null,
|
|
84
|
+
error: artifact ? null : `manifest is missing a ${platform} artifact`,
|
|
85
|
+
};
|
|
86
|
+
manifestCache.set(cacheKey, result);
|
|
87
|
+
return result;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const result = {
|
|
90
|
+
fetchedAt: Date.now(),
|
|
91
|
+
artifact: null,
|
|
92
|
+
error:
|
|
93
|
+
error instanceof Error ? error.message : "failed to fetch desktop release manifest",
|
|
94
|
+
};
|
|
95
|
+
manifestCache.set(cacheKey, result);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
26
100
|
const getUpdaterSnapshot = async () => {
|
|
27
101
|
const { BuildConfig, Updater } = await loadDesktopRuntime();
|
|
28
102
|
const [buildConfig, version, hash, channel, baseUrl] = await Promise.all([
|
|
@@ -32,9 +106,16 @@ const getUpdaterSnapshot = async () => {
|
|
|
32
106
|
Updater.localInfo.channel(),
|
|
33
107
|
Updater.localInfo.baseUrl(),
|
|
34
108
|
]);
|
|
35
|
-
|
|
36
|
-
|
|
109
|
+
const platform = resolveDesktopReleasePlatform();
|
|
110
|
+
const updateInfo = Updater.updateInfo?.() ?? null;
|
|
111
|
+
const shouldLoadReleaseArtifact = Boolean(updateInfo?.updateAvailable || updateInfo?.updateReady);
|
|
112
|
+
const releaseArtifactState = shouldLoadReleaseArtifact
|
|
113
|
+
? await readPublishedReleaseArtifact(baseUrl, platform)
|
|
114
|
+
: { artifact: null, error: null };
|
|
115
|
+
|
|
116
|
+
return createDesktopUpdaterSnapshot({
|
|
37
117
|
desktop: true,
|
|
118
|
+
platform,
|
|
38
119
|
activeOperation,
|
|
39
120
|
localInfo: {
|
|
40
121
|
version,
|
|
@@ -43,10 +124,12 @@ const getUpdaterSnapshot = async () => {
|
|
|
43
124
|
baseUrl,
|
|
44
125
|
},
|
|
45
126
|
buildConfig,
|
|
46
|
-
updateInfo
|
|
127
|
+
updateInfo,
|
|
47
128
|
latestStatus: latestStatus(Updater),
|
|
48
129
|
statusHistory: Updater.getStatusHistory(),
|
|
49
|
-
|
|
130
|
+
releaseArtifact: releaseArtifactState.artifact,
|
|
131
|
+
manifestError: releaseArtifactState.error,
|
|
132
|
+
});
|
|
50
133
|
};
|
|
51
134
|
|
|
52
135
|
const runOperation = (
|
|
@@ -79,6 +162,22 @@ const runOperation = (
|
|
|
79
162
|
return true;
|
|
80
163
|
};
|
|
81
164
|
|
|
165
|
+
const OPERATION_EXECUTORS: Record<
|
|
166
|
+
"check" | "download" | "apply",
|
|
167
|
+
{ resetHistory?: boolean; run: (updater: UpdaterInstance) => Promise<void> }
|
|
168
|
+
> = {
|
|
169
|
+
check: {
|
|
170
|
+
resetHistory: true,
|
|
171
|
+
run: (updater) => updater.checkForUpdate(),
|
|
172
|
+
},
|
|
173
|
+
download: {
|
|
174
|
+
run: (updater) => updater.downloadUpdate(),
|
|
175
|
+
},
|
|
176
|
+
apply: {
|
|
177
|
+
run: (updater) => updater.applyUpdate(),
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
82
181
|
export const handleDesktopUpdaterGet = async () => {
|
|
83
182
|
if (!isDesktopMode()) return notDesktopResponse();
|
|
84
183
|
|
|
@@ -104,27 +203,36 @@ export const handleDesktopUpdaterPost = async (req: Request) => {
|
|
|
104
203
|
|
|
105
204
|
const action = body.action;
|
|
106
205
|
|
|
107
|
-
if (action === "check") {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
});
|
|
120
|
-
return json(await getUpdaterSnapshot(), 202);
|
|
121
|
-
}
|
|
206
|
+
if (action === "check" || action === "download" || action === "apply") {
|
|
207
|
+
const snapshot = await getUpdaterSnapshot();
|
|
208
|
+
if (action !== "check" && snapshot.summary.primaryAction !== action) {
|
|
209
|
+
return json(
|
|
210
|
+
{
|
|
211
|
+
error:
|
|
212
|
+
snapshot.summary.statusMessage ??
|
|
213
|
+
`Desktop updater is not ready to ${action} right now.`,
|
|
214
|
+
},
|
|
215
|
+
409
|
|
216
|
+
);
|
|
217
|
+
}
|
|
122
218
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
219
|
+
const operation = OPERATION_EXECUTORS[action];
|
|
220
|
+
const started = runOperation(
|
|
221
|
+
action,
|
|
222
|
+
async () => {
|
|
223
|
+
const { Updater } = await loadDesktopRuntime();
|
|
224
|
+
await operation.run(Updater);
|
|
225
|
+
},
|
|
226
|
+
operation.resetHistory ?? false
|
|
227
|
+
);
|
|
228
|
+
if (!started) {
|
|
229
|
+
return json(
|
|
230
|
+
{
|
|
231
|
+
error: `Desktop updater is already busy with ${activeOperation ?? "another operation"}.`,
|
|
232
|
+
},
|
|
233
|
+
409
|
|
234
|
+
);
|
|
235
|
+
}
|
|
128
236
|
return json(await getUpdaterSnapshot(), 202);
|
|
129
237
|
}
|
|
130
238
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// server/api/favoriteHandlers.ts
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { getServerAuthorityStore } from "../../database/server/db";
|
|
4
4
|
import {
|
|
5
5
|
createFavoriteKey,
|
|
6
6
|
createFavoriteStatsKey,
|
|
7
7
|
} from "../../database/keys";
|
|
8
|
+
import { writeStoreOps } from "../../database/server/storeBatchCompat";
|
|
8
9
|
import { isTombstoneRecord } from "../../database/tombstones";
|
|
9
10
|
|
|
10
11
|
import type { ApiContext, ApiError } from "../api/types";
|
|
@@ -21,6 +22,8 @@ import {
|
|
|
21
22
|
ListFavoritesResult,
|
|
22
23
|
} from "../../app/favorite/type";
|
|
23
24
|
|
|
25
|
+
const getFavoriteStore = () => getServerAuthorityStore();
|
|
26
|
+
|
|
24
27
|
function toTimeMs(t: unknown) {
|
|
25
28
|
if (typeof t === "number") return t;
|
|
26
29
|
const n = Date.parse(String(t ?? 0));
|
|
@@ -109,6 +112,7 @@ function resolveFavoriteKeysByKey(
|
|
|
109
112
|
|
|
110
113
|
/** 安全 get:不存在时返回 undefined,而不是抛错 */
|
|
111
114
|
async function safeGet<T>(key: string): Promise<T | undefined> {
|
|
115
|
+
const serverDb = getFavoriteStore();
|
|
112
116
|
try {
|
|
113
117
|
const record = await serverDb.get(key);
|
|
114
118
|
return isTombstoneRecord(record) ? undefined : record;
|
|
@@ -138,6 +142,7 @@ async function setFavoriteState(
|
|
|
138
142
|
desiredFavoriteState: boolean,
|
|
139
143
|
favoritedAt?: number
|
|
140
144
|
): Promise<ToggleFavoriteResult> {
|
|
145
|
+
const serverDb = getFavoriteStore();
|
|
141
146
|
const resolved = resolveFavoriteKeysByKey(targetType, userId, targetKey);
|
|
142
147
|
const {
|
|
143
148
|
relKey,
|
|
@@ -213,7 +218,7 @@ async function setFavoriteState(
|
|
|
213
218
|
}
|
|
214
219
|
}
|
|
215
220
|
|
|
216
|
-
await serverDb
|
|
221
|
+
await writeStoreOps(serverDb, ops);
|
|
217
222
|
|
|
218
223
|
return buildFavoriteResult(
|
|
219
224
|
targetType,
|
|
@@ -302,6 +307,7 @@ async function listFavoritesForUser(
|
|
|
302
307
|
targetType: ListableFavoriteTargetType,
|
|
303
308
|
userId: string
|
|
304
309
|
): Promise<ListFavoritesResult> {
|
|
310
|
+
const serverDb = getFavoriteStore();
|
|
305
311
|
const normalizedTargetType =
|
|
306
312
|
targetType === "doc" || targetType === "content" ? "page" : targetType;
|
|
307
313
|
|