nolo-cli 0.1.39 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/agent-runtime/dialogWritePlan.ts +39 -0
- package/agent-runtime/hostAdapter.ts +4 -0
- package/agent-runtime/hybridRecordStore.ts +5 -3
- package/agent-runtime/index.ts +15 -0
- package/agent-runtime/localLoop.ts +87 -7
- package/agent-runtime/localToolPolicy.ts +2 -13
- package/agent-runtime/localWorkspaceTools.ts +42 -110
- package/agent-runtime/runtimeToolPolicy.ts +2 -11
- package/agent-runtime/runtimeToolSurface.ts +198 -0
- package/agent-runtime/types.ts +1 -0
- package/agentAliases.ts +2 -1
- package/agentRunCommand.ts +10 -32
- package/agentRuntimeLocal.ts +1 -0
- package/ai/agent/_executeModel.ts +146 -0
- package/ai/agent/agentSlice.ts +556 -1
- package/ai/agent/appWorkingMemory.ts +126 -0
- package/ai/agent/buildEditingContext.ts +378 -0
- package/ai/agent/buildSystemPrompt.ts +585 -0
- package/ai/agent/canvasEditingContext.ts +49 -0
- package/ai/agent/cleanAgentMessages.ts +140 -0
- package/ai/agent/cliChatClient.ts +153 -0
- package/ai/agent/cliExecutor.ts +314 -40
- package/ai/agent/contextCompiler.ts +107 -0
- package/ai/agent/contextLayerContract.ts +44 -0
- package/ai/agent/createAgentSchema.ts +272 -0
- package/ai/agent/currentTimeContext.ts +65 -0
- package/ai/agent/executeToolCall.ts +58 -0
- package/ai/agent/fetchAgentContexts.ts +42 -0
- package/ai/agent/generatePrompt.ts +3 -0
- package/ai/agent/getFullChatContextKeys.ts +168 -0
- package/ai/agent/guidedCreation/capabilities.ts +84 -0
- package/ai/agent/guidedCreation/types.ts +38 -0
- package/ai/agent/isLiveAudioOnlyAgent.ts +26 -0
- package/ai/agent/liveAudioModel.ts +2 -0
- package/ai/agent/pageBuilderHandoffRules.ts +75 -0
- package/ai/agent/persistMessageWithFixedId.ts +37 -0
- package/ai/agent/planSlice.ts +259 -0
- package/ai/agent/referenceUtils.ts +229 -0
- package/ai/agent/runAgentBackground.ts +310 -0
- package/ai/agent/runAgentClientLoop.ts +164 -0
- package/ai/agent/runtimeGuidance.ts +116 -0
- package/ai/agent/serverOrigin.ts +7 -0
- package/ai/agent/startParallelAgentStreams.ts +424 -0
- package/ai/agent/startupProtocol.ts +53 -0
- package/ai/agent/streamAgentChatTurn.ts +2001 -0
- package/ai/agent/streamAgentChatTurnUtils.ts +860 -0
- package/ai/agent/toolFailureGuard.ts +99 -0
- package/ai/agent/types.ts +73 -0
- package/ai/agent/utils/imageOutput.ts +37 -0
- package/ai/agent/utils/publicImageAgentMode.ts +26 -0
- package/ai/ai.locale.ts +1095 -0
- package/ai/chat/accumulateToolCallChunks.ts +126 -0
- package/ai/chat/fetchUtils.ts +143 -0
- package/ai/chat/inlineImageUrlsForCustomProvider.ts +117 -0
- package/ai/chat/parseApiError.ts +67 -0
- package/ai/chat/parseMultilineSSE.ts +95 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +897 -0
- package/ai/chat/sendOpenAIResponseRequest.ts +720 -0
- package/ai/chat/serverProxyRetry.ts +102 -0
- package/ai/chat/shouldUseServerProxy.ts +18 -0
- package/ai/chat/streamRetry.ts +46 -0
- package/ai/chat/updateTotalUsage.ts +89 -0
- package/ai/context/buildReferenceContext.ts +437 -0
- package/ai/context/retention.ts +165 -0
- package/ai/context/tokenUtils.ts +78 -0
- package/ai/llm/agentCapabilities.ts +74 -0
- package/ai/llm/deepinfra.ts +79 -0
- package/ai/llm/fireworks.ts +68 -0
- package/ai/llm/generateRequestBody.ts +165 -0
- package/ai/llm/getModelContextWindow.ts +93 -0
- package/ai/llm/getPricing.ts +252 -0
- package/ai/llm/imagePricing.ts +66 -0
- package/ai/llm/isResponseAPIModel.ts +13 -0
- package/ai/llm/kimi.ts +23 -0
- package/ai/llm/mimo.ts +99 -0
- package/ai/llm/mistral.ts +21 -0
- package/ai/llm/models.ts +45 -0
- package/ai/llm/openrouterModels.ts +6 -0
- package/ai/llm/providers.ts +313 -0
- package/ai/llm/reasoningModels.ts +27 -0
- package/ai/llm/types.ts +82 -0
- package/ai/llm/usageRequestOptions.ts +59 -0
- package/ai/memory/queryShared.ts +161 -0
- package/ai/memory/recentRelationshipRecap.ts +247 -0
- package/ai/memory/remember.ts +167 -0
- package/ai/memory/store.ts +20 -0
- package/ai/memory/storeShared.ts +76 -0
- package/ai/memory/types.ts +46 -0
- package/ai/memory/understanding.ts +349 -0
- package/ai/memory/understandingGreeting.ts +264 -0
- package/ai/policy/personalizationDialog.ts +333 -0
- package/ai/policy/runtimePolicy.ts +454 -0
- package/ai/policy/selfUpdateFields.ts +48 -0
- package/ai/policy/types.ts +64 -0
- package/ai/skills/referenceRuntime.ts +274 -0
- package/ai/skills/skillDiagnostics.ts +251 -0
- package/ai/skills/skillDocBuilder.ts +139 -0
- package/ai/skills/skillSummaryMarker.ts +26 -0
- package/ai/token/calculatePrice.ts +576 -0
- package/ai/token/missingUsageEstimate.ts +42 -0
- package/ai/token/normalizeUsage.ts +124 -0
- package/ai/token/openaiImageGenerationUsage.ts +56 -0
- package/ai/token/prepareTokenUsageData.ts +93 -0
- package/ai/token/resolveBillingTarget.ts +52 -0
- package/ai/token/saveTokenRecord.ts +53 -0
- package/ai/token/types.ts +103 -0
- package/ai/tools/agent/agentTools.ts +235 -0
- package/ai/tools/agent/agentUpdateShared.ts +311 -0
- package/ai/tools/agent/callAgentTool.ts +139 -0
- package/ai/tools/agent/createAgentTool.ts +512 -0
- package/ai/tools/agent/createDialogTool.ts +69 -0
- package/ai/tools/agent/createSkillAgentTool.ts +62 -0
- package/ai/tools/agent/parallelBudget.ts +221 -0
- package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
- package/ai/tools/agent/presets/appBuilderPreset.ts +154 -0
- package/ai/tools/agent/runLlmTool.ts +96 -0
- package/ai/tools/agent/runStreamingAgentTool.ts +73 -0
- package/ai/tools/agent/skillAgentArgs.ts +106 -0
- package/ai/tools/agent/startAgentDialogTool.ts +53 -0
- package/ai/tools/agent/streamParallelAgentsTool.ts +123 -0
- package/ai/tools/agent/updateAgentTool.ts +96 -0
- package/ai/tools/agent/updateSelfTool.ts +113 -0
- package/ai/tools/amazonProductScraperTool.ts +86 -0
- package/ai/tools/apifyActorClient.ts +45 -0
- package/ai/tools/appEditGuard.ts +372 -0
- package/ai/tools/appReadSnapshot.ts +153 -0
- package/ai/tools/appTools.ts +1549 -0
- package/ai/tools/applyEditTool.ts +259 -0
- package/ai/tools/applyLineEditsTool.ts +315 -0
- package/ai/tools/browserTools/click.ts +33 -0
- package/ai/tools/browserTools/closeSession.ts +29 -0
- package/ai/tools/browserTools/common.ts +27 -0
- package/ai/tools/browserTools/openSession.ts +48 -0
- package/ai/tools/browserTools/readContent.ts +38 -0
- package/ai/tools/browserTools/selectOption.ts +46 -0
- package/ai/tools/browserTools/typeText.ts +42 -0
- package/ai/tools/category/createCategoryTool.ts +66 -0
- package/ai/tools/category/queryContentsByCategoryTool.ts +69 -0
- package/ai/tools/category/updateContentCategoryTool.ts +75 -0
- package/ai/tools/cfBrowserTools.ts +319 -0
- package/ai/tools/cfSpeechToTextTool.ts +49 -0
- package/ai/tools/checkEnvTool.ts +102 -0
- package/ai/tools/cloudflareCrawlTool.ts +289 -0
- package/ai/tools/codeSearchTool.ts +123 -0
- package/ai/tools/codeTools.ts +101 -0
- package/ai/tools/convertMarxistsBookTool.ts +103 -0
- package/ai/tools/createDocTool.ts +132 -0
- package/ai/tools/createSkillDocTool.ts +155 -0
- package/ai/tools/createWorkflowTool.ts +154 -0
- package/ai/tools/delayTool.ts +31 -0
- package/ai/tools/deleteSpacesTool.ts +325 -0
- package/ai/tools/deleteSpacesToolModel.ts +159 -0
- package/ai/tools/devReloadUtils.ts +29 -0
- package/ai/tools/dialogMessageSearch.ts +137 -0
- package/ai/tools/doctorSkillTool.ts +72 -0
- package/ai/tools/ecommerceScraperTool.ts +86 -0
- package/ai/tools/emailTools.ts +549 -0
- package/ai/tools/evalSkillTool.ts +92 -0
- package/ai/tools/exaSearchTool.ts +63 -0
- package/ai/tools/execShellTool.ts +266 -0
- package/ai/tools/executeSqlTool.ts +192 -0
- package/ai/tools/fetchWebpageSupport.ts +333 -0
- package/ai/tools/fetchWebpageTool.ts +97 -0
- package/ai/tools/geminiImagePreviewTool.ts +386 -0
- package/ai/tools/generateDocxTool.ts +215 -0
- package/ai/tools/googleSearchScraperTool.ts +106 -0
- package/ai/tools/importDataTool.ts +133 -0
- package/ai/tools/importSkillTool.ts +162 -0
- package/ai/tools/index.ts +2308 -0
- package/ai/tools/jdProductScraperTool.ts +821 -0
- package/ai/tools/listUserSpacesTool.ts +113 -0
- package/ai/tools/localFilesTool.ts +276 -0
- package/ai/tools/marxistsOfflineBook.ts +253 -0
- package/ai/tools/modelUsageTools.ts +206 -0
- package/ai/tools/noloWorkspaceReadTools.ts +467 -0
- package/ai/tools/olmOcrTool.ts +33 -0
- package/ai/tools/openaiImageTool.ts +267 -0
- package/ai/tools/prepareTools.ts +23 -0
- package/ai/tools/readDocTool.ts +88 -0
- package/ai/tools/readFileTool.ts +214 -0
- package/ai/tools/readTool.ts +194 -0
- package/ai/tools/readXPostTool.ts +229 -0
- package/ai/tools/readXhsProfileTool.ts +627 -0
- package/ai/tools/rememberMemoryTool.ts +84 -0
- package/ai/tools/remotionVideoTool.ts +151 -0
- package/ai/tools/searchDialogMessagesTool.ts +222 -0
- package/ai/tools/searchWorkspaceTool.ts +259 -0
- package/ai/tools/skillFollowup.ts +86 -0
- package/ai/tools/surfWeatherTool.ts +169 -0
- package/ai/tools/table/addTableRowTool.ts +217 -0
- package/ai/tools/table/createTableTool.ts +315 -0
- package/ai/tools/table/rowTools.ts +386 -0
- package/ai/tools/table/schemaTools.ts +244 -0
- package/ai/tools/table/shareTableTool.ts +148 -0
- package/ai/tools/table/toolShared.ts +129 -0
- package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
- package/ai/tools/toolApiClient.ts +279 -0
- package/ai/tools/toolResultError.ts +42 -0
- package/ai/tools/toolRunSlice.ts +303 -0
- package/ai/tools/toolSchemaCompatibility.ts +53 -0
- package/ai/tools/uiAskChoiceTool.ts +104 -0
- package/ai/tools/updateContentTitleTool.ts +84 -0
- package/ai/tools/updateDocTool.ts +105 -0
- package/ai/tools/updateUserPreferenceProfileTool.ts +153 -0
- package/ai/tools/wereadGatewayTool.ts +152 -0
- package/ai/tools/whisperTool.ts +76 -0
- package/ai/tools/writeFileTool.ts +213 -0
- package/ai/tools/youtubeScraperTool.ts +116 -0
- package/ai/tools/ziweiChartTool.ts +678 -0
- package/ai/types.ts +55 -0
- package/ai/workflow/workflowExecutor.ts +323 -0
- package/ai/workflow/workflowSlice.ts +73 -0
- package/ai/workflow/workflowTypes.ts +106 -0
- package/app/actions/syncAppRecord.ts +73 -0
- package/app/constants/animationSets.ts +21 -0
- package/app/constants/appEditor.ts +99 -0
- package/app/favorite/favoriteSlice.ts +690 -0
- package/app/favorite/type.ts +43 -0
- package/app/hooks/deleteDbKey.ts +233 -0
- package/app/i18n/client.ts +13 -0
- package/app/i18n/i18n.base.ts +14 -0
- package/app/i18n/i18n.config.ts +77 -0
- package/app/i18n/index.ts +15 -0
- package/app/i18n/mapLanguage.ts +11 -0
- package/app/i18n/translations/appBuilder.locale.ts +453 -0
- package/app/i18n/translations/error.locale.ts +246 -0
- package/app/i18n/translations/interface.locale.ts +2174 -0
- package/app/i18n/translations/pricing.locale.ts +397 -0
- package/app/i18n/translations/privacy.locale.ts +168 -0
- package/app/i18n/translations/seo.locale.ts +129 -0
- package/app/i18n/translations/terms.locale.ts +124 -0
- package/app/i18n/types.ts +6 -0
- package/app/notifications/model.ts +77 -0
- package/app/notifications/notificationSlice.ts +141 -0
- package/app/reducer.ts +36 -0
- package/app/settings/dbActionThunks.ts +34 -0
- package/app/settings/defaultSpacePreference.ts +87 -0
- package/app/settings/settingSlice.tsx +1212 -0
- package/app/settings/settingsRecord.ts +8 -0
- package/app/stateViews/runtime.ts +90 -0
- package/app/store.ts +55 -0
- package/app/theme/colors.ts +280 -0
- package/app/theme/fontPreference.ts +77 -0
- package/app/theme/theme.config.ts +120 -0
- package/app/theme/themeModeBootstrap.ts +123 -0
- package/app/types/appSummary.ts +114 -0
- package/app/types.ts +358 -0
- package/app/utils/appKeys.ts +55 -0
- package/app/utils/async.ts +28 -0
- package/app/utils/desktopAgentRuntimeTurnClient.ts +73 -0
- package/app/utils/env.ts +17 -0
- package/app/utils/fileUtils.ts +229 -0
- package/app/utils/imageUtils.ts +274 -0
- package/app/utils/myContentItems.ts +289 -0
- package/app/utils/retryAfter.ts +36 -0
- package/app/utils/retryFetch.ts +61 -0
- package/app/utils/toast.ts +3 -0
- package/auth/action/signUpAction.ts +227 -0
- package/auth/adminPermissions.ts +18 -0
- package/auth/authSlice.ts +531 -0
- package/auth/client/loginRequest.ts +14 -0
- package/auth/resetAuthScopedClientState.ts +27 -0
- package/auth/routes.ts +178 -0
- package/auth/token.ts +63 -0
- package/auth/types.ts +40 -0
- package/chat/chat.locale.ts +813 -0
- package/chat/dialog/actions/addCybotAction.ts +52 -0
- package/chat/dialog/actions/addReferenceKeysAction.ts +62 -0
- package/chat/dialog/actions/builtinDialogLlm.ts +35 -0
- package/chat/dialog/actions/cleanupCliSession.ts +40 -0
- package/chat/dialog/actions/createDialogAction.ts +379 -0
- package/chat/dialog/actions/createScheduledTaskAction.ts +78 -0
- package/chat/dialog/actions/handleSendMessageAction.ts +197 -0
- package/chat/dialog/actions/handleSendMessageResolver.ts +27 -0
- package/chat/dialog/actions/removeCybotAction.ts +6 -0
- package/chat/dialog/actions/removeDialogAgentAction.ts +44 -0
- package/chat/dialog/actions/replacePrimaryCybotAction.ts +6 -0
- package/chat/dialog/actions/setPrimaryDialogAgentAction.ts +52 -0
- package/chat/dialog/actions/updateDialogSummaryAction.ts +430 -0
- package/chat/dialog/actions/updateDialogTitleAction.ts +151 -0
- package/chat/dialog/actions/updateDialogTitlePolicy.ts +30 -0
- package/chat/dialog/actions/updateTokensAction.ts +233 -0
- package/chat/dialog/dialogAgents.ts +72 -0
- package/chat/dialog/dialogSlice.ts +872 -0
- package/chat/dialog/dialogTitle.ts +81 -0
- package/chat/dialog/dialogTokenStats.ts +12 -0
- package/chat/dialog/dialogUrl.ts +6 -0
- package/chat/dialog/goal.ts +108 -0
- package/chat/dialog/objectAssistantRegistry.ts +286 -0
- package/chat/dialog/schedule.ts +17 -0
- package/chat/messages/fetchAndCacheMessages.ts +119 -0
- package/chat/messages/fetchConvMsgs.ts +51 -0
- package/chat/messages/fileUrl.ts +13 -0
- package/chat/messages/messageAgent.ts +8 -0
- package/chat/messages/messageContent.ts +199 -0
- package/chat/messages/messageContract.ts +88 -0
- package/chat/messages/messageSlice.ts +1367 -0
- package/chat/messages/toolThunks.ts +625 -0
- package/cli/agentAliases.ts +2 -1
- package/cli/agentRunCommand.ts +10 -32
- package/cli/agentRuntimeLocal.ts +1 -0
- package/cli/client/agentRun.ts +67 -95
- package/cli/client/localRuntimeAdapter.ts +323 -54
- package/cli/commandRegistry.ts +2 -2
- package/cli/machineWsRunDispatch.ts +51 -6
- package/cli/offlineMarxistsAgentCommand.ts +6 -4
- package/client/agentConfigResolver.test.ts +2 -2
- package/client/agentRun.test.ts +175 -57
- package/client/agentRun.ts +67 -95
- package/client/localRuntimeAdapter.test.ts +682 -37
- package/client/localRuntimeAdapter.ts +323 -54
- package/client/localRuntimeDryRun.test.ts +23 -9
- package/client/localToolPolicy.test.ts +4 -4
- package/commandRegistry.ts +2 -2
- package/core/builtinAgents.ts +209 -0
- package/core/config.ts +15 -0
- package/core/crypto.ts +51 -0
- package/core/generateKeyPairFromSeedV1.ts +15 -0
- package/core/generateMainKey.ts +22 -0
- package/core/init.ts +41 -0
- package/core/localOrigins.ts +8 -0
- package/core/password.ts +13 -0
- package/core/prefix.ts +23 -0
- package/create/editor/transforms/fromMarkdown/index.ts +260 -0
- package/create/editor/transforms/fromMarkdown/inline.ts +285 -0
- package/create/editor/transforms/fromMarkdown/table.ts +130 -0
- package/create/editor/transforms/markdownToSlate.ts +24 -0
- package/create/editor/transforms/slateToRenderMarkdown.ts +218 -0
- package/create/editor/transforms/slateToSimplifiedMarkdown.ts +224 -0
- package/create/editor/transforms/slateToText.ts +33 -0
- package/create/editor/utils/slateUtils.ts +233 -0
- package/create/space/addSpaceAction.ts +193 -0
- package/create/space/category/categoryActions.ts +427 -0
- package/create/space/changeSpaceAction.ts +36 -0
- package/create/space/constants.ts +8 -0
- package/create/space/content/addContentAction.ts +116 -0
- package/create/space/content/contentThunks.ts +90 -0
- package/create/space/content/deleteContentFromSpaceAction.ts +187 -0
- package/create/space/content/deleteMultipleContentAction.ts +112 -0
- package/create/space/content/moveContentAction.ts +285 -0
- package/create/space/content/updateContentCategoryAction.ts +154 -0
- package/create/space/content/updateContentTitleAction.ts +151 -0
- package/create/space/content/uploadAndAddFileToSpaceAction.ts +98 -0
- package/create/space/contentKeyUtils.ts +117 -0
- package/create/space/deleteSpaceAction.ts +276 -0
- package/create/space/fetchSpaceAction.ts +70 -0
- package/create/space/fetchSpaceSidebarStateAction.ts +26 -0
- package/create/space/loadDefaultSpaceAction.ts +57 -0
- package/create/space/member/addMemberAction.ts +79 -0
- package/create/space/member/fetchUserSpaceMembershipsAction.ts +386 -0
- package/create/space/member/memberThunks.ts +47 -0
- package/create/space/member/removeMemberAction.ts +67 -0
- package/create/space/resolvePreferredSpaceId.ts +113 -0
- package/create/space/sidebarVisibleTypes.ts +241 -0
- package/create/space/space.locale.ts +1087 -0
- package/create/space/spaceAccess.ts +182 -0
- package/create/space/spaceCollapsedState.ts +54 -0
- package/create/space/spaceKeys.ts +65 -0
- package/create/space/spaceSlice.ts +328 -0
- package/create/space/spaceThunks.ts +410 -0
- package/create/space/types.ts +27 -0
- package/create/space/updateSpaceAction.ts +107 -0
- package/create/space/utils/permissions.ts +47 -0
- package/create/types.ts +21 -0
- package/database/actions/agentReadResolution.ts +33 -0
- package/database/actions/common.ts +243 -0
- package/database/actions/deleteFile.ts +40 -0
- package/database/actions/fileContent.ts +125 -0
- package/database/actions/patch.ts +155 -0
- package/database/actions/read.ts +358 -0
- package/database/actions/readAndWait.ts +260 -0
- package/database/actions/readRequestManager.ts +120 -0
- package/database/actions/readResolution.ts +125 -0
- package/database/actions/remove.ts +94 -0
- package/database/actions/replication.ts +477 -0
- package/database/actions/upload.ts +186 -0
- package/database/actions/upsert.ts +56 -0
- package/database/actions/write.ts +146 -0
- package/database/authority/ownerKey.ts +80 -0
- package/database/authority/recordAuthority.ts +67 -0
- package/database/authority/userAuthorityRegistry.ts +54 -0
- package/database/client/fetchUserData.ts +61 -0
- package/database/dbActionThunks.ts +1 -0
- package/database/dbSlice.ts +149 -0
- package/database/fileRing.ts +51 -0
- package/database/fileStorage.ts +232 -0
- package/database/fileUrl.ts +34 -0
- package/database/keys.ts +767 -0
- package/database/queryPrefixes.ts +14 -0
- package/database/requests.ts +443 -0
- package/database/runtimeServerContext.ts +54 -0
- package/database/server/levelAuthorityStore.ts +20 -1
- package/database/tenantPlacement.ts +57 -0
- package/database/userPreferenceRegister.ts +131 -0
- package/database/utils/ulid.ts +1 -0
- package/integrations/anthropic/anthropicModels.ts +47 -0
- package/integrations/deepseek/models.ts +37 -0
- package/integrations/google/models.ts +341 -0
- package/integrations/openai/chatCompletionStreamMode.ts +10 -0
- package/integrations/openai/filterAndCleanMessages.ts +284 -0
- package/integrations/openai/flexTier.ts +102 -0
- package/integrations/openai/generateOpenAIRequestBody.ts +274 -0
- package/integrations/openai/generateResponseRequestBody.ts +77 -0
- package/integrations/openai/models.ts +271 -0
- package/integrations/openai/providerBodyCompatibility.ts +23 -0
- package/integrations/openai/responsesHelpers.ts +297 -0
- package/integrations/x-reader/types.ts +109 -0
- package/integrations/xai/models.ts +13 -0
- package/integrations/xhs-reader/analyze/profileAnalyzer.ts +205 -0
- package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +624 -0
- package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +227 -0
- package/integrations/xhs-reader/client/xhsWebApiClient.ts +229 -0
- package/integrations/xhs-reader/normalize.ts +390 -0
- package/integrations/xhs-reader/orchestrator.ts +178 -0
- package/integrations/xhs-reader/redaction.ts +68 -0
- package/integrations/xhs-reader/types.ts +244 -0
- package/integrations/xhs-reader/url.ts +57 -0
- package/machineWsRunDispatch.ts +51 -6
- package/offlineMarxistsAgentCommand.ts +6 -4
- package/package.json +430 -3
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +468 -0
- package/render/page/types.ts +17 -0
- package/render/table/createTableAction.ts +270 -0
- package/render/table/deleteTableAction.ts +193 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1106 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +252 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/server/handlers/agentRun/types.ts +104 -0
- package/share/action.ts +225 -0
- package/share/helpers.ts +302 -0
- package/share/keys.ts +243 -0
- package/share/publicSharePolicy.ts +27 -0
- package/share/shareSlice.ts +53 -0
- package/share/types.ts +100 -0
package/ai/agent/cliExecutor.ts
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
import { exec, execSync, spawn } from "child_process";
|
|
17
17
|
import { randomUUID } from "node:crypto";
|
|
18
|
-
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
19
|
-
import { join } from "node:path";
|
|
18
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
20
20
|
import { tmpdir } from "node:os";
|
|
21
21
|
import { resolveLaunchableCodexCommand } from "../../connector-experimental/codexBinary";
|
|
22
22
|
import { buildCliPrompt } from "./cliPrompt";
|
|
@@ -26,9 +26,22 @@ import { buildCliPrompt } from "./cliPrompt";
|
|
|
26
26
|
/** 已支持的 CLI 工具。新增时在此联合类型追加,并在 EXECUTORS 里注册实现 */
|
|
27
27
|
export type CliProvider = "copilot" | "gemini" | "codex" | "claude" | "agy";
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* CLI provider 图片输入。
|
|
31
|
+
*
|
|
32
|
+
* - `source` 是原始输入(本地路径 / data URL / http URL / file URL)
|
|
33
|
+
* - `materializedPath` 是 materialize 后写入磁盘的绝对路径
|
|
34
|
+
* (本地路径保持不变,data URL 写入临时文件,file URL 转换为本地路径)
|
|
35
|
+
* - HTTP/HTTPS URL 目前无法原生传给 CLI,只作为 prompt 引用保留
|
|
36
|
+
*/
|
|
37
|
+
export interface CliImageInput {
|
|
38
|
+
source: string;
|
|
39
|
+
materializedPath?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
export interface CliExecuteOptions {
|
|
30
43
|
model?: string;
|
|
31
|
-
timeout?: number; // ms
|
|
44
|
+
timeout?: number; // ms;各 CLI executor 可按任务类型设置自己的默认值
|
|
32
45
|
cwd?: string;
|
|
33
46
|
env?: Record<string, string | undefined>;
|
|
34
47
|
yolo?: boolean; // 允许所有工具,默认 true(后台任务常用)
|
|
@@ -41,6 +54,8 @@ export interface CliExecuteOptions {
|
|
|
41
54
|
maxTokens?: number;
|
|
42
55
|
enableThinking?: boolean;
|
|
43
56
|
thinkingBudget?: number;
|
|
57
|
+
/** 图片输入(本地路径 / data URL / file URL)。materialize 由内部处理。 */
|
|
58
|
+
imageInputs?: CliImageInput[];
|
|
44
59
|
}
|
|
45
60
|
|
|
46
61
|
export interface CliExecuteResult {
|
|
@@ -55,6 +70,8 @@ type CliSessionMessage = {
|
|
|
55
70
|
content: string;
|
|
56
71
|
};
|
|
57
72
|
|
|
73
|
+
const DEFAULT_AGY_TIMEOUT_MS = 600_000;
|
|
74
|
+
|
|
58
75
|
export interface CliSessionHandle {
|
|
59
76
|
sessionId: string;
|
|
60
77
|
provider: CliProvider;
|
|
@@ -184,6 +201,138 @@ function shouldPassClaudeModel(options: CliExecuteOptions): boolean {
|
|
|
184
201
|
return (options.env?.NOLO_CLAUDE_CLI_ALLOW_MODEL ?? process.env.NOLO_CLAUDE_CLI_ALLOW_MODEL) === "1";
|
|
185
202
|
}
|
|
186
203
|
|
|
204
|
+
// ── CLI 图片 materialize ─────────────────────────────────────────────────────
|
|
205
|
+
|
|
206
|
+
const DATA_URL_RE = /^data:image\/([\w.+-]+);base64,([A-Za-z0-9+/=]+)$/;
|
|
207
|
+
|
|
208
|
+
/** data URL extension (without prefix) → 完整扩展名 */
|
|
209
|
+
const MIME_EXT: Record<string, string> = {
|
|
210
|
+
"png": ".png",
|
|
211
|
+
"jpeg": ".jpg",
|
|
212
|
+
"jpg": ".jpg",
|
|
213
|
+
"gif": ".gif",
|
|
214
|
+
"webp": ".webp",
|
|
215
|
+
"svg+xml": ".svg",
|
|
216
|
+
"bmp": ".bmp",
|
|
217
|
+
"tiff": ".tiff",
|
|
218
|
+
"avif": ".avif",
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
function inferExtFromMime(extPart: string): string {
|
|
222
|
+
return MIME_EXT[extPart.toLowerCase().trim()] ?? ".bin";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const FILE_URL_RE = /^file:\/\/(.+)$/;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* 将单个 data URL 图片写入临时文件,返回绝对路径。
|
|
229
|
+
* caller 负责在执行完后清理 tempDir。
|
|
230
|
+
*/
|
|
231
|
+
function writeDataUrlToTempImage(dataUrl: string, tempDir: string, index: number): string {
|
|
232
|
+
const match = dataUrl.match(DATA_URL_RE);
|
|
233
|
+
if (!match) {
|
|
234
|
+
throw new Error(`Invalid data URL format for image #${index + 1}; expected data:image/<type>;base64,<data>`);
|
|
235
|
+
}
|
|
236
|
+
const [, mimeExt, b64] = match;
|
|
237
|
+
const ext = inferExtFromMime(mimeExt);
|
|
238
|
+
const filePath = join(tempDir, `image-${index + 1}${ext}`);
|
|
239
|
+
writeFileSync(filePath, Buffer.from(b64, "base64"));
|
|
240
|
+
return filePath;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Materialize image input sources into on-disk paths where possible.
|
|
245
|
+
*
|
|
246
|
+
* - 本地 path / file URL → 解析为绝对路径,无需写临时文件
|
|
247
|
+
* - data:image/...;base64,... → 写入 tempDir 内临时文件
|
|
248
|
+
* - http(s) URL → 不做下载,保留 source 引用;materializedPath 为空
|
|
249
|
+
*
|
|
250
|
+
* 返回 `{ materialized, tempDir }`,caller 需在执行完成后 `rmSync(tempDir, { recursive: true, force: true })`。
|
|
251
|
+
* 当没有任何 data URL 时 tempDir 不会被创建,返回 null。
|
|
252
|
+
*/
|
|
253
|
+
export function materializeCliImageInputs(
|
|
254
|
+
imageInputs: CliImageInput[],
|
|
255
|
+
cwd: string,
|
|
256
|
+
): { materialized: CliImageInput[]; tempDir: string | null } {
|
|
257
|
+
let tempDir: string | null = null;
|
|
258
|
+
const materialized = imageInputs.map((input, index) => {
|
|
259
|
+
const src = input.source.trim();
|
|
260
|
+
|
|
261
|
+
if (src.startsWith("http://") || src.startsWith("https://")) {
|
|
262
|
+
return { ...input, materializedPath: undefined };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const fileUrlMatch = src.match(FILE_URL_RE);
|
|
266
|
+
if (fileUrlMatch) {
|
|
267
|
+
const localPath = fileUrlMatch[1];
|
|
268
|
+
return {
|
|
269
|
+
...input,
|
|
270
|
+
materializedPath: isAbsolute(localPath) ? localPath : resolve(cwd, localPath),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (src.startsWith("data:")) {
|
|
275
|
+
if (!tempDir) {
|
|
276
|
+
tempDir = mkdtempSync(join(tmpdir(), "nolo-cli-assets-"));
|
|
277
|
+
}
|
|
278
|
+
const filePath = writeDataUrlToTempImage(src, tempDir, index);
|
|
279
|
+
return { ...input, materializedPath: filePath };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// 本地路径
|
|
283
|
+
return {
|
|
284
|
+
...input,
|
|
285
|
+
materializedPath: isAbsolute(src) ? src : resolve(cwd, src),
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
return { materialized, tempDir };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* 根据 provider 构建图片降级 prompt 块。
|
|
294
|
+
* Codex 使用原生 `-i` 标志,无需注入 prompt。
|
|
295
|
+
* 其他 provider 使用此函数将图片路径列表注入到 prompt 前面。
|
|
296
|
+
*/
|
|
297
|
+
function buildImageReferencePromptBlock(
|
|
298
|
+
provider: CliProvider,
|
|
299
|
+
materialized: CliImageInput[],
|
|
300
|
+
): { promptSuffix: string; warning: string | null } {
|
|
301
|
+
const label = getCliProviderLabel(provider);
|
|
302
|
+
const localPaths = materialized
|
|
303
|
+
.filter((img) => img.materializedPath)
|
|
304
|
+
.map((img) => img.materializedPath!);
|
|
305
|
+
const httpUrls = materialized
|
|
306
|
+
.filter((img) => !img.materializedPath)
|
|
307
|
+
.map((img) => img.source);
|
|
308
|
+
|
|
309
|
+
const lines: string[] = [];
|
|
310
|
+
if (localPaths.length > 0) {
|
|
311
|
+
lines.push(
|
|
312
|
+
`[User attached image(s) - local file references (accessible at these paths):]`,
|
|
313
|
+
...localPaths.map((p) => ` - ${p}`),
|
|
314
|
+
`Please read and analyze these image files as part of the user's request.`,
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
if (httpUrls.length > 0) {
|
|
318
|
+
lines.push(
|
|
319
|
+
`[User attached image(s) - remote URLs (content not available locally):]`,
|
|
320
|
+
...httpUrls.map((u) => ` - ${u}`),
|
|
321
|
+
`These remote URLs could not be downloaded automatically. If you cannot access them, describe what you can infer from context.`,
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const warning =
|
|
326
|
+
materialized.length > 0
|
|
327
|
+
? `${label} image input is passed as local file references; native image flags are not available in this wrapper.`
|
|
328
|
+
: null;
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
promptSuffix: lines.length > 0 ? lines.join("\n") + "\n\n" : "",
|
|
332
|
+
warning,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
187
336
|
function collectCliCapabilityWarnings(
|
|
188
337
|
provider: CliProvider,
|
|
189
338
|
options: CliExecuteOptions
|
|
@@ -226,18 +375,51 @@ function resolveCliExecution(
|
|
|
226
375
|
provider: CliProvider,
|
|
227
376
|
prompt: string,
|
|
228
377
|
options: CliExecuteOptions
|
|
229
|
-
): { prompt: string; options: CliExecuteOptions; warnings: string[] } {
|
|
378
|
+
): { prompt: string; options: CliExecuteOptions; warnings: string[]; imageTempDir?: string } {
|
|
230
379
|
const warnings = collectCliCapabilityWarnings(provider, options);
|
|
380
|
+
|
|
381
|
+
// Handle image inputs
|
|
382
|
+
const imageInputs = options.imageInputs ?? [];
|
|
383
|
+
let resolvedPrompt = prompt;
|
|
384
|
+
let resolvedOptions = options;
|
|
385
|
+
let imageTempDir: string | undefined;
|
|
386
|
+
|
|
387
|
+
if (imageInputs.length > 0) {
|
|
388
|
+
const { materialized, tempDir } = materializeCliImageInputs(
|
|
389
|
+
imageInputs,
|
|
390
|
+
options.cwd ?? process.cwd(),
|
|
391
|
+
);
|
|
392
|
+
imageTempDir = tempDir ?? undefined;
|
|
393
|
+
|
|
394
|
+
if (provider === "codex") {
|
|
395
|
+
// Codex uses native -i flags; update options with materialized imageInputs
|
|
396
|
+
resolvedOptions = {
|
|
397
|
+
...resolvedOptions,
|
|
398
|
+
imageInputs: materialized,
|
|
399
|
+
};
|
|
400
|
+
} else {
|
|
401
|
+
// Non-codex providers: inject image references into prompt
|
|
402
|
+
const block = buildImageReferencePromptBlock(provider, materialized);
|
|
403
|
+
if (block.promptSuffix) {
|
|
404
|
+
resolvedPrompt = block.promptSuffix + resolvedPrompt;
|
|
405
|
+
}
|
|
406
|
+
if (block.warning) {
|
|
407
|
+
warnings.push(block.warning);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
231
412
|
if (supportsNativeSystemPrompt(provider) || !options.systemPrompt?.trim()) {
|
|
232
|
-
return { prompt, options, warnings };
|
|
413
|
+
return { prompt: resolvedPrompt, options: resolvedOptions, warnings, imageTempDir };
|
|
233
414
|
}
|
|
234
415
|
return {
|
|
235
|
-
prompt: buildCliPrompt(options.systemPrompt,
|
|
416
|
+
prompt: buildCliPrompt(options.systemPrompt, resolvedPrompt),
|
|
236
417
|
options: {
|
|
237
|
-
...
|
|
418
|
+
...resolvedOptions,
|
|
238
419
|
systemPrompt: undefined,
|
|
239
420
|
},
|
|
240
421
|
warnings,
|
|
422
|
+
imageTempDir,
|
|
241
423
|
};
|
|
242
424
|
}
|
|
243
425
|
|
|
@@ -410,6 +592,11 @@ function executeCodex(
|
|
|
410
592
|
yolo = true,
|
|
411
593
|
} = options;
|
|
412
594
|
|
|
595
|
+
// Collect materialized image paths from imageInputs
|
|
596
|
+
const imagePaths = (options.imageInputs ?? [])
|
|
597
|
+
.map((img) => img.materializedPath)
|
|
598
|
+
.filter((p): p is string => Boolean(p));
|
|
599
|
+
|
|
413
600
|
return new Promise((resolve, reject) => {
|
|
414
601
|
const tempDir = mkdtempSync(join(tmpdir(), "codex-exec-"));
|
|
415
602
|
const outputFile = join(tempDir, "last-message.txt");
|
|
@@ -429,6 +616,10 @@ function executeCodex(
|
|
|
429
616
|
args.push("--sandbox");
|
|
430
617
|
args.push("danger-full-access");
|
|
431
618
|
}
|
|
619
|
+
// Add image flags for Codex CLI native image support
|
|
620
|
+
for (const imgPath of imagePaths) {
|
|
621
|
+
args.push("-i", imgPath);
|
|
622
|
+
}
|
|
432
623
|
const start = Date.now();
|
|
433
624
|
const proc = spawn(executable, [...args, prompt], {
|
|
434
625
|
cwd,
|
|
@@ -569,12 +760,49 @@ function formatCliTimeout(timeoutMs: number) {
|
|
|
569
760
|
return `${Math.max(1, Math.ceil(timeoutMs / 1000))}s`;
|
|
570
761
|
}
|
|
571
762
|
|
|
763
|
+
function tailText(value: string, maxChars = 1200): string {
|
|
764
|
+
if (value.length <= maxChars) return value;
|
|
765
|
+
return value.slice(value.length - maxChars);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function terminateCliProcessGroup(
|
|
769
|
+
proc: ReturnType<typeof spawn>,
|
|
770
|
+
signal: NodeJS.Signals
|
|
771
|
+
) {
|
|
772
|
+
const pid = typeof proc.pid === "number" ? proc.pid : 0;
|
|
773
|
+
if (pid > 0 && process.platform !== "win32") {
|
|
774
|
+
try {
|
|
775
|
+
process.kill(-pid, signal);
|
|
776
|
+
return;
|
|
777
|
+
} catch {
|
|
778
|
+
// Fall back to the child process if the group is unavailable.
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
try {
|
|
782
|
+
proc.kill(signal);
|
|
783
|
+
} catch {
|
|
784
|
+
// Best effort cleanup only.
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function buildAgyTimeoutError(timeout: number, stdout: string, stderr: string) {
|
|
789
|
+
const parts = [
|
|
790
|
+
`Antigravity CLI timed out after ${timeout}ms.`,
|
|
791
|
+
"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.",
|
|
792
|
+
];
|
|
793
|
+
const stdoutTail = tailText(stdout).trim();
|
|
794
|
+
const stderrTail = tailText(stderr).trim();
|
|
795
|
+
if (stdoutTail) parts.push(`stdout tail:\n${stdoutTail}`);
|
|
796
|
+
if (stderrTail) parts.push(`stderr tail:\n${stderrTail}`);
|
|
797
|
+
return new Error(parts.join("\n"));
|
|
798
|
+
}
|
|
799
|
+
|
|
572
800
|
function executeAgy(
|
|
573
801
|
prompt: string,
|
|
574
802
|
options: CliExecuteOptions
|
|
575
803
|
): Promise<CliExecuteResult> {
|
|
576
804
|
const {
|
|
577
|
-
timeout =
|
|
805
|
+
timeout = DEFAULT_AGY_TIMEOUT_MS,
|
|
578
806
|
cwd = process.cwd(),
|
|
579
807
|
yolo = true,
|
|
580
808
|
} = options;
|
|
@@ -597,15 +825,28 @@ function executeAgy(
|
|
|
597
825
|
cwd,
|
|
598
826
|
env: buildCliProcessEnv(options.env),
|
|
599
827
|
stdio: ["ignore", "pipe", "pipe"],
|
|
828
|
+
detached: process.platform !== "win32",
|
|
600
829
|
});
|
|
601
830
|
let stdout = "";
|
|
602
831
|
let stderr = "";
|
|
603
832
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
833
|
+
let forceTimer: ReturnType<typeof setTimeout> | undefined;
|
|
834
|
+
let settled = false;
|
|
835
|
+
|
|
836
|
+
const clearTimers = () => {
|
|
837
|
+
if (timer) clearTimeout(timer);
|
|
838
|
+
if (forceTimer) clearTimeout(forceTimer);
|
|
839
|
+
};
|
|
604
840
|
|
|
605
841
|
if (timeout > 0) {
|
|
606
842
|
timer = setTimeout(() => {
|
|
607
|
-
|
|
608
|
-
|
|
843
|
+
if (settled) return;
|
|
844
|
+
settled = true;
|
|
845
|
+
terminateCliProcessGroup(proc, "SIGTERM");
|
|
846
|
+
forceTimer = setTimeout(() => {
|
|
847
|
+
terminateCliProcessGroup(proc, "SIGKILL");
|
|
848
|
+
}, 3_000);
|
|
849
|
+
reject(buildAgyTimeoutError(timeout, stdout, stderr));
|
|
609
850
|
}, timeout + 1_000);
|
|
610
851
|
}
|
|
611
852
|
|
|
@@ -618,7 +859,12 @@ function executeAgy(
|
|
|
618
859
|
});
|
|
619
860
|
|
|
620
861
|
proc.on("close", (code) => {
|
|
621
|
-
if (
|
|
862
|
+
if (settled) {
|
|
863
|
+
clearTimers();
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
settled = true;
|
|
867
|
+
clearTimers();
|
|
622
868
|
if (code !== 0 && code !== null) {
|
|
623
869
|
reject(new Error(`Antigravity CLI exited with code ${code}\nstderr: ${stderr}`));
|
|
624
870
|
return;
|
|
@@ -632,7 +878,9 @@ function executeAgy(
|
|
|
632
878
|
});
|
|
633
879
|
|
|
634
880
|
proc.on("error", (err) => {
|
|
635
|
-
if (
|
|
881
|
+
if (settled) return;
|
|
882
|
+
settled = true;
|
|
883
|
+
clearTimers();
|
|
636
884
|
reject(err);
|
|
637
885
|
});
|
|
638
886
|
});
|
|
@@ -699,11 +947,17 @@ export async function executeCli(
|
|
|
699
947
|
throw new Error(`Unknown CLI provider: "${provider}". Supported: ${Object.keys(EXECUTORS).join(", ")}`);
|
|
700
948
|
}
|
|
701
949
|
const resolved = resolveCliExecution(provider, prompt, options);
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
950
|
+
try {
|
|
951
|
+
const result = await executor(resolved.prompt, resolved.options);
|
|
952
|
+
return {
|
|
953
|
+
...result,
|
|
954
|
+
warnings: [...resolved.warnings, ...(result.warnings ?? [])],
|
|
955
|
+
};
|
|
956
|
+
} finally {
|
|
957
|
+
if (resolved.imageTempDir) {
|
|
958
|
+
rmSync(resolved.imageTempDir, { recursive: true, force: true });
|
|
959
|
+
}
|
|
960
|
+
}
|
|
707
961
|
}
|
|
708
962
|
|
|
709
963
|
export { buildCliPrompt };
|
|
@@ -831,36 +1085,56 @@ export function executeCliStreaming(
|
|
|
831
1085
|
): Promise<CliExecuteResult> {
|
|
832
1086
|
const resolved = resolveCliExecution(provider, prompt, options);
|
|
833
1087
|
const executor = EXECUTORS[provider];
|
|
1088
|
+
|
|
1089
|
+
const cleanupImageTempDir = () => {
|
|
1090
|
+
if (resolved.imageTempDir) {
|
|
1091
|
+
rmSync(resolved.imageTempDir, { recursive: true, force: true });
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
const withCleanup = <T>(promise: Promise<T>): Promise<T> =>
|
|
1096
|
+
promise.finally(cleanupImageTempDir);
|
|
1097
|
+
|
|
834
1098
|
if (provider === "gemini") {
|
|
835
|
-
return
|
|
836
|
-
.
|
|
1099
|
+
return withCleanup(
|
|
1100
|
+
executeGeminiStreaming(resolved.prompt, resolved.options as CliExecuteOptions & { onChunk: (chunk: string) => void })
|
|
1101
|
+
.then((result) => ({ ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] }))
|
|
1102
|
+
);
|
|
837
1103
|
}
|
|
838
1104
|
if (provider === "codex") {
|
|
839
|
-
return
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1105
|
+
return withCleanup(
|
|
1106
|
+
executor(resolved.prompt, resolved.options).then((result) => {
|
|
1107
|
+
const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
|
|
1108
|
+
if (merged.text) options.onChunk(merged.text);
|
|
1109
|
+
return merged;
|
|
1110
|
+
})
|
|
1111
|
+
);
|
|
844
1112
|
}
|
|
845
1113
|
if (provider === "claude") {
|
|
846
|
-
return
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
1114
|
+
return withCleanup(
|
|
1115
|
+
executor(resolved.prompt, resolved.options).then((result) => {
|
|
1116
|
+
const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
|
|
1117
|
+
if (merged.text) options.onChunk(merged.text);
|
|
1118
|
+
return merged;
|
|
1119
|
+
})
|
|
1120
|
+
);
|
|
851
1121
|
}
|
|
852
1122
|
if (provider === "agy") {
|
|
853
|
-
return
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1123
|
+
return withCleanup(
|
|
1124
|
+
executor(resolved.prompt, resolved.options).then((result) => {
|
|
1125
|
+
const merged = { ...result, warnings: [...resolved.warnings, ...(result.warnings ?? [])] };
|
|
1126
|
+
if (merged.text) options.onChunk(merged.text);
|
|
1127
|
+
return merged;
|
|
1128
|
+
})
|
|
1129
|
+
);
|
|
858
1130
|
}
|
|
859
1131
|
if (provider !== "copilot") {
|
|
860
|
-
return
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
1132
|
+
return withCleanup(
|
|
1133
|
+
executor(resolved.prompt, resolved.options).then((result) => ({
|
|
1134
|
+
...result,
|
|
1135
|
+
warnings: [...resolved.warnings, ...(result.warnings ?? [])],
|
|
1136
|
+
}))
|
|
1137
|
+
);
|
|
864
1138
|
}
|
|
865
1139
|
|
|
866
1140
|
const {
|
|
@@ -871,7 +1145,7 @@ export function executeCliStreaming(
|
|
|
871
1145
|
onChunk,
|
|
872
1146
|
} = resolved.options as CliExecuteOptions & { onChunk: (chunk: string) => void };
|
|
873
1147
|
|
|
874
|
-
return new Promise((resolve, reject) => {
|
|
1148
|
+
return withCleanup(new Promise<CliExecuteResult>((resolve, reject) => {
|
|
875
1149
|
const args = [
|
|
876
1150
|
"copilot", "--",
|
|
877
1151
|
"-p", resolved.prompt,
|
|
@@ -931,7 +1205,7 @@ export function executeCliStreaming(
|
|
|
931
1205
|
if (timer) clearTimeout(timer);
|
|
932
1206
|
reject(err);
|
|
933
1207
|
});
|
|
934
|
-
});
|
|
1208
|
+
}));
|
|
935
1209
|
}
|
|
936
1210
|
|
|
937
1211
|
function executeGeminiStreaming(
|
|
@@ -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
|
+
};
|