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
|
@@ -3,8 +3,11 @@ import type {
|
|
|
3
3
|
AgentRuntimeHostAdapter,
|
|
4
4
|
AgentRuntimeSaveTurnInput,
|
|
5
5
|
} from "../agentRuntimeLocal";
|
|
6
|
+
import { request as httpRequest } from "node:http";
|
|
7
|
+
import { request as httpsRequest } from "node:https";
|
|
6
8
|
import {
|
|
7
9
|
buildLocalWorkspacePolicyToolNames,
|
|
10
|
+
resolveLocalWorkspaceShellToolExposure,
|
|
8
11
|
buildLocalWorkspaceToolset,
|
|
9
12
|
buildLocalWorkspaceOpenAiTools,
|
|
10
13
|
buildOpenAiCompatibleChatCompletionRequest,
|
|
@@ -13,8 +16,11 @@ import {
|
|
|
13
16
|
parseOpenAiCompatibleChatCompletionResponse,
|
|
14
17
|
parsePlatformChatCompletionData,
|
|
15
18
|
parsePlatformChatCompletionResponse,
|
|
19
|
+
resolveHostRuntimeConfigFromEnv,
|
|
16
20
|
resolvePlatformChatProviderConfig,
|
|
21
|
+
resolveRequestedRuntimeToolNames,
|
|
17
22
|
shouldUsePlatformChatProvider,
|
|
23
|
+
type HostRuntimeConfig,
|
|
18
24
|
} from "../agentRuntimeLocal";
|
|
19
25
|
import type { AgentRuntimeChatMessage } from "../agent-runtime";
|
|
20
26
|
import { getDefaultCliLocalRuntimeDb } from "../localRuntimeDb";
|
|
@@ -46,6 +52,29 @@ import {
|
|
|
46
52
|
type EnvLike = Record<string, string | undefined>;
|
|
47
53
|
type FetchInput = Parameters<typeof fetch>[0];
|
|
48
54
|
type FetchInit = Parameters<typeof fetch>[1];
|
|
55
|
+
type CliLocalRuntimeCliExecution = {
|
|
56
|
+
text: string;
|
|
57
|
+
raw?: string;
|
|
58
|
+
elapsed?: number;
|
|
59
|
+
warnings?: string[];
|
|
60
|
+
};
|
|
61
|
+
type CliLocalRuntimeCliExecutor = (
|
|
62
|
+
provider: string,
|
|
63
|
+
prompt: string,
|
|
64
|
+
options: {
|
|
65
|
+
model?: string;
|
|
66
|
+
timeout?: number;
|
|
67
|
+
cwd?: string;
|
|
68
|
+
yolo?: boolean;
|
|
69
|
+
env?: EnvLike;
|
|
70
|
+
systemPrompt?: string;
|
|
71
|
+
reasoningEffort?: "low" | "medium" | "high" | "xhigh" | "max";
|
|
72
|
+
temperature?: number;
|
|
73
|
+
topP?: number;
|
|
74
|
+
frequencyPenalty?: number;
|
|
75
|
+
maxTokens?: number;
|
|
76
|
+
}
|
|
77
|
+
) => Promise<CliLocalRuntimeCliExecution>;
|
|
49
78
|
const TRANSIENT_FETCH_MAX_ATTEMPTS = 8;
|
|
50
79
|
const TRANSIENT_FETCH_RETRY_BASE_DELAY_MS = 250;
|
|
51
80
|
|
|
@@ -53,23 +82,34 @@ export type CliLocalRuntimeDb = CliKvDb;
|
|
|
53
82
|
|
|
54
83
|
export type CliLocalRuntimeAdapterDeps = {
|
|
55
84
|
env: EnvLike;
|
|
85
|
+
hostRuntimeConfig?: HostRuntimeConfig;
|
|
56
86
|
db?: CliLocalRuntimeDb;
|
|
57
87
|
store?: HybridRecordStore;
|
|
58
88
|
now?: () => number;
|
|
59
89
|
createId?: () => string;
|
|
60
90
|
fetchImpl?: typeof fetch;
|
|
61
91
|
cwd?: string;
|
|
62
|
-
useCwdAsTaskWorkspaceBase?: boolean;
|
|
63
92
|
output?: { write(chunk: string): unknown };
|
|
64
93
|
prepareTaskWorktree?: typeof prepareTaskWorktree;
|
|
65
94
|
localToolExecutors?: Record<string, (call: any) => Promise<{ content: string; metadata?: Record<string, unknown> }>>;
|
|
95
|
+
executeCli?: CliLocalRuntimeCliExecutor;
|
|
66
96
|
sleep?: (ms: number) => Promise<void>;
|
|
97
|
+
loopbackRequest?: (input: FetchInput, init?: FetchInit) => Promise<Response>;
|
|
67
98
|
};
|
|
68
99
|
|
|
69
100
|
async function defaultLocalRuntimeDb(): Promise<CliLocalRuntimeDb> {
|
|
70
101
|
return getDefaultCliLocalRuntimeDb();
|
|
71
102
|
}
|
|
72
103
|
|
|
104
|
+
async function defaultExecuteCli(
|
|
105
|
+
provider: string,
|
|
106
|
+
prompt: string,
|
|
107
|
+
options: Parameters<CliLocalRuntimeCliExecutor>[2]
|
|
108
|
+
) {
|
|
109
|
+
const { executeCli } = await import("../ai/agent/cliExecutor");
|
|
110
|
+
return executeCli(provider as any, prompt, options);
|
|
111
|
+
}
|
|
112
|
+
|
|
73
113
|
function createFallbackId() {
|
|
74
114
|
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`.toUpperCase();
|
|
75
115
|
}
|
|
@@ -78,10 +118,6 @@ function resolveLocalUserId(env: EnvLike) {
|
|
|
78
118
|
return env.NOLO_LOCAL_USER_ID || env.NOLO_USER_ID || "local";
|
|
79
119
|
}
|
|
80
120
|
|
|
81
|
-
function shellModeEnabled(env: EnvLike) {
|
|
82
|
-
return ["worktree", "dangerous", "1", "true"].includes(env.NOLO_LOCAL_SHELL_MODE || "");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
121
|
function parseLocalToolBudgets(env: EnvLike) {
|
|
86
122
|
const raw = env.NOLO_LOCAL_TOOL_BUDGETS?.trim();
|
|
87
123
|
if (!raw) return {};
|
|
@@ -122,15 +158,70 @@ function transientFetchRetryDelayMs(attempt: number) {
|
|
|
122
158
|
return Math.min(attempt * TRANSIENT_FETCH_RETRY_BASE_DELAY_MS, 2_000);
|
|
123
159
|
}
|
|
124
160
|
|
|
161
|
+
function isLoopbackUrl(input: FetchInput) {
|
|
162
|
+
try {
|
|
163
|
+
const target = typeof input === "string" || input instanceof URL
|
|
164
|
+
? new URL(String(input))
|
|
165
|
+
: new URL(input.url);
|
|
166
|
+
const hostname = target.hostname.toLowerCase();
|
|
167
|
+
return hostname === "127.0.0.1" || hostname === "localhost" || hostname === "::1";
|
|
168
|
+
} catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function toNodeRequestBody(body: FetchInit["body"]) {
|
|
174
|
+
if (typeof body === "string") return Buffer.from(body);
|
|
175
|
+
if (body instanceof Uint8Array) return Buffer.from(body);
|
|
176
|
+
if (body instanceof ArrayBuffer) return Buffer.from(body);
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function defaultLoopbackRequest(input: FetchInput, init?: FetchInit) {
|
|
181
|
+
const target = typeof input === "string" || input instanceof URL
|
|
182
|
+
? new URL(String(input))
|
|
183
|
+
: new URL(input.url);
|
|
184
|
+
const headers = new Headers(init?.headers);
|
|
185
|
+
const body = toNodeRequestBody(init?.body);
|
|
186
|
+
if (body && !headers.has("Content-Length")) {
|
|
187
|
+
headers.set("Content-Length", String(body.byteLength));
|
|
188
|
+
}
|
|
189
|
+
return await new Promise<Response>((resolve, reject) => {
|
|
190
|
+
const requestImpl = target.protocol === "https:" ? httpsRequest : httpRequest;
|
|
191
|
+
const req = requestImpl(target, {
|
|
192
|
+
method: init?.method ?? "GET",
|
|
193
|
+
headers: Object.fromEntries(headers.entries()),
|
|
194
|
+
}, (res) => {
|
|
195
|
+
const chunks: Buffer[] = [];
|
|
196
|
+
res.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
197
|
+
res.on("end", () => {
|
|
198
|
+
resolve(new Response(Buffer.concat(chunks), {
|
|
199
|
+
status: res.statusCode ?? 500,
|
|
200
|
+
headers: res.headers as Record<string, string>,
|
|
201
|
+
}));
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
req.on("error", reject);
|
|
205
|
+
if (body) req.write(body);
|
|
206
|
+
req.end();
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
125
210
|
async function fetchWithTransientRetry(
|
|
126
211
|
fetchImpl: typeof fetch,
|
|
127
212
|
input: FetchInput,
|
|
128
213
|
init?: FetchInit,
|
|
129
|
-
options: {
|
|
214
|
+
options: {
|
|
215
|
+
sleep?: (ms: number) => Promise<void>;
|
|
216
|
+
loopbackRequest?: (input: FetchInput, init?: FetchInit) => Promise<Response>;
|
|
217
|
+
} = {}
|
|
130
218
|
) {
|
|
131
219
|
let lastError: unknown;
|
|
132
220
|
for (let attempt = 1; attempt <= TRANSIENT_FETCH_MAX_ATTEMPTS; attempt += 1) {
|
|
133
221
|
try {
|
|
222
|
+
if (options.loopbackRequest && isLoopbackUrl(input)) {
|
|
223
|
+
return await options.loopbackRequest(input, init);
|
|
224
|
+
}
|
|
134
225
|
return await fetchImpl(input, init);
|
|
135
226
|
} catch (error) {
|
|
136
227
|
if (!isTransientFetchError(error)) throw error;
|
|
@@ -143,32 +234,52 @@ async function fetchWithTransientRetry(
|
|
|
143
234
|
throw lastError;
|
|
144
235
|
}
|
|
145
236
|
|
|
146
|
-
function buildOpenAiTools(args: {
|
|
147
|
-
|
|
237
|
+
function buildOpenAiTools(args: {
|
|
238
|
+
requestedToolNames?: string[];
|
|
239
|
+
platformToolNames?: string[];
|
|
240
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
241
|
+
}) {
|
|
242
|
+
const toolset = buildLocalWorkspaceToolsetForHost(args);
|
|
148
243
|
return [
|
|
149
244
|
...buildLocalWorkspaceOpenAiTools({
|
|
150
245
|
toolNames: toolset.toolNames,
|
|
151
246
|
exposeShellTools: toolset.exposeShellTools,
|
|
152
247
|
}),
|
|
153
|
-
...buildServerPlatformOpenAiTools({ toolNames: args.
|
|
248
|
+
...buildServerPlatformOpenAiTools({ toolNames: args.platformToolNames }),
|
|
154
249
|
];
|
|
155
250
|
}
|
|
156
251
|
|
|
157
|
-
function
|
|
252
|
+
function buildLocalWorkspaceToolsetForHost(args: {
|
|
253
|
+
requestedToolNames?: string[];
|
|
254
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
255
|
+
}) {
|
|
256
|
+
const requestedToolNames = args.requestedToolNames ?? [];
|
|
257
|
+
const exposeShellTools = resolveLocalWorkspaceShellToolExposure({
|
|
258
|
+
declaredToolNames: requestedToolNames,
|
|
259
|
+
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
260
|
+
});
|
|
158
261
|
const toolset = buildLocalWorkspaceToolset({
|
|
159
|
-
declaredToolNames:
|
|
160
|
-
exposeShellTools
|
|
262
|
+
declaredToolNames: requestedToolNames,
|
|
263
|
+
exposeShellTools,
|
|
161
264
|
});
|
|
162
265
|
return toolset;
|
|
163
266
|
}
|
|
164
267
|
|
|
165
|
-
function buildLocalPolicyToolNames(args: {
|
|
268
|
+
function buildLocalPolicyToolNames(args: {
|
|
269
|
+
requestedToolNames?: string[];
|
|
270
|
+
platformToolNames?: string[];
|
|
271
|
+
hostRuntimeConfig: HostRuntimeConfig;
|
|
272
|
+
}) {
|
|
273
|
+
const exposeShellTools = resolveLocalWorkspaceShellToolExposure({
|
|
274
|
+
declaredToolNames: args.requestedToolNames,
|
|
275
|
+
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
276
|
+
});
|
|
166
277
|
return [
|
|
167
278
|
...buildLocalWorkspacePolicyToolNames({
|
|
168
|
-
declaredToolNames: args.
|
|
169
|
-
exposeShellTools
|
|
279
|
+
declaredToolNames: args.requestedToolNames,
|
|
280
|
+
exposeShellTools,
|
|
170
281
|
}),
|
|
171
|
-
...((args.
|
|
282
|
+
...((args.platformToolNames ?? []).includes("taskRun") ? ["taskRun"] : []),
|
|
172
283
|
];
|
|
173
284
|
}
|
|
174
285
|
|
|
@@ -254,6 +365,33 @@ function readLocalWorkspaceMode(agentConfig: AgentRuntimeAgentConfig | null) {
|
|
|
254
365
|
return value === "task-worktree" ? "task-worktree" : "current";
|
|
255
366
|
}
|
|
256
367
|
|
|
368
|
+
function extractRuntimeMessageText(content: AgentRuntimeChatMessage["content"]) {
|
|
369
|
+
if (typeof content === "string") return content;
|
|
370
|
+
if (!Array.isArray(content)) return "";
|
|
371
|
+
return content
|
|
372
|
+
.filter((part): part is Extract<typeof part, { type: "text" }> => part?.type === "text")
|
|
373
|
+
.map((part) => part.text ?? "")
|
|
374
|
+
.join("");
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function buildCliTaskPromptFromMessages(messages: AgentRuntimeChatMessage[]) {
|
|
378
|
+
const history = messages
|
|
379
|
+
.filter((message) => message.role === "user" || message.role === "assistant")
|
|
380
|
+
.map((message) => {
|
|
381
|
+
const text = extractRuntimeMessageText(message.content).trim();
|
|
382
|
+
if (!text) return null;
|
|
383
|
+
return `[${message.role === "user" ? "用户" : "助手"}]\n${text}`;
|
|
384
|
+
})
|
|
385
|
+
.filter((message): message is string => Boolean(message))
|
|
386
|
+
.slice(-6);
|
|
387
|
+
|
|
388
|
+
if (history.length === 0) return "";
|
|
389
|
+
if (history.length === 1 && history[0]?.startsWith("[用户]\n")) {
|
|
390
|
+
return history[0].slice("[用户]\n".length);
|
|
391
|
+
}
|
|
392
|
+
return `请基于以下最近对话继续完成当前任务。\n\n${history.join("\n\n")}`;
|
|
393
|
+
}
|
|
394
|
+
|
|
257
395
|
async function resolveStore(deps: CliLocalRuntimeAdapterDeps) {
|
|
258
396
|
if (deps.store) return deps.store;
|
|
259
397
|
return createCliHybridRecordStore({
|
|
@@ -323,12 +461,19 @@ export function createCliLocalRuntimeAdapter(
|
|
|
323
461
|
const now = deps.now ?? Date.now;
|
|
324
462
|
const createId = deps.createId ?? createFallbackId;
|
|
325
463
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
464
|
+
const loopbackRequest = deps.loopbackRequest ?? (deps.fetchImpl ? undefined : defaultLoopbackRequest);
|
|
465
|
+
const executeCli = deps.executeCli ?? defaultExecuteCli;
|
|
326
466
|
const userId = resolveLocalUserId(deps.env);
|
|
467
|
+
const hostRuntimeConfig = deps.hostRuntimeConfig ?? resolveHostRuntimeConfigFromEnv({
|
|
468
|
+
env: deps.env,
|
|
469
|
+
surface: "cli-local",
|
|
470
|
+
workspaceBinding: "explicit-cwd",
|
|
471
|
+
});
|
|
327
472
|
const localToolBudgets = parseLocalToolBudgets(deps.env);
|
|
328
473
|
const localToolUsage = new Map<string, number>();
|
|
329
474
|
let activeAgentToolNames: string[] = [];
|
|
330
475
|
let workspaceSession: WorkspaceSession = createWorkspaceSession(
|
|
331
|
-
|
|
476
|
+
hostRuntimeConfig.workspaceBinding === "default-cwd"
|
|
332
477
|
? { defaultCwd: deps.cwd }
|
|
333
478
|
: { cwd: deps.cwd }
|
|
334
479
|
);
|
|
@@ -369,9 +514,13 @@ export function createCliLocalRuntimeAdapter(
|
|
|
369
514
|
store: await resolveStore(deps),
|
|
370
515
|
userId,
|
|
371
516
|
});
|
|
517
|
+
const requestedToolNames = agentConfig
|
|
518
|
+
? resolveRequestedRuntimeToolNames({ agentConfig })
|
|
519
|
+
: [];
|
|
372
520
|
activeAgentToolNames = buildLocalPolicyToolNames({
|
|
373
|
-
|
|
374
|
-
|
|
521
|
+
requestedToolNames,
|
|
522
|
+
platformToolNames: agentConfig?.toolNames,
|
|
523
|
+
hostRuntimeConfig,
|
|
375
524
|
});
|
|
376
525
|
await activateAgentWorkspaceSession({ agentRef, agentConfig });
|
|
377
526
|
return agentConfig;
|
|
@@ -389,6 +538,48 @@ export function createCliLocalRuntimeAdapter(
|
|
|
389
538
|
cwd: workspaceSession.workspaceRoot,
|
|
390
539
|
}),
|
|
391
540
|
resolveProvider: async (agentConfig) => {
|
|
541
|
+
if (agentConfig.apiSource === "cli") {
|
|
542
|
+
const cliProvider = String(agentConfig.cliProvider || "copilot").trim() || "copilot";
|
|
543
|
+
return {
|
|
544
|
+
model: agentConfig.model || cliProvider,
|
|
545
|
+
complete: async (messages) => {
|
|
546
|
+
const [firstMessage, ...remainingMessages] = messages;
|
|
547
|
+
const systemPrompt = firstMessage?.role === "system"
|
|
548
|
+
? extractRuntimeMessageText(firstMessage.content).trim()
|
|
549
|
+
: "";
|
|
550
|
+
const taskPrompt = buildCliTaskPromptFromMessages(
|
|
551
|
+
firstMessage?.role === "system" ? remainingMessages : messages
|
|
552
|
+
);
|
|
553
|
+
const result = await executeCli(cliProvider, taskPrompt, {
|
|
554
|
+
...(agentConfig.model ? { model: agentConfig.model } : {}),
|
|
555
|
+
cwd: workspaceSession.workspaceRoot,
|
|
556
|
+
yolo: true,
|
|
557
|
+
env: deps.env,
|
|
558
|
+
...(systemPrompt ? { systemPrompt } : {}),
|
|
559
|
+
...(typeof agentConfig.reasoning_effort === "string"
|
|
560
|
+
? { reasoningEffort: agentConfig.reasoning_effort as "low" | "medium" | "high" | "xhigh" | "max" }
|
|
561
|
+
: {}),
|
|
562
|
+
...(typeof agentConfig.temperature === "number"
|
|
563
|
+
? { temperature: agentConfig.temperature }
|
|
564
|
+
: {}),
|
|
565
|
+
...(typeof agentConfig.top_p === "number" ? { topP: agentConfig.top_p } : {}),
|
|
566
|
+
...(typeof agentConfig.frequency_penalty === "number"
|
|
567
|
+
? { frequencyPenalty: agentConfig.frequency_penalty }
|
|
568
|
+
: {}),
|
|
569
|
+
...(typeof agentConfig.max_tokens === "number"
|
|
570
|
+
? { maxTokens: agentConfig.max_tokens }
|
|
571
|
+
: {}),
|
|
572
|
+
});
|
|
573
|
+
return {
|
|
574
|
+
content: result.text,
|
|
575
|
+
model: agentConfig.model || cliProvider,
|
|
576
|
+
provider: cliProvider,
|
|
577
|
+
trace: messages,
|
|
578
|
+
};
|
|
579
|
+
},
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
392
583
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
393
584
|
const providerConfig = resolvePlatformChatProviderConfig({
|
|
394
585
|
agentConfig,
|
|
@@ -397,9 +588,11 @@ export function createCliLocalRuntimeAdapter(
|
|
|
397
588
|
return {
|
|
398
589
|
model: providerConfig.model,
|
|
399
590
|
complete: async (messages) => {
|
|
591
|
+
const requestedToolNames = resolveRequestedRuntimeToolNames({ agentConfig });
|
|
400
592
|
const tools = buildOpenAiTools({
|
|
401
|
-
|
|
402
|
-
|
|
593
|
+
requestedToolNames,
|
|
594
|
+
platformToolNames: agentConfig.toolNames,
|
|
595
|
+
hostRuntimeConfig,
|
|
403
596
|
});
|
|
404
597
|
const request = buildPlatformChatCompletionRequest({
|
|
405
598
|
providerConfig,
|
|
@@ -408,6 +601,7 @@ export function createCliLocalRuntimeAdapter(
|
|
|
408
601
|
});
|
|
409
602
|
const res = await fetchWithTransientRetry(fetchImpl, request.url, request.init, {
|
|
410
603
|
sleep: deps.sleep,
|
|
604
|
+
loopbackRequest,
|
|
411
605
|
});
|
|
412
606
|
const data = parsePlatformChatCompletionData(await res.text().catch(() => ""));
|
|
413
607
|
if (!res.ok) {
|
|
@@ -429,9 +623,11 @@ export function createCliLocalRuntimeAdapter(
|
|
|
429
623
|
return {
|
|
430
624
|
model: providerConfig.model,
|
|
431
625
|
complete: async (messages) => {
|
|
626
|
+
const requestedToolNames = resolveRequestedRuntimeToolNames({ agentConfig });
|
|
432
627
|
const tools = buildOpenAiTools({
|
|
433
|
-
|
|
434
|
-
|
|
628
|
+
requestedToolNames,
|
|
629
|
+
platformToolNames: agentConfig.toolNames,
|
|
630
|
+
hostRuntimeConfig,
|
|
435
631
|
});
|
|
436
632
|
const request = buildOpenAiCompatibleChatCompletionRequest({
|
|
437
633
|
providerConfig,
|
|
@@ -440,6 +636,7 @@ export function createCliLocalRuntimeAdapter(
|
|
|
440
636
|
});
|
|
441
637
|
const res = await fetchWithTransientRetry(fetchImpl, request.url, request.init, {
|
|
442
638
|
sleep: deps.sleep,
|
|
639
|
+
loopbackRequest,
|
|
443
640
|
});
|
|
444
641
|
const data = await res.json().catch(() => ({}));
|
|
445
642
|
if (!res.ok) {
|
|
@@ -461,6 +658,7 @@ export function createCliLocalRuntimeAdapter(
|
|
|
461
658
|
});
|
|
462
659
|
const result = await executeLocalToolWithPolicy({
|
|
463
660
|
env: deps.env,
|
|
661
|
+
hostRuntimeConfig,
|
|
464
662
|
agentToolNames: activeAgentToolNames,
|
|
465
663
|
call,
|
|
466
664
|
executors: localToolExecutors,
|
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { executeLocalToolWithPolicy, resolveLocalToolPolicy } from "./localToolPolicy";
|
|
4
|
+
import { createHostRuntimeConfig } from "../agent-runtime";
|
|
5
|
+
|
|
6
|
+
function createCliHostRuntimeConfig(allowShell = false) {
|
|
7
|
+
return createHostRuntimeConfig({
|
|
8
|
+
surface: "cli-local",
|
|
9
|
+
workspaceBinding: "explicit-cwd",
|
|
10
|
+
allowShell,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
describe("CLI local tool policy", () => {
|
|
6
|
-
test("allows execShell
|
|
15
|
+
test("allows execShell when the host grants shell capability", () => {
|
|
7
16
|
expect(resolveLocalToolPolicy({
|
|
8
|
-
env: {
|
|
9
|
-
|
|
17
|
+
env: {},
|
|
18
|
+
hostRuntimeConfig: createCliHostRuntimeConfig(true),
|
|
19
|
+
agentToolNames: ["execShell"],
|
|
10
20
|
toolName: "execShell",
|
|
11
21
|
})).toEqual({ allowed: true, toolName: "execShell" });
|
|
12
22
|
});
|
|
13
23
|
|
|
14
|
-
test("blocks execShell unless
|
|
24
|
+
test("blocks execShell unless the host grants shell capability", () => {
|
|
15
25
|
expect(resolveLocalToolPolicy({
|
|
16
26
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "execShell" },
|
|
27
|
+
hostRuntimeConfig: createCliHostRuntimeConfig(),
|
|
17
28
|
agentToolNames: ["execShell"],
|
|
18
29
|
toolName: "execShell",
|
|
19
30
|
})).toMatchObject({ allowed: false });
|
|
20
31
|
});
|
|
21
32
|
|
|
33
|
+
test("blocks execShell when shell was not requested by the runtime", () => {
|
|
34
|
+
expect(resolveLocalToolPolicy({
|
|
35
|
+
env: {},
|
|
36
|
+
hostRuntimeConfig: createCliHostRuntimeConfig(true),
|
|
37
|
+
agentToolNames: [],
|
|
38
|
+
toolName: "execShell",
|
|
39
|
+
})).toMatchObject({
|
|
40
|
+
allowed: false,
|
|
41
|
+
reason: "execShell is not requested by this agent runtime.",
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
22
45
|
test("requires both env allowlist and agent declaration", () => {
|
|
23
46
|
expect(resolveLocalToolPolicy({
|
|
24
47
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "readFile" },
|
|
@@ -36,6 +59,7 @@ describe("CLI local tool policy", () => {
|
|
|
36
59
|
test("executes only registered tools after policy allows them", async () => {
|
|
37
60
|
const result = await executeLocalToolWithPolicy({
|
|
38
61
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "readFile" },
|
|
62
|
+
hostRuntimeConfig: createCliHostRuntimeConfig(),
|
|
39
63
|
agentToolNames: ["readFile"],
|
|
40
64
|
call: { id: "call-1", name: "readFile", arguments: "{\"path\":\"README.md\"}" },
|
|
41
65
|
executors: {
|
|
@@ -127,8 +127,42 @@ export function resolveDaemonLogPath(env: ConnectorDaemonEnv) {
|
|
|
127
127
|
return env.NOLO_CONNECT_LOG || join(homedir(), ".nolo", "logs", "connector.log");
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
export function
|
|
131
|
-
return
|
|
130
|
+
export function buildConnectorDaemonEnv(env: ConnectorDaemonEnv, cwd: string) {
|
|
131
|
+
return {
|
|
132
|
+
...env,
|
|
133
|
+
NOLO_CONNECTOR_WORKDIR: env.NOLO_CONNECTOR_WORKDIR?.trim() || cwd,
|
|
134
|
+
NOLO_AGENT_WORKDIR: env.NOLO_AGENT_WORKDIR?.trim() || cwd,
|
|
135
|
+
NOLO_LOCAL_WORKTREE: env.NOLO_LOCAL_WORKTREE?.trim() || cwd,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function firstNonEmptyValue(...values: Array<string | undefined>) {
|
|
140
|
+
for (const value of values) {
|
|
141
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
142
|
+
}
|
|
143
|
+
return "";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function buildDaemonCommand(
|
|
147
|
+
cliEntrypointPath: string | undefined,
|
|
148
|
+
env: ConnectorDaemonEnv,
|
|
149
|
+
fallbackEntrypointPath = import.meta.path,
|
|
150
|
+
) {
|
|
151
|
+
const command = [process.execPath, cliEntrypointPath || fallbackEntrypointPath, "connect", "--ws"];
|
|
152
|
+
const serverUrl = firstNonEmptyValue(env.NOLO_SERVER, env.NOLO_SERVER_URL, env.BASE_URL);
|
|
153
|
+
const authToken = firstNonEmptyValue(
|
|
154
|
+
env.NOLO_MACHINE_API_KEY,
|
|
155
|
+
env.AUTH_TOKEN,
|
|
156
|
+
env.AUTH,
|
|
157
|
+
env.BENCHMARK_AUTH_TOKEN,
|
|
158
|
+
);
|
|
159
|
+
if (serverUrl) {
|
|
160
|
+
command.push("--server-url", serverUrl);
|
|
161
|
+
}
|
|
162
|
+
if (authToken) {
|
|
163
|
+
command.push("--api-key", authToken);
|
|
164
|
+
}
|
|
165
|
+
return command;
|
|
132
166
|
}
|
|
133
167
|
|
|
134
168
|
export function defaultSpawnDaemon(args: {
|
|
@@ -179,9 +213,9 @@ export async function runConnectorDaemon(deps: ConnectorDaemonDeps = {}) {
|
|
|
179
213
|
|
|
180
214
|
const logPath = resolveDaemonLogPath(env);
|
|
181
215
|
const result = (deps.spawnDaemon ?? defaultSpawnDaemon)({
|
|
182
|
-
cmd: buildDaemonCommand(deps.cliEntrypointPath, deps.fallbackEntrypointPath),
|
|
216
|
+
cmd: buildDaemonCommand(deps.cliEntrypointPath, env, deps.fallbackEntrypointPath),
|
|
183
217
|
cwd,
|
|
184
|
-
env,
|
|
218
|
+
env: buildConnectorDaemonEnv(env, cwd),
|
|
185
219
|
logPath,
|
|
186
220
|
});
|
|
187
221
|
output.write(`Connector daemon started${result.pid ? ` pid=${result.pid}` : ""}. Log: ${logPath}\n`);
|
package/connectorRunArtifact.ts
CHANGED
|
@@ -24,22 +24,46 @@ function normalizePath(value: string) {
|
|
|
24
24
|
return resolve(value.trim());
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function resolveExistingCandidate(
|
|
28
|
+
value: string | undefined,
|
|
29
|
+
checked: string[],
|
|
30
|
+
label: string
|
|
31
|
+
) {
|
|
32
|
+
const trimmed = value?.trim();
|
|
33
|
+
if (!trimmed) return null;
|
|
34
|
+
const normalized = normalizePath(trimmed);
|
|
35
|
+
if (existsSync(normalized)) return normalized;
|
|
36
|
+
checked.push(`${label}=${normalized}`);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
export function resolveConnectorRunCwd(args: {
|
|
28
41
|
env?: EnvLike;
|
|
29
42
|
policy: MachineRunPermissionPolicy;
|
|
30
43
|
fallbackCwd?: string;
|
|
31
44
|
}) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
args.env?.
|
|
35
|
-
args.env?.
|
|
36
|
-
""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
const checked: string[] = [];
|
|
46
|
+
const candidates: Array<[string | undefined, string]> = [
|
|
47
|
+
[args.env?.NOLO_CONNECTOR_WORKDIR, "NOLO_CONNECTOR_WORKDIR"],
|
|
48
|
+
[args.env?.NOLO_AGENT_WORKDIR, "NOLO_AGENT_WORKDIR"],
|
|
49
|
+
[args.env?.NOLO_LOCAL_WORKTREE, "NOLO_LOCAL_WORKTREE"],
|
|
50
|
+
[args.policy.writableRoots[0], "writableRoots[0]"],
|
|
51
|
+
[args.fallbackCwd, "fallbackCwd"],
|
|
52
|
+
[process.env.PWD, "PWD"],
|
|
53
|
+
[process.cwd(), "process.cwd()"],
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
for (const [value, label] of candidates) {
|
|
57
|
+
const resolved = resolveExistingCandidate(value, checked, label);
|
|
58
|
+
if (resolved) return resolved;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (checked.length > 0) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Connector run cwd does not exist. Checked: ${checked.join(", ")}`
|
|
64
|
+
);
|
|
41
65
|
}
|
|
42
|
-
|
|
66
|
+
throw new Error("Connector run cwd could not be resolved.");
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
async function runGit(
|
|
@@ -15,14 +15,18 @@ export function isConnectorWebSocketAuthError(error: unknown): error is Connecto
|
|
|
15
15
|
export async function resolveConnectorWebSocketTarget(input: {
|
|
16
16
|
serverUrl: string;
|
|
17
17
|
machineId: string;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
connectorSurface?: string;
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
fetchImpl?: typeof fetch;
|
|
21
|
+
}) {
|
|
21
22
|
const directWsUrl = new URL(input.serverUrl);
|
|
22
23
|
directWsUrl.protocol = directWsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
23
24
|
directWsUrl.pathname = "/api/connector/ws";
|
|
24
|
-
directWsUrl.search = "";
|
|
25
|
-
directWsUrl.searchParams.set("machineId", input.machineId);
|
|
25
|
+
directWsUrl.search = "";
|
|
26
|
+
directWsUrl.searchParams.set("machineId", input.machineId);
|
|
27
|
+
if (input.connectorSurface?.trim()) {
|
|
28
|
+
directWsUrl.searchParams.set("connectorSurface", input.connectorSurface.trim().toLowerCase());
|
|
29
|
+
}
|
|
26
30
|
|
|
27
31
|
const probeUrl = new URL(input.serverUrl);
|
|
28
32
|
probeUrl.pathname = "/api/connector/ws";
|