nolo-cli 0.1.39 → 0.1.41
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/README.md +4 -4
- package/agent-runtime/dialogWritePlan.ts +39 -0
- package/agent-runtime/hostAdapter.ts +4 -0
- package/agent-runtime/hybridRecordStore.ts +5 -3
- package/agent-runtime/index.ts +15 -0
- package/agent-runtime/localLoop.ts +87 -7
- package/agent-runtime/localToolPolicy.ts +2 -13
- package/agent-runtime/localWorkspaceTools.ts +42 -110
- package/agent-runtime/runtimeToolPolicy.ts +2 -11
- package/agent-runtime/runtimeToolSurface.ts +198 -0
- package/agent-runtime/types.ts +1 -0
- package/agentAliases.ts +2 -1
- package/agentRunCommand.ts +10 -32
- package/agentRuntimeLocal.ts +1 -0
- package/ai/agent/_executeModel.ts +146 -0
- package/ai/agent/agentSlice.ts +556 -1
- package/ai/agent/appWorkingMemory.ts +126 -0
- package/ai/agent/buildEditingContext.ts +378 -0
- package/ai/agent/buildSystemPrompt.ts +585 -0
- package/ai/agent/canvasEditingContext.ts +49 -0
- package/ai/agent/cleanAgentMessages.ts +140 -0
- package/ai/agent/cliChatClient.ts +153 -0
- package/ai/agent/cliExecutor.ts +314 -40
- package/ai/agent/contextCompiler.ts +107 -0
- package/ai/agent/contextLayerContract.ts +44 -0
- package/ai/agent/createAgentSchema.ts +272 -0
- package/ai/agent/currentTimeContext.ts +65 -0
- package/ai/agent/executeToolCall.ts +58 -0
- package/ai/agent/fetchAgentContexts.ts +42 -0
- package/ai/agent/generatePrompt.ts +3 -0
- package/ai/agent/getFullChatContextKeys.ts +168 -0
- package/ai/agent/guidedCreation/capabilities.ts +84 -0
- package/ai/agent/guidedCreation/types.ts +38 -0
- package/ai/agent/isLiveAudioOnlyAgent.ts +26 -0
- package/ai/agent/liveAudioModel.ts +2 -0
- package/ai/agent/pageBuilderHandoffRules.ts +75 -0
- package/ai/agent/persistMessageWithFixedId.ts +37 -0
- package/ai/agent/planSlice.ts +259 -0
- package/ai/agent/referenceUtils.ts +229 -0
- package/ai/agent/runAgentBackground.ts +310 -0
- package/ai/agent/runAgentClientLoop.ts +164 -0
- package/ai/agent/runtimeGuidance.ts +116 -0
- package/ai/agent/serverOrigin.ts +7 -0
- package/ai/agent/startParallelAgentStreams.ts +424 -0
- package/ai/agent/startupProtocol.ts +53 -0
- package/ai/agent/streamAgentChatTurn.ts +2001 -0
- package/ai/agent/streamAgentChatTurnUtils.ts +860 -0
- package/ai/agent/toolFailureGuard.ts +99 -0
- package/ai/agent/types.ts +73 -0
- package/ai/agent/utils/imageOutput.ts +37 -0
- package/ai/agent/utils/publicImageAgentMode.ts +26 -0
- package/ai/ai.locale.ts +1095 -0
- package/ai/chat/accumulateToolCallChunks.ts +126 -0
- package/ai/chat/fetchUtils.ts +143 -0
- package/ai/chat/inlineImageUrlsForCustomProvider.ts +117 -0
- package/ai/chat/parseApiError.ts +67 -0
- package/ai/chat/parseMultilineSSE.ts +95 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +897 -0
- package/ai/chat/sendOpenAIResponseRequest.ts +720 -0
- package/ai/chat/serverProxyRetry.ts +102 -0
- package/ai/chat/shouldUseServerProxy.ts +18 -0
- package/ai/chat/streamRetry.ts +46 -0
- package/ai/chat/updateTotalUsage.ts +89 -0
- package/ai/context/buildReferenceContext.ts +437 -0
- package/ai/context/retention.ts +165 -0
- package/ai/context/tokenUtils.ts +78 -0
- package/ai/llm/agentCapabilities.ts +74 -0
- package/ai/llm/deepinfra.ts +79 -0
- package/ai/llm/fireworks.ts +68 -0
- package/ai/llm/generateRequestBody.ts +165 -0
- package/ai/llm/getModelContextWindow.ts +93 -0
- package/ai/llm/getPricing.ts +252 -0
- package/ai/llm/imagePricing.ts +66 -0
- package/ai/llm/isResponseAPIModel.ts +13 -0
- package/ai/llm/kimi.ts +23 -0
- package/ai/llm/mimo.ts +99 -0
- package/ai/llm/mistral.ts +21 -0
- package/ai/llm/models.ts +45 -0
- package/ai/llm/openrouterModels.ts +6 -0
- package/ai/llm/providers.ts +313 -0
- package/ai/llm/reasoningModels.ts +27 -0
- package/ai/llm/types.ts +82 -0
- package/ai/llm/usageRequestOptions.ts +59 -0
- package/ai/memory/queryShared.ts +161 -0
- package/ai/memory/recentRelationshipRecap.ts +247 -0
- package/ai/memory/remember.ts +167 -0
- package/ai/memory/store.ts +20 -0
- package/ai/memory/storeShared.ts +76 -0
- package/ai/memory/types.ts +46 -0
- package/ai/memory/understanding.ts +349 -0
- package/ai/memory/understandingGreeting.ts +264 -0
- package/ai/policy/personalizationDialog.ts +333 -0
- package/ai/policy/runtimePolicy.ts +454 -0
- package/ai/policy/selfUpdateFields.ts +48 -0
- package/ai/policy/types.ts +64 -0
- package/ai/skills/referenceRuntime.ts +274 -0
- package/ai/skills/skillDiagnostics.ts +251 -0
- package/ai/skills/skillDocBuilder.ts +139 -0
- package/ai/skills/skillSummaryMarker.ts +26 -0
- package/ai/token/calculatePrice.ts +576 -0
- package/ai/token/missingUsageEstimate.ts +42 -0
- package/ai/token/normalizeUsage.ts +124 -0
- package/ai/token/openaiImageGenerationUsage.ts +56 -0
- package/ai/token/prepareTokenUsageData.ts +93 -0
- package/ai/token/resolveBillingTarget.ts +52 -0
- package/ai/token/saveTokenRecord.ts +53 -0
- package/ai/token/types.ts +103 -0
- package/ai/tools/agent/agentTools.ts +235 -0
- package/ai/tools/agent/agentUpdateShared.ts +311 -0
- package/ai/tools/agent/callAgentTool.ts +139 -0
- package/ai/tools/agent/createAgentTool.ts +512 -0
- package/ai/tools/agent/createDialogTool.ts +69 -0
- package/ai/tools/agent/createSkillAgentTool.ts +62 -0
- package/ai/tools/agent/parallelBudget.ts +221 -0
- package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
- package/ai/tools/agent/presets/appBuilderPreset.ts +154 -0
- package/ai/tools/agent/runLlmTool.ts +96 -0
- package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
- package/ai/tools/agent/skillAgentArgs.ts +106 -0
- package/ai/tools/agent/startAgentDialogTool.ts +53 -0
- package/ai/tools/agent/streamParallelAgentsTool.ts +123 -0
- package/ai/tools/agent/updateAgentTool.ts +96 -0
- package/ai/tools/agent/updateSelfTool.ts +113 -0
- package/ai/tools/amazonProductScraperTool.ts +86 -0
- package/ai/tools/apifyActorClient.ts +45 -0
- package/ai/tools/appEditGuard.ts +372 -0
- package/ai/tools/appReadSnapshot.ts +153 -0
- package/ai/tools/appTools.ts +1549 -0
- package/ai/tools/applyEditTool.ts +259 -0
- package/ai/tools/applyLineEditsTool.ts +315 -0
- package/ai/tools/browserTools/click.ts +33 -0
- package/ai/tools/browserTools/closeSession.ts +29 -0
- package/ai/tools/browserTools/common.ts +27 -0
- package/ai/tools/browserTools/openSession.ts +48 -0
- package/ai/tools/browserTools/readContent.ts +38 -0
- package/ai/tools/browserTools/selectOption.ts +46 -0
- package/ai/tools/browserTools/typeText.ts +42 -0
- package/ai/tools/category/createCategoryTool.ts +66 -0
- package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
- package/ai/tools/category/updateContentCategoryTool.ts +75 -0
- package/ai/tools/cfBrowserTools.ts +319 -0
- package/ai/tools/cfSpeechToTextTool.ts +49 -0
- package/ai/tools/checkEnvTool.ts +102 -0
- package/ai/tools/cloudflareCrawlTool.ts +289 -0
- package/ai/tools/codeSearchTool.ts +123 -0
- package/ai/tools/codeTools.ts +101 -0
- package/ai/tools/convertMarxistsBookTool.ts +103 -0
- package/ai/tools/createDocTool.ts +132 -0
- package/ai/tools/createSkillDocTool.ts +155 -0
- package/ai/tools/createWorkflowTool.ts +154 -0
- package/ai/tools/delayTool.ts +31 -0
- package/ai/tools/deleteSpacesTool.ts +325 -0
- package/ai/tools/deleteSpacesToolModel.ts +159 -0
- package/ai/tools/devReloadUtils.ts +29 -0
- package/ai/tools/dialogMessageSearch.ts +137 -0
- package/ai/tools/doctorSkillTool.ts +72 -0
- package/ai/tools/ecommerceScraperTool.ts +86 -0
- package/ai/tools/emailTools.ts +549 -0
- package/ai/tools/evalSkillTool.ts +92 -0
- package/ai/tools/exaSearchTool.ts +63 -0
- package/ai/tools/execShellTool.ts +266 -0
- package/ai/tools/executeSqlTool.ts +192 -0
- package/ai/tools/fetchWebpageSupport.ts +333 -0
- package/ai/tools/fetchWebpageTool.ts +97 -0
- package/ai/tools/geminiImagePreviewTool.ts +386 -0
- package/ai/tools/generateDocxTool.ts +215 -0
- package/ai/tools/googleSearchScraperTool.ts +106 -0
- package/ai/tools/importDataTool.ts +133 -0
- package/ai/tools/importSkillTool.ts +162 -0
- package/ai/tools/index.ts +2308 -0
- package/ai/tools/jdProductScraperTool.ts +821 -0
- package/ai/tools/listUserSpacesTool.ts +113 -0
- package/ai/tools/localFilesTool.ts +276 -0
- package/ai/tools/marxistsOfflineBook.ts +253 -0
- package/ai/tools/modelUsageTools.ts +206 -0
- package/ai/tools/noloWorkspaceReadTools.ts +467 -0
- package/ai/tools/olmOcrTool.ts +33 -0
- package/ai/tools/openaiImageTool.ts +267 -0
- package/ai/tools/prepareTools.ts +23 -0
- package/ai/tools/readDocTool.ts +88 -0
- package/ai/tools/readFileTool.ts +214 -0
- package/ai/tools/readTool.ts +194 -0
- package/ai/tools/readXPostTool.ts +229 -0
- package/ai/tools/readXhsProfileTool.ts +627 -0
- package/ai/tools/rememberMemoryTool.ts +84 -0
- package/ai/tools/remotionVideoTool.ts +151 -0
- package/ai/tools/searchDialogMessagesTool.ts +222 -0
- package/ai/tools/searchWorkspaceTool.ts +259 -0
- package/ai/tools/skillFollowup.ts +86 -0
- package/ai/tools/surfWeatherTool.ts +169 -0
- package/ai/tools/table/addTableRowTool.ts +217 -0
- package/ai/tools/table/createTableTool.ts +315 -0
- package/ai/tools/table/rowTools.ts +386 -0
- package/ai/tools/table/schemaTools.ts +244 -0
- package/ai/tools/table/shareTableTool.ts +148 -0
- package/ai/tools/table/toolShared.ts +129 -0
- package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
- package/ai/tools/toolApiClient.ts +279 -0
- package/ai/tools/toolResultError.ts +42 -0
- package/ai/tools/toolRunSlice.ts +303 -0
- package/ai/tools/toolSchemaCompatibility.ts +53 -0
- package/ai/tools/uiAskChoiceTool.ts +104 -0
- package/ai/tools/updateContentTitleTool.ts +84 -0
- package/ai/tools/updateDocTool.ts +105 -0
- package/ai/tools/updateUserPreferenceProfileTool.ts +153 -0
- package/ai/tools/wereadGatewayTool.ts +152 -0
- package/ai/tools/whisperTool.ts +76 -0
- package/ai/tools/writeFileTool.ts +213 -0
- package/ai/tools/youtubeScraperTool.ts +116 -0
- package/ai/tools/ziweiChartTool.ts +678 -0
- package/ai/types.ts +55 -0
- package/ai/workflow/workflowExecutor.ts +323 -0
- package/ai/workflow/workflowSlice.ts +73 -0
- package/ai/workflow/workflowTypes.ts +106 -0
- package/app/actions/syncAppRecord.ts +73 -0
- package/app/constants/animationSets.ts +21 -0
- package/app/constants/appEditor.ts +99 -0
- package/app/favorite/favoriteSlice.ts +690 -0
- package/app/favorite/type.ts +43 -0
- package/app/hooks/deleteDbKey.ts +233 -0
- package/app/i18n/client.ts +13 -0
- package/app/i18n/i18n.base.ts +14 -0
- package/app/i18n/i18n.config.ts +77 -0
- package/app/i18n/index.ts +15 -0
- package/app/i18n/mapLanguage.ts +11 -0
- package/app/i18n/translations/appBuilder.locale.ts +453 -0
- package/app/i18n/translations/error.locale.ts +246 -0
- package/app/i18n/translations/interface.locale.ts +2174 -0
- package/app/i18n/translations/pricing.locale.ts +397 -0
- package/app/i18n/translations/privacy.locale.ts +168 -0
- package/app/i18n/translations/seo.locale.ts +129 -0
- package/app/i18n/translations/terms.locale.ts +124 -0
- package/app/i18n/types.ts +6 -0
- package/app/notifications/model.ts +77 -0
- package/app/notifications/notificationSlice.ts +141 -0
- package/app/reducer.ts +36 -0
- package/app/settings/dbActionThunks.ts +34 -0
- package/app/settings/defaultSpacePreference.ts +87 -0
- package/app/settings/settingSlice.tsx +1212 -0
- package/app/settings/settingsRecord.ts +8 -0
- package/app/stateViews/runtime.ts +90 -0
- package/app/store.ts +55 -0
- package/app/theme/colors.ts +280 -0
- package/app/theme/fontPreference.ts +77 -0
- package/app/theme/theme.config.ts +120 -0
- package/app/theme/themeModeBootstrap.ts +123 -0
- package/app/types/appSummary.ts +114 -0
- package/app/types.ts +358 -0
- package/app/utils/appKeys.ts +55 -0
- package/app/utils/async.ts +28 -0
- package/app/utils/desktopAgentRuntimeTurnClient.ts +73 -0
- package/app/utils/env.ts +17 -0
- package/app/utils/fileUtils.ts +229 -0
- package/app/utils/imageUtils.ts +274 -0
- package/app/utils/myContentItems.ts +289 -0
- package/app/utils/retryAfter.ts +36 -0
- package/app/utils/retryFetch.ts +61 -0
- package/app/utils/toast.ts +3 -0
- package/auth/action/signUpAction.ts +227 -0
- package/auth/adminPermissions.ts +18 -0
- package/auth/authSlice.ts +531 -0
- package/auth/client/loginRequest.ts +14 -0
- package/auth/resetAuthScopedClientState.ts +27 -0
- package/auth/routes.ts +178 -0
- package/auth/token.ts +63 -0
- package/auth/types.ts +40 -0
- package/chat/chat.locale.ts +813 -0
- package/chat/dialog/actions/addCybotAction.ts +52 -0
- package/chat/dialog/actions/addReferenceKeysAction.ts +62 -0
- package/chat/dialog/actions/builtinDialogLlm.ts +35 -0
- package/chat/dialog/actions/cleanupCliSession.ts +40 -0
- package/chat/dialog/actions/createDialogAction.ts +379 -0
- package/chat/dialog/actions/createScheduledTaskAction.ts +78 -0
- package/chat/dialog/actions/handleSendMessageAction.ts +197 -0
- package/chat/dialog/actions/handleSendMessageResolver.ts +27 -0
- package/chat/dialog/actions/removeCybotAction.ts +6 -0
- package/chat/dialog/actions/removeDialogAgentAction.ts +44 -0
- package/chat/dialog/actions/replacePrimaryCybotAction.ts +6 -0
- package/chat/dialog/actions/setPrimaryDialogAgentAction.ts +52 -0
- package/chat/dialog/actions/updateDialogSummaryAction.ts +430 -0
- package/chat/dialog/actions/updateDialogTitleAction.ts +151 -0
- package/chat/dialog/actions/updateDialogTitlePolicy.ts +30 -0
- package/chat/dialog/actions/updateTokensAction.ts +233 -0
- package/chat/dialog/dialogAgents.ts +72 -0
- package/chat/dialog/dialogSlice.ts +872 -0
- package/chat/dialog/dialogTitle.ts +81 -0
- package/chat/dialog/dialogTokenStats.ts +12 -0
- package/chat/dialog/dialogUrl.ts +6 -0
- package/chat/dialog/goal.ts +108 -0
- package/chat/dialog/objectAssistantRegistry.ts +286 -0
- package/chat/dialog/schedule.ts +17 -0
- package/chat/messages/fetchAndCacheMessages.ts +119 -0
- package/chat/messages/fetchConvMsgs.ts +51 -0
- package/chat/messages/fileUrl.ts +13 -0
- package/chat/messages/messageAgent.ts +8 -0
- package/chat/messages/messageContent.ts +199 -0
- package/chat/messages/messageContract.ts +88 -0
- package/chat/messages/messageSlice.ts +1367 -0
- package/chat/messages/toolThunks.ts +625 -0
- package/cli/agentAliases.ts +2 -1
- package/cli/agentRunCommand.ts +10 -32
- package/cli/agentRuntimeLocal.ts +1 -0
- package/cli/client/agentRun.ts +67 -95
- package/cli/client/localRuntimeAdapter.ts +323 -54
- package/cli/commandRegistry.ts +2 -2
- package/cli/machineWsRunDispatch.ts +51 -6
- package/cli/offlineMarxistsAgentCommand.ts +6 -4
- package/client/agentConfigResolver.test.ts +2 -2
- package/client/agentRun.test.ts +175 -57
- package/client/agentRun.ts +67 -95
- package/client/localRuntimeAdapter.test.ts +682 -37
- package/client/localRuntimeAdapter.ts +323 -54
- package/client/localRuntimeDryRun.test.ts +23 -9
- package/client/localToolPolicy.test.ts +4 -4
- package/commandRegistry.ts +2 -2
- package/core/builtinAgents.ts +209 -0
- package/core/config.ts +15 -0
- package/core/crypto.ts +51 -0
- package/core/generateKeyPairFromSeedV1.ts +15 -0
- package/core/generateMainKey.ts +22 -0
- package/core/init.ts +41 -0
- package/core/localOrigins.ts +8 -0
- package/core/password.ts +13 -0
- package/core/prefix.ts +23 -0
- package/create/editor/transforms/fromMarkdown/index.ts +260 -0
- package/create/editor/transforms/fromMarkdown/inline.ts +285 -0
- package/create/editor/transforms/fromMarkdown/table.ts +130 -0
- package/create/editor/transforms/markdownToSlate.ts +24 -0
- package/create/editor/transforms/slateToRenderMarkdown.ts +218 -0
- package/create/editor/transforms/slateToSimplifiedMarkdown.ts +224 -0
- package/create/editor/transforms/slateToText.ts +33 -0
- package/create/editor/utils/slateUtils.ts +233 -0
- package/create/space/addSpaceAction.ts +193 -0
- package/create/space/category/categoryActions.ts +427 -0
- package/create/space/changeSpaceAction.ts +36 -0
- package/create/space/constants.ts +8 -0
- package/create/space/content/addContentAction.ts +116 -0
- package/create/space/content/contentThunks.ts +90 -0
- package/create/space/content/deleteContentFromSpaceAction.ts +187 -0
- package/create/space/content/deleteMultipleContentAction.ts +112 -0
- package/create/space/content/moveContentAction.ts +285 -0
- package/create/space/content/updateContentCategoryAction.ts +154 -0
- package/create/space/content/updateContentTitleAction.ts +151 -0
- package/create/space/content/uploadAndAddFileToSpaceAction.ts +98 -0
- package/create/space/contentKeyUtils.ts +117 -0
- package/create/space/deleteSpaceAction.ts +276 -0
- package/create/space/fetchSpaceAction.ts +70 -0
- package/create/space/fetchSpaceSidebarStateAction.ts +26 -0
- package/create/space/loadDefaultSpaceAction.ts +57 -0
- package/create/space/member/addMemberAction.ts +79 -0
- package/create/space/member/fetchUserSpaceMembershipsAction.ts +386 -0
- package/create/space/member/memberThunks.ts +47 -0
- package/create/space/member/removeMemberAction.ts +67 -0
- package/create/space/resolvePreferredSpaceId.ts +113 -0
- package/create/space/sidebarVisibleTypes.ts +241 -0
- package/create/space/space.locale.ts +1087 -0
- package/create/space/spaceAccess.ts +182 -0
- package/create/space/spaceCollapsedState.ts +54 -0
- package/create/space/spaceKeys.ts +65 -0
- package/create/space/spaceSlice.ts +328 -0
- package/create/space/spaceThunks.ts +410 -0
- package/create/space/types.ts +27 -0
- package/create/space/updateSpaceAction.ts +107 -0
- package/create/space/utils/permissions.ts +47 -0
- package/create/types.ts +21 -0
- package/database/actions/agentReadResolution.ts +33 -0
- package/database/actions/common.ts +243 -0
- package/database/actions/deleteFile.ts +40 -0
- package/database/actions/fileContent.ts +125 -0
- package/database/actions/patch.ts +155 -0
- package/database/actions/read.ts +358 -0
- package/database/actions/readAndWait.ts +260 -0
- package/database/actions/readRequestManager.ts +120 -0
- package/database/actions/readResolution.ts +125 -0
- package/database/actions/remove.ts +94 -0
- package/database/actions/replication.ts +477 -0
- package/database/actions/upload.ts +186 -0
- package/database/actions/upsert.ts +56 -0
- package/database/actions/write.ts +146 -0
- package/database/authority/ownerKey.ts +80 -0
- package/database/authority/recordAuthority.ts +67 -0
- package/database/authority/userAuthorityRegistry.ts +54 -0
- package/database/client/fetchUserData.ts +61 -0
- package/database/dbActionThunks.ts +1 -0
- package/database/dbSlice.ts +149 -0
- package/database/fileRing.ts +51 -0
- package/database/fileStorage.ts +232 -0
- package/database/fileUrl.ts +34 -0
- package/database/keys.ts +767 -0
- package/database/queryPrefixes.ts +14 -0
- package/database/requests.ts +443 -0
- package/database/runtimeServerContext.ts +54 -0
- package/database/server/levelAuthorityStore.ts +20 -1
- package/database/tenantPlacement.ts +57 -0
- package/database/userPreferenceRegister.ts +131 -0
- package/database/utils/ulid.ts +1 -0
- package/integrations/anthropic/anthropicModels.ts +47 -0
- package/integrations/deepseek/models.ts +37 -0
- package/integrations/google/models.ts +341 -0
- package/integrations/openai/chatCompletionStreamMode.ts +10 -0
- package/integrations/openai/filterAndCleanMessages.ts +284 -0
- package/integrations/openai/flexTier.ts +102 -0
- package/integrations/openai/generateOpenAIRequestBody.ts +274 -0
- package/integrations/openai/generateResponseRequestBody.ts +77 -0
- package/integrations/openai/models.ts +271 -0
- package/integrations/openai/providerBodyCompatibility.ts +23 -0
- package/integrations/openai/responsesHelpers.ts +297 -0
- package/integrations/x-reader/types.ts +109 -0
- package/integrations/xai/models.ts +13 -0
- package/integrations/xhs-reader/analyze/profileAnalyzer.ts +205 -0
- package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +624 -0
- package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +227 -0
- package/integrations/xhs-reader/client/xhsWebApiClient.ts +229 -0
- package/integrations/xhs-reader/normalize.ts +390 -0
- package/integrations/xhs-reader/orchestrator.ts +178 -0
- package/integrations/xhs-reader/redaction.ts +68 -0
- package/integrations/xhs-reader/types.ts +244 -0
- package/integrations/xhs-reader/url.ts +57 -0
- package/machineWsRunDispatch.ts +51 -6
- package/offlineMarxistsAgentCommand.ts +6 -4
- package/package.json +430 -3
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +468 -0
- package/render/page/types.ts +17 -0
- package/render/table/createTableAction.ts +270 -0
- package/render/table/deleteTableAction.ts +193 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1106 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +252 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/server/handlers/agentRun/types.ts +104 -0
- package/share/action.ts +225 -0
- package/share/helpers.ts +302 -0
- package/share/keys.ts +243 -0
- package/share/publicSharePolicy.ts +27 -0
- package/share/shareSlice.ts +53 -0
- package/share/types.ts +100 -0
|
@@ -20,9 +20,52 @@ type EnvLike = Record<string, string | undefined>;
|
|
|
20
20
|
export type LocalCliExecutor = (
|
|
21
21
|
provider: string,
|
|
22
22
|
prompt: string,
|
|
23
|
-
options: {
|
|
23
|
+
options: {
|
|
24
|
+
model?: string;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
cwd?: string;
|
|
27
|
+
yolo?: boolean;
|
|
28
|
+
env?: EnvLike;
|
|
29
|
+
imageInputs?: Array<{ source: string; materializedPath?: string }>;
|
|
30
|
+
}
|
|
24
31
|
) => Promise<{ text: string; raw?: string; elapsed?: number }>;
|
|
25
32
|
|
|
33
|
+
/**
|
|
34
|
+
* 从 connector payload 的 userInput 中提取 multimodal 内容。
|
|
35
|
+
* 如果 userInput 是字符串,直接返回 { text, imageUrls: [] }。
|
|
36
|
+
* 如果 userInput 是 multimodal content array(`[{ type: "text" }, { type: "image_url" }]`),
|
|
37
|
+
* 提取 text 和 image_url parts。
|
|
38
|
+
*/
|
|
39
|
+
function extractMultimodalUserInput(userInput: unknown): {
|
|
40
|
+
text: string;
|
|
41
|
+
imageUrls: string[];
|
|
42
|
+
} {
|
|
43
|
+
if (typeof userInput === "string") {
|
|
44
|
+
return { text: userInput, imageUrls: [] };
|
|
45
|
+
}
|
|
46
|
+
if (!Array.isArray(userInput)) {
|
|
47
|
+
return { text: String(userInput ?? ""), imageUrls: [] };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const textParts: string[] = [];
|
|
51
|
+
const imageUrls: string[] = [];
|
|
52
|
+
|
|
53
|
+
for (const part of userInput) {
|
|
54
|
+
if (!part || typeof part !== "object") continue;
|
|
55
|
+
if ((part as any).type === "text" && typeof (part as any).text === "string") {
|
|
56
|
+
textParts.push((part as any).text);
|
|
57
|
+
} else if (
|
|
58
|
+
(part as any).type === "image_url" &&
|
|
59
|
+
typeof (part as any).image_url?.url === "string" &&
|
|
60
|
+
(part as any).image_url.url.trim()
|
|
61
|
+
) {
|
|
62
|
+
imageUrls.push((part as any).image_url.url.trim());
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { text: textParts.join("\n"), imageUrls };
|
|
67
|
+
}
|
|
68
|
+
|
|
26
69
|
type ConnectorRuntimePolicy = {
|
|
27
70
|
runtimeTools?: string[];
|
|
28
71
|
agentTools?: string[];
|
|
@@ -103,7 +146,6 @@ function summarizeRuntimePolicyForLogs(policy?: ConnectorRuntimePolicy) {
|
|
|
103
146
|
workspaceMode: policy?.workspace?.mode ?? null,
|
|
104
147
|
workspaceCwd: policy?.workspace?.cwd ?? null,
|
|
105
148
|
shellEnabled: policy?.shell?.enabled ?? null,
|
|
106
|
-
shellMode: policy?.shell?.mode ?? null,
|
|
107
149
|
};
|
|
108
150
|
}
|
|
109
151
|
|
|
@@ -188,13 +230,13 @@ function runtimeWorkspacePermissionPolicy(
|
|
|
188
230
|
runtimeEnv: EnvLike,
|
|
189
231
|
cwd: string
|
|
190
232
|
): PermissionPolicy | null {
|
|
233
|
+
void runtimeEnv;
|
|
191
234
|
if (!requestsLocalWorkspaceRuntime(runtimePolicy)) return null;
|
|
192
235
|
return {
|
|
193
236
|
mode: "full_access",
|
|
194
237
|
allowFilesystemRead: true,
|
|
195
238
|
allowFilesystemWrite: true,
|
|
196
239
|
allowShell:
|
|
197
|
-
runtimeEnv.NOLO_LOCAL_SHELL_MODE === "worktree" &&
|
|
198
240
|
Array.isArray(runtimePolicy?.runtimeTools) &&
|
|
199
241
|
runtimePolicy.runtimeTools.includes("execShell"),
|
|
200
242
|
writableRoots: [cwd],
|
|
@@ -332,8 +374,6 @@ async function defaultRunConnectorLocalRuntimeAgent(args: {
|
|
|
332
374
|
requestId: args.parsed.requestId,
|
|
333
375
|
agentKey,
|
|
334
376
|
cwd: args.cwd,
|
|
335
|
-
runtimeEnvShellModeBeforePolicy: args.runtimeEnv.NOLO_LOCAL_SHELL_MODE ?? null,
|
|
336
|
-
runtimeEnvShellModeAfterPolicy: env.NOLO_LOCAL_SHELL_MODE ?? null,
|
|
337
377
|
...summarizeRuntimePolicyForLogs(policy),
|
|
338
378
|
});
|
|
339
379
|
const adapter = createCliLocalRuntimeAdapter({
|
|
@@ -454,7 +494,9 @@ export async function handleConnectorRunMessage(
|
|
|
454
494
|
try {
|
|
455
495
|
const machinePermissionPolicy = resolveMachineRunPermissionPolicy(agentConfig);
|
|
456
496
|
const runtimePolicy = runtimePolicyFromConnectorPayload(parsed);
|
|
457
|
-
const
|
|
497
|
+
const extractedInput = extractMultimodalUserInput(parsed.payload?.userInput);
|
|
498
|
+
const userInput = extractedInput.text;
|
|
499
|
+
const connectorImageUrls = extractedInput.imageUrls;
|
|
458
500
|
const timeout = normalizeConnectorRunTimeoutMs(parsed.payload?.timeoutMs);
|
|
459
501
|
let cwd = resolveConnectorRunCwd({ env: runtimeEnv, policy: machinePermissionPolicy });
|
|
460
502
|
let runContent = "";
|
|
@@ -553,6 +595,9 @@ export async function handleConnectorRunMessage(
|
|
|
553
595
|
effectiveRuntimeEnv.AUTH_TOKEN ||
|
|
554
596
|
effectiveRuntimeEnv.AUTH,
|
|
555
597
|
},
|
|
598
|
+
...(connectorImageUrls.length > 0
|
|
599
|
+
? { imageInputs: connectorImageUrls.map((url) => ({ source: url })) }
|
|
600
|
+
: {}),
|
|
556
601
|
}).finally(() => clearInterval(heartbeat));
|
|
557
602
|
logConnectorRun("agent.run.cli.result", {
|
|
558
603
|
requestId: parsed.requestId,
|
|
@@ -40,15 +40,17 @@ function readFlagValue(args: string[], flag: string) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function parseUserIdFromToken(token: string) {
|
|
43
|
-
const payload = token.split(".")[
|
|
44
|
-
if (!payload) return
|
|
43
|
+
const payload = token.split(".")[1];
|
|
44
|
+
if (!payload) return undefined;
|
|
45
45
|
try {
|
|
46
46
|
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
47
47
|
const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
|
|
48
48
|
const parsed = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
|
|
49
|
-
return typeof parsed?.userId === "string"
|
|
49
|
+
return typeof parsed?.userId === "string" && parsed.userId.trim()
|
|
50
|
+
? parsed.userId.trim()
|
|
51
|
+
: undefined;
|
|
50
52
|
} catch {
|
|
51
|
-
return
|
|
53
|
+
return undefined;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -15,7 +15,7 @@ describe("agent config resolver", () => {
|
|
|
15
15
|
cliProvider: "codex",
|
|
16
16
|
customProviderUrl: "https://provider.example/v1",
|
|
17
17
|
toolNames: ["legacyTool", "readFile"],
|
|
18
|
-
tools: ["readFile", "
|
|
18
|
+
tools: ["readFile", "editFile"],
|
|
19
19
|
runtimeBinding: { machineId: "machine-1" },
|
|
20
20
|
delegation: { target: "local" },
|
|
21
21
|
temperature: 0.2,
|
|
@@ -33,7 +33,7 @@ describe("agent config resolver", () => {
|
|
|
33
33
|
apiSource: "platform",
|
|
34
34
|
cliProvider: "codex",
|
|
35
35
|
customProviderUrl: "https://provider.example/v1",
|
|
36
|
-
toolNames: ["legacyTool", "readFile", "
|
|
36
|
+
toolNames: ["legacyTool", "readFile", "editFile"],
|
|
37
37
|
runtimeBinding: { machineId: "machine-1" },
|
|
38
38
|
delegation: { target: "local" },
|
|
39
39
|
temperature: 0.2,
|
package/client/agentRun.test.ts
CHANGED
|
@@ -35,11 +35,11 @@ describe("cli agent run client", () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
test("identifies server platform tools that local runtime cannot provide", () => {
|
|
38
|
-
expect(findServerPlatformTools(["
|
|
38
|
+
expect(findServerPlatformTools(["readFile", "queryTableRows", "updateTableRow"])).toEqual([
|
|
39
39
|
"queryTableRows",
|
|
40
40
|
"updateTableRow",
|
|
41
41
|
]);
|
|
42
|
-
expect(findServerPlatformTools(["
|
|
42
|
+
expect(findServerPlatformTools(["readFile", "execShell"])).toEqual([]);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
test("calls the Nolo HTTP API directly when AUTH_TOKEN is present", async () => {
|
|
@@ -239,7 +239,6 @@ describe("cli agent run client", () => {
|
|
|
239
239
|
parentDialogId: "dialog-2",
|
|
240
240
|
background: true,
|
|
241
241
|
noStream: true,
|
|
242
|
-
maxToolRounds: 12,
|
|
243
242
|
timeoutMs: 600000,
|
|
244
243
|
scriptDir: "C:/missing/scripts",
|
|
245
244
|
env: { AUTH_TOKEN: "token-123" },
|
|
@@ -259,7 +258,6 @@ describe("cli agent run client", () => {
|
|
|
259
258
|
inheritedFromDialogKey: "dialog-user-1-dialog-2",
|
|
260
259
|
parentDialogId: "dialog-2",
|
|
261
260
|
background: true,
|
|
262
|
-
maxRounds: 12,
|
|
263
261
|
timeoutMs: 600000,
|
|
264
262
|
stream: false,
|
|
265
263
|
});
|
|
@@ -345,72 +343,75 @@ describe("cli agent run client", () => {
|
|
|
345
343
|
expect(output.text()).toContain("frontend > local:polish notifications");
|
|
346
344
|
});
|
|
347
345
|
|
|
348
|
-
test("
|
|
346
|
+
test("continues forced local tool loops until the provider returns final text", async () => {
|
|
349
347
|
const output = new CaptureOutput();
|
|
350
348
|
let completeCalls = 0;
|
|
349
|
+
let toolCalls = 0;
|
|
350
|
+
|
|
351
351
|
const result = await runAgentTurn({
|
|
352
352
|
agentName: "frontend",
|
|
353
353
|
agentKey: "frontend-local",
|
|
354
354
|
serverUrl: "https://nolo.chat",
|
|
355
|
-
message: "
|
|
355
|
+
message: "make screenshots",
|
|
356
356
|
scriptDir: "C:/missing/scripts",
|
|
357
|
-
env: { AUTH_TOKEN: "token-123"
|
|
357
|
+
env: { AUTH_TOKEN: "token-123" },
|
|
358
358
|
output,
|
|
359
359
|
runtimeMode: "local",
|
|
360
|
-
maxToolRounds: 0,
|
|
361
360
|
localRuntimeAdapter: {
|
|
362
361
|
host: "cli",
|
|
363
|
-
capabilities: ["local-provider", "local-persistence"],
|
|
362
|
+
capabilities: ["local-provider", "local-persistence", "local-tools"],
|
|
364
363
|
loadAgentConfig: async (agentRef) => ({
|
|
365
364
|
key: agentRef,
|
|
366
365
|
name: "Frontend",
|
|
367
366
|
prompt: "Fix UI",
|
|
368
367
|
model: "fake-local",
|
|
368
|
+
toolNames: ["readFile"],
|
|
369
369
|
}),
|
|
370
370
|
loadDialogHistory: async () => [],
|
|
371
|
-
saveTurn: async () => ({ dialogId: "dialog-local" }),
|
|
371
|
+
saveTurn: async () => ({ dialogId: "dialog-local-retry" }),
|
|
372
372
|
resolveProvider: async () => ({
|
|
373
373
|
model: "fake-local",
|
|
374
374
|
complete: async () => {
|
|
375
375
|
completeCalls += 1;
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
376
|
+
if (completeCalls <= 3) {
|
|
377
|
+
return {
|
|
378
|
+
content: "",
|
|
379
|
+
model: "fake-local",
|
|
380
|
+
tool_calls: [{
|
|
381
|
+
id: `call-${completeCalls}`,
|
|
382
|
+
type: "function",
|
|
383
|
+
function: { name: "readFile", arguments: "{}" },
|
|
384
|
+
}],
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return { content: "done after retry", model: "fake-local" };
|
|
385
388
|
},
|
|
386
389
|
}),
|
|
387
|
-
executeTool: async () =>
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
390
|
+
executeTool: async () => {
|
|
391
|
+
toolCalls += 1;
|
|
392
|
+
return { content: "ok" };
|
|
393
|
+
},
|
|
391
394
|
},
|
|
392
395
|
});
|
|
393
396
|
|
|
394
|
-
expect(result).
|
|
395
|
-
expect(
|
|
396
|
-
expect(output.text()).toContain("
|
|
397
|
+
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-local-retry" });
|
|
398
|
+
expect(toolCalls).toBe(3);
|
|
399
|
+
expect(output.text()).toContain("frontend > done after retry");
|
|
397
400
|
});
|
|
398
401
|
|
|
399
|
-
test("
|
|
402
|
+
test("prints compact local tool trace by default", async () => {
|
|
400
403
|
const output = new CaptureOutput();
|
|
401
404
|
let completeCalls = 0;
|
|
402
|
-
let toolCalls = 0;
|
|
403
405
|
|
|
404
406
|
const result = await runAgentTurn({
|
|
405
407
|
agentName: "frontend",
|
|
406
408
|
agentKey: "frontend-local",
|
|
407
409
|
serverUrl: "https://nolo.chat",
|
|
408
|
-
message: "
|
|
410
|
+
message: "inspect repo",
|
|
409
411
|
scriptDir: "C:/missing/scripts",
|
|
410
412
|
env: { AUTH_TOKEN: "token-123" },
|
|
411
413
|
output,
|
|
412
414
|
runtimeMode: "local",
|
|
413
|
-
maxToolRounds: 1,
|
|
414
415
|
localRuntimeAdapter: {
|
|
415
416
|
host: "cli",
|
|
416
417
|
capabilities: ["local-provider", "local-persistence", "local-tools"],
|
|
@@ -419,42 +420,39 @@ describe("cli agent run client", () => {
|
|
|
419
420
|
name: "Frontend",
|
|
420
421
|
prompt: "Fix UI",
|
|
421
422
|
model: "fake-local",
|
|
422
|
-
toolNames: ["
|
|
423
|
+
toolNames: ["readFile"],
|
|
423
424
|
}),
|
|
424
425
|
loadDialogHistory: async () => [],
|
|
425
|
-
saveTurn: async () => ({ dialogId: "dialog-local
|
|
426
|
+
saveTurn: async () => ({ dialogId: "dialog-local" }),
|
|
426
427
|
resolveProvider: async () => ({
|
|
427
428
|
model: "fake-local",
|
|
428
429
|
complete: async () => {
|
|
429
430
|
completeCalls += 1;
|
|
430
|
-
if (completeCalls
|
|
431
|
+
if (completeCalls === 1) {
|
|
431
432
|
return {
|
|
432
433
|
content: "",
|
|
433
434
|
model: "fake-local",
|
|
434
435
|
tool_calls: [{
|
|
435
|
-
id:
|
|
436
|
+
id: "call-read",
|
|
436
437
|
type: "function",
|
|
437
|
-
function: { name: "
|
|
438
|
+
function: { name: "readFile", arguments: JSON.stringify({ path: "README.md" }) },
|
|
438
439
|
}],
|
|
439
440
|
};
|
|
440
441
|
}
|
|
441
|
-
return { content: "done
|
|
442
|
+
return { content: "done", model: "fake-local" };
|
|
442
443
|
},
|
|
443
444
|
}),
|
|
444
|
-
executeTool: async () => {
|
|
445
|
-
toolCalls += 1;
|
|
446
|
-
return { content: "ok" };
|
|
447
|
-
},
|
|
445
|
+
executeTool: async () => ({ content: "clean" }),
|
|
448
446
|
},
|
|
449
447
|
});
|
|
450
448
|
|
|
451
|
-
expect(result).
|
|
452
|
-
expect(
|
|
453
|
-
expect(output.text()).toContain("
|
|
454
|
-
expect(output.text()).toContain("
|
|
449
|
+
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local" });
|
|
450
|
+
expect(output.text()).toContain("[nolo:tool] #1 -> readFile README.md");
|
|
451
|
+
expect(output.text()).toContain("[nolo:tool] #1 <- readFile");
|
|
452
|
+
expect(output.text()).toContain("1 line");
|
|
455
453
|
});
|
|
456
454
|
|
|
457
|
-
test("
|
|
455
|
+
test("does not print local tool trace when disabled by env", async () => {
|
|
458
456
|
const output = new CaptureOutput();
|
|
459
457
|
let completeCalls = 0;
|
|
460
458
|
|
|
@@ -464,10 +462,9 @@ describe("cli agent run client", () => {
|
|
|
464
462
|
serverUrl: "https://nolo.chat",
|
|
465
463
|
message: "inspect repo",
|
|
466
464
|
scriptDir: "C:/missing/scripts",
|
|
467
|
-
env: { AUTH_TOKEN: "token-123" },
|
|
465
|
+
env: { AUTH_TOKEN: "token-123", NOLO_TRACE_TOOLS: "0" },
|
|
468
466
|
output,
|
|
469
467
|
runtimeMode: "local",
|
|
470
|
-
traceTools: true,
|
|
471
468
|
localRuntimeAdapter: {
|
|
472
469
|
host: "cli",
|
|
473
470
|
capabilities: ["local-provider", "local-persistence", "local-tools"],
|
|
@@ -476,10 +473,10 @@ describe("cli agent run client", () => {
|
|
|
476
473
|
name: "Frontend",
|
|
477
474
|
prompt: "Fix UI",
|
|
478
475
|
model: "fake-local",
|
|
479
|
-
toolNames: ["
|
|
476
|
+
toolNames: ["readFile"],
|
|
480
477
|
}),
|
|
481
478
|
loadDialogHistory: async () => [],
|
|
482
|
-
saveTurn: async () => ({ dialogId: "dialog-local" }),
|
|
479
|
+
saveTurn: async () => ({ dialogId: "dialog-local-no-trace" }),
|
|
483
480
|
resolveProvider: async () => ({
|
|
484
481
|
model: "fake-local",
|
|
485
482
|
complete: async () => {
|
|
@@ -491,7 +488,7 @@ describe("cli agent run client", () => {
|
|
|
491
488
|
tool_calls: [{
|
|
492
489
|
id: "call-read",
|
|
493
490
|
type: "function",
|
|
494
|
-
function: { name: "
|
|
491
|
+
function: { name: "readFile", arguments: JSON.stringify({ path: "README.md" }) },
|
|
495
492
|
}],
|
|
496
493
|
};
|
|
497
494
|
}
|
|
@@ -502,9 +499,79 @@ describe("cli agent run client", () => {
|
|
|
502
499
|
},
|
|
503
500
|
});
|
|
504
501
|
|
|
505
|
-
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local" });
|
|
506
|
-
expect(output.text()).toContain("[nolo:tool]
|
|
507
|
-
|
|
502
|
+
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local-no-trace" });
|
|
503
|
+
expect(output.text()).not.toContain("[nolo:tool]");
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
test("prints local tool events as jsonl when requested", async () => {
|
|
507
|
+
const output = new CaptureOutput();
|
|
508
|
+
let completeCalls = 0;
|
|
509
|
+
|
|
510
|
+
const result = await runAgentTurn({
|
|
511
|
+
agentName: "frontend",
|
|
512
|
+
agentKey: "frontend-local",
|
|
513
|
+
serverUrl: "https://nolo.chat",
|
|
514
|
+
message: "inspect repo",
|
|
515
|
+
scriptDir: "C:/missing/scripts",
|
|
516
|
+
env: { AUTH_TOKEN: "token-123" },
|
|
517
|
+
output,
|
|
518
|
+
runtimeMode: "local",
|
|
519
|
+
eventsMode: "jsonl",
|
|
520
|
+
localRuntimeAdapter: {
|
|
521
|
+
host: "cli",
|
|
522
|
+
capabilities: ["local-provider", "local-persistence", "local-tools"],
|
|
523
|
+
loadAgentConfig: async (agentRef) => ({
|
|
524
|
+
key: agentRef,
|
|
525
|
+
name: "Frontend",
|
|
526
|
+
prompt: "Fix UI",
|
|
527
|
+
model: "fake-local",
|
|
528
|
+
toolNames: ["execShell"],
|
|
529
|
+
}),
|
|
530
|
+
loadDialogHistory: async () => [],
|
|
531
|
+
saveTurn: async () => ({ dialogId: "dialog-local-jsonl" }),
|
|
532
|
+
resolveProvider: async () => ({
|
|
533
|
+
model: "fake-local",
|
|
534
|
+
complete: async () => {
|
|
535
|
+
completeCalls += 1;
|
|
536
|
+
if (completeCalls === 1) {
|
|
537
|
+
return {
|
|
538
|
+
content: "",
|
|
539
|
+
model: "fake-local",
|
|
540
|
+
tool_calls: [{
|
|
541
|
+
id: "call-shell",
|
|
542
|
+
type: "function",
|
|
543
|
+
function: { name: "execShell", arguments: JSON.stringify({ command: "git status --short" }) },
|
|
544
|
+
}],
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
return { content: "done", model: "fake-local" };
|
|
548
|
+
},
|
|
549
|
+
}),
|
|
550
|
+
executeTool: async () => ({ content: "stdout:\nclean\n\nexitCode: 0", metadata: { exitCode: 0 } }),
|
|
551
|
+
},
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local-jsonl" });
|
|
555
|
+
const events = output.text()
|
|
556
|
+
.split(/\r?\n/)
|
|
557
|
+
.filter((line) => line.startsWith("{"))
|
|
558
|
+
.map((line) => JSON.parse(line))
|
|
559
|
+
.filter((event) => typeof event.type === "string" && event.type.startsWith("tool-"));
|
|
560
|
+
expect(events).toHaveLength(2);
|
|
561
|
+
expect(events[0]).toMatchObject({
|
|
562
|
+
schemaVersion: 1,
|
|
563
|
+
type: "tool-call",
|
|
564
|
+
round: 1,
|
|
565
|
+
tool: "execShell",
|
|
566
|
+
argsPreview: "git status --short",
|
|
567
|
+
});
|
|
568
|
+
expect(events[1]).toMatchObject({
|
|
569
|
+
schemaVersion: 1,
|
|
570
|
+
type: "tool-result",
|
|
571
|
+
round: 1,
|
|
572
|
+
tool: "execShell",
|
|
573
|
+
summary: expect.stringContaining("exit=0"),
|
|
574
|
+
});
|
|
508
575
|
});
|
|
509
576
|
|
|
510
577
|
test("passes local tool evidence to task-run writeback", async () => {
|
|
@@ -536,7 +603,7 @@ describe("cli agent run client", () => {
|
|
|
536
603
|
name: "Frontend",
|
|
537
604
|
prompt: "Fix UI",
|
|
538
605
|
model: "fake-local",
|
|
539
|
-
toolNames: ["
|
|
606
|
+
toolNames: ["readFile"],
|
|
540
607
|
}),
|
|
541
608
|
loadDialogHistory: async () => [],
|
|
542
609
|
saveTurn: async () => ({ dialogId: "dialog-local" }),
|
|
@@ -551,7 +618,7 @@ describe("cli agent run client", () => {
|
|
|
551
618
|
tool_calls: [{
|
|
552
619
|
id: "call-read",
|
|
553
620
|
type: "function",
|
|
554
|
-
function: { name: "
|
|
621
|
+
function: { name: "readFile", arguments: JSON.stringify({ path: "README.md" }) },
|
|
555
622
|
}],
|
|
556
623
|
};
|
|
557
624
|
}
|
|
@@ -565,7 +632,7 @@ describe("cli agent run client", () => {
|
|
|
565
632
|
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local" });
|
|
566
633
|
expect(writebacks).toHaveLength(1);
|
|
567
634
|
expect(writebacks[0].toolEvidence).toEqual({
|
|
568
|
-
toolsUsed: ["
|
|
635
|
+
toolsUsed: ["readFile"],
|
|
569
636
|
summary: {
|
|
570
637
|
callCount: 1,
|
|
571
638
|
resultCount: 1,
|
|
@@ -820,6 +887,58 @@ describe("cli agent run client", () => {
|
|
|
820
887
|
expect(output.text()).toContain("pm > server ok");
|
|
821
888
|
});
|
|
822
889
|
|
|
890
|
+
test("auto mode keeps local runtime for CLI provider agents even when they declare platform tools", async () => {
|
|
891
|
+
const output = new CaptureOutput();
|
|
892
|
+
const httpCalls: string[] = [];
|
|
893
|
+
let providerCalled = false;
|
|
894
|
+
|
|
895
|
+
const result = await runAgentTurn({
|
|
896
|
+
agentName: "frontend-implementer",
|
|
897
|
+
agentKey: "frontend-implementer",
|
|
898
|
+
serverUrl: "https://nolo.chat",
|
|
899
|
+
message: "polish notifications",
|
|
900
|
+
scriptDir: "C:/missing/scripts",
|
|
901
|
+
env: { AUTH_TOKEN: "token-123" },
|
|
902
|
+
output,
|
|
903
|
+
runtimeMode: "auto",
|
|
904
|
+
localRuntimeAdapter: {
|
|
905
|
+
host: "cli",
|
|
906
|
+
capabilities: ["leveldb-agent-config", "local-provider", "local-tools"],
|
|
907
|
+
loadAgentConfig: async (agentRef) => ({
|
|
908
|
+
key: agentRef,
|
|
909
|
+
name: "AGY",
|
|
910
|
+
prompt: "Implement frontend tasks.",
|
|
911
|
+
provider: "agy",
|
|
912
|
+
cliProvider: "agy",
|
|
913
|
+
toolNames: ["streamParallelAgents", "taskRun"],
|
|
914
|
+
}),
|
|
915
|
+
loadDialogHistory: async () => [],
|
|
916
|
+
saveTurn: async () => ({ dialogId: "dialog-agy-auto-local" }),
|
|
917
|
+
resolveProvider: async () => ({
|
|
918
|
+
model: "agy",
|
|
919
|
+
complete: async () => {
|
|
920
|
+
providerCalled = true;
|
|
921
|
+
return { content: "agy local ok", model: "agy" };
|
|
922
|
+
},
|
|
923
|
+
}),
|
|
924
|
+
executeTool: async () => {
|
|
925
|
+
throw new Error("no tools expected");
|
|
926
|
+
},
|
|
927
|
+
},
|
|
928
|
+
fetchImpl: async (url) => {
|
|
929
|
+
httpCalls.push(String(url));
|
|
930
|
+
return Response.json({ content: "server" });
|
|
931
|
+
},
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
expect(providerCalled).toBe(true);
|
|
935
|
+
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-agy-auto-local" });
|
|
936
|
+
expect(httpCalls).toEqual([]);
|
|
937
|
+
expect(output.text()).not.toContain("skipping local runtime");
|
|
938
|
+
expect(output.text()).toContain("frontend-implementer -> working locally");
|
|
939
|
+
expect(output.text()).toContain("frontend-implementer > agy local ok");
|
|
940
|
+
});
|
|
941
|
+
|
|
823
942
|
test("auto mode does not skip monthly Mimo when a local shell cwd is already bound", async () => {
|
|
824
943
|
const output = new CaptureOutput();
|
|
825
944
|
const httpCalls: string[] = [];
|
|
@@ -833,7 +952,6 @@ describe("cli agent run client", () => {
|
|
|
833
952
|
scriptDir: "C:/missing/scripts",
|
|
834
953
|
env: {
|
|
835
954
|
AUTH_TOKEN: "token-123",
|
|
836
|
-
NOLO_LOCAL_SHELL_MODE: "worktree",
|
|
837
955
|
},
|
|
838
956
|
output,
|
|
839
957
|
runtimeMode: "auto",
|