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
|
@@ -16,38 +16,38 @@ const scalePrice = (price: ModelPrice, multiplier: number): ModelPrice => ({
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
const GPT_5_4_STANDARD_PRICE: ModelPrice = {
|
|
19
|
-
input: 2.5,
|
|
20
|
-
output: 15,
|
|
21
|
-
inputCacheHit: 0.25,
|
|
19
|
+
input: 2.5 * 8,
|
|
20
|
+
output: 15 * 8,
|
|
21
|
+
inputCacheHit: 0.25 * 8,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const GPT_5_5_STANDARD_PRICE: ModelPrice = {
|
|
25
|
-
input: 5,
|
|
26
|
-
output: 30,
|
|
27
|
-
inputCacheHit: 0.5,
|
|
25
|
+
input: 5 * 8,
|
|
26
|
+
output: 30 * 8,
|
|
27
|
+
inputCacheHit: 0.5 * 8,
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const GPT_5_4_LONG_CONTEXT_PRICE: ModelPrice = {
|
|
31
|
-
input: 5,
|
|
32
|
-
output: 22.5,
|
|
33
|
-
inputCacheHit: 0.5,
|
|
31
|
+
input: 5 * 8,
|
|
32
|
+
output: 22.5 * 8,
|
|
33
|
+
inputCacheHit: 0.5 * 8,
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
const GPT_5_5_LONG_CONTEXT_PRICE: ModelPrice = {
|
|
37
|
-
input: 10,
|
|
38
|
-
output: 45,
|
|
39
|
-
inputCacheHit: 1,
|
|
37
|
+
input: 10 * 8,
|
|
38
|
+
output: 45 * 8,
|
|
39
|
+
inputCacheHit: 1 * 8,
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const GPT_5_4_PRO_STANDARD_PRICE: ModelPrice = {
|
|
43
|
-
input: 30,
|
|
44
|
-
output: 180,
|
|
43
|
+
input: 30 * 8,
|
|
44
|
+
output: 180 * 8,
|
|
45
45
|
inputCacheHit: 0,
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
const GPT_5_4_PRO_LONG_CONTEXT_PRICE: ModelPrice = {
|
|
49
|
-
input: 60,
|
|
50
|
-
output: 270,
|
|
49
|
+
input: 60 * 8,
|
|
50
|
+
output: 270 * 8,
|
|
51
51
|
inputCacheHit: 0,
|
|
52
52
|
};
|
|
53
53
|
|
|
@@ -141,7 +141,7 @@ export const openAIModels: Model[] = [
|
|
|
141
141
|
// OpenAI's current public pricing page does not list GPT Image 2 separately.
|
|
142
142
|
// Reuse GPT Image 1.5 pricing as a conservative placeholder until official
|
|
143
143
|
// GPT Image 2 pricing is published.
|
|
144
|
-
price: { input: 5, output: 10, inputCacheHit: 1.25 },
|
|
144
|
+
price: { input: 5 * 8, output: 10 * 8, inputCacheHit: 1.25 * 8 },
|
|
145
145
|
pricePerImage: 0.04 * 8,
|
|
146
146
|
},
|
|
147
147
|
{
|
|
@@ -190,7 +190,7 @@ export const openAIModels: Model[] = [
|
|
|
190
190
|
contextWindow: 400_000,
|
|
191
191
|
maxOutputTokens: 128_000,
|
|
192
192
|
supportsReasoningEffort: true,
|
|
193
|
-
price: { input: 0.75, output: 4.5, inputCacheHit: 0.075 },
|
|
193
|
+
price: { input: 0.75 * 8, output: 4.5 * 8, inputCacheHit: 0.075 * 8 },
|
|
194
194
|
},
|
|
195
195
|
{
|
|
196
196
|
name: "gpt-5.4-nano",
|
|
@@ -200,7 +200,7 @@ export const openAIModels: Model[] = [
|
|
|
200
200
|
contextWindow: 400_000,
|
|
201
201
|
maxOutputTokens: 128_000,
|
|
202
202
|
supportsReasoningEffort: true,
|
|
203
|
-
price: { input: 0.2, output: 1.25, inputCacheHit: 0.02 },
|
|
203
|
+
price: { input: 0.2 * 8, output: 1.25 * 8, inputCacheHit: 0.02 * 8 },
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
name: "gpt-5.4-pro",
|
|
@@ -247,7 +247,7 @@ export const openAIModels: Model[] = [
|
|
|
247
247
|
contextWindow: 400_000,
|
|
248
248
|
maxOutputTokens: 128_000,
|
|
249
249
|
supportsReasoningEffort: true,
|
|
250
|
-
price: { input:
|
|
250
|
+
price: { input: 1.25 * 8, output: 10 * 8, inputCacheHit: 0.125 * 8 },
|
|
251
251
|
},
|
|
252
252
|
{
|
|
253
253
|
name: "gpt-5-mini",
|
|
@@ -256,7 +256,7 @@ export const openAIModels: Model[] = [
|
|
|
256
256
|
contextWindow: 400_000,
|
|
257
257
|
maxOutputTokens: 128_000,
|
|
258
258
|
supportsReasoningEffort: true,
|
|
259
|
-
price: { input:
|
|
259
|
+
price: { input: 0.25 * 8, output: 2 * 8, inputCacheHit: 0.025 * 8 },
|
|
260
260
|
},
|
|
261
261
|
{
|
|
262
262
|
name: "o3-pro",
|
|
@@ -266,6 +266,6 @@ export const openAIModels: Model[] = [
|
|
|
266
266
|
maxOutputTokens: 100_000,
|
|
267
267
|
supportsReasoningEffort: true,
|
|
268
268
|
endpointKey: "responses",
|
|
269
|
-
price: { input:
|
|
269
|
+
price: { input: 20 * 8, output: 80 * 8, inputCacheHit: 0 },
|
|
270
270
|
},
|
|
271
271
|
];
|
|
@@ -6,7 +6,7 @@ export const xaiModels: Model[] = [
|
|
|
6
6
|
displayName: "Grok4 0709",
|
|
7
7
|
hasVision: false,
|
|
8
8
|
contextWindow: 131072,
|
|
9
|
-
price: { input: 3 *
|
|
9
|
+
price: { input: 3 * 8, output: 15 * 8 }, // $3/$15 per MTok × 7
|
|
10
10
|
fnCall: true,
|
|
11
11
|
jsonOutput: true,
|
|
12
12
|
},
|
package/localRuntimeDb.ts
CHANGED
|
@@ -20,9 +20,46 @@ export function buildCliLocalRuntimeDbEnv(env: EnvLike = process.env) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export function isCliLocalRuntimeDbLockError(error: unknown): boolean {
|
|
24
|
+
const queue: unknown[] = [error];
|
|
25
|
+
const seen = new Set<unknown>();
|
|
26
|
+
|
|
27
|
+
while (queue.length > 0) {
|
|
28
|
+
const current = queue.shift();
|
|
29
|
+
if (!current || seen.has(current)) continue;
|
|
30
|
+
seen.add(current);
|
|
31
|
+
|
|
32
|
+
const text = `${(current as any)?.code ?? ""} ${(current as any)?.message ?? current}`;
|
|
33
|
+
if (/LEVEL_LOCKED|Resource temporarily unavailable|\/LOCK|LOCK:|db locked|locked/i.test(text)) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if ((current as any)?.cause) queue.push((current as any).cause);
|
|
38
|
+
if (Array.isArray((current as any)?.errors)) queue.push(...(current as any).errors);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function formatCliLocalRuntimeDbOpenError(dbPath: string, error: unknown) {
|
|
45
|
+
if (!isCliLocalRuntimeDbLockError(error)) {
|
|
46
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
47
|
+
}
|
|
48
|
+
return new Error(
|
|
49
|
+
`CLI local runtime DB is locked at ${dbPath}. Another nolo local runtime is already using it. ` +
|
|
50
|
+
"Stop the other local runtime, rerun without --local, or set NOLO_SERVER_DB_PATH to a different cache path.",
|
|
51
|
+
{ cause: error instanceof Error ? error : undefined }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
23
55
|
export async function getDefaultCliLocalRuntimeDb(): Promise<CliLocalRuntimeDb> {
|
|
24
|
-
|
|
56
|
+
const dbPath = buildCliLocalRuntimeDbEnv(process.env).NOLO_SERVER_DB_PATH;
|
|
57
|
+
process.env.NOLO_SERVER_DB_PATH = dbPath;
|
|
25
58
|
const { default: serverDb, ensureServerDbOpen } = await import("./database/server/db");
|
|
26
|
-
|
|
59
|
+
try {
|
|
60
|
+
await ensureServerDbOpen();
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw formatCliLocalRuntimeDbOpenError(dbPath, error);
|
|
63
|
+
}
|
|
27
64
|
return serverDb as CliLocalRuntimeDb;
|
|
28
65
|
}
|
package/machineCommandPrompts.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
resolveMachineRunPermissionPolicy,
|
|
4
4
|
type MachineRunPermissionPolicy,
|
|
5
5
|
} from "./ai/agent/machineRunPermissions";
|
|
6
|
+
import { buildNoloReadOnlyBridgePrompt } from "./noloReadBridgePrompt";
|
|
6
7
|
|
|
7
8
|
export function inferTaskRunRole(agentKey: string, agentConfig: any) {
|
|
8
9
|
const haystack = [agentKey, agentConfig?.name, agentConfig?.prompt]
|
|
@@ -62,6 +63,7 @@ export function buildConnectorCliPrompt(
|
|
|
62
63
|
const policy = permissionPolicy ?? resolveMachineRunPermissionPolicy(agentConfig);
|
|
63
64
|
return [
|
|
64
65
|
typeof agentConfig?.prompt === "string" ? agentConfig.prompt.trim() : "",
|
|
66
|
+
buildNoloReadOnlyBridgePrompt(),
|
|
65
67
|
bridgeArgs
|
|
66
68
|
? buildTaskRunBridgePrompt({
|
|
67
69
|
agentKey: bridgeArgs.agentKey,
|
package/machineCommands.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MachineHeartbeat } from "./connector-experimental/protocol";
|
|
2
|
+
import { NOLO_CLUSTER_SERVERS, normalizeKnownServerOrigin } from "./database/config";
|
|
2
3
|
import { detectMachineInfo } from "./connector-experimental/machineInfo";
|
|
3
4
|
import {
|
|
4
5
|
type HeartbeatLoopOptions,
|
|
@@ -42,6 +43,7 @@ export {
|
|
|
42
43
|
type MachineCommandDeps = {
|
|
43
44
|
env?: EnvLike;
|
|
44
45
|
output?: OutputLike;
|
|
46
|
+
signal?: AbortSignal;
|
|
45
47
|
cliEntrypointPath?: string;
|
|
46
48
|
maxConnectorAttempts?: number;
|
|
47
49
|
sleep?: (ms: number) => Promise<void>;
|
|
@@ -60,6 +62,100 @@ type MachineCommandDeps = {
|
|
|
60
62
|
};
|
|
61
63
|
|
|
62
64
|
const defaultSleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
|
|
65
|
+
const MACHINE_TOKEN_PREFIX = "sk_machine_";
|
|
66
|
+
|
|
67
|
+
async function sleepWithAbort(ms: number, sleep: (ms: number) => Promise<void>, signal?: AbortSignal) {
|
|
68
|
+
if (!signal) {
|
|
69
|
+
await sleep(ms);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (signal.aborted) return;
|
|
73
|
+
await Promise.race([
|
|
74
|
+
sleep(ms),
|
|
75
|
+
new Promise<void>((resolve) => {
|
|
76
|
+
signal.addEventListener("abort", () => resolve(), { once: true });
|
|
77
|
+
}),
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function resolveConnectorReconnectDelayMs(env: EnvLike) {
|
|
82
|
+
const raw = Number(env.NOLO_CONNECT_RECONNECT_MS ?? "");
|
|
83
|
+
return Number.isFinite(raw) && raw >= 0 ? raw : 5_000;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isMachineToken(token: string) {
|
|
87
|
+
return token.trim().startsWith(MACHINE_TOKEN_PREFIX);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function resolveClusterConnectServerUrls(serverUrl: string, authToken: string) {
|
|
91
|
+
const normalizedPrimary = normalizeKnownServerOrigin(serverUrl) ?? serverUrl.trim().replace(/\/+$/, "");
|
|
92
|
+
if (isMachineToken(authToken)) return [normalizedPrimary];
|
|
93
|
+
const normalizedCluster = NOLO_CLUSTER_SERVERS
|
|
94
|
+
.map((baseUrl) => normalizeKnownServerOrigin(baseUrl) ?? baseUrl)
|
|
95
|
+
.filter((value, index, list) => value && list.indexOf(value) === index);
|
|
96
|
+
if (!normalizedCluster.includes(normalizedPrimary)) return [normalizedPrimary];
|
|
97
|
+
return [normalizedPrimary, ...normalizedCluster.filter((baseUrl) => baseUrl !== normalizedPrimary)];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function linkAbortSignal(signal: AbortSignal | undefined, controller: AbortController) {
|
|
101
|
+
if (!signal) return;
|
|
102
|
+
if (signal.aborted) {
|
|
103
|
+
controller.abort();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function sendMachineHeartbeat(args: {
|
|
110
|
+
serverUrl: string;
|
|
111
|
+
authToken: string;
|
|
112
|
+
fetchImpl: typeof fetch;
|
|
113
|
+
machine: MachineHeartbeat;
|
|
114
|
+
}) {
|
|
115
|
+
const res = await args.fetchImpl(`${args.serverUrl}/api/machines/heartbeat`, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: {
|
|
118
|
+
Authorization: `Bearer ${args.authToken}`,
|
|
119
|
+
"Content-Type": "application/json",
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify(args.machine),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!res.ok) {
|
|
125
|
+
const text = await res.text().catch(() => "");
|
|
126
|
+
throw new Error(`HTTP ${res.status}\n${text}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function sendHeartbeatAcrossServers(args: {
|
|
131
|
+
serverUrls: string[];
|
|
132
|
+
authToken: string;
|
|
133
|
+
fetchImpl: typeof fetch;
|
|
134
|
+
machine: MachineHeartbeat;
|
|
135
|
+
output: OutputLike;
|
|
136
|
+
}) {
|
|
137
|
+
let primaryError: Error | null = null;
|
|
138
|
+
for (const [index, serverUrl] of args.serverUrls.entries()) {
|
|
139
|
+
try {
|
|
140
|
+
await sendMachineHeartbeat({
|
|
141
|
+
serverUrl,
|
|
142
|
+
authToken: args.authToken,
|
|
143
|
+
fetchImpl: args.fetchImpl,
|
|
144
|
+
machine: args.machine,
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
const resolvedError = error instanceof Error ? error : new Error(String(error));
|
|
148
|
+
if (index === 0) {
|
|
149
|
+
primaryError = resolvedError;
|
|
150
|
+
} else {
|
|
151
|
+
args.output.write(
|
|
152
|
+
`[nolo] secondary connector registration failed for ${serverUrl}: ${resolvedError.message}\n`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (primaryError) throw primaryError;
|
|
158
|
+
}
|
|
63
159
|
|
|
64
160
|
async function defaultExecuteCli(
|
|
65
161
|
provider: string,
|
|
@@ -75,9 +171,9 @@ function detectLaunchableMachineInfo() {
|
|
|
75
171
|
}
|
|
76
172
|
|
|
77
173
|
export async function runMachineConnectCommand(
|
|
78
|
-
args: string[],
|
|
79
|
-
deps: MachineCommandDeps = {}
|
|
80
|
-
) {
|
|
174
|
+
args: string[],
|
|
175
|
+
deps: MachineCommandDeps = {}
|
|
176
|
+
) {
|
|
81
177
|
const env = deps.env ?? process.env;
|
|
82
178
|
const output = deps.output ?? process.stdout;
|
|
83
179
|
const authToken = resolveConnectAuthToken(args, env);
|
|
@@ -85,29 +181,31 @@ export async function runMachineConnectCommand(
|
|
|
85
181
|
writeAuthMissing(output);
|
|
86
182
|
return 1;
|
|
87
183
|
}
|
|
88
|
-
|
|
184
|
+
|
|
89
185
|
const serverUrl = resolveConnectServerUrl(args, env);
|
|
186
|
+
const serverUrls = resolveClusterConnectServerUrls(serverUrl, authToken);
|
|
90
187
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
91
188
|
const machine = (deps.machineInfo ?? detectLaunchableMachineInfo)();
|
|
92
189
|
const sendHeartbeat = async () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!res.ok) {
|
|
103
|
-
const text = await res.text().catch(() => "");
|
|
104
|
-
throw new Error(`HTTP ${res.status}\n${text}`);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
190
|
+
await sendHeartbeatAcrossServers({
|
|
191
|
+
serverUrls,
|
|
192
|
+
authToken,
|
|
193
|
+
fetchImpl,
|
|
194
|
+
machine,
|
|
195
|
+
output,
|
|
196
|
+
});
|
|
197
|
+
};
|
|
107
198
|
|
|
108
199
|
if (hasFlag(args, "--daemon") || hasFlag(args, "--background")) {
|
|
109
200
|
return runMachineDaemonCommand({
|
|
110
|
-
env
|
|
201
|
+
env: {
|
|
202
|
+
...env,
|
|
203
|
+
NOLO_SERVER: serverUrl,
|
|
204
|
+
NOLO_SERVER_URL: serverUrl,
|
|
205
|
+
BASE_URL: serverUrl,
|
|
206
|
+
AUTH_TOKEN: authToken,
|
|
207
|
+
NOLO_MACHINE_API_KEY: authToken,
|
|
208
|
+
},
|
|
111
209
|
output,
|
|
112
210
|
cliEntrypointPath: deps.cliEntrypointPath,
|
|
113
211
|
validateWorkspaceLinks: deps.validateWorkspaceLinks,
|
|
@@ -123,50 +221,82 @@ export async function runMachineConnectCommand(
|
|
|
123
221
|
const maxAttempts = deps.maxConnectorAttempts ?? Infinity;
|
|
124
222
|
const sleep = deps.sleep ?? defaultSleep;
|
|
125
223
|
const reconnectDelayMs = resolveConnectorReconnectDelayMs(env);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
224
|
+
const runServerSession = async (targetServerUrl: string, signal?: AbortSignal) => {
|
|
225
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
226
|
+
if (signal?.aborted) {
|
|
227
|
+
return { serverUrl: targetServerUrl, exitCode: 0 };
|
|
228
|
+
}
|
|
229
|
+
const runtimeServerUrl =
|
|
230
|
+
env.NOLO_CONNECT_RUNTIME_SERVER_URL ||
|
|
231
|
+
env.NOLO_RUNTIME_SERVER_URL ||
|
|
232
|
+
targetServerUrl;
|
|
233
|
+
const exitCode = await runMachineWsSession({
|
|
234
|
+
env,
|
|
235
|
+
output,
|
|
236
|
+
signal,
|
|
237
|
+
machine,
|
|
238
|
+
sendHeartbeat: () =>
|
|
239
|
+
sendMachineHeartbeat({
|
|
240
|
+
serverUrl: targetServerUrl,
|
|
241
|
+
authToken,
|
|
242
|
+
fetchImpl,
|
|
243
|
+
machine,
|
|
244
|
+
}),
|
|
245
|
+
runHeartbeatLoop: deps.runHeartbeatLoop ?? defaultRunHeartbeatLoop,
|
|
246
|
+
connectWebSocket: deps.connectWebSocket ?? defaultConnectWebSocket,
|
|
247
|
+
serverUrl: targetServerUrl,
|
|
248
|
+
authToken,
|
|
249
|
+
resolveConnectorWebSocketTarget: (options) =>
|
|
250
|
+
resolveConnectorWebSocketTarget({
|
|
251
|
+
...options,
|
|
252
|
+
fetchImpl,
|
|
253
|
+
}),
|
|
254
|
+
onMessage: (message, send) =>
|
|
255
|
+
handleConnectorRunMessage(
|
|
256
|
+
message,
|
|
257
|
+
send,
|
|
258
|
+
deps.executeCli ?? defaultExecuteCli,
|
|
259
|
+
{
|
|
260
|
+
...env,
|
|
261
|
+
NOLO_SERVER: runtimeServerUrl,
|
|
262
|
+
NOLO_SERVER_URL: runtimeServerUrl,
|
|
263
|
+
BASE_URL: runtimeServerUrl,
|
|
264
|
+
AUTH_TOKEN: authToken,
|
|
265
|
+
NOLO_MACHINE_API_KEY: authToken,
|
|
266
|
+
},
|
|
267
|
+
fetchImpl,
|
|
268
|
+
{
|
|
269
|
+
buildConnectorCliPrompt,
|
|
270
|
+
}
|
|
271
|
+
),
|
|
272
|
+
});
|
|
273
|
+
if (exitCode === 2) return { serverUrl: targetServerUrl, exitCode: 2 };
|
|
274
|
+
if (signal?.aborted) {
|
|
275
|
+
return { serverUrl: targetServerUrl, exitCode: 0 };
|
|
276
|
+
}
|
|
277
|
+
if (attempt >= maxAttempts) return { serverUrl: targetServerUrl, exitCode };
|
|
278
|
+
output.write(`[nolo] Connector websocket disconnected. Reconnecting in ${reconnectDelayMs}ms.\n`);
|
|
279
|
+
await sleepWithAbort(reconnectDelayMs, sleep, signal);
|
|
280
|
+
}
|
|
281
|
+
return { serverUrl: targetServerUrl, exitCode: 0 };
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const sessionAbort = new AbortController();
|
|
285
|
+
linkAbortSignal(deps.signal, sessionAbort);
|
|
286
|
+
|
|
287
|
+
const sessionPromises = serverUrls.map(async (targetServerUrl, index) => {
|
|
288
|
+
const result = await runServerSession(targetServerUrl, sessionAbort.signal);
|
|
289
|
+
if (index > 0 && result.exitCode !== 0 && !sessionAbort.signal.aborted) {
|
|
290
|
+
output.write(
|
|
291
|
+
`[nolo] secondary connector registration failed for ${targetServerUrl}: exit ${result.exitCode}\n`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
});
|
|
296
|
+
const results = await Promise.all(sessionPromises);
|
|
297
|
+
if (results.some((result) => result.exitCode === 0)) return 0;
|
|
298
|
+
if (results.some((result) => result.exitCode === 2)) return 1;
|
|
299
|
+
return results[0]?.exitCode ?? 1;
|
|
170
300
|
}
|
|
171
301
|
|
|
172
302
|
if (hasFlag(args, "--watch")) {
|
package/machineWsRunDispatch.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { runLocalAgentTurn, type LocalAgentToolEvent } from "./agent-runtime/localLoop";
|
|
2
|
+
import { resolveHostRuntimeConfigFromEnv } from "./agent-runtime/hostRuntimeConfig";
|
|
3
|
+
import { normalizeAgentRunDialogLineage } from "./ai/agent/agentRunDialogLineage";
|
|
2
4
|
import {
|
|
3
5
|
assertMachineRunAllowed as defaultAssertMachineRunAllowed,
|
|
4
6
|
resolveMachineRunPermissionPolicy as defaultResolveMachineRunPermissionPolicy,
|
|
@@ -118,6 +120,24 @@ function requestsLocalWorkspaceRuntime(policy?: ConnectorRuntimePolicy) {
|
|
|
118
120
|
);
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
function isMachineBoundLocalCustomProvider(agentConfig: any) {
|
|
124
|
+
const machineId =
|
|
125
|
+
isRecord(agentConfig?.runtimeBinding) && typeof agentConfig.runtimeBinding.machineId === "string"
|
|
126
|
+
? agentConfig.runtimeBinding.machineId.trim()
|
|
127
|
+
: "";
|
|
128
|
+
const providerUrl =
|
|
129
|
+
typeof agentConfig?.customProviderUrl === "string"
|
|
130
|
+
? agentConfig.customProviderUrl.trim()
|
|
131
|
+
: "";
|
|
132
|
+
if (!machineId || !providerUrl) return false;
|
|
133
|
+
try {
|
|
134
|
+
const hostname = new URL(providerUrl).hostname.toLowerCase();
|
|
135
|
+
return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1";
|
|
136
|
+
} catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
121
141
|
function hasExplicitMachinePermissions(agentConfig: any) {
|
|
122
142
|
const runtimeBinding = isRecord(agentConfig?.runtimeBinding) ? agentConfig.runtimeBinding : {};
|
|
123
143
|
return Boolean(
|
|
@@ -130,6 +150,7 @@ function hasExplicitMachinePermissions(agentConfig: any) {
|
|
|
130
150
|
|
|
131
151
|
function runtimeWorkspacePermissionPolicy(
|
|
132
152
|
runtimePolicy: ConnectorRuntimePolicy | undefined,
|
|
153
|
+
hostRuntimeConfig: { capabilities: { allowShell: boolean } },
|
|
133
154
|
cwd: string
|
|
134
155
|
): PermissionPolicy | null {
|
|
135
156
|
if (!requestsTaskWorktree(runtimePolicy)) return null;
|
|
@@ -137,7 +158,10 @@ function runtimeWorkspacePermissionPolicy(
|
|
|
137
158
|
mode: "full_access",
|
|
138
159
|
allowFilesystemRead: true,
|
|
139
160
|
allowFilesystemWrite: true,
|
|
140
|
-
allowShell:
|
|
161
|
+
allowShell:
|
|
162
|
+
hostRuntimeConfig.capabilities.allowShell &&
|
|
163
|
+
Array.isArray(runtimePolicy?.runtimeTools) &&
|
|
164
|
+
runtimePolicy.runtimeTools.includes("execShell"),
|
|
141
165
|
writableRoots: [cwd],
|
|
142
166
|
};
|
|
143
167
|
}
|
|
@@ -175,13 +199,20 @@ function mergeToolNames(...values: unknown[]) {
|
|
|
175
199
|
function localRuntimeEnvFromPolicy(runtimeEnv: EnvLike, policy?: ConnectorRuntimePolicy): EnvLike {
|
|
176
200
|
return {
|
|
177
201
|
...runtimeEnv,
|
|
178
|
-
...(policy?.shell?.enabled && policy.shell.mode === "worktree"
|
|
179
|
-
? { NOLO_LOCAL_SHELL_MODE: "worktree" }
|
|
180
|
-
: {}),
|
|
181
202
|
...(policy?.workspace?.cwd ? { NOLO_LOCAL_WORKTREE: policy.workspace.cwd } : {}),
|
|
182
203
|
};
|
|
183
204
|
}
|
|
184
205
|
|
|
206
|
+
function forwardedUserAuthToken(parsed: any): string {
|
|
207
|
+
const value = parsed?.payload?.meta?.userAuthToken;
|
|
208
|
+
return typeof value === "string" ? value.trim() : "";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function withForwardedUserAuthToken(runtimeEnv: EnvLike, parsed: any): EnvLike {
|
|
212
|
+
const userAuthToken = forwardedUserAuthToken(parsed);
|
|
213
|
+
return userAuthToken ? { ...runtimeEnv, AUTH_TOKEN: userAuthToken } : runtimeEnv;
|
|
214
|
+
}
|
|
215
|
+
|
|
185
216
|
function runtimeWorkspaceRootFromTrace(trace: unknown): string | undefined {
|
|
186
217
|
if (!Array.isArray(trace)) return undefined;
|
|
187
218
|
for (const message of trace) {
|
|
@@ -241,6 +272,12 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
|
|
|
241
272
|
? args.parsed.payload.agentConfig
|
|
242
273
|
: {};
|
|
243
274
|
const policy = runtimePolicyFromConnectorPayload(args.parsed);
|
|
275
|
+
const wantsTaskWorktree = requestsTaskWorktree(policy);
|
|
276
|
+
const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
|
|
277
|
+
env: args.runtimeEnv,
|
|
278
|
+
surface: "connector-local",
|
|
279
|
+
workspaceBinding: wantsTaskWorktree ? "default-cwd" : "explicit-cwd",
|
|
280
|
+
});
|
|
244
281
|
const agentRecord = {
|
|
245
282
|
...payloadAgentConfig,
|
|
246
283
|
dbKey: agentKey,
|
|
@@ -262,12 +299,14 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
|
|
|
262
299
|
[`agent-${args.runtimeEnv.NOLO_USER_ID || "local"}-${agentKey}`, agentRecord],
|
|
263
300
|
[`agent-${args.runtimeEnv.NOLO_LOCAL_USER_ID || args.runtimeEnv.NOLO_USER_ID || "local"}-${agentKey}`, agentRecord],
|
|
264
301
|
]);
|
|
265
|
-
const env = localRuntimeEnvFromPolicy(
|
|
266
|
-
|
|
302
|
+
const env = localRuntimeEnvFromPolicy(
|
|
303
|
+
withForwardedUserAuthToken(args.runtimeEnv, args.parsed),
|
|
304
|
+
policy
|
|
305
|
+
);
|
|
267
306
|
const adapter = createCliLocalRuntimeAdapter({
|
|
268
307
|
env,
|
|
308
|
+
hostRuntimeConfig,
|
|
269
309
|
cwd: args.cwd,
|
|
270
|
-
useCwdAsTaskWorkspaceBase: wantsTaskWorktree,
|
|
271
310
|
...(wantsTaskWorktree
|
|
272
311
|
? {
|
|
273
312
|
prepareTaskWorktree: (input) => prepareTaskWorktree({
|
|
@@ -350,6 +389,20 @@ function normalizeConnectorRunTimeoutMs(value: unknown): number | undefined {
|
|
|
350
389
|
return Math.floor(value);
|
|
351
390
|
}
|
|
352
391
|
|
|
392
|
+
function normalizeConnectorRunPayloadContinueDialogId(payload: unknown) {
|
|
393
|
+
if (!isRecord(payload)) return payload;
|
|
394
|
+
const dialogLineage = normalizeAgentRunDialogLineage({
|
|
395
|
+
continueDialogId: payload.continueDialogId,
|
|
396
|
+
});
|
|
397
|
+
const normalizedPayload = { ...payload };
|
|
398
|
+
if (dialogLineage.continueDialogId) {
|
|
399
|
+
normalizedPayload.continueDialogId = dialogLineage.continueDialogId;
|
|
400
|
+
} else {
|
|
401
|
+
delete normalizedPayload.continueDialogId;
|
|
402
|
+
}
|
|
403
|
+
return normalizedPayload;
|
|
404
|
+
}
|
|
405
|
+
|
|
353
406
|
export async function handleConnectorRunMessage(
|
|
354
407
|
message: string,
|
|
355
408
|
send: (message: string) => void,
|
|
@@ -365,6 +418,12 @@ export async function handleConnectorRunMessage(
|
|
|
365
418
|
return;
|
|
366
419
|
}
|
|
367
420
|
if (parsed?.type !== "agent.run" || typeof parsed.requestId !== "string") return;
|
|
421
|
+
if (isRecord(parsed)) {
|
|
422
|
+
parsed = {
|
|
423
|
+
...parsed,
|
|
424
|
+
payload: normalizeConnectorRunPayloadContinueDialogId(parsed.payload),
|
|
425
|
+
};
|
|
426
|
+
}
|
|
368
427
|
const agentConfig = parsed.payload?.agentConfig ?? {};
|
|
369
428
|
const sendProgress = (progress: ConnectorRunProgress) => {
|
|
370
429
|
send(JSON.stringify({
|
|
@@ -392,6 +451,11 @@ export async function handleConnectorRunMessage(
|
|
|
392
451
|
try {
|
|
393
452
|
const machinePermissionPolicy = resolveMachineRunPermissionPolicy(agentConfig);
|
|
394
453
|
const runtimePolicy = runtimePolicyFromConnectorPayload(parsed);
|
|
454
|
+
const hostRuntimeConfig = resolveHostRuntimeConfigFromEnv({
|
|
455
|
+
env: runtimeEnv,
|
|
456
|
+
surface: agentConfig.apiSource === "cli" ? "connector-cli" : "connector-local",
|
|
457
|
+
workspaceBinding: requestsTaskWorktree(runtimePolicy) ? "default-cwd" : "explicit-cwd",
|
|
458
|
+
});
|
|
395
459
|
const userInput = String(parsed.payload?.userInput ?? "");
|
|
396
460
|
const timeout = normalizeConnectorRunTimeoutMs(parsed.payload?.timeoutMs);
|
|
397
461
|
let cwd = resolveConnectorRunCwd({ env: runtimeEnv, policy: machinePermissionPolicy });
|
|
@@ -414,7 +478,7 @@ export async function handleConnectorRunMessage(
|
|
|
414
478
|
artifactCwd = prepared.path;
|
|
415
479
|
}
|
|
416
480
|
const runtimePermissionPolicy = !hasExplicitMachinePermissions(agentConfig)
|
|
417
|
-
? runtimeWorkspacePermissionPolicy(runtimePolicy, cwd)
|
|
481
|
+
? runtimeWorkspacePermissionPolicy(runtimePolicy, hostRuntimeConfig, cwd)
|
|
418
482
|
: null;
|
|
419
483
|
const effectivePermissionPolicy = scopePermissionPolicyToRuntimeWorkspace(
|
|
420
484
|
runtimePermissionPolicy ?? machinePermissionPolicy,
|
|
@@ -472,17 +536,18 @@ export async function handleConnectorRunMessage(
|
|
|
472
536
|
updatedAt: Date.now(),
|
|
473
537
|
});
|
|
474
538
|
}, 15_000);
|
|
539
|
+
const effectiveRuntimeEnv = withForwardedUserAuthToken(runtimeEnv, parsed);
|
|
475
540
|
const result = await executeCli(provider, materializedPrompt.prompt, {
|
|
476
541
|
model: agentConfig.model || undefined,
|
|
477
542
|
timeout,
|
|
478
543
|
cwd,
|
|
479
544
|
yolo: true,
|
|
480
545
|
env: {
|
|
481
|
-
NOLO_SERVER:
|
|
482
|
-
NOLO_SERVER_URL:
|
|
483
|
-
BASE_URL:
|
|
484
|
-
AUTH_TOKEN:
|
|
485
|
-
NOLO_MACHINE_API_KEY:
|
|
546
|
+
NOLO_SERVER: effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.BASE_URL,
|
|
547
|
+
NOLO_SERVER_URL: effectiveRuntimeEnv.NOLO_SERVER_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.BASE_URL,
|
|
548
|
+
BASE_URL: effectiveRuntimeEnv.BASE_URL || effectiveRuntimeEnv.NOLO_SERVER || effectiveRuntimeEnv.NOLO_SERVER_URL,
|
|
549
|
+
AUTH_TOKEN: effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH || effectiveRuntimeEnv.NOLO_MACHINE_API_KEY,
|
|
550
|
+
NOLO_MACHINE_API_KEY: effectiveRuntimeEnv.NOLO_MACHINE_API_KEY || effectiveRuntimeEnv.AUTH_TOKEN || effectiveRuntimeEnv.AUTH,
|
|
486
551
|
},
|
|
487
552
|
}).finally(() => clearInterval(heartbeat));
|
|
488
553
|
logConnectorRun("agent.run.cli.result", {
|
|
@@ -518,13 +583,13 @@ export async function handleConnectorRunMessage(
|
|
|
518
583
|
}));
|
|
519
584
|
return;
|
|
520
585
|
}
|
|
521
|
-
if (!requestsLocalWorkspaceRuntime(runtimePolicy)) {
|
|
586
|
+
if (!requestsLocalWorkspaceRuntime(runtimePolicy) && !isMachineBoundLocalCustomProvider(agentConfig)) {
|
|
522
587
|
throw new Error("Connector can only execute non-CLI agents when runtimeToolPolicySnapshot requests a local workspace runtime.");
|
|
523
588
|
}
|
|
524
589
|
baseSha = await readConnectorGitHead(cwd);
|
|
525
590
|
const result = await runConnectorLocalRuntimeAgent({
|
|
526
591
|
parsed,
|
|
527
|
-
runtimeEnv,
|
|
592
|
+
runtimeEnv: withForwardedUserAuthToken(runtimeEnv, parsed),
|
|
528
593
|
cwd,
|
|
529
594
|
fetchImpl,
|
|
530
595
|
onProgress: sendProgress,
|