@gotgenes/pi-subagents 18.0.1 → 18.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/docs/architecture/architecture.md +165 -203
- package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
- package/package.json +6 -7
- package/src/config/default-agents.ts +3 -0
- package/src/lifecycle/subagent.ts +25 -14
- package/src/observation/notification.ts +23 -10
- package/src/observation/subagent-events-observer.ts +1 -3
- package/src/runtime.ts +2 -1
- package/src/service/service-adapter.ts +20 -17
- package/src/session/model-resolver.ts +31 -30
- package/src/tools/agent-tool.ts +17 -13
- package/src/tools/get-result-report.ts +60 -0
- package/src/tools/get-result-tool.ts +25 -40
- package/src/tools/helpers.ts +21 -5
- package/src/tools/spawn-config.ts +5 -5
- package/src/tools/steer-tool.ts +37 -27
- package/src/types.ts +4 -1
- package/src/ui/session-navigator.ts +0 -2
- package/.prettierignore +0 -5
- package/AGENTS.md +0 -7
- package/docs/plans/0048-implement-subagents-api.md +0 -304
- package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
- package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
- package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
- package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
- package/docs/plans/0054-decompose-index-into-modules.md +0 -302
- package/docs/plans/0057-structured-debug-logging.md +0 -154
- package/docs/plans/0061-session-format-transcript.md +0 -284
- package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
- package/docs/plans/0069-create-subagent-runtime.md +0 -345
- package/docs/plans/0070-extract-event-handlers.md +0 -306
- package/docs/plans/0071-extract-session-config-assembler.md +0 -362
- package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
- package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
- package/docs/plans/0077-inject-project-agents-dir.md +0 -115
- package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
- package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
- package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
- package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
- package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
- package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
- package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
- package/docs/plans/0108-extract-agent-type-registry.md +0 -322
- package/docs/plans/0109-extract-settings-manager.md +0 -276
- package/docs/plans/0110-agent-activity-tracker.md +0 -297
- package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
- package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
- package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
- package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
- package/docs/plans/0115-decompose-agent-tool.md +0 -337
- package/docs/plans/0116-type-housekeeping.md +0 -351
- package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
- package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
- package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
- package/docs/plans/0132-inject-io-into-session-config.md +0 -219
- package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
- package/docs/plans/0134-reduce-as-any-casts.md +0 -366
- package/docs/plans/0135-extract-display-helpers.md +0 -182
- package/docs/plans/0136-decompose-agent-menu.md +0 -300
- package/docs/plans/0144-consolidate-observation-model.md +0 -263
- package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
- package/docs/plans/0146-narrow-ui-context.md +0 -319
- package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
- package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
- package/docs/plans/0152-add-prompt-snippet.md +0 -91
- package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
- package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
- package/docs/plans/0166-extract-parent-session-info.md +0 -231
- package/docs/plans/0167-narrow-runner-io.md +0 -150
- package/docs/plans/0168-extract-tool-filter-config.md +0 -173
- package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
- package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
- package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
- package/docs/plans/0172-extract-turn-formatting.md +0 -206
- package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
- package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
- package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
- package/docs/plans/0192-define-session-context-interface.md +0 -107
- package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
- package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
- package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
- package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
- package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
- package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
- package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
- package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
- package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
- package/docs/plans/0215-decompose-build-parent-context.md +0 -166
- package/docs/plans/0216-decompose-start-agent.md +0 -255
- package/docs/plans/0217-extract-overwrite-guard.md +0 -176
- package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
- package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
- package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
- package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
- package/docs/plans/0229-agent-born-complete.md +0 -564
- package/docs/plans/0230-extract-concurrency-queue.md +0 -265
- package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
- package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
- package/docs/plans/0237-remove-disallowed-tools.md +0 -180
- package/docs/plans/0238-remove-extensions-filtering.md +0 -191
- package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
- package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
- package/docs/plans/0256-extract-worktree-isolation.md +0 -256
- package/docs/plans/0257-extract-child-session-factory.md +0 -285
- package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
- package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
- package/docs/plans/0265-born-complete-subagent-session.md +0 -333
- package/docs/plans/0270-type-consumable-public-surface.md +0 -204
- package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
- package/docs/plans/0277-encapsulate-agent-session.md +0 -304
- package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
- package/docs/plans/0360-custom-agents-default-append.md +0 -132
- package/docs/plans/0373-extract-subagent-state.md +0 -250
- package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
- package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
- package/docs/plans/0376-extract-manager-observer.md +0 -232
- package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
- package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
- package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
- package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
- package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
- package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
- package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
- package/docs/plans/0412-unify-session-mock-builders.md +0 -146
- package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
- package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
- package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
- package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
- package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
- package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
- package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
- package/docs/plans/0427-reconsider-ui-direction.md +0 -212
- package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
- package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
- package/docs/plans/0443-consolidate-remaining-test-clone-families.md +0 -268
- package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
- package/docs/plans/0445-native-session-navigation.md +0 -365
- package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
- package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
- package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
- package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
- package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
- package/docs/plans/0470-refresh-readme-command-surface.md +0 -159
- package/docs/retro/0048-implement-subagents-api.md +0 -44
- package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
- package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
- package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
- package/docs/retro/0054-decompose-index-into-modules.md +0 -53
- package/docs/retro/0057-structured-debug-logging.md +0 -77
- package/docs/retro/0061-session-format-transcript.md +0 -41
- package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
- package/docs/retro/0069-create-subagent-runtime.md +0 -43
- package/docs/retro/0070-extract-event-handlers.md +0 -49
- package/docs/retro/0071-extract-session-config-assembler.md +0 -60
- package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
- package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
- package/docs/retro/0077-inject-project-agents-dir.md +0 -33
- package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
- package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
- package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
- package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
- package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
- package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
- package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
- package/docs/retro/0108-extract-agent-type-registry.md +0 -41
- package/docs/retro/0109-extract-settings-manager.md +0 -55
- package/docs/retro/0110-agent-activity-tracker.md +0 -44
- package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
- package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
- package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
- package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
- package/docs/retro/0115-decompose-agent-tool.md +0 -51
- package/docs/retro/0116-type-housekeeping.md +0 -42
- package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
- package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
- package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
- package/docs/retro/0132-inject-io-into-session-config.md +0 -33
- package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
- package/docs/retro/0134-reduce-as-any-casts.md +0 -56
- package/docs/retro/0135-extract-display-helpers.md +0 -38
- package/docs/retro/0136-decompose-agent-menu.md +0 -43
- package/docs/retro/0144-consolidate-observation-model.md +0 -39
- package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
- package/docs/retro/0146-narrow-ui-context.md +0 -70
- package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
- package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
- package/docs/retro/0152-add-prompt-snippet.md +0 -34
- package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
- package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
- package/docs/retro/0166-extract-parent-session-info.md +0 -66
- package/docs/retro/0167-narrow-runner-io.md +0 -63
- package/docs/retro/0168-extract-tool-filter-config.md +0 -76
- package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
- package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
- package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
- package/docs/retro/0172-extract-turn-formatting.md +0 -80
- package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
- package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
- package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
- package/docs/retro/0192-define-session-context-interface.md +0 -59
- package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
- package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
- package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
- package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
- package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
- package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
- package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
- package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
- package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
- package/docs/retro/0215-decompose-build-parent-context.md +0 -61
- package/docs/retro/0216-decompose-start-agent.md +0 -80
- package/docs/retro/0217-extract-overwrite-guard.md +0 -63
- package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
- package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
- package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
- package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
- package/docs/retro/0229-agent-born-complete.md +0 -89
- package/docs/retro/0230-extract-concurrency-queue.md +0 -38
- package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
- package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
- package/docs/retro/0237-remove-disallowed-tools.md +0 -78
- package/docs/retro/0238-remove-extensions-filtering.md +0 -72
- package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
- package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
- package/docs/retro/0256-extract-worktree-isolation.md +0 -89
- package/docs/retro/0257-extract-child-session-factory.md +0 -33
- package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
- package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
- package/docs/retro/0265-born-complete-subagent-session.md +0 -97
- package/docs/retro/0270-type-consumable-public-surface.md +0 -108
- package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
- package/docs/retro/0277-encapsulate-agent-session.md +0 -80
- package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
- package/docs/retro/0360-custom-agents-default-append.md +0 -81
- package/docs/retro/0373-extract-subagent-state.md +0 -94
- package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
- package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
- package/docs/retro/0376-extract-manager-observer.md +0 -81
- package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
- package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
- package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
- package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
- package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
- package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
- package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
- package/docs/retro/0412-unify-session-mock-builders.md +0 -80
- package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
- package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
- package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
- package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
- package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
- package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
- package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
- package/docs/retro/0427-reconsider-ui-direction.md +0 -102
- package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -97
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
- package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
- package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
- package/docs/retro/0445-native-session-navigation.md +0 -122
- package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
- package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
- package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
- package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
- package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
- package/docs/retro/0470-refresh-readme-command-surface.md +0 -40
- package/src/observation/notification-state.ts +0 -27
- package/vitest.config.ts +0 -14
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 166
|
|
3
|
-
issue_title: "refactor(pi-subagents): extract ParentSessionInfo from AgentSpawnConfig (13 fields)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Extract ParentSessionInfo from AgentSpawnConfig
|
|
7
|
-
|
|
8
|
-
## Problem Statement
|
|
9
|
-
|
|
10
|
-
`AgentSpawnConfig` in `agent-manager.ts` has 13 fields.
|
|
11
|
-
Three of those fields — `parentSessionFile`, `parentSessionId`, and `toolCallId` — form a natural cluster around parent session identity.
|
|
12
|
-
They always travel together through `agent-tool.ts` → `foreground-runner.ts` / `background-spawner.ts` → `AgentManager.spawn()`.
|
|
13
|
-
Extracting them into a named value object reduces `AgentSpawnConfig` from 13 to 11 fields (10 + 1 nested) and introduces the `ParentSessionInfo` domain concept.
|
|
14
|
-
|
|
15
|
-
## Goals
|
|
16
|
-
|
|
17
|
-
- Extract `ParentSessionInfo` interface with `parentSessionFile`, `parentSessionId`, and `toolCallId`.
|
|
18
|
-
- Replace the three flat optional fields on `AgentSpawnConfig` with a single optional `parentSession?: ParentSessionInfo` field.
|
|
19
|
-
- Replace the flat fields on `BackgroundParams`, `ForegroundParams`, and `RunOptions` with the same grouped type.
|
|
20
|
-
- Update all callers (agent-tool, foreground-runner, background-spawner, agent-manager, agent-runner) and their tests.
|
|
21
|
-
- Non-breaking refactor — no public API changes (the `SubagentsService` boundary does not expose these fields).
|
|
22
|
-
|
|
23
|
-
## Non-Goals
|
|
24
|
-
|
|
25
|
-
- Changing the `NotificationState` or `notification` module — they remain as-is; `toolCallId` is just extracted from the group at the `AgentManager.spawn` boundary.
|
|
26
|
-
- Further decomposition of `AgentSpawnConfig` (e.g., extracting execution or callback clusters) — tracked separately.
|
|
27
|
-
- Modifying `session-dir.ts` or `deriveSubagentSessionDir` — the function signature stays the same; callers just unwrap `parentSession.parentSessionFile` before calling it.
|
|
28
|
-
|
|
29
|
-
## Background
|
|
30
|
-
|
|
31
|
-
Issue #165 (closed) decomposed `ResolvedSpawnConfig` into `SpawnIdentity`, `SpawnExecution`, and `SpawnPresentation`.
|
|
32
|
-
This issue continues that structural improvement by grouping the parent-session fields that flow from `agent-tool.ts` through to `agent-runner.ts`.
|
|
33
|
-
|
|
34
|
-
The three fields are:
|
|
35
|
-
|
|
36
|
-
- `parentSessionFile` — path to the parent session's JSONL file, used by `deriveSubagentSessionDir` to place child sessions next to the parent.
|
|
37
|
-
- `parentSessionId` — session ID of the parent agent, stored in the child session's `parentSession` header via `sessionManager.newSession()`.
|
|
38
|
-
- `toolCallId` — tool call ID for background notification wiring; when set, `AgentManager.spawn` creates a `NotificationState`.
|
|
39
|
-
|
|
40
|
-
All three originate in `agent-tool.ts`'s `execute` function and are threaded unchanged through intermediate modules.
|
|
41
|
-
|
|
42
|
-
### Current flow
|
|
43
|
-
|
|
44
|
-
```text
|
|
45
|
-
agent-tool execute → getSessionInfo() + toolCallId param
|
|
46
|
-
→ BackgroundParams { parentSessionFile, parentSessionId, toolCallId }
|
|
47
|
-
→ spawnBackground → manager.spawn(opts: AgentSpawnConfig { ...flat fields })
|
|
48
|
-
→ AgentManager.spawn → options.toolCallId → NotificationState
|
|
49
|
-
→ startAgent → runner.run(RunOptions { parentSessionFile, parentSessionId })
|
|
50
|
-
→ deriveSessionDir(parentSessionFile, ...)
|
|
51
|
-
→ sessionManager.newSession({ parentSession: parentSessionId })
|
|
52
|
-
|
|
53
|
-
→ ForegroundParams { parentSessionFile, parentSessionId }
|
|
54
|
-
→ runForeground → manager.spawnAndWait(opts: AgentSpawnConfig { ...flat fields })
|
|
55
|
-
→ (same AgentManager path)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### After extraction
|
|
59
|
-
|
|
60
|
-
```text
|
|
61
|
-
agent-tool execute → getSessionInfo() + toolCallId param
|
|
62
|
-
→ parentSession: ParentSessionInfo { parentSessionFile, parentSessionId, toolCallId }
|
|
63
|
-
→ BackgroundParams { parentSession }
|
|
64
|
-
→ spawnBackground → manager.spawn(opts: AgentSpawnConfig { parentSession })
|
|
65
|
-
→ AgentManager.spawn → parentSession.toolCallId → NotificationState
|
|
66
|
-
→ startAgent → runner.run(RunOptions { parentSession })
|
|
67
|
-
→ deriveSessionDir(parentSession?.parentSessionFile, ...)
|
|
68
|
-
→ sessionManager.newSession({ parentSession: parentSession?.parentSessionId })
|
|
69
|
-
|
|
70
|
-
→ ForegroundParams { parentSession }
|
|
71
|
-
→ runForeground → manager.spawnAndWait(opts: AgentSpawnConfig { parentSession })
|
|
72
|
-
→ (same AgentManager path)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Design Overview
|
|
76
|
-
|
|
77
|
-
### `ParentSessionInfo` interface
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
export interface ParentSessionInfo {
|
|
81
|
-
/** Path to the parent session's JSONL file (for deriving the subagent session directory). */
|
|
82
|
-
parentSessionFile?: string;
|
|
83
|
-
/** Session ID of the parent agent (stored in the child session's parentSession header). */
|
|
84
|
-
parentSessionId?: string;
|
|
85
|
-
/** Tool call ID for background notification wiring. When set, spawn attaches NotificationState. */
|
|
86
|
-
toolCallId?: string;
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
All three fields remain optional — they are only available when spawning from an active session (the `SubagentsService` boundary omits them entirely).
|
|
91
|
-
|
|
92
|
-
The interface lives in `lifecycle/agent-manager.ts` alongside `AgentSpawnConfig` since that is the primary consumer.
|
|
93
|
-
If a future refactoring moves `AgentSpawnConfig` to its own file, `ParentSessionInfo` should move with it.
|
|
94
|
-
|
|
95
|
-
### Consumer call-site sketch
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// agent-tool.ts execute():
|
|
99
|
-
const parentSession: ParentSessionInfo = {
|
|
100
|
-
parentSessionFile: sessionInfo.parentSessionFile,
|
|
101
|
-
parentSessionId: sessionInfo.parentSessionId,
|
|
102
|
-
toolCallId,
|
|
103
|
-
};
|
|
104
|
-
// ...
|
|
105
|
-
spawnBackground(manager, widget, agentActivity, { config, snapshot, parentSession });
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
The grouped object eliminates the three-field spread that was repeated in both `spawnBackground` and `runForeground` call sites.
|
|
109
|
-
|
|
110
|
-
### `AgentSpawnConfig` change
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
export interface AgentSpawnConfig {
|
|
114
|
-
// ... existing fields (description, model, maxTurns, etc.)
|
|
115
|
-
/** Parent session identity — grouped fields that travel together from the tool boundary. */
|
|
116
|
-
parentSession?: ParentSessionInfo;
|
|
117
|
-
// Remove: parentSessionFile, parentSessionId, toolCallId
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### `RunOptions` change
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
export interface RunOptions {
|
|
125
|
-
// ... existing fields
|
|
126
|
-
/** Parent session identity (file path + session ID). */
|
|
127
|
-
parentSession?: ParentSessionInfo;
|
|
128
|
-
// Remove: parentSessionFile, parentSessionId
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Note: `RunOptions` does not use `toolCallId` — it was never threaded to the runner.
|
|
133
|
-
The runner only reads `parentSessionFile` and `parentSessionId` from the group.
|
|
134
|
-
|
|
135
|
-
### `getSessionInfo` return type update
|
|
136
|
-
|
|
137
|
-
The `getSessionInfo` callback in `AgentToolDeps` currently returns `{ parentSessionFile: string; parentSessionId: string }`.
|
|
138
|
-
It should remain unchanged — it does not include `toolCallId` (which comes from the `execute` callback's first argument).
|
|
139
|
-
The `agent-tool.ts` execute function constructs a `ParentSessionInfo` by merging `getSessionInfo()` output with `toolCallId`.
|
|
140
|
-
|
|
141
|
-
## Module-Level Changes
|
|
142
|
-
|
|
143
|
-
### New types
|
|
144
|
-
|
|
145
|
-
1. `src/lifecycle/agent-manager.ts` — add `ParentSessionInfo` interface (exported).
|
|
146
|
-
|
|
147
|
-
### Modified interfaces
|
|
148
|
-
|
|
149
|
-
1. `src/lifecycle/agent-manager.ts` — `AgentSpawnConfig`: replace `parentSessionFile?`, `parentSessionId?`, `toolCallId?` with `parentSession?: ParentSessionInfo`.
|
|
150
|
-
2. `src/lifecycle/agent-runner.ts` — `RunOptions`: replace `parentSessionFile?`, `parentSessionId?` with `parentSession?: ParentSessionInfo`.
|
|
151
|
-
3. `src/tools/background-spawner.ts` — `BackgroundParams`: replace `parentSessionFile`, `parentSessionId`, `toolCallId` with `parentSession: ParentSessionInfo`.
|
|
152
|
-
4. `src/tools/foreground-runner.ts` — `ForegroundParams`: replace `parentSessionFile`, `parentSessionId` with `parentSession: ParentSessionInfo`.
|
|
153
|
-
|
|
154
|
-
### Modified implementations
|
|
155
|
-
|
|
156
|
-
1. `src/lifecycle/agent-manager.ts` — `AgentManager.spawn()`: read `options.parentSession?.toolCallId` instead of `options.toolCallId`; pass `parentSession` to `RunOptions`.
|
|
157
|
-
2. `src/lifecycle/agent-runner.ts` — `runAgent()`: read `options.parentSession?.parentSessionFile` and `options.parentSession?.parentSessionId`.
|
|
158
|
-
3. `src/tools/agent-tool.ts` — `createAgentTool` execute: construct `ParentSessionInfo` from `getSessionInfo()` + `toolCallId`, pass as `parentSession` to both spawners.
|
|
159
|
-
4. `src/tools/background-spawner.ts` — `spawnBackground()`: read `params.parentSession` and pass fields to `AgentSpawnConfig`.
|
|
160
|
-
5. `src/tools/foreground-runner.ts` — `runForeground()`: read `params.parentSession` and pass fields to `AgentSpawnConfig`.
|
|
161
|
-
|
|
162
|
-
### No changes needed
|
|
163
|
-
|
|
164
|
-
- `src/tools/agent-tool.ts` — `AgentToolDeps.getSessionInfo` return type stays the same.
|
|
165
|
-
- `src/session/session-dir.ts` — `deriveSubagentSessionDir` signature unchanged.
|
|
166
|
-
- `src/observation/notification-state.ts` — constructor signature unchanged.
|
|
167
|
-
- `src/service/service-adapter.ts` — does not pass parent session fields.
|
|
168
|
-
- `src/index.ts` — `getSessionInfo` callback unchanged.
|
|
169
|
-
|
|
170
|
-
## Test Impact Analysis
|
|
171
|
-
|
|
172
|
-
### New tests enabled
|
|
173
|
-
|
|
174
|
-
No new unit tests are enabled — this is a structural grouping, not new behavior.
|
|
175
|
-
|
|
176
|
-
### Existing tests that need updates
|
|
177
|
-
|
|
178
|
-
1. `test/lifecycle/agent-manager.test.ts` — update spawn calls from flat `parentSessionFile`/`parentSessionId`/`toolCallId` to nested `parentSession: { ... }` form; update assertions to read from `parentSession`.
|
|
179
|
-
2. `test/lifecycle/agent-runner.test.ts` — update `RunOptions` construction from flat to nested `parentSession`.
|
|
180
|
-
3. `test/tools/agent-tool.test.ts` — update assertion checking `toolCallId` on spawn opts to check `parentSession.toolCallId`.
|
|
181
|
-
4. `test/tools/background-spawner.test.ts` — update `makeParams` factory from flat fields to `parentSession: { ... }`.
|
|
182
|
-
5. `test/tools/foreground-runner.test.ts` — update params construction from flat fields to `parentSession: { ... }`.
|
|
183
|
-
6. `test/helpers/make-deps.ts` — `getSessionInfo` mock stays unchanged (returns flat `{ parentSessionFile, parentSessionId }`).
|
|
184
|
-
|
|
185
|
-
### Tests that stay as-is
|
|
186
|
-
|
|
187
|
-
- `test/session/session-dir.test.ts` — tests `deriveSubagentSessionDir` directly, no interface change.
|
|
188
|
-
- `test/observation/notification-state.test.ts` — tests `NotificationState` constructor directly.
|
|
189
|
-
- `test/observation/notification.test.ts` — tests notification formatting with `record.notification`, not spawn config.
|
|
190
|
-
|
|
191
|
-
## TDD Order
|
|
192
|
-
|
|
193
|
-
1. **Define `ParentSessionInfo` and update `AgentSpawnConfig`** — add interface, replace three flat fields with `parentSession?`.
|
|
194
|
-
Update `AgentManager.spawn` and `startAgent` to read from the nested group.
|
|
195
|
-
Update `agent-manager.test.ts` to use nested form.
|
|
196
|
-
Run `pnpm run check` to verify no downstream type errors remain.
|
|
197
|
-
Commit: `refactor: define ParentSessionInfo and nest in AgentSpawnConfig`
|
|
198
|
-
|
|
199
|
-
2. **Update `RunOptions` in `agent-runner.ts`** — replace flat `parentSessionFile?`/`parentSessionId?` with `parentSession?`.
|
|
200
|
-
Update `runAgent` to read `options.parentSession?.parentSessionFile` and `options.parentSession?.parentSessionId`.
|
|
201
|
-
Update `agent-runner.test.ts`.
|
|
202
|
-
Commit: `refactor: nest ParentSessionInfo in RunOptions`
|
|
203
|
-
|
|
204
|
-
3. **Update `BackgroundParams` and `spawnBackground`** — replace three flat fields with `parentSession: ParentSessionInfo`.
|
|
205
|
-
Update `spawnBackground` to pass `parentSession` to spawn opts.
|
|
206
|
-
Update `background-spawner.test.ts`.
|
|
207
|
-
Commit: `refactor: nest ParentSessionInfo in BackgroundParams`
|
|
208
|
-
|
|
209
|
-
4. **Update `ForegroundParams` and `runForeground`** — replace two flat fields with `parentSession: ParentSessionInfo`.
|
|
210
|
-
Update `runForeground` to pass `parentSession` to spawn opts.
|
|
211
|
-
Update `foreground-runner.test.ts`.
|
|
212
|
-
Commit: `refactor: nest ParentSessionInfo in ForegroundParams`
|
|
213
|
-
|
|
214
|
-
5. **Update `agent-tool.ts` execute** — construct `ParentSessionInfo` from `getSessionInfo()` + `toolCallId`, pass as `parentSession` to both spawner call sites.
|
|
215
|
-
Update `agent-tool.test.ts`.
|
|
216
|
-
Commit: `refactor: construct ParentSessionInfo in agent-tool execute`
|
|
217
|
-
|
|
218
|
-
6. **Final verification** — run full test suite (`pnpm vitest run`) and type check (`pnpm run check`).
|
|
219
|
-
No separate commit unless adjustments are needed.
|
|
220
|
-
|
|
221
|
-
## Risks and Mitigations
|
|
222
|
-
|
|
223
|
-
| Risk | Mitigation |
|
|
224
|
-
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
225
|
-
| Deep-merge trap: test factories using `Partial<BackgroundParams>` spread may silently ignore nested overrides | Audit `makeParams` in `background-spawner.test.ts` — convert from flat-field spread to nested `parentSession` construction |
|
|
226
|
-
| `toolCallId` conditionally absent for foreground calls | `ParentSessionInfo.toolCallId` is optional; `ForegroundParams.parentSession` includes it but won't set it — matches current behavior |
|
|
227
|
-
| Type check passes but runtime breaks due to nested access on undefined | `parentSession?` is optional on `AgentSpawnConfig`; all reads use optional chaining (`options.parentSession?.toolCallId`) |
|
|
228
|
-
|
|
229
|
-
## Open Questions
|
|
230
|
-
|
|
231
|
-
None — the extraction is mechanical and the issue description is unambiguous.
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 167
|
|
3
|
-
issue_title: "refactor(pi-subagents): narrow RunnerIO (9 methods → 2 focused interfaces)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Narrow RunnerIO into EnvironmentIO + SessionFactoryIO
|
|
7
|
-
|
|
8
|
-
## Problem Statement
|
|
9
|
-
|
|
10
|
-
`RunnerIO` in `agent-runner.ts` bundles 8 members (7 methods + 1 sub-interface) into a single IO boundary.
|
|
11
|
-
The methods split naturally into two concerns — environment discovery vs. SDK object creation — but the current monolithic interface forces every consumer (and every test mock) to provide all members regardless of which subset they actually use.
|
|
12
|
-
This violates Interface Segregation (ISP) and inflates test factory helpers.
|
|
13
|
-
|
|
14
|
-
## Goals
|
|
15
|
-
|
|
16
|
-
- Split `RunnerIO` into two focused interfaces: `EnvironmentIO` (3 methods) and `SessionFactoryIO` (5 methods + `assemblerIO`).
|
|
17
|
-
- Keep `RunnerIO` as a type alias (`EnvironmentIO & SessionFactoryIO`) so the change is fully backward-compatible at the type level.
|
|
18
|
-
- Update both test `createRunnerIO()` factories to use the new sub-interfaces in their comments/structure (no behavioral test changes needed — factories already return plain objects).
|
|
19
|
-
- Zero runtime behavior change.
|
|
20
|
-
|
|
21
|
-
## Non-Goals
|
|
22
|
-
|
|
23
|
-
- Splitting the `runAgent()` function itself — that's a separate concern.
|
|
24
|
-
- Changing how `createAgentRunner()` accepts its IO parameter — it keeps taking `RunnerIO` (the intersection).
|
|
25
|
-
- Refactoring `index.ts` wiring — the construction site already builds a plain object; it will continue to satisfy `RunnerIO`.
|
|
26
|
-
- Extracting `AssemblerIO` further — it already has its own interface in `session-config.ts`.
|
|
27
|
-
|
|
28
|
-
## Background
|
|
29
|
-
|
|
30
|
-
`RunnerIO` was introduced in issue #133 to decouple `agent-runner.ts` from direct Pi SDK imports.
|
|
31
|
-
It succeeded at making the runner testable via plain stubs, but bundled all IO into one wide interface.
|
|
32
|
-
Issue #164 (closed) reorganized source into domain directories; the current file path is `src/lifecycle/agent-runner.ts`.
|
|
33
|
-
|
|
34
|
-
The 8 members group into two cohesive clusters:
|
|
35
|
-
|
|
36
|
-
| Cluster | Members | Responsibility |
|
|
37
|
-
| --------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
38
|
-
| Environment discovery | `detectEnv`, `getAgentDir`, `deriveSessionDir` | Discover runtime environment, resolve directories |
|
|
39
|
-
| Session factory | `createResourceLoader`, `createSessionManager`, `createSettingsManager`, `createSession`, `assemblerIO` | Create SDK objects for a child session |
|
|
40
|
-
|
|
41
|
-
In `runAgent()`, the environment methods are called first (lines ~265–275), then the factory methods build SDK objects (lines ~280–320).
|
|
42
|
-
The two groups have no cross-dependencies within `runAgent()`.
|
|
43
|
-
|
|
44
|
-
## Design Overview
|
|
45
|
-
|
|
46
|
-
### New interfaces
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
/** Environment discovery — detect runtime context and resolve directories. */
|
|
50
|
-
export interface EnvironmentIO {
|
|
51
|
-
detectEnv: (exec: ShellExec, cwd: string) => Promise<EnvInfo>;
|
|
52
|
-
getAgentDir: () => string;
|
|
53
|
-
deriveSessionDir: (parentSessionFile: string | undefined, effectiveCwd: string) => string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Session factory — create SDK objects for a child agent session. */
|
|
57
|
-
export interface SessionFactoryIO {
|
|
58
|
-
createResourceLoader: (opts: ResourceLoaderOptions) => ResourceLoaderLike;
|
|
59
|
-
createSessionManager: (cwd: string, sessionDir: string) => SessionManagerLike;
|
|
60
|
-
createSettingsManager: (cwd: string, agentDir: string) => SettingsManager;
|
|
61
|
-
createSession: (opts: CreateSessionOptions) => Promise<{ session: AgentSession }>;
|
|
62
|
-
assemblerIO: AssemblerIO;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* IO boundary injected into runAgent().
|
|
67
|
-
* Backward-compatible intersection of the two focused interfaces.
|
|
68
|
-
*/
|
|
69
|
-
export type RunnerIO = EnvironmentIO & SessionFactoryIO;
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Backward compatibility
|
|
73
|
-
|
|
74
|
-
- `RunnerIO` becomes a type alias for the intersection.
|
|
75
|
-
Any code that imports `RunnerIO` continues to compile unchanged.
|
|
76
|
-
- `index.ts` builds a plain object literal that satisfies `RunnerIO` — no change needed.
|
|
77
|
-
- Test factories return unannotated objects that are structurally compatible — no change needed for compilation, but comments can be updated to reference the sub-interfaces.
|
|
78
|
-
|
|
79
|
-
### Consumer call-site verification
|
|
80
|
-
|
|
81
|
-
The call site in `createAgentRunner()` (3 lines):
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
export function createAgentRunner(io: RunnerIO): AgentRunner {
|
|
85
|
-
return {
|
|
86
|
-
run: (snapshot, type, prompt, options) => runAgent(snapshot, type, prompt, options, io),
|
|
87
|
-
resume: resumeAgent,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
This passes the full `io` to `runAgent()`, which continues to accept `RunnerIO`.
|
|
93
|
-
No Tell-Don't-Ask or LoD violations introduced.
|
|
94
|
-
|
|
95
|
-
## Module-Level Changes
|
|
96
|
-
|
|
97
|
-
### `src/lifecycle/agent-runner.ts`
|
|
98
|
-
|
|
99
|
-
1. Add `EnvironmentIO` interface (3 members) before the current `RunnerIO` definition.
|
|
100
|
-
2. Add `SessionFactoryIO` interface (5 members) after `EnvironmentIO`.
|
|
101
|
-
3. Change `RunnerIO` from an `interface` to a `type` alias: `type RunnerIO = EnvironmentIO & SessionFactoryIO`.
|
|
102
|
-
4. Export the two new interfaces alongside `RunnerIO`.
|
|
103
|
-
5. Move existing JSDoc from `RunnerIO` members to the sub-interfaces.
|
|
104
|
-
6. No changes to function signatures — `runAgent()` and `createAgentRunner()` keep accepting `RunnerIO`.
|
|
105
|
-
|
|
106
|
-
### `src/index.ts`
|
|
107
|
-
|
|
108
|
-
No changes.
|
|
109
|
-
The construction site builds a plain object satisfying all 8 members — TypeScript's structural typing ensures it satisfies `EnvironmentIO & SessionFactoryIO` without annotation changes.
|
|
110
|
-
|
|
111
|
-
### Test files
|
|
112
|
-
|
|
113
|
-
No behavioral changes.
|
|
114
|
-
The `createRunnerIO()` factories in both test files return unannotated plain objects that structurally satisfy the intersection.
|
|
115
|
-
Comments referencing `RunnerIO` can be updated to mention the sub-interfaces for documentation clarity.
|
|
116
|
-
|
|
117
|
-
Files affected:
|
|
118
|
-
|
|
119
|
-
- `test/lifecycle/agent-runner.test.ts` — update comment (line ~23–27).
|
|
120
|
-
- `test/lifecycle/agent-runner-extension-tools.test.ts` — update comment (line ~46).
|
|
121
|
-
|
|
122
|
-
## Test Impact Analysis
|
|
123
|
-
|
|
124
|
-
1. **New unit tests enabled:** The split enables future tests that inject only `EnvironmentIO` or only `SessionFactoryIO` — useful when testing environment-only or factory-only code paths in future extractions.
|
|
125
|
-
No new tests are needed in this issue because `runAgent()` still consumes the full intersection.
|
|
126
|
-
2. **Redundant tests:** None — existing tests already test through `runAgent()` which uses all members.
|
|
127
|
-
3. **Tests that stay as-is:** All existing tests in both `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` remain valid; the factories produce objects compatible with the new type alias.
|
|
128
|
-
|
|
129
|
-
## TDD Order
|
|
130
|
-
|
|
131
|
-
1. **Red → Green: export `EnvironmentIO` and `SessionFactoryIO`, convert `RunnerIO` to type alias.**
|
|
132
|
-
Test surface: existing `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` suites (must still pass).
|
|
133
|
-
Run `pnpm run check` to verify type compatibility.
|
|
134
|
-
Commit: `refactor: split RunnerIO into EnvironmentIO and SessionFactoryIO (#167)`
|
|
135
|
-
|
|
136
|
-
2. **Update test comments to reference sub-interfaces.**
|
|
137
|
-
Test surface: no behavioral test changes — comment-only updates.
|
|
138
|
-
Commit: `refactor: update test comments for RunnerIO sub-interfaces (#167)`
|
|
139
|
-
|
|
140
|
-
## Risks and Mitigations
|
|
141
|
-
|
|
142
|
-
| Risk | Mitigation |
|
|
143
|
-
| --------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
144
|
-
| External consumers importing `RunnerIO` break | `RunnerIO` remains exported as a type alias for the intersection — fully backward-compatible |
|
|
145
|
-
| Test factories need updating | Factories return unannotated objects — structural typing handles the new type alias without changes |
|
|
146
|
-
| Future extractions assume wrong interface | Each sub-interface has a clear JSDoc explaining its scope |
|
|
147
|
-
|
|
148
|
-
## Open Questions
|
|
149
|
-
|
|
150
|
-
None — the split follows the natural cohesion boundary identified in the issue body.
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 168
|
|
3
|
-
issue_title: "refactor(pi-subagents): extract ToolFilterConfig from SessionConfig (11 fields)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Extract ToolFilterConfig from SessionConfig
|
|
7
|
-
|
|
8
|
-
## Problem Statement
|
|
9
|
-
|
|
10
|
-
`SessionConfig` in `session-config.ts` has 10 top-level fields.
|
|
11
|
-
Three of those fields — `toolNames`, `disallowedSet`, and `extensions` — form a cohesive tool-filtering cluster consumed together by `filterActiveTools` in `agent-runner.ts`.
|
|
12
|
-
Today `filterActiveTools` accepts these as three separate positional parameters, and the guard condition `cfg.extensions !== false || cfg.disallowedSet` is duplicated at both call sites.
|
|
13
|
-
Extracting the cluster into a named `ToolFilterConfig` type makes the relationship explicit and gives `filterActiveTools` a single named input.
|
|
14
|
-
|
|
15
|
-
## Goals
|
|
16
|
-
|
|
17
|
-
- Define a `ToolFilterConfig` interface grouping `toolNames`, `disallowedSet`, and `extensions`.
|
|
18
|
-
- Nest `ToolFilterConfig` inside `SessionConfig`, replacing the three flat fields.
|
|
19
|
-
- Change `filterActiveTools` to accept `ToolFilterConfig` instead of three positional parameters.
|
|
20
|
-
- Update `runAgent` to destructure `cfg.toolFilter` at both filter call sites.
|
|
21
|
-
- Update all test assertions that read the three flat fields to use the nested path.
|
|
22
|
-
|
|
23
|
-
## Non-Goals
|
|
24
|
-
|
|
25
|
-
- Extracting `ToolFilterConfig` into its own file — the type is small (3 fields) and co-located with its producer (`assembleSessionConfig`).
|
|
26
|
-
- Adding a `needsFiltering()` predicate or encapsulating the guard condition — follow-up if the duplication grows.
|
|
27
|
-
- Changing the `extensions` field on `AgentConfig` — that lives in the config domain and is unrelated.
|
|
28
|
-
|
|
29
|
-
## Background
|
|
30
|
-
|
|
31
|
-
### Affected modules
|
|
32
|
-
|
|
33
|
-
| Module | Role |
|
|
34
|
-
| ------------------------------- | -------------------------------------------------------------------- |
|
|
35
|
-
| `src/session/session-config.ts` | Defines `SessionConfig`, produces it in `assembleSessionConfig` |
|
|
36
|
-
| `src/lifecycle/agent-runner.ts` | Consumes `SessionConfig` in `runAgent`, contains `filterActiveTools` |
|
|
37
|
-
|
|
38
|
-
### Consumer analysis
|
|
39
|
-
|
|
40
|
-
`runAgent` accesses the three tool-filter fields in four places:
|
|
41
|
-
|
|
42
|
-
1. `tools: cfg.toolNames` — passed to `io.createSession` (session-creation tool list).
|
|
43
|
-
2. `noExtensions: cfg.extensions === false` — resource-loader option.
|
|
44
|
-
3. Two identical guard-plus-filter blocks passing all three fields to `filterActiveTools`.
|
|
45
|
-
|
|
46
|
-
After extraction, sites 1 and 2 will read from `cfg.toolFilter.toolNames` and `cfg.toolFilter.extensions`.
|
|
47
|
-
Site 3 (both occurrences) will pass `cfg.toolFilter` as a single argument.
|
|
48
|
-
|
|
49
|
-
### Test files affected
|
|
50
|
-
|
|
51
|
-
| Test file | What changes |
|
|
52
|
-
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
53
|
-
| `test/session/session-config.test.ts` | Assertions on `result.toolNames`, `result.extensions`, `result.disallowedSet` move to `result.toolFilter.*` |
|
|
54
|
-
| `test/lifecycle/agent-runner-extension-tools.test.ts` | No direct `SessionConfig` assertions — exercises tool filtering via `runAgent` end-to-end; no changes needed |
|
|
55
|
-
|
|
56
|
-
### Dependency
|
|
57
|
-
|
|
58
|
-
Issue #164 (reorganize into domain directories) — closed ✓.
|
|
59
|
-
|
|
60
|
-
## Design Overview
|
|
61
|
-
|
|
62
|
-
### ToolFilterConfig shape
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
/** Tool filtering configuration — consumed by filterActiveTools. */
|
|
66
|
-
export interface ToolFilterConfig {
|
|
67
|
-
/** Built-in tool name allowlist for this agent type. */
|
|
68
|
-
toolNames: string[];
|
|
69
|
-
/** Disallowed tool set from agentConfig. undefined when empty. */
|
|
70
|
-
disallowedSet: Set<string> | undefined;
|
|
71
|
-
/** Resolved extensions setting: false | true | string[] allowlist. */
|
|
72
|
-
extensions: boolean | string[];
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### SessionConfig after extraction
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
export interface SessionConfig {
|
|
80
|
-
effectiveCwd: string;
|
|
81
|
-
systemPrompt: string;
|
|
82
|
-
toolFilter: ToolFilterConfig;
|
|
83
|
-
model: unknown;
|
|
84
|
-
thinkingLevel: ThinkingLevel | undefined;
|
|
85
|
-
noSkills: boolean;
|
|
86
|
-
extras: PromptExtras;
|
|
87
|
-
agentMaxTurns: number | undefined;
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Field count drops from 10 top-level fields to 8 (7 remaining + 1 `toolFilter`).
|
|
92
|
-
|
|
93
|
-
### filterActiveTools after extraction
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
function filterActiveTools(
|
|
97
|
-
activeTools: string[],
|
|
98
|
-
config: ToolFilterConfig,
|
|
99
|
-
): string[] {
|
|
100
|
-
const { toolNames, extensions, disallowedSet } = config;
|
|
101
|
-
// ... body unchanged
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Consumer call site (runAgent)
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// Resource loader
|
|
109
|
-
noExtensions: cfg.toolFilter.extensions === false,
|
|
110
|
-
|
|
111
|
-
// Session creation
|
|
112
|
-
tools: cfg.toolFilter.toolNames,
|
|
113
|
-
|
|
114
|
-
// Guard + filter (two sites)
|
|
115
|
-
if (cfg.toolFilter.extensions !== false || cfg.toolFilter.disallowedSet) {
|
|
116
|
-
const filtered = filterActiveTools(session.getActiveToolNames(), cfg.toolFilter);
|
|
117
|
-
session.setActiveToolsByName(filtered);
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Module-Level Changes
|
|
122
|
-
|
|
123
|
-
### `src/session/session-config.ts`
|
|
124
|
-
|
|
125
|
-
1. Add `ToolFilterConfig` interface (exported — consumed by `agent-runner.ts`).
|
|
126
|
-
2. Replace `toolNames`, `disallowedSet`, and `extensions` fields on `SessionConfig` with a single `toolFilter: ToolFilterConfig` field.
|
|
127
|
-
3. Update `assembleSessionConfig` return statement to nest the three values under `toolFilter`.
|
|
128
|
-
|
|
129
|
-
### `src/lifecycle/agent-runner.ts`
|
|
130
|
-
|
|
131
|
-
1. Import `ToolFilterConfig` from `session-config.ts`.
|
|
132
|
-
2. Change `filterActiveTools` signature from `(activeTools, toolNames, extensions, disallowedSet)` to `(activeTools, config: ToolFilterConfig)`.
|
|
133
|
-
3. Destructure `config` inside `filterActiveTools` body.
|
|
134
|
-
4. Update both filter call sites to pass `cfg.toolFilter` instead of three separate arguments.
|
|
135
|
-
5. Update `noExtensions:` and `tools:` references to use `cfg.toolFilter.*`.
|
|
136
|
-
|
|
137
|
-
### `test/session/session-config.test.ts`
|
|
138
|
-
|
|
139
|
-
1. Update all assertions reading `result.toolNames` → `result.toolFilter.toolNames`.
|
|
140
|
-
2. Update all assertions reading `result.extensions` → `result.toolFilter.extensions`.
|
|
141
|
-
3. Update all assertions reading `result.disallowedSet` → `result.toolFilter.disallowedSet`.
|
|
142
|
-
|
|
143
|
-
## Test Impact Analysis
|
|
144
|
-
|
|
145
|
-
1. No new unit tests are needed — the extraction does not introduce new behavior or branching.
|
|
146
|
-
2. No existing tests become redundant — the assembler tests verify field population, and the extension-tools integration tests verify end-to-end filtering.
|
|
147
|
-
Both remain valuable at their respective layers.
|
|
148
|
-
3. The `agent-runner-extension-tools.test.ts` tests exercise tool filtering via `runAgent` and do not reference `SessionConfig` fields directly, so they require no changes and serve as regression canaries for the refactoring.
|
|
149
|
-
|
|
150
|
-
## TDD Order
|
|
151
|
-
|
|
152
|
-
This is a pure refactoring with no new behavior, so the steps are refactor→verify rather than red→green.
|
|
153
|
-
|
|
154
|
-
1. **Add `ToolFilterConfig` interface and nest it in `SessionConfig`; update assembler return.**
|
|
155
|
-
Update `session-config.test.ts` assertions to read from `result.toolFilter.*`.
|
|
156
|
-
Run `pnpm run check` + tests.
|
|
157
|
-
Commit: `refactor(pi-subagents): extract ToolFilterConfig from SessionConfig`
|
|
158
|
-
|
|
159
|
-
2. **Change `filterActiveTools` signature to accept `ToolFilterConfig`; update `runAgent` call sites.**
|
|
160
|
-
Import `ToolFilterConfig`, destructure inside `filterActiveTools`, update all `cfg.*` references in `runAgent`.
|
|
161
|
-
Run `pnpm run check` + full test suite.
|
|
162
|
-
Commit: `refactor(pi-subagents): pass ToolFilterConfig to filterActiveTools`
|
|
163
|
-
|
|
164
|
-
## Risks and Mitigations
|
|
165
|
-
|
|
166
|
-
| Risk | Mitigation |
|
|
167
|
-
| ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
168
|
-
| `cfg.toolNames` is also used for `tools:` in `createSession` — nesting it might confuse readers about intent | The field name `toolFilter.toolNames` is still descriptive; add a brief inline comment at the `tools:` site if needed |
|
|
169
|
-
| Test assertions reference flat fields — missing one causes a silent pass on `undefined` | grep for all three field names across `test/` before committing step 1 |
|
|
170
|
-
|
|
171
|
-
## Open Questions
|
|
172
|
-
|
|
173
|
-
None — the issue's proposed shape matches the architecture doc exactly and the change is internal to the package.
|