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/ai/agent/cliExecutor.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI Executor - 通过命令行工具执行 AI 任务
|
|
3
3
|
*
|
|
4
|
-
* 设计为可扩展:当前支持 Copilot CLI、Gemini CLI、Codex CLI、Claude CLI 与
|
|
4
|
+
* 设计为可扩展:当前支持 Copilot CLI、Gemini CLI、Codex CLI、Claude CLI、Antigravity CLI 与 Qoder CLI。
|
|
5
5
|
*
|
|
6
6
|
* 注意:
|
|
7
7
|
* - CLI provider 与普通 model 路由共享 prompt / model / 最近文本上下文这些能力面
|
|
@@ -18,13 +18,14 @@ import { randomUUID } from "node:crypto";
|
|
|
18
18
|
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
19
19
|
import { isAbsolute, join, resolve } from "node:path";
|
|
20
20
|
import { tmpdir } from "node:os";
|
|
21
|
+
import { StringDecoder } from "node:string_decoder";
|
|
21
22
|
import { resolveLaunchableCodexCommand } from "../../connector-experimental/codexBinary";
|
|
22
23
|
import { buildCliPrompt } from "./cliPrompt";
|
|
23
24
|
|
|
24
25
|
// ── 类型定义 ──────────────────────────────────────────────────────────────────
|
|
25
26
|
|
|
26
27
|
/** 已支持的 CLI 工具。新增时在此联合类型追加,并在 EXECUTORS 里注册实现 */
|
|
27
|
-
export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy";
|
|
28
|
+
export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy" | "qoder";
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* CLI provider 图片输入。
|
|
@@ -41,7 +42,7 @@ export interface CliImageInput {
|
|
|
41
42
|
|
|
42
43
|
export interface CliExecuteOptions {
|
|
43
44
|
model?: string;
|
|
44
|
-
timeout?: number; // ms
|
|
45
|
+
timeout?: number; // ms;各 CLI executor 可按任务类型设置自己的默认值
|
|
45
46
|
cwd?: string;
|
|
46
47
|
env?: Record<string, string | undefined>;
|
|
47
48
|
yolo?: boolean; // 允许所有工具,默认 true(后台任务常用)
|
|
@@ -70,6 +71,18 @@ type CliSessionMessage = {
|
|
|
70
71
|
content: string;
|
|
71
72
|
};
|
|
72
73
|
|
|
74
|
+
const DEFAULT_AGY_TIMEOUT_MS = 600_000;
|
|
75
|
+
const BUFFERED_STREAMING_PROVIDERS = new Set<CliProvider>([
|
|
76
|
+
"codex",
|
|
77
|
+
"claude",
|
|
78
|
+
"agy",
|
|
79
|
+
"qoder",
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
export function isBufferedCliStreamingProvider(provider: CliProvider): boolean {
|
|
83
|
+
return BUFFERED_STREAMING_PROVIDERS.has(provider);
|
|
84
|
+
}
|
|
85
|
+
|
|
73
86
|
export interface CliSessionHandle {
|
|
74
87
|
sessionId: string;
|
|
75
88
|
provider: CliProvider;
|
|
@@ -157,12 +170,39 @@ function normalizeProxyEnv(env: Record<string, string | undefined>): Record<stri
|
|
|
157
170
|
}
|
|
158
171
|
|
|
159
172
|
function buildCliProcessEnv(extraEnv?: Record<string, string | undefined>) {
|
|
173
|
+
const baseEnv = {
|
|
174
|
+
...process.env,
|
|
175
|
+
...extraEnv,
|
|
176
|
+
NO_COLOR: "1",
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// Enhance PATH on macOS so GUI-launched app can find brew/local tools
|
|
180
|
+
if (process.platform === "darwin") {
|
|
181
|
+
const defaultMacPaths = [
|
|
182
|
+
`${process.env.HOME || ""}/.local/bin`,
|
|
183
|
+
"/opt/homebrew/bin",
|
|
184
|
+
"/opt/homebrew/sbin",
|
|
185
|
+
"/usr/local/bin",
|
|
186
|
+
"/usr/local/sbin",
|
|
187
|
+
`${process.env.HOME || ""}/.bun/bin`,
|
|
188
|
+
`${process.env.HOME || ""}/Library/pnpm`,
|
|
189
|
+
`${process.env.HOME || ""}/.npm-global/bin`,
|
|
190
|
+
`${process.env.HOME || ""}/bin`,
|
|
191
|
+
];
|
|
192
|
+
const existingPath = baseEnv.PATH || "/usr/bin:/bin:/usr/sbin:/sbin";
|
|
193
|
+
const paths = existingPath.split(":");
|
|
194
|
+
for (const p of defaultMacPaths) {
|
|
195
|
+
if (p && !paths.includes(p)) {
|
|
196
|
+
paths.unshift(p); // Put brew/local paths at the front
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
baseEnv.PATH = paths.join(":");
|
|
200
|
+
}
|
|
201
|
+
|
|
160
202
|
return Object.fromEntries(
|
|
161
|
-
Object.entries(normalizeProxyEnv(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
NO_COLOR: "1",
|
|
165
|
-
})).filter((entry): entry is [string, string] => typeof entry[1] === "string")
|
|
203
|
+
Object.entries(normalizeProxyEnv(baseEnv)).filter(
|
|
204
|
+
(entry): entry is [string, string] => typeof entry[1] === "string"
|
|
205
|
+
)
|
|
166
206
|
);
|
|
167
207
|
}
|
|
168
208
|
|
|
@@ -176,6 +216,8 @@ function getCliProviderLabel(provider: CliProvider): string {
|
|
|
176
216
|
return "Copilot CLI";
|
|
177
217
|
case "agy":
|
|
178
218
|
return "Antigravity CLI";
|
|
219
|
+
case "qoder":
|
|
220
|
+
return "Qoder CLI";
|
|
179
221
|
case "gemini":
|
|
180
222
|
return "Gemini CLI";
|
|
181
223
|
}
|
|
@@ -192,7 +234,7 @@ function supportsModel(provider: CliProvider): boolean {
|
|
|
192
234
|
}
|
|
193
235
|
|
|
194
236
|
function supportsReasoningEffort(provider: CliProvider): boolean {
|
|
195
|
-
return provider === "claude" || provider === "copilot";
|
|
237
|
+
return provider === "claude" || provider === "copilot" || provider === "qoder";
|
|
196
238
|
}
|
|
197
239
|
|
|
198
240
|
function shouldPassClaudeModel(options: CliExecuteOptions): boolean {
|
|
@@ -624,8 +666,8 @@ function executeCodex(
|
|
|
624
666
|
env: buildCliProcessEnv(options.env),
|
|
625
667
|
stdio: ["ignore", "pipe", "pipe"],
|
|
626
668
|
});
|
|
627
|
-
|
|
628
|
-
|
|
669
|
+
const stdout = createUtf8Collector();
|
|
670
|
+
const stderr = createUtf8Collector();
|
|
629
671
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
630
672
|
|
|
631
673
|
if (timeout > 0) {
|
|
@@ -636,22 +678,24 @@ function executeCodex(
|
|
|
636
678
|
}
|
|
637
679
|
|
|
638
680
|
proc.stdout.on("data", (data: Buffer) => {
|
|
639
|
-
stdout
|
|
681
|
+
stdout.write(data);
|
|
640
682
|
});
|
|
641
683
|
|
|
642
684
|
proc.stderr.on("data", (data: Buffer) => {
|
|
643
|
-
stderr
|
|
685
|
+
stderr.write(data);
|
|
644
686
|
});
|
|
645
687
|
|
|
646
688
|
proc.on("close", (code) => {
|
|
647
689
|
if (timer) clearTimeout(timer);
|
|
690
|
+
const stdoutText = stdout.end();
|
|
691
|
+
const stderrText = stderr.end();
|
|
648
692
|
if (code !== 0 && code !== null) {
|
|
649
693
|
rmSync(tempDir, { recursive: true, force: true });
|
|
650
|
-
reject(new Error(`Codex CLI exited with code ${code}\nstderr: ${
|
|
694
|
+
reject(new Error(`Codex CLI exited with code ${code}\nstderr: ${stderrText}`));
|
|
651
695
|
return;
|
|
652
696
|
}
|
|
653
697
|
|
|
654
|
-
let text =
|
|
698
|
+
let text = stdoutText.trim();
|
|
655
699
|
try {
|
|
656
700
|
const lastMessage = readFileSync(outputFile, "utf8").trim();
|
|
657
701
|
if (lastMessage) text = lastMessage;
|
|
@@ -663,7 +707,7 @@ function executeCodex(
|
|
|
663
707
|
|
|
664
708
|
resolve({
|
|
665
709
|
text,
|
|
666
|
-
raw:
|
|
710
|
+
raw: stdoutText,
|
|
667
711
|
elapsed: Date.now() - start,
|
|
668
712
|
});
|
|
669
713
|
});
|
|
@@ -714,8 +758,8 @@ function executeClaude(
|
|
|
714
758
|
env: buildCliProcessEnv(options.env),
|
|
715
759
|
stdio: ["ignore", "pipe", "pipe"],
|
|
716
760
|
});
|
|
717
|
-
|
|
718
|
-
|
|
761
|
+
const stdout = createUtf8Collector();
|
|
762
|
+
const stderr = createUtf8Collector();
|
|
719
763
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
720
764
|
|
|
721
765
|
if (timeout > 0) {
|
|
@@ -726,23 +770,25 @@ function executeClaude(
|
|
|
726
770
|
}
|
|
727
771
|
|
|
728
772
|
proc.stdout.on("data", (data: Buffer) => {
|
|
729
|
-
stdout
|
|
773
|
+
stdout.write(data);
|
|
730
774
|
});
|
|
731
775
|
|
|
732
776
|
proc.stderr.on("data", (data: Buffer) => {
|
|
733
|
-
stderr
|
|
777
|
+
stderr.write(data);
|
|
734
778
|
});
|
|
735
779
|
|
|
736
780
|
proc.on("close", (code) => {
|
|
737
781
|
if (timer) clearTimeout(timer);
|
|
782
|
+
const stdoutText = stdout.end();
|
|
783
|
+
const stderrText = stderr.end();
|
|
738
784
|
if (code !== 0 && code !== null) {
|
|
739
|
-
reject(new Error(`Claude CLI exited with code ${code}\nstderr: ${
|
|
785
|
+
reject(new Error(`Claude CLI exited with code ${code}\nstderr: ${stderrText}`));
|
|
740
786
|
return;
|
|
741
787
|
}
|
|
742
788
|
|
|
743
789
|
resolve({
|
|
744
|
-
text:
|
|
745
|
-
raw:
|
|
790
|
+
text: stdoutText.trim(),
|
|
791
|
+
raw: stdoutText,
|
|
746
792
|
elapsed: Date.now() - start,
|
|
747
793
|
});
|
|
748
794
|
});
|
|
@@ -758,12 +804,78 @@ function formatCliTimeout(timeoutMs: number) {
|
|
|
758
804
|
return `${Math.max(1, Math.ceil(timeoutMs / 1000))}s`;
|
|
759
805
|
}
|
|
760
806
|
|
|
807
|
+
function tailText(value: string, maxChars = 1200): string {
|
|
808
|
+
if (value.length <= maxChars) return value;
|
|
809
|
+
return value.slice(value.length - maxChars);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function createUtf8Collector() {
|
|
813
|
+
const decoder = new StringDecoder("utf8");
|
|
814
|
+
let text = "";
|
|
815
|
+
let ended = false;
|
|
816
|
+
const finish = () => {
|
|
817
|
+
if (ended) return "";
|
|
818
|
+
ended = true;
|
|
819
|
+
const chunk = decoder.end();
|
|
820
|
+
if (chunk) text += chunk;
|
|
821
|
+
return chunk;
|
|
822
|
+
};
|
|
823
|
+
return {
|
|
824
|
+
write(data: Buffer): string {
|
|
825
|
+
if (ended) return "";
|
|
826
|
+
const chunk = decoder.write(data);
|
|
827
|
+
text += chunk;
|
|
828
|
+
return chunk;
|
|
829
|
+
},
|
|
830
|
+
finish,
|
|
831
|
+
end(): string {
|
|
832
|
+
finish();
|
|
833
|
+
return text;
|
|
834
|
+
},
|
|
835
|
+
get text() {
|
|
836
|
+
return text;
|
|
837
|
+
},
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function terminateCliProcessGroup(
|
|
842
|
+
proc: ReturnType<typeof spawn>,
|
|
843
|
+
signal: NodeJS.Signals
|
|
844
|
+
) {
|
|
845
|
+
const pid = typeof proc.pid === "number" ? proc.pid : 0;
|
|
846
|
+
if (pid > 0 && process.platform !== "win32") {
|
|
847
|
+
try {
|
|
848
|
+
process.kill(-pid, signal);
|
|
849
|
+
return;
|
|
850
|
+
} catch {
|
|
851
|
+
// Fall back to the child process if the group is unavailable.
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
try {
|
|
855
|
+
proc.kill(signal);
|
|
856
|
+
} catch {
|
|
857
|
+
// Best effort cleanup only.
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function buildAgyTimeoutError(timeout: number, stdout: string, stderr: string) {
|
|
862
|
+
const parts = [
|
|
863
|
+
`Antigravity CLI timed out after ${timeout}ms.`,
|
|
864
|
+
"agy print mode is agentic and can keep waiting for the conversation to become fully idle; prefer shorter scoped prompts or split the task into multiple turns.",
|
|
865
|
+
];
|
|
866
|
+
const stdoutTail = tailText(stdout).trim();
|
|
867
|
+
const stderrTail = tailText(stderr).trim();
|
|
868
|
+
if (stdoutTail) parts.push(`stdout tail:\n${stdoutTail}`);
|
|
869
|
+
if (stderrTail) parts.push(`stderr tail:\n${stderrTail}`);
|
|
870
|
+
return new Error(parts.join("\n"));
|
|
871
|
+
}
|
|
872
|
+
|
|
761
873
|
function executeAgy(
|
|
762
874
|
prompt: string,
|
|
763
875
|
options: CliExecuteOptions
|
|
764
876
|
): Promise<CliExecuteResult> {
|
|
765
877
|
const {
|
|
766
|
-
timeout =
|
|
878
|
+
timeout = DEFAULT_AGY_TIMEOUT_MS,
|
|
767
879
|
cwd = process.cwd(),
|
|
768
880
|
yolo = true,
|
|
769
881
|
} = options;
|
|
@@ -786,42 +898,142 @@ function executeAgy(
|
|
|
786
898
|
cwd,
|
|
787
899
|
env: buildCliProcessEnv(options.env),
|
|
788
900
|
stdio: ["ignore", "pipe", "pipe"],
|
|
901
|
+
detached: process.platform !== "win32",
|
|
789
902
|
});
|
|
790
|
-
|
|
791
|
-
|
|
903
|
+
const stdout = createUtf8Collector();
|
|
904
|
+
const stderr = createUtf8Collector();
|
|
792
905
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
906
|
+
let forceTimer: ReturnType<typeof setTimeout> | undefined;
|
|
907
|
+
let settled = false;
|
|
908
|
+
|
|
909
|
+
const clearTimers = () => {
|
|
910
|
+
if (timer) clearTimeout(timer);
|
|
911
|
+
if (forceTimer) clearTimeout(forceTimer);
|
|
912
|
+
};
|
|
793
913
|
|
|
794
914
|
if (timeout > 0) {
|
|
795
915
|
timer = setTimeout(() => {
|
|
796
|
-
|
|
797
|
-
|
|
916
|
+
if (settled) return;
|
|
917
|
+
settled = true;
|
|
918
|
+
terminateCliProcessGroup(proc, "SIGTERM");
|
|
919
|
+
forceTimer = setTimeout(() => {
|
|
920
|
+
terminateCliProcessGroup(proc, "SIGKILL");
|
|
921
|
+
}, 3_000);
|
|
922
|
+
reject(buildAgyTimeoutError(timeout, stdout.end(), stderr.end()));
|
|
798
923
|
}, timeout + 1_000);
|
|
799
924
|
}
|
|
800
925
|
|
|
801
926
|
proc.stdout.on("data", (data: Buffer) => {
|
|
802
|
-
stdout
|
|
927
|
+
stdout.write(data);
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
proc.stderr.on("data", (data: Buffer) => {
|
|
931
|
+
stderr.write(data);
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
proc.on("close", (code) => {
|
|
935
|
+
if (settled) {
|
|
936
|
+
clearTimers();
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
settled = true;
|
|
940
|
+
clearTimers();
|
|
941
|
+
const stdoutText = stdout.end();
|
|
942
|
+
const stderrText = stderr.end();
|
|
943
|
+
if (code !== 0 && code !== null) {
|
|
944
|
+
console.error("[cliExecutor] agy process exited with non-zero code:", code, "stderr:", stderrText);
|
|
945
|
+
reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderrText}`));
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
resolve({
|
|
950
|
+
text: stdoutText.trim(),
|
|
951
|
+
raw: stdoutText,
|
|
952
|
+
elapsed: Date.now() - start,
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
proc.on("error", (err) => {
|
|
957
|
+
if (settled) return;
|
|
958
|
+
settled = true;
|
|
959
|
+
clearTimers();
|
|
960
|
+
console.error("[cliExecutor] agy process error event:", err);
|
|
961
|
+
reject(err);
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
function executeQoder(
|
|
967
|
+
prompt: string,
|
|
968
|
+
options: CliExecuteOptions
|
|
969
|
+
): Promise<CliExecuteResult> {
|
|
970
|
+
const {
|
|
971
|
+
model,
|
|
972
|
+
reasoningEffort,
|
|
973
|
+
timeout = 120_000,
|
|
974
|
+
cwd = process.cwd(),
|
|
975
|
+
yolo = true,
|
|
976
|
+
} = options;
|
|
977
|
+
|
|
978
|
+
return new Promise((resolve, reject) => {
|
|
979
|
+
const args = ["-p", prompt, "--cwd", cwd];
|
|
980
|
+
if (model) {
|
|
981
|
+
args.push("--model");
|
|
982
|
+
args.push(model);
|
|
983
|
+
}
|
|
984
|
+
if (reasoningEffort) {
|
|
985
|
+
args.push("--reasoning-effort");
|
|
986
|
+
args.push(reasoningEffort);
|
|
987
|
+
}
|
|
988
|
+
if (yolo) {
|
|
989
|
+
args.push("--dangerously-skip-permissions");
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
const start = Date.now();
|
|
993
|
+
const proc = spawn("qoder", args, {
|
|
994
|
+
cwd,
|
|
995
|
+
env: buildCliProcessEnv(options.env),
|
|
996
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
997
|
+
});
|
|
998
|
+
const stdout = createUtf8Collector();
|
|
999
|
+
const stderr = createUtf8Collector();
|
|
1000
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1001
|
+
|
|
1002
|
+
if (timeout > 0) {
|
|
1003
|
+
timer = setTimeout(() => {
|
|
1004
|
+
proc.kill("SIGTERM");
|
|
1005
|
+
reject(new Error(`Qoder CLI timed out after ${timeout}ms`));
|
|
1006
|
+
}, timeout);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
proc.stdout.on("data", (data: Buffer) => {
|
|
1010
|
+
stdout.write(data);
|
|
803
1011
|
});
|
|
804
1012
|
|
|
805
1013
|
proc.stderr.on("data", (data: Buffer) => {
|
|
806
|
-
stderr
|
|
1014
|
+
stderr.write(data);
|
|
807
1015
|
});
|
|
808
1016
|
|
|
809
1017
|
proc.on("close", (code) => {
|
|
810
1018
|
if (timer) clearTimeout(timer);
|
|
1019
|
+
const stdoutText = stdout.end();
|
|
1020
|
+
const stderrText = stderr.end();
|
|
811
1021
|
if (code !== 0 && code !== null) {
|
|
812
|
-
|
|
1022
|
+
console.error("[cliExecutor] qoder process exited with non-zero code:", code, "stderr:", stderrText);
|
|
1023
|
+
reject(new Error(`Qoder CLI exited with code ${code}\nstderr: ${stderrText}`));
|
|
813
1024
|
return;
|
|
814
1025
|
}
|
|
815
1026
|
|
|
816
1027
|
resolve({
|
|
817
|
-
text:
|
|
818
|
-
raw:
|
|
1028
|
+
text: stdoutText.trim(),
|
|
1029
|
+
raw: stdoutText,
|
|
819
1030
|
elapsed: Date.now() - start,
|
|
820
1031
|
});
|
|
821
1032
|
});
|
|
822
1033
|
|
|
823
1034
|
proc.on("error", (err) => {
|
|
824
1035
|
if (timer) clearTimeout(timer);
|
|
1036
|
+
console.error("[cliExecutor] qoder process error event:", err);
|
|
825
1037
|
reject(err);
|
|
826
1038
|
});
|
|
827
1039
|
});
|
|
@@ -838,6 +1050,7 @@ const EXECUTORS: Record<
|
|
|
838
1050
|
codex: executeCodex,
|
|
839
1051
|
claude: executeClaude,
|
|
840
1052
|
agy: executeAgy,
|
|
1053
|
+
qoder: executeQoder,
|
|
841
1054
|
};
|
|
842
1055
|
|
|
843
1056
|
function formatCliSessionTask(messages: CliSessionMessage[]): string {
|
|
@@ -874,7 +1087,7 @@ function getCliSessionOrThrow(sessionId: string): CliSessionState {
|
|
|
874
1087
|
/**
|
|
875
1088
|
* 执行 CLI 任务
|
|
876
1089
|
*
|
|
877
|
-
* @param provider CLI 工具类型(如 "copilot" | "gemini" | "codex" | "claude" | "agy")
|
|
1090
|
+
* @param provider CLI 工具类型(如 "copilot" | "gemini" | "codex" | "claude" | "agy" | "qoder")
|
|
878
1091
|
* @param prompt 完整 prompt(system prompt 已由调用方拼好)
|
|
879
1092
|
* @param options 执行选项
|
|
880
1093
|
*/
|
|
@@ -1060,7 +1273,7 @@ export function executeCliStreaming(
|
|
|
1060
1273
|
})
|
|
1061
1274
|
);
|
|
1062
1275
|
}
|
|
1063
|
-
if (provider === "agy") {
|
|
1276
|
+
if (provider === "agy" || provider === "qoder") {
|
|
1064
1277
|
return withCleanup(
|
|
1065
1278
|
executor(resolved.prompt, resolved.options).then((result) => {
|
|
1066
1279
|
const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
|
|
@@ -1099,10 +1312,10 @@ export function executeCliStreaming(
|
|
|
1099
1312
|
const start = Date.now();
|
|
1100
1313
|
const proc = spawn("gh", args, {
|
|
1101
1314
|
cwd,
|
|
1102
|
-
env:
|
|
1315
|
+
env: buildCliProcessEnv(resolved.options.env),
|
|
1103
1316
|
});
|
|
1104
1317
|
|
|
1105
|
-
|
|
1318
|
+
const stdout = createUtf8Collector();
|
|
1106
1319
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1107
1320
|
|
|
1108
1321
|
if (timeout > 0) {
|
|
@@ -1113,8 +1326,7 @@ export function executeCliStreaming(
|
|
|
1113
1326
|
}
|
|
1114
1327
|
|
|
1115
1328
|
proc.stdout.on("data", (data: Buffer) => {
|
|
1116
|
-
const chunk =
|
|
1117
|
-
raw += chunk;
|
|
1329
|
+
const chunk = stdout.write(data);
|
|
1118
1330
|
// 过滤噪音行后再推送
|
|
1119
1331
|
const cleaned = chunk
|
|
1120
1332
|
.split("\n")
|
|
@@ -1125,6 +1337,7 @@ export function executeCliStreaming(
|
|
|
1125
1337
|
|
|
1126
1338
|
proc.on("close", (code) => {
|
|
1127
1339
|
if (timer) clearTimeout(timer);
|
|
1340
|
+
const raw = stdout.end();
|
|
1128
1341
|
if (code !== 0 && code !== null) {
|
|
1129
1342
|
reject(new Error(`Copilot CLI exited with code ${code}`));
|
|
1130
1343
|
return;
|
|
@@ -1169,11 +1382,14 @@ function executeGeminiStreaming(
|
|
|
1169
1382
|
const start = Date.now();
|
|
1170
1383
|
const proc = spawn("gemini", args, {
|
|
1171
1384
|
cwd,
|
|
1172
|
-
env: {
|
|
1385
|
+
env: buildCliProcessEnv({
|
|
1386
|
+
...options.env,
|
|
1387
|
+
NODE_OPTIONS: "--no-deprecation",
|
|
1388
|
+
}),
|
|
1173
1389
|
});
|
|
1174
1390
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1391
|
+
const stdout = createUtf8Collector();
|
|
1392
|
+
const stderr = createUtf8Collector();
|
|
1177
1393
|
let lineBuffer = "";
|
|
1178
1394
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1179
1395
|
|
|
@@ -1198,8 +1414,7 @@ function executeGeminiStreaming(
|
|
|
1198
1414
|
}
|
|
1199
1415
|
|
|
1200
1416
|
proc.stdout.on("data", (data: Buffer) => {
|
|
1201
|
-
const chunk =
|
|
1202
|
-
raw += chunk;
|
|
1417
|
+
const chunk = stdout.write(data);
|
|
1203
1418
|
lineBuffer += chunk;
|
|
1204
1419
|
|
|
1205
1420
|
let newlineIndex = lineBuffer.indexOf("\n");
|
|
@@ -1220,15 +1435,18 @@ function executeGeminiStreaming(
|
|
|
1220
1435
|
});
|
|
1221
1436
|
|
|
1222
1437
|
proc.stderr.on("data", (data: Buffer) => {
|
|
1223
|
-
stderr
|
|
1438
|
+
stderr.write(data);
|
|
1224
1439
|
});
|
|
1225
1440
|
|
|
1226
1441
|
proc.on("close", (code) => {
|
|
1227
1442
|
if (timer) clearTimeout(timer);
|
|
1443
|
+
lineBuffer += stdout.finish();
|
|
1444
|
+
const raw = stdout.text;
|
|
1445
|
+
const stderrText = stderr.end();
|
|
1228
1446
|
flushLineBuffer();
|
|
1229
1447
|
|
|
1230
1448
|
if (code !== 0 && code !== null) {
|
|
1231
|
-
reject(new Error(`Gemini CLI exited with code ${code}\nstderr: ${
|
|
1449
|
+
reject(new Error(`Gemini CLI exited with code ${code}\nstderr: ${stderrText}`));
|
|
1232
1450
|
return;
|
|
1233
1451
|
}
|
|
1234
1452
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Simple deterministic hash for cache-key purposes (browser + server compatible)
|
|
2
|
+
function createHash(_algo: string) {
|
|
3
|
+
let buf = "";
|
|
4
|
+
return {
|
|
5
|
+
update(s: string) { buf += s; return this; },
|
|
6
|
+
digest(_enc: string) {
|
|
7
|
+
// FNV-1a 32-bit, hex-padded to 8 chars
|
|
8
|
+
let h = 0x811c9dc5;
|
|
9
|
+
for (let i = 0; i < buf.length; i++) {
|
|
10
|
+
h ^= buf.charCodeAt(i);
|
|
11
|
+
h = (h * 0x01000193) >>> 0;
|
|
12
|
+
}
|
|
13
|
+
return h.toString(16).padStart(8, "0");
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type ContextLayerOwner =
|
|
19
|
+
| "platform"
|
|
20
|
+
| "agent"
|
|
21
|
+
| "user"
|
|
22
|
+
| "runtime";
|
|
23
|
+
|
|
24
|
+
export type ContextLayerCacheScope = "static" | "session" | "turn";
|
|
25
|
+
|
|
26
|
+
export type ContextLayer = {
|
|
27
|
+
id: string;
|
|
28
|
+
owner: ContextLayerOwner;
|
|
29
|
+
content?: string | null;
|
|
30
|
+
tokenBudget?: number;
|
|
31
|
+
cacheScope?: ContextLayerCacheScope;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type CompiledContextLayer = {
|
|
35
|
+
id: string;
|
|
36
|
+
owner: ContextLayerOwner;
|
|
37
|
+
content: string;
|
|
38
|
+
cacheScope: ContextLayerCacheScope;
|
|
39
|
+
charCount: number;
|
|
40
|
+
estimatedTokens: number;
|
|
41
|
+
tokenBudget?: number;
|
|
42
|
+
budgetStatus?: "within-budget" | "over-budget";
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type CompiledContext = {
|
|
46
|
+
content: string;
|
|
47
|
+
layers: CompiledContextLayer[];
|
|
48
|
+
cacheProfile: {
|
|
49
|
+
stablePrefixHash: string;
|
|
50
|
+
stablePrefixLayerIds: string[];
|
|
51
|
+
stablePrefixCharCount: number;
|
|
52
|
+
stablePrefixEstimatedTokens: number;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const hasLayerContent = (
|
|
57
|
+
layer: ContextLayer
|
|
58
|
+
): layer is ContextLayer & { content: string } => Boolean(layer.content);
|
|
59
|
+
|
|
60
|
+
export const estimateContextTokens = (content: string): number =>
|
|
61
|
+
Math.ceil(content.length / 4);
|
|
62
|
+
|
|
63
|
+
export const compileContextLayers = (
|
|
64
|
+
layers: ContextLayer[]
|
|
65
|
+
): CompiledContext => {
|
|
66
|
+
const compiledLayers = layers
|
|
67
|
+
.filter(hasLayerContent)
|
|
68
|
+
.map((layer): CompiledContextLayer => {
|
|
69
|
+
const estimatedTokens = estimateContextTokens(layer.content);
|
|
70
|
+
return {
|
|
71
|
+
id: layer.id,
|
|
72
|
+
owner: layer.owner,
|
|
73
|
+
content: layer.content,
|
|
74
|
+
cacheScope: layer.cacheScope ?? "turn",
|
|
75
|
+
charCount: layer.content.length,
|
|
76
|
+
estimatedTokens,
|
|
77
|
+
tokenBudget: layer.tokenBudget,
|
|
78
|
+
budgetStatus:
|
|
79
|
+
typeof layer.tokenBudget === "number"
|
|
80
|
+
? estimatedTokens <= layer.tokenBudget
|
|
81
|
+
? "within-budget"
|
|
82
|
+
: "over-budget"
|
|
83
|
+
: undefined,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
const stablePrefixLayers: CompiledContextLayer[] = [];
|
|
87
|
+
for (const layer of compiledLayers) {
|
|
88
|
+
if (layer.cacheScope === "turn") break;
|
|
89
|
+
stablePrefixLayers.push(layer);
|
|
90
|
+
}
|
|
91
|
+
const stablePrefixContent = stablePrefixLayers
|
|
92
|
+
.map((layer) => layer.content)
|
|
93
|
+
.join("\n\n");
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
content: compiledLayers.map((layer) => layer.content).join("\n\n"),
|
|
97
|
+
layers: compiledLayers,
|
|
98
|
+
cacheProfile: {
|
|
99
|
+
stablePrefixHash: createHash("sha256")
|
|
100
|
+
.update(stablePrefixContent)
|
|
101
|
+
.digest("hex"),
|
|
102
|
+
stablePrefixLayerIds: stablePrefixLayers.map((layer) => layer.id),
|
|
103
|
+
stablePrefixCharCount: stablePrefixContent.length,
|
|
104
|
+
stablePrefixEstimatedTokens: estimateContextTokens(stablePrefixContent),
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
type ContextLayerContractOptions = {
|
|
2
|
+
hasRememberMemoryTool?: boolean;
|
|
3
|
+
hasDocTools?: boolean;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const buildContextLayerContractBlock = (
|
|
7
|
+
options: ContextLayerContractOptions = {}
|
|
8
|
+
): string => {
|
|
9
|
+
const lines = [
|
|
10
|
+
"--- 上下文分层约定 ---",
|
|
11
|
+
"不要把所有信息都塞进同一层。优先利用已有的 memory / knowledge / doc,而不是把它们混成一段长对话。",
|
|
12
|
+
"",
|
|
13
|
+
"层次边界:",
|
|
14
|
+
"1. memory layer:放短到中期、可复用但不必永久挂载的偏好、近期共识和压缩后的经验;要短、可检索、可替换。",
|
|
15
|
+
"2. knowledge layer:放稳定规则、长期有效事实和每轮都会反复依赖的说明;优先通过 prompt / references 自动加载。",
|
|
16
|
+
"3. doc layer:放需要跨轮次持续维护的外部工作台,例如 runbook、mission、incident、checkpoint、idea backlog、experiment log;需要时显式读取和更新。",
|
|
17
|
+
"",
|
|
18
|
+
"写入原则:",
|
|
19
|
+
"- 临时步骤、原始长日志、一次性思路,不要直接写进 memory 或 knowledge。",
|
|
20
|
+
"- 稳定行为规则、长期固定约束,优先沉淀到 knowledge layer。",
|
|
21
|
+
"- 用户偏好、最近形成的协作共识、近期反复有用的经验,优先沉淀到 memory layer。",
|
|
22
|
+
"- 需要跨轮次接力的任务状态、运行手册、事故记录、检查点,优先写入 doc layer。",
|
|
23
|
+
"",
|
|
24
|
+
"读取原则:",
|
|
25
|
+
"- 先用 knowledge layer 解决稳定规则问题。",
|
|
26
|
+
"- 再用 memory layer 补充近期偏好和延续性。",
|
|
27
|
+
"- 需要真实运行现场、任务状态或可共享工作台时,再读 doc layer。",
|
|
28
|
+
"- 当前用户输入始终高于 recent memory;recent memory 高于过旧的 doc 推断。",
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
if (options.hasRememberMemoryTool) {
|
|
32
|
+
lines.push(
|
|
33
|
+
"- 当某条偏好、近期共识或复用经验对未来明显有帮助时,可以调用 rememberMemory,但要写成简洁可复用的一句话;只有当前 dialog 明确绑定了 space,且内容属于共享协作规则时才写 space memory。"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (options.hasDocTools) {
|
|
38
|
+
lines.push(
|
|
39
|
+
"- 当任务需要 24h 连续运行、跨 dialog 接力或人工与 agent 共读时,优先把 mission / runbook / incident / checkpoint / idea backlog / experiment log 写入 doc layer。"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return lines.join("\n");
|
|
44
|
+
};
|