From 1ab19190e9bd2f5bb5c40c8ba58fc121da6b4941 Mon Sep 17 00:00:00 2001 From: Haozhe Date: Tue, 18 Aug 2026 00:30:49 +0800 Subject: [PATCH] refactor(agent-core-v2): strip comments from agent-core-v2, kap-server, and transcript (#3010) --- .agents/skills/agent-core-dev/SKILL.md | 2 +- .agents/skills/agent-core-dev/orient.md | 39 +- .agents/skills/agent-core-dev/server-align.md | 4 +- .../agent-core-dev/service-authoring.md | 7 +- .agents/skills/agent-core-dev/verify.md | 2 +- AGENTS.md | 1 + package.json | 2 +- packages/agent-core-v2/AGENTS.md | 23 +- packages/agent-core-v2/docs/features.md | 2 +- .../scripts/gen-config-manifest.mts | 64 --- .../scripts/gen-state-manifest.mts | 131 ------ .../scripts/gen-wire-manifest.mts | 145 +----- .../agent-core-v2/scripts/lib/jsonSchema.mts | 11 - .../src/_base/asyncEventQueue.ts | 14 - .../src/_base/contribution/registry.ts | 17 - .../src/_base/di/cascadeEngine.ts | 66 --- .../agent-core-v2/src/_base/di/collection.ts | 24 - .../src/_base/di/dependencyGraph.ts | 18 - .../agent-core-v2/src/_base/di/descriptors.ts | 7 - packages/agent-core-v2/src/_base/di/errors.ts | 6 - packages/agent-core-v2/src/_base/di/fiber.ts | 53 --- packages/agent-core-v2/src/_base/di/graph.ts | 4 - .../src/_base/di/instantiation.ts | 24 - .../src/_base/di/instantiationService.ts | 31 -- .../agent-core-v2/src/_base/di/lifecycle.ts | 7 - packages/agent-core-v2/src/_base/di/scope.ts | 13 - .../agent-core-v2/src/_base/di/scopeUnits.ts | 29 -- .../agent-core-v2/src/_base/di/service.ts | 28 -- .../src/_base/di/serviceCollection.ts | 17 - packages/agent-core-v2/src/_base/di/test.ts | 4 - .../src/_base/di/testInstantiationService.ts | 24 - .../src/_base/di/util/linkedList.ts | 4 - .../agent-core-v2/src/_base/errors/codes.ts | 9 - .../src/_base/errors/errorMessage.ts | 4 - .../agent-core-v2/src/_base/errors/errors.ts | 5 - .../src/_base/errors/serialize.ts | 10 - .../src/_base/errors/unexpectedError.ts | 7 - packages/agent-core-v2/src/_base/event.ts | 12 - .../src/_base/execEnv/bufferedReadable.ts | 9 - .../src/_base/execEnv/decodeText.ts | 9 - .../src/_base/execEnv/environmentProbe.ts | 19 - .../src/_base/execEnv/globPattern.ts | 12 - .../src/_base/execEnv/loginShellPath.ts | 23 - .../src/_base/lifecycle/disposer.ts | 10 - .../src/_base/lifecycle/errors.ts | 4 - .../src/_base/lifecycle/ledger.ts | 12 - .../src/_base/lifecycle/lifecycleMachine.ts | 8 - .../agent-core-v2/src/_base/log/fileLog.ts | 16 - .../agent-core-v2/src/_base/log/formatter.ts | 9 - packages/agent-core-v2/src/_base/log/log.ts | 12 - .../agent-core-v2/src/_base/log/logConfig.ts | 8 - .../agent-core-v2/src/_base/log/logService.ts | 11 - .../src/_base/state/stateRegistry.ts | 37 -- .../agent-core-v2/src/_base/text/encoding.ts | 34 -- .../src/_base/text/frontmatter.ts | 9 - .../src/_base/text/line-endings.ts | 7 - .../agent-core-v2/src/_base/utils/abort.ts | 5 - .../src/_base/utils/canonical-args.ts | 4 - packages/agent-core-v2/src/_base/utils/env.ts | 4 - .../agent-core-v2/src/_base/utils/fileMeta.ts | 11 - packages/agent-core-v2/src/_base/utils/fs.ts | 5 - .../src/_base/utils/hero-slug.ts | 4 - .../agent-core-v2/src/_base/utils/paths.ts | 9 - .../agent-core-v2/src/_base/utils/promise.ts | 8 - .../agent-core-v2/src/_base/utils/proxy.ts | 5 - .../src/_base/utils/render-prompt.ts | 12 - .../agent-core-v2/src/_base/utils/retry.ts | 7 - .../agent-core-v2/src/_base/utils/timer.ts | 17 - .../src/_base/utils/typeEquality.ts | 17 - .../agent-core-v2/src/_base/utils/types.ts | 4 - .../src/_base/utils/workdir-slug.ts | 12 - .../src/_base/utils/xml-escape.ts | 4 - packages/agent-core-v2/src/_base/version.ts | 4 - .../src/agent/activityView/activityView.ts | 15 - .../agent/activityView/activityViewService.ts | 21 - .../agentsMdReminder/agentsMdReminder.ts | 11 - .../agentsMdReminderService.ts | 13 - .../src/agent/agentsMdReminder/bashTargets.ts | 23 - .../src/agent/blob/agentBlobService.ts | 7 - .../src/agent/blob/agentBlobServiceImpl.ts | 9 - .../src/agent/blob/byteLruCache.ts | 13 - .../src/agent/command/agentCommand.ts | 9 - .../src/agent/command/agentCommandService.ts | 12 - .../src/agent/command/commandContribution.ts | 12 - .../contextInjector/contextInjectorService.ts | 15 - .../agent/contextMemory/compactionHandoff.ts | 11 - .../src/agent/contextMemory/contextEvents.ts | 14 - .../contextMemory/contextMemoryService.ts | 16 - .../src/agent/contextMemory/contextOps.ts | 36 -- .../agent/contextMemory/contextTranscript.ts | 7 - .../agent/contextMemory/conversationTime.ts | 15 - .../conversationUndoParticipants.ts | 7 - .../src/agent/contextMemory/loopEventFold.ts | 42 -- .../src/agent/contextMemory/messageId.ts | 13 - .../agent/contextMemory/toolResultRender.ts | 9 - .../src/agent/contextMemory/vacuousContent.ts | 9 - .../contextProjector/contextProjector.ts | 16 - .../contextProjectorService.ts | 14 - .../agent/contextProjector/mediaProjection.ts | 12 - .../src/agent/contextProjector/projection.ts | 20 - .../src/agent/externalHooks/configSection.ts | 9 - .../src/agent/externalHooks/externalHooks.ts | 9 - .../externalHooks/externalHooksService.ts | 24 - .../src/agent/fullCompaction/compactionOps.ts | 37 -- .../src/agent/fullCompaction/errors.ts | 4 - .../fullCompaction/fullCompactionService.ts | 20 - .../agent-core-v2/src/agent/goal/errors.ts | 4 - packages/agent-core-v2/src/agent/goal/goal.ts | 7 - .../src/agent/goal/goalDeadlineScheduler.ts | 7 - .../goal/goalDeadlineSchedulerService.ts | 7 - .../agent-core-v2/src/agent/goal/goalOps.ts | 31 -- .../src/agent/goal/goalService.ts | 42 -- .../agent-core-v2/src/agent/goal/types.ts | 4 - .../interruptionReminder.ts | 7 - .../interruptionReminderOps.ts | 11 - .../interruptionReminderService.ts | 8 - .../src/agent/llmRequester/llmRequestOps.ts | 10 - .../agent/llmRequester/llmRequesterService.ts | 40 -- .../llmRequester/toolCallIdNormalizer.ts | 15 - .../src/agent/loop/configSection.ts | 22 - .../agent-core-v2/src/agent/loop/errors.ts | 7 - .../src/agent/loop/loopContinuationService.ts | 15 - .../src/agent/loop/loopService.ts | 34 -- .../src/agent/loop/stepRequest.ts | 15 - .../src/agent/loop/stepRequestQueue.ts | 15 - .../src/agent/loop/turnEvents.ts | 19 - .../agent-core-v2/src/agent/loop/turnOps.ts | 22 - .../src/agent/mcp/mcpDiscoveryOps.ts | 11 - .../agent-core-v2/src/agent/mcp/mcpEvents.ts | 10 - .../agent-core-v2/src/agent/mcp/mcpService.ts | 29 -- .../agent-core-v2/src/agent/mcp/output.ts | 42 -- .../agent-core-v2/src/agent/mcp/tools/auth.ts | 26 -- .../agent-core-v2/src/agent/mcp/tools/mcp.ts | 29 -- .../src/agent/media/configSection.ts | 16 - .../src/agent/media/file-type.ts | 8 - .../src/agent/media/image-compress.ts | 40 -- .../src/agent/media/image-format-policy.ts | 29 -- .../src/agent/media/image-originals.ts | 27 -- .../src/agent/media/imageConfigBridge.ts | 20 - .../src/agent/media/kimiFileUrl.ts | 9 - .../agent-core-v2/src/agent/media/mediaRef.ts | 49 -- .../src/agent/media/mediaResolver.ts | 15 - .../src/agent/media/mediaResolverService.ts | 88 ---- .../src/agent/media/mediaTools.ts | 7 - .../src/agent/media/mediaToolsRegistrar.ts | 36 -- .../src/agent/media/promptMediaIntake.ts | 20 - .../src/agent/media/registerMediaTools.ts | 12 - .../src/agent/media/sessionMediaStore.ts | 9 - .../agent/media/sessionMediaStoreService.ts | 15 - .../src/agent/media/videoResolver.ts | 9 - .../src/agent/media/videoResolverService.ts | 25 - .../src/agent/media/videoUpload.ts | 9 - .../src/agent/media/webp-dec-wasm.ts | 4 - .../src/agent/media/webp-decode.ts | 20 - .../permissionGate/permissionGateService.ts | 13 - .../src/agent/permissionMode/configSection.ts | 13 - .../injection/permissionModeInjection.ts | 12 - .../agent/permissionMode/permissionModeOps.ts | 12 - .../permissionMode/permissionModeService.ts | 16 - .../permissionPolicyService.ts | 9 - .../agent/permissionRules/configSection.ts | 12 - .../permissionRules/permissionRulesOps.ts | 20 - .../permissionRules/permissionRulesService.ts | 11 - .../src/agent/plugin/agentPlugin.ts | 7 - .../src/agent/plugin/agentPluginOps.ts | 10 - .../src/agent/plugin/agentPluginService.ts | 37 -- .../src/agent/pluginCommand/pluginCommand.ts | 11 - .../pluginCommand/pluginCommandService.ts | 11 - .../src/agent/profile/context.ts | 29 -- .../agent-core-v2/src/agent/profile/errors.ts | 4 - .../src/agent/profile/profile.ts | 17 - .../src/agent/profile/profileOps.ts | 48 -- .../src/agent/profile/profileService.ts | 108 ----- .../agent-core-v2/src/agent/prompt/errors.ts | 4 - .../src/agent/prompt/promptMetadataText.ts | 10 - .../src/agent/prompt/promptOps.ts | 1 - .../src/agent/prompt/promptService.ts | 33 -- .../src/agent/prompt/promptStepRequests.ts | 19 - .../agent/runtimeBinding/runtimeBindingOps.ts | 1 - .../src/agent/scopeContext/scopeContext.ts | 12 - .../src/agent/shellCommand/shellCommand.ts | 9 - .../agent/shellCommand/shellCommandService.ts | 24 - .../agent-core-v2/src/agent/skill/skill.ts | 15 - .../agent-core-v2/src/agent/skill/skillOps.ts | 15 - .../src/agent/skill/skillService.ts | 20 - .../src/agent/state/agentState.ts | 15 - .../src/agent/state/agentStateService.ts | 22 - .../src/agent/stepRetry/stepRetryService.ts | 21 - .../agent/systemReminder/systemReminder.ts | 10 - .../systemReminder/systemReminderService.ts | 7 - .../src/agent/task/configSection.ts | 18 - .../agent-core-v2/src/agent/task/errors.ts | 4 - .../src/agent/task/notificationXml.ts | 10 - .../agent-core-v2/src/agent/task/persist.ts | 19 - .../src/agent/task/printDefaults.ts | 20 - packages/agent-core-v2/src/agent/task/task.ts | 11 - .../agent-core-v2/src/agent/task/taskOps.ts | 33 -- .../src/agent/task/taskService.ts | 44 -- .../src/agent/tokenCounting/configSection.ts | 20 - .../src/agent/tokenCounting/tokenCounting.ts | 18 - .../agent/tokenCounting/tokenCountingOps.ts | 20 - .../tokenCounting/tokenCountingService.ts | 29 -- .../agent/toolActivation/toolActivation.ts | 15 - .../toolActivation/toolActivationService.ts | 32 -- .../src/agent/toolApproval/toolApproval.ts | 9 - .../agent/toolApproval/toolApprovalService.ts | 13 - .../src/agent/toolDedupe/toolDedupe.ts | 10 - .../src/agent/toolDedupe/toolDedupeService.ts | 17 - .../toolExecutor/beforeToolExecuteEvent.ts | 24 - .../src/agent/toolExecutor/toolExecutor.ts | 9 - .../agent/toolExecutor/toolExecutorEvents.ts | 10 - .../agent/toolExecutor/toolExecutorService.ts | 17 - .../src/agent/toolExecutor/toolHooks.ts | 29 -- .../src/agent/toolExecutor/toolScheduler.ts | 10 - .../src/agent/toolPolicy/configSection.ts | 8 - .../src/agent/toolPolicy/evaluate.ts | 25 - .../src/agent/toolPolicy/toolPolicy.ts | 7 - .../src/agent/toolPolicy/toolPolicyService.ts | 14 - .../builtinToolAssemblyService.ts | 14 - .../agent/toolRegistry/toolContribution.ts | 34 -- .../src/agent/toolRegistry/toolRegistry.ts | 8 - .../agent/toolRegistry/toolRegistryService.ts | 8 - .../toolResultTruncation.ts | 10 - .../toolResultTruncationService.ts | 9 - .../src/agent/toolSelect/dynamicTools.ts | 28 -- .../src/agent/toolSelect/flag.ts | 11 - .../src/agent/toolSelect/toolSelect.ts | 8 - .../toolSelect/toolSelectAnnouncements.ts | 7 - .../toolSelectAnnouncementsService.ts | 13 - .../src/agent/toolSelect/toolSelectSchemas.ts | 7 - .../toolSelect/toolSelectSchemasService.ts | 7 - .../src/agent/toolSelect/toolSelectService.ts | 18 - .../src/agent/tools/agent/agent.ts | 12 - .../src/agent/tools/agent/agentTool.ts | 43 -- .../src/agent/tools/agent/subagent-task.ts | 12 - .../ask-user-question/ask-user-question.ts | 13 - .../ask-user-question/askUserQuestionTool.ts | 23 - .../question-background-task.ts | 11 - .../tools/cron/cron-create/cron-create.ts | 11 - .../tools/cron/cron-create/cronCreateTool.ts | 33 -- .../tools/cron/cron-delete/cron-delete.ts | 10 - .../tools/cron/cron-delete/cronDeleteTool.ts | 44 -- .../agent/tools/cron/cron-list/cron-list.ts | 10 - .../tools/cron/cron-list/cronListTool.ts | 47 -- .../src/agent/tools/edit/edit.ts | 14 - .../src/agent/tools/edit/editTool.ts | 21 - .../src/agent/tools/fetch-url/fetch-url.ts | 11 - .../src/agent/tools/fetch-url/fetchUrlTool.ts | 13 - .../tools/goal/create-goal/create-goal.ts | 11 - .../tools/goal/create-goal/createGoalTool.ts | 11 - .../src/agent/tools/goal/get-goal/get-goal.ts | 11 - .../agent/tools/goal/get-goal/getGoalTool.ts | 10 - .../goal/set-goal-budget/set-goal-budget.ts | 10 - .../goal/set-goal-budget/setGoalBudgetTool.ts | 11 - .../tools/goal/update-goal/update-goal.ts | 11 - .../tools/goal/update-goal/updateGoalTool.ts | 12 - .../src/agent/tools/os/bash/bash.ts | 15 - .../src/agent/tools/os/bash/bashTool.ts | 42 -- .../src/agent/tools/os/glob/glob.ts | 14 - .../src/agent/tools/os/glob/globTool.ts | 61 --- .../src/agent/tools/os/grep/grep.ts | 12 - .../src/agent/tools/os/grep/grepTool.ts | 34 -- .../src/agent/tools/os/read/read.ts | 23 - .../src/agent/tools/os/read/readTool.ts | 29 -- .../src/agent/tools/os/write/write.ts | 15 - .../src/agent/tools/os/write/writeTool.ts | 20 - .../tools/read-media-file/read-media-file.ts | 11 - .../read-media-file/readMediaFileTool.ts | 58 --- .../agent/tools/select-tools/select-tools.ts | 9 - .../tools/select-tools/selectToolsTool.ts | 14 - .../src/agent/tools/skill/skill.ts | 12 - .../src/agent/tools/skill/skillTool.ts | 20 - .../agent/tools/task/task-list/task-list.ts | 9 - .../tools/task/task-list/taskListTool.ts | 12 - .../tools/task/task-output/task-output.ts | 9 - .../tools/task/task-output/taskOutputTool.ts | 20 - .../agent/tools/task/task-stop/task-stop.ts | 9 - .../tools/task/task-stop/taskStopTool.ts | 14 - .../src/agent/tools/todo-list/todo-list.ts | 14 - .../src/agent/tools/todo-list/todoListTool.ts | 16 - .../src/agent/tools/web-search/web-search.ts | 14 - .../agent/tools/web-search/webSearchTool.ts | 20 - packages/agent-core-v2/src/agent/undo/undo.ts | 7 - .../src/agent/undo/undoService.ts | 10 - .../agent-core-v2/src/agent/usage/errors.ts | 4 - .../agent-core-v2/src/agent/usage/usage.ts | 8 - .../src/agent/usage/usageEvents.ts | 10 - .../agent-core-v2/src/agent/usage/usageOps.ts | 16 - .../src/agent/usage/usageService.ts | 15 - .../src/agent/userTool/userToolOps.ts | 19 - .../src/agent/userTool/userToolService.ts | 19 - .../src/app/agentIdentity/agentIdentity.ts | 22 - .../app/agentIdentity/agentIdentityService.ts | 13 - .../src/app/agentIdentity/configSection.ts | 17 - .../agentProfileCatalog.ts | 38 -- .../agentProfileContribution.ts | 18 - .../agentProfileRegistry.ts | 26 -- .../agentProfileRegistryService.ts | 16 - .../builtinAgentProfileLoader.ts | 11 - .../builtinAgentProfileLoaderService.ts | 15 - .../app/agentProfileCatalog/contribution.ts | 13 - .../app/agentProfileCatalog/profile-shared.ts | 30 -- .../app/agentProfileCatalog/promptPrefix.ts | 8 - packages/agent-core-v2/src/app/auth/auth.ts | 12 - .../agent-core-v2/src/app/auth/authService.ts | 15 - .../src/app/auth/configSection.ts | 23 - packages/agent-core-v2/src/app/auth/errors.ts | 4 - .../src/app/auth/oauthProtocol.ts | 12 - .../src/app/auth/webSearch/webSearch.ts | 12 - .../app/auth/webSearch/webSearchService.ts | 23 - .../src/app/authLegacy/authLegacy.ts | 10 - .../src/app/authLegacy/authLegacyService.ts | 11 - .../src/app/bashParser/bashParser.ts | 14 - .../src/app/bashParser/bashParserService.ts | 14 - .../src/app/bootstrap/bootstrap.ts | 19 - .../src/app/bootstrap/bootstrapService.ts | 11 - .../src/app/capability/capability.ts | 12 - .../src/app/capability/capabilityEvents.ts | 1 - .../src/app/capability/capabilityService.ts | 12 - .../src/app/capability/entries/context.ts | 7 - .../src/app/capability/entries/kimiCu.ts | 32 -- .../app/capability/entries/kimiWebbridge.ts | 19 - .../src/app/capability/errors.ts | 4 - .../agent-core-v2/src/app/capability/host.ts | 12 - .../agent-core-v2/src/app/capability/types.ts | 11 - .../agent-core-v2/src/app/config/config.ts | 35 -- .../src/app/config/configEvents.ts | 15 - .../app/config/configOverlayContributions.ts | 15 - .../src/app/config/configPure.ts | 8 - .../app/config/configSectionContributions.ts | 12 - .../src/app/config/configService.ts | 45 -- .../src/app/config/deprecations.ts | 11 - .../agent-core-v2/src/app/config/errors.ts | 7 - .../src/app/config/migrations.ts | 7 - .../src/app/config/sectionDiff.ts | 8 - packages/agent-core-v2/src/app/config/toml.ts | 13 - packages/agent-core-v2/src/app/cron/clock.ts | 29 -- .../src/app/cron/configSection.ts | 9 - .../agent-core-v2/src/app/cron/cron-expr.ts | 19 - .../agent-core-v2/src/app/cron/cronTask.ts | 8 - .../src/app/cron/cronTaskPersistence.ts | 10 - .../app/cron/cronTaskPersistenceService.ts | 9 - packages/agent-core-v2/src/app/cron/errors.ts | 4 - packages/agent-core-v2/src/app/cron/format.ts | 9 - packages/agent-core-v2/src/app/cron/jitter.ts | 29 -- .../agent-core-v2/src/app/edit/editService.ts | 9 - .../agent-core-v2/src/app/edit/fileEdit.ts | 10 - .../src/app/edit/fileEditService.ts | 9 - .../agent-core-v2/src/app/edit/textModel.ts | 9 - .../agent-core-v2/src/app/event/errors.ts | 9 - packages/agent-core-v2/src/app/event/event.ts | 12 - .../agent-core-v2/src/app/event/event2.ts | 24 - .../agent-core-v2/src/app/event/eventBus.ts | 21 - .../src/app/event/eventBusService.ts | 22 - .../src/app/event/eventService.ts | 10 - .../src/app/event/fiberEventResolver.ts | 13 - .../externalHooksRunner.ts | 11 - .../externalHooksRunnerService.ts | 17 - .../src/app/externalHooksRunner/index.ts | 7 - .../src/app/externalHooksRunner/runner.ts | 12 - .../src/app/feature/featureManager.ts | 19 - .../src/app/feature/featureManagerService.ts | 12 - .../agent-core-v2/src/app/file/fileService.ts | 9 - .../src/app/file/fileServiceImpl.ts | 12 - packages/agent-core-v2/src/app/flag/flag.ts | 12 - .../src/app/flag/flagRegistry.ts | 10 - .../src/app/flag/flagRegistryService.ts | 9 - .../agent-core-v2/src/app/flag/flagService.ts | 9 - .../agent-core-v2/src/app/gateway/gateway.ts | 7 - .../src/app/gateway/gatewayService.ts | 11 - packages/agent-core-v2/src/app/git/git.ts | 12 - .../agent-core-v2/src/app/git/gitParsers.ts | 8 - .../agent-core-v2/src/app/git/gitService.ts | 12 - .../agent-core-v2/src/app/git/workTree.ts | 12 - .../hostFolderBrowser/hostFolderBrowser.ts | 12 - .../hostFolderBrowserService.ts | 9 - .../src/app/kosongConfig/builtInModelsDev.ts | 3 - .../src/app/kosongConfig/configSection.ts | 25 - .../src/app/kosongConfig/discovery.ts | 13 - .../src/app/kosongConfig/discoveryService.ts | 45 -- .../src/app/kosongConfig/envOverlay.ts | 19 - .../src/app/kosongConfig/errors.ts | 7 - .../kosongConfig/hostRequestHeadersAdapter.ts | 16 - .../src/app/kosongConfig/kosongConfig.ts | 20 - .../app/kosongConfig/kosongConfigService.ts | 32 -- .../src/app/kosongConfig/modelsDev.ts | 15 - .../src/app/kosongConfig/modelsDevImport.ts | 17 - .../kosongConfig/modelsDevImportService.ts | 38 -- .../src/app/kosongConfig/modelsDevUpstream.ts | 14 - .../src/app/kosongConfig/oauthTokenAdapter.ts | 8 - .../src/app/mcpConfig/configSection.ts | 8 - .../src/app/mcpConfig/oauthStore.ts | 18 - .../agent-core-v2/src/app/plugin/errors.ts | 4 - .../src/app/plugin/github-resolver.ts | 7 - .../agent-core-v2/src/app/plugin/manager.ts | 7 - .../src/app/plugin/marketplace.ts | 29 -- .../agent-core-v2/src/app/plugin/plugin.ts | 16 - .../src/app/plugin/pluginEvents.ts | 1 - .../src/app/plugin/pluginService.ts | 18 - .../projectLocalConfig/projectLocalConfig.ts | 10 - packages/agent-core-v2/src/app/scopes.ts | 9 - .../src/app/sessionExport/errors.ts | 4 - .../src/app/sessionExport/file-source.ts | 7 - .../src/app/sessionExport/manifest.ts | 8 - .../src/app/sessionExport/sessionExport.ts | 9 - .../app/sessionExport/sessionExportService.ts | 9 - .../src/app/sessionExport/wire-scan.ts | 8 - .../src/app/sessionExport/zip.ts | 8 - .../src/app/sessionIndex/sessionIndex.ts | 33 -- .../sessionIndex/sessionIndexMirrorService.ts | 39 -- .../src/app/sessionIndex/sessionIndexModel.ts | 17 - .../app/sessionIndex/sessionIndexProjector.ts | 52 --- .../app/sessionIndex/sessionIndexService.ts | 73 --- .../app/sessionIndex/sessionIndexSource.ts | 22 - .../src/app/sessionLegacy/sessionLegacy.ts | 17 - .../app/sessionLegacy/sessionLegacyService.ts | 20 - .../src/app/sessionLegacy/sessionProtocol.ts | 9 - .../src/app/sessionManager/sessionLookup.ts | 13 - .../src/app/skillCatalog/builtin/builtin.ts | 16 - .../builtin/check-kimi-code-docs.ts | 4 - .../app/skillCatalog/builtin/custom-theme.ts | 4 - .../builtin/import-from-cc-codex.ts | 4 - .../app/skillCatalog/builtin/mcp-config.ts | 4 - .../src/app/skillCatalog/builtin/registry.ts | 13 - .../src/app/skillCatalog/builtin/sub-skill.ts | 4 - .../app/skillCatalog/builtin/update-config.ts | 4 - .../app/skillCatalog/builtin/write-goal.ts | 4 - .../app/skillCatalog/builtinSkillSource.ts | 14 - .../src/app/skillCatalog/configSection.ts | 26 -- .../src/app/skillCatalog/errors.ts | 4 - .../app/skillCatalog/fileSkillDiscovery.ts | 11 - .../skillCatalog/inMemorySkillDiscovery.ts | 14 - .../src/app/skillCatalog/parser.ts | 8 - .../src/app/skillCatalog/registry.ts | 9 - .../src/app/skillCatalog/skillDiscovery.ts | 13 - .../src/app/skillCatalog/skillRoots.ts | 10 - .../src/app/skillCatalog/skillSource.ts | 14 - .../src/app/skillCatalog/types.ts | 14 - .../app/skillCatalog/userFileSkillSource.ts | 9 - .../agent-core-v2/src/app/state/appState.ts | 12 - .../src/app/state/appStateService.ts | 9 - packages/agent-core-v2/src/app/task/task.ts | 15 - .../agent-core-v2/src/app/task/taskService.ts | 8 - .../app/telemetry/agentTelemetryContext.ts | 8 - .../telemetry/agentTelemetryContextService.ts | 8 - .../src/app/telemetry/cloudAppender.ts | 11 - .../src/app/telemetry/cloudTransport.ts | 8 - .../src/app/telemetry/consoleAppender.ts | 7 - .../src/app/telemetry/coreVersion.ts | 11 - .../agent-core-v2/src/app/telemetry/events.ts | 17 - .../src/app/telemetry/privacy.ts | 10 - .../src/app/telemetry/telemetry.ts | 11 - .../src/app/telemetry/telemetryService.ts | 9 - packages/agent-core-v2/src/app/web/errors.ts | 4 - .../src/app/web/providers/local-fetch-url.ts | 14 - .../src/app/web/tools/fetch-url-types.ts | 4 - packages/agent-core-v2/src/app/web/web.ts | 8 - .../agent-core-v2/src/app/web/webService.ts | 23 - .../app/workspace/fileWorkspacePersistence.ts | 12 - .../src/app/workspace/workspace.ts | 9 - .../src/app/workspace/workspaceAlias.ts | 12 - .../src/app/workspace/workspacePersistence.ts | 21 - .../src/app/workspace/workspaceService.ts | 54 --- .../app/workspaceAliases/workspaceAliases.ts | 9 - .../workspaceAliasesService.ts | 15 - .../workspaceSessions/workspaceSessions.ts | 11 - .../workspaceSessionsService.ts | 14 - .../agent-core-v2/src/debug/debugCascade.ts | 28 -- .../src/debug/debugCascadeService.ts | 17 - .../agent-core-v2/src/debug/debugGraph.ts | 11 - .../src/debug/debugGraphService.ts | 9 - .../agent-core-v2/src/debug/debugLedger.ts | 11 - .../src/debug/debugLedgerService.ts | 8 - packages/agent-core-v2/src/debug/errors.ts | 4 - packages/agent-core-v2/src/debug/index.ts | 5 - packages/agent-core-v2/src/debug/scopeTree.ts | 11 - packages/agent-core-v2/src/env.d.ts | 2 - packages/agent-core-v2/src/errors.ts | 6 - .../agent-core-v2/src/features/btw/btw.ts | 9 - .../src/features/btw/btwFeature.ts | 9 - .../src/features/btw/btwService.ts | 15 - .../src/features/dateChange/dateChange.ts | 7 - .../features/dateChange/dateChangeService.ts | 17 - .../features/dateChange/disclosureBaseline.ts | 13 - .../src/features/debugEvents/debugEvents.ts | 18 - .../debugEvents/debugEventsFeature.ts | 11 - .../debugEvents/debugEventsService.ts | 13 - .../agent-core-v2/src/features/feature.ts | 15 - .../src/features/featureAssembly.ts | 9 - .../src/features/featureAssemblyService.ts | 9 - .../src/features/featureRegistry.ts | 12 - .../src/features/plan/configSection.ts | 12 - .../src/features/plan/exitPlanModeReview.ts | 13 - .../plan/injection/planModeInjection.ts | 12 - .../src/features/plan/planFeature.ts | 16 - .../src/features/plan/planOps.ts | 31 -- .../src/features/plan/planService.ts | 24 - .../src/features/plan/profile/plan.ts | 9 - .../tools/enter-plan-mode/enter-plan-mode.ts | 10 - .../enter-plan-mode/enterPlanModeTool.ts | 10 - .../tools/exit-plan-mode/exit-plan-mode.ts | 11 - .../tools/exit-plan-mode/exitPlanModeTool.ts | 19 - .../src/features/sessionInit/profile/init.ts | 10 - .../src/features/sessionInit/sessionInit.ts | 10 - .../sessionInit/sessionInitService.ts | 24 - .../swarm/agent/injection/swarmInjection.ts | 8 - .../src/features/swarm/agent/swarmService.ts | 17 - .../features/swarm/session/agentRunBatch.ts | 11 - .../features/swarm/session/sessionSwarm.ts | 8 - .../swarm/session/sessionSwarmService.ts | 22 - .../src/features/swarm/swarmFeature.ts | 16 - .../src/features/swarm/swarmOps.ts | 18 - .../swarm/tools/agent-swarm/agent-swarm.ts | 11 - .../swarm/tools/agent-swarm/agentSwarmTool.ts | 24 - .../features/tower/protocol/frontmatter.ts | 10 - .../src/features/tower/protocol/git.ts | 7 - .../src/features/tower/protocol/paths.ts | 5 - .../src/features/tower/protocol/repoRoot.ts | 10 - .../src/features/tower/protocol/store.ts | 92 ---- .../src/features/tower/protocol/types.ts | 8 - .../src/features/tower/skill/skill.ts | 7 - .../features/tower/tools/finding/finding.ts | 10 - .../tower/tools/finding/findingTool.ts | 10 - .../src/features/tower/tools/inbox/inbox.ts | 9 - .../features/tower/tools/inbox/inboxTool.ts | 9 - .../src/features/tower/tools/init/init.ts | 10 - .../src/features/tower/tools/init/initTool.ts | 15 - .../src/features/tower/tools/merge/merge.ts | 11 - .../features/tower/tools/merge/mergeTool.ts | 10 - .../features/tower/tools/mission/mission.ts | 11 - .../tower/tools/mission/missionTool.ts | 10 - .../src/features/tower/tools/plan/plan.ts | 10 - .../src/features/tower/tools/plan/planTool.ts | 9 - .../src/features/tower/tools/review/review.ts | 10 - .../features/tower/tools/review/reviewTool.ts | 11 - .../src/features/tower/tools/send/send.ts | 10 - .../src/features/tower/tools/send/sendTool.ts | 9 - .../src/features/tower/tools/spawn/spawn.ts | 9 - .../features/tower/tools/spawn/spawnTool.ts | 64 --- .../src/features/tower/tools/status/status.ts | 11 - .../features/tower/tools/status/statusTool.ts | 11 - .../src/features/tower/tools/support.ts | 8 - .../features/tower/tools/teardown/teardown.ts | 11 - .../tower/tools/teardown/teardownTool.ts | 10 - .../agent-core-v2/src/features/tower/tower.ts | 7 - .../src/features/tower/towerFeature.ts | 23 - .../src/features/tower/towerOps.ts | 13 - .../src/features/tower/towerRateLimit.ts | 6 - .../features/tower/towerRateLimitService.ts | 16 - .../src/features/tower/towerService.ts | 32 -- .../src/features/tower/workerProfile.ts | 24 - packages/agent-core-v2/src/hooks.ts | 6 - packages/agent-core-v2/src/index.ts | 12 - .../src/kosong/contract/capability.ts | 12 - .../src/kosong/contract/errors.ts | 25 - .../src/kosong/contract/generate.ts | 11 - .../src/kosong/contract/inspection.ts | 13 - .../src/kosong/contract/message.ts | 12 - .../src/kosong/contract/messageHelpers.ts | 12 - .../src/kosong/contract/provider.ts | 18 - .../src/kosong/contract/requestTrace.ts | 7 - .../src/kosong/contract/tokens.ts | 10 - .../agent-core-v2/src/kosong/contract/tool.ts | 9 - .../src/kosong/contract/usage.ts | 8 - .../agent-core-v2/src/kosong/model/catalog.ts | 31 -- .../src/kosong/model/catalogService.ts | 57 --- .../src/kosong/model/completionBudget.ts | 17 - .../agent-core-v2/src/kosong/model/errors.ts | 12 +- .../src/kosong/model/hostRequestHeaders.ts | 21 - .../src/kosong/model/inspection.ts | 24 - .../agent-core-v2/src/kosong/model/model.ts | 29 -- .../src/kosong/model/model.types.ts | 22 - .../src/kosong/model/modelAuth.ts | 22 - .../src/kosong/model/modelOAuth.ts | 11 - .../src/kosong/model/modelRequester.ts | 13 - .../src/kosong/model/modelRequesterImpl.ts | 22 - .../src/kosong/model/modelService.ts | 9 - .../src/kosong/model/thinking.ts | 35 -- .../src/kosong/protocol/errors.ts | 18 - .../src/kosong/protocol/protocol.ts | 22 - .../src/kosong/protocol/protocolBase.ts | 13 - .../src/kosong/protocol/protocolTrait.ts | 33 -- .../bases/anthropic/anthropic-profile.ts | 6 - .../bases/anthropic/anthropic.contrib.ts | 10 - .../provider/bases/anthropic/anthropic.ts | 32 -- .../bases/anthropic/anthropicHooks.ts | 11 - .../kosong/provider/bases/anthropic/index.ts | 5 - .../google-genai/google-genai.contrib.ts | 13 - .../bases/google-genai/google-genai.ts | 23 - .../provider/bases/google-genai/index.ts | 5 - .../provider/bases/merge-user-messages.ts | 8 - .../bases/openai/chat-completions-stream.ts | 9 - .../src/kosong/provider/bases/openai/index.ts | 6 - .../provider/bases/openai/openai-common.ts | 21 - .../bases/openai/openai-legacy.contrib.ts | 15 - .../provider/bases/openai/openai-legacy.ts | 37 -- .../bases/openai/openai-responses.contrib.ts | 10 - .../provider/bases/openai/openai-responses.ts | 23 - .../provider/bases/openai/openaiHooks.ts | 18 - .../provider/bases/openai/reasoning-key.ts | 18 - .../src/kosong/provider/bases/request-auth.ts | 9 - .../src/kosong/provider/bases/tool-call-id.ts | 8 - .../provider/protocolAdapterRegistry.ts | 26 -- .../src/kosong/provider/provider.ts | 19 - .../src/kosong/provider/providerDefinition.ts | 19 - .../src/kosong/provider/providerService.ts | 9 - .../provider/providers/kimi/kimi-errors.ts | 22 - .../provider/providers/kimi/kimi-files.ts | 10 - .../provider/providers/kimi/kimi-schema.ts | 12 - .../provider/providers/kimi/kimi.contrib.ts | 82 ---- .../provider/providers/standard.contrib.ts | 31 -- .../agent-core-v2/src/kosong/recordDiff.ts | 9 - .../agent-core-v2/src/mcpCore/client-http.ts | 4 - .../src/mcpCore/client-remote.ts | 4 - .../src/mcpCore/client-shared.ts | 4 - .../agent-core-v2/src/mcpCore/client-sse.ts | 4 - .../agent-core-v2/src/mcpCore/client-stdio.ts | 4 - .../src/mcpCore/config-schema.ts | 14 - .../src/mcpCore/connection-manager.ts | 31 -- packages/agent-core-v2/src/mcpCore/errors.ts | 4 - .../src/mcpCore/oauth/callback-server.ts | 11 - .../src/mcpCore/oauth/provider.ts | 33 -- .../src/mcpCore/oauth/service.ts | 28 -- .../agent-core-v2/src/mcpCore/oauth/store.ts | 10 - .../agent-core-v2/src/mcpCore/tool-naming.ts | 4 - packages/agent-core-v2/src/mcpCore/types.ts | 8 - .../backends/node-local/hostClockService.ts | 7 - .../node-local/hostEnvironmentService.ts | 15 - .../os/backends/node-local/hostFsService.ts | 7 - .../backends/node-local/hostFsWatchService.ts | 7 - .../backends/node-local/hostProcessService.ts | 9 - .../node-local/hostTerminalService.ts | 12 - .../os/backends/node-local/tools/rgLocator.ts | 10 - .../src/os/backends/node-local/tools/runRg.ts | 9 - .../src/os/interface/hostClock.ts | 7 - .../src/os/interface/hostEnvironment.ts | 20 - .../src/os/interface/hostFileSystem.ts | 10 - .../src/os/interface/hostFsErrors.ts | 15 - .../src/os/interface/hostFsWatch.ts | 15 - .../src/os/interface/hostProcess.ts | 10 - .../src/os/interface/terminal.ts | 13 - .../src/os/interface/terminalErrors.ts | 4 - .../backends/memory/inMemoryStorageService.ts | 13 - .../src/persistence/backends/minidb/flag.ts | 9 - .../backends/minidb/miniDbQueryStore.ts | 78 ---- .../backends/node-fs/appendLogStore.ts | 16 - .../backends/node-fs/atomicDocumentStore.ts | 9 - .../backends/node-fs/blobStoreService.ts | 8 - .../backends/node-fs/fileStorageService.ts | 23 - .../node-fs/projectLocalConfigService.ts | 11 - .../persistence/interface/appendLogStore.ts | 23 - .../interface/atomicDocumentStore.ts | 10 - .../src/persistence/interface/blobStore.ts | 11 - .../src/persistence/interface/queryStore.ts | 27 -- .../src/persistence/interface/storage.ts | 31 -- .../session/agentLifecycle/agentLifecycle.ts | 23 - .../agentLifecycle/agentLifecycleService.ts | 28 -- .../src/session/agentLifecycle/errors.ts | 4 - .../src/session/agentLifecycle/mainAgent.ts | 17 - .../agentLifecycle/profile/gitContext.ts | 15 - .../agentLifecycle/profile/profiles.ts | 11 - .../agentLifecycle/subagentMetadata.ts | 8 - .../src/session/approval/approval.ts | 9 - .../src/session/approval/approvalService.ts | 12 - .../agent-core-v2/src/session/cron/cronOps.ts | 18 - .../src/session/cron/sessionCronService.ts | 10 - .../session/cron/sessionCronServiceImpl.ts | 30 -- packages/agent-core-v2/src/session/errors.ts | 5 - .../session/externalHooks/externalHooks.ts | 13 - .../externalHooks/externalHooksService.ts | 30 -- .../src/session/externalHooks/index.ts | 6 - .../src/session/interaction/interaction.ts | 13 - .../src/session/interaction/interactionOps.ts | 23 - .../session/interaction/interactionService.ts | 19 - .../src/session/mcp/ephemeralMcpServers.ts | 15 - .../src/session/mcp/mergedConnectionView.ts | 14 - .../src/session/mcp/sessionMcpHandle.ts | 19 - .../src/session/question/question.ts | 17 - .../src/session/question/questionService.ts | 12 - .../sessionActivity/sessionActivity.ts | 14 - .../sessionActivity/sessionActivityService.ts | 15 - .../sessionActivity/sessionOutcomeMirror.ts | 11 - .../sessionOutcomeMirrorService.ts | 15 - .../agentProfileCatalogSeed.ts | 10 - .../sessionAgentProfileCatalog.ts | 15 - .../sessionAgentProfileCatalogService.ts | 20 - .../session/sessionContext/sessionContext.ts | 12 - .../instructionsProvider.ts | 10 - .../session/sessionLog/sessionLogService.ts | 11 - .../session/sessionMetadata/promptMetadata.ts | 12 - .../sessionMetadata/sessionMetaEvents.ts | 9 - .../sessionMetadata/sessionMetadata.ts | 13 - .../sessionMetadata/sessionMetadataService.ts | 53 --- .../sessionSkillCatalog/skillCatalog.ts | 7 - .../sessionSkillCatalog/skillCatalogData.ts | 8 - .../skillCatalogService.ts | 16 - .../sessionTitle/agentTitlePromptSource.ts | 8 - .../agentTitlePromptSourceService.ts | 17 - .../src/session/sessionTitle/flag.ts | 9 - .../src/session/sessionTitle/sessionTitle.ts | 10 - .../sessionTitle/sessionTitleService.ts | 27 -- .../sessionToolPolicy/sessionToolPolicy.ts | 10 - .../sessionToolPolicyService.ts | 11 - .../sessionToolPolicyGate.ts | 9 - .../sessionToolPolicyGateService.ts | 10 - .../src/session/state/sessionState.ts | 12 - .../src/session/state/sessionStateService.ts | 8 - .../src/session/subagent/configSection.ts | 99 ---- .../src/session/subagent/flag.ts | 10 - .../src/session/subagent/mirrorAgentRun.ts | 24 - .../src/session/subagent/runAgentTurn.ts | 15 - .../src/session/subagent/subagent.ts | 11 - .../subagent/subagentModelsValidation.ts | 14 - .../subagentModelsValidationService.ts | 16 - .../src/session/subagent/subagentService.ts | 11 - .../src/session/terminal/terminalService.ts | 10 - .../src/session/todo/sessionTodo.ts | 9 - .../src/session/todo/sessionTodoService.ts | 11 - .../src/session/todo/todoItem.ts | 8 - .../src/session/todo/todoListReminder.ts | 8 - .../agent-core-v2/src/session/todo/todoOps.ts | 10 - .../workspaceContext/workspaceContext.ts | 12 - .../workspaceContextService.ts | 12 - .../session/workspaceInfo/workspaceInfo.ts | 10 - packages/agent-core-v2/src/state/errors.ts | 9 - .../src/state/eventDispatcher.ts | 18 - .../src/state/eventDispatcherService.ts | 31 -- packages/agent-core-v2/src/state/state.ts | 60 --- .../src/state/stateContribution.ts | 40 -- .../agent-core-v2/src/tool/args-validator.ts | 9 - .../agent-core-v2/src/tool/input-schema.ts | 19 - .../agent-core-v2/src/tool/path-access.ts | 20 - .../agent-core-v2/src/tool/result-builder.ts | 8 - packages/agent-core-v2/src/tool/rule-match.ts | 12 - .../agent-core-v2/src/tool/tool-args-parse.ts | 9 - .../agent-core-v2/src/tool/toolContract.ts | 17 - packages/agent-core-v2/src/wire/errors.ts | 11 - .../agent-core-v2/src/wire/migration/v1.5.ts | 7 - packages/agent-core-v2/src/wire/record.ts | 10 - packages/agent-core-v2/src/wire/wire.ts | 11 - .../agent-core-v2/src/wire/wireService.ts | 13 - .../sessionLifecycle/internal/addressing.ts | 12 - .../internal/forkTurnSlice.ts | 16 - .../sessionLifecycle/sessionLifecycle.ts | 24 - .../sessionLifecycleEvents.ts | 14 - .../sessionLifecycleService.ts | 112 ----- .../src/workspace/state/workspaceState.ts | 12 - .../workspace/state/workspaceStateService.ts | 11 - .../configSection.ts | 8 - .../explicitAgentProfileLoader.ts | 12 - .../explicitAgentProfileLoaderService.ts | 9 - .../extraAgentProfileLoader.ts | 12 - .../extraAgentProfileLoaderService.ts | 10 - .../internal/agentFile.ts | 13 - .../internal/agentFileDiscovery.ts | 18 - .../internal/agentProfileFromFile.ts | 20 - .../internal/agentProfileLoader.ts | 21 - .../internal/agentRoots.ts | 7 - .../internal/paths.ts | 10 - .../internal/systemFile.ts | 17 - .../internal/types.ts | 9 - .../pluginAgentProfileLoader.ts | 10 - .../pluginAgentProfileLoaderService.ts | 12 - .../userAgentProfileLoader.ts | 14 - .../userAgentProfileLoaderService.ts | 13 - .../workspaceAgentProfileLoader.ts | 12 - .../workspaceAgentProfileLoaderService.ts | 14 - .../workspaceContext/workspaceContext.ts | 14 - .../workspace/workspaceDirs/workspaceDirs.ts | 15 - .../workspaceDirs/workspaceDirsService.ts | 19 - .../src/workspace/workspaceFs/fs.ts | 12 - .../src/workspace/workspaceFs/fsService.ts | 24 - .../src/workspace/workspaceFs/fsWatch.ts | 16 - .../workspace/workspaceFs/fsWatchService.ts | 15 - .../workspace/workspaceFs/internal/errors.ts | 4 - .../workspaceFs/internal/fsProcess.ts | 9 - .../workspaceFs/internal/fsSearch.ts | 8 - .../workspaceFs/internal/rgLocator.ts | 18 - .../workspace/workspaceFs/internal/runRg.ts | 10 - .../workspace/workspaceGit/workspaceGit.ts | 8 - .../workspaceGit/workspaceGitService.ts | 9 - .../workspaceInstructions.ts | 15 - .../workspaceInstructionsService.ts | 19 - .../workspace/workspaceMcp/workspaceMcp.ts | 21 - .../workspaceMcp/workspaceMcpService.ts | 56 --- .../internal/config-loader.ts | 15 - .../workspaceMcpConfig/workspaceMcpConfig.ts | 20 - .../workspaceMcpConfigService.ts | 26 -- .../explicitFileSkillSource.ts | 11 - .../extraFileSkillSource.ts | 13 - .../pluginSkillSource.ts | 11 - .../rootFileSkillSource.ts | 12 - .../workspaceSkillCatalog.ts | 14 - .../workspaceSkillCatalogService.ts | 16 - .../workspaceTrust/workspaceTrust.ts | 16 - .../workspaceTrust/workspaceTrustService.ts | 19 - .../test/_base/di/planSample.test.ts | 7 - .../_base/execEnv/environmentProbe.test.ts | 18 - .../test/_base/execEnv/loginShellPath.test.ts | 25 - .../test/_base/lifecycle/ledger.test.ts | 1 - .../agent-core-v2/test/_base/log/stubs.ts | 7 - .../test/_base/text/encoding.test.ts | 2 - .../test/_base/utils/paths.test.ts | 9 - .../test/_base/utils/tokens.test.ts | 8 - .../agent/activityView/activityView.test.ts | 6 - .../agentsMdReminder/agentsMdReminder.test.ts | 8 - .../test/agent/blob/agentBlobService.test.ts | 18 - .../test/agent/blob/byteLruCache.test.ts | 11 - .../contextInjector/contextInjector.test.ts | 9 - .../test/agent/contextMemory/context.test.ts | 5 - .../contextMemory/contextTranscript.test.ts | 8 - .../agent/contextMemory/splice-replay.test.ts | 11 - .../test/agent/contextMemory/stubs.ts | 9 - .../contextProjector.bench.ts | 16 - .../projector-tool-exchanges.test.ts | 10 - .../test/agent/externalHooks/runner-stub.ts | 12 - .../fullCompaction/fullCompaction.test.ts | 28 -- .../agent/fullCompaction/strategy.test.ts | 3 - .../test/agent/goal/goal.test.ts | 8 - .../test/agent/goal/goalOps.test.ts | 6 - .../agent-core-v2/test/agent/goal/stubs.ts | 4 - .../test/agent/goal/tools/goal-tools.test.ts | 6 - .../llmRequester/llmRequesterService.test.ts | 12 - .../llmRequester/toolCallIdNormalizer.test.ts | 3 +- .../agent-core-v2/test/agent/loop/stubs.ts | 3 - .../test/agent/mcp/output.test.ts | 5 - .../test/agent/mcp/tools/auth.test.ts | 2 - .../test/agent/media/file-type.test.ts | 16 - .../test/agent/media/image-compress.test.ts | 55 --- .../test/agent/media/mediaRef.test.ts | 11 - .../test/agent/media/mediaResolver.test.ts | 22 - .../agent/media/sessionMediaStore.test.ts | 11 - .../test/agent/media/tools/read-media.test.ts | 9 - .../test/agent/permissionMode/stubs.ts | 9 - .../test/agent/permissionPolicy/stubs.ts | 9 - .../test/agent/permissionRules/stubs.ts | 9 - .../test/agent/plugin/agentPlugin.test.ts | 15 - .../agent/pluginCommand/pluginCommand.test.ts | 11 - .../test/agent/profile/apply-profile.test.ts | 15 +- .../test/agent/profile/binding.test.ts | 3 - .../test/agent/profile/config-state.test.ts | 4 - .../agent/prompt/promptMetadataText.test.ts | 18 - .../test/agent/prompt/promptService.test.ts | 8 - .../test/agent/prompt/submit.test.ts | 11 - .../questionTools/tools/ask-user.test.ts | 7 - .../test/agent/skill/activateSkill.test.ts | 20 - .../test/agent/skill/skill.test.ts | 16 - .../test/agent/state/agentState.test.ts | 6 - .../agent/task/foreground-persistence.test.ts | 7 - .../test/agent/task/heartbeat-stale.test.ts | 4 - .../task/idle-notification-repro.test.ts | 20 - .../test/agent/task/persist.test.ts | 10 - .../test/agent/task/reconcile.test.ts | 4 - .../test/agent/task/rpc-events.test.ts | 4 - .../agent-core-v2/test/agent/task/stubs.ts | 7 - .../test/agent/task/subagent-timeout.test.ts | 11 - .../test/agent/task/taskManager.test.ts | 5 - .../test/agent/task/taskService.test.ts | 12 - .../test/agent/task/tools/task-tools.test.ts | 4 - .../agent/tokenCounting/tokenCounting.test.ts | 17 - .../test/agent/toolExecutor/stubs.ts | 9 - .../agent/toolSelect/dynamicTools.test.ts | 9 - .../agent/toolSelect/toolSelect.e2e.test.ts | 20 - .../toolSelect/toolSelectService.test.ts | 11 - .../test/agent/undo/undo.test.ts | 8 - .../app/agentIdentity/agentIdentity.test.ts | 38 -- .../test/app/agentIdentity/stubs.ts | 12 - .../agentProfileRegistry.test.ts | 16 - .../profile-shared.test.ts | 38 +- .../agent-core-v2/test/app/auth/auth.test.ts | 10 - .../agent-core-v2/test/app/bootstrap/stubs.ts | 8 - .../app/capability/capabilityService.test.ts | 10 - .../test/app/capability/host.test.ts | 12 - .../test/app/capability/kimiCu.test.ts | 32 -- .../test/app/capability/kimiWebbridge.test.ts | 21 - .../test/app/config/config.test.ts | 49 -- .../test/app/config/configManifest.test.ts | 8 - .../agent-core-v2/test/app/config/stubs.ts | 7 - .../test/app/edit/tools/edit.test.ts | 11 - .../test/app/event/event.test.ts | 1 - .../test/app/event/eventBus.test.ts | 1 - .../externalHooksRunner/integration.test.ts | 3 - .../test/app/file/fileService.test.ts | 5 - packages/agent-core-v2/test/app/flag/stubs.ts | 6 - .../test/app/kosongConfig/discovery.test.ts | 23 - .../test/app/kosongConfig/envOverlay.test.ts | 13 - .../kosongConfig/kosongConfigService.test.ts | 24 - .../app/kosongConfig/modelsDevImport.test.ts | 30 -- .../test/app/llmProtocol/errors.test.ts | 5 - .../test/app/model/model.test.ts | 10 - .../test/app/plugin/github-resolver.test.ts | 8 - .../app/plugin/manager-consumption.test.ts | 10 - .../test/app/plugin/manager.test.ts | 8 - .../test/app/plugin/pluginService.test.ts | 12 - .../agent-core-v2/test/app/plugin/stubs.ts | 4 - .../test/app/provider/provider.test.ts | 10 - .../agent-core-v2/test/app/provider/stubs.ts | 6 - .../app/sessionIndex/sessionIndex.test.ts | 116 +---- .../sessionIndex/sessionIndexMirror.test.ts | 5 - .../test/app/sessionIndex/stubs.ts | 7 - .../app/sessionLegacy/sessionLegacy.test.ts | 16 - .../skillCatalog/builtinSkillSource.test.ts | 27 -- .../app/skillCatalog/builtinTower.test.ts | 14 - .../skillCatalog/fileSkillDiscovery.test.ts | 9 - .../skillCatalog/plugin-session-start.test.ts | 9 - .../test/app/skillCatalog/stubs.ts | 4 - .../telemetry/agentTelemetryContext.test.ts | 4 - .../agent-core-v2/test/app/telemetry/stubs.ts | 8 - .../app/web/providers/local-fetch-url.test.ts | 9 - .../test/app/web/tools/fetch-url.test.ts | 13 - .../test/app/web/web-fetch-service.test.ts | 13 - .../test/features/btw/btw.test.ts | 2 - .../dateChange/dateChangeInjection.test.ts | 11 - .../test/features/plan/planGuard.test.ts | 14 - .../test/features/swarm/sessionSwarm.test.ts | 2 - .../test/features/swarm/swarm.test.ts | 13 - .../test/features/tower/repoRoot.test.ts | 2 - .../test/features/tower/store.test.ts | 35 -- .../features/tower/tools/spawnTool.test.ts | 12 - .../features/tower/tools/towerTools.test.ts | 10 - .../test/features/tower/towerService.test.ts | 4 - .../test/features/tower/workerProfile.test.ts | 20 - packages/agent-core-v2/test/harness/agent.ts | 13 - .../test/kosong/contract/errors.test.ts | 9 - .../test/kosong/contract/generate.test.ts | 9 - .../test/kosong/contract/usage-tokens.test.ts | 8 - .../test/kosong/model/catalog.test.ts | 30 -- .../kosong/model/completionBudget.test.ts | 13 - .../test/kosong/model/modelAuth.test.ts | 14 - .../test/kosong/model/modelRequester.test.ts | 17 - .../test/kosong/model/modelService.test.ts | 11 - .../test/kosong/model/thinking.test.ts | 21 - .../test/kosong/protocol/errors.test.ts | 10 - .../test/kosong/protocol/protocol.test.ts | 12 - .../test/kosong/protocol/protocolBase.test.ts | 13 - .../kosong/protocol/protocolTrait.test.ts | 10 - .../test/kosong/provider/composition.test.ts | 49 -- .../test/kosong/provider/errors.test.ts | 26 -- .../test/kosong/provider/kimi.test.ts | 28 -- .../test/kosong/provider/openaiHooks.test.ts | 15 - .../kosong/provider/providerService.test.ts | 13 - packages/agent-core-v2/test/kosong/stubs.ts | 7 - .../test/lint/event-uniqueness.test.ts | 10 - .../lint/fixtures/duplicate-events.fixture.ts | 8 - .../test/lint/vendor-name-gates.test.ts | 17 - .../test/mcpCore/connection-manager.test.ts | 14 - .../test/mcpCore/oauth/store.test.ts | 1 - .../node-local/hostEnvironmentService.test.ts | 12 - .../node-local/hostFsWatchService.test.ts | 9 - .../os/backends/node-local/tools/bash.test.ts | 22 - .../os/backends/node-local/tools/glob.test.ts | 10 - .../os/backends/node-local/tools/read.test.ts | 19 - .../node-local/tools/rgLocator.test.ts | 10 - .../backends/node-local/tools/write.test.ts | 13 - .../backends/minidb/miniDbQueryStore.test.ts | 5 - .../backends/node-fs/appendLogStore.test.ts | 9 - .../test/persistence/interface/stubs.ts | 6 - .../agentLifecycle/agentLifecycle.test.ts | 10 - .../agentLifecycle/profile/profiles.test.ts | 13 - .../test/session/approval/stubs.ts | 8 - .../session/cron/cron-fire-steer.e2e.test.ts | 16 - .../sessionOutcomeMirror.test.ts | 8 - .../sessionAgentProfileCatalog.test.ts | 15 - .../sessionMetadata/sessionMetadata.test.ts | 27 +- .../sessionSkillCatalog/skillCatalog.test.ts | 11 - .../agentTitlePromptSourceService.test.ts | 6 - .../sessionTitle/sessionTitleService.test.ts | 9 - .../titleExcerpt.integration.test.ts | 9 - .../test/session/todo/sessionTodo.test.ts | 7 - packages/agent-core-v2/test/setup.ts | 14 - .../test/state/builtinReplayableKeys.ts | 1 - .../test/state/eventDispatcher.test.ts | 1 - .../test/state/stateManifest.test.ts | 10 - packages/agent-core-v2/test/state/stubs.ts | 5 - packages/agent-core-v2/test/tool/tool.test.ts | 28 -- .../test/wire/migration/v1.5.test.ts | 6 - .../test/wire/persistence.test.ts | 9 - .../test/wire/store-event.test.ts | 1 - .../test/wire/wire-compat.test.ts | 1 - .../test/wire/wireManifest.test.ts | 9 - .../agentFile.test.ts | 10 - .../agentFileDiscovery.test.ts | 9 - .../agentProfileLoader.test.ts | 15 - .../agentRoots.test.ts | 8 - .../systemFile.test.ts | 12 - .../workspaceFs/fsWatchService.test.ts | 8 - .../instructions.test.ts | 11 - .../workspaceMcp/initialization.test.ts | 10 - .../workspaceMcp/workspaceMcp.test.ts | 30 -- .../workspaceMcpConfig/config-loader.test.ts | 8 - .../workspaceMcpConfig.test.ts | 11 - .../skillCatalog.test.ts | 10 - .../workspaceTrust/workspaceTrust.test.ts | 12 - packages/kap-server/AGENTS.md | 6 +- packages/kap-server/src/contract.ts | 13 - packages/kap-server/src/env.d.ts | 5 - packages/kap-server/src/envelope.ts | 6 - packages/kap-server/src/error-handler.ts | 29 -- packages/kap-server/src/index.ts | 5 - packages/kap-server/src/instanceRegistry.ts | 42 -- .../kap-server/src/lib/contentDisposition.ts | 4 - packages/kap-server/src/lib/fileLaunch.ts | 16 - packages/kap-server/src/lib/httpRange.ts | 5 - packages/kap-server/src/lib/promptMedia.ts | 91 ---- packages/kap-server/src/lib/requestLog.ts | 7 - packages/kap-server/src/middleware/auth.ts | 28 -- .../kap-server/src/middleware/defineRoute.ts | 75 --- .../kap-server/src/middleware/hostnames.ts | 29 -- packages/kap-server/src/middleware/origin.ts | 32 -- .../kap-server/src/middleware/rateLimit.ts | 18 - packages/kap-server/src/middleware/schema.ts | 9 - .../src/middleware/securityHeaders.ts | 34 -- .../kap-server/src/middleware/validate.ts | 25 - packages/kap-server/src/openapi/transforms.ts | 12 - packages/kap-server/src/protocol/display.ts | 3 - packages/kap-server/src/protocol/envelope.ts | 6 - .../kap-server/src/protocol/error-codes.ts | 87 ---- .../kap-server/src/protocol/events-zod.ts | 8 - packages/kap-server/src/protocol/message.ts | 15 - .../kap-server/src/protocol/rest-approval.ts | 5 - .../src/protocol/rest-capability.ts | 6 - .../src/protocol/rest-connection.ts | 14 - packages/kap-server/src/protocol/rest-file.ts | 6 - packages/kap-server/src/protocol/rest-fs.ts | 8 - .../kap-server/src/protocol/rest-message.ts | 5 - packages/kap-server/src/protocol/rest-meta.ts | 32 -- .../src/protocol/rest-modelCatalog.ts | 38 -- .../kap-server/src/protocol/rest-oauth.ts | 9 - .../kap-server/src/protocol/rest-plugin.ts | 16 - .../kap-server/src/protocol/rest-prompt.ts | 27 -- .../kap-server/src/protocol/rest-question.ts | 6 - .../kap-server/src/protocol/rest-search.ts | 8 - .../kap-server/src/protocol/rest-session.ts | 25 - .../kap-server/src/protocol/rest-skill.ts | 12 - .../kap-server/src/protocol/rest-snapshot.ts | 29 -- packages/kap-server/src/protocol/rest-task.ts | 6 - .../kap-server/src/protocol/rest-terminal.ts | 9 - packages/kap-server/src/protocol/rest-tool.ts | 6 - .../kap-server/src/protocol/rest-workspace.ts | 10 - packages/kap-server/src/protocol/session.ts | 7 - packages/kap-server/src/protocol/skill.ts | 1 - packages/kap-server/src/protocol/task.ts | 3 - packages/kap-server/src/protocol/tool.ts | 3 - .../kap-server/src/protocol/ws-control.ts | 25 - packages/kap-server/src/request-id.ts | 10 - packages/kap-server/src/requestLogging.ts | 19 - .../kap-server/src/routes/action-suffix.ts | 33 -- packages/kap-server/src/routes/approvals.ts | 37 -- packages/kap-server/src/routes/auth.ts | 14 - .../kap-server/src/routes/capabilities.ts | 27 -- packages/kap-server/src/routes/config.ts | 54 --- packages/kap-server/src/routes/connections.ts | 16 - packages/kap-server/src/routes/files.ts | 25 - packages/kap-server/src/routes/fs.ts | 65 --- packages/kap-server/src/routes/guiStore.ts | 4 - packages/kap-server/src/routes/messages.ts | 37 -- packages/kap-server/src/routes/meta.ts | 19 - .../kap-server/src/routes/modelCatalog.ts | 143 +----- packages/kap-server/src/routes/oauth.ts | 21 - packages/kap-server/src/routes/plugins.ts | 72 --- packages/kap-server/src/routes/prompts.ts | 55 --- packages/kap-server/src/routes/questions.ts | 107 +---- .../src/routes/registerApiV1Routes.ts | 18 - .../src/routes/registerApiV2Routes.ts | 10 - packages/kap-server/src/routes/search.ts | 11 - .../src/routes/sessionAgentConfig.ts | 12 - .../kap-server/src/routes/sessionExport.ts | 11 - .../kap-server/src/routes/sessionMedia.ts | 30 -- .../kap-server/src/routes/sessionProfile.ts | 12 - packages/kap-server/src/routes/sessions.ts | 203 -------- packages/kap-server/src/routes/shutdown.ts | 10 - packages/kap-server/src/routes/skills.ts | 129 ------ packages/kap-server/src/routes/snapshot.ts | 27 -- packages/kap-server/src/routes/tasks.ts | 99 ---- packages/kap-server/src/routes/terminals.ts | 33 -- packages/kap-server/src/routes/tools.ts | 78 ---- packages/kap-server/src/routes/transcript.ts | 135 ------ packages/kap-server/src/routes/v2/sessions.ts | 90 ---- packages/kap-server/src/routes/workspaceFs.ts | 74 --- packages/kap-server/src/routes/workspaces.ts | 36 -- packages/kap-server/src/search/contract.ts | 48 -- packages/kap-server/src/search/docs.ts | 15 - packages/kap-server/src/search/indexCore.ts | 274 +---------- packages/kap-server/src/search/match.ts | 49 +- .../kap-server/src/search/searchService.ts | 240 +--------- packages/kap-server/src/search/snippet.ts | 10 - packages/kap-server/src/search/wireExtract.ts | 69 +-- .../kap-server/src/search/worker/entry.ts | 44 -- packages/kap-server/src/search/worker/host.ts | 143 +----- .../kap-server/src/search/worker/protocol.ts | 20 - .../kap-server/src/search/worker/runtime.ts | 12 - .../kap-server/src/security/bindClassify.ts | 34 -- .../src/services/auth/authTokenService.ts | 14 - .../src/services/auth/credentials.ts | 16 - .../src/services/auth/persistentToken.ts | 14 - .../src/services/auth/privateFiles.ts | 4 - .../src/services/auth/tokenStore.ts | 12 - .../src/services/guiStore/guiStoreService.ts | 4 - .../src/services/legacyStatus/legacyStatus.ts | 29 -- .../src/services/messages/messageHistory.ts | 24 - .../services/messages/messageProjection.ts | 34 -- .../modelCatalogRefreshScheduler.ts | 20 - .../src/services/pinoLoggerService.ts | 13 - packages/kap-server/src/services/telemetry.ts | 17 - .../src/services/transcript/coreBinding.ts | 94 ---- .../src/services/transcript/coreEventMap.ts | 180 -------- .../services/transcript/transcriptService.ts | 123 ----- .../src/services/transcript/wireRecords.ts | 9 - packages/kap-server/src/start.ts | 124 ----- packages/kap-server/src/transport/channel.ts | 10 - .../src/transport/channelRegistry.ts | 30 -- .../kap-server/src/transport/dispatcher.ts | 8 - packages/kap-server/src/transport/errors.ts | 8 - .../kap-server/src/transport/mainAgent.ts | 18 - .../src/transport/registerDebugRoutes.ts | 16 - .../src/transport/serviceDispatcherRoutes.ts | 32 -- .../src/transport/ws/bearerProtocol.ts | 4 - .../src/transport/ws/connectionRegistry.ts | 21 - .../kap-server/src/transport/ws/v1/events.ts | 15 - .../src/transport/ws/v1/fsWatchBridge.ts | 30 -- .../transport/ws/v1/inFlightTurnTracker.ts | 21 - .../src/transport/ws/v1/protocol.ts | 8 - .../src/transport/ws/v1/registerWsV1.ts | 12 +- .../ws/v1/sessionEventBroadcaster.ts | 298 ------------ .../transport/ws/v1/sessionEventJournal.ts | 34 +- .../transport/ws/v1/subagentRosterTracker.ts | 67 --- .../src/transport/ws/v1/wsConnectionV1.ts | 87 +--- .../test/apiSurface.snapshot.test.ts | 24 - packages/kap-server/test/approvals.test.ts | 1 - packages/kap-server/test/auth.test.ts | 1 - .../kap-server/test/authWiring.e2e.test.ts | 12 - packages/kap-server/test/boot.test.ts | 22 - packages/kap-server/test/capabilities.test.ts | 20 - packages/kap-server/test/connections.test.ts | 10 - .../test/debugNonloopback.e2e.test.ts | 13 - .../kap-server/test/disableAuth.e2e.test.ts | 17 +- packages/kap-server/test/fileLaunch.test.ts | 5 - packages/kap-server/test/files.test.ts | 13 - packages/kap-server/test/fs-watch.e2e.test.ts | 24 - packages/kap-server/test/fs.test.ts | 11 - packages/kap-server/test/guiStore.test.ts | 1 - .../kap-server/test/hostExposure.e2e.test.ts | 15 - packages/kap-server/test/hostnames.test.ts | 6 - .../test/inFlightTurnTracker.test.ts | 4 - .../kap-server/test/instanceRegistry.test.ts | 20 - .../kap-server/test/mediaRefParity.test.ts | 23 - packages/kap-server/test/messages.test.ts | 28 -- packages/kap-server/test/meta.test.ts | 19 - packages/kap-server/test/modelCatalog.test.ts | 4 - .../test/modelCatalogCatalog.test.ts | 42 -- .../test/modelCatalogProviderWrite.test.ts | 58 --- .../test/modelCatalogRefreshScheduler.test.ts | 2 - packages/kap-server/test/openapi.test.ts | 11 - packages/kap-server/test/plugins.test.ts | 71 +-- packages/kap-server/test/prompts.test.ts | 85 +--- packages/kap-server/test/questions.test.ts | 14 +- packages/kap-server/test/rateLimit.test.ts | 4 - .../kap-server/test/requestLogging.test.ts | 2 - packages/kap-server/test/rpc.test.ts | 40 -- .../test/search/searchRoute.test.ts | 27 -- .../test/search/searchService.test.ts | 433 ++---------------- .../test/search/wireExtract.test.ts | 16 - .../kap-server/test/securityHeaders.test.ts | 10 - .../messages/messageProjection.test.ts | 15 - .../test/services/transcript.test.ts | 166 ------- .../test/sessionEventBroadcaster.test.ts | 381 ++------------- .../test/sessionEventJournal.test.ts | 12 +- packages/kap-server/test/sessions.test.ts | 83 +--- packages/kap-server/test/setup.ts | 27 -- packages/kap-server/test/skills.test.ts | 38 -- packages/kap-server/test/snapshot.test.ts | 36 +- .../test/subagentRosterTracker.test.ts | 16 - packages/kap-server/test/tasks.test.ts | 22 +- packages/kap-server/test/telemetry.test.ts | 7 - packages/kap-server/test/terminals.test.ts | 11 - packages/kap-server/test/tools.test.ts | 27 -- packages/kap-server/test/transcript.test.ts | 97 ---- .../kap-server/test/transport-errors.test.ts | 6 - packages/kap-server/test/v2Sessions.test.ts | 27 -- packages/kap-server/test/workspaceFs.test.ts | 10 - .../kap-server/test/workspaceLayout.test.ts | 26 -- packages/kap-server/test/workspaces.test.ts | 5 - .../kap-server/test/wsConnectionV1.test.ts | 48 -- packages/kap-server/test/wsHostOrigin.test.ts | 12 - .../kap-server/test/wsUpgradeAuth.test.ts | 15 - packages/kap-server/test/wsV1Resync.test.ts | 15 - packages/transcript/AGENTS.md | 4 + packages/transcript/src/contract/events.ts | 25 - packages/transcript/src/contract/mediaRef.ts | 14 - packages/transcript/src/contract/schema.ts | 34 -- .../transcript/src/granularity/filterOps.ts | 15 - packages/transcript/src/granularity/grade.ts | 19 - packages/transcript/src/history/foldFacts.ts | 102 ----- packages/transcript/src/history/groupTurns.ts | 90 ---- packages/transcript/src/model/attachment.ts | 13 - packages/transcript/src/model/frame.ts | 16 - packages/transcript/src/model/ids.ts | 12 - packages/transcript/src/model/interaction.ts | 22 - packages/transcript/src/model/item.ts | 9 - packages/transcript/src/model/meta.ts | 9 - packages/transcript/src/model/prompt.ts | 9 - packages/transcript/src/model/task.ts | 8 - packages/transcript/src/model/todo.ts | 14 - packages/transcript/src/model/turn.ts | 8 - packages/transcript/src/ops/apply.ts | 36 -- packages/transcript/src/ops/operation.ts | 13 - .../transcript/src/pagination/paginate.ts | 23 - .../transcript/src/store/agentTranscript.ts | 16 - .../transcript/src/store/transcriptStore.ts | 10 - packages/transcript/src/view/registry.ts | 15 - packages/transcript/test/layers.test.ts | 72 +-- packages/transcript/test/store.test.ts | 35 +- scripts/check-no-comments.mjs | 232 ++++++++++ 1213 files changed, 395 insertions(+), 22907 deletions(-) create mode 100644 scripts/check-no-comments.mjs diff --git a/.agents/skills/agent-core-dev/SKILL.md b/.agents/skills/agent-core-dev/SKILL.md index 887296a64..5cf11c040 100644 --- a/.agents/skills/agent-core-dev/SKILL.md +++ b/.agents/skills/agent-core-dev/SKILL.md @@ -33,7 +33,7 @@ End-to-end procedures that span the stages. Reach for these before reading the s ## Stages -- [Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the four `LifecycleScope` tiers and visibility, and the file-header comment convention. Read before touching business code. +- [Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the four `LifecycleScope` tiers and visibility, and the no-comment convention. Read before touching business code. - [Stage 2 — Design a service](design.md): pick a scope, split a domain across scopes, choose a calling style (direct call vs event vs hook), and direct dependencies. Decide *where things live and who knows whom* before coding. - Topic: [Domain boundaries vs Scope](domain-boundaries.md) — keep `session` / `agent` / `turn` from becoming god objects; data-ownership test and their split conclusions. - Topic: [Persistence layering](persistence.md) — the three-layer `Store → Storage → backend` model, naming Stores by access pattern, and which layer business code should depend on. diff --git a/.agents/skills/agent-core-dev/orient.md b/.agents/skills/agent-core-dev/orient.md index 9644fbea9..8a50152ff 100644 --- a/.agents/skills/agent-core-dev/orient.md +++ b/.agents/skills/agent-core-dev/orient.md @@ -66,45 +66,12 @@ There is no domain-layer numbering — a domain may import any other domain, gui - v2 never imports v1 (`@moonshot-ai/agent-core` or any subpath). - The kosong subtree (`src/kosong/{contract,protocol,provider,model}`) keeps its strict internal order (`contract ← protocol ← provider/model`), purity bans (no SDKs in `contract`/`protocol`), and the `provider/bases` registration boundary. -## File-header comment convention +## Comment convention -`packages/agent-core-v2/AGENTS.md` mandates a header-only comment style: - -- **Header only.** Comments live solely in the top-of-file `/** */` block — never beside functions, methods, or statements. The code is the source of truth for *how*; the header states *what the module exposes and the responsibility it owns*. -- **Identity line first.** Start with `` `` domain — . `` Keep an existing `(cross-cutting)` label as-is. Write the role as a responsibility ("drives the turn lifecycle"), not a symbol list. -- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no prefix = App (see service-authoring.md). State the same scope in the header so the two never drift. -- **Interface files** (`.ts`) state the public contract + scope: which `IXxx` they define and what it is for. -- **Impl files** (`Service.ts`) add collaborators + scope: list every imported cross-domain collaborator as a role ("persists records through `records`"); read scope from `registerScopedService(LifecycleScope.X, …)`. -- **Contribution files** (`.ts` / `.contrib.ts`) state what they register into the target domain (e.g. "registers the `log` config section into `config`"). -- **Pure-function / `.types` / `.errors` files** state the responsibility only — they own no scoped state, so no scope line. - -Impl file example (`sessionMetadataService.ts`): - -```ts -/** - * `sessionMetadata` domain — `ISessionMetadata` implementation. - * - * Persists the session metadata document (`state.json`) through the `storage` - * access-pattern store (`IAtomicDocumentStore`), rooted at the `metaScope` - * namespace from `sessionContext`. Loads the existing document on - * construction (creating it on first run), and logs through `log`. Bound at - * Session scope. - */ -``` - -Contribution file example (`config.ts` inside `log/`): - -```ts -/** - * `log` domain — registers the `log` config section into `config`. - * - * Owns the `log` section schema and its env overlay; imported for the - * registration side effect. Bound at App scope. - */ -``` +`packages/agent-core-v2/AGENTS.md` bans comments: no file headers, no section banners, no statement-level narration — the code is the source of truth. The only exception is JSDoc attached to exported symbols, which flows into the generated `.d.ts` and the consumers' IDE hover. Tooling directives (`eslint-disable`, `@ts-expect-error`, …) are banned too: fix the underlying lint/type problem instead, and put negative type-safety cases in compiler-asserted fixtures. Scope is carried by the filename: `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no prefix = App (see service-authoring.md). ## Red lines (this stage) - Import via the `#/...` alias (mapped to `src/`); never reach into another domain's internals by relative path. - Short-lived may inject long-lived; never the reverse. -- File-header comments describe role and scope only; never narrate implementation beside statements. +- No comments — not file headers, not beside statements; exported-symbol JSDoc is the only exception. diff --git a/.agents/skills/agent-core-dev/server-align.md b/.agents/skills/agent-core-dev/server-align.md index 32a8948a4..88bc7892f 100644 --- a/.agents/skills/agent-core-dev/server-align.md +++ b/.agents/skills/agent-core-dev/server-align.md @@ -128,7 +128,7 @@ registerScopedService( Conventions: - **Name** the domain `Legacy` and the interface with the scope prefix, `ILegacyService` (e.g. `prompt` / `IAgentPromptService`), per service-authoring.md. -- **Header comment** must say it is an `edge adapter` and name both the v1 contract it implements and the native v2 Service it leaves untouched (see `prompt.ts`). +- **Role is carried by the name** — `Legacy` marks it as an `edge adapter`; the v1 contract it implements and the native v2 Service it leaves untouched stay evident from its delegation targets (see `prompt.ts`). - **Scope** = the lifetime of the *legacy* state it holds (the `prompt` queue is per-agent → `LifecycleScope.Agent`). Apply [orient.md](orient.md) / [design.md](design.md) normally — a LegacyService is not exempt from scope rules. - **Delegate, do not duplicate** business logic. The LegacyService translates the v1 contract into native-Service calls and translates results back; the real work stays in the native Service. - **Contract types come from the v1 wire schema homes** (the owning v2 domain contract or `kap-server/src/protocol`), so the interface cannot drift from the wire shape. @@ -236,7 +236,7 @@ Before submitting a server-align change: - [ ] Request and response schemas come from their owning home (the `agent-core-v2` domain contract or `packages/kap-server/src/protocol`); no inline re-declaration in server-v2. - [ ] Existing schema fields are unchanged in name, type, and semantics; only optional fields added (if any). - [ ] Native v2 Service left clean; v1-only behavior isolated in a `Legacy` / `ILegacyService` edge adapter when the semantics diverge. -- [ ] LegacyService registered with the correct `LifecycleScope` and a header comment naming it an edge adapter + the native Service it preserves. +- [ ] LegacyService registered with the correct `LifecycleScope` and named as the `Legacy` edge adapter preserving the native Service. - [ ] Domain error codes registered in `agent-core-v2`; wire codes registered in `packages/kap-server/src/protocol`; route maps them in `sendMappedError`, matching v1's status codes and idempotent envelopes. - [ ] Route resolves the scope from the URL by `accessor.get(IX)`; no cached scope; finishes before disposal. - [ ] Tests assert the wire envelope + protocol shape; wire-shape guards added/updated where the route mirrors v1. diff --git a/.agents/skills/agent-core-dev/service-authoring.md b/.agents/skills/agent-core-dev/service-authoring.md index 6aef86824..0648e17e6 100644 --- a/.agents/skills/agent-core-dev/service-authoring.md +++ b/.agents/skills/agent-core-dev/service-authoring.md @@ -17,7 +17,7 @@ One folder per domain, **camelCase**: `session/`, `sessionActivity/`, `contextMe ``` - **Strictly one service per file.** An interface file holds exactly one injectable interface and exactly one `createDecorator(...)`; an impl file holds exactly one service implementation class and exactly one `registerScopedService(...)`. No exceptions for "tightly-coupled" groups: even same-scope collaborators each get their own `.ts` + `Service.ts` pair. -- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no scope prefix = App (see [Naming](#naming)). The header comment restates the same scope. +- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no scope prefix = App (see [Naming](#naming)). - A domain therefore has as many impl files as it has services (e.g. `logService.ts` for the App `ILogService`, `sessionLogService.ts` for the Session `ISessionLogService`). See [Multi-Service domains](#multi-service-domains). The package entry `src/index.ts` imports and `export *`s every domain's leaf files precisely (one line per leaf), so importing the package still runs every `registerScopedService(...)` side effect — exactly as the old per-domain barrels did. @@ -293,11 +293,10 @@ Importing the package therefore fires every `register*` side effect, exactly as - Load the impl file too — its top-level `registerScopedService(...)` only runs when the module is imported. - `export *` helper modules only if they are part of the domain's public surface. -- Each leaf's file-header comment still names the domain, scope, and (for impls) the `register*` binding it owns. ## Comments -- **File-header comment is mandatory** and the only place comments live (orient.md). State the identity line, the role, collaborators (impls), and scope. +- **No comments** (orient.md): no file headers, no statement-level narration; the only exception is JSDoc attached to exported symbols. - **Methods and fields carry no comments by default.** Well-named identifiers and types say *what*; the code is the source of truth for *how*. - Write an inline comment only when the *why* is non-obvious (a hidden constraint, a subtle invariant, a workaround). One short line. - For unimplemented stubs, throw `NotImplementedError('feature')` rather than `throw new Error('TODO: …')` (errors.md). @@ -351,4 +350,4 @@ import './greet/greetService'; - Never `new` a `@IService`-carrying Service — except inside an explicit factory method, which is not a DI request. - Events: typed per-Service event → `Event`/`Emitter` from `'#/_base/event'`; cross-domain broadcast → `IEventService` from `'#/event'`. - `src/index.ts` must import/export every leaf file (including the impl) so each `register*` side effect runs. -- File-header comment only; methods/fields carry no comments by default; stubs throw `NotImplementedError`. +- No comments by default (orient.md); stubs throw `NotImplementedError`. diff --git a/.agents/skills/agent-core-dev/verify.md b/.agents/skills/agent-core-dev/verify.md index 8ab7dd095..41203e980 100644 --- a/.agents/skills/agent-core-dev/verify.md +++ b/.agents/skills/agent-core-dev/verify.md @@ -21,7 +21,7 @@ Walk the stages you touched and confirm: - **Design** — scope follows state identity; no `Map` at `App`; dependency arrows do not make a foundational layer know an upstream one; no cycle was routed around. - **Implement** — no `new` on `@IService`-carrying classes; `@IX` on constructor params only (service params after static params); interface + impl carry `_serviceBrand`; decorator names unique; coded errors only; flags for unreleased behavior. - **Test** — SUT resolved by interface; stubs under `test/`; scope tests re-register after `_clearScopedRegistryForTests()`; teardown through one `DisposableStore`. -- **Files** — header comments describe role + scope only; registration runs from the impl file's top level; the new domain is exported from `src/index.ts`. +- **Files** — no comments (exported-symbol JSDoc excepted); registration runs from the impl file's top level; the new domain is exported from `src/index.ts`. Then re-read the [global red lines](SKILL.md#global-red-lines) once — they catch most cross-stage mistakes in a single scan. diff --git a/AGENTS.md b/AGENTS.md index b18f4db8b..3cec21d62 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,6 +48,7 @@ This is a TypeScript monorepo built for agent-assisted development. Keep the roo ## General Coding Rules +- `packages/agent-core-v2`, `packages/kap-server`, and `packages/transcript` are comment-free zones: no line/block comments; the exceptions are JSDoc attached to exported symbols and load-bearing lint-suppression directives (`oxlint-disable` / `eslint-disable`), while other tooling directives (`@ts-expect-error`, …) stay banned. Enforced by `scripts/check-no-comments.mjs`, which runs as part of `pnpm lint`. - For optional object properties, pass `undefined` directly instead of using conditional spread. - YES: `{ user }` - NO: `{ ...(user ? { user } : undefined) }` diff --git a/package.json b/package.json index 4acbcbef6..5cbcad953 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "vis": "pnpm -C apps/vis run dev", "dev:docs": "pnpm -C docs install --ignore-workspace && pnpm -C docs run dev", "typecheck": "pnpm run build:packages && pnpm -r --filter './packages/*' run typecheck && pnpm --filter @moonshot-ai/kimi-code run typecheck && pnpm --filter kimi-code run typecheck && pnpm --filter @moonshot-ai/vis-server run typecheck && pnpm --filter @moonshot-ai/vis-web run typecheck", - "lint": "oxlint --type-aware", + "lint": "node scripts/check-no-comments.mjs && oxlint --type-aware", "lint:fix": "pnpm run lint --fix", "lint:pkg": "pnpm --filter @moonshot-ai/kimi-code exec publint && npm_config_cache=${TMPDIR:-/tmp}/kimi-code-npm-cache pnpm --filter @moonshot-ai/kimi-code exec attw --pack . --profile node16", "sherif": "sherif -i @agentclientprotocol/sdk", diff --git a/packages/agent-core-v2/AGENTS.md b/packages/agent-core-v2/AGENTS.md index cdb757c1f..c591d7668 100644 --- a/packages/agent-core-v2/AGENTS.md +++ b/packages/agent-core-v2/AGENTS.md @@ -10,7 +10,7 @@ Four `LifecycleScope` tiers — `App` / `Workspace` / `Session` / `Agent` (strin The DI kernel (`src/_base/di/`) owns the unit layer on top of the scoped registry: -- `service.ts` — `Service`: the unit base class (extends `Disposable`). Capabilities live on `this` (`provide` / `effect` / `on` / `get` / `ref`, plus `name` / `state` / `config`). Two-phase construction: inside the ctor `provide`/`on`/`effect` buffer (writes only — `get`/`ref` throw, dependencies are constructor parameters); the kernel binds the runtime after `Reflect.construct` and flushes in writing order; a manually `new`ed instance throws on every capability call. Services whose own members collide with the `Service` vocabulary keep `extends Disposable` with a NOTE comment — still full DI units (cascade/ledger do not require `Service`). +- `service.ts` — `Service`: the unit base class (extends `Disposable`). Capabilities live on `this` (`provide` / `effect` / `on` / `get` / `ref`, plus `name` / `state` / `config`). Two-phase construction: inside the ctor `provide`/`on`/`effect` buffer (writes only — `get`/`ref` throw, dependencies are constructor parameters); the kernel binds the runtime after `Reflect.construct` and flushes in writing order; a manually `new`ed instance throws on every capability call. Services whose own members collide with the `Service` vocabulary keep `extends Disposable` — still full DI units (cascade/ledger do not require `Service`). - `fiber.ts` — the `Fiber` capability interface (not a DI token), `FiberHandle` (thenable / `state` / `uid` / `update` / `dispose`), `ServiceRecipe` (class / arrow function / `{apply}`), the `FiberState` five-state machine, and `ScopeUnits(kind)` — the materialization collection token, one per scope kind. - `collection.ts` — `collection(name)` contribution tokens. Contribute with `this.provide(token, value)`; a fold declares the token as a constructor parameter and receives a `CollectionView` (`items` / `records` / incremental `onDidChange`). Records are visible to the provider's ancestors and descendants (never sibling subtrees); provider death withdraws. Collection edges enter the graph for introspection but never join a cascade contagion set. - `scopeUnits.ts` — the kernel fold: every scope-creation point (`createScopedChildHandle` / `Scope.createApp` / `Scope.createChild`) runs `watchScopeUnits(container, kind)` before eager activation, materializing each visible `ScopeUnits(kind)` record's recipe as a unit inside the new scope (disposal hangs on the record provider's book — provider death tears the materialized units down across the tree). `ScopeOptions.configureContainer` runs at the same point (the session seed adapters use it). @@ -35,25 +35,8 @@ Domain-slice scenarios that used to live in `examples/.example.ts` are now ## Comment conventions -- **Header only, external role only.** Comments live solely in the top-of-file `/** */` block — never beside functions, methods, or statements. Say what the module exposes and the responsibility it owns; the code is the source of truth for how it works, so do not narrate implementation steps, enumerate every export, or note porting / skeleton status. -- **Identity line first.** Start with `` `` domain — . `` Keep an existing `(cross-cutting)` label as-is. Write the role as a responsibility ("drives the turn lifecycle"), not a symbol list ("turn driver + context + loop runner"). -- **Impl files add collaborators + scope; contract files add the public contract + scope.** For impls, list every imported cross-domain collaborator as a role ("persists records through `records`") — declared dependencies count even if not yet wired in this WIP port; infrastructure imports (`_base/**`) are not collaborators. Read scope from `registerScopedService(LifecycleScope.X, …)`. - -### Examples - -Impl (`src/session/sessionMetadata/sessionMetadataService.ts`): - -```ts -/** - * `sessionMetadata` domain — `ISessionMetadata` implementation. - * - * Persists the session metadata document (`state.json`) through the `storage` - * access-pattern store (`IAtomicDocumentStore`), rooted at the `metaScope` - * namespace from `sessionContext`. Loads the existing document on - * construction (creating it on first run), and logs through `log`. Bound at - * Session scope. - */ -``` +- **No comments.** The code is the source of truth; do not write file headers, section banners, or implementation narration. The one exception is JSDoc attached to exported symbols (it flows into the generated `.d.ts` and the consumers' IDE hover); keep it focused on the public contract. +- **Lint-suppression directives are the tooling exception.** `oxlint-disable` / `eslint-disable` comments are allowed where they suppress an active rule for a deliberate pattern (e.g. the Event2 class+payload-interface merging idiom). `@ts-expect-error`, `@ts-ignore`, and `ts-nocheck` stay banned — fix the underlying type problem instead; negative type-safety cases go into compiler-asserted fixtures. ## Telemetry diff --git a/packages/agent-core-v2/docs/features.md b/packages/agent-core-v2/docs/features.md index e520fd1e9..c8ccc9aea 100644 --- a/packages/agent-core-v2/docs/features.md +++ b/packages/agent-core-v2/docs/features.md @@ -93,7 +93,7 @@ keep their static registrations; the service and the two tools go through the Fe ## Adding a new feature -1. `src/features//` — domain files follow the usual conventions (header comments, +1. `src/features//` — domain files follow the usual conventions (no comments, one service per file pair, `.md?raw` assets move with the feature). 2. `Feature.ts` — the Feature subclass + `registerFeature(...)`. 3. `src/index.ts` — precise leaf imports/exports; no barrel. diff --git a/packages/agent-core-v2/scripts/gen-config-manifest.mts b/packages/agent-core-v2/scripts/gen-config-manifest.mts index 5853bce21..411c5b5df 100644 --- a/packages/agent-core-v2/scripts/gen-config-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-config-manifest.mts @@ -1,26 +1,3 @@ -/** - * Generates `docs/config-manifest.toml` — the single place to see every config - * section registered via `registerConfigSection(...)` plus every effective - * overlay registered via `registerConfigOverlay(...)`. - * - * Two passes: - * 1. Static scan of `src/**` maps each registered section domain (and each - * overlay) to the source file that registers it — the "owner". - * 2. Runtime pass imports `src/index.ts` ("import = register") and drains the - * module-level contributions, capturing defaults, env bindings, and the - * registered hooks exactly as the running process sees them. - * - * The output is TOML in the on-disk shape (snake_case keys): one `[table]` per - * section, uncommented assignments for registered defaults, and commented - * `# field: type` lines for the remaining schema fields. - * - * Usage: - * pnpm --filter @moonshot-ai/agent-core-v2 gen:config-manifest # write the file - * pnpm --filter @moonshot-ai/agent-core-v2 gen:config-manifest --check # freshness check (CI-style) - * - * Freshness is also enforced by `test/app/config/configManifest.test.ts`. - */ - import { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; import { join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -44,10 +21,6 @@ const PKG = join(import.meta.dirname, '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'config-manifest.toml'); -// --------------------------------------------------------------------------- -// Static pass — domain/overlay → owner file -// --------------------------------------------------------------------------- - function walk(dir: string, out: string[] = []): string[] { for (const entry of readdirSync(dir)) { const p = join(dir, entry); @@ -62,7 +35,6 @@ function constStringValue(source: string, ident: string): string | undefined { return re.exec(source)?.[1]; } -/** domain key → owner file (relative to the package root). */ function scanSectionOwners(): Map { const owners = new Map(); for (const file of walk(SRC)) { @@ -77,12 +49,9 @@ function scanSectionOwners(): Map { return owners; } -/** overlay variable name → owner file (relative to the package root). */ function scanOverlayOwners(): Map { const owners = new Map(); for (const file of walk(SRC)) { - // Skip the collector module itself — its `registerConfigOverlay(overlay)` - // function signature is not a registration. if (file.endsWith('configOverlayContributions.ts')) continue; const source = readFileSync(file, 'utf-8'); if (!source.includes('registerConfigOverlay(')) continue; @@ -94,11 +63,6 @@ function scanOverlayOwners(): Map { return owners; } -// --------------------------------------------------------------------------- -// TOML-like rendering helpers -// --------------------------------------------------------------------------- - -/** Serialize a small JSON value as an inline TOML value. */ function toTomlValue(value: unknown): string { if (typeof value === 'string') return JSON.stringify(value); if (typeof value === 'number' || typeof value === 'boolean') return String(value); @@ -116,7 +80,6 @@ interface EnvRow { readonly detail: string; } -/** Property access shape of an `EnvBinding` object (avoids index-signature access). */ interface EnvBindingFields { readonly env?: unknown; readonly deprecatedEnv?: unknown; @@ -148,11 +111,6 @@ function snakePath(field: string): string { const RULE = `# ${'#'.repeat(74)}`; -// --------------------------------------------------------------------------- -// Section rendering -// --------------------------------------------------------------------------- - -/** `# field: type (default: x)` comment lines for an object schema's properties. */ function renderFieldComments( properties: Record, root: JsonSchema, @@ -165,8 +123,6 @@ function renderFieldComments( const propDefault = asJsonSchema(resolved)?.default; const defNote = propDefault !== undefined ? ` (default: ${JSON.stringify(propDefault)})` : ''; lines.push(`${indent}# ${camelToSnake(name)}: ${describeType(resolved)}${defNote}`); - // Expand nested object fields one level at a time (depth-capped so a - // recursive $ref cannot loop). const subProps = asJsonSchema(resolved)?.properties; if (depth < 3 && isRecord(subProps) && Object.keys(subProps).length > 0) { lines.push(...renderFieldComments(subProps, root, `${indent} `, depth + 1)); @@ -181,7 +137,6 @@ function renderBody(section: ConfigSectionContribution): string[] { const jsonSchema = schema === undefined ? undefined : toJsonSchema(schema); if (jsonSchema === undefined) { - // No schema (passthrough) or a schema that JSON Schema cannot represent. if (isRecord(options.defaultValue)) { return [ `[${key}]`, @@ -197,7 +152,6 @@ function renderBody(section: ConfigSectionContribution): string[] { return [`[${key}]`, `# (${schema === undefined ? 'no schema — passthrough' : 'schema uses transforms; see the owner file'})`]; } - // Object with named fields. if (isRecord(jsonSchema.properties) && Object.keys(jsonSchema.properties).length > 0) { const defaults = isRecord(options.defaultValue) ? options.defaultValue : {}; const lines = [`[${key}]`]; @@ -207,8 +161,6 @@ function renderBody(section: ConfigSectionContribution): string[] { lines.push(`${fieldKey} = ${truncate(toTomlValue(defaults[name]))}`); continue; } - // A nested object field is an on-disk sub-table (`[section.field]`) — - // render its own fields instead of a flat `field: object` comment. const resolved = resolveRef(prop, jsonSchema); const subProps = asJsonSchema(resolved)?.properties; if (isRecord(subProps) && Object.keys(subProps).length > 0) { @@ -217,7 +169,6 @@ function renderBody(section: ConfigSectionContribution): string[] { lines.push(...renderFieldComments(subProps, jsonSchema, ' ')); continue; } - // An array-of-objects field carries its element fields inline. const itemProps = asJsonSchema( resolveRef(asJsonSchema(resolved)?.items, jsonSchema), )?.properties; @@ -231,7 +182,6 @@ function renderBody(section: ConfigSectionContribution): string[] { return lines; } - // Record section — one sub-table per entry. if (jsonSchema.additionalProperties !== undefined) { const valueSchema = resolveRef(jsonSchema.additionalProperties, jsonSchema); const valueProps = asJsonSchema(valueSchema)?.properties; @@ -247,10 +197,6 @@ function renderBody(section: ConfigSectionContribution): string[] { return lines; } - // Array-of-tables section — one `[[section]]` entry per element. There is - // no `[section]` parent table in TOML, so the whole shape stays commented; - // emitting a bare `[${key}]` header would parse as a plain table, which - // array sections (e.g. `hooks`) reject on load. if (jsonSchema.type === 'array') { const itemProps = asJsonSchema(resolveRef(jsonSchema.items, jsonSchema))?.properties; if (isRecord(itemProps) && Object.keys(itemProps).length > 0) { @@ -262,7 +208,6 @@ function renderBody(section: ConfigSectionContribution): string[] { } } - // Scalar / array section — a plain top-level key. if (options.defaultValue !== undefined) { return [`${key} = ${truncate(toTomlValue(options.defaultValue))}`]; } @@ -302,12 +247,7 @@ function renderSection(section: ConfigSectionContribution, owner: string | undef return lines; } -// --------------------------------------------------------------------------- -// Manifest rendering -// --------------------------------------------------------------------------- - export async function buildConfigManifest(): Promise { - // "import = register": loading the package root fills the contribution bags. await import('../src/index.ts'); const sections = getConfigSectionContributions().toSorted((a, b) => a.domain.localeCompare(b.domain), @@ -345,10 +285,6 @@ export async function buildConfigManifest(): Promise { return out.join('\n'); } -// --------------------------------------------------------------------------- -// CLI -// --------------------------------------------------------------------------- - async function main(): Promise { const check = process.argv.includes('--check'); const manifest = await buildConfigManifest(); diff --git a/packages/agent-core-v2/scripts/gen-state-manifest.mts b/packages/agent-core-v2/scripts/gen-state-manifest.mts index 4471cb4ee..1a0cc7be9 100644 --- a/packages/agent-core-v2/scripts/gen-state-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-state-manifest.mts @@ -1,39 +1,3 @@ -/** - * Generates `docs/state-manifest.d.ts` — the single place to see every state - * key registered into the four scoped state services (App-scope - * `IAppStateService`, Workspace-scope `IWorkspaceStateService`, Session-scope - * `ISessionStateService`, Agent-scope `IAgentStateService`). - * - * Pure static pass (state keys are registered inside DI scope constructors, so - * there is no process-level registry to drain the way `gen-wire-manifest` - * does): - * 1. A ts-morph scan of `src/{app,workspace,session,agent,features}/**` - * collects every top-level `defineState('name', ...)` key constant. - * 2. Every `.register(key)` call site resolves its argument back to a key - * constant (following imports); the key joins the scope of the - * registering file (`src/app/**` → App, `src/workspace/**` → Workspace, - * `src/session/**` → Session, `src/agent/**` → Agent). Files under - * `src/features/**` register into whichever scope their services are - * materialized in, so the scope is resolved from the register-call - * receiver's type (`IAgentStateService` → Agent, …). - * A key that is defined but never registered is excluded. - * - * The output is a self-contained `.d.ts`: each key's value type is the - * compile-time `StateKey` parameter, expanded fully inline through the type - * checker — no imports and no helper declarations. Every named type is marked - * at its expansion site with an inline `TypeName — source/file.ts` comment; - * recursion stops with a `TypeName — recursive` marker on an `unknown`. Generic - * instantiations are expanded structurally and classes render as their public - * instance shape; only lib globals (`Map`/`Set`/…) and a few noted external - * ambient types keep their names. - * - * Usage: - * pnpm --filter @moonshot-ai/agent-core-v2 gen:state-manifest # write the file - * pnpm --filter @moonshot-ai/agent-core-v2 gen:state-manifest --check # freshness check (CI-style) - * - * Freshness is also enforced by `test/state/stateManifest.test.ts`. - */ - import { readFileSync, writeFileSync } from 'node:fs'; import { join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -59,7 +23,6 @@ const REPO_ROOT = join(PKG, '..', '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'state-manifest.d.ts'); -/** src first-level directory → manifest section. */ const SCOPES = [ { dir: 'app', @@ -92,11 +55,9 @@ type ScopeDir = (typeof SCOPES)[number]['dir']; interface KeyDef { readonly constName: string; readonly keyName: string; - /** Absolute path of the file defining the key constant. */ readonly file: string; readonly exported: boolean; readonly declaration: VariableDeclaration; - /** Present when the key chains `.replayable(...)` — the key is materialized into the Agent-scope state service. */ readonly replayable?: { readonly durable: boolean; readonly undoable: boolean; @@ -111,7 +72,6 @@ interface Registration { interface StateManifestModel { readonly registrations: readonly Registration[]; - /** Keys defined under the scope dirs but never registered (dead candidates). */ readonly unregistered: readonly KeyDef[]; } @@ -124,7 +84,6 @@ function isFeaturesFile(file: string): boolean { return relative(SRC, file).split(/[\\/]/)[0] === 'features'; } -/** Feature files register into the scope of their materialized services — resolve it from the register-call receiver's state-service type. */ const FEATURES_RECEIVER_SCOPE: Readonly> = { IAppStateService: 'app', IWorkspaceStateService: 'workspace', @@ -132,7 +91,6 @@ const FEATURES_RECEIVER_SCOPE: Readonly> = { IAgentStateService: 'agent', }; -/** Resolve the scope from the contributeState-call receiver's state-service type. */ function receiverScope( expression: PropertyAccessExpression, checker: TypeChecker, @@ -157,36 +115,23 @@ function featuresRegisterScope( return scope; } -/** Package-root-relative posix path (used in index/comment columns). */ function srcRelative(file: string): string { return relative(PKG, file).split('\\').join('/'); } -/** Repo-root-relative posix path (used in type-name comments). */ function repoRelative(file: string): string { return relative(REPO_ROOT, file).split('\\').join('/'); } -/** Quote a property key only when it is not a plain identifier. */ function tsFieldKey(key: string): string { return /^[$A-Z_a-z][$\w]*$/.test(key) ? key : JSON.stringify(key); } -/** - * The checker names a `unique symbol` key `__@@` — - * the numeric id is a compilation-global counter that shifts with unrelated - * edits, so the manifest renders the stable `__@` form instead. - */ function stableSymbolKey(key: string): string { const match = /^__@(.+)@\d+$/.exec(key); return match === null ? key : `__@${match[1]}`; } -// --------------------------------------------------------------------------- -// Static pass — key constants and their register call sites -// --------------------------------------------------------------------------- - -/** Pass 1 — every top-level `defineState('name', ...)` constant under the scope dirs. */ function collectKeyDefs(project: Project): Map { const defs = new Map(); for (const sf of project.getSourceFiles()) { @@ -212,11 +157,6 @@ function collectKeyDefs(project: Project): Map { return defs; } -/** - * Walk a `defineState('name', ...)` / `.replayable({...})` / `.undoable(...)` / - * `.on(Event, fold)` call chain down to the `defineState` call; returns the key - * name plus the replayable metadata when the chain promotes the key. - */ function parseDefineStateChain( initializer: CallExpression, ): { keyName: string; replayable?: KeyDef['replayable'] } | undefined { @@ -260,7 +200,6 @@ function parseDefineStateChain( } } -/** Resolve a `.register(...)` argument back to its `defineState` constant. */ function resolveKeyDef( identifier: Identifier, defs: ReadonlyMap, @@ -275,7 +214,6 @@ function resolveKeyDef( return undefined; } -/** Pass 2 — every `.register(key)` call site whose argument is a state key. */ function collectRegistrations( project: Project, defs: ReadonlyMap, @@ -331,36 +269,19 @@ function createProject(): Project { return project; } -// --------------------------------------------------------------------------- -// Type expansion — render every key's value type fully inline. -// -// Every named type declared in the repo is expanded at the use site and marked -// with a `/* TypeName — source/file.ts */` comment; a recursion point stops -// with a `/* TypeName — recursive (...) */ unknown` marker. Types from lib -// (`Map`, `Set`, `Date`, …) or node_modules are ambient and keep their names -// (type arguments are still rendered recursively). Generic instantiations and -// anonymous shapes are expanded structurally from their apparent members, so -// the checker always hands us substituted, concrete member types. -// --------------------------------------------------------------------------- - const NO_TRUNCATION = ts.TypeFormatFlags.NoTruncation; class TypeRenderer { private readonly checker: ts.TypeChecker; - /** Cycle guard for anonymous / generic-instantiation structural expansion. */ private readonly expanding = new Set(); - /** Named types currently being expanded along this path (recursion guard). */ private readonly expandingNamed: ts.Symbol[] = []; - /** Ambient names kept as-is whose declaration lives outside the TS lib. */ readonly externals = new Set(); - /** Degradations worth reporting (cycle fallbacks). */ readonly warnings = new Set(); constructor(private readonly project: Project) { this.checker = project.getTypeChecker().compilerObject; } - /** Render the value type `T` of a key's `StateKey`. */ renderKeyType(def: KeyDef): string { const valueType = def.declaration.getType().getTypeArguments()[0]; if (valueType === undefined) { @@ -371,8 +292,6 @@ class TypeRenderer { return this.renderType(valueType, def.declaration, 0); } - // -- core dispatch -------------------------------------------------------- - private renderType( type: MorphType, location: Node, @@ -381,12 +300,10 @@ class TypeRenderer { ): string { if (depth > 40) return this.fallback(type, location, 'depth cap'); - // A single enum-literal type (e.g. `FaultKind.A`) — value + enum comment. if ((type.getFlags() & ts.TypeFlags.EnumLiteral) !== 0) { return this.renderEnumLiteral(type); } - // The boolean union (`false | true`) collapses to `boolean`. if (type.isUnion() && (type.getFlags() & ts.TypeFlags.Boolean) !== 0) return 'boolean'; if (type.isUnion()) { @@ -431,11 +348,6 @@ class TypeRenderer { return this.fallback(type, location, 'unhandled type kind'); } - /** - * Render union members: a `false | true` pair anywhere collapses to - * `boolean`, `null`/`undefined` sort last, duplicates removed, and parens - * are only added when the union actually has multiple members. - */ private renderUnionMembers( members: readonly MorphType[], location: Node, @@ -488,10 +400,8 @@ class TypeRenderer { ); } - /** typeToString is only safe on leaf types (never emits `import(...)`). */ private leafText(type: MorphType): string { const text = this.checker.typeToString(type.compilerType, undefined, NO_TRUNCATION); - // Normalize double-quoted string literals to the repo's single-quote style. if (text.length >= 2 && text.startsWith('"') && text.endsWith('"')) { const value = JSON.parse(text) as string; return value.includes("'") ? JSON.stringify(value) : `'${value}'`; @@ -509,9 +419,6 @@ class TypeRenderer { return text; } - // -- enums ---------------------------------------------------------------- - - /** The literal value of an enum-literal type, quoted TS-style. */ private enumLiteralValue(type: MorphType): string { const value = (type.compilerType as ts.LiteralType).value; if (typeof value === 'string') { @@ -521,7 +428,6 @@ class TypeRenderer { return this.leafText(type); } - /** The enum declaration backing an enum-literal type, if any. */ private enumDeclOf(type: MorphType): Node | undefined { const memberDecl = type.getSymbol()?.getDeclarations()[0]; if (memberDecl === undefined || !Node.isEnumMember(memberDecl)) return undefined; @@ -540,7 +446,6 @@ class TypeRenderer { return text; } - /** Collapse a union covering every member of one enum: comment + values. */ private tryRenderEnumUnion(type: MorphType): string | undefined { const members = type.getUnionTypes(); if (members.length === 0) return undefined; @@ -560,13 +465,6 @@ class TypeRenderer { return `/* ${sym.getName()} — ${repoRelative(enumDecl.getSourceFile().getFilePath())} */ ${values.join(' | ')}`; } - // -- named-type annotation -------------------------------------------------- - - /** - * Where do the symbol's declarations live: repo ('named' — expand inline - * with a name comment), lib/node_modules ('ambient' — keep the name), or - * mixed/anonymous ('inline' — expand without a comment). - */ private classify(sym: MorphSymbol): 'named' | 'ambient' | 'inline' { const decls = sym.getDeclarations(); if (decls.length === 0) return 'inline'; @@ -599,10 +497,6 @@ class TypeRenderer { } } - /** - * `Name — origin` comment prefixed to the expansion. A named type already - * on the expansion path stops with a recursion marker instead. - */ private renderNamed(sym: MorphSymbol, expand: () => string): string { const decl = sym.getDeclarations()[0]; const origin = @@ -621,14 +515,6 @@ class TypeRenderer { } } - /** - * Render a type through the alias it was referenced with, when that alias is - * worth keeping: a repo-declared non-generic alias expands inline under its - * name comment; a lib or node_modules alias (`Readonly`, `Record`, - * `Partial`, …) is referenced as `Name` with recursive arguments. - * `skipSymbol` suppresses the alias's own annotation while its right-hand - * side is being rendered (the alias type still carries itself as aliasSymbol). - */ private tryRenderAlias( type: MorphType, location: Node, @@ -655,8 +541,6 @@ class TypeRenderer { return undefined; } - // -- object types ----------------------------------------------------------- - private renderObjectType( type: MorphType, location: Node, @@ -667,8 +551,6 @@ class TypeRenderer { if (alias !== undefined) return alias; const sym = type.getSymbol(); const typeArgs = type.getTypeArguments(); - // `__type`/`__object` are checker names for anonymous shapes — they are - // never real symbols, so skip the named-type paths and expand structurally. const anonymous = sym === undefined || /^__(type|object)$/.test(sym.getName()); if (!anonymous && sym.compilerSymbol !== skipSymbol) { const kind = this.classify(sym); @@ -686,9 +568,7 @@ class TypeRenderer { return this.renderStructural(type, location, depth); } - /** Structural rendering from the type's apparent members (braced or arrow). */ private renderStructural(type: MorphType, location: Node, depth: number): string { - // Cycle guard for self-referential instantiations expanded inline. if (this.expanding.has(type.compilerType)) { return this.fallback(type, location, 'cycle expanding'); } @@ -719,7 +599,6 @@ class TypeRenderer { } } - /** Member lines of an object type, each indented by two spaces. */ private renderObjectBody( type: MorphType, location: Node, @@ -736,7 +615,6 @@ class TypeRenderer { const at = decl ?? location; const propType = prop.getTypeAtLocation(at); const optional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0; - // An optional prop's `| undefined` is redundant with the `?` — drop it. const rendered = optional && propType.isUnion() ? this.renderUnionMembers( @@ -818,10 +696,6 @@ class TypeRenderer { } } -// --------------------------------------------------------------------------- -// Manifest rendering -// --------------------------------------------------------------------------- - function renderManifest( model: StateManifestModel, project: Project, @@ -837,7 +711,6 @@ function renderManifest( ); } - // Snapshot interfaces — rendering these fills the external-name registry. const sections: string[] = []; for (const scope of SCOPES) { const regs = byScope.get(scope.dir) ?? []; @@ -969,10 +842,6 @@ export function buildStateManifest(): string { return buildAll().manifest; } -// --------------------------------------------------------------------------- -// CLI -// --------------------------------------------------------------------------- - function main(): void { const check = process.argv.includes('--check'); const { model, manifest, warnings } = buildAll(); diff --git a/packages/agent-core-v2/scripts/gen-wire-manifest.mts b/packages/agent-core-v2/scripts/gen-wire-manifest.mts index 6841df8bb..1c65088e4 100644 --- a/packages/agent-core-v2/scripts/gen-wire-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-wire-manifest.mts @@ -1,28 +1,3 @@ -/** - * Generates `docs/wire-manifest.d.ts` — the single place to see every durable - * wire record type declared as an `Event2` subclass (`static type` + - * `static durable = true` + `static schema`). - * - * Two passes: - * 1. Static scan of `src/**` maps each durable event type to the source file - * that declares it — the "owner" — and collects the migration chain from - * `src/wire/migration/v*.ts`. - * 2. Runtime pass imports `src/index.ts` plus every event/state module found - * in the static pass ("import = register") and drains `EVENT2_REGISTRY` - * (type → class → schema) and `REPLAYABLE_STATE_KEYS` (folding states, blob - * codecs) exactly as the running process sees them. - * - * The output is a `.d.ts` — one payload declaration per record type, with a - * `WirePayloadMap` from record type to declaration — using real TypeScript - * type syntax for the sketches. - * - * Usage: - * pnpm --filter @moonshot-ai/agent-core-v2 gen:wire-manifest # write the file - * pnpm --filter @moonshot-ai/agent-core-v2 gen:wire-manifest --check # freshness check (CI-style) - * - * Freshness is also enforced by `test/wire/wireManifest.test.ts`. - */ - import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; import { dirname, join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -43,10 +18,6 @@ const PKG = join(import.meta.dirname, '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'wire-manifest.d.ts'); -// --------------------------------------------------------------------------- -// Static pass — durable event type → owner file; migration chain -// --------------------------------------------------------------------------- - function walk(dir: string, out: string[] = []): string[] { for (const entry of readdirSync(dir)) { const p = join(dir, entry); @@ -60,14 +31,6 @@ const TYPE_DECL_RE = /static\s+override\s+readonly\s+type\s*=\s*'([^']+)'/g; const DURABLE_DECL_RE = /static\s+override\s+readonly\s+durable\s*=\s*true/; const CLASS_DECL_RE = /class\s+(\w+)\s+extends\s+Event2/g; -/** - * event type → owner file (relative to the package root), the files worth - * importing for the runtime pass, the types statically declared durable - * (the class window between one `type` declaration and the next carries - * `durable = true`), and the event class name → type map (the class window - * between one `class … extends Event2` declaration and the next carries one - * `static type`). - */ function scanEventDeclarations(): { owners: Map; importFiles: string[]; @@ -104,7 +67,6 @@ function scanEventDeclarations(): { return { owners, importFiles, durableTypes, classTypes }; } -/** `1.0 -> 1.1 -> ...` chain read from the `src/wire/migration/v*.ts` files. */ function scanMigrationChain(): string { const dir = join(SRC, 'wire', 'migration'); const pairs: { source: string; target: string }[] = []; @@ -122,10 +84,6 @@ function scanMigrationChain(): string { return chain.join(' -> '); } -// --------------------------------------------------------------------------- -// Static pass — replayable state keys and their fold targets -// --------------------------------------------------------------------------- - interface ReplayableStateScan { readonly keyName: string; readonly constName: string; @@ -138,7 +96,6 @@ const ON_FOLD_RE = /\.on\(\s*([A-Za-z_$][\w$]*)/g; const KEY_ON_RE = /\b([A-Za-z_$][\w$]*)\.on\(\s*([A-Za-z_$][\w$]*)/g; const PROTOCOL_EVENT_RE = /(?:appendMessage|applyCompaction|clear|undo):\s*([A-Za-z_$][\w$]*)/g; -/** Balanced-paren read of the argument list starting at the `(` after a chain method. */ function readCallArguments(text: string, parenIndex: number): string { let depth = 0; for (let i = parenIndex; i < text.length; i++) { @@ -161,11 +118,6 @@ function readCallArguments(text: string, parenIndex: number): string { return text.slice(parenIndex + 1); } -/** - * `readExpression` variant for `defineState(...)` chains: the fold bodies are - * arbitrary code, where `<` / `>` are comparison operators as often as generic - * brackets — only `()` `{}` `[]` delimit the statement reliably. - */ function readChain(source: string, start: number): string { let depth = 0; const n = source.length; @@ -214,8 +166,6 @@ function scanReplayableStates(): ReplayableStateScan[] { byConst.set(constName, scan); } } - // A key's fold vocabulary may grow outside its defining chain - // (`otherKey.on(Event, …)` in a feature module). for (const file of walk(SRC)) { const source = readFileSync(file, 'utf-8'); if (!source.includes('.on(')) continue; @@ -229,7 +179,6 @@ function scanReplayableStates(): ReplayableStateScan[] { return states; } -/** The four undoable-protocol event types, resolved through the class-name map. */ function scanUndoableProtocolTypes(classTypes: ReadonlyMap): string[] { for (const file of walk(SRC)) { const source = readFileSync(file, 'utf-8'); @@ -252,23 +201,12 @@ function scanUndoableProtocolTypes(classTypes: ReadonlyMap): str throw new Error('[gen-wire-manifest] registerUndoableProtocol call not found under src/'); } -// --------------------------------------------------------------------------- -// Payload sketch -// -// A Sketch is a small tree: strings are one-line type annotations, dicts are -// object shapes, and a one-element array marks an array-of shape. The d.ts -// renderer below turns the tree into real TypeScript syntax. -// --------------------------------------------------------------------------- - type SketchDict = { [key: string]: Sketch }; type Sketch = string | SketchDict | [Sketch]; -/** First key of a dict produced by expanding a named type. */ const TYPE_KEY = '_type'; -/** Marker key rendered as a `// …` comment when a field list is capped. */ const MORE_KEY = '…'; -/** Compact one-line rendering of a Sketch (used inside unions/intersections). */ function stringifySketch(sketch: Sketch): string { if (typeof sketch === 'string') return sketch; if (Array.isArray(sketch)) { @@ -280,7 +218,6 @@ function stringifySketch(sketch: Sketch): string { .join(', ')} }`; } -/** Build a Sketch tree from a zod JSON-schema projection. */ function sketchFromJsonSchema(schema: unknown, root: JsonSchema, depth: number): Sketch { const resolved = resolveRef(schema, root); const s = asJsonSchema(resolved); @@ -301,7 +238,6 @@ function sketchFromJsonSchema(schema: unknown, root: JsonSchema, depth: number): return describeType(resolved, tsQuote); } -/** Build the payload Sketch tree for one op (all three data paths converge). */ function buildPayloadSketch( schema: unknown, staticSketch?: string | Map, @@ -322,7 +258,6 @@ function buildPayloadSketch( } return dict; } - // An empty object schema (`z.object({})`) is a payload-less record. if ( jsonSchema.type === 'object' && (jsonSchema.additionalProperties === undefined || jsonSchema.additionalProperties === false) @@ -332,10 +267,6 @@ function buildPayloadSketch( return describeType(jsonSchema, tsQuote); } -// --------------------------------------------------------------------------- -// d.ts rendering — Sketch tree → TypeScript declarations -// --------------------------------------------------------------------------- - function pascalCase(name: string): string { return name .split(/[^A-Za-z0-9]+/) @@ -348,11 +279,6 @@ function tsFieldKey(key: string): string { return /^[$A-Z_a-z][$\w]*$/.test(key) ? key : JSON.stringify(key); } -/** - * Convert a one-line sketch annotation into a valid TS type expression. - * Returns the type plus an optional doc note (the expanded type's name, or a - * hoisted shared spread that cannot be expressed inline). - */ function sketchStringToTs(text: string): { type: string; doc?: string } { let t = text.trim(); const docs: string[] = []; @@ -361,7 +287,6 @@ function sketchStringToTs(text: string): { type: string; doc?: string } { docs.push(named[1]); t = named[2].trim(); } - // A hoisted shared spread (`...base & A | B`) becomes a doc note + variants. const spread = /^((?:\.\.\.[$\w]+(?: \+ )?)+) & ([\s\S]+)$/.exec(t); if (spread?.[1] !== undefined && spread[2] !== undefined) { docs.push(`shared base: ${spread[1]}`); @@ -373,10 +298,6 @@ function sketchStringToTs(text: string): { type: string; doc?: string } { return { type: t, doc: docs.length > 0 ? docs.join(' · ') : undefined }; } -/** - * Render a Sketch as TS type-expression lines. The first line continues after - * the field's `key: `; subsequent lines carry `indent`. - */ function renderTsType(sketch: Sketch, indent: string): { doc?: string; lines: string[] } { if (typeof sketch === 'string') { const { type, doc } = sketchStringToTs(sketch); @@ -401,7 +322,7 @@ function emitTsDict(lines: string[], dict: SketchDict, indent: string): void { lines.push(`${indent}// …`); continue; } - if (key === TYPE_KEY) continue; // surfaces as the field's doc comment + if (key === TYPE_KEY) continue; if (key.startsWith('...')) { lines.push(`${indent}// spread: ${key}`); continue; @@ -418,7 +339,6 @@ function emitTsDict(lines: string[], dict: SketchDict, indent: string): void { } } -/** One record type's payload declaration (`interface` for objects, `type` otherwise). */ function renderPayloadDecl( entry: { type: string }, owner: string | undefined, @@ -436,7 +356,6 @@ function renderPayloadDecl( if (typeof sketch === 'string') { const { type, doc } = sketchStringToTs(sketch); if (type.startsWith('(')) { - // Unrepresentable schema note — keep the declaration parseable. header.push(` * ${type.slice(1, -1)}`); header.push(' */'); return [...header, `interface ${name} {\n ${nameField}\n}`, '']; @@ -470,12 +389,6 @@ function renderPayloadDecl( return lines; } -// --------------------------------------------------------------------------- -// Static payload fallback — sketch fields from source when the zod schema -// cannot be projected to JSON Schema (payloads using `z.custom()`) -// --------------------------------------------------------------------------- - -/** Find the index of the closer matching the opener at `start` (quotes-aware). */ function matchDelimiter(source: string, start: number, open: string, close: string): number { let depth = 0; for (let i = start; i < source.length; i++) { @@ -509,7 +422,6 @@ function matchDelimiter(source: string, start: number, open: string, close: stri return -1; } -/** Split `body` into top-level parts on any of `separators` (quotes/nesting-aware). */ function splitTopLevel(body: string, separators: readonly string[] = [',']): string[] { const parts: string[] = []; let depth = 0; @@ -537,7 +449,6 @@ function splitTopLevel(body: string, separators: readonly string[] = [',']): str return parts.filter((p) => p !== ''); } -/** Split an object literal's body into top-level `key: expr` fields. */ function splitObjectFields(body: string): Map { const fields = new Map(); for (const part of splitTopLevel(body)) { @@ -552,13 +463,11 @@ function splitObjectFields(body: string): Map { return fields; } -/** Extract the body of the first balanced `{...}` in `text` starting at `braceIndex`. */ function objectBody(text: string, braceIndex: number): string | undefined { const end = matchDelimiter(text, braceIndex, '{', '}'); return end === -1 ? undefined : text.slice(braceIndex + 1, end); } -/** Read one expression from `start` up to the top-level `;` that ends the statement. */ function readExpression(source: string, start: number): string { let depth = 0; const n = source.length; @@ -580,7 +489,6 @@ function readExpression(source: string, start: number): string { return source.slice(start); } -/** Quote a string literal TS-style (single quotes) so sketches need no JSON escapes. */ function tsQuote(raw: string): string { return raw.includes("'") ? JSON.stringify(raw) : `'${raw}'`; } @@ -589,15 +497,12 @@ function escapeRegExp(raw: string): string { return raw.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'); } -/** Resolve a `schema:` expression to an object-literal body, following local consts. */ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | undefined { if (depth > 2) return undefined; - // z.object({ ... }) / z.strictObject({ ... }) — inline literal. const inline = /^z\.\w*[oO]bject\s*\(/.exec(expr); if (inline !== null) { const rest = expr.slice(inline[0].length).trimStart(); if (rest.startsWith('{')) return objectBody(rest, 0); - // z.object(SHAPE_CONST) — look up the local shape const. const shapeName = /^([$\w]+)/.exec(rest)?.[1]; if (shapeName !== undefined) { const constRe = new RegExp(`const\\s+${shapeName}\\s*(?::[^=;]+)?=\\s*\\{`); @@ -606,7 +511,6 @@ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | } return undefined; } - // schema: SOME_CONST — follow `const X = z.object(...)` in the same file. const ident = /^([$\w]+)$/.exec(expr.trim())?.[1]; if (ident !== undefined) { const constRe = new RegExp(`const\\s+${ident}\\s*(?::[^=;]+)?=\\s*`); @@ -619,13 +523,6 @@ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | return undefined; } -// --------------------------------------------------------------------------- -// TS type summarizer — expand `z.custom()` type names into readable sketches -// by resolving the alias (or interface) across local definitions, imports, and -// re-exports. Discriminated unions collapse to `union on type: "a" | "b"`. -// Resolution work is bounded by a per-expansion step budget. -// --------------------------------------------------------------------------- - interface Budget { remaining: number; } @@ -654,7 +551,6 @@ interface TsField { readonly optional: boolean; } -/** Split a TS object type literal body into fields (separators: `;` / `,`). */ function splitTsTypeFields(body: string): Map { const fields = new Map(); for (const part of splitTopLevel(body, [';', ','])) { @@ -697,7 +593,6 @@ function renderTsFields( return dict; } -/** Find a local `type X = ...` / `interface X {...}` definition's RHS text. */ function findTsTypeDef(name: string, file: string): string | undefined { const source = readCached(file); const typeRe = new RegExp(`(?:export\\s+)?type\\s+${name}(?:<[^>;=]*>)?\\s*=\\s*`); @@ -712,7 +607,6 @@ function findTsTypeDef(name: string, file: string): string | undefined { return undefined; } -/** Find the module specifier a name is imported (or named-re-exported) from. */ function findImportSource(file: string, name: string): string | undefined { const source = readCached(file); const re = /(?:import|export)\s+(?:type\s+)?\{([^}]+)\}\s*from\s*'([^']+)'/g; @@ -744,8 +638,6 @@ function summarizeTsUnion( charBudget: number, depth: number, ): string { - // Resolve member idents one level so alias unions (ContextMessage = A | B | C) - // still expose their object shapes. const resolved = members.map((m) => { const t = m.trim(); if (/^[$\w]+$/.test(t)) { @@ -757,7 +649,6 @@ function summarizeTsUnion( const bodies = resolved.map((m) => (m.trim().startsWith('{') ? objectBody(m.trim(), 0) : undefined)); if (bodies.length > 0 && bodies.every((b) => b !== undefined)) { const fieldMaps = bodies.map((b) => splitTsTypeFields(b!)); - // Discriminated union: one field is a string literal in every member. for (const [name, info] of fieldMaps[0]!) { if ( /^'[^']*'$/.test(info.type) && @@ -767,7 +658,6 @@ function summarizeTsUnion( return truncate(`union on ${name}: ${values.join(' | ')}`, charBudget); } } - // Unions stay one-line strings; object members use the compact renderer. return truncate( fieldMaps .map((fm) => stringifySketch(renderTsFields(fm, file, budget, charBudget, depth + 1))) @@ -810,7 +700,6 @@ function summarizeTsTypeExpr( if (intersections.length > 1) { if (!spend(budget)) return truncate(text, 80); const sides = intersections.map((m) => summarizeTsTypeExpr(m, file, budget, charBudget, depth + 1)); - // An intersection of object shapes merges into one dictionary. if (sides.every((side) => typeof side !== 'string' && !Array.isArray(side))) { return Object.assign({}, ...sides) as SketchDict; } @@ -830,7 +719,6 @@ function summarizeTsTypeExpr( return truncate(text, 80); } -/** Resolve a type name to a readable summary across aliases, imports, re-exports. */ function summarizeTsType(name: string, fromFile: string, budget: Budget): Sketch | undefined { if (!spend(budget)) return undefined; const def = findTsTypeDef(name, fromFile); @@ -849,16 +737,8 @@ function summarizeTsType(name: string, fromFile: string, budget: Budget): Sketch return undefined; } -/** - * Render a zod field expression as a Sketch, in the same notation the - * JSON-Schema path produces (`string`, `'a' | 'b'`, `Foo[]`). `z.custom()` - * and bare type idents expand through the TS type summarizer — object shapes - * become nested dicts (keyed with the type name under `_type`), everything - * else stays a one-line string. - */ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { let text = expr.replaceAll(/\s+/g, ' ').trim(); - // Strip trailing modifiers the sketch does not mark. let stripped = true; while (stripped) { stripped = false; @@ -874,8 +754,6 @@ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { const custom = /^z\.custom<(.+)>\(\)$/.exec(text); if (custom?.[1] !== undefined) { const typeName = custom[1].trim(); - // Expand the TS type only at the top levels — nested fields keep the bare - // type name so long union member sketches stay readable. if (depth > 1) return typeName; const summary = summarizeTsType(typeName, ownerFile, TS_BUDGET()); if (summary === undefined) return typeName; @@ -949,14 +827,12 @@ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { return truncate(text, 80); } -/** Sketch a `z.union([...])` body (one-line string); object members get field sketches. */ function friendlyZodUnion(body: string, ownerFile: string, depth: number): string { const members = splitTopLevel(body.trim().replace(/^\[/, '').replace(/\]$/, '')); const source = readCached(ownerFile); const bodies = members.map((m) => resolveSchemaLiteral(m, source)); if (members.length > 0 && bodies.every((b) => b !== undefined)) { const fieldMaps = bodies.map((b) => splitObjectFields(b)); - // Hoist spreads shared by every member (`...base & { … } | { … }`). const spreadSets = fieldMaps.map((fm) => [...fm.keys()].filter((k) => fm.get(k) === '')); const commonSpreads = (spreadSets[0] ?? []).filter((s) => spreadSets.every((set) => set.includes(s)), @@ -979,12 +855,6 @@ function friendlyZodUnion(body: string, ownerFile: string, depth: number): strin ); } -/** - * Best-effort payload sketch from the owner source for schemas that use - * `z.custom` (not representable as JSON Schema). Returns a field map for - * object payloads, a type string for whole-payload custom schemas, or - * `undefined` when the source shape is not recognized. - */ function sketchPayloadFromSource( ownerFile: string, type: string, @@ -1025,15 +895,8 @@ function sketchPayloadFromSource( return sketch; } -// --------------------------------------------------------------------------- -// Manifest rendering -// --------------------------------------------------------------------------- - export async function buildWireManifest(): Promise { const { owners, importFiles, durableTypes, classTypes } = scanEventDeclarations(); - // "import = register": loading the package root plus every event/state module - // found in the static pass fills EVENT2_REGISTRY, even for - // modules index.ts does not load. await import('../src/index.ts'); for (const file of importFiles) { await import(relative(join(PKG, 'scripts'), file)); @@ -1045,7 +908,6 @@ export async function buildWireManifest(): Promise { const entries = [...EVENT2_REGISTRY.values()].toSorted((a, b) => a.type.localeCompare(b.type)); const migrationChain = scanMigrationChain(); - // type → folding states / blob codec owners, scanned from the defineState chains. const folding = new Map(); const protocolTypes = scanUndoableProtocolTypes(classTypes); for (const state of scanReplayableStates()) { @@ -1138,7 +1000,6 @@ export async function buildWireManifest(): Promise { declNames.push([entry.type, `${pascalCase(entry.type)}Payload`]); } - // Record type → payload declaration map. out.push('/** Record type → payload sketch. */'); out.push('interface WirePayloadMap {'); for (const [type, declName] of declNames) { @@ -1149,10 +1010,6 @@ export async function buildWireManifest(): Promise { return out.join('\n'); } -// --------------------------------------------------------------------------- -// CLI -// --------------------------------------------------------------------------- - async function main(): Promise { const check = process.argv.includes('--check'); const manifest = await buildWireManifest(); diff --git a/packages/agent-core-v2/scripts/lib/jsonSchema.mts b/packages/agent-core-v2/scripts/lib/jsonSchema.mts index a04b4d491..dafca8175 100644 --- a/packages/agent-core-v2/scripts/lib/jsonSchema.mts +++ b/packages/agent-core-v2/scripts/lib/jsonSchema.mts @@ -1,11 +1,3 @@ -/** - * Shared JSON-schema helpers for the manifest generators - * (`gen-config-manifest.mts`, `gen-wire-manifest.mts`). - * - * Both generators drain runtime registries that carry zod schemas and render - * field/type sketches from their JSON Schema projection. - */ - import { z } from 'zod'; export function isRecord(value: unknown): value is Record { @@ -76,9 +68,6 @@ export function describeType( } if (s.type === 'array') return `${describeType(s.items, quoteString)}[]`; if (s.type === 'object') { - // Named sub-tables (zod objects emit `additionalProperties: false`) are - // rendered by the caller; only a schema-valued additionalProperties marks - // a true record. if (isRecord(s.properties)) return 'object'; if (isRecord(s.additionalProperties)) { return `record`; diff --git a/packages/agent-core-v2/src/_base/asyncEventQueue.ts b/packages/agent-core-v2/src/_base/asyncEventQueue.ts index a917d87a6..e49240fd7 100644 --- a/packages/agent-core-v2/src/_base/asyncEventQueue.ts +++ b/packages/agent-core-v2/src/_base/asyncEventQueue.ts @@ -1,17 +1,3 @@ -/** - * `_base.asyncEventQueue` — push-based async iterable. - * - * Bridges a callback-driven producer (e.g. a streaming LLM's `onMessagePart`) - * to an async-generator consumer. Values pushed while there is a pending - * `next()` waiter are delivered immediately; otherwise they buffer in-order. - * `end()` signals normal termination; `fail(err)` terminates with an error - * that is thrown at the next `next()` (once the buffered values have been - * drained). Idempotent — repeated `end`/`fail`/`push` after termination are - * no-ops. - * - * Layer L0 substrate. - */ - export class AsyncEventQueue implements AsyncIterable, AsyncIterator { private readonly values: T[] = []; private readonly waiters: Array<{ diff --git a/packages/agent-core-v2/src/_base/contribution/registry.ts b/packages/agent-core-v2/src/_base/contribution/registry.ts index 5db87eb20..9c3f23092 100644 --- a/packages/agent-core-v2/src/_base/contribution/registry.ts +++ b/packages/agent-core-v2/src/_base/contribution/registry.ts @@ -1,19 +1,3 @@ -/** - * `_base/contribution` domain — generic source-keyed contribution - * registry. - * - * The storage half of the Contribution / Registry / Catalog extension-point - * pattern: a *contribution* is a plain data structure offered by an outer - * contributor (a loader, a plugin, a code module); the *registry* stores at - * most one contribution per `sourceId` — re-registering the same `sourceId` - * replaces the previous entry, which is the only dedup this layer performs. - * Content-level dedup (e.g. by item name), ordering, and merge rules are the - * Catalog's projection job, never the registry's. `register` returns a handle - * whose `dispose` unregisters — but only the entry it registered, so a stale - * handle can never evict a newer re-registration. Every mutation fires - * `onDidChange` with the affected `sourceId` so catalogs can re-project. - */ - import { Disposable, type IDisposable } from '../di/lifecycle'; import { Emitter, type Event } from '../event'; @@ -27,7 +11,6 @@ export interface RegisterContributionOptions { readonly priority?: number; } -// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ContributionRegistry extends Disposable { private readonly registrations = new Map>(); private readonly onDidChangeEmitter = this._register(new Emitter()); diff --git a/packages/agent-core-v2/src/_base/di/cascadeEngine.ts b/packages/agent-core-v2/src/_base/di/cascadeEngine.ts index 472100d1f..e33425c37 100644 --- a/packages/agent-core-v2/src/_base/di/cascadeEngine.ts +++ b/packages/agent-core-v2/src/_base/di/cascadeEngine.ts @@ -1,33 +1,3 @@ -/** - * `di` domain — cascade engine + wait scheduler (L2), one per container, with - * tree-wide orchestration (D9: cascades propagate along instance edges across - * scopes). - * - * The dependency graph, request queue, in-flight set, and settle waiters are - * shared by the whole scope tree (`CascadeTree`, owned by the root). Every - * change (provide / unprovide / update) runs as a single transaction - * orchestrated by the engine of the scope where the change was submitted: - * ① compute the contagion set from the tree-global graph; - * ② broadcast WillCascade to the orchestrator's abort hook (bounded wait, - * then forced; failures are best-effort, never a veto); - * ③ tear the contagion set down in global reverse topological order, serially - * (each scope's engine executes its own units; Active → Unloading → - * Pending, or removed for an unprovided token; a descendant scope that dies - * mid-transaction is skipped idempotently); - * ④ apply the change in its own scope (a replace never passes through the - * waiting area); - * ⑤ recheck the waiting area across scopes and rebuild satisfied units in - * global topological order; - * ⑥ append the transaction to the orchestrator's history ring. - * - * Requests serialize through the tree queue; requests queued together merge - * their contagion sets (deduped by scope+token) into one transaction. This is - * one transaction across the tree but not a distributed transaction: a single - * orchestrator, a deterministic order, local execution per scope. Like the - * Ledger, the engine has a sync fast path: with no async abort wait and no - * async disposers, a transaction completes within the tick. - */ - import { onUnexpectedError } from '../errors/unexpectedError'; import { Emitter, type Event } from '../event'; import { isPromiseLike } from '../lifecycle/disposer'; @@ -48,7 +18,6 @@ export type UnitActivation = 'eager' | 'ondemand'; export interface CascadeChange { readonly action: CascadeAction; - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier; readonly descriptor?: SyncDescriptor; readonly instance?: unknown; @@ -96,37 +65,25 @@ export interface CascadeEngineOptions { } export interface CascadeHost { - // eslint-disable-next-line @typescript-eslint/no-explicit-any isRegistered(token: ServiceIdentifier): boolean; - // eslint-disable-next-line @typescript-eslint/no-explicit-any ownerScopeOf(token: ServiceIdentifier): object | undefined; - // eslint-disable-next-line @typescript-eslint/no-explicit-any isMaterialized(token: ServiceIdentifier): boolean; - // eslint-disable-next-line @typescript-eslint/no-explicit-any materialize(token: ServiceIdentifier): unknown; - // eslint-disable-next-line @typescript-eslint/no-explicit-any retire(token: ServiceIdentifier): void | Promise; - // eslint-disable-next-line @typescript-eslint/no-explicit-any applyProvide( - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, descriptor: SyncDescriptor, config: unknown, ): number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any applyProvideInstance( - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, instance: unknown, config: unknown, ): number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any applyUnprovide(token: ServiceIdentifier): void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any recipeOf(token: ServiceIdentifier): SyncDescriptor | undefined; dependenciesOf( recipe: SyncDescriptor, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Array>; } @@ -225,14 +182,11 @@ export class CascadeTree { export class CascadeEngine { private readonly _units = new Map< - // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier, UnitRecord >(); private readonly _pendingIndex = new Map< - // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any Set> >(); private readonly _history: CascadeHistoryEntry[] = []; @@ -256,28 +210,23 @@ export class CascadeEngine { this._options = { ...this._options, ...options }; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any stateOf(token: ServiceIdentifier): UnitState | undefined { return this._units.get(token)?.state; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any activationOf(token: ServiceIdentifier): UnitActivation | undefined { return this._units.get(token)?.activation; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any materializable(token: ServiceIdentifier): boolean { return this._host.recipeOf(token) !== undefined; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any failureOf(token: ServiceIdentifier): unknown { const unit = this._units.get(token); return unit?.state === 'Failed' ? unit.error : undefined; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any isInFlight(token: ServiceIdentifier): boolean { const owner = this._host.ownerScopeOf(token) ?? this._scope; return this._tree.inFlightHas({ scope: owner, token }); @@ -335,7 +284,6 @@ export class CascadeEngine { }); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any update(token: ServiceIdentifier, reason?: string): Promise { return this.submit({ action: 'update', @@ -356,7 +304,6 @@ export class CascadeEngine { } resolveWhenAvailable( - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, timeoutMs?: number, ): Promise { @@ -387,7 +334,6 @@ export class CascadeEngine { }); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any observedMaterialization(token: ServiceIdentifier): void { const unit = this._units.get(token); if (unit !== undefined && unit.state === 'Pending') { @@ -415,9 +361,7 @@ export class CascadeEngine { this._onDidCascade.dispose(); } - _teardownForCascade( - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, tornDown: string[], parkAsPending: boolean, @@ -467,7 +411,6 @@ export class CascadeEngine { } } - private _pump(): void { if (this._tree.running) { return; @@ -505,7 +448,6 @@ export class CascadeEngine { } } - private _transact(batch: QueuedRequest[]): void | Promise { const changes = mergeBatch(batch); const started = this._options.now?.() ?? Date.now(); @@ -656,8 +598,6 @@ export class CascadeEngine { return undefined; } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _unitFor(token: ServiceIdentifier): UnitRecord { let unit = this._units.get(token); if (unit === undefined) { @@ -669,7 +609,6 @@ export class CascadeEngine { } private _setUnitState( - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, unit: UnitRecord, state: UnitState, @@ -687,7 +626,6 @@ export class CascadeEngine { } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _markPending( token: ServiceIdentifier, activation?: UnitActivation, @@ -706,7 +644,6 @@ export class CascadeEngine { private _recheckPending(rebuilt: string[], failed: string[]): void { for (;;) { this._pendingIndex.clear(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any const satisfied: ServiceIdentifier[] = []; for (const [token, unit] of this._units) { if (unit.state !== 'Pending') continue; @@ -747,7 +684,6 @@ export class CascadeEngine { } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _activate(token: ServiceIdentifier, rebuilt: string[], failed: string[]): void { const unit = this._unitFor(token); this._setUnitState(token, unit, 'Activating', undefined); @@ -762,7 +698,6 @@ export class CascadeEngine { } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _missingDeps(token: ServiceIdentifier): Array> { const recipe = this._host.recipeOf(token); if (recipe === undefined) { @@ -773,7 +708,6 @@ export class CascadeEngine { .filter((dep) => !this._isAvailable(dep)); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _isAvailable(dep: ServiceIdentifier): boolean { if (!this._host.isRegistered(dep)) { return false; diff --git a/packages/agent-core-v2/src/_base/di/collection.ts b/packages/agent-core-v2/src/_base/di/collection.ts index 75a96e650..ef7ba3699 100644 --- a/packages/agent-core-v2/src/_base/di/collection.ts +++ b/packages/agent-core-v2/src/_base/di/collection.ts @@ -1,30 +1,8 @@ -/** - * `di` domain — collection tokens, live views, and the tree-global record - * store (L3, D12). - * - * A contribution point is a `collection(name)` token; contributing is - * `this.provide(token, value)` — no registry API. Records physically live - * under the provider's scope and are visible to the provider's ancestors AND - * descendants (never to sibling subtrees): capabilities flow upward, and a - * fold at any tier also sees what its own subtree contributed. Every record - * carries the provider unit's name and scope path so folds can group/filter - * by source. Record lifetime hangs on the provider's book — provider death - * withdraws the record (and scope death tears the provider's book). - * - * A fold service declares the token as a constructor parameter and receives - * a `CollectionView`: `items`/`records` are computed live, `onDidChange` - * delivers incremental `{added, removed}` payloads. Collection edges are - * recorded in the persistent graph for introspection but never join a - * cascade contagion set — a fold refolds incrementally instead of being - * rebuilt. - */ - import { Emitter, type Event } from '../event'; import type { Ledger } from '../lifecycle/ledger'; import { storeCustomDependency, type ServiceIdentifier } from './instantiation'; export interface CollectionToken { - // eslint-disable-next-line @typescript-eslint/no-explicit-any (target: any, key: string | symbol | undefined, index: number): void; readonly name: string; @@ -50,7 +28,6 @@ export function collection( return existing as CollectionToken; } const token = function collectionDecorator( - // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, _key: string | symbol | undefined, index: number, @@ -58,7 +35,6 @@ export function collection( if (arguments.length !== 3) { throw new Error('@CollectionToken-decorator can only be used to decorate a parameter'); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any storeCustomDependency(token as unknown as ServiceIdentifier, 'collection', target, index); } as unknown as CollectionToken; Object.defineProperty(token, 'toString', { diff --git a/packages/agent-core-v2/src/_base/di/dependencyGraph.ts b/packages/agent-core-v2/src/_base/di/dependencyGraph.ts index bfc936e9d..69f574eb8 100644 --- a/packages/agent-core-v2/src/_base/di/dependencyGraph.ts +++ b/packages/agent-core-v2/src/_base/di/dependencyGraph.ts @@ -1,23 +1,7 @@ -/** - * `di` domain — persistent dependency graph (L2 substrate), tree-global. - * - * One graph is shared by every container of a scope tree. Edges are recorded - * when a service's constructor dependencies are resolved and removed when the - * consumer is torn down, so the graph always mirrors the live containers. - * Both ends of an edge are scope-tagged: a consumer in a child scope may bind - * a token owned by an ancestor scope (child → parent only — a parent can never - * resolve a child's token, so cross-tree cycles are impossible by - * construction). Instance edges bind a consumer to its dependency's - * generation (the dependency changes → the consumer is torn down and rebuilt, - * across scopes); collection edges (Phase 3) are recorded for introspection - * but never join a cascade contagion set. - */ - import type { ServiceIdentifier } from './instantiation'; export interface ScopedToken { readonly scope: object; - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier; } @@ -31,7 +15,6 @@ export interface DependencyEdge { export class PairIndex { private readonly _map = new Map, V >>(); @@ -82,7 +65,6 @@ export class DependencyGraph { addInstance( instance: object, scope: object, - // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier, ): void { const ref: ScopedToken = { scope, token }; diff --git a/packages/agent-core-v2/src/_base/di/descriptors.ts b/packages/agent-core-v2/src/_base/di/descriptors.ts index c841d4f5d..e9f81dd58 100644 --- a/packages/agent-core-v2/src/_base/di/descriptors.ts +++ b/packages/agent-core-v2/src/_base/di/descriptors.ts @@ -1,15 +1,8 @@ -/** - * `di` domain — `SyncDescriptor` packaging a constructor and its static arguments. - */ - export class SyncDescriptor { - // eslint-disable-next-line @typescript-eslint/no-explicit-any public readonly ctor: any; constructor( - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: new (...args: any[]) => T, - // eslint-disable-next-line @typescript-eslint/no-explicit-any public readonly staticArguments: ReadonlyArray = [], ) { this.ctor = ctor; diff --git a/packages/agent-core-v2/src/_base/di/errors.ts b/packages/agent-core-v2/src/_base/di/errors.ts index e95353c31..391d8a908 100644 --- a/packages/agent-core-v2/src/_base/di/errors.ts +++ b/packages/agent-core-v2/src/_base/di/errors.ts @@ -1,20 +1,14 @@ -/** - * `di` domain — `CyclicDependencyError` raised on DI dependency cycles. - */ - import type { Graph } from './graph'; export class CyclicDependencyError extends Error { readonly path: ReadonlyArray; - // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(pathOrGraph: ReadonlyArray | Graph) { if (Array.isArray(pathOrGraph)) { const path = pathOrGraph as ReadonlyArray; super(`Cyclic DI dependency detected: ${path.join(' → ')}`); this.path = path; } else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any const graph = pathOrGraph as Graph; const cycle = graph.findCycleSlow(); const detail = cycle ?? `UNABLE to detect cycle, dumping graph:\n${graph.toString()}`; diff --git a/packages/agent-core-v2/src/_base/di/fiber.ts b/packages/agent-core-v2/src/_base/di/fiber.ts index 6c7220b0d..6308adf83 100644 --- a/packages/agent-core-v2/src/_base/di/fiber.ts +++ b/packages/agent-core-v2/src/_base/di/fiber.ts @@ -1,34 +1,3 @@ -/** - * `di` domain — the L3 unit layer: the `Fiber` capability contract, unit - * recipes, and the construction protocol that binds them to a container. - * - * A unit recipe comes in three shapes — a class extending `Service` - * (`service.ts`), a function `(fiber, config) => cleanup`, or an object with - * `apply(fiber, config)` — carrying optional statics (`name` / `inject` / - * `Config`; `Config` is a standard-schema that must validate - * synchronously). A materialized unit receives a `Fiber` facade exposing the - * five capabilities: `provide` (token-bound units, anonymous sub-units, and - * collection records), `effect` (ledger-anchored side effects), `on` (event - * subscriptions), `get` (declared-dependency resolution) and `ref` (live - * references). Every capability returns a `FiberHandle` — a thenable that - * settles once the unit is active, and carries `update` / `dispose`. - * - * `FiberRuntime` never touches the container directly: it delegates to a - * `FiberHost` (implemented by the instantiation service) and anchors every - * teardown into the unit's `Ledger`, so provider death withdraws everything - * the unit provided. `get` is restricted to the recipe's declared - * dependencies (constructor parameters for class recipes, the `inject` - * static for function/object recipes). - * - * The construction protocol bridges class recipes and the container: the - * container pushes a `ConstructionFrame`, the `Service` base buffers - * capability calls made inside the constructor as `BufferedOp`s (answered - * with `PendingFiberHandle`s), and `bindServiceUnit` flushes the buffer - * against the freshly bound runtime once construction finishes — 构造期只写 - * 不读. `ScopeUnits(kind)` mints the per-scope-kind materialization - * collection token folded by `scopeUnits.ts`. - */ - import type { IDisposable } from './lifecycle'; import type { Emitter } from '../event'; import { isPromiseLike, type EffectBody } from '../lifecycle/disposer'; @@ -64,29 +33,23 @@ export interface ConfigSchema { export interface RecipeStatics { readonly name?: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly inject?: readonly ServiceIdentifier[]; readonly Config?: ConfigSchema; } export type ServiceClassRecipe = - // eslint-disable-next-line @typescript-eslint/no-explicit-any (new (...args: any[]) => unknown) & RecipeStatics; export type ServiceFunctionRecipe = (( fiber: Fiber, - // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ) => any) & RecipeStatics; export type ServiceObjectRecipe = { apply( fiber: Fiber, - // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any; } & RecipeStatics; @@ -116,7 +79,6 @@ export interface Fiber { effect(body: EffectBody, label?: string): FiberHandle; - // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter, handler: (e: any) => void): FiberHandle; get(id: ServiceIdentifier): T; @@ -146,10 +108,8 @@ export class ServiceRecipeError extends Error { } export interface ConstructionFrame { - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly ctor: new (...args: any[]) => any; readonly config: unknown; - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier | undefined; readonly host: FiberHost; } @@ -170,7 +130,6 @@ export function currentConstruction(): ConstructionFrame | undefined { export const SERVICE_MARK = Symbol('serviceUnit'); -// eslint-disable-next-line @typescript-eslint/no-explicit-any export function isServiceRecipe(ctor: any): ctor is ServiceClassRecipe { return typeof ctor === 'function' && ctor.prototype?.[SERVICE_MARK] === true; } @@ -201,15 +160,12 @@ export interface FiberHost { }, ): TokenProvideCore; provideTokenInstance(id: ServiceIdentifier, instance: T): TokenProvideCore; - // eslint-disable-next-line @typescript-eslint/no-explicit-any tokenState(id: ServiceIdentifier): string | undefined; - // eslint-disable-next-line @typescript-eslint/no-explicit-any updateToken(id: ServiceIdentifier, config: unknown, hasConfig: boolean): Promise; resolveTokenWhenAvailable(id: ServiceIdentifier): Promise; resolveInstance(id: ServiceIdentifier): T; materializedInstance(id: ServiceIdentifier): T | undefined; liveRef(id: ServiceIdentifier): LiveRef; - // eslint-disable-next-line @typescript-eslint/no-explicit-any recordInstanceEdge(node: object | undefined, id: ServiceIdentifier): void; collectionView(token: CollectionToken): CollectionView; addCollectionRecord( @@ -218,7 +174,6 @@ export interface FiberHost { providerBook: Ledger, value: T, ): () => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any constructService(ctor: new (...args: any[]) => T, config: unknown): T; } @@ -231,7 +186,6 @@ export interface TokenProvideCore { export type FiberEventResolver = ( host: FiberHost, event: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any handler: (e: any) => void, ) => IDisposable; @@ -246,7 +200,6 @@ export function bindServiceUnit(instance: UnitInternals & IDisposable, frame: Co if (buffer === null) { return; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any const ctor = (instance as any).constructor as ServiceClassRecipe; const runtime = new FiberRuntime( frame.host, @@ -316,9 +269,7 @@ export class FiberRuntime implements Fiber { private readonly _book: Ledger, readonly name: string, readonly config: unknown, - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _token: ServiceIdentifier | undefined, - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _declared: ReadonlySet>, private readonly _edgeNode: object | undefined, ) {} @@ -339,9 +290,7 @@ export class FiberRuntime implements Fiber { provide(recipe: ServiceRecipe, opts?: FiberProvideOptions): FiberHandle; provide(token: CollectionToken, value: T): FiberHandle; provide( - // eslint-disable-next-line @typescript-eslint/no-explicit-any first: ServiceIdentifier | ServiceRecipe | CollectionToken, - // eslint-disable-next-line @typescript-eslint/no-explicit-any second?: any, third?: FiberProvideOptions, ): FiberHandle { @@ -384,7 +333,6 @@ export class FiberRuntime implements Fiber { }); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter, handler: (e: any) => void): FiberHandle { let subscription: IDisposable; if (typeof event === 'string') { @@ -443,7 +391,6 @@ export class FiberRuntime implements Fiber { const config = validateConfig(recipe.Config, opts?.config, name); const core = this._host.provideToken( id, - // eslint-disable-next-line @typescript-eslint/no-explicit-any new SyncDescriptor(recipe as new (...args: any[]) => T), { activation: opts?.activation === ScopeActivation.OnDemand ? 'ondemand' : 'eager', diff --git a/packages/agent-core-v2/src/_base/di/graph.ts b/packages/agent-core-v2/src/_base/di/graph.ts index b4d10d9ab..e137209d7 100644 --- a/packages/agent-core-v2/src/_base/di/graph.ts +++ b/packages/agent-core-v2/src/_base/di/graph.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — directed `Graph` with cycle detection for DI instantiation. - */ - export class Node { readonly incoming = new Map>(); readonly outgoing = new Map>(); diff --git a/packages/agent-core-v2/src/_base/di/instantiation.ts b/packages/agent-core-v2/src/_base/di/instantiation.ts index f059ea7a5..4553e8d76 100644 --- a/packages/agent-core-v2/src/_base/di/instantiation.ts +++ b/packages/agent-core-v2/src/_base/di/instantiation.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — service identifiers, `createDecorator`, and the `IInstantiationService` contract. - */ - import type { SyncDescriptor, SyncDescriptor0 } from './descriptors'; import type { CascadeEngine } from './cascadeEngine'; import type { Event } from '../event'; @@ -10,15 +6,12 @@ import type { ServiceCollection } from './serviceCollection'; export type DependencyKind = 'instance' | 'collection' | 'ref'; -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace _util { - // eslint-disable-next-line @typescript-eslint/no-explicit-any export const serviceIds = new Map>(); export const DI_TARGET = '$di$target'; export const DI_DEPENDENCIES = '$di$dependencies'; export interface ServiceDependency { - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly id: ServiceIdentifier; readonly index: number; readonly kind: DependencyKind; @@ -38,11 +31,8 @@ export namespace _util { ); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type export interface DI_TARGET_OBJ extends Function { - // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type [DI_TARGET]: Function; - // eslint-disable-next-line @typescript-eslint/no-explicit-any [DI_DEPENDENCIES]: { id: ServiceIdentifier; index: number; kind: DependencyKind }[]; } } @@ -53,14 +43,12 @@ export interface IConstructorSignature { new (...args: [...Args, ...Services]): T; } -// eslint-disable-next-line @typescript-eslint/no-explicit-any export type GetLeadingNonServiceArgs = TArgs extends [] ? [] : TArgs extends [...infer TFirst, BrandedService] ? GetLeadingNonServiceArgs : TArgs; export interface ServiceIdentifier { - // eslint-disable-next-line @typescript-eslint/no-explicit-any (target: any, key: string | symbol | undefined, index: number): void; readonly type: T; @@ -69,9 +57,7 @@ export interface ServiceIdentifier { } function storeServiceDependency( - // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type target: Function, index: number, kind: DependencyKind = 'instance', @@ -86,10 +72,8 @@ function storeServiceDependency( } export function storeCustomDependency( - // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier, kind: DependencyKind, - // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, index: number, ): void { @@ -103,7 +87,6 @@ export function createDecorator(name: string): ServiceIdentifier { } const id = function serviceDecorator( - // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, _key: string | symbol | undefined, index: number, @@ -158,7 +141,6 @@ export interface LiveRef { export function ref( id: ServiceIdentifier, ): (target: object, key: string | symbol | undefined, index: number) => void { - // eslint-disable-next-line @typescript-eslint/no-explicit-any return function refDecorator(target: any, _key: string | symbol | undefined, index: number): void { if (arguments.length !== 3) { throw new Error('@ref-decorator can only be used to decorate a parameter'); @@ -195,11 +177,9 @@ export interface IInstantiationService { fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS ): R; - // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance(descriptor: SyncDescriptor0): T; createInstance< Ctor extends new ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any ...args: any[] ) => unknown, R extends InstanceType, @@ -222,14 +202,10 @@ export const IInstantiationService: ServiceIdentifier = createDecorator('instantiationService'); export interface ServiceCollectionLike { - // eslint-disable-next-line @typescript-eslint/no-explicit-any set(id: ServiceIdentifier, instanceOrDescriptor: any): unknown; - // eslint-disable-next-line @typescript-eslint/no-explicit-any get(id: ServiceIdentifier): any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any has(id: ServiceIdentifier): boolean; forEach( - // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (id: ServiceIdentifier, value: any) => void, ): void; } diff --git a/packages/agent-core-v2/src/_base/di/instantiationService.ts b/packages/agent-core-v2/src/_base/di/instantiationService.ts index 5a4004291..32bab2052 100644 --- a/packages/agent-core-v2/src/_base/di/instantiationService.ts +++ b/packages/agent-core-v2/src/_base/di/instantiationService.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — `InstantiationService` container (instantiation, child scopes, cycle detection). - */ - import { SyncDescriptor } from './descriptors'; import { CascadeEngine, CascadeTree, type CascadeChange, type CascadeHost } from './cascadeEngine'; import { @@ -41,7 +37,6 @@ import { Ledger, type LedgerEntry } from '../lifecycle/ledger'; import type { Disposer } from '../lifecycle/disposer'; import { ServiceCollection } from './serviceCollection'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars const enum TraceType { None = 0, Creation = 1, @@ -58,7 +53,6 @@ export class Trace { override branch() { return this; } }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any static traceInvocation(_enableTracing: boolean, fn: any): Trace { return !_enableTracing ? Trace._None @@ -68,14 +62,12 @@ export class Trace { ); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any static traceCreation(_enableTracing: boolean, ctor: any): Trace { return !_enableTracing ? Trace._None : new Trace(TraceType.Creation, ctor.name); } private static _totals: number = 0; private readonly _start: number = Date.now(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _dep: [ServiceIdentifier, boolean, Trace?][] = []; private constructor( @@ -83,7 +75,6 @@ export class Trace { readonly name: string | null ) { } - // eslint-disable-next-line @typescript-eslint/no-explicit-any branch(id: ServiceIdentifier, first: boolean): Trace { const child = new Trace(TraceType.Branch, id.toString()); this._dep.push([id, first, child]); @@ -149,7 +140,6 @@ export class InstantiationService implements IInstantiationService { private readonly _instanceEntries = new Map(); private readonly _provideEntries = new Map< - // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier, { readonly entry: LedgerEntry; readonly core: TokenProvideCore } >(); @@ -158,17 +148,14 @@ export class InstantiationService implements IInstantiationService { protected readonly _children = new Set(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _inProgress: ServiceIdentifier[] = []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _activeInstantiations = new Set>(); private readonly _collectionStore: CollectionStore; private readonly _collectionViews = new Map< CollectionToken, - // eslint-disable-next-line @typescript-eslint/no-explicit-any CollectionViewImpl >(); @@ -240,7 +227,6 @@ export class InstantiationService implements IInstantiationService { return (this._parent?.cascadeDepth ?? -1) + 1; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _ownerOf(id: ServiceIdentifier): InstantiationService | undefined { if (this._services.has(id)) { return this; @@ -431,7 +417,6 @@ export class InstantiationService implements IInstantiationService { void this._unprovideCore(id); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _releaseProvideEntry(id: ServiceIdentifier): void { const prev = this._provideEntries.get(id); if (prev !== undefined) { @@ -508,7 +493,6 @@ export class InstantiationService implements IInstantiationService { provideToken: (id, descriptor, options) => this._provideCore(id, descriptor, options), provideTokenInstance: (id: ServiceIdentifier, instance: T) => this._provideCore(id, instance, undefined), - // eslint-disable-next-line @typescript-eslint/no-explicit-any tokenState: (id: ServiceIdentifier) => { const owner = this._ownerOf(id) ?? this; return owner.cascade.stateOf(id); @@ -530,7 +514,6 @@ export class InstantiationService implements IInstantiationService { materializedInstance: (id: ServiceIdentifier): T | undefined => this._materializedInstanceOf(id), liveRef: (id: ServiceIdentifier): LiveRef => this._liveRef(id), - // eslint-disable-next-line @typescript-eslint/no-explicit-any recordInstanceEdge: (node: object | undefined, id: ServiceIdentifier) => { if (node === undefined) { return; @@ -556,7 +539,6 @@ export class InstantiationService implements IInstantiationService { providerBook, value, ), - // eslint-disable-next-line @typescript-eslint/no-explicit-any constructService: (ctor: new (...args: any[]) => T, config: unknown): T => { return this._createInstance(ctor, [], Trace.traceCreation(this._enableTracing, ctor), { config, @@ -622,14 +604,10 @@ export class InstantiationService implements IInstantiationService { return labels.join('/'); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance(descriptor: SyncDescriptor, ...rest: any[]): T; - // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance(ctor: new (...args: any[]) => T, ...rest: any[]): T; createInstance( - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctorOrDescriptor: SyncDescriptor | (new (...args: any[]) => T), - // eslint-disable-next-line @typescript-eslint/no-explicit-any ...rest: any[] ): T { this._assertNotDisposed(); @@ -698,9 +676,7 @@ export class InstantiationService implements IInstantiationService { } } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createInstance(ctor: any, args: unknown[], _trace: Trace, unit?: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any id?: ServiceIdentifier; config?: unknown; }): T { @@ -730,7 +706,6 @@ export class InstantiationService implements IInstantiationService { serviceDependencies.length > 0 ? serviceDependencies[0]!.index : args.length; if (args.length !== firstServiceArgPos) { - // eslint-disable-next-line no-console globalThis.console.trace( `[createInstance] First service dependency of ${(ctor as { name?: string }).name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`, ); @@ -755,7 +730,6 @@ export class InstantiationService implements IInstantiationService { pushConstructionFrame(frame); let instance: T; try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any instance = Reflect.construct(ctor as new (...args: any[]) => T, finalArgs); } finally { popConstructionFrame(); @@ -814,7 +788,6 @@ export class InstantiationService implements IInstantiationService { desc: SyncDescriptor, _trace: Trace, ): T { - // eslint-disable-next-line @typescript-eslint/no-explicit-any type Triple = { id: ServiceIdentifier; desc: SyncDescriptor; _trace: Trace }; const graph = new Graph(data => data.id.toString()); @@ -887,7 +860,6 @@ export class InstantiationService implements IInstantiationService { private _createServiceInstanceWithOwner( id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: any, args: ReadonlyArray = [], _trace: Trace, @@ -908,7 +880,6 @@ export class InstantiationService implements IInstantiationService { private _createServiceInstance( id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: any, args: ReadonlyArray = [], _trace: Trace, @@ -977,7 +948,6 @@ export class InstantiationService implements IInstantiationService { private _getServiceInstanceOrDescriptor( id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ): T | SyncDescriptor | undefined { const instanceOrDesc = this._services.get(id); if (instanceOrDesc === undefined && this._parent) { @@ -988,7 +958,6 @@ export class InstantiationService implements IInstantiationService { private _throwIfStrict(msg: string, printWarning: boolean): void { if (printWarning) { - // eslint-disable-next-line no-console globalThis.console.warn(msg); } if (this._strict) { diff --git a/packages/agent-core-v2/src/_base/di/lifecycle.ts b/packages/agent-core-v2/src/_base/di/lifecycle.ts index 4cb5dc5d1..bc5020698 100644 --- a/packages/agent-core-v2/src/_base/di/lifecycle.ts +++ b/packages/agent-core-v2/src/_base/di/lifecycle.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — disposable lifecycle primitives (`Disposable`, `DisposableStore`, `IDisposable`). - */ - import { onUnexpectedError } from '../errors/unexpectedError'; import { Ledger, type LedgerEntry } from '../lifecycle/ledger'; @@ -340,7 +336,6 @@ export abstract class Disposable implements IDisposable { } } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Disposable { export const None: IDisposable = Object.freeze({ dispose(): void {}, @@ -560,7 +555,6 @@ export class DisposableMap set(key: K, value: V, skipDisposeOnOverwrite = false): void { if (this._isDisposed) { - // eslint-disable-next-line no-console console.warn( new Error( 'Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!', @@ -643,7 +637,6 @@ export class DisposableSet add(value: V): void { if (this._isDisposed) { - // eslint-disable-next-line no-console console.warn( new Error( 'Trying to add a disposable to a DisposableSet that has already been disposed of. The added object will be leaked!', diff --git a/packages/agent-core-v2/src/_base/di/scope.ts b/packages/agent-core-v2/src/_base/di/scope.ts index 3a7fc3438..c9ed73982 100644 --- a/packages/agent-core-v2/src/_base/di/scope.ts +++ b/packages/agent-core-v2/src/_base/di/scope.ts @@ -1,14 +1,3 @@ -/** - * `di` domain — DI Scope tree (`Scope`) and scoped service registry. - * - * Scoped services are resolved when their scope is created by default; - * registrations that defer construction until first resolution use `OnDemand`. - * - * The kernel only knows the scope tree and the `ScopeKind` partial order. - * The tier set is a business concept: the host bootstrap declares it through - * `setScopeTopology` (see `src/app/scopes.ts`). - */ - import { BugIndicatingError } from '../errors/errors'; import { SyncDescriptor } from './descriptors'; import { ScopeActivation, type ProvideAllEntry } from './instantiation'; @@ -54,7 +43,6 @@ const _scopedRegistry: ScopedEntry[] = []; export function registerScopedService( scope: ScopeKind, id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: new (...args: any[]) => T, activation: ScopeActivation = ScopeActivation.OnScopeCreated, domain: string = 'unknown', @@ -78,7 +66,6 @@ export function _clearScopedRegistryForTests(): void { } export type ScopeSeed = ReadonlyArray< - // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly [ServiceIdentifier, unknown] >; diff --git a/packages/agent-core-v2/src/_base/di/scopeUnits.ts b/packages/agent-core-v2/src/_base/di/scopeUnits.ts index 7fd6688a4..7219222c3 100644 --- a/packages/agent-core-v2/src/_base/di/scopeUnits.ts +++ b/packages/agent-core-v2/src/_base/di/scopeUnits.ts @@ -1,31 +1,3 @@ -/** - * `di` domain — the kernel-side `ScopeUnits(kind)` fold (L3, D11/G2). - * - * `ScopeUnits(kind)` is the materialization collection token the kernel mints - * per scope kind. When a scope of that kind is created, this fold watches the - * new scope's live view of the token and materializes every record's recipe - * as a unit INSIDE that scope (cross-scope materialization): a feature - * contributed once at App scope becomes one live unit per Session/Agent - * scope, automatically. - * - * Lifetime rules (per §5.6): - * - the materialized unit's disposal hangs on the RECORD PROVIDER's book — - * disposing the provider retracts the record and tears the materialized - * units down across the tree (连坐); - * - a target scope's natural death tears its materialized units down with it - * (the fold ledger is anchored into the scope's container ledger); both - * anchors are idempotent, so a provider dying mid-teardown is a no-op; - * - records visible at creation are materialized immediately; the view's - * incremental changes reconcile the set by record identity. - * - * A materialized unit's own `this.provide(...)` registrations are ordinary - * token provides in the target scope — they join the graph and cascades as - * usual. The materialized unit itself carries no token identity, so its own - * constructor dependencies do not independently join cascades (feature - * recipes are dependency-free assemblies by convention, per the Plan - * sample); its provided tokens fully participate. - */ - import { onUnexpectedError } from '../errors/unexpectedError'; import type { IDisposable } from './lifecycle'; import { Ledger } from '../lifecycle/ledger'; @@ -118,7 +90,6 @@ export function watchScopeUnits(container: InstantiationService, kind: ScopeKind materialize(record); } } - // Snapshot: `retract()` deletes its own entry from `materialized`. for (const [id, retract] of Array.from(materialized)) { if (!seen.has(id)) { retract(); diff --git a/packages/agent-core-v2/src/_base/di/service.ts b/packages/agent-core-v2/src/_base/di/service.ts index c7c30e74c..66d61583a 100644 --- a/packages/agent-core-v2/src/_base/di/service.ts +++ b/packages/agent-core-v2/src/_base/di/service.ts @@ -1,25 +1,3 @@ -/** - * `di` domain — the `Service` base class for L3 unit recipes. - * - * Extending `Service` turns a class into a unit recipe with the five `Fiber` - * capabilities (`this.provide` / `effect` / `on` / `get` / `ref`). The class - * follows the two-phase construction protocol: inside the constructor — when - * the container builds the instance under a matching `ConstructionFrame` — - * capability calls do not run immediately; they are buffered as - * `BufferedOp`s and answered with `PendingFiberHandle`s, then flushed - * against the real `FiberRuntime` by `bindServiceUnit` right after - * construction (`fiber.ts`). Reads (`get` / `ref`) are forbidden during this - * phase — declare dependencies as constructor parameters instead (构造期只写 - * 不读). A `Service` created by manual `new` never gets a bound runtime, and - * its capability calls throw `FiberProtocolError`. - * - * The `SERVICE_MARK` prototype marker (set below) lets the container - * recognize `Service`-derived class recipes and drive them through this - * protocol; services whose members collide with the `Service` vocabulary - * keep `extends Disposable` and use the function/object recipe forms - * instead. - */ - import type { Emitter } from '../event'; import type { EffectBody } from '../lifecycle/disposer'; import type { Ledger } from '../lifecycle/ledger'; @@ -56,7 +34,6 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals const frame = currentConstruction(); if ( frame !== undefined && - // eslint-disable-next-line @typescript-eslint/no-explicit-any frame.ctor === (new.target as unknown as new (...args: any[]) => any) ) { this.__unitBuffer = []; @@ -65,7 +42,6 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals this.__unitBuffer = null; this.config = undefined; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any this.name = (this.constructor as any).name || 'anonymous'; } @@ -78,9 +54,7 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals provide(recipe: ServiceRecipe, opts?: FiberProvideOptions): FiberHandle; provide(token: CollectionToken, value: T): FiberHandle; provide( - // eslint-disable-next-line @typescript-eslint/no-explicit-any first: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any second?: any, third?: FiberProvideOptions, ): FiberHandle { @@ -105,7 +79,6 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals return this._runtime().effect(body, label); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter, handler: (e: any) => void): FiberHandle { const label = typeof event === 'string' ? `on:${event}` : 'on:emitter'; if (this.__unitBuffer !== null) { @@ -154,7 +127,6 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals return this.__unitRuntime; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _pendingName(first: any): string { if (typeof first === 'function') { return (first as RecipeStatics).name ?? String(first); diff --git a/packages/agent-core-v2/src/_base/di/serviceCollection.ts b/packages/agent-core-v2/src/_base/di/serviceCollection.ts index b553fbf63..ba8550eb6 100644 --- a/packages/agent-core-v2/src/_base/di/serviceCollection.ts +++ b/packages/agent-core-v2/src/_base/di/serviceCollection.ts @@ -1,12 +1,3 @@ -/** - * `di` domain — `ServiceCollection`: the dynamic registry (L1). - * - * Maps a service id to its recipe (`SyncDescriptor`) or materialized instance. - * Every write stamps the entry with a container-monotonic `uid` (a generation - * marker used for introspection and history — it plays no role in change - * detection) and fires the token's availability event with `{ oldUid, newUid }`. - */ - import { Emitter } from '../event'; import { SyncDescriptor } from './descriptors'; import type { ServiceIdentifier } from './instantiation'; @@ -25,17 +16,14 @@ export interface AvailabilityChange { } export class ServiceCollection { - // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _entries = new Map, ServiceCollectionEntry>(); private readonly _emitters = new Map< - // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier, Emitter >(); private _nextUid = 0; constructor( - // eslint-disable-next-line @typescript-eslint/no-explicit-any ...entries: ReadonlyArray, unknown]> ) { for (const [id, value] of entries) { @@ -102,17 +90,14 @@ export class ServiceCollection { return prev.value as T | SyncDescriptor | undefined; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any entry(id: ServiceIdentifier): ServiceCollectionEntry | undefined { return this._entries.get(id); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any uidOf(id: ServiceIdentifier): number | undefined { return this._entries.get(id)?.uid; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any configOf(id: ServiceIdentifier): unknown { return this._entries.get(id)?.config; } @@ -124,7 +109,6 @@ export class ServiceCollection { return this._emitterFor(id).event(listener); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any has(id: ServiceIdentifier): boolean { return this._entries.has(id); } @@ -135,7 +119,6 @@ export class ServiceCollection { forEach( callback: ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier, value: unknown, ) => void, diff --git a/packages/agent-core-v2/src/_base/di/test.ts b/packages/agent-core-v2/src/_base/di/test.ts index 2af4154c7..5bdfc3e25 100644 --- a/packages/agent-core-v2/src/_base/di/test.ts +++ b/packages/agent-core-v2/src/_base/di/test.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — scoped test host and service-stub helpers for DI domain tests. - */ - export { createServices, TestInstantiationService, diff --git a/packages/agent-core-v2/src/_base/di/testInstantiationService.ts b/packages/agent-core-v2/src/_base/di/testInstantiationService.ts index f7fb86aa6..7537f4de2 100644 --- a/packages/agent-core-v2/src/_base/di/testInstantiationService.ts +++ b/packages/agent-core-v2/src/_base/di/testInstantiationService.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — `TestInstantiationService` and scoped test-container helpers. - */ - import * as sinon from 'sinon'; import { SyncDescriptor, type SyncDescriptor0 } from './descriptors'; @@ -14,12 +10,10 @@ import { InstantiationService, Trace } from './instantiationService'; import { DisposableStore, dispose, isDisposable, toDisposable, type IDisposable } from './lifecycle'; import { ServiceCollection } from './serviceCollection'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any type AnyConstructor = new (...args: any[]) => T; interface IServiceMock { id: ServiceIdentifier; - // eslint-disable-next-line @typescript-eslint/no-explicit-any service?: any; } @@ -79,7 +73,6 @@ export class TestInstantiationService extends InstantiationService implements ID ...args: GetLeadingNonServiceArgs> ): R; public override createInstance( - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctorOrDescriptor: any, ...rest: unknown[] ): unknown { @@ -116,10 +109,8 @@ export class TestInstantiationService extends InstantiationService implements ID ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stub( id: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg2: any, arg3?: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg4?: any, ): T | SyncDescriptor | sinon.SinonStub | sinon.SinonSpy { if (arg2 instanceof SyncDescriptor && typeof arg3 !== 'string') { @@ -156,31 +147,24 @@ export class TestInstantiationService extends InstantiationService implements ID public stubPromise( id?: ServiceIdentifier, fnProperty?: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any value?: any, ): T | sinon.SinonStub; public stubPromise( id?: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor?: any, fnProperty?: string, value?: V, ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stubPromise( id?: ServiceIdentifier, - // eslint-disable-next-line @typescript-eslint/no-explicit-any obj?: any, fnProperty?: string, value?: V, ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stubPromise( - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg1?: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg2?: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg3?: any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any arg4?: any, ): unknown { arg3 = typeof arg2 === 'string' ? Promise.resolve(arg3) : arg3; @@ -195,9 +179,7 @@ export class TestInstantiationService extends InstantiationService implements ID } private _create(serviceMock: IServiceMock, options: SinonOptions, reset?: boolean): T; - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _create(ctor: any, options: SinonOptions): T | sinon.SinonMock; - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _create(arg1: any, options: SinonOptions, reset: boolean = false): any { if (this._isServiceMock(arg1)) { const service = this._getOrCreateService(arg1, options, reset); @@ -238,7 +220,6 @@ export class TestInstantiationService extends InstantiationService implements ID return service as T; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createStub(arg: any): any { if (arg instanceof SyncDescriptor) { return sinon.createStubInstance(arg.ctor); @@ -252,7 +233,6 @@ export class TestInstantiationService extends InstantiationService implements ID return Object.create(null); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createReplacement(value: any): sinon.SinonStub | sinon.SinonSpy { if (typeof value === 'function') { return isSinonSpyLike(value) ? value : sinon.spy(value); @@ -260,12 +240,10 @@ export class TestInstantiationService extends InstantiationService implements ID return value ? sinon.stub().returns(value) : sinon.stub(); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _hasSinonOption(service: any, key: keyof SinonOptions): boolean { return Boolean(service?.sinonOptions?.[key]); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private _isServiceMock(arg: any): arg is IServiceMock { return typeof arg === 'object' && arg !== null && 'id' in arg; } @@ -292,7 +270,6 @@ interface SinonOptions { } export interface ServiceRegistration { - // eslint-disable-next-line @typescript-eslint/no-explicit-any define(id: ServiceIdentifier, ctor: new (...args: any[]) => T): void; defineInstance(id: ServiceIdentifier, instance: T): void; definePartialInstance(id: ServiceIdentifier, instance: Partial): void; @@ -311,7 +288,6 @@ export function createServices( options: CreateServicesOptions = {}, ): TestInstantiationService { const serviceCollection = new ServiceCollection(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any const instanceIds = new Set>(); const register = ( diff --git a/packages/agent-core-v2/src/_base/di/util/linkedList.ts b/packages/agent-core-v2/src/_base/di/util/linkedList.ts index 625208058..4ae8b60a6 100644 --- a/packages/agent-core-v2/src/_base/di/util/linkedList.ts +++ b/packages/agent-core-v2/src/_base/di/util/linkedList.ts @@ -1,7 +1,3 @@ -/** - * `di` domain — `LinkedList` with O(1) push/removal for parked event listeners. - */ - class Node { static readonly Undefined = new Node(undefined); diff --git a/packages/agent-core-v2/src/_base/errors/codes.ts b/packages/agent-core-v2/src/_base/errors/codes.ts index e6fd5aabf..c10012fad 100644 --- a/packages/agent-core-v2/src/_base/errors/codes.ts +++ b/packages/agent-core-v2/src/_base/errors/codes.ts @@ -1,12 +1,3 @@ -/** - * `errors` domain (cross-cutting) — error-code contract, runtime registry, and - * metadata backing serialization. - * - * Owns the `ErrorDomain` contract every business domain uses to contribute its - * codes, the registry (`registerErrorDomain` / `errorInfo` / `isErrorCode`), - * and the domain-independent core codes (`internal`, `not_implemented`). - */ - export interface ErrorInfo { readonly title: string; readonly retryable: boolean; diff --git a/packages/agent-core-v2/src/_base/errors/errorMessage.ts b/packages/agent-core-v2/src/_base/errors/errorMessage.ts index de1230a7e..d30f2ea6b 100644 --- a/packages/agent-core-v2/src/_base/errors/errorMessage.ts +++ b/packages/agent-core-v2/src/_base/errors/errorMessage.ts @@ -1,7 +1,3 @@ -/** - * Render thrown values as human-readable lines for logs and CLI output. - */ - import { isCodedError } from './serialize'; export function toErrorMessage(error: unknown, verbose = false): string { diff --git a/packages/agent-core-v2/src/_base/errors/errors.ts b/packages/agent-core-v2/src/_base/errors/errors.ts index d5cd7cebe..88b1ce272 100644 --- a/packages/agent-core-v2/src/_base/errors/errors.ts +++ b/packages/agent-core-v2/src/_base/errors/errors.ts @@ -1,8 +1,3 @@ -/** - * Base error classes shared by every domain — `Error2` and related - * control-flow errors. - */ - import { CoreErrors } from './codes'; import type { ErrorCode } from '#/errors'; diff --git a/packages/agent-core-v2/src/_base/errors/serialize.ts b/packages/agent-core-v2/src/_base/errors/serialize.ts index 5b6ad0b40..2176204e1 100644 --- a/packages/agent-core-v2/src/_base/errors/serialize.ts +++ b/packages/agent-core-v2/src/_base/errors/serialize.ts @@ -1,13 +1,3 @@ -/** - * `errors` domain (cross-cutting) — wire serialization of thrown values. - * - * Converts between thrown values and the portable `ErrorPayload` that crosses - * process / language boundaries, recursively through the `cause` chain. Knows - * only coded errors and the core codes: business-domain translation (e.g. - * provider API errors) happens at the owning domain's boundary before errors - * reach this layer, so `_base/errors` never imports a business domain. - */ - import { CoreErrors, errorInfo, isErrorCode } from './codes'; import type { ErrorCode } from '#/errors'; import { Error2 } from './errors'; diff --git a/packages/agent-core-v2/src/_base/errors/unexpectedError.ts b/packages/agent-core-v2/src/_base/errors/unexpectedError.ts index 8b55d0265..3d1dcdedb 100644 --- a/packages/agent-core-v2/src/_base/errors/unexpectedError.ts +++ b/packages/agent-core-v2/src/_base/errors/unexpectedError.ts @@ -1,12 +1,6 @@ -/** - * Unexpected-error reporting hook (`onUnexpectedError`) — surfaces exceptions - * thrown by listener callbacks. - */ - export type UnexpectedErrorHandler = (err: unknown) => void; const defaultHandler: UnexpectedErrorHandler = (err) => { - // eslint-disable-next-line no-console console.error('[unexpected]', err); }; @@ -24,7 +18,6 @@ export function onUnexpectedError(err: unknown): void { try { currentHandler(err); } catch (handlerErr) { - // eslint-disable-next-line no-console console.error('[unexpected] handler threw', handlerErr, 'while reporting', err); } } diff --git a/packages/agent-core-v2/src/_base/event.ts b/packages/agent-core-v2/src/_base/event.ts index 35b0559cc..a80483c2c 100644 --- a/packages/agent-core-v2/src/_base/event.ts +++ b/packages/agent-core-v2/src/_base/event.ts @@ -1,14 +1,3 @@ -/** - * `event` domain — `Event` / `Emitter` primitives, the async - * `AsyncEmitter` / `IWaitUntil` participation primitive (for interceptable - * `onWill` events whose listeners register work via `waitUntil`), the - * `handleVetos` helper (for `onBefore*` veto events whose listeners answer - * with `veto(value, id)`), and event combinators (`once` / `map` / `filter` - * / `any`). `Emitter` accepts an optional debug name that its - * `EventSubscription` carries as an `on:` ledger label, so event - * subscriptions stay identifiable in unit-book introspection. - */ - import { onUnexpectedError, safelyCallListener } from './errors/unexpectedError'; import { Disposable, @@ -207,7 +196,6 @@ export function handleVetos( return Promise.allSettled(promises).then(() => lazyValue); } -// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Event { export const None: Event = () => Disposable.None; diff --git a/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts b/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts index a89a60527..00ed8dece 100644 --- a/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts +++ b/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts @@ -1,12 +1,3 @@ -/** - * `_base/execEnv` — `BufferedReadable` stream helper. - * - * A `Readable` wrapper that preserves source backpressure while still allowing - * consumers to read buffered output after the source has ended. Used by process - * spawners so `wait()`-then-read on small/medium outputs works without draining - * unboundedly. Kept as a pure helper with no DI dependencies. - */ - import { Readable } from 'node:stream'; export class BufferedReadable extends Readable { diff --git a/packages/agent-core-v2/src/_base/execEnv/decodeText.ts b/packages/agent-core-v2/src/_base/execEnv/decodeText.ts index 543a83c82..2f0a12908 100644 --- a/packages/agent-core-v2/src/_base/execEnv/decodeText.ts +++ b/packages/agent-core-v2/src/_base/execEnv/decodeText.ts @@ -1,11 +1,3 @@ -/** - * `_base/execEnv` — Python-compatible text decoding with `errors` handling. - * - * Reads text with the same `strict`/`replace`/`ignore` semantics Python's - * `open(..., errors=)` provides. Kept as a pure helper with no DI - * dependencies. - */ - export type TextDecodeErrors = 'strict' | 'replace' | 'ignore'; function isUtf8Continuation(byte: number): boolean { @@ -135,7 +127,6 @@ export function decodeTextWithErrors( ignoreBOM: boolean = false, ): string { let webLabel: string | undefined; - // eslint-disable-next-line typescript-eslint/switch-exhaustiveness-check switch (encoding) { case 'utf-8': case 'utf8': diff --git a/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts b/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts index a9c4e5ffc..6f8618551 100644 --- a/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts +++ b/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts @@ -1,22 +1,3 @@ -/** - * `_base/execEnv` — OS / shell probe. - * - * Detects the host operating system, architecture, kernel release, and a - * usable POSIX shell path. The result is a pure function of injected probes - * (`platform` / `arch` / `release` / `env` / `isFile` / `execFileText`) so the - * same suite runs identically on any host OS. `probeHostEnvironmentFromNode()` - * bundles the Node defaults for production callers and memoises the promise. - * - * On Windows the probe expects bash from Git for Windows or MSYS2. If no - * shell can be located the function throws `ProbeShellNotFoundError`, a - * distinct type carrying the checked paths (`checked`) with an install hint - * in its message, so the DI boundary can tell a missing shell apart from - * other probe errors and translate it into a coded error. Set - * `KIMI_SHELL_PATH` to override. - * - * Kept as a pure helper with no DI dependencies. - */ - import { execFile as nodeExecFile } from 'node:child_process'; import { constants as fsConstants } from 'node:fs'; import { access } from 'node:fs/promises'; diff --git a/packages/agent-core-v2/src/_base/execEnv/globPattern.ts b/packages/agent-core-v2/src/_base/execEnv/globPattern.ts index 6dc9db8b8..4efd1eb02 100644 --- a/packages/agent-core-v2/src/_base/execEnv/globPattern.ts +++ b/packages/agent-core-v2/src/_base/execEnv/globPattern.ts @@ -1,15 +1,3 @@ -/** - * `_base/execEnv` — glob-pattern-to-regex conversion. - * - * Pure function. Mirrors Python pathlib semantics: includes dotfiles, - * case-sensitive by default. - */ - -/** - * Convert a single glob pattern segment (e.g. `"*.txt"`, `"file?.log"`) into - * a RegExp. `*` matches any run of non-`/` characters; `?` matches any single - * non-`/` character; `[abc]` matches one of a set (leading `!` negates). - */ export function globPatternToRegex(pattern: string, caseSensitive: boolean): RegExp { let regex = '^'; for (let i = 0; i < pattern.length; i++) { diff --git a/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts b/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts index c36234732..b72c4a499 100644 --- a/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts +++ b/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts @@ -1,26 +1,3 @@ -/** - * `_base/execEnv` — login-shell PATH probe. - * - * Enriches `process.env.PATH` with entries from the user's login shell. When - * kimi-code is launched from a context that skipped the user's shell profile - * (GUI launchers, non-login parent shells), `process.env.PATH` misses entries - * like `/opt/homebrew/bin`, so commands spawned by the Bash tool can't find - * tools the user has in their interactive shell (e.g. `gh`). We run the user's - * login shell once (`$SHELL -l -c /usr/bin/env`), extract its PATH, and append - * the entries the current PATH lacks. Existing entries keep their order and - * priority; failures (no resolvable shell, hung or broken profile) silently - * leave PATH untouched. - * - * launchd/daemon launches can leave `$SHELL` unset or blank, so the probe falls - * back to the OS account's login shell from the user database before giving up. - * - * The probe is a pure function of injected deps so the suite runs identically - * on any host. Windows is skipped: the problem is specific to POSIX - * login-shell profiles. - * - * Kept as a pure helper with no DI dependencies. - */ - import { userInfo } from 'node:os'; import { execFileText } from './environmentProbe'; diff --git a/packages/agent-core-v2/src/_base/lifecycle/disposer.ts b/packages/agent-core-v2/src/_base/lifecycle/disposer.ts index a40ca6618..6e7a9a566 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/disposer.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/disposer.ts @@ -1,13 +1,3 @@ -/** - * `_base.lifecycle` — disposer types shared by the Ledger. - * - * A `Disposer` undoes one registered side effect. Disposers are dual-track - * (sync / async), mirroring ES explicit resource management: a Ledger whose - * entries are all synchronous tears down within a single tick; any async - * entry suspends the teardown promise until it settles. - */ - -/** Why the ledger is being torn down; threaded through to every disposer. */ export type TeardownReason = 'scope-close' | 'cascade' | 'unload'; export type Disposer = (reason: TeardownReason) => void | Promise; diff --git a/packages/agent-core-v2/src/_base/lifecycle/errors.ts b/packages/agent-core-v2/src/_base/lifecycle/errors.ts index 4ea32c5d9..e210bbdda 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/errors.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/errors.ts @@ -1,7 +1,3 @@ -/** - * `_base.lifecycle` — Ledger errors. - */ - export class LedgerDisposedError extends Error { constructor( readonly ledgerLabel: string, diff --git a/packages/agent-core-v2/src/_base/lifecycle/ledger.ts b/packages/agent-core-v2/src/_base/lifecycle/ledger.ts index ea79a628d..f39b15c17 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/ledger.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/ledger.ts @@ -1,15 +1,3 @@ -/** - * `_base.lifecycle` — `Ledger`: an ordered book of rollbackable registrations. - * - * A Ledger records entries (disposers, effects, child ledgers) in registration - * order and tears them down in strict reverse order, awaiting each entry - * serially — never in parallel. Rollback is uninterruptible: a failing entry - * is logged (with its label) and teardown continues. Registering into a - * disposing/disposed ledger throws immediately. - * - * The Ledger knows nothing about DI; scopes and containers build on top of it. - */ - import { onUnexpectedError } from '../errors/unexpectedError'; import { isAsyncIterable, diff --git a/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts b/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts index 0b5c6b401..784aab797 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts @@ -1,11 +1,3 @@ -/** - * `_base.lifecycle` — in-memory lifecycle transitions with guarded async transactions. - * - * Provides a domain-independent state holder that enters a transition state before - * asynchronous work begins and coordinates explicit commit, rollback, cleanup, and - * compensation actions. It has no persistence, event, DI, or scope dependencies. - */ - export type LifecycleTransitionErrorReason = | 'invalid_state' | 'transition_conflict' diff --git a/packages/agent-core-v2/src/_base/log/fileLog.ts b/packages/agent-core-v2/src/_base/log/fileLog.ts index edf74a782..e52c065ba 100644 --- a/packages/agent-core-v2/src/_base/log/fileLog.ts +++ b/packages/agent-core-v2/src/_base/log/fileLog.ts @@ -1,15 +1,3 @@ -/** - * `_base/log` — plain (non-DI) log sinks. - * - * Owns the `RotatingFileWriter` (size-rotated, async-serial, sync-flush on - * exit) and the `ILogWriter` implementations built on top of it (`FileLogWriter`), - * plus the in-memory and console sinks used by tests and debugging. All classes - * here are plain: constructed with an explicit options object, no `@IService` - * deps, never registered with the container — a `*LogService` creates and owns - * them. Uses `node:fs` rather than `kaos` because rotation needs atomic rename - * and synchronous append. - */ - import { appendFileSync, mkdirSync } from 'node:fs'; import { mkdir, open, rename, stat, unlink } from 'node:fs/promises'; import { dirname } from 'pathe'; @@ -282,19 +270,15 @@ export class ConsoleLogWriter implements ILogWriter { const { text } = formatEntry(entry, { ansi: process.stderr.isTTY === true }); switch (entry.level) { case 'error': - // eslint-disable-next-line no-console console.error(text); break; case 'warn': - // eslint-disable-next-line no-console console.warn(text); break; case 'debug': - // eslint-disable-next-line no-console console.debug(text); break; default: - // eslint-disable-next-line no-console console.log(text); } } diff --git a/packages/agent-core-v2/src/_base/log/formatter.ts b/packages/agent-core-v2/src/_base/log/formatter.ts index 409261575..c2bb51e3e 100644 --- a/packages/agent-core-v2/src/_base/log/formatter.ts +++ b/packages/agent-core-v2/src/_base/log/formatter.ts @@ -1,12 +1,3 @@ -/** - * `log` domain — logfmt entry formatter. - * - * Renders a `LogEntry` as a single logfmt line (`ISO LEVEL msg k=v ...`), - * redacts secret-shaped keys and raw secret patterns, truncates oversized - * fields, optionally colorizes the level with ANSI, and indents error stacks. - * Pure — no I/O, no DI. - */ - import type { LogContext, LogEntry, LogEntryError } from './log'; export const MSG_MAX_CHARS = 200; diff --git a/packages/agent-core-v2/src/_base/log/log.ts b/packages/agent-core-v2/src/_base/log/log.ts index 5afd73e31..58051c11a 100644 --- a/packages/agent-core-v2/src/_base/log/log.ts +++ b/packages/agent-core-v2/src/_base/log/log.ts @@ -1,15 +1,3 @@ -/** - * `_base/log` — structured logging contract. - * - * Defines the public logging model shared by every scope: the `LogEntry` / - * `LogLevel` types, the `ILogger` / `ILogService` facade used by other domains - * to emit leveled entries, and the plain `ILogWriter` sink shape. There is a - * single `ILogService` DI token; each scope binds its own `*LogService` - * implementation to it, so consumers just inject `@ILogService` and the scope - * decides where entries land. `ILogWriter` is a plain (non-DI) interface — sinks - * are created by the `*LogService` implementations, not registered. - */ - import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; diff --git a/packages/agent-core-v2/src/_base/log/logConfig.ts b/packages/agent-core-v2/src/_base/log/logConfig.ts index 6be4bd0a4..34ae349ee 100644 --- a/packages/agent-core-v2/src/_base/log/logConfig.ts +++ b/packages/agent-core-v2/src/_base/log/logConfig.ts @@ -1,11 +1,3 @@ -/** - * `log` domain — runtime logging configuration. - * - * Builds the `LoggingConfig` from `KIMI_LOG_*` environment variables plus - * defaults, resolves the global and per-session log paths, and exposes the - * `ILogOptions` seed used to inject the resolved config into a App scope. - */ - import { join } from 'pathe'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/_base/log/logService.ts b/packages/agent-core-v2/src/_base/log/logService.ts index f403edee4..c5a0c5dc2 100644 --- a/packages/agent-core-v2/src/_base/log/logService.ts +++ b/packages/agent-core-v2/src/_base/log/logService.ts @@ -1,14 +1,3 @@ -/** - * `_base/log` — `BoundLogger` base and the App-scope `ILogService`. - * - * `BoundLogger` filters entries by level, extracts the payload into ctx/error, - * merges bound context, and writes to a plain `ILogWriter`. It extends - * `Service` so scope implementations can flush synchronously when their - * scope is disposed. `AppLogService` is the App-scope binding of the single - * `ILogService` token: it owns the global rotating file sink and reads its - * level from `ILogOptions`. - */ - import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/_base/state/stateRegistry.ts b/packages/agent-core-v2/src/_base/state/stateRegistry.ts index d5fa5c0b3..54fd1fbfb 100644 --- a/packages/agent-core-v2/src/_base/state/stateRegistry.ts +++ b/packages/agent-core-v2/src/_base/state/stateRegistry.ts @@ -1,39 +1,3 @@ -/** - * `state` domain — scope-agnostic keyed state container primitives. - * - * Owns the typed `StateKey` descriptor (manufactured by `defineState` in - * the top-level `state` domain), the `IStateRegistry` base interface shared - * by the per-scope state services, and the `StateRegistry` implementation - * backing them: a `Map`-backed store - * where keys are declared - * up front (`register`), read and replaced (`get` / `set`), and observed - * (`onDidChange(key)` per key, `onDidChangeAny` globally). Two exports serve - * debugging: `entries()` returns the live key/value references for in-process - * readers, and `snapshot()` returns a JSON-safe deep copy for RPC / inspector - * export: Maps become plain objects or entry arrays, Sets become arrays, - * functions are dropped, circular references become `'(circular)'`, and - * instances with a custom prototype (service references, tools, Promises) - * collapse to a `'(ClassName)'` marker — plain data is recursed, resource - * graphs are not, so a value that reaches into the DI object graph cannot - * fan the copy out until the heap is exhausted. A key flagged - * `snapshotExcluded` (replayable event-sourced state, whose authoritative - * copy is the wire journal) is skipped by `snapshot()` so the debug export - * never deep-copies it. Misuse (duplicate registration, reading or writing an - * unregistered key) is a caller bug and raises `BugIndicatingError`. - * - * Cascading inspection: each scope's state service keeps a reference to the - * parent scope's registry (`inspectParent`, assigned from the injected - * parent-tier state service; App is the root) and declares its tier name - * (`inspectScope`). `inspect()` folds that chain into a `StateInspection` - * tree — this scope's `snapshot()` plus the ancestors' — so one RPC call - * from any scope tier exports the whole App → … → current-scope state path. - * - * Values are stored as-is — the container does not freeze or clone, so - * replacing the whole value via `set` is the recommended update style; - * mutating a held `Map` / `Set` in place bypasses change notification. - * Persistence and replay are out of scope here. Scope-agnostic. - */ - import { Disposable, type IDisposable, toDisposable } from '../di/lifecycle'; import { BugIndicatingError } from '../errors/errors'; import { Emitter, type Event } from '../event'; @@ -67,7 +31,6 @@ export interface IStateRegistry { inspect(): StateInspection; } -// NOTE: stays Disposable — its own 'get' collides with the Fiber export class StateRegistry extends Disposable implements IStateRegistry { private readonly values = new Map(); private readonly registrations = new Map(); diff --git a/packages/agent-core-v2/src/_base/text/encoding.ts b/packages/agent-core-v2/src/_base/text/encoding.ts index 32df9743d..ab153049f 100644 --- a/packages/agent-core-v2/src/_base/text/encoding.ts +++ b/packages/agent-core-v2/src/_base/text/encoding.ts @@ -1,26 +1,3 @@ -/** - * `_base` text helpers — UTF text encoding detection and decoding. - * - * Detection algorithm derived from VS Code - * `src/vs/workbench/services/textfile/common/encoding.ts` - * (MIT License, Copyright (c) Microsoft Corporation): BOM sniffing plus a - * zero-byte parity heuristic that recognizes BOM-less UTF-16 LE/BE, so text - * files saved as UTF-16 (e.g. Windows Notepad `.txt`) can be transcoded to - * UTF-8 instead of being refused as binary. - * - * The parity heuristic deliberately deviates from VS Code in one way: VS - * Code requires *every* byte pair to conform (a single CJK character, whose - * UTF-16 unit carries no zero byte, falsifies the pattern and the file is - * deemed binary). Here, zero bytes must instead appear at least twice and at - * exactly one parity — odd indices mean UTF-16 LE (`0xAA 0x00`), even - * indices mean UTF-16 BE (`0x00 0xAA`) — which tolerates mixed Latin/CJK - * content while still rejecting real binaries (zeros at both parities, or - * an isolated zero byte). Legacy 8-bit encodings (GBK, Big5, Shift-JIS, …) - * are never guessed — a wrong silent guess is worse than a clear refusal. - * - * Pure functions over bytes; no io happens here. - */ - export type UtfTextEncoding = 'utf-8' | 'utf-16le' | 'utf-16be'; export interface TextClassification { @@ -46,12 +23,6 @@ export interface TextEncodingDetection { /** Number of leading bytes inspected for the zero-byte heuristic. */ export const ENCODING_DETECTION_SAMPLE_BYTES = 512; -/** - * Minimum zero bytes (at a single parity) before the BOM-less UTF-16 - * heuristic commits. One isolated zero byte is too ambiguous — a short - * binary blob like `"plain prefix" + 00 01` would otherwise masquerade as - * UTF-16 BE. - */ const MIN_ZERO_BYTES_FOR_UTF16 = 2; const UTF16BE_BOM = [0xfe, 0xff] as const; @@ -59,7 +30,6 @@ const UTF16LE_BOM = [0xff, 0xfe] as const; const UTF8_BOM = [0xef, 0xbb, 0xbf] as const; function sniffTextEncoding(sample: Uint8Array): TextEncodingDetection { - // Always trust a BOM first. if (sample.length >= 2) { const b0 = sample[0]!; const b1 = sample[1]!; @@ -74,10 +44,6 @@ function sniffTextEncoding(sample: Uint8Array): TextEncodingDetection { } } - // BOM-less UTF-16: zero bytes cluster at one parity — odd indices for LE - // (`0xAA 0x00`), even for BE (`0x00 0xAA`). CJK units carry no zero byte, - // so only the *placement* of zeros is checked, not their density. Zeros - // at both parities, or fewer than the ambiguity threshold, mean binary. let zerosAtOdd = 0; let zerosAtEven = 0; const limit = Math.min(sample.length, ENCODING_DETECTION_SAMPLE_BYTES); diff --git a/packages/agent-core-v2/src/_base/text/frontmatter.ts b/packages/agent-core-v2/src/_base/text/frontmatter.ts index 16bb2b0fc..601a0254c 100644 --- a/packages/agent-core-v2/src/_base/text/frontmatter.ts +++ b/packages/agent-core-v2/src/_base/text/frontmatter.ts @@ -1,12 +1,3 @@ -/** - * `_base` text helpers — Markdown frontmatter parsing. - * - * Splits a Markdown document into its YAML frontmatter block and body. Pure - * text processing with no IO and no domain knowledge. A document without a - * leading `---` fence parses as all body with `data: null`; an unterminated - * fence is a `FrontmatterError`. - */ - import { load as loadYaml } from 'js-yaml'; export class FrontmatterError extends Error { diff --git a/packages/agent-core-v2/src/_base/text/line-endings.ts b/packages/agent-core-v2/src/_base/text/line-endings.ts index 3f27470a8..62508eccc 100644 --- a/packages/agent-core-v2/src/_base/text/line-endings.ts +++ b/packages/agent-core-v2/src/_base/text/line-endings.ts @@ -1,10 +1,3 @@ -/** - * `_base` text helpers — model-text line-ending normalization. - * - * Normalizes CRLF → LF for display and re-materializes CRLF on write, so the - * model sees a consistent view while the on-disk bytes stay faithful. - */ - export type LineEndingStyle = 'lf' | 'crlf' | 'mixed'; export interface ModelTextView { diff --git a/packages/agent-core-v2/src/_base/utils/abort.ts b/packages/agent-core-v2/src/_base/utils/abort.ts index 09b2860fb..7662966b2 100644 --- a/packages/agent-core-v2/src/_base/utils/abort.ts +++ b/packages/agent-core-v2/src/_base/utils/abort.ts @@ -1,8 +1,3 @@ -/** - * Abort-signal helpers — user-cancellation errors, abortable promises, signal - * linking, and deadline abort signals. - */ - export function abortError(message = 'Aborted'): Error { const error = new Error(message); error.name = 'AbortError'; diff --git a/packages/agent-core-v2/src/_base/utils/canonical-args.ts b/packages/agent-core-v2/src/_base/utils/canonical-args.ts index 40661ed20..feca131c1 100644 --- a/packages/agent-core-v2/src/_base/utils/canonical-args.ts +++ b/packages/agent-core-v2/src/_base/utils/canonical-args.ts @@ -1,7 +1,3 @@ -/** - * `_base` utility — canonical JSON argument serialization for stable tool-call keys. - */ - export function canonicalTelemetryArgs(args: unknown): string { const json = JSON.stringify(sortJsonValue(args)); return json ?? String(args); diff --git a/packages/agent-core-v2/src/_base/utils/env.ts b/packages/agent-core-v2/src/_base/utils/env.ts index 9412d448a..12a62fc74 100644 --- a/packages/agent-core-v2/src/_base/utils/env.ts +++ b/packages/agent-core-v2/src/_base/utils/env.ts @@ -1,7 +1,3 @@ -/** - * Parse environment-variable string values into typed primitives. - */ - const TRUE_BOOLEAN_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']); const FALSE_BOOLEAN_ENV_VALUES = new Set(['0', 'false', 'no', 'off']); diff --git a/packages/agent-core-v2/src/_base/utils/fileMeta.ts b/packages/agent-core-v2/src/_base/utils/fileMeta.ts index 6ea99aec8..4f76835b0 100644 --- a/packages/agent-core-v2/src/_base/utils/fileMeta.ts +++ b/packages/agent-core-v2/src/_base/utils/fileMeta.ts @@ -1,14 +1,3 @@ -/** - * File content metadata helpers — binary detection, line counting, etag, and - * extension-based mime / language guessing. - * - * Pure functions over bytes, text, and stat-like shapes; no io happens here. - * Binary detection samples the leading `FS_BINARY_SAMPLE_BYTES` of a file and - * flags it as binary when the non-printable fraction exceeds - * `FS_BINARY_NONPRINTABLE_FRACTION`; etags are built from any stat-like shape - * carrying `size` / `mtimeMs` / `ino` (`FileMetaStat`). - */ - import { extname } from 'node:path'; import { classifyTextSample } from '#/_base/text/encoding'; diff --git a/packages/agent-core-v2/src/_base/utils/fs.ts b/packages/agent-core-v2/src/_base/utils/fs.ts index 7e1bb3e16..da9bacd1a 100644 --- a/packages/agent-core-v2/src/_base/utils/fs.ts +++ b/packages/agent-core-v2/src/_base/utils/fs.ts @@ -1,8 +1,3 @@ -/** - * Low-level durable file-write primitives — atomic writes plus file and - * directory fsync helpers. - */ - import { randomBytes } from 'node:crypto'; import { closeSync, fsyncSync, openSync } from 'node:fs'; import * as nodeFs from 'node:fs'; diff --git a/packages/agent-core-v2/src/_base/utils/hero-slug.ts b/packages/agent-core-v2/src/_base/utils/hero-slug.ts index e4d78a174..a8099bccf 100644 --- a/packages/agent-core-v2/src/_base/utils/hero-slug.ts +++ b/packages/agent-core-v2/src/_base/utils/hero-slug.ts @@ -1,7 +1,3 @@ -/** - * Hero-name slug generator for readable, memorable identifiers. - */ - import { randomInt } from 'node:crypto'; export const HERO_NAMES = [ diff --git a/packages/agent-core-v2/src/_base/utils/paths.ts b/packages/agent-core-v2/src/_base/utils/paths.ts index 34de452b1..757fcff70 100644 --- a/packages/agent-core-v2/src/_base/utils/paths.ts +++ b/packages/agent-core-v2/src/_base/utils/paths.ts @@ -1,12 +1,3 @@ -/** - * `_base/utils/paths` (cross-cutting) — pure path predicates and directory - * walks. - * - * Constrains filesystem watches to selected subtrees and scanner-visible - * entries, and walks host directory chains with platform-native path - * semantics so drive-letter / UNC roots keep their host form. - */ - import nodePath from 'node:path'; function normalizeSlashes(p: string): string { diff --git a/packages/agent-core-v2/src/_base/utils/promise.ts b/packages/agent-core-v2/src/_base/utils/promise.ts index 3669a548c..6a6e61099 100644 --- a/packages/agent-core-v2/src/_base/utils/promise.ts +++ b/packages/agent-core-v2/src/_base/utils/promise.ts @@ -1,11 +1,3 @@ -/** - * Timeout outcome promise — resolves with a fixed value after a delay. - * - * The timer goes through `setClampedTimeout`, so huge ("effectively - * unbounded") timeouts still mean a long wait instead of overflowing into an - * immediate fire. - */ - import { setClampedTimeout } from './timer'; const NEVER = new Promise(() => {}); diff --git a/packages/agent-core-v2/src/_base/utils/proxy.ts b/packages/agent-core-v2/src/_base/utils/proxy.ts index 7a4e06806..12570257a 100644 --- a/packages/agent-core-v2/src/_base/utils/proxy.ts +++ b/packages/agent-core-v2/src/_base/utils/proxy.ts @@ -1,8 +1,3 @@ -/** - * Resolve and install proxy configuration for outbound `fetch` and spawned - * child processes (HTTP/HTTPS and SOCKS, honoring `NO_PROXY`). - */ - import { Agent, buildConnector, diff --git a/packages/agent-core-v2/src/_base/utils/render-prompt.ts b/packages/agent-core-v2/src/_base/utils/render-prompt.ts index 9c49236e0..2d41956f0 100644 --- a/packages/agent-core-v2/src/_base/utils/render-prompt.ts +++ b/packages/agent-core-v2/src/_base/utils/render-prompt.ts @@ -1,15 +1,3 @@ -/** - * Shared prompt-template renderer (`renderPrompt`). - * - * A single `${var}` substitution pass: every variable present in `vars` is - * replaced with its string value, unknown or non-string placeholders stay - * verbatim, and a bare `$` is never special. There is no conditional or loop - * syntax by design — call sites compose optional sections in code and pass - * them as pre-rendered blocks. This keeps user-facing templates (agent files, - * `SYSTEM.md`) safe to write: a literal `${...}` inside prose or a code - * snippet can never crash rendering. - */ - const PROMPT_VARIABLE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g; export function renderPrompt(template: string, vars: Record): string { diff --git a/packages/agent-core-v2/src/_base/utils/retry.ts b/packages/agent-core-v2/src/_base/utils/retry.ts index 8c46ace09..ed4132f7d 100644 --- a/packages/agent-core-v2/src/_base/utils/retry.ts +++ b/packages/agent-core-v2/src/_base/utils/retry.ts @@ -1,10 +1,3 @@ -/** - * `_base` retry helpers — exponential and server-directed backoff, abortable - * sleeps, and error-field extraction. The default budget is 10 attempts per - * step: the 500ms ×2 ramp capped at 32s waits out multi-minute provider - * overload (sustained 429s) before a turn fails. - */ - import { abortable } from '#/_base/utils/abort'; export const DEFAULT_MAX_RETRY_ATTEMPTS = 10; diff --git a/packages/agent-core-v2/src/_base/utils/timer.ts b/packages/agent-core-v2/src/_base/utils/timer.ts index 08cfa4214..f6eee2496 100644 --- a/packages/agent-core-v2/src/_base/utils/timer.ts +++ b/packages/agent-core-v2/src/_base/utils/timer.ts @@ -1,20 +1,3 @@ -/** - * Repeating timer primitive — a disposable `setInterval` wrapper. - * - * `IntervalTimer` owns a single `setInterval` handle: `cancelAndSet` (re)starts - * the loop (cancelling any previous handle first), `cancel` stops it, and - * `dispose` guarantees the handle is cleared — so it can be `_register`-ed on a - * `Disposable` owner and cleaned up for free. One instance is reused across - * start/stop cycles instead of juggling raw `ReturnType` - * values. Mirrors VS Code's `IntervalTimer`. - * - * `setClampedTimeout` is a `setTimeout` whose delay is clamped to - * `MAX_TIMER_DELAY_MS`, the largest delay the host timer accepts: beyond it - * the delay overflows into an immediate (~1ms) fire, so huge ("effectively - * unbounded") timeouts would fire at once instead of waiting. Callers that - * outlive the clamp (~24.8 days) re-arm. - */ - import type { IDisposable } from '#/_base/di/lifecycle'; export const MAX_TIMER_DELAY_MS = 0x7fffffff; diff --git a/packages/agent-core-v2/src/_base/utils/typeEquality.ts b/packages/agent-core-v2/src/_base/utils/typeEquality.ts index 006a717cd..7c10c7dd8 100644 --- a/packages/agent-core-v2/src/_base/utils/typeEquality.ts +++ b/packages/agent-core-v2/src/_base/utils/typeEquality.ts @@ -1,20 +1,3 @@ -/** - * Compile-time type equality. - * - * Used to pin a hand-written type to the zod schema that re-derives it: a - * drift in either direction (added / removed field, changed field type, - * optionality flip) fails typecheck. - * - * `Equal` compares by mutual assignability through a contravariant - * function-type trick, so it is stricter than a one-way `A extends B` - * check. Both sides are flattened first (a homomorphic mapped type), so a - * schema-side intersection (e.g. the `{...} & { [k: string]: unknown }` - * that a passthrough object infers to) compares equal to the equivalent - * hand-written object type instead of failing on type-node shape. The - * comparison cannot see `readonly` modifiers (an inherent TS limitation), - * so hand-written types should match zod's mutable inference exactly. - */ - type Flatten = { [K in keyof T]: T[K] } & {}; export type Equal = diff --git a/packages/agent-core-v2/src/_base/utils/types.ts b/packages/agent-core-v2/src/_base/utils/types.ts index 9d50459d7..45a0d1c9d 100644 --- a/packages/agent-core-v2/src/_base/utils/types.ts +++ b/packages/agent-core-v2/src/_base/utils/types.ts @@ -1,7 +1,3 @@ -/** - * Promise-aware utility types for function and method signatures. - */ - export type Promisify = [T] extends [Promise] ? T : Promise; export type PromisifyMethods = { [K in keyof T]: T[K] extends (...args: infer Args) => infer Return diff --git a/packages/agent-core-v2/src/_base/utils/workdir-slug.ts b/packages/agent-core-v2/src/_base/utils/workdir-slug.ts index 60efc3826..15ea2d554 100644 --- a/packages/agent-core-v2/src/_base/utils/workdir-slug.ts +++ b/packages/agent-core-v2/src/_base/utils/workdir-slug.ts @@ -1,15 +1,3 @@ -/** - * Working-directory identity helpers. - * - * `slugifyWorkDirName` turns a directory name into a safe, bounded token; - * `encodeWorkDirKey` derives the stable, opaque `workspaceId` for a working - * directory (`wd__`). The `workspaceId` is the backend-neutral - * identity used to group sessions and to key the workspace registry; backends - * never expose the raw working-directory path. `workspaceRootKey` is the - * comparison-only companion: it answers "is this the same directory?" without - * changing the id that was already minted for it. - */ - import { createHash } from 'node:crypto'; const MAX_WORKDIR_SLUG_LENGTH = 40; diff --git a/packages/agent-core-v2/src/_base/utils/xml-escape.ts b/packages/agent-core-v2/src/_base/utils/xml-escape.ts index 832645aa7..6e5cb49ce 100644 --- a/packages/agent-core-v2/src/_base/utils/xml-escape.ts +++ b/packages/agent-core-v2/src/_base/utils/xml-escape.ts @@ -1,7 +1,3 @@ -/** - * XML escaping helpers for content, attribute values, and tag delimiters. - */ - export function escapeXml(input: string): string { return input .replaceAll('&', '&') diff --git a/packages/agent-core-v2/src/_base/version.ts b/packages/agent-core-v2/src/_base/version.ts index dfa8a6a94..baff62759 100644 --- a/packages/agent-core-v2/src/_base/version.ts +++ b/packages/agent-core-v2/src/_base/version.ts @@ -1,7 +1,3 @@ -/** - * agent-core-v2 version helper — exposes the package version to integrations. - */ - export function getCoreVersion(): string { return '0.0.0'; } diff --git a/packages/agent-core-v2/src/agent/activityView/activityView.ts b/packages/agent-core-v2/src/agent/activityView/activityView.ts index 4d707f71e..0e0ac9126 100644 --- a/packages/agent-core-v2/src/agent/activityView/activityView.ts +++ b/packages/agent-core-v2/src/agent/activityView/activityView.ts @@ -1,19 +1,4 @@ -/** - * `activityView` domain — the agent's one-way activity projection. - * - * Defines `IAgentActivityView`: a per-agent, read-only, event-folded read - * model of "what this agent is doing" — the current turn with its live - * phase/stream/step/retry/pending-approval/tool-call detail and the latest - * turn outcome, published on the agent's event bus as - * `agent.activity.updated`. The view OWNS NO authoritative state: every fact - * is folded from the agent's own event bus (loop turn/step/delta/tool/retry, - * permission approval, task, and full-compaction events) and seeded once from - * the owning services; it can be discarded and rebuilt at any time. Bound at - * Agent scope — one instance per agent, dying with it. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { PromptOrigin } from '#/agent/contextMemory/types'; import type { TurnEndReason } from '#/agent/loop/turnEvents'; diff --git a/packages/agent-core-v2/src/agent/activityView/activityViewService.ts b/packages/agent-core-v2/src/agent/activityView/activityViewService.ts index 0064aec2f..0ef3f99ae 100644 --- a/packages/agent-core-v2/src/agent/activityView/activityViewService.ts +++ b/packages/agent-core-v2/src/agent/activityView/activityViewService.ts @@ -1,23 +1,3 @@ -/** - * `activityView` domain — `IAgentActivityView` implementation. - * - * A pure fold of the agent's own event bus: turn boundaries drive the turn - * slice (active → detail updates → ended → `lastTurn`), step/delta/tool/retry - * events drive the live phase/stream/retry detail, permission approval events - * drive the pending-approval list, while task and full-compaction events drive - * the background-work slice. The view seeds once from `IAgentLoopService`, - * `IAgentTaskService`, and `IAgentFullCompactionService`, and recovers the - * last turn's outcome from the durable `turnKey` state through `state` - * (`IEventDispatcher`), so a cold-resumed agent still reports how its - * previous turn ended (reads, never writes). Otherwise the view holds only - * derived state, so it can be discarded and rebuilt at any time. The mutable - * view state (`lifecycle`, `turn`, `lastTurn`, `background`, `current`) is - * registered into `agentState` (`IAgentStateService`) and read/written - * through it; the event-bus subscription handles stay mechanism held by the - * `Disposable` base, and `MutableTurn`'s in-place-mutated Maps stay instance - * fields of that per-turn class. Bound at Agent scope. - */ - import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -91,7 +71,6 @@ export const activityViewCurrentKey = defineState('activityV background: [], })); -// NOTE: stays Disposable — its own 'state' collides with the Fiber export class AgentActivityView extends Disposable implements IAgentActivityView { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts index a7efdff13..db0eba9e4 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts @@ -1,14 +1,3 @@ -/** - * `agentsMdReminder` domain — AGENTS.md discovery-reminder contract. - * - * Defines the `IAgentAgentsMdReminderService`, the seed side of the domain: - * `profile` reports the AGENTS.md paths it injected into the system prompt - * (on every profile apply, with the agent's effective cwd), and `sessionInit` - * re-seeds after `/init` regenerates the file, so the reminder hook can tell - * "already injected" apart from newly discovered instruction files. Bound at - * Agent scope. - */ - import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IAgentAgentsMdReminderService { diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts index 92a5617a9..45f9fd750 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts @@ -1,16 +1,3 @@ -/** - * `agentsMdReminder` domain — `IAgentAgentsMdReminderService` - * implementation. - * - * Discovers AGENTS.md files reached through `toolExecutor` and the tool path - * policy, parsing Bash targets through `bashParser` and probing through the os - * services. Restores prompt provenance through the `profile` state on the - * event dispatcher, resolves - * roots through `sessionContext` and `bootstrap`, stores discovery state in - * `agentState`, appends through `systemReminder`, and reports through - * `telemetry`. Bound at Agent scope. - */ - import { basename, dirname, isAbsolute, join, normalize } from 'pathe'; import { Disposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts index eed1b7727..418057bbe 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts @@ -1,26 +1,3 @@ -/** - * `agentsMdReminder` domain — Bash-command directory extraction. - * - * Statically extracts the directories a Bash tool call is going to inspect, - * walking the `bashParser` syntax tree: the literal operands of - * directory-listing commands (`ls` / `tree` / `find` / `dir` / `exa` / `eza` / - * `lsd`), with literal `cd` commands rebasing relative resolution as they - * appear (`cd packages && ls kap-server`) and a genuinely operand-less - * listing command listing the current base (one whose operands all failed - * resolution is skipped instead). Only top-level simple commands are read — - * anything not statically resolvable (expansions, command - * substitution, glob characters (quoted or not), `~`, quoting mixes, compound - * constructs, `cd -`, a `cd` inside a pipeline, or a listing command invoked - * through a path prefix like `./ls` whose semantics are unknown) is skipped, - * and a `cd` whose operand cannot be resolved poisons relative resolution - * (never guesses a base) until an absolute `cd` re-anchors. Flags are dropped - * together with the arguments of the known argument-taking options - * (`ls --sort size`), and `find` collects leading paths past its no-argument - * global options (`find -L packages`) before stopping at the expression. - * A missed directory is recovered by the later Read/Edit/Write - * probes; a wrong one is not, so skipping always wins over guessing. - */ - import { isAbsolute, join, normalize } from 'pathe'; import type { BashSyntaxNode } from '#/app/bashParser/bashParser'; diff --git a/packages/agent-core-v2/src/agent/blob/agentBlobService.ts b/packages/agent-core-v2/src/agent/blob/agentBlobService.ts index 1524e7cab..94bfd6a7b 100644 --- a/packages/agent-core-v2/src/agent/blob/agentBlobService.ts +++ b/packages/agent-core-v2/src/agent/blob/agentBlobService.ts @@ -1,10 +1,3 @@ -/** - * `blob` domain — `IAgentBlobService` contract. - * - * Offloads large inline media payloads to content-addressed blob storage and - * loads them back on read. Bound at Agent scope. - */ - import type { ContentPart } from '#/kosong/contract/message'; import { createDecorator } from "#/_base/di/instantiation"; diff --git a/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts b/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts index d3e13057c..2ad64a8a2 100644 --- a/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts +++ b/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts @@ -1,12 +1,3 @@ -/** - * `blob` domain — `IAgentBlobService` implementation. - * - * Offloads large inline media payloads into content-addressed blobs and - * loads them back on read; persists bytes through `IBlobStore` under the - * agent's `scope('blobs')` root, matching the v1 `/blobs/` - * layout. Bound at Agent scope. - */ - import { createHash } from 'node:crypto'; import type { ContentPart } from '#/kosong/contract/message'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/agent/blob/byteLruCache.ts b/packages/agent-core-v2/src/agent/blob/byteLruCache.ts index 06b18477d..0a182d959 100644 --- a/packages/agent-core-v2/src/agent/blob/byteLruCache.ts +++ b/packages/agent-core-v2/src/agent/blob/byteLruCache.ts @@ -1,16 +1,3 @@ -/** - * `blob` domain — byte-bounded LRU cache. - * - * A small, dependency-free cache whose capacity is measured in **bytes** rather - * than entries. Hits refresh an entry to most-recently-used; inserts evict the - * least-recently-used entries until the payload fits. A single payload larger - * than `maxBytes` is never cached. - * - * Module-private helper; not part of the package surface. Owned as a value - * (not a DI service) so each agent keeps its own cache. Promote to a shared - * util only when a second caller appears. - */ - export class ByteLruCache { private readonly map = new Map(); private currentBytes = 0; diff --git a/packages/agent-core-v2/src/agent/command/agentCommand.ts b/packages/agent-core-v2/src/agent/command/agentCommand.ts index 5fe6db25f..16ece5924 100644 --- a/packages/agent-core-v2/src/agent/command/agentCommand.ts +++ b/packages/agent-core-v2/src/agent/command/agentCommand.ts @@ -1,12 +1,3 @@ -/** - * `command` domain — the `IAgentCommandService` contract. - * - * The agent-scope registry over the `CommandContribution` collection: lists - * the contributed executable commands (name-level dedup, last record wins, - * `source` = provider unit name) and runs one by name with an args string. - * Bound at Agent scope. - */ - import type { Event } from '#/_base/event'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/command/agentCommandService.ts b/packages/agent-core-v2/src/agent/command/agentCommandService.ts index 27379d570..33fde5a27 100644 --- a/packages/agent-core-v2/src/agent/command/agentCommandService.ts +++ b/packages/agent-core-v2/src/agent/command/agentCommandService.ts @@ -1,15 +1,3 @@ -/** - * `command` domain — `IAgentCommandService` implementation. - * - * The fold over the `CommandContribution` collection (`command`): `list()` - * dedupes the live records by name (a later record shadows an earlier one of - * the same name), and `run` invokes the contribution's callback inside an - * `invokeFunction` so its `ctx.get` resolves through the agent container. - * Unknown names fail with a coded `REQUEST_INVALID` error. Bound at Agent - * scope; constructed on demand — nothing pushes to a command registry, every - * consumer pulls. - */ - import { Emitter, type Event } from '#/_base/event'; import { type CollectionRecord, type CollectionView } from '#/_base/di/collection'; import { diff --git a/packages/agent-core-v2/src/agent/command/commandContribution.ts b/packages/agent-core-v2/src/agent/command/commandContribution.ts index 73a63da3c..f902c3a6f 100644 --- a/packages/agent-core-v2/src/agent/command/commandContribution.ts +++ b/packages/agent-core-v2/src/agent/command/commandContribution.ts @@ -1,15 +1,3 @@ -/** - * `command` domain — the `CommandContribution` collection token and payload. - * - * An executable command a Feature (or any unit) contributes into the - * agent-scope registry (`IAgentCommandService`) — unlike plugin commands, - * which are prompt templates, a contributed command runs engine-side with DI - * access. `run` receives a `CommandRunContext` whose `get` resolves services - * from the target agent's container; the records carry the provider unit's - * name as `source`, and a record is withdrawn when its provider dies. No - * scoped state — pure payload + token. - */ - import { collection } from '#/_base/di/collection'; import type { ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts b/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts index a8dcf5b6e..d4829d03e 100644 --- a/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts +++ b/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts @@ -1,15 +1,3 @@ -/** - * `contextInjector` domain — `IAgentContextInjectorService` implementation. - * - * Reconciles registered model-context providers against `contextMemory` at the - * head of every loop step (before the step's request is built), so every LLM - * request sees the freshest injections. A compaction splice re-arms the - * new-turn flag for the next step. `reconcileWhenIdle` lets out-of-loop - * callers (SDK RPC surfaces) refresh one provider immediately while the loop - * is quiet. Writes reminders through `systemReminder` and reports provider - * failures through `log`. Bound at Agent scope. - */ - import { toDisposable, type IDisposable } from "#/_base/di/lifecycle"; import { Service } from "#/_base/di/service"; import { LifecycleScope } from '#/app/scopes'; @@ -96,9 +84,6 @@ export class AgentContextInjectorService extends Service implements IAgentContex const rearmed = this.takeCompactionRearm(); await this.inject(ctx.firstStepOfTurn || rearmed); await next(); - // Compaction can run inside a later handler of this same chain - // (full-compaction's beforeStep). Its splice always drops injection - // messages, so re-reconcile here — still before the step's request. if (this.takeCompactionRearm()) { await this.inject(true); } diff --git a/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts b/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts index a489ad9a2..fd05dda5a 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts @@ -1,13 +1,3 @@ -/** - * `contextMemory` domain helper — builds the bounded context window produced - * by compaction and exposes the shared user-message selection rules used by - * live execution and replay. - * - * Estimates token sizes through `kosong`'s contract heuristics (injectable as - * `TokenEstimate`) and wraps elision notes through `systemReminder`. - * Scope-agnostic. - */ - import { estimateTokens, estimateTokensForMessage, estimateTokensForMessages } from '#/kosong/contract/tokens'; import type { ContentPart } from '#/kosong/contract/message'; import { wrapSystemReminder } from '#/agent/systemReminder/systemReminder'; @@ -127,7 +117,6 @@ export function buildContextCompactionShape( }; } - export function buildCompactionSummaryText(summary: string): string { const suffix = summary.trim(); return `${COMPACTION_SUMMARY_PREFIX}\n${suffix.length > 0 ? suffix : '(no summary available)'}`; diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts b/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts index 55eb64d10..a41095190 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts @@ -1,18 +1,4 @@ -/** - * `contextMemory` domain — the durable `context.*` Event2 classes and the - * observable `context.spliced` fact. - * - * The five durable classes are the wire-protocol 1.4 record vocabulary for - * the per-agent conversation history; their `serialize()` output is the - * on-disk record (flat payload, epoch-ms `time`), so v1- and v2-written - * sessions reduce identically and replay stays silent. `ContextSpliced` is - * the live-only observable counterpart broadcast after every splice-shaped - * mutation (`clear` / `applyCompaction` / `undo` / verified cross-model - * trailing removal). Scope-agnostic. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts b/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts index 339a53aaa..6f39770b3 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts @@ -1,15 +1,3 @@ -/** - * `contextMemory` domain — `IAgentContextMemoryService` implementation. - * - * Owns per-agent conversation history through the event dispatcher, maintains - * measurements with `tokenCounting`. Every - * splice-shaped mutation (`clear` / `applyCompaction` / `undo`, plus verified - * cross-model trailing removal) publishes `context.spliced` from the live path - * only — replay rebuilds silently — and truncates the measured-anchor ledger - * when a cut crosses an anchor, letting `tokenCounting` restore the surviving - * prefix's REAL size from the remaining anchors. Bound at Agent scope. - */ - import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -46,7 +34,6 @@ import { import type { LoopRecordedEvent } from './loopEventFold'; import type { ContextMessage } from './types'; -// NOTE: stays Disposable — its own 'get' collides with the Fiber export class AgentContextMemoryService extends Disposable implements IAgentContextMemoryService { declare readonly _serviceBrand: undefined; @@ -165,9 +152,6 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte private dispatchCutEvents(cutIndex: number): void { const model = this.agentState.get(tokenCountingKey); if (!model.anchors.some((anchor) => anchor.length > cutIndex)) return; - // The display tokens are the post-cut size computed from the CURRENT - // ledger — anchors at or below the cut are identical before and after - // the truncation, so the pre-dispatch read is exact. void this.dispatcher.dispatch( new TokenCountingTruncated({ length: cutIndex, diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts b/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts index 6ae90c0af..80186c277 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts @@ -1,39 +1,3 @@ -/** - * `contextMemory` domain — the conversation-history state (`contextMemoryKey`) - * and its folds over the durable `context.*` events (`ContextAppendMessage` / - * `ContextAppendLoopEvent` / `ContextClear` / `ContextApplyCompaction` / - * `ContextUndo`), plus the undo-cut and compaction-record helpers. - * - * Declares the history as `ContextMessage[]` (initial `[]`); every fold runs - * on the immer draft and either mutates it or returns a replacement, so a - * no-op keeps the same reference (immer returns the base state untouched). - * The live write path emits the v1 vocabulary: non-loop appends (user - * prompts, injections, hook/task notices) go on the wire as - * `context.append_message` (persisted without local ids — the on-disk record - * matches v1's field set), while the agent loop streams each turn as - * `context.append_loop_event` records — the same on-disk shape the v1 loop - * writes — folded into assistant / tool messages both at live dispatch time - * and on replay, so v1- and v2-written sessions reduce identically. - * Swarm-mode announcements are owned by the `swarm` domain's - * context-injection provider; the trailing enter-reminder pop on - * `swarm_mode.exit` is registered by the swarm feature onto `contextMemoryKey` - * (see `popSwarmModeReminder`). - * - * `context.undo` counts conversation ticks with the single `isUndoAnchor` - * predicate — the same definition the checkpoint - * protocol pushes with, so anchor counting and checkpoint pushing can never - * drift apart. - * - * Blob handling is declared as a `StateBlobCodec` on `contextMemoryKey.replayable.blobs`: - * - `dehydrate(record, transform)`: at dispatch time, traverses message content - * in `context.append_message` and `context.append_loop_event` records, - * passing each `ContentPart[]` through `transform` to offload oversized data - * URIs. - * - `rehydrate(state, transform)`: after replay, traverses the surviving final - * state and loads `blobref:` URLs back to inline data — skipping I/O for - * data that was compacted away during the session. - */ - import { z } from 'zod'; import { ErrorCodes, Error2 } from '#/errors'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts b/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts index 773378317..178272b47 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts @@ -1,10 +1,3 @@ -/** - * `contextMemory` domain — rebuilds display history from the wire journal. - * - * Supplies transcript consumers with full pre-compaction history and folded - * context length while preserving undo/clear semantics. Scope-agnostic. - */ - import { type ContentPart, type ToolCall } from '#/kosong/contract/message'; import type { WireRecord } from '#/wire/record'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts b/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts index 7878a8fd9..ca1edd089 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts @@ -1,18 +1,3 @@ -/** - * `contextMemory` domain — shared conversation clock and the undoable - * protocol registration. - * - * Defines the undo anchor vocabulary and registers the undoable protocol - * consumed by the state domain's `.undoable()` expansion: the four protocol - * events (`context.append_message` / `context.apply_compaction` / - * `context.clear` / `context.undo`), the single `isUndoAnchor` tick - * predicate, and the undo-count guard. A state key whose value must follow - * conversation undo chains `.undoable()` — never hand-rolling the - * checkpoint/clear/rollback folds — so undo anchors push a checkpoint, - * compaction/clear drop the markers, and `context.undo` rolls back through - * inverse patches (or through the key's custom `onUndo`). Scope-agnostic. - */ - import { registerUndoableProtocol } from '#/state/state'; import { diff --git a/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts b/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts index 6d152f138..22a07edbf 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts @@ -1,10 +1,3 @@ -/** - * `contextMemory` domain — Agent-scoped post-undo reconciliation registry. - * - * Hosts state-repair participants for the undo coordinator. Bound at Agent - * scope. - */ - import { createDecorator } from '#/_base/di/instantiation'; import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts b/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts index d9ead31e5..521dc2aba 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts @@ -1,44 +1,3 @@ -/** - * `contextMemory` loop-event fold — reduction of `context.append_loop_event` - * records into folded `ContextMessage`s. - * - * The agent loop streams a turn as `context.append_loop_event` records - * (`step.begin` / `content.part` / `tool.call` / `tool.result` / `step.end`) - * and never writes a folded assistant message, keeping the on-disk shape - * byte-compatible with v1. This fold turns them into assistant / tool - * messages — at live dispatch time and again when `WireService.restore` - * restores an Agent. Without it, restore would skip those records (no Op is - * registered for the type) and the restored `contextMemoryKey` — and every - * consumer built on it — would show only the user prompts. - * - * Semantics mirror the v1 fold exactly: - * - `step.begin` → open an assistant message (`partial: true`); first settle - * the step left open by a failed attempt - * - `content.part`→ append to the open assistant's content - * - `tool.call` → append to the open assistant's `toolCalls`, mark pending - * - `tool.result` → push a `tool` message (with the v1 output - * wrapping), clear its pending id - * - `step.end` → settle the assistant - * "Settle" closes any tool exchange left open (interrupted result messages), - * then drops the partial assistant when nothing sendable was recorded (no - * tool calls; every content part vacuous — an output-free assistant only - * trips provider message validation) and seals it (`partial: undefined`) - * when it carries output. v1 never produced - * `step.begin` without `step.end` (its retries stayed inside one request), so - * the drop/seal rule is the v2 extension that makes loop-level retries — a - * retried attempt is its own `step.begin` — replay to the same history the - * live loop folded. - * A `context.append_message` reduced while a tool exchange is still open is - * deferred and flushed once the exchange closes, so strict-provider - * assistant↔tool adjacency is preserved. - * - * The fold is stateful across records within one replay. State is carried in a - * `WeakMap` keyed by each committed state array (immer drafts resolve to - * their `original`), so the public `getState(ContextModel)` view stays a - * plain `ContextMessage[]` and concurrent replays of different agent scopes - * never share fold state. - */ - import { isDraft, original } from 'immer'; import type { FinishReason } from '#/kosong/contract/provider'; @@ -114,7 +73,6 @@ interface FoldCtx { const foldCtxMap = new WeakMap(); function ctxOf(state: readonly ContextMessage[]): FoldCtx { - // eslint-disable-next-line @typescript-eslint/no-explicit-any const key = (isDraft(state) ? original(state as any) : state) as object; let ctx = foldCtxMap.get(key); if (ctx === undefined) { diff --git a/packages/agent-core-v2/src/agent/contextMemory/messageId.ts b/packages/agent-core-v2/src/agent/contextMemory/messageId.ts index b764549d6..6518caed9 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/messageId.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/messageId.ts @@ -1,16 +1,3 @@ -/** - * `contextMemory` message id helpers. - * - * Local message ids (`msg_`) are process-lifetime identifiers only — - * they are NOT persisted: the on-disk `context.append_message` record carries - * exactly v1's field set, and public message ids are derived from the - * transcript index (by the server layer's `ContextMessage → wire Message` - * projection), which stays stable across live reads and resume. - * `newMessageId` remains for callers that need an opaque per-process id. - * Provider-assigned ids live on the separate `providerMessageId` field and - * never collide with this namespace. - */ - import { ulid } from 'ulid'; export function newMessageId(): string { diff --git a/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts b/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts index 683cd465f..26e4969f1 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts @@ -1,12 +1,3 @@ -/** - * `contextMemory` domain helper — projects stored tool result facts into - * model-visible content. - * - * Tool messages keep the raw tool output plus structured status fields in - * context. The LLM projection is the only boundary that turns those facts into - * system status text or appends model-only notes. - */ - import type { ContentPart } from '#/kosong/contract/message'; const TOOL_ERROR_STATUS = 'ERROR: Tool execution failed.'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts b/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts index 932de9214..e0e1f9e46 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts @@ -1,12 +1,3 @@ -/** - * `contextMemory` vacuous-content predicate — shared test for content parts - * that carry nothing the provider wire can represent. Vacuous means an empty - * or whitespace-only text block, or an empty thinking block with no provider - * signature; a signed thinking block (`encrypted`) is never vacuous — - * reasoning providers require it back verbatim — and media parts always - * carry content. - */ - import type { ContentPart } from '#/kosong/contract/message'; export function isVacuousContentPart(part: ContentPart): boolean { diff --git a/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts b/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts index 1262ba471..46e1bbacd 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts @@ -1,19 +1,3 @@ -/** - * `contextProjector` domain — Agent-scope context projection contract. - * - * Defines wire-safe history projections and an opaque snapshot of the media - * identities that a provider rejected, allowing later steps to strip only - * that content while preserving newly generated recovery media. - * - * Projection variability is expressed as data: a `ProjectionPolicy` — - * `structure: 'strict'` adds the structural repairs strict providers need - * (duplicate tool calls dropped, consecutive assistants merged, leading - * non-user messages dropped); `media` selects the provider-rejection - * fallback (`'degraded'` replaces all but the most recent media with text - * markers after an HTTP 413; `{ strip }` replaces exactly the snapshotted - * media identities after a rejected-format or still-too-large resend). - */ - import { createDecorator } from '#/_base/di/instantiation'; import type { Message } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts b/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts index c0f50e302..82bab0a2e 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts @@ -1,17 +1,3 @@ -/** - * `contextProjector` domain — `IAgentContextProjectorService` implementation. - * - * Projects stored context history into the wire messages sent to the model, - * applies the read-side media fallbacks selected by `policy.media`, and - * surfaces every repair the projection had to apply: the repairs are - * summarized once per distinct signature into a single deduped warning - * (through `log`) plus a `context_projection_repaired` telemetry event - * (through `telemetry`), so a silently-mangled history always leaves a - * trace. The mutable repair-dedup signature (`lastRepairSignature`) is - * registered into `agentState` (`IAgentStateService`) and read/written - * through it. Bound at Agent scope. - */ - import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; diff --git a/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts b/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts index 0c81f03c5..741465ce9 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts @@ -1,15 +1,3 @@ -/** - * `contextProjector` domain — read-side media fallbacks for the two - * deterministic provider rejections. - * - * The degraded projection replaces all but the most recent media parts with - * text markers after an HTTP 413 body-size rejection; the strip projection - * replaces exactly the snapshotted media identities after a rejected-format - * or still-too-large resend, so a newly generated recovery image stays - * visible on later steps. Both rewrite only the projected wire messages — - * the stored history keeps its media. - */ - import { createHash } from 'node:crypto'; import type { ContentPart, Message } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/agent/contextProjector/projection.ts b/packages/agent-core-v2/src/agent/contextProjector/projection.ts index 3b25495cc..c4cd5f726 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/projection.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/projection.ts @@ -1,23 +1,3 @@ -/** - * `contextProjector` domain — rebuilds stored context history into - * provider-valid wire messages and reports every repair through an anomaly - * sink. - * - * The default projection pairs tool calls with their results (a displaced - * result returns to its call, an orphan is dropped, a call left open is - * closed with a synthetic interrupted result), renders stored tool-result - * facts for the model, drops blank text and wholly-vacuous messages, skips - * partial messages, and merges consecutive user prompts. The strict - * projection adds the repairs strict providers need: duplicate tool calls - * dropped, consecutive assistants merged, leading non-user messages dropped. - * - * A history slice without any assistant message is a sizing slice (used to - * size tool results): tool messages project like any other message instead - * of pairing into exchanges. A synthesized close counts as `trailing` — an - * expected in-flight close rather than a defect — exactly when no non-tool, - * non-partial message follows the owning message in the slice. - */ - import { ErrorCodes, Error2 } from '#/errors'; import { renderToolResultForModel } from '#/agent/contextMemory/toolResultRender'; import type { ContextMessage } from '#/agent/contextMemory/types'; diff --git a/packages/agent-core-v2/src/agent/externalHooks/configSection.ts b/packages/agent-core-v2/src/agent/externalHooks/configSection.ts index a84b322fc..e9550c4a2 100644 --- a/packages/agent-core-v2/src/agent/externalHooks/configSection.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/configSection.ts @@ -1,12 +1,3 @@ -/** - * `externalHooks` domain — `hooks` config-section schema and TOML - * transforms. - * - * Owns the `[[hooks]]` configuration section (external hook definitions), - * including the snake_case ↔ camelCase TOML transforms for each hook entry. - * Registered at module load via `registerConfigSection`. - */ - import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts b/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts index f56571ea1..6aae3f2e5 100644 --- a/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts @@ -1,12 +1,3 @@ -/** - * `externalHooks` domain — contract for configured external hook - * commands. - * - * The service is intentionally observer-shaped: business domains expose their - * own minimal hook contexts, and the L6 implementation listens to those hooks - * to invoke configured external commands. - */ - import { createDecorator } from '#/_base/di/instantiation'; export interface RenderedExternalHookResult { diff --git a/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts b/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts index a28ed0b2e..95a2bedf6 100644 --- a/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts @@ -1,28 +1,4 @@ -/** - * `externalHooks` domain — Agent-scope adapter for external - * hook commands. - * - * Listens to hook slots and agent events owned by the agent behavior/lifecycle - * domains (`toolExecutor`, `permissionGate`, `prompt`, `turn`, `loop`, - * `fullCompaction`, and `task`) and translates those minimal contexts into the - * configured external hook commands, run through the shared App-scope - * `IExternalHooksRunnerService` (so this adapter never owns an engine lifecycle - * of its own). This includes the bus-driven lifecycle signals - * `turn.started` → `TurnStarted`, `prompt.queued` → `UserPromptQueued`, and - * `task.started` → `TaskStarted`. Every payload it sends is enriched with the - * cached session title (seeded from and kept fresh by `ISessionMetadata`). - * Appends - * UserPromptSubmit hook results through `contextMemory`, drives Stop hook - * continuations by enqueueing a mergeable `StepRequest` onto `loop`, and - * passes the current session id from `sessionContext` - * into hook runner payloads. The one mutable latch - * (`stopHookContinuationUsed`, the Stop-hook re-entry guard) is registered - * into `agentState` (`IAgentStateService`) and read/written through it; the - * hook listener registrations stay ordinary disposables on the instance. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { IInstantiationService } from '#/_base/di/instantiation'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts b/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts index 7845afa36..171b77dc3 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts @@ -1,41 +1,4 @@ -/** - * `fullCompaction` domain — the `fullCompactionKey` state, the durable - * `full_compaction.begin` (`FullCompactionBegin`) / `full_compaction.cancel` - * (`FullCompactionCancel`) / `full_compaction.complete` - * (`FullCompactionComplete`) events that mirror the full-compaction lifecycle - * into a persisted, replayable phase, plus the live-only `compaction.*` - * observables (`CompactionStarted` / `CompactionBlocked` / - * `CompactionCancelled` / `CompactionCompleted`). - * - * The state is intentionally phase-only — `{ phase }` (initial `idle`). The - * richer per-compaction data is NOT resume state: `instruction` is only needed - * by the live worker (which does not survive a restart) and by telemetry, so it - * rides the `begin` payload (and is persisted on the record for audit) but is - * not stored in the state; result numbers are consumed live by the - * `CompactionCompleted` signal and their durable effect (the summary message - * plus compaction metrics) already lives in the context history. The live - * `complete` payload is empty to match the v1 wire shape; legacy logs may still - * carry result numbers, and the replay schema parse accepts and strips them - * while the fold collapses to `idle`. Each fold keeps the same reference on a - * no-op so the state's reference-equality stays quiet; it carries no - * non-determinism. The durable classes are the wire-protocol record - * vocabulary: their `serialize()` output is the on-disk record (flat payload, - * epoch-ms `time`), byte-compatible with the retired op encoding. - * - * The runtime orchestration — `ActiveCompaction`, its `AbortController`, and - * the in-flight worker promise — stays OUT of the state (live-only service - * members): none of it can be resumed, and a session never restores mid-flight. - * A `running` phase stranded by a crash is reset to `idle` by the service's - * `dispatcher.hooks.onDidRestore` hook. - * - * The `compaction.*` observables are transient: `CompactionStarted` is emitted - * from the `FullCompactionBegin` fold via `ctx.emit` (live only, reading the - * event payload like the retired `toEvent`); the rest are dispatched directly - * by the service. Replay never emits them. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/fullCompaction/errors.ts b/packages/agent-core-v2/src/agent/fullCompaction/errors.ts index 0aa153ce7..554374ae3 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/errors.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/errors.ts @@ -1,7 +1,3 @@ -/** - * `fullCompaction` domain error codes. - */ - import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const FullCompactionErrors = { diff --git a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts index 96dd6587d..94efa719e 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts @@ -1,23 +1,3 @@ -/** - * `fullCompaction` domain — `IAgentFullCompactionService` implementation. - * - * Runs full-history compaction: reserves the per-turn compaction slot, drives - * the compaction LLM round (with overflow / truncation shrink retries), - * applies the summary back into context memory, and recovers the loop from - * context-overflow failures by blocking the turn on the in-flight job. The - * mutable plain-data state (`compactionCountInTurn`, - * `observedMaxContextTokensByModel`, `lastCompactedTokenCount`, - * `consecutiveOverflowCompactions`, `activeTurnId`) is registered into - * `agentState` (`IAgentStateService`) and read/written through it; - * `_compacting` (the in-flight job — AbortController / Promise / trace), the - * `hooks.onWillCompact` slot, the `_onDidFinishCompaction` Emitter, and the - * `strategy` stay instance fields (mechanism, not plain data). The compaction - * splice re-arms `contextInjector`'s new-turn flag, so providers re-reconcile - * at the next step head. Bound at Agent scope and constructed with - * the scope so the overflow recovery handler registers before the first turn - * runs. - */ - import type { IDisposable } from '#/_base/di/lifecycle'; import { Service } from "#/_base/di/service"; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/agent/goal/errors.ts b/packages/agent-core-v2/src/agent/goal/errors.ts index ff59b94e9..ec0bc2837 100644 --- a/packages/agent-core-v2/src/agent/goal/errors.ts +++ b/packages/agent-core-v2/src/agent/goal/errors.ts @@ -1,7 +1,3 @@ -/** - * `goal` domain error codes. - */ - import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const GoalErrors = { diff --git a/packages/agent-core-v2/src/agent/goal/goal.ts b/packages/agent-core-v2/src/agent/goal/goal.ts index e88c5952c..14afa9710 100644 --- a/packages/agent-core-v2/src/agent/goal/goal.ts +++ b/packages/agent-core-v2/src/agent/goal/goal.ts @@ -1,10 +1,3 @@ -/** - * `goal` domain — main-agent goal lifecycle contract. - * - * Defines the commands and snapshots used to create, inspect, update, and clear - * the durable goal state. Bound at Agent scope; subagent callers are rejected - * with `goal.unsupported_agent`. - */ import { createDecorator } from "#/_base/di/instantiation"; import type { CreateGoalInput, diff --git a/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts b/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts index 6d460f6e8..5ae6a80bd 100644 --- a/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts +++ b/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts @@ -1,10 +1,3 @@ -/** - * `goal` domain — wall-clock deadline scheduling contract. - * - * Defines the App-scoped `IGoalDeadlineScheduler` for measuring active time - * and arming hard wall-clock budget deadlines. - */ - import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts b/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts index 8e63f1199..78cf2cace 100644 --- a/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts +++ b/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts @@ -1,10 +1,3 @@ -/** - * `goal` domain — `IGoalDeadlineScheduler` implementation. - * - * Measures monotonic elapsed time and schedules disposable one-shot deadlines - * with the host timer API. Bound at App scope. - */ - import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/goal/goalOps.ts b/packages/agent-core-v2/src/agent/goal/goalOps.ts index 454e06c1b..434ca98be 100644 --- a/packages/agent-core-v2/src/agent/goal/goalOps.ts +++ b/packages/agent-core-v2/src/agent/goal/goalOps.ts @@ -1,35 +1,4 @@ -/** - * `goal` domain — the `goalKey` state, the durable `goal.create` - * (`GoalCreate`) / `goal.update` (`GoalUpdate`) / `goal.clear` (`GoalClear`) / - * `forked` (`GoalForked`) events for the per-agent goal lifecycle, and the - * live-only `goal.updated` observable (`GoalUpdated`). - * - * The state holds `GoalState | null` (initial `null`); `GoalState` holds the - * persistent, replayable fields — identity, objective, status, `turnsUsed` / - * `tokensUsed`, the accumulated `wallClockMs`, the current active interval's - * epoch-ms `wallClockResumedAt`, `budgetLimits`, and `terminalReason`. The - * persistence contract charges an active interval from its persisted - * create/resume anchor through the first recovery clock read, then folds that - * interval into `wallClockMs` while recovery pauses the goal. This - * intentionally includes unobservable crash downtime: a monotonic clock - * cannot span processes, while learning the crash instant would require - * periodic durable writes. System-clock rollback is clamped to zero. The - * 1.4 -> 1.5 compatibility transform (also applied before sealing - * envelope-less logs) derives missing create/resume/checkpoint anchors from - * those records' existing epoch-ms `time` stamps. The durable classes are the - * wire-protocol record vocabulary: their `serialize()` output is the on-disk - * record (flat payload, epoch-ms `time`), byte-compatible with the retired op - * encoding. The non-deterministic values stay OUT of the folds: `goalId` and - * the wall-clock anchor/totals are computed by the live service and carried - * in event payloads. Each fold keeps the same reference when nothing changes - * so the state's reference-equality stays quiet. The `GoalUpdated` fact is - * dispatched live by the service (observable, never on replay); restore - * rebuilds the state silently and the service's `dispatcher.hooks.onDidRestore` - * forces a replayed `active` goal back to `paused`. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/goal/goalService.ts b/packages/agent-core-v2/src/agent/goal/goalService.ts index 27ff9ceb1..ef356fcf0 100644 --- a/packages/agent-core-v2/src/agent/goal/goalService.ts +++ b/packages/agent-core-v2/src/agent/goal/goalService.ts @@ -1,44 +1,3 @@ -/** - * `goal` domain — `IAgentGoalService` implementation. - * - * Owns the main-agent goal lifecycle; persists the goal in the `goalKey` - * state (`GoalState | null`) through the durable `GoalCreate` / `GoalUpdate` / - * `GoalClear` events (`dispatcher.dispatch`), reads it through - * `dispatcher.getState`, dispatches the live-only `GoalUpdated` observable - * through the same dispatcher, and forces a replayed `active` - * goal back to `paused` via `dispatcher.hooks.onDidRestore`. The accumulated - * `wallClockMs` lives in the state (set from each event payload, never by - * `Date.now()` inside a fold); the active interval's epoch-ms - * `wallClockResumedAt` anchor is - * persisted at create/resume boundaries so recovery can settle crash-spanning - * elapsed time without periodic writes. A `forked` journal record (written at - * a fork boundary) clears the state. Injects reminders through - * `contextInjector`, drives continuation turns by enqueueing `newTurn` - * `StepRequest`s onto `loop` (the continuation message materializes when the - * loop pops it), accounts live - * turn usage through `usage`, observes terminal goal tool results through - * `toolExecutor`, appends one-time reminder events through `systemReminder`, reports - * telemetry through `telemetry`, and checks main-agent eligibility through - * `scopeContext`. Measures time and arms hard deadlines through `goal`'s - * App-scoped deadline scheduler. Two `onBeforeExecuteTool` veto listeners - * guard the goal lifecycle: stale or budget-exhausted goal tool calls are - * vetoed with synthetic results, and a `CreateGoal` call carrying a - * `goal_start` display outside `auto` mode defers to a cold `waitUntil` - * factory that runs the goal-start review through `toolApproval` under the - * origin `goal-start-review-ask` — including the permission-mode switch - * picked on the approval surface. The mutable turn-tracking and wall-clock - * state (`liveTurnId`, `goalDrivenTurns`, `countedGoalTurns`, - * `goalStarterTurns`, `goalOutcomeToolResultTurns`, - * `goalOutcomeContinuationTurns`, `budgetGraceTurns`, - * `pendingContinuationGoals`, `goalTurnTargets`, `exhaustedTurnBudgetGoals`, - * `liveWallClockStartedAt`, `resumeContinuation`) is registered into - * `agentState` (`IAgentStateService`) and read/written through it; the - * `pendingContinuation` promise lock and the `wallClockDeadline` disposable - * slot stay plain fields. Bound at Agent scope. - * Subagent instances reject every goal command and do not install goal - * injection, accounting, budget, or continuation hooks. - */ - import { randomUUID } from 'node:crypto'; import { z } from 'zod'; @@ -290,7 +249,6 @@ export const goalResumeContinuationKey = defineState undefined as ResumeContinuation | undefined, ); -// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentGoalService extends Disposable implements IAgentGoalService { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/goal/types.ts b/packages/agent-core-v2/src/agent/goal/types.ts index ea20af32b..48d0e2de4 100644 --- a/packages/agent-core-v2/src/agent/goal/types.ts +++ b/packages/agent-core-v2/src/agent/goal/types.ts @@ -1,7 +1,3 @@ -/** - * `goal` domain — public goal lifecycle and budget models. - */ - export type GoalStatus = 'active' | 'paused' | 'blocked' | 'complete'; export type GoalActor = 'user' | 'model' | 'runtime' | 'system'; diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts index 619accfcf..5dfb78d60 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts @@ -1,10 +1,3 @@ -/** - * `interruptionReminder` domain (L4) — user-interruption reminder contract. - * - * Defines the Agent-scoped aspect that records a model-visible reminder after - * a user-cancelled turn. Bound at Agent scope. - */ - import { createDecorator } from '#/_base/di/instantiation'; export interface IAgentInterruptionReminderService { diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts index 2c6de9d07..d686c90ff 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts @@ -1,15 +1,4 @@ -/** - * `interruptionReminder` domain — legacy journal compatibility tombstone. - * - * Retains the historical `interruptionReminder.recorded` durable event as a - * no-op fold on a `null` state so old Agent journals replay without - * unknown-record diagnostics. New interruption reminders append at the - * cancellation event point and write no domain-owned delivery state. - * Scope-agnostic. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts index 1466db7ab..7ea0ea776 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts @@ -1,11 +1,3 @@ -/** - * `interruptionReminder` domain — `IAgentInterruptionReminderService` implementation. - * - * Observes completed turns through `eventBus`, appends user-cancellation facts - * through `systemReminder` at the event point, and reads `contextMemory` to - * collapse retry-only duplicate notices. Bound at Agent scope. - */ - import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts b/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts index 142b111a5..fc451fcd2 100644 --- a/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts +++ b/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts @@ -1,14 +1,4 @@ -/** - * `llmRequester` domain — durable request-trace state and events. - * - * Defines the `llm.tools_snapshot` snapshot event and the `llm.request` - * outbound request trace event; the `llmRequestTraceKey` state folds only - * the snapshot de-dup cursor (`llm.request` records restore as journal facts - * with no state). Scope-agnostic. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts b/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts index cb2726031..050b65e74 100644 --- a/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts +++ b/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts @@ -1,40 +1,3 @@ -/** - * `llmRequester` domain — `IAgentLLMRequesterService` implementation. - * - * Assembles per-turn `ModelRequestInput` from `profile` (system prompt), - * `contextMemory` + `contextProjector` (history), `toolRegistry` (tools), and - * `toolSelect` (progressive-disclosure shaping of the tool and history views), - * folds the completion-token budget into the profile's dialect-free intent - * params, then drives a bounded request chain through the `ModelRequester` - * resolved from `IModelCatalog`: one primary `requester.request(input, signal, - * params)` attempt plus accumulating projection rebuilds — each repeated - * provider rejection (request structure, body size, image format) adds its own - * repair on top of the ones already applied. Before each request the projected - * messages pass through `media`'s - * media resolver, which rewrites every `kimi-file://` prompt-media reference - * to a provider-acceptable part (an uploaded `ms://` video, an inline base64 - * `data:` part, or a degradation tag/drop) so the internal reference never - * reaches the wire. When a - * model is configured, `prepareTurnConfig` snapshots the - * model, effective thinking effort, and system prompt at the turn boundary - * so loop telemetry and every request in that turn share one configuration. - * Forwards streamed `part` events to the caller's `onPart` - * handler — rewriting duplicate provider tool call ids into per-agent unique - * ones through `ToolCallIdNormalizer`, since self-hosted endpoints may - * renumber ids per response and every downstream keying assumes uniqueness — - * records `usage` through `IAgentUsageService`, resolves to an - * `AgentLLMRequestFinish` on the `finish` event, logs the request lifecycle - * (config deduplicated by content, request/response/failure lines, plus - * per-request fields) through `log`, publishes advisory model-capability - * warnings through the `WarningIssued` event, records durable request-trace - * events through the event dispatcher, reports each request's `x-trace-id` to its caller, and - * reports provider failures through `telemetry`. The mutable request state - * (`lastConfigLogSignature`, `turnConfigs`, `mediaDegradedTurns`, - * `mediaStrippedTurns`, `emittedThinkingEffortWarnings`) is registered into - * `agentState` (`IAgentStateService`) and read/written through it. Bound at - * Agent scope. - */ - import { createHash } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -447,9 +410,6 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { } this.usage.record(request.modelAlias, usage ?? emptyUsage(), request.source); - // Only a stream that actually reported usage may write a measured - // anchor — recording emptyUsage() zeros would zero the context size and - // silence compaction for providers without usage reporting. if (usage !== undefined) { this.tokenCounting.measured(request.messages, [message], usage); } diff --git a/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts b/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts index df2c951af..0a21267c5 100644 --- a/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts +++ b/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts @@ -1,18 +1,3 @@ -/** - * `llmRequester` domain — per-agent tool call id normalizer. - * - * Self-hosted OpenAI-compatible endpoints may renumber tool call ids on every - * response (`Bash_0`, `Bash_1`, ...), so unrelated calls reach the engine - * sharing one id while every downstream keying — context rebuild, transcript - * frames, activity views, outbound call/result pairing — assumes an id - * identifies exactly one call. The normalizer enforces that at the ingestion - * boundary: the first occurrence of an id passes through unchanged, later - * occurrences are rewritten to a readable `__` suffix. Claimed ids are - * remembered for the agent's lifetime (seeded from the restored context), and - * a failed request attempt rolls its claims back so a projection retry - * re-streams the same logical calls under the same ids. - */ - import type { Message, ToolCall } from '#/kosong/contract/message'; export class ToolCallIdNormalizer { diff --git a/packages/agent-core-v2/src/agent/loop/configSection.ts b/packages/agent-core-v2/src/agent/loop/configSection.ts index d169a4830..b04d4e4cc 100644 --- a/packages/agent-core-v2/src/agent/loop/configSection.ts +++ b/packages/agent-core-v2/src/agent/loop/configSection.ts @@ -1,25 +1,3 @@ -/** - * `loop` domain — `loopControl` config-section schema, env bindings, and - * TOML transforms. - * - * Owns the `[loop_control]` configuration section (step / retry / context-size - * limits). Renamed keys are declared through the config domain's deprecation - * mechanism (`deprecations`): a deprecated key in `config.toml` no longer - * applies and reports a warning pointing at its replacement — this covers the - * `max_retries_per_step` → `max_attempts_per_step` rename and the older - * `max_steps_per_run` → `max_steps_per_turn` one. The step and retry budgets - * also accept operational env overrides (`KIMI_LOOP_MAX_STEPS_PER_TURN` / - * `KIMI_LOOP_MAX_ATTEMPTS_PER_STEP`; the former - * `KIMI_LOOP_MAX_RETRIES_PER_STEP` still resolves as a deprecated fallback - * with a warning); `config` resolves each field as `env > config.toml > - * default` and re-applies the env binding on every read. Self-registered at - * module load via `registerConfigSection`. - * - * While a field's env var is set, `stripEnvBoundFields` restores its env-free - * raw value before `set`/`replace` persists, so an env override echoed - * back through a config write can never leak into `config.toml`. - */ - import { z } from 'zod'; import { type EnvBindings, envBindings, stripEnvBoundFields } from '#/app/config/config'; diff --git a/packages/agent-core-v2/src/agent/loop/errors.ts b/packages/agent-core-v2/src/agent/loop/errors.ts index ace59d6fb..662b4ee5f 100644 --- a/packages/agent-core-v2/src/agent/loop/errors.ts +++ b/packages/agent-core-v2/src/agent/loop/errors.ts @@ -1,10 +1,3 @@ -/** - * `loop` domain error codes. - * - * `turn.agent_busy` is the legacy turn-domain code; the wire string is - * unchanged. - */ - import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const LoopErrors = { diff --git a/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts b/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts index 8564f317c..bd0e5aea8 100644 --- a/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts +++ b/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts @@ -1,18 +1,3 @@ -/** - * `loop` domain — tool-step continuation aspect. - * - * A step that executed tools must drive one more step so the model consumes - * the tool results: this service watches the loop's `onDidFinishStep` and enqueues - * a `ContinuationStepRequest` whenever a step ends with `tool_calls` — which - * is exactly when the step ran tools without a stopTurn tool result (the - * loop maps that combination onto the `tool_calls` finish reason). The loop - * itself only drains the queue and dispatches errors; it never enqueues. A - * hook-set `stopTurn` still wins over the continuation: the turn ends at the - * step boundary and the turn-scoped request is discarded by the run-end - * cleanup. Bound at Agent scope and constructed with the scope so the hook - * registers before the first turn runs. - */ - import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/loop/loopService.ts b/packages/agent-core-v2/src/agent/loop/loopService.ts index 8e9db3236..f22e9ea17 100644 --- a/packages/agent-core-v2/src/agent/loop/loopService.ts +++ b/packages/agent-core-v2/src/agent/loop/loopService.ts @@ -1,36 +1,3 @@ -/** - * `loop` domain — `IAgentLoopService` implementation. - * - * Owns a FIFO of Turn jobs, each with its own `StepRequestQueue`. Admission - * reserves a stable Turn handle immediately; the head job alone books the - * agent's work span with the session lifecycle, records `turn.prompt`, - * publishes `turn.started`, and drains its Steps. Ending unbooks the work span, - * then publishes `turn.ended` and pumps the next queued Turn. Requests without - * an active Turn remain in the Loop-owned pending-input queue and bind to the - * next admitted Turn. - * - * The run drains the queue one batch per step: each batch's driver request - * (plus any mergeable requests folded into it) materializes its context - * messages, then one LLM step runs (`onWillBeginStep` → streamed request → content - * parts → tool execution → `step.end` → `onDidFinishStep`). The loop itself never - * enqueues — it only runs requests and dispatches errors. A failed step is - * dispatched to the registered error handlers (first match wins); a handler - * that claims and catches the error has already enqueued the turn's - * continuation itself, so the loop only learns caught-or-not, while an - * unclaimed or uncaught error fails the turn. Dispatches the durable - * `turn.*` events and the transient `turn.*` / delta observables through - * `state` (`IEventDispatcher`), persists loop events through - * `contextMemory`, and reads the step budget from `config`. The plain-data - * loop state - * (`nextReservedTurnId`, `lastRequestTraceId`, `disposing`) is registered - * into `agentState` (`IAgentStateService`) and read/written through it; - * `pendingTurns` and `activeTurnJob` stay plain fields because a `TurnJob` - * holds resources (`AbortController`, controlled promises, a - * `StepRequestQueue`) that must not be snapshotted, alongside the mechanism - * resources (`standaloneStepQueue`, `pendingAssignments`, `errorHandlers`, - * `settleWaiters`, `activeRequestTrace`). Bound at Agent scope. - */ - import { randomUUID } from 'node:crypto'; import { createControlledPromise } from '@antfu/utils'; @@ -113,7 +80,6 @@ export const loopLastRequestTraceIdKey = defineState( ); export const loopDisposingKey = defineState('loop.disposing', () => false); -// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentLoopService extends Disposable implements IAgentLoopService { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/loop/stepRequest.ts b/packages/agent-core-v2/src/agent/loop/stepRequest.ts index fb7c438f6..6cbd92955 100644 --- a/packages/agent-core-v2/src/agent/loop/stepRequest.ts +++ b/packages/agent-core-v2/src/agent/loop/stepRequest.ts @@ -1,18 +1,3 @@ -/** - * `loop` domain — `StepRequest` contracts for the loop's step queue. - * - * A `StepRequest` is one queued unit of step work. Senders create plain - * request objects and hand them to `IAgentLoopService.enqueue`; requests - * carry no DI identity of their own, so - * constructing them with `new` is expected. Each request describes the context - * message(s) it contributes — computed lazily at pop time through - * `resolveContextMessages` — plus its queue semantics (`mergeable`, - * `turnScoped`). Because the message only materializes when the loop pops the - * request, an aborted request is discarded without ever touching the context: - * removal needs no compensating undo. Runtime types only; not registered with - * the container. - */ - import { randomUUID } from 'node:crypto'; import type { ContentPart } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts b/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts index 383f22668..b8aa03ae4 100644 --- a/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts +++ b/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts @@ -1,18 +1,3 @@ -/** - * `loop` domain — the step queue held by `AgentLoopService`. - * - * Turn-owned FIFO with head insertion: senders enqueue `StepRequest`s (tail - * for ordered work, head for retries of a failed step), and one Turn drains - * its queue one batch per step. A batch is one *driver* (the first - * non-mergeable request) plus every *mergeable* request folded into the - * driver's step — this is how steers land in the same LLM request as pending - * tool results or a fresh prompt instead of each costing its own step. Extra - * non-mergeable requests stay queued and drive later steps. Aborted requests - * are discarded when reached, leaving the context untouched. When a run ends, - * turn-scoped requests are aborted while agent-scoped requests (steers) carry - * into the next turn. - */ - import type { StepRequest } from './stepRequest'; export interface StepRequestBatch { diff --git a/packages/agent-core-v2/src/agent/loop/turnEvents.ts b/packages/agent-core-v2/src/agent/loop/turnEvents.ts index 52df446f3..389a84152 100644 --- a/packages/agent-core-v2/src/agent/loop/turnEvents.ts +++ b/packages/agent-core-v2/src/agent/loop/turnEvents.ts @@ -1,23 +1,4 @@ -/** - * `loop` domain — the transient observable `turn.*` / delta `Event2` classes - * published through the event dispatcher as a turn runs. These are the loop's - * share of the agent event stream; consumers subscribe by class (or by `type` - * string). The durable `turn.ended` fact (`TurnEnded`) lives with the - * `turnKey` state in `turnOps`. - * `turn.started` additionally carries the text extracted from the turn's - * input parts (absent when the turn opened with no text part): consumers - * that render the user's prompt must take it from there, because the context - * append carrying the same text is not a bus event and lands later. The - * prompt rides the event only for displayable user origins - * ({@link isDisplayablePromptOrigin}) — a system-triggered turn (goal - * continuation, subagent run, cron…) has internal steering text as its input, - * which must never surface in transcripts. When the turn's prompt bundles - * skill activations, their rendered blocks (prepended to the content, one - * text part per skill) are excluded from the extracted text. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import type { PromptOrigin } from '#/agent/contextMemory/types'; import { Event2 } from '#/app/event/event2'; import type { FinishReason } from '#/kosong/contract/provider'; diff --git a/packages/agent-core-v2/src/agent/loop/turnOps.ts b/packages/agent-core-v2/src/agent/loop/turnOps.ts index 567785865..f27ab3f04 100644 --- a/packages/agent-core-v2/src/agent/loop/turnOps.ts +++ b/packages/agent-core-v2/src/agent/loop/turnOps.ts @@ -1,26 +1,4 @@ -/** - * `loop` domain — the `turnKey` state and the durable `turn.prompt` - * (`TurnPrompt`) / `turn.steer` (`TurnSteer`) / `turn.cancel` (`TurnCancel`) / - * `turn.ended` (`TurnEnded`) events behind monotonically increasing turn - * identity. - * - * The state owns the next available turn id, including cancelled queued - * reservations and legacy loop-event observations (the - * `ContextAppendLoopEvent` fold), plus the terminal `lastEnded` outcome - * (reason / error / durationMs) so downstream history rebuilds and - * cold-resumed read models (e.g. the activity view) can recover how the last - * turn ended. The durable classes are the wire-protocol record vocabulary: - * their `serialize()` output is the on-disk record (flat payload, epoch-ms - * `time`), byte-compatible with the retired op encoding. `TurnEnded` merges - * the retired op with the same-named bus fact: it is durable AND observable, - * and carries the bus-only `interruptReason` alongside the persisted fields — - * its `serialize()` override emits exactly the op's record shape, so the - * journal stays byte-identical and replay never republishes. Consumed by the - * Agent-scope `loopService`. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import type { KimiErrorPayload } from '#/_base/errors/serialize'; diff --git a/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts b/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts index 6a47bba2c..0a63e16a4 100644 --- a/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts +++ b/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts @@ -1,15 +1,4 @@ -/** - * `mcp` domain — MCP tool-discovery state. - * - * Restores the per-agent de-dup cursor for durable MCP discovery records, - * keyed by `${serverName}\n${hash}` entries already present in this log. The - * durable `mcp.tools_discovered` event (`McpToolsDiscovered`) carries the - * discovered tool snapshot; only the cursor is folded into state. - * Scope-agnostic. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import { z } from 'zod'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts b/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts index 638b97fe7..7515df7db 100644 --- a/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts +++ b/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts @@ -1,14 +1,4 @@ -/** - * `mcp` domain — the transient observable `mcp.server.status` / - * `tool.list.updated` `Event2` classes published through the event dispatcher - * as workspace MCP servers change state, plus the shared agent-wide `error` - * observable (`AgentErrorEvent`, a `KimiErrorPayload` on the bus) whose type - * string is contract-fixed for downstream consumers; this domain only owns - * the declaration, any agent service may dispatch it. - */ - /* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ - import type { KimiErrorPayload } from '#/_base/errors/serialize'; import { Event2 } from '#/app/event/event2'; diff --git a/packages/agent-core-v2/src/agent/mcp/mcpService.ts b/packages/agent-core-v2/src/agent/mcp/mcpService.ts index 99f14ab08..d3afabb0b 100644 --- a/packages/agent-core-v2/src/agent/mcp/mcpService.ts +++ b/packages/agent-core-v2/src/agent/mcp/mcpService.ts @@ -1,32 +1,3 @@ -/** - * `mcp` domain — `IAgentMcpService` implementation. - * - * Mirrors the workspace-level shared MCP connection manager's server set - * into the agent's tool registry (the manager arrives through the seeded - * `ISessionMcpHandle` — one manager per workspace handler, shared by every - * session and agent): registers qualified tools for connected servers, - * keeps them registered across reconnects, keeps them registered (with - * calls short-circuited to a removal notice) when the server is tombstoned - * as `removed`, swaps in the OAuth tool for - * `needs-auth` servers, journals tool discoveries on the wire (queued until - * restore finishes), and publishes `mcp.server.status` / `tool.list.updated` - * / collision `error` observables through `state` (`IEventDispatcher`). Only the session's baseline servers take part - * (`ISessionMcpHandle.isBaselineServer`, checked on every replayed and - * live status change): a server that appears mid-session — a plugin - * install or a config edit — is ignored here, so its tools, status events, - * and discoveries never reach a live agent; it joins on the next session - * materialization (`/new`, `/reload`, resume), while a tombstoned baseline - * server reconnecting under the same name (a re-enabled plugin) registers - * again. Sessions and agents construct without awaiting the manager's - * initial connect; each LLM step instead waits for it through a `loop` - * onWillBeginStep hook (a no-op once settled), with the per-execution - * `toolExecutor` onWillExecuteTool wait as the backstop. The plain-data state (`mcpToolsByServer`, `discoveryWritesReady`) - * is registered into `agentState` (`IAgentStateService`) and read/written - * through it; `mcpTools` stays a plain instance field (its values hold - * disposable resource handles, not plain data), as does `pendingDiscoveries` - * (a closure queue of deferred discovery writes). Bound at Agent scope. - */ - import { createHash } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/mcp/output.ts b/packages/agent-core-v2/src/agent/mcp/output.ts index d2af05e44..996ca4ae2 100644 --- a/packages/agent-core-v2/src/agent/mcp/output.ts +++ b/packages/agent-core-v2/src/agent/mcp/output.ts @@ -1,45 +1,3 @@ -/** - * MCP tool-call result → ExecutableTool output pipeline. - * - * Owns the full path from "MCP protocol content blocks" to "what the agent - * loop feeds back to the model": - * 1. Convert each {@link MCPContentBlock} to a kosong `ContentPart` - * (dropping unsupported shapes). - * 2. Wrap media-only outputs in `` tags so the - * model can attribute binary output when several tools return media. - * 3. Serialize `structuredContent` and server `_meta` into a trailing - * `` text part — appended after the media wrap so - * a media-only result keeps its attribution tags, and before the text - * budget so oversized payloads stay bounded. Literal closing tags inside - * the serialized payload are stripped so server data cannot fake an - * early end of the block. `_meta` keys with a protocol-reserved prefix - * (per the spec's key-name rules: a `modelcontextprotocol` or `mcp` - * label followed by at least one more label, as in - * `modelcontextprotocol.io/…` or `tools.mcp.com/…`, but not a vendor - * namespace like `com.example.mcp/…`) are dropped first: they carry - * host/protocol plumbing rather than model-facing data, while unprefixed - * and vendor-prefixed keys pass through because their semantics belong - * to the server. Non-serialisable payloads drop the whole block rather - * than failing the call. - * 4. Apply the 100K text/think character budget to the tool's own text. - * This runs BEFORE captions exist, so a chatty tool (page text + a - * screenshot) can never evict or slice the compression caption — that - * would silently reintroduce the very degradation the caption reports. - * 5. Compress oversized inline images, announcing each compression with a - * caption (original vs. sent size, readback path to the persisted - * original) so downsampling is never silent. The captions ride the - * result's `note` side channel — projected to the model at fold time, but - * kept out of `output` so UIs never render them. - * 6. Apply the per-part 10 MB binary cap: oversized binary parts - * (image/audio/video URLs) collapse to a notice, so a single - * screenshot cannot evict every text part. - * 7. Collapse a single-text-part result to a plain string output; otherwise - * emit the `ContentPart[]` as-is. - * - * `mcpResultToExecutableOutput` is the single entry point; the per-step - * helpers stay private so callers cannot bypass the limits. - */ - import type { ContentPart } from '#/kosong/contract/message'; import type { ITelemetryService } from '#/app/telemetry/telemetry'; diff --git a/packages/agent-core-v2/src/agent/mcp/tools/auth.ts b/packages/agent-core-v2/src/agent/mcp/tools/auth.ts index 4464a90a3..0426a71c6 100644 --- a/packages/agent-core-v2/src/agent/mcp/tools/auth.ts +++ b/packages/agent-core-v2/src/agent/mcp/tools/auth.ts @@ -1,29 +1,3 @@ -/** - * Synthetic `mcp____authenticate` tool. - * - * When a remote MCP server lands in the `needs-auth` state — i.e. its - * initial connection failed with a 401 / `UnauthorizedError` and no static - * bearer token is configured — the {@link ToolManager} swaps the real MCP - * tool list for this single tool. Calling it: - * - * 1. Asks {@link McpOAuthService} to perform RFC 9728 / RFC 8414 / RFC 7591 - * discovery and produce an authorization URL. - * 2. Streams that URL back to the model via `onUpdate({kind:'status'})` - * and returns it in the tool output so the model can hand it to the - * human user. - * 3. Blocks (up to {@link DEFAULT_AUTH_TIMEOUT_MS}) on the one-shot - * localhost callback listener owned by the OAuth service. - * 4. Drives a manager-level `reconnect(name)` once tokens have been - * persisted, which flips the entry to `connected` and lets - * `ToolManager` swap the synthetic tool out for the real MCP tools. - * - * The blocking shape keeps the implementation - * simple at the cost of holding one tool call open for the duration of - * the human's browser flow. If the model ends up re-invoking the tool - * mid-flow we just start a fresh flow; the new callback server supersedes - * the old one. - */ - import { z } from 'zod'; import { diff --git a/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts b/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts index 3f527c3f2..1067f5774 100644 --- a/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts +++ b/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts @@ -1,32 +1,3 @@ -/** - * MCP tool adapter — wraps a remote MCP tool as an `ExecutableTool`. - * - * Each tool exposed by a connected MCP server is adapted into an - * `ExecutableTool` whose `resolveExecution` forwards the call to the client - * and normalizes the result. When a call fails, the adapter picks one of - * three recoveries based on why it failed: - * - * - The server answered (a JSON-RPC error, or a response that failed - * client-side schema validation) → the error is rethrown; reconnecting - * would not change the answer. - * - The failure is ambiguous (a raw fetch/socket error) → the client is - * probed with a ping: alive means a transient blip and the call is - * retried once in place; dead means the transport is gone. - * - The transport is provably dead (the SDK fired `onclose`, or the probe - * failed) → the server is reconnected once through `options.reconnect` - * and the call retried on the fresh client, so a dropped connection - * surfaces as a slow call instead of a failed turn. - * - * Retries are at-least-once: if the transport died after the server - * processed the call but before the response arrived, the retry may - * duplicate side effects. There is no protocol-level dedup across - * reconnects, so this trade-off is accepted deliberately. - * - * When the server has been tombstoned as removed (`options.isRemoved`), - * the call short-circuits to an error result telling the model to stop - * calling the tool — no client call, no reconnect. - */ - import type { Tool as KosongTool } from '#/kosong/contract/tool'; import type { ITelemetryService } from '#/app/telemetry/telemetry'; import { Error2, ErrorCodes, toErrorMessage } from '#/errors'; diff --git a/packages/agent-core-v2/src/agent/media/configSection.ts b/packages/agent-core-v2/src/agent/media/configSection.ts index cd87e17ca..ef9c75bfb 100644 --- a/packages/agent-core-v2/src/agent/media/configSection.ts +++ b/packages/agent-core-v2/src/agent/media/configSection.ts @@ -1,19 +1,3 @@ -/** - * `media` domain — `image` config-section schema and env bindings. - * - * Owns the `[image]` section: the longest-edge ceiling (`max_edge_px`) applied - * when compressing images for the model, and the raw-byte budget - * (`read_byte_budget`) for images the model reads for itself (ReadMediaFile's - * default path). Both are persisted user preferences that also accept an - * operational env override (`KIMI_IMAGE_MAX_EDGE_PX` / - * `KIMI_IMAGE_READ_BYTE_BUDGET`); `config` resolves each field as - * `env > config.toml > default` and re-applies the env binding on every read. - * - * While a field's env var is set, `stripEnvBoundFields` restores its env-free - * raw value before `set`/`replace` persists, so an env override echoed - * back through a config write can never leak into `config.toml`. - */ - import { z } from 'zod'; import { type EnvBindings, envBindings, stripEnvBoundFields } from '#/app/config/config'; diff --git a/packages/agent-core-v2/src/agent/media/file-type.ts b/packages/agent-core-v2/src/agent/media/file-type.ts index 7d2e93302..d729c6823 100644 --- a/packages/agent-core-v2/src/agent/media/file-type.ts +++ b/packages/agent-core-v2/src/agent/media/file-type.ts @@ -1,11 +1,3 @@ -/** - * `media` domain — magic-byte + extension file-type detection. - * - * Classifies a file as text / image / video from its first bytes and - * extension, and resolves a MIME type, with no npm dependency. Pure helper; - * no scoped service. - */ - import { AUDIO_MIME_BY_SUFFIX, IMAGE_MIME_BY_SUFFIX, diff --git a/packages/agent-core-v2/src/agent/media/image-compress.ts b/packages/agent-core-v2/src/agent/media/image-compress.ts index f3961d199..9622de623 100644 --- a/packages/agent-core-v2/src/agent/media/image-compress.ts +++ b/packages/agent-core-v2/src/agent/media/image-compress.ts @@ -1,39 +1,3 @@ -/** - * `media` domain — image compression for model ingestion. - * - * Shrink oversized images before they reach the model. - * - * A multimodal request carries each image as a base64 data URL; an unbounded - * screenshot or photo wastes context tokens and can blow past the provider's - * per-image byte ceiling. This module downsamples and re-encodes such images - * so they fit a pixel + byte budget, while leaving already-small images - * untouched — the common case is a fast, codec-free pass-through. - * - * Design notes: - * - Pure JS (jimp + a wasm WebP decoder), imported lazily so the codecs are - * only paid for when an image actually needs work; startup and the fast - * path stay cheap. - * - Best effort: any decode/encode failure returns the original bytes - * unchanged (`changed: false`). Callers must verify that this unchanged - * result satisfies their delivery limits before forwarding it. - * - Format gate first: content-part lists pass through - * {@link gateImageFormatParts} before any compression, so images outside - * the provider-accepted set are never decoded or forwarded — one - * unsupported image in the session history would make every subsequent - * request fail. - * - PNG, JPEG, and (non-animated) WebP are re-encoded; WebP re-encodes - * through the PNG/JPEG ladder after a wasm decode. GIF and animated WebP - * are passed through to preserve animation. Formats outside the - * provider-accepted set never reach this module from the content-part - * paths (the format gate drops them first); direct callers get a - * passthrough. - * - Compression must never be silent to the model: results carry the - * original dimensions, {@link buildImageCompressionCaption} renders the - * shared "what was compressed, where is the original" note every ingestion - * point can place next to the image, and {@link cropImageForModel} lets a - * caller read a region of the original back at full fidelity. - */ - import type { ContentPart } from '#/kosong/contract/message'; import { sniffImageDimensions } from './file-type'; @@ -416,7 +380,6 @@ export interface CompressAnnotateOptions { readonly persistOriginal?: (bytes: Uint8Array, mimeType: string) => Promise; } - export interface ImageCropRegion { readonly x: number; readonly y: number; @@ -577,7 +540,6 @@ export async function cropImageForModel( } } - export interface ImageVariantDescription { readonly width: number; readonly height: number; @@ -642,7 +604,6 @@ export function formatByteSize(bytes: number): string { return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } - type JimpImage = Awaited>; interface EncodedImage { @@ -738,7 +699,6 @@ function fitWithinEdge(image: JimpImage, edge: number): boolean { return true; } - type CropErrorKind = | 'empty' | 'unsupported_format' diff --git a/packages/agent-core-v2/src/agent/media/image-format-policy.ts b/packages/agent-core-v2/src/agent/media/image-format-policy.ts index 3c7451412..0d470a897 100644 --- a/packages/agent-core-v2/src/agent/media/image-format-policy.ts +++ b/packages/agent-core-v2/src/agent/media/image-format-policy.ts @@ -1,32 +1,3 @@ -/** - * `media` domain — provider-accepted image formats, the single source - * of truth. - * - * Model providers accept only PNG, JPEG, GIF, and WebP image blocks. An - * `image_url` part carrying any other MIME (AVIF, HEIC, BMP, TIFF, ICO, …) - * is rejected by the API — and because prompts and tool results persist in - * the session history, that one part makes every subsequent request fail - * too ("session poisoning"). Every ingestion point therefore refuses - * unsupported formats instead of passing the bytes through. - * - * The policy is deliberately a closed set, not a denylist: a format is only - * ever sent when it is known to be accepted. Supporting a new format means - * adding it to {@link MODEL_ACCEPTED_IMAGE_MIMES}; tailoring the refusal - * guidance for a newly-seen unsupported format means adding one row to - * {@link UNSUPPORTED_IMAGE_FORMATS}. - * - * Inbound MIME strings are normalized for the DECISION - * ({@link normalizeImageMime}: case, whitespace, `image/jpg`), but every - * call site must forward the CANONICAL MIME into the session — strict - * provider whitelists (e.g. Anthropic's) reject the raw alias, which would - * re-create the very session poisoning this module exists to prevent. - * - * Scope: only inline `data:` images can be gated. A remote http(s) image URL - * (an MCP `resource_link`, a REST `source.kind: 'url'` part) carries no - * bytes to inspect, and providers that support URL images fetch them - * server-side; those pass through unchanged. - */ - import { IMAGE_MIME_BY_SUFFIX, sniffMediaFromMagic } from './file-type'; export const MODEL_ACCEPTED_IMAGE_MIMES: ReadonlySet = new Set([ diff --git a/packages/agent-core-v2/src/agent/media/image-originals.ts b/packages/agent-core-v2/src/agent/media/image-originals.ts index 71b56b5bb..534e47905 100644 --- a/packages/agent-core-v2/src/agent/media/image-originals.ts +++ b/packages/agent-core-v2/src/agent/media/image-originals.ts @@ -1,30 +1,3 @@ -/** - * `media` domain — content-addressed store for pre-compression image originals. - * - * When an ingestion point (MCP tool result, pasted image, inline base64 - * upload) compresses an image that exists only in memory, the original bytes - * would be gone for good — the model could never zoom into a detail the - * downsampled copy lost. This module persists those originals so the - * compression caption can point at a real path the model can read back with - * `ReadMediaFile` (typically with `region`). - * - * Placement: callers that know their session pass - * `{ dir: sessionMediaOriginalsDir(sessionDir) }` so originals live at - * `/media-originals/` — owned by the session, cleaned up with it, - * and immune to OS temp reaping. The shared temp-dir cache - * ({@link originalImageCacheDir}) is only the fallback for call sites with no - * session context. - * - * Design notes: - * - Content-addressed (sha256): duplicate pastes/results reuse one file and - * repeated writes are idempotent. - * - Best effort: any filesystem failure returns null; callers then emit a - * caption without a readback path. Persistence must never block a prompt. - * - Size-capped: after each write the store is swept oldest-first (mtime) - * until it fits {@link DEFAULT_MAX_TOTAL_BYTES}, so long sessions cannot - * fill the disk. - */ - import { createHash } from 'node:crypto'; import { mkdir, readdir, stat, unlink, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; diff --git a/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts b/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts index 4b930b3e2..a8ee4a3fb 100644 --- a/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts +++ b/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts @@ -1,22 +1,3 @@ -/** - * `media` domain — bridge from the `image` config section into the - * compression support module's resolver seam. - * - * The compression module is deliberately config-agnostic so foundational - * code never imports the config domain: it exposes - * `setConfiguredMaxImageEdgePx` / `setConfiguredReadImageByteBudget` and - * resolves its defaults as `configured ?? built-in`. This bridge is the - * single owner that populates that seam from the env-resolved `[image]` - * section — env (`KIMI_IMAGE_MAX_EDGE_PX` / `KIMI_IMAGE_READ_BYTE_BUDGET`) is - * already folded into `config.get('image')` by the config layer, so nothing - * here reads `process.env`. - * - * Constructed eagerly at Agent scope (before the first turn) and kept in - * sync via `onDidSectionChange`, so every compression call site honors - * config/env. Pushes are idempotent (one global config), so multiple agents - * are harmless. - */ - import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; @@ -36,7 +17,6 @@ export interface IImageConfigBridge { export const IImageConfigBridge: ServiceIdentifier = createDecorator('imageConfigBridge'); -// NOTE: stays Disposable — its own 'config' collides with the Fiber export class ImageConfigBridge extends Disposable implements IImageConfigBridge { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts b/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts index d7a26ef91..0edb6ef5f 100644 --- a/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts +++ b/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts @@ -1,12 +1,3 @@ -/** - * `media` domain — the `kimi-file://` internal media reference. - * - * Aliases of the sibling daemon file reference helpers (`./mediaRef`), kept - * under the historical names so existing call sites read unchanged. New code - * should prefer the canonical `*DaemonFile*` names. - * Pure helpers; no scoped service. - */ - export { buildDaemonFileUrl as buildKimiFileUrl, isDaemonFileUrl as isKimiFileUrl, diff --git a/packages/agent-core-v2/src/agent/media/mediaRef.ts b/packages/agent-core-v2/src/agent/media/mediaRef.ts index e76d0ce84..c3460988c 100644 --- a/packages/agent-core-v2/src/agent/media/mediaRef.ts +++ b/packages/agent-core-v2/src/agent/media/mediaRef.ts @@ -1,52 +1,3 @@ -/** - * `media` domain — media classification and daemon file references. - * - * "Media kind" is the classification every upload edge, resolver, and - * projection agrees on: `image`, `video`, and `audio` (the media content-part - * kinds a model can consume) plus `file` (anything else, which always - * degrades to a path reference). The helpers derive the kind from a content - * part, a MIME type, or a path suffix, and the suffix tables are the single - * source of truth for suffix ↔ MIME mapping — `agent/media/file-type` - * re-exports them for its magic-byte detection. `mediaExtensionForMime` - * inverts the tables (first suffix wins) so every materialization path - * derives the same file extension for an extensionless upload. - * - * A daemon file reference is the internal `kimi-file://` URL: - * `fileId` addresses the daemon upload the request-time media resolver reads - * bytes from. The reference lives in context memory and never reaches the - * provider wire — the resolver rewrites it first. The kind of a referenced - * file is carried by the enclosing content part (`image_url` / `video_url`), - * never by the URL itself, so existing references stay valid. - * - * The materialized copy lives at the session-canonical location - * (`sessionMediaFilePath`: `/media/`), written by - * the session media store at prompt intake. The reference deliberately - * carries no path: a persisted absolute path would bind the durable record - * to one machine and one home directory (a fork or a home relocation would - * stale it), so the display path is derived from the session media store by - * file id at read time instead. A legacy `?path=` query (the retired - * write-time snapshot) is tolerated at parse time and ignored. - * - * The `` tag is the model-facing - * degradation form: the resolver swaps a media part for the tag when the - * bytes cannot reach the provider, and plain-text edges (skill/plugin args) - * write it directly; clients parse it back to render or re-open the file. - * Emission escapes the path as an XML attribute; parsing unescapes it and - * tolerates extra attributes and a missing closing tag. - * `matchSingleMediaPathTag` matches only when the whole (trimmed) text is - * exactly one tag; tags embedded in larger user text are never matched, - * because treating them as markup would eat user content. - * - * A daemon-ref media part is self-contained: read models derive the - * attachment (kind from the part type, file id from the reference) straight - * from the part via `daemonFileRefFromPart` — there is no tag+ref pairing - * to compute. A standalone tag in history is user-visible text or a legacy - * degrade form and always stays a text part. - * - * Pure types and pure functions only — no I/O, no SDKs; depends only on the - * `ContentPart` envelope type from `kosong/contract`. - */ - import { join } from 'node:path'; import type { ContentPart } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/agent/media/mediaResolver.ts b/packages/agent-core-v2/src/agent/media/mediaResolver.ts index 5ef82ff97..b459db931 100644 --- a/packages/agent-core-v2/src/agent/media/mediaResolver.ts +++ b/packages/agent-core-v2/src/agent/media/mediaResolver.ts @@ -1,18 +1,3 @@ -/** - * `media` domain — request-time media reference resolver contract. - * - * Rewrites the `kimi-file://` daemon references a prompt carries in the - * projected wire messages into provider-acceptable parts (an uploaded - * `ms://` video reference, an inline base64 `data:` part, a `