nolo-cli 0.1.40 → 0.1.42
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 +27 -12
- package/agent-runtime/agentThread.ts +222 -0
- package/agent-runtime/agentThreadAdmission.ts +74 -0
- package/agent-runtime/dialogWritePlan.ts +42 -0
- package/agent-runtime/hostAdapter.ts +1 -0
- package/agent-runtime/hybridRecordStore.ts +5 -3
- package/agent-runtime/index.ts +43 -0
- package/agent-runtime/localLoop.ts +31 -2
- package/agent-runtime/localToolPolicy.ts +1 -0
- package/agent-runtime/localWorkspaceTools.ts +1258 -78
- package/agent-runtime/noloWorkspaceTools.ts +20 -1
- package/agent-runtime/runtimeToolPolicy.ts +1 -5
- package/agent-runtime/runtimeToolSurface.ts +1 -0
- package/agentAliases.ts +29 -9
- package/agentInternalCommandEntries.ts +11 -3
- package/agentMachineCommands.ts +1 -0
- package/agentRecordCommands.ts +2 -2
- package/agentRecordHelpers.ts +59 -6
- package/agentRunCommand.ts +84 -19
- 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 +599 -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 +264 -46
- 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 +2135 -0
- package/ai/agent/streamAgentChatTurnUtils.ts +923 -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 +1165 -0
- package/ai/chat/accumulateToolCallChunks.ts +126 -0
- package/ai/chat/fetchUtils.ts +143 -0
- package/ai/chat/inlineImageUrlsForCustomProvider.ts +122 -0
- package/ai/chat/parseApiError.ts +67 -0
- package/ai/chat/parseMultilineSSE.ts +95 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +921 -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 +22 -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 +31 -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/policy.ts +49 -0
- package/ai/memory/queryShared.ts +167 -0
- package/ai/memory/recentRelationshipRecap.ts +251 -0
- package/ai/memory/remember.ts +111 -0
- package/ai/memory/scope.ts +74 -0
- package/ai/memory/store.ts +20 -0
- package/ai/memory/storeShared.ts +76 -0
- package/ai/memory/types.ts +52 -0
- package/ai/memory/understanding.ts +341 -0
- package/ai/memory/understandingGreeting.ts +264 -0
- package/ai/policy/personalizationDialog.ts +333 -0
- package/ai/policy/runtimePolicy.ts +526 -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 +214 -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 +54 -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 +2290 -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 +193 -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 +638 -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 +326 -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/toolPacks.ts +19 -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 +58 -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/deletedFavoriteProjection.ts +31 -0
- package/app/favorite/favoriteSlice.ts +690 -0
- package/app/favorite/type.ts +43 -0
- package/app/hooks/deleteDbKey.ts +254 -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 +2206 -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 +118 -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 +75 -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 +78 -0
- package/auth/authSlice.ts +531 -0
- package/auth/client/loginRequest.ts +14 -0
- package/auth/resetAuthScopedClientState.ts +27 -0
- package/auth/routes.ts +183 -0
- package/auth/token.ts +63 -0
- package/auth/types.ts +40 -0
- package/chat/chat.locale.ts +817 -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 +202 -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/dialogAttachmentCleanup.ts +135 -0
- package/chat/dialog/dialogSlice.ts +985 -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/activityCompletion.ts +97 -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/imagePayloadPersistence.ts +22 -0
- package/chat/messages/messageAgent.ts +8 -0
- package/chat/messages/messageContent.ts +203 -0
- package/chat/messages/messageContract.ts +88 -0
- package/chat/messages/messageSlice.ts +1386 -0
- package/chat/messages/toolThunks.ts +646 -0
- package/chat/messages/types.ts +8 -1
- package/chat/messages/web/toolDisplayName.ts +686 -0
- package/cli/agentAliases.ts +29 -9
- package/cli/agentInternalCommandEntries.ts +11 -3
- package/cli/agentMachineCommands.ts +1 -0
- package/cli/agentRecordCommands.ts +2 -2
- package/cli/agentRecordHelpers.ts +59 -6
- package/cli/agentRunCommand.ts +84 -19
- package/cli/client/agentRun.ts +92 -261
- package/cli/client/localRuntimeAdapter.ts +292 -50
- package/cli/commandRegistry.ts +7 -4
- package/cli/dialogAttachmentCleanup.ts +151 -0
- package/cli/dialogCommands.ts +163 -61
- package/cli/dialogInternalCommandEntries.ts +1 -1
- package/cli/docCreateCommands.ts +345 -0
- package/cli/docInternalCommandEntries.ts +11 -0
- package/cli/docPageHelpers.ts +80 -0
- package/cli/docSkillHelpers.ts +67 -0
- package/cli/docSpaceHelpers.ts +46 -0
- package/cli/internalCommandEntries.ts +4 -0
- package/cli/machineCommands.ts +18 -34
- package/cli/memoryCommands.ts +253 -0
- package/cli/memoryInternalCommandEntries.ts +9 -0
- package/cli/qoderUsageProbe.ts +252 -0
- package/cli/scriptCommandEntries.ts +0 -3
- package/cli/secretScan.ts +31 -0
- package/cli/tableCommands.ts +248 -13
- package/cli/workflowInternalCommandEntries.ts +2 -3
- package/client/agentRun.test.ts +119 -83
- package/client/agentRun.ts +92 -261
- package/client/localRuntimeAdapter.test.ts +894 -32
- package/client/localRuntimeAdapter.ts +292 -50
- package/commandRegistry.ts +7 -4
- package/connector-experimental/capabilities.ts +10 -9
- 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 +260 -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/tenantPlacement.ts +57 -0
- package/database/userPreferenceRegister.ts +131 -0
- package/database/utils/ulid.ts +1 -0
- package/dialogAttachmentCleanup.ts +151 -0
- package/dialogCommands.ts +163 -61
- package/dialogInternalCommandEntries.ts +1 -1
- package/docCreateCommands.ts +345 -0
- package/docInternalCommandEntries.ts +11 -0
- package/docPageHelpers.ts +80 -0
- package/docSkillHelpers.ts +67 -0
- package/docSpaceHelpers.ts +46 -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 +271 -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/redaction.ts +68 -0
- package/integrations/xhs-reader/types.ts +277 -0
- package/integrations/xhs-reader/url.ts +80 -0
- package/internalCommandEntries.ts +4 -0
- package/machineCommands.ts +18 -34
- package/memoryCommands.ts +253 -0
- package/memoryInternalCommandEntries.ts +9 -0
- package/package.json +454 -9
- package/qoderUsageProbe.ts +252 -0
- package/render/contentIcon/types.ts +167 -0
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +495 -0
- package/render/page/types.ts +19 -0
- package/render/table/createTableAction.ts +274 -0
- package/render/table/deleteTableAction.ts +193 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1167 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +262 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/scriptCommandEntries.ts +0 -3
- package/secretScan.ts +31 -0
- package/server/handlers/agentRun/types.ts +105 -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
- package/tableCommands.ts +248 -13
- package/workflowInternalCommandEntries.ts +2 -3
- package/ai/tools/agent/taskRunTool.ts +0 -112
- package/cli/client/taskRunPrompt.ts +0 -27
- package/cli/taskRunCommand.ts +0 -265
- package/client/taskRunPrompt.ts +0 -27
- package/taskRunCommand.ts +0 -265
package/cli/tableCommands.ts
CHANGED
|
@@ -55,6 +55,11 @@ function parseOutputMode(raw: string): OutputMode {
|
|
|
55
55
|
throw new Error(`--output must be one of full, raw, items, json, jsonl; got ${raw}`);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
function resolveQueryColumns(columns: string[] | undefined, includeActivity: boolean): string[] | undefined {
|
|
59
|
+
if (!includeActivity) return columns;
|
|
60
|
+
return Array.isArray(columns) ? includeTableActivityColumns(columns) : undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
function parseTableArg(raw: string): { tenantId?: string; tableId?: string } {
|
|
59
64
|
const trimmed = raw.trim();
|
|
60
65
|
if (!trimmed) return {};
|
|
@@ -66,6 +71,32 @@ function parseTableArg(raw: string): { tenantId?: string; tableId?: string } {
|
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
|
|
74
|
+
function normalizeSpaceInput(raw: string): string {
|
|
75
|
+
const value = raw.trim();
|
|
76
|
+
if (!value) return "";
|
|
77
|
+
if (value.startsWith("http://") || value.startsWith("https://")) {
|
|
78
|
+
const match = new URL(value).pathname.match(/^\/space\/([^/]+)/);
|
|
79
|
+
return match?.[1] ? decodeURIComponent(match[1]).replace(/^space-/, "") : "";
|
|
80
|
+
}
|
|
81
|
+
return value.replace(/^space-/, "");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getSpaceContentKeys(spaceRecord: any): Set<string> {
|
|
85
|
+
const keys = new Set<string>();
|
|
86
|
+
const contents = spaceRecord?.contents;
|
|
87
|
+
if (!contents || typeof contents !== "object") return keys;
|
|
88
|
+
for (const [entryKey, value] of Object.entries(contents)) {
|
|
89
|
+
keys.add(entryKey);
|
|
90
|
+
if (value && typeof value === "object") {
|
|
91
|
+
const contentKey = (value as any).contentKey;
|
|
92
|
+
if (typeof contentKey === "string" && contentKey.trim()) {
|
|
93
|
+
keys.add(contentKey.trim());
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return keys;
|
|
98
|
+
}
|
|
99
|
+
|
|
69
100
|
function resolveServerUrl(args: string[], env: EnvLike): string {
|
|
70
101
|
return (
|
|
71
102
|
readOption(args, "--server-url") ||
|
|
@@ -89,16 +120,46 @@ function resolveAuthToken(args: string[], env: EnvLike): string {
|
|
|
89
120
|
}
|
|
90
121
|
|
|
91
122
|
function parseJwtTenantId(token: string): string | undefined {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const parsed = JSON.parse(decoded);
|
|
98
|
-
return typeof parsed.userId === "string" ? parsed.userId : typeof parsed.sub === "string" ? parsed.sub : undefined;
|
|
99
|
-
} catch {
|
|
100
|
-
return undefined;
|
|
123
|
+
for (const parsed of parseJwtPayloadCandidates(token)) {
|
|
124
|
+
const userId = parsed.userId;
|
|
125
|
+
const sub = parsed.sub;
|
|
126
|
+
if (typeof userId === "string" && userId) return userId;
|
|
127
|
+
if (typeof sub === "string" && sub) return sub;
|
|
101
128
|
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function parseJwtUsername(token: string): string | undefined {
|
|
133
|
+
for (const parsed of parseJwtPayloadCandidates(token)) {
|
|
134
|
+
const username = parsed.username;
|
|
135
|
+
if (typeof username === "string" && username.trim()) return username.trim();
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function parseJwtPayloadCandidates(token: string): Array<Record<string, unknown>> {
|
|
141
|
+
const trimmed = token.trim();
|
|
142
|
+
if (!trimmed) return [];
|
|
143
|
+
const parts = trimmed.split(".").filter(Boolean);
|
|
144
|
+
const payloadCandidates = parts.length >= 3 ? [parts[1], parts[0]] : [parts[0]];
|
|
145
|
+
const parsed: Array<Record<string, unknown>> = [];
|
|
146
|
+
for (const payload of payloadCandidates) {
|
|
147
|
+
try {
|
|
148
|
+
const decoded = Buffer.from(payload, "base64").toString("utf8");
|
|
149
|
+
const value = JSON.parse(decoded);
|
|
150
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
151
|
+
parsed.push(value as Record<string, unknown>);
|
|
152
|
+
}
|
|
153
|
+
} catch {}
|
|
154
|
+
}
|
|
155
|
+
return parsed;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function resolveUserId(args: string[], env: EnvLike, authToken: string): string | undefined {
|
|
159
|
+
const explicit = readOption(args, "--tenant-id") || env.USER_ID || parseJwtTenantId(authToken);
|
|
160
|
+
if (explicit) return explicit;
|
|
161
|
+
const username = parseJwtUsername(authToken);
|
|
162
|
+
return username && /^[a-z0-9_-]+$/i.test(username) ? username : undefined;
|
|
102
163
|
}
|
|
103
164
|
|
|
104
165
|
function formatOutput(input: { envelope: any; rawData: any; mode: OutputMode }): string {
|
|
@@ -133,6 +194,182 @@ function usage(): string {
|
|
|
133
194
|
].join("\n");
|
|
134
195
|
}
|
|
135
196
|
|
|
197
|
+
function listUsage(): string {
|
|
198
|
+
return [
|
|
199
|
+
"Usage:",
|
|
200
|
+
" nolo table list [--limit <n>] [--title-query <text>] [--purpose <purpose>] [--output full|raw|items|json|jsonl]",
|
|
201
|
+
"",
|
|
202
|
+
].join("\n");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function tableHasPurpose(table: any, purpose: string): boolean {
|
|
206
|
+
return typeof table?.purpose === "string" && table.purpose.toLowerCase() === purpose.toLowerCase();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function getComparableUpdatedAt(record: any): number {
|
|
210
|
+
const raw = record?.updatedAt ?? record?.updated_at ?? record?.createdAt ?? record?.created;
|
|
211
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
212
|
+
if (typeof raw === "string") return Date.parse(raw) || 0;
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function formatTableListOutput(args: {
|
|
217
|
+
mode: OutputMode;
|
|
218
|
+
tables: any[];
|
|
219
|
+
envelope: any;
|
|
220
|
+
}) {
|
|
221
|
+
if (args.mode === "full") return JSON.stringify(args.envelope, null, 2);
|
|
222
|
+
if (args.mode === "raw") return JSON.stringify(args.tables, null, 2);
|
|
223
|
+
if (args.mode === "items") return JSON.stringify(args.tables, null, 2);
|
|
224
|
+
return args.tables.map((item) => JSON.stringify(item)).join("\n");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function runTableListCommand(args: string[], deps: TableCommandDeps = {}): Promise<number> {
|
|
228
|
+
const env = deps.env ?? process.env;
|
|
229
|
+
const output = deps.output ?? process.stdout;
|
|
230
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
231
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
232
|
+
output.write(listUsage());
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let outputMode: OutputMode;
|
|
237
|
+
try {
|
|
238
|
+
outputMode = parseOutputMode(readOption(args, "--output") || "items");
|
|
239
|
+
} catch (error) {
|
|
240
|
+
output.write(`[nolo] table list failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
241
|
+
return 1;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const authToken = resolveAuthToken(args, env);
|
|
245
|
+
const userId = resolveUserId(args, env, authToken);
|
|
246
|
+
if (!userId) {
|
|
247
|
+
output.write("[nolo] table list failed: user id is required. Pass --tenant-id or use a login token.\n");
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
if (!authToken) {
|
|
251
|
+
output.write("[nolo] table list failed: AUTH_TOKEN is required.\n");
|
|
252
|
+
return 1;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const limit = Math.max(1, Math.min(Number(readOption(args, "--limit") || 50), 200));
|
|
256
|
+
const titleQuery = readOption(args, "--title-query").trim().toLowerCase();
|
|
257
|
+
const purpose = readOption(args, "--purpose").trim();
|
|
258
|
+
const spaceId = normalizeSpaceInput(readOption(args, "--space") || readOption(args, "--space-id"));
|
|
259
|
+
const scanLimit = titleQuery || purpose ? Math.max(limit * 5, 200) : limit;
|
|
260
|
+
const serverUrl = resolveServerUrl(args, env);
|
|
261
|
+
|
|
262
|
+
let records: any[];
|
|
263
|
+
try {
|
|
264
|
+
records = spaceId
|
|
265
|
+
? await fetchSpaceTableRecords({
|
|
266
|
+
authToken,
|
|
267
|
+
fetchImpl,
|
|
268
|
+
serverUrl,
|
|
269
|
+
spaceId,
|
|
270
|
+
})
|
|
271
|
+
: await fetchUserTableRecords({
|
|
272
|
+
authToken,
|
|
273
|
+
fetchImpl,
|
|
274
|
+
limit: Math.min(scanLimit, 500),
|
|
275
|
+
serverUrl,
|
|
276
|
+
userId,
|
|
277
|
+
});
|
|
278
|
+
} catch (error) {
|
|
279
|
+
output.write(`[nolo] table list failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
280
|
+
return 1;
|
|
281
|
+
}
|
|
282
|
+
const tables = records
|
|
283
|
+
.filter((table: any) => table && typeof table === "object" && !table.deletedAt)
|
|
284
|
+
.filter((table: any) => !titleQuery || String(table.displayName ?? table.name ?? table.title ?? "").toLowerCase().includes(titleQuery))
|
|
285
|
+
.filter((table: any) => !purpose || tableHasPurpose(table, purpose))
|
|
286
|
+
.sort((left: any, right: any) => getComparableUpdatedAt(right) - getComparableUpdatedAt(left))
|
|
287
|
+
.slice(0, limit)
|
|
288
|
+
.map((table: any) => ({
|
|
289
|
+
dbKey: table.dbKey ?? null,
|
|
290
|
+
tableId: table.tableId ?? null,
|
|
291
|
+
displayName: table.displayName ?? table.name ?? table.title ?? "(untitled)",
|
|
292
|
+
spaceId: table.spaceId ?? null,
|
|
293
|
+
tenantId: table.tenantId ?? null,
|
|
294
|
+
columnCount: Array.isArray(table.columns) ? table.columns.length : 0,
|
|
295
|
+
createdAt: table.createdAt ?? null,
|
|
296
|
+
updatedAt: table.updatedAt ?? table.updated_at ?? null,
|
|
297
|
+
}));
|
|
298
|
+
|
|
299
|
+
const envelope = { success: true, userId, ...(spaceId ? { space: spaceId } : {}), total: tables.length, tables };
|
|
300
|
+
output.write(`${formatTableListOutput({ mode: outputMode, tables, envelope })}\n`);
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async function readJsonResponse(response: Response) {
|
|
305
|
+
const text = await response.text();
|
|
306
|
+
let payload: any;
|
|
307
|
+
try {
|
|
308
|
+
payload = text ? JSON.parse(text) : {};
|
|
309
|
+
} catch {
|
|
310
|
+
if (!response.ok) throw new Error(text || response.statusText);
|
|
311
|
+
return text;
|
|
312
|
+
}
|
|
313
|
+
if (!response.ok || payload?.error) {
|
|
314
|
+
throw new Error(payload?.error ?? response.statusText);
|
|
315
|
+
}
|
|
316
|
+
return payload;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async function fetchUserTableRecords(args: {
|
|
320
|
+
authToken: string;
|
|
321
|
+
fetchImpl: typeof fetch;
|
|
322
|
+
limit: number;
|
|
323
|
+
serverUrl: string;
|
|
324
|
+
userId: string;
|
|
325
|
+
}) {
|
|
326
|
+
const response = await args.fetchImpl(
|
|
327
|
+
`${args.serverUrl}/api/v1/db/query/${encodeURIComponent(args.userId)}?limit=${args.limit}`,
|
|
328
|
+
{
|
|
329
|
+
method: "POST",
|
|
330
|
+
headers: {
|
|
331
|
+
Authorization: `Bearer ${args.authToken}`,
|
|
332
|
+
"Content-Type": "application/json",
|
|
333
|
+
},
|
|
334
|
+
body: JSON.stringify({ type: "table" }),
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
const payload = await readJsonResponse(response);
|
|
338
|
+
return Array.isArray(payload?.data?.data)
|
|
339
|
+
? payload.data.data
|
|
340
|
+
: Array.isArray(payload?.data)
|
|
341
|
+
? payload.data
|
|
342
|
+
: [];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function fetchSpaceTableRecords(args: {
|
|
346
|
+
authToken: string;
|
|
347
|
+
fetchImpl: typeof fetch;
|
|
348
|
+
serverUrl: string;
|
|
349
|
+
spaceId: string;
|
|
350
|
+
}) {
|
|
351
|
+
const readRecord = async (dbKey: string) => {
|
|
352
|
+
const response = await args.fetchImpl(
|
|
353
|
+
`${args.serverUrl}/api/v1/db/read/${encodeURIComponent(dbKey)}`,
|
|
354
|
+
{ headers: { Authorization: `Bearer ${args.authToken}` } }
|
|
355
|
+
);
|
|
356
|
+
const payload = await readJsonResponse(response);
|
|
357
|
+
return payload?.data ?? payload;
|
|
358
|
+
};
|
|
359
|
+
const space = await readRecord(`space-${args.spaceId}`);
|
|
360
|
+
const tableKeys = [...getSpaceContentKeys(space)].filter((key) => key.startsWith("meta-"));
|
|
361
|
+
const records = await Promise.all(
|
|
362
|
+
tableKeys.map(async (key) => {
|
|
363
|
+
try {
|
|
364
|
+
return await readRecord(key);
|
|
365
|
+
} catch {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
return records.filter(Boolean);
|
|
371
|
+
}
|
|
372
|
+
|
|
136
373
|
export async function runTableQueryCommand(args: string[], deps: TableCommandDeps = {}): Promise<number> {
|
|
137
374
|
const env = deps.env ?? process.env;
|
|
138
375
|
const output = deps.output ?? process.stdout;
|
|
@@ -159,7 +396,7 @@ export async function runTableQueryCommand(args: string[], deps: TableCommandDep
|
|
|
159
396
|
|
|
160
397
|
const tableArg = parseTableArg(readOption(args, "--table"));
|
|
161
398
|
const authToken = resolveAuthToken(args, env);
|
|
162
|
-
const tenantId = readOption(args, "--tenant-id") || tableArg.tenantId || env
|
|
399
|
+
const tenantId = readOption(args, "--tenant-id") || tableArg.tenantId || resolveUserId(args, env, authToken);
|
|
163
400
|
const tableId = tableArg.tableId;
|
|
164
401
|
const hasSingleRowShortcut = Boolean(readOption(args, "--row") || readOption(args, "--row-id") || readOption(args, "--row-dbkey"));
|
|
165
402
|
if (!tenantId || !tableId) {
|
|
@@ -184,9 +421,7 @@ export async function runTableQueryCommand(args: string[], deps: TableCommandDep
|
|
|
184
421
|
tenantId,
|
|
185
422
|
tableId,
|
|
186
423
|
filters: filters ?? {},
|
|
187
|
-
columns: hasFlag(args, "--include-activity")
|
|
188
|
-
? includeTableActivityColumns(columns)
|
|
189
|
-
: columns,
|
|
424
|
+
columns: resolveQueryColumns(columns, hasFlag(args, "--include-activity")),
|
|
190
425
|
includeBaseFields: !hasFlag(args, "--no-base-fields"),
|
|
191
426
|
limit: Number(readOption(args, "--limit") || (hasSingleRowShortcut ? 1 : 20)),
|
|
192
427
|
offset: Number(readOption(args, "--offset") || 0),
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { createEnvCommand } from "./cliCommandFactories";
|
|
2
2
|
import type { CommandEntry } from "./cliCommandTypes";
|
|
3
|
-
import { runTableQueryCommand } from "./tableCommands";
|
|
4
|
-
import { runTaskRunCommand } from "./taskRunCommand";
|
|
3
|
+
import { runTableListCommand, runTableQueryCommand } from "./tableCommands";
|
|
5
4
|
|
|
6
5
|
export function getWorkflowInternalCommandEntries(): CommandEntry[] {
|
|
7
6
|
return [
|
|
7
|
+
createEnvCommand(["table", "list"], "List table metadata", runTableListCommand),
|
|
8
8
|
createEnvCommand(["table", "query"], "Query table rows", runTableQueryCommand),
|
|
9
|
-
createEnvCommand(["task-run"], "Update durable task-run state through the runner bridge", runTaskRunCommand),
|
|
10
9
|
];
|
|
11
10
|
}
|
package/client/agentRun.test.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
2
2
|
import { Writable } from "node:stream";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
classifyTaskContextReviewStatus,
|
|
6
6
|
findServerPlatformTools,
|
|
7
7
|
runAgentTurn,
|
|
8
8
|
} from "./agentRun";
|
|
@@ -24,14 +24,14 @@ class CaptureOutput extends Writable {
|
|
|
24
24
|
|
|
25
25
|
describe("cli agent run client", () => {
|
|
26
26
|
test("classifies only clear reviewer outcomes", () => {
|
|
27
|
-
expect(
|
|
28
|
-
expect(
|
|
29
|
-
expect(
|
|
30
|
-
expect(
|
|
31
|
-
expect(
|
|
27
|
+
expect(classifyTaskContextReviewStatus("Review decision: passed")).toBe("passed");
|
|
28
|
+
expect(classifyTaskContextReviewStatus("Review decision: needs_changes")).toBe("needs_changes");
|
|
29
|
+
expect(classifyTaskContextReviewStatus("Review decision: blocked")).toBe("blocked");
|
|
30
|
+
expect(classifyTaskContextReviewStatus("LGTM, no issues found")).toBe("passed");
|
|
31
|
+
expect(classifyTaskContextReviewStatus("Changes requested for missing test coverage")).toBe(
|
|
32
32
|
"needs_changes"
|
|
33
33
|
);
|
|
34
|
-
expect(
|
|
34
|
+
expect(classifyTaskContextReviewStatus("I looked at the diff and have notes")).toBeUndefined();
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
test("identifies server platform tools that local runtime cannot provide", () => {
|
|
@@ -111,18 +111,23 @@ describe("cli agent run client", () => {
|
|
|
111
111
|
reason: "connector_execution_failed",
|
|
112
112
|
code: "connector_disconnected_mid_run",
|
|
113
113
|
message: "Connector disconnected for machine: machine-win",
|
|
114
|
+
dialogId: "dialog-failed-1",
|
|
114
115
|
}, { status: 502 }),
|
|
115
116
|
});
|
|
116
117
|
|
|
117
|
-
expect(result).toEqual({ exitCode: 1 });
|
|
118
|
+
expect(result).toEqual({ exitCode: 1, dialogId: "dialog-failed-1" });
|
|
118
119
|
expect(output.text()).toContain("[nolo] Agent request failed: HTTP 502");
|
|
119
120
|
expect(output.text()).toContain("Connector execution failed");
|
|
120
121
|
expect(output.text()).toContain("Connector disconnected for machine: machine-win");
|
|
121
122
|
expect(output.text()).toContain("code=connector_disconnected_mid_run");
|
|
122
123
|
expect(output.text()).toContain("reason=connector_execution_failed");
|
|
124
|
+
expect(output.text()).toContain("[nolo] failed dialog: dialog-failed-1");
|
|
125
|
+
expect(output.text()).toContain(
|
|
126
|
+
'nolo agent run agent-win-codex --continue dialog-failed-1 --msg "retry"'
|
|
127
|
+
);
|
|
123
128
|
});
|
|
124
129
|
|
|
125
|
-
test("
|
|
130
|
+
test("converts task row context to subjectRefs without legacy prompt or runtime taskRun payload", async () => {
|
|
126
131
|
const output = new CaptureOutput();
|
|
127
132
|
const requests: Array<{ body: any }> = [];
|
|
128
133
|
|
|
@@ -135,10 +140,8 @@ describe("cli agent run client", () => {
|
|
|
135
140
|
env: { AUTH_TOKEN: "token-123" },
|
|
136
141
|
output,
|
|
137
142
|
runtimeMode: "server",
|
|
138
|
-
|
|
143
|
+
taskRowContext: {
|
|
139
144
|
rowDbKey: "row-b2e06f801f-01TASK",
|
|
140
|
-
taskRunId: "taskrun-1",
|
|
141
|
-
workItemId: "frontend-filter",
|
|
142
145
|
artifactIds: ["artifact-1"],
|
|
143
146
|
},
|
|
144
147
|
fetchImpl: async (_url, init) => {
|
|
@@ -147,22 +150,17 @@ describe("cli agent run client", () => {
|
|
|
147
150
|
},
|
|
148
151
|
});
|
|
149
152
|
|
|
150
|
-
expect(requests[0]?.body.userInput).
|
|
151
|
-
expect(requests[0]?.body.
|
|
152
|
-
expect(requests[0]?.body.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
rowDbKey: "row-b2e06f801f-01TASK",
|
|
157
|
-
taskRunId: "taskrun-1",
|
|
158
|
-
workItemId: "frontend-filter",
|
|
159
|
-
artifactIds: ["artifact-1"],
|
|
153
|
+
expect(requests[0]?.body.userInput).toBe("Fix the filter UI");
|
|
154
|
+
expect(requests[0]?.body.runtimeContext.taskRun).toBeUndefined();
|
|
155
|
+
expect(requests[0]?.body.runtimeContext.subjectRefs).toContainEqual({
|
|
156
|
+
kind: "table-row",
|
|
157
|
+
id: "row-b2e06f801f-01TASK",
|
|
158
|
+
role: "task",
|
|
160
159
|
});
|
|
161
160
|
});
|
|
162
161
|
|
|
163
|
-
test("
|
|
162
|
+
test("does not write task-context completion after an HTTP agent run returns a dialog", async () => {
|
|
164
163
|
const output = new CaptureOutput();
|
|
165
|
-
const writebacks: any[] = [];
|
|
166
164
|
|
|
167
165
|
const result = await runAgentTurn({
|
|
168
166
|
agentName: "frontend-implementer",
|
|
@@ -173,12 +171,8 @@ describe("cli agent run client", () => {
|
|
|
173
171
|
env: { AUTH_TOKEN: "token-123" },
|
|
174
172
|
output,
|
|
175
173
|
runtimeMode: "server",
|
|
176
|
-
|
|
174
|
+
taskRowContext: {
|
|
177
175
|
rowDbKey: "row-b2e06f801f-01TASK",
|
|
178
|
-
workItemId: "frontend-filter",
|
|
179
|
-
},
|
|
180
|
-
taskRunRecorder: async (args) => {
|
|
181
|
-
writebacks.push(args);
|
|
182
176
|
},
|
|
183
177
|
fetchImpl: async () => {
|
|
184
178
|
return Response.json({ content: "patched", dialogId: "dialog-1" });
|
|
@@ -186,16 +180,6 @@ describe("cli agent run client", () => {
|
|
|
186
180
|
});
|
|
187
181
|
|
|
188
182
|
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-1" });
|
|
189
|
-
expect(writebacks).toHaveLength(1);
|
|
190
|
-
expect(writebacks[0]).toMatchObject({
|
|
191
|
-
status: "completed",
|
|
192
|
-
dialogId: "dialog-1",
|
|
193
|
-
resultSummary: "patched",
|
|
194
|
-
});
|
|
195
|
-
expect(writebacks[0].options.taskRunContext).toEqual({
|
|
196
|
-
rowDbKey: "row-b2e06f801f-01TASK",
|
|
197
|
-
workItemId: "frontend-filter",
|
|
198
|
-
});
|
|
199
183
|
});
|
|
200
184
|
|
|
201
185
|
test("sends image inputs as multimodal userInput over HTTP", async () => {
|
|
@@ -237,6 +221,7 @@ describe("cli agent run client", () => {
|
|
|
237
221
|
category: "manual-checks",
|
|
238
222
|
inheritedFromDialogKey: "dialog-user-1-dialog-2",
|
|
239
223
|
parentDialogId: "dialog-2",
|
|
224
|
+
subjectDialogKey: "01SUBJECTDIALOG",
|
|
240
225
|
background: true,
|
|
241
226
|
noStream: true,
|
|
242
227
|
timeoutMs: 600000,
|
|
@@ -261,12 +246,45 @@ describe("cli agent run client", () => {
|
|
|
261
246
|
timeoutMs: 600000,
|
|
262
247
|
stream: false,
|
|
263
248
|
});
|
|
249
|
+
expect(requests[0]?.body.runtimeContext.subjectRefs).toEqual([
|
|
250
|
+
{ kind: "dialog", id: "01SUBJECTDIALOG", role: "subject" },
|
|
251
|
+
]);
|
|
264
252
|
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-1" });
|
|
265
253
|
});
|
|
266
254
|
|
|
267
|
-
test("
|
|
255
|
+
test("sends explicit subject refs over HTTP for review evidence", async () => {
|
|
256
|
+
const output = new CaptureOutput();
|
|
257
|
+
const requests: Array<{ body: any }> = [];
|
|
258
|
+
|
|
259
|
+
await runAgentTurn({
|
|
260
|
+
agentName: "reviewer",
|
|
261
|
+
agentKey: "agent-reviewer",
|
|
262
|
+
serverUrl: "https://nolo.chat",
|
|
263
|
+
message: "Review this implementation",
|
|
264
|
+
subjectRefs: [
|
|
265
|
+
{ kind: "table-row", id: "row-user-board-task", role: "subject" },
|
|
266
|
+
{ kind: "dialog", id: "dialog-impl", role: "review-target" },
|
|
267
|
+
{ kind: "external", id: "commit:abc123", role: "commit" },
|
|
268
|
+
],
|
|
269
|
+
scriptDir: "C:/missing/scripts",
|
|
270
|
+
env: { AUTH_TOKEN: "token-123" },
|
|
271
|
+
output,
|
|
272
|
+
runtimeMode: "server",
|
|
273
|
+
fetchImpl: async (_url, init) => {
|
|
274
|
+
requests.push({ body: JSON.parse(String(init?.body)) });
|
|
275
|
+
return Response.json({ content: "queued", dialogId: "dialog-review" });
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
expect(requests[0]?.body.runtimeContext.subjectRefs).toEqual([
|
|
280
|
+
{ kind: "table-row", id: "row-user-board-task", role: "subject" },
|
|
281
|
+
{ kind: "dialog", id: "dialog-impl", role: "review-target" },
|
|
282
|
+
{ kind: "external", id: "commit:abc123", role: "commit" },
|
|
283
|
+
]);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test("does not write background handoff state", async () => {
|
|
268
287
|
const output = new CaptureOutput();
|
|
269
|
-
const writebacks: any[] = [];
|
|
270
288
|
|
|
271
289
|
const result = await runAgentTurn({
|
|
272
290
|
agentName: "frontend-implementer",
|
|
@@ -278,12 +296,8 @@ describe("cli agent run client", () => {
|
|
|
278
296
|
runtimeMode: "server",
|
|
279
297
|
background: true,
|
|
280
298
|
noStream: true,
|
|
281
|
-
|
|
299
|
+
taskRowContext: {
|
|
282
300
|
rowDbKey: "row-b2e06f801f-01TASK",
|
|
283
|
-
workItemId: "self",
|
|
284
|
-
},
|
|
285
|
-
taskRunRecorder: async (args) => {
|
|
286
|
-
writebacks.push(args);
|
|
287
301
|
},
|
|
288
302
|
output,
|
|
289
303
|
fetchImpl: async () => {
|
|
@@ -292,11 +306,6 @@ describe("cli agent run client", () => {
|
|
|
292
306
|
});
|
|
293
307
|
|
|
294
308
|
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-bg" });
|
|
295
|
-
expect(writebacks).toHaveLength(1);
|
|
296
|
-
expect(writebacks[0]).toMatchObject({
|
|
297
|
-
status: "running",
|
|
298
|
-
dialogId: "dialog-bg",
|
|
299
|
-
});
|
|
300
309
|
});
|
|
301
310
|
|
|
302
311
|
test("runs forced local turns through the injected runtime adapter without HTTP", async () => {
|
|
@@ -571,12 +580,12 @@ describe("cli agent run client", () => {
|
|
|
571
580
|
round: 1,
|
|
572
581
|
tool: "execShell",
|
|
573
582
|
summary: expect.stringContaining("exit=0"),
|
|
583
|
+
metadata: { exitCode: 0 },
|
|
574
584
|
});
|
|
575
585
|
});
|
|
576
586
|
|
|
577
|
-
test("
|
|
587
|
+
test("does not pass local tool evidence to an external writeback path", async () => {
|
|
578
588
|
const output = new CaptureOutput();
|
|
579
|
-
const writebacks: any[] = [];
|
|
580
589
|
let completeCalls = 0;
|
|
581
590
|
|
|
582
591
|
const result = await runAgentTurn({
|
|
@@ -588,12 +597,8 @@ describe("cli agent run client", () => {
|
|
|
588
597
|
env: { AUTH_TOKEN: "token-123" },
|
|
589
598
|
output,
|
|
590
599
|
runtimeMode: "local",
|
|
591
|
-
|
|
600
|
+
taskRowContext: {
|
|
592
601
|
rowDbKey: "row-b2e06f801f-01TASK",
|
|
593
|
-
workItemId: "self",
|
|
594
|
-
},
|
|
595
|
-
taskRunRecorder: async (args) => {
|
|
596
|
-
writebacks.push(args);
|
|
597
602
|
},
|
|
598
603
|
localRuntimeAdapter: {
|
|
599
604
|
host: "cli",
|
|
@@ -630,21 +635,10 @@ describe("cli agent run client", () => {
|
|
|
630
635
|
});
|
|
631
636
|
|
|
632
637
|
expect(result).toMatchObject({ exitCode: 0, dialogId: "dialog-local" });
|
|
633
|
-
expect(writebacks).toHaveLength(1);
|
|
634
|
-
expect(writebacks[0].toolEvidence).toEqual({
|
|
635
|
-
toolsUsed: ["readFile"],
|
|
636
|
-
summary: {
|
|
637
|
-
callCount: 1,
|
|
638
|
-
resultCount: 1,
|
|
639
|
-
errorCount: 0,
|
|
640
|
-
rounds: 1,
|
|
641
|
-
},
|
|
642
|
-
});
|
|
643
638
|
});
|
|
644
639
|
|
|
645
|
-
test("
|
|
640
|
+
test("does not write local background handoff state", async () => {
|
|
646
641
|
const output = new CaptureOutput();
|
|
647
|
-
const writebacks: any[] = [];
|
|
648
642
|
|
|
649
643
|
const result = await runAgentTurn({
|
|
650
644
|
agentName: "frontend",
|
|
@@ -656,12 +650,8 @@ describe("cli agent run client", () => {
|
|
|
656
650
|
output,
|
|
657
651
|
runtimeMode: "local",
|
|
658
652
|
background: true,
|
|
659
|
-
|
|
653
|
+
taskRowContext: {
|
|
660
654
|
rowDbKey: "row-b2e06f801f-01TASK",
|
|
661
|
-
workItemId: "self",
|
|
662
|
-
},
|
|
663
|
-
taskRunRecorder: async (args) => {
|
|
664
|
-
writebacks.push(args);
|
|
665
655
|
},
|
|
666
656
|
localRuntimeAdapter: {
|
|
667
657
|
host: "cli",
|
|
@@ -685,12 +675,6 @@ describe("cli agent run client", () => {
|
|
|
685
675
|
});
|
|
686
676
|
|
|
687
677
|
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-local-bg" });
|
|
688
|
-
expect(writebacks).toHaveLength(1);
|
|
689
|
-
expect(writebacks[0]).toMatchObject({
|
|
690
|
-
status: "running",
|
|
691
|
-
dialogId: "dialog-local-bg",
|
|
692
|
-
});
|
|
693
|
-
expect(writebacks[0].resultSummary).toBeUndefined();
|
|
694
678
|
});
|
|
695
679
|
|
|
696
680
|
test("auto mode prefers a working local runtime before HTTP", async () => {
|
|
@@ -887,6 +871,58 @@ describe("cli agent run client", () => {
|
|
|
887
871
|
expect(output.text()).toContain("pm > server ok");
|
|
888
872
|
});
|
|
889
873
|
|
|
874
|
+
test("auto mode keeps local runtime for CLI provider agents even when they declare platform tools", async () => {
|
|
875
|
+
const output = new CaptureOutput();
|
|
876
|
+
const httpCalls: string[] = [];
|
|
877
|
+
let providerCalled = false;
|
|
878
|
+
|
|
879
|
+
const result = await runAgentTurn({
|
|
880
|
+
agentName: "frontend-implementer",
|
|
881
|
+
agentKey: "frontend-implementer",
|
|
882
|
+
serverUrl: "https://nolo.chat",
|
|
883
|
+
message: "polish notifications",
|
|
884
|
+
scriptDir: "C:/missing/scripts",
|
|
885
|
+
env: { AUTH_TOKEN: "token-123" },
|
|
886
|
+
output,
|
|
887
|
+
runtimeMode: "auto",
|
|
888
|
+
localRuntimeAdapter: {
|
|
889
|
+
host: "cli",
|
|
890
|
+
capabilities: ["leveldb-agent-config", "local-provider", "local-tools"],
|
|
891
|
+
loadAgentConfig: async (agentRef) => ({
|
|
892
|
+
key: agentRef,
|
|
893
|
+
name: "AGY",
|
|
894
|
+
prompt: "Implement frontend tasks.",
|
|
895
|
+
provider: "agy",
|
|
896
|
+
cliProvider: "agy",
|
|
897
|
+
toolNames: ["streamParallelAgents", "queryTableRows"],
|
|
898
|
+
}),
|
|
899
|
+
loadDialogHistory: async () => [],
|
|
900
|
+
saveTurn: async () => ({ dialogId: "dialog-agy-auto-local" }),
|
|
901
|
+
resolveProvider: async () => ({
|
|
902
|
+
model: "agy",
|
|
903
|
+
complete: async () => {
|
|
904
|
+
providerCalled = true;
|
|
905
|
+
return { content: "agy local ok", model: "agy" };
|
|
906
|
+
},
|
|
907
|
+
}),
|
|
908
|
+
executeTool: async () => {
|
|
909
|
+
throw new Error("no tools expected");
|
|
910
|
+
},
|
|
911
|
+
},
|
|
912
|
+
fetchImpl: async (url) => {
|
|
913
|
+
httpCalls.push(String(url));
|
|
914
|
+
return Response.json({ content: "server" });
|
|
915
|
+
},
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
expect(providerCalled).toBe(true);
|
|
919
|
+
expect(result).toEqual({ exitCode: 0, dialogId: "dialog-agy-auto-local" });
|
|
920
|
+
expect(httpCalls).toEqual([]);
|
|
921
|
+
expect(output.text()).not.toContain("skipping local runtime");
|
|
922
|
+
expect(output.text()).toContain("frontend-implementer -> working locally");
|
|
923
|
+
expect(output.text()).toContain("frontend-implementer > agy local ok");
|
|
924
|
+
});
|
|
925
|
+
|
|
890
926
|
test("auto mode does not skip monthly Mimo when a local shell cwd is already bound", async () => {
|
|
891
927
|
const output = new CaptureOutput();
|
|
892
928
|
const httpCalls: string[] = [];
|
|
@@ -1064,7 +1100,7 @@ describe("cli agent run client", () => {
|
|
|
1064
1100
|
model: "fake-local",
|
|
1065
1101
|
runtimeToolPolicy: {
|
|
1066
1102
|
version: 1,
|
|
1067
|
-
agentTools: ["queryTableRows", "
|
|
1103
|
+
agentTools: ["queryTableRows", "streamParallelAgents"],
|
|
1068
1104
|
runtimeTools: ["execShell"],
|
|
1069
1105
|
},
|
|
1070
1106
|
}),
|
|
@@ -1089,7 +1125,7 @@ describe("cli agent run client", () => {
|
|
|
1089
1125
|
expect(httpCalls).toHaveLength(1);
|
|
1090
1126
|
expect(httpCalls[0]?.body.agentKey).toBe("agent-policy-platform-tools");
|
|
1091
1127
|
expect(output.text()).toContain("auto runtime: skipping local runtime");
|
|
1092
|
-
expect(output.text()).toContain("queryTableRows,
|
|
1128
|
+
expect(output.text()).toContain("queryTableRows, streamParallelAgents");
|
|
1093
1129
|
});
|
|
1094
1130
|
|
|
1095
1131
|
test("auto mode skips known platform agents when local config cannot be read", async () => {
|