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
package/client/agentRun.ts
CHANGED
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
import { LOCAL_AGENT_CONFIG_MISSING_CODE } from "../agent-runtime/localLoop";
|
|
5
|
-
import type { LocalAgentToolEvent } from "../agent-runtime/localLoop";
|
|
3
|
+
import { normalizeAgentRunDialogLineage } from "../ai/agent/agentRunDialogLineage";
|
|
6
4
|
import type { AgentRuntimeHostAdapter, AgentRuntimeRequestedMode } from "../agentRuntimeLocal";
|
|
7
5
|
import type { EnvLike } from "../cliEnvHelpers";
|
|
8
6
|
import type { OutputLike } from "../cliIoTypes";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
7
|
+
import type { TaskRunPromptContext } from "./taskRunPrompt";
|
|
8
|
+
import { type TaskRunRecorder } from "./agentRunTaskRunRecorder";
|
|
9
|
+
import { buildUserInputContent } from "./agentRunInput";
|
|
12
10
|
import {
|
|
13
|
-
formatToolTraceEvent,
|
|
14
|
-
nextLocalToolRoundLimit,
|
|
15
|
-
parseLocalToolRoundLimitError,
|
|
16
|
-
resolveLocalToolRoundRetryLimit,
|
|
17
|
-
shouldCollectLocalToolEvidence,
|
|
18
|
-
shouldTraceLocalTools,
|
|
19
|
-
summarizeLocalToolEvidence,
|
|
20
|
-
type TaskRunToolEvidence,
|
|
21
|
-
} from "./agentRunLocalExecution";
|
|
22
|
-
import {
|
|
23
|
-
findServerPlatformTools,
|
|
24
11
|
resolveRequestedRuntimeMode,
|
|
25
12
|
shouldAttemptAutoLocal,
|
|
26
|
-
shouldShowUsage,
|
|
27
13
|
shouldSkipAutoLocalForServerPlatformTools,
|
|
28
14
|
shouldUseScriptBridge,
|
|
29
15
|
} from "./agentRunRuntimeSelection";
|
|
16
|
+
import {
|
|
17
|
+
isMissingLocalAgentConfigError,
|
|
18
|
+
refreshMissingLocalAgentConfig,
|
|
19
|
+
resolveLocalRuntimeAdapter,
|
|
20
|
+
runInjectedLocalAgentTurn,
|
|
21
|
+
runLocalAgentTurnWithAutoRoundExpansion,
|
|
22
|
+
} from "./agentRunLocalExecutor";
|
|
23
|
+
import { runHttpAgentTurn } from "./agentRunServerTransport";
|
|
30
24
|
export { classifyTaskRunReviewStatus } from "./agentRunLocalExecution";
|
|
31
25
|
export { findServerPlatformTools, shouldUseScriptBridge } from "./agentRunRuntimeSelection";
|
|
32
|
-
|
|
33
|
-
type TaskRunAgentRole = "pm" | "frontend" | "fullstack" | "reviewer" | "codex";
|
|
34
26
|
|
|
35
|
-
type RunAgentTurnOptions = {
|
|
27
|
+
export type RunAgentTurnOptions = {
|
|
36
28
|
agentName: string;
|
|
37
29
|
agentKey: string;
|
|
38
30
|
serverUrl: string;
|
|
@@ -57,14 +49,7 @@ type RunAgentTurnOptions = {
|
|
|
57
49
|
timeoutMs?: number;
|
|
58
50
|
traceTools?: boolean;
|
|
59
51
|
taskRunContext?: TaskRunPromptContext;
|
|
60
|
-
taskRunRecorder?:
|
|
61
|
-
options: RunAgentTurnOptions;
|
|
62
|
-
status: "running" | "completed" | "failed";
|
|
63
|
-
dialogId?: string;
|
|
64
|
-
resultSummary?: string;
|
|
65
|
-
errorCode?: string;
|
|
66
|
-
toolEvidence?: TaskRunToolEvidence;
|
|
67
|
-
}) => Promise<void>;
|
|
52
|
+
taskRunRecorder?: TaskRunRecorder<RunAgentTurnOptions>;
|
|
68
53
|
scriptPathExists?: (path: string) => boolean;
|
|
69
54
|
fetchImpl?: typeof fetch;
|
|
70
55
|
};
|
|
@@ -74,241 +59,12 @@ export type RunAgentTurnResult = {
|
|
|
74
59
|
dialogId?: string;
|
|
75
60
|
streamInterrupted?: boolean;
|
|
76
61
|
};
|
|
77
|
-
|
|
78
|
-
function resolveServerPlatformToolNames(agentConfig: any) {
|
|
79
|
-
return findServerPlatformTools([
|
|
80
|
-
...(Array.isArray(agentConfig?.toolNames) ? agentConfig.toolNames : []),
|
|
81
|
-
...(Array.isArray(agentConfig?.runtimeToolPolicy?.agentTools)
|
|
82
|
-
? agentConfig.runtimeToolPolicy.agentTools
|
|
83
|
-
: []),
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function resolveAuthToken(env: EnvLike) {
|
|
88
|
-
return env.AUTH_TOKEN || env.AUTH || env.BENCHMARK_AUTH_TOKEN || "";
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function buildDefaultLocalRuntimeAdapter(options: RunAgentTurnOptions) {
|
|
92
|
-
return createCliLocalRuntimeAdapter({
|
|
93
|
-
env: options.env,
|
|
94
|
-
fetchImpl: options.fetchImpl,
|
|
95
|
-
cwd: options.localRuntimeCwd,
|
|
96
|
-
output: options.output,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function resolveLocalRuntimeAdapter(options: RunAgentTurnOptions) {
|
|
101
|
-
return (
|
|
102
|
-
options.localRuntimeAdapter ||
|
|
103
|
-
options.localRuntimeAdapterFactory?.(options.env, { cwd: options.localRuntimeCwd }) ||
|
|
104
|
-
buildDefaultLocalRuntimeAdapter(options)
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function buildUserInputContent(message: string, imageUrls: string[] = []) {
|
|
109
|
-
if (imageUrls.length === 0) return message;
|
|
110
|
-
return [
|
|
111
|
-
...(message.trim() ? [{ type: "text" as const, text: message }] : []),
|
|
112
|
-
...imageUrls.map((url) => ({
|
|
113
|
-
type: "image_url" as const,
|
|
114
|
-
image_url: { url },
|
|
115
|
-
})),
|
|
116
|
-
];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function isMissingLocalAgentConfigError(error: unknown, agentRef: string) {
|
|
120
|
-
return Boolean(
|
|
121
|
-
error &&
|
|
122
|
-
typeof error === "object" &&
|
|
123
|
-
"code" in error &&
|
|
124
|
-
(error as { code?: string; agentRef?: string }).code === LOCAL_AGENT_CONFIG_MISSING_CODE &&
|
|
125
|
-
(error as { code?: string; agentRef?: string }).agentRef === agentRef
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
62
|
|
|
130
|
-
function
|
|
131
|
-
|
|
132
|
-
if (normalized.includes("project-manager") || normalized.includes("manager")) return "pm";
|
|
133
|
-
if (normalized.includes("frontend")) return "frontend";
|
|
134
|
-
if (normalized.includes("fullstack")) return "fullstack";
|
|
135
|
-
if (normalized.includes("review")) return "reviewer";
|
|
136
|
-
return "codex";
|
|
63
|
+
function resolveAuthToken(env: EnvLike) {
|
|
64
|
+
return env.AUTH_TOKEN || env.AUTH || env.BENCHMARK_AUTH_TOKEN || "";
|
|
137
65
|
}
|
|
138
66
|
|
|
139
|
-
async function
|
|
140
|
-
options: RunAgentTurnOptions;
|
|
141
|
-
cliArgs: string[];
|
|
142
|
-
}) {
|
|
143
|
-
const scriptPath = join(args.options.scriptDir, "taskRun.ts");
|
|
144
|
-
const proc = Bun.spawn({
|
|
145
|
-
cmd: [process.execPath, scriptPath, ...args.cliArgs],
|
|
146
|
-
stdout: "pipe",
|
|
147
|
-
stderr: "pipe",
|
|
148
|
-
env: {
|
|
149
|
-
...process.env,
|
|
150
|
-
...args.options.env,
|
|
151
|
-
BASE_URL: args.options.serverUrl,
|
|
152
|
-
},
|
|
153
|
-
});
|
|
154
|
-
const [stdout, stderr, exitCode] = await Promise.all([
|
|
155
|
-
new Response(proc.stdout).text(),
|
|
156
|
-
new Response(proc.stderr).text(),
|
|
157
|
-
proc.exited,
|
|
158
|
-
]);
|
|
159
|
-
if (exitCode !== 0) {
|
|
160
|
-
throw new Error((stderr || stdout || `taskRun.ts exited ${exitCode}`).trim());
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async function defaultTaskRunRecorder(args: {
|
|
165
|
-
options: RunAgentTurnOptions;
|
|
166
|
-
status: "running" | "completed" | "failed";
|
|
167
|
-
dialogId?: string;
|
|
168
|
-
resultSummary?: string;
|
|
169
|
-
errorCode?: string;
|
|
170
|
-
toolEvidence?: TaskRunToolEvidence;
|
|
171
|
-
}) {
|
|
172
|
-
const context = args.options.taskRunContext;
|
|
173
|
-
if (!context?.rowDbKey) return;
|
|
174
|
-
const role = inferTaskRunAgentRole(args.options.agentName || args.options.agentKey);
|
|
175
|
-
if (role === "reviewer" && args.status !== "running") {
|
|
176
|
-
await runTaskRunCli({
|
|
177
|
-
options: args.options,
|
|
178
|
-
cliArgs: [
|
|
179
|
-
"request-review",
|
|
180
|
-
"--row-dbkey",
|
|
181
|
-
context.rowDbKey,
|
|
182
|
-
"--base-url",
|
|
183
|
-
args.options.serverUrl,
|
|
184
|
-
"--reviewer-agent-key",
|
|
185
|
-
args.options.agentKey,
|
|
186
|
-
...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
|
|
187
|
-
...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
|
|
188
|
-
],
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
await runTaskRunCli({
|
|
192
|
-
options: args.options,
|
|
193
|
-
cliArgs: [
|
|
194
|
-
"record-agent-run",
|
|
195
|
-
"--row-dbkey",
|
|
196
|
-
context.rowDbKey,
|
|
197
|
-
"--base-url",
|
|
198
|
-
args.options.serverUrl,
|
|
199
|
-
"--agent-key",
|
|
200
|
-
args.options.agentKey,
|
|
201
|
-
"--role",
|
|
202
|
-
role,
|
|
203
|
-
"--run-status",
|
|
204
|
-
args.status,
|
|
205
|
-
...(context.workItemId ? ["--work-item-id", context.workItemId] : []),
|
|
206
|
-
...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
|
|
207
|
-
...(args.resultSummary ? ["--result-summary", args.resultSummary.slice(0, 240)] : []),
|
|
208
|
-
...(args.errorCode ? ["--error-code", args.errorCode] : []),
|
|
209
|
-
...(args.toolEvidence?.toolsUsed?.length
|
|
210
|
-
? ["--tools-used", args.toolEvidence.toolsUsed.join(",")]
|
|
211
|
-
: []),
|
|
212
|
-
...(args.toolEvidence?.summary
|
|
213
|
-
? ["--tool-trace-summary", JSON.stringify(args.toolEvidence.summary)]
|
|
214
|
-
: []),
|
|
215
|
-
],
|
|
216
|
-
});
|
|
217
|
-
if (context.workItemId && args.dialogId) {
|
|
218
|
-
await runTaskRunCli({
|
|
219
|
-
options: args.options,
|
|
220
|
-
cliArgs: [
|
|
221
|
-
"update-work-item",
|
|
222
|
-
"--row-dbkey",
|
|
223
|
-
context.rowDbKey,
|
|
224
|
-
"--base-url",
|
|
225
|
-
args.options.serverUrl,
|
|
226
|
-
"--id",
|
|
227
|
-
context.workItemId,
|
|
228
|
-
"--dialog-ids",
|
|
229
|
-
args.dialogId,
|
|
230
|
-
],
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
if (role === "reviewer" && args.status !== "running") {
|
|
234
|
-
const reviewStatus =
|
|
235
|
-
args.status === "failed" ? "blocked" : classifyTaskRunReviewStatus(args.resultSummary);
|
|
236
|
-
if (reviewStatus) {
|
|
237
|
-
await runTaskRunCli({
|
|
238
|
-
options: args.options,
|
|
239
|
-
cliArgs: [
|
|
240
|
-
"review-result",
|
|
241
|
-
"--row-dbkey",
|
|
242
|
-
context.rowDbKey,
|
|
243
|
-
"--base-url",
|
|
244
|
-
args.options.serverUrl,
|
|
245
|
-
"--review-status",
|
|
246
|
-
reviewStatus,
|
|
247
|
-
"--reviewer-agent-key",
|
|
248
|
-
args.options.agentKey,
|
|
249
|
-
...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
|
|
250
|
-
...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
|
|
251
|
-
],
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async function recordTaskRunOutcome(args: {
|
|
258
|
-
options: RunAgentTurnOptions;
|
|
259
|
-
status: "running" | "completed" | "failed";
|
|
260
|
-
dialogId?: string;
|
|
261
|
-
resultSummary?: string;
|
|
262
|
-
errorCode?: string;
|
|
263
|
-
toolEvidence?: TaskRunToolEvidence;
|
|
264
|
-
}) {
|
|
265
|
-
if (!args.options.taskRunContext?.rowDbKey) return;
|
|
266
|
-
try {
|
|
267
|
-
await (args.options.taskRunRecorder ?? defaultTaskRunRecorder)(args);
|
|
268
|
-
} catch (error) {
|
|
269
|
-
args.options.output.write(
|
|
270
|
-
`[nolo] task-run writeback failed: ${error instanceof Error ? error.message : String(error)}\n`
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
function formatUsage(usage: any, dialogId: unknown) {
|
|
276
|
-
const parts: string[] = [];
|
|
277
|
-
if (typeof dialogId === "string" && dialogId) parts.push(`dialog=${dialogId}`);
|
|
278
|
-
|
|
279
|
-
const input = usage?.input_tokens ?? usage?.prompt_tokens ?? 0;
|
|
280
|
-
const output = usage?.output_tokens ?? usage?.completion_tokens ?? 0;
|
|
281
|
-
if (input || output) parts.push(`tokens=${input}+${output}`);
|
|
282
|
-
|
|
283
|
-
return parts.length ? ` (${parts.join(" ")})` : "";
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function buildTransportErrorHint(serverUrl: string, error: unknown) {
|
|
287
|
-
const endpoint = `${serverUrl}/api/agent/run`;
|
|
288
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
289
|
-
|
|
290
|
-
let detail =
|
|
291
|
-
`[nolo] Could not reach ${endpoint}.\n` +
|
|
292
|
-
`Reason: ${reason}\n`;
|
|
293
|
-
|
|
294
|
-
try {
|
|
295
|
-
const parsed = new URL(serverUrl);
|
|
296
|
-
if (parsed.hostname === "127.0.0.1" || parsed.hostname === "localhost") {
|
|
297
|
-
detail +=
|
|
298
|
-
"If you meant local dev, start the local API first.\n" +
|
|
299
|
-
"Otherwise set NOLO_SERVER to a reachable server, or re-run `nolo login --server https://nolo.chat`.\n";
|
|
300
|
-
return detail;
|
|
301
|
-
}
|
|
302
|
-
} catch {
|
|
303
|
-
// Keep the generic hint below when serverUrl is not a valid absolute URL.
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
detail +=
|
|
307
|
-
"Check NOLO_SERVER / BASE_URL and make sure the configured server is reachable.\n";
|
|
308
|
-
return detail;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async function runScriptBridge(options: RunAgentTurnOptions, scriptPath: string) {
|
|
67
|
+
async function runScriptBridge(options: RunAgentTurnOptions, scriptPath: string) {
|
|
312
68
|
options.output.write(`\n${options.agentName} -> working via local script...\n\n`);
|
|
313
69
|
const proc = Bun.spawn({
|
|
314
70
|
cmd: [
|
|
@@ -361,394 +117,45 @@ async function runScriptBridge(options: RunAgentTurnOptions, scriptPath: string)
|
|
|
361
117
|
}
|
|
362
118
|
return { exitCode };
|
|
363
119
|
}
|
|
364
|
-
|
|
365
|
-
async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string) {
|
|
366
|
-
options.output.write(`\n${options.agentName} -> working...\n`);
|
|
367
|
-
|
|
368
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
369
|
-
let res: Response;
|
|
370
|
-
try {
|
|
371
|
-
res = await fetchImpl(`${options.serverUrl}/api/agent/run`, {
|
|
372
|
-
method: "POST",
|
|
373
|
-
headers: {
|
|
374
|
-
Authorization: `Bearer ${authToken}`,
|
|
375
|
-
"Content-Type": "application/json",
|
|
376
|
-
},
|
|
377
|
-
body: JSON.stringify({
|
|
378
|
-
agentKey: options.agentKey,
|
|
379
|
-
userInput: buildUserInputContent(
|
|
380
|
-
prependTaskRunPrompt(options.message, options.taskRunContext),
|
|
381
|
-
options.imageUrls
|
|
382
|
-
),
|
|
383
|
-
runtimeContext: {
|
|
384
|
-
surface: "cli",
|
|
385
|
-
host: "terminal",
|
|
386
|
-
runtime: "bun",
|
|
387
|
-
entrypoint: "nolo-cli",
|
|
388
|
-
capabilities: ["text-io", "streaming", "slash-commands"],
|
|
389
|
-
...(options.taskRunContext
|
|
390
|
-
? {
|
|
391
|
-
taskRun: {
|
|
392
|
-
rowDbKey: options.taskRunContext.rowDbKey,
|
|
393
|
-
...(options.taskRunContext.taskRunId
|
|
394
|
-
? { taskRunId: options.taskRunContext.taskRunId }
|
|
395
|
-
: {}),
|
|
396
|
-
...(options.taskRunContext.workItemId
|
|
397
|
-
? { workItemId: options.taskRunContext.workItemId }
|
|
398
|
-
: {}),
|
|
399
|
-
...(options.taskRunContext.artifactIds?.length
|
|
400
|
-
? { artifactIds: options.taskRunContext.artifactIds }
|
|
401
|
-
: {}),
|
|
402
|
-
},
|
|
403
|
-
}
|
|
404
|
-
: {}),
|
|
405
|
-
},
|
|
406
|
-
...(options.continueDialogId
|
|
407
|
-
? { continueDialogId: options.continueDialogId }
|
|
408
|
-
: {}),
|
|
409
|
-
...(options.spaceId ? { spaceId: options.spaceId } : {}),
|
|
410
|
-
...(options.category ? { category: options.category } : {}),
|
|
411
|
-
...(options.inheritedFromDialogKey
|
|
412
|
-
? { inheritedFromDialogKey: options.inheritedFromDialogKey }
|
|
413
|
-
: {}),
|
|
414
|
-
...(options.parentDialogId ? { parentDialogId: options.parentDialogId } : {}),
|
|
415
|
-
...(options.background ? { background: true } : {}),
|
|
416
|
-
...(typeof options.maxToolRounds === "number" ? { maxRounds: options.maxToolRounds } : {}),
|
|
417
|
-
...(typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {}),
|
|
418
|
-
stream: !options.noStream && !options.background,
|
|
419
|
-
}),
|
|
420
|
-
});
|
|
421
|
-
} catch (error) {
|
|
422
|
-
options.output.write(buildTransportErrorHint(options.serverUrl, error));
|
|
423
|
-
return { exitCode: 1 };
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const contentType = res.headers.get("content-type") || "";
|
|
427
|
-
if (contentType.includes("text/event-stream") && res.body) {
|
|
428
|
-
const result = await readStreamingAgentRun(options, res);
|
|
429
|
-
await recordTaskRunOutcome({
|
|
430
|
-
options,
|
|
431
|
-
status: result.streamInterrupted
|
|
432
|
-
? "running"
|
|
433
|
-
: result.exitCode === 0
|
|
434
|
-
? "completed"
|
|
435
|
-
: "failed",
|
|
436
|
-
dialogId: result.dialogId,
|
|
437
|
-
...(result.exitCode !== 0 ? { errorCode: "STREAM_FAILED" } : {}),
|
|
438
|
-
});
|
|
439
|
-
return result;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
let data: any = {};
|
|
443
|
-
try {
|
|
444
|
-
data = await res.json();
|
|
445
|
-
} catch {
|
|
446
|
-
data = {};
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
if (!res.ok) {
|
|
450
|
-
options.output.write(`[nolo] Agent request failed: HTTP ${res.status}\n`);
|
|
451
|
-
if (data?.error || data?.message) {
|
|
452
|
-
options.output.write(`${data.error || data.message}\n`);
|
|
453
|
-
}
|
|
454
|
-
await recordTaskRunOutcome({
|
|
455
|
-
options,
|
|
456
|
-
status: "failed",
|
|
457
|
-
errorCode: `HTTP_${res.status}`,
|
|
458
|
-
resultSummary: String(data?.error || data?.message || "").trim() || undefined,
|
|
459
|
-
});
|
|
460
|
-
return { exitCode: 1 };
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
const content = String(data?.content ?? data?.message ?? "").trim();
|
|
464
|
-
if (content) {
|
|
465
|
-
options.output.write(`\n${options.agentName} > ${content}\n`);
|
|
466
|
-
} else {
|
|
467
|
-
options.output.write(`\n${options.agentName} > (no text response)\n`);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const usage = formatUsage(data?.usage, data?.dialogId);
|
|
471
|
-
if (usage && shouldShowUsage(options.env)) options.output.write(`${usage}\n`);
|
|
472
|
-
const result = {
|
|
473
|
-
exitCode: 0,
|
|
474
|
-
...(typeof data?.dialogId === "string" && data.dialogId
|
|
475
|
-
? { dialogId: data.dialogId }
|
|
476
|
-
: {}),
|
|
477
|
-
};
|
|
478
|
-
await recordTaskRunOutcome({
|
|
479
|
-
options,
|
|
480
|
-
status: options.background ? "running" : "completed",
|
|
481
|
-
dialogId: result.dialogId,
|
|
482
|
-
...(!options.background && content ? { resultSummary: content } : {}),
|
|
483
|
-
});
|
|
484
|
-
return result;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
async function runInjectedLocalAgentTurn(options: RunAgentTurnOptions) {
|
|
488
|
-
return runLocalAgentTurnWithAutoRoundExpansion(options, { reportFailure: true });
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
async function refreshMissingLocalAgentConfig(options: RunAgentTurnOptions) {
|
|
492
|
-
const adapter = resolveLocalRuntimeAdapter(options);
|
|
493
|
-
if (!adapter) return false;
|
|
494
|
-
const agentConfig = await adapter.loadAgentConfig(options.agentKey);
|
|
495
|
-
return Boolean(agentConfig);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
async function runLocalAgentTurnWithAutoRoundExpansion(
|
|
499
|
-
options: RunAgentTurnOptions,
|
|
500
|
-
settings: { reportFailure: boolean }
|
|
501
|
-
) {
|
|
502
|
-
const maxRetryLimit = resolveLocalToolRoundRetryLimit(options);
|
|
503
|
-
let currentMaxToolRounds = options.maxToolRounds;
|
|
504
|
-
let lastResult: Awaited<ReturnType<typeof runLocalAgentTurnForCli>> | null = null;
|
|
505
|
-
|
|
506
|
-
while (true) {
|
|
507
|
-
const attemptOptions = {
|
|
508
|
-
...options,
|
|
509
|
-
...(typeof currentMaxToolRounds === "number" ? { maxToolRounds: currentMaxToolRounds } : {}),
|
|
510
|
-
};
|
|
511
|
-
const result = await runLocalAgentTurnForCli(attemptOptions, { reportFailure: false });
|
|
512
|
-
lastResult = result;
|
|
513
|
-
if (result.exitCode === 0) return result;
|
|
514
|
-
|
|
515
|
-
const exhaustedRounds = parseLocalToolRoundLimitError(result.localError);
|
|
516
|
-
if (exhaustedRounds === null) break;
|
|
517
|
-
|
|
518
|
-
const nextMaxToolRounds = nextLocalToolRoundLimit(exhaustedRounds);
|
|
519
|
-
if (nextMaxToolRounds > maxRetryLimit) break;
|
|
520
|
-
|
|
521
|
-
options.output.write(
|
|
522
|
-
`[nolo] Local agent used all ${exhaustedRounds} tool rounds; retrying with ${nextMaxToolRounds}.\n`
|
|
523
|
-
);
|
|
524
|
-
currentMaxToolRounds = nextMaxToolRounds;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (settings.reportFailure && lastResult?.localError) {
|
|
528
|
-
options.output.write(
|
|
529
|
-
`[nolo] Local agent run failed: ${
|
|
530
|
-
lastResult.localError instanceof Error ? lastResult.localError.message : String(lastResult.localError)
|
|
531
|
-
}\n`
|
|
532
|
-
);
|
|
533
|
-
await recordTaskRunOutcome({
|
|
534
|
-
options,
|
|
535
|
-
status: "failed",
|
|
536
|
-
errorCode: "LOCAL_AGENT_FAILED",
|
|
537
|
-
resultSummary:
|
|
538
|
-
lastResult.localError instanceof Error ? lastResult.localError.message : String(lastResult.localError),
|
|
539
|
-
toolEvidence: lastResult.toolEvidence,
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
return lastResult ?? { exitCode: 1 };
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
async function runLocalAgentTurnForCli(
|
|
546
|
-
options: RunAgentTurnOptions,
|
|
547
|
-
settings: { reportFailure: boolean }
|
|
548
|
-
) {
|
|
549
|
-
const adapter = resolveLocalRuntimeAdapter(options);
|
|
550
|
-
if (!adapter) {
|
|
551
|
-
options.output.write("[nolo] Local runtime was requested but no local runtime adapter is available.\n");
|
|
552
|
-
return { exitCode: 1 };
|
|
553
|
-
}
|
|
554
120
|
|
|
555
|
-
options.output.write(`\n${options.agentName} -> working locally...\n`);
|
|
556
|
-
const toolEvents: LocalAgentToolEvent[] = [];
|
|
557
|
-
try {
|
|
558
|
-
const traceLocalTools = shouldTraceLocalTools(options);
|
|
559
|
-
const collectToolEvidence = shouldCollectLocalToolEvidence(options);
|
|
560
|
-
const result = await runLocalAgentTurn({
|
|
561
|
-
adapter,
|
|
562
|
-
agentRef: options.agentKey,
|
|
563
|
-
input: buildUserInputContent(
|
|
564
|
-
prependTaskRunPrompt(options.message, options.taskRunContext),
|
|
565
|
-
options.imageUrls
|
|
566
|
-
),
|
|
567
|
-
continueDialogId: options.continueDialogId,
|
|
568
|
-
spaceId: options.spaceId,
|
|
569
|
-
category: options.category,
|
|
570
|
-
inheritedFromDialogKey: options.inheritedFromDialogKey,
|
|
571
|
-
parentDialogId: options.parentDialogId,
|
|
572
|
-
background: options.background,
|
|
573
|
-
noStream: options.noStream,
|
|
574
|
-
maxToolRounds: options.maxToolRounds,
|
|
575
|
-
...(traceLocalTools || collectToolEvidence
|
|
576
|
-
? {
|
|
577
|
-
onToolEvent: (event) => {
|
|
578
|
-
if (collectToolEvidence) toolEvents.push(event);
|
|
579
|
-
if (traceLocalTools) options.output.write(formatToolTraceEvent(event));
|
|
580
|
-
},
|
|
581
|
-
}
|
|
582
|
-
: {}),
|
|
583
|
-
});
|
|
584
|
-
const content = result.content.trim();
|
|
585
|
-
if (content) {
|
|
586
|
-
options.output.write(`\n${options.agentName} > ${content}\n`);
|
|
587
|
-
} else {
|
|
588
|
-
options.output.write(`\n${options.agentName} > (no text response)\n`);
|
|
589
|
-
}
|
|
590
|
-
await recordTaskRunOutcome({
|
|
591
|
-
options,
|
|
592
|
-
status: options.background ? "running" : "completed",
|
|
593
|
-
dialogId: result.dialogId,
|
|
594
|
-
...(!options.background && content ? { resultSummary: content } : {}),
|
|
595
|
-
toolEvidence: summarizeLocalToolEvidence(toolEvents),
|
|
596
|
-
});
|
|
597
|
-
return { exitCode: 0, dialogId: result.dialogId };
|
|
598
|
-
} catch (error) {
|
|
599
|
-
if (settings.reportFailure) {
|
|
600
|
-
options.output.write(
|
|
601
|
-
`[nolo] Local agent run failed: ${
|
|
602
|
-
error instanceof Error ? error.message : String(error)
|
|
603
|
-
}\n`
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
return { exitCode: 1, localError: error, toolEvidence: summarizeLocalToolEvidence(toolEvents) };
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
async function readStreamingAgentRun(
|
|
611
|
-
options: RunAgentTurnOptions,
|
|
612
|
-
res: Response,
|
|
613
|
-
): Promise<RunAgentTurnResult> {
|
|
614
|
-
const reader = res.body?.getReader();
|
|
615
|
-
if (!reader) {
|
|
616
|
-
options.output.write("[nolo] Agent stream response did not include a readable body.\n");
|
|
617
|
-
return { exitCode: 1 };
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
const decoder = new TextDecoder();
|
|
621
|
-
const writer = createStreamingTextWriter({
|
|
622
|
-
write: (chunk) => options.output.write(chunk),
|
|
623
|
-
});
|
|
624
|
-
let buffer = "";
|
|
625
|
-
let content = "";
|
|
626
|
-
let dialogId: string | undefined;
|
|
627
|
-
let usage: any;
|
|
628
|
-
let hasPrintedLabel = false;
|
|
629
|
-
|
|
630
|
-
const printLabel = () => {
|
|
631
|
-
if (hasPrintedLabel) return;
|
|
632
|
-
options.output.write(`\n${options.agentName} > `);
|
|
633
|
-
hasPrintedLabel = true;
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
const handlePayload = (payload: any) => {
|
|
637
|
-
if (typeof payload?.dialogId === "string" && payload.dialogId.trim()) {
|
|
638
|
-
dialogId = payload.dialogId;
|
|
639
|
-
}
|
|
640
|
-
if (payload?.error || payload?.type === "error") {
|
|
641
|
-
throw new Error(String(payload.error || payload.message || "Agent stream failed"));
|
|
642
|
-
}
|
|
643
|
-
if (payload?.type === "done") {
|
|
644
|
-
usage = payload.usage;
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
if (payload?.type === "dialog" || payload?.type === "status") {
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
const chunk =
|
|
652
|
-
payload?.type === "text"
|
|
653
|
-
? payload.content
|
|
654
|
-
: typeof payload?.chunk === "string"
|
|
655
|
-
? payload.chunk
|
|
656
|
-
: "";
|
|
657
|
-
if (!chunk) return;
|
|
658
|
-
|
|
659
|
-
printLabel();
|
|
660
|
-
content += chunk;
|
|
661
|
-
writer.push(chunk);
|
|
662
|
-
};
|
|
663
|
-
|
|
664
|
-
try {
|
|
665
|
-
while (true) {
|
|
666
|
-
const { done, value } = await reader.read();
|
|
667
|
-
if (done) break;
|
|
668
|
-
|
|
669
|
-
buffer += decoder.decode(value, { stream: true });
|
|
670
|
-
const events = buffer.split("\n\n");
|
|
671
|
-
buffer = events.pop() ?? "";
|
|
672
|
-
|
|
673
|
-
for (const event of events) {
|
|
674
|
-
const dataLines = event
|
|
675
|
-
.split("\n")
|
|
676
|
-
.filter((line) => line.startsWith("data:"))
|
|
677
|
-
.map((line) => line.slice(5).trim())
|
|
678
|
-
.filter(Boolean);
|
|
679
|
-
for (const raw of dataLines) {
|
|
680
|
-
handlePayload(JSON.parse(raw));
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
if (buffer.trim()) {
|
|
685
|
-
const raw = buffer
|
|
686
|
-
.split("\n")
|
|
687
|
-
.find((line) => line.startsWith("data:"))
|
|
688
|
-
?.slice(5)
|
|
689
|
-
.trim();
|
|
690
|
-
if (raw) handlePayload(JSON.parse(raw));
|
|
691
|
-
}
|
|
692
|
-
} catch (error) {
|
|
693
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
694
|
-
if (dialogId) {
|
|
695
|
-
options.output.write(
|
|
696
|
-
`\n[nolo] Agent stream transport interrupted after dialog ${dialogId} was created: ${message}\n`
|
|
697
|
-
);
|
|
698
|
-
options.output.write("[nolo] The agent run may still finish on the server; read the dialog before retrying.\n");
|
|
699
|
-
return { exitCode: 0, dialogId, streamInterrupted: true };
|
|
700
|
-
}
|
|
701
|
-
options.output.write(`\n[nolo] Agent stream failed: ${message}\n`);
|
|
702
|
-
return { exitCode: 1 };
|
|
703
|
-
} finally {
|
|
704
|
-
writer.flushAll();
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
if (!content) {
|
|
708
|
-
options.output.write(`\n${options.agentName} > (no text response)\n`);
|
|
709
|
-
} else {
|
|
710
|
-
options.output.write("\n");
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
const usageText = formatUsage(usage, dialogId);
|
|
714
|
-
if (usageText && shouldShowUsage(options.env)) options.output.write(`${usageText}\n`);
|
|
715
|
-
return {
|
|
716
|
-
exitCode: 0,
|
|
717
|
-
...(dialogId ? { dialogId } : {}),
|
|
718
|
-
};
|
|
719
|
-
}
|
|
720
|
-
|
|
721
121
|
export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
122
|
+
const dialogLineage = normalizeAgentRunDialogLineage(options);
|
|
123
|
+
const effectiveOptions: RunAgentTurnOptions = {
|
|
124
|
+
...options,
|
|
125
|
+
continueDialogId: dialogLineage.continueDialogId,
|
|
126
|
+
inheritedFromDialogKey: dialogLineage.inheritedFromDialogKey,
|
|
127
|
+
parentDialogId: dialogLineage.parentDialogId,
|
|
128
|
+
};
|
|
722
129
|
const authToken = resolveAuthToken(options.env);
|
|
723
|
-
const scriptPath = join(
|
|
130
|
+
const scriptPath = join(effectiveOptions.scriptDir, "chatWithAgent.ts");
|
|
724
131
|
const scriptPathExists = (options.scriptPathExists ?? existsSync)(scriptPath);
|
|
725
|
-
const runtimeMode = resolveRequestedRuntimeMode(
|
|
132
|
+
const runtimeMode = resolveRequestedRuntimeMode(effectiveOptions);
|
|
726
133
|
|
|
727
134
|
if (runtimeMode === "local") {
|
|
728
|
-
return runInjectedLocalAgentTurn(
|
|
135
|
+
return runInjectedLocalAgentTurn(effectiveOptions);
|
|
729
136
|
}
|
|
730
137
|
|
|
731
|
-
if (runtimeMode === "auto" && shouldAttemptAutoLocal(
|
|
138
|
+
if (runtimeMode === "auto" && shouldAttemptAutoLocal(effectiveOptions)) {
|
|
732
139
|
const skipLocal = await shouldSkipAutoLocalForServerPlatformTools({
|
|
733
|
-
...
|
|
734
|
-
resolveLocalRuntimeAdapter: () => resolveLocalRuntimeAdapter(
|
|
140
|
+
...effectiveOptions,
|
|
141
|
+
resolveLocalRuntimeAdapter: () => resolveLocalRuntimeAdapter(effectiveOptions),
|
|
735
142
|
});
|
|
736
143
|
if (!skipLocal) {
|
|
737
|
-
const localResult = await runLocalAgentTurnWithAutoRoundExpansion(
|
|
144
|
+
const localResult = await runLocalAgentTurnWithAutoRoundExpansion(effectiveOptions, { reportFailure: false });
|
|
738
145
|
if (localResult.exitCode === 0) {
|
|
739
146
|
return {
|
|
740
147
|
exitCode: localResult.exitCode,
|
|
741
148
|
...(localResult.dialogId ? { dialogId: localResult.dialogId } : {}),
|
|
742
149
|
};
|
|
743
150
|
}
|
|
744
|
-
if (isMissingLocalAgentConfigError(localResult.localError,
|
|
745
|
-
|
|
151
|
+
if (isMissingLocalAgentConfigError(localResult.localError, effectiveOptions.agentKey)) {
|
|
152
|
+
effectiveOptions.output.write(
|
|
746
153
|
`[nolo] Local agent config was missing; refreshing from the configured server and retrying local once.\n`
|
|
747
154
|
);
|
|
748
155
|
try {
|
|
749
|
-
const refreshed = await refreshMissingLocalAgentConfig(
|
|
156
|
+
const refreshed = await refreshMissingLocalAgentConfig(effectiveOptions);
|
|
750
157
|
if (refreshed) {
|
|
751
|
-
const retriedLocalResult = await runLocalAgentTurnWithAutoRoundExpansion(
|
|
158
|
+
const retriedLocalResult = await runLocalAgentTurnWithAutoRoundExpansion(effectiveOptions, {
|
|
752
159
|
reportFailure: false,
|
|
753
160
|
});
|
|
754
161
|
if (retriedLocalResult.exitCode === 0) {
|
|
@@ -766,16 +173,16 @@ export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
|
766
173
|
}
|
|
767
174
|
|
|
768
175
|
if (shouldUseScriptBridge({ hasAuthToken: Boolean(authToken), scriptPathExists })) {
|
|
769
|
-
return runScriptBridge(
|
|
176
|
+
return runScriptBridge(effectiveOptions, scriptPath);
|
|
770
177
|
}
|
|
771
|
-
|
|
772
|
-
if (!authToken) {
|
|
773
|
-
|
|
774
|
-
"[nolo] This install needs an auth token before it can talk to agents.\n" +
|
|
775
|
-
"Set AUTH_TOKEN, or use the repo-local CLI where the dev script bridge is available.\n"
|
|
776
|
-
);
|
|
178
|
+
|
|
179
|
+
if (!authToken) {
|
|
180
|
+
effectiveOptions.output.write(
|
|
181
|
+
"[nolo] This install needs an auth token before it can talk to agents.\n" +
|
|
182
|
+
"Set AUTH_TOKEN, or use the repo-local CLI where the dev script bridge is available.\n"
|
|
183
|
+
);
|
|
777
184
|
return { exitCode: 1 };
|
|
778
185
|
}
|
|
779
186
|
|
|
780
|
-
return runHttpAgentTurn(
|
|
781
|
-
}
|
|
187
|
+
return runHttpAgentTurn(effectiveOptions, { authToken });
|
|
188
|
+
}
|