@selesai/code 0.4.0 → 0.5.1
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/dist/core/agent-session-auto-handoff.test.d.ts +2 -0
- package/dist/core/agent-session-auto-handoff.test.d.ts.map +1 -0
- package/dist/core/agent-session-auto-handoff.test.js +161 -0
- package/dist/core/agent-session-auto-handoff.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +4 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +43 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/settings-manager-auto-handoff.test.d.ts +2 -0
- package/dist/core/settings-manager-auto-handoff.test.d.ts.map +1 -0
- package/dist/core/settings-manager-auto-handoff.test.js +29 -0
- package/dist/core/settings-manager-auto-handoff.test.js.map +1 -0
- package/dist/core/settings-manager.d.ts +9 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +22 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/extensions/context-compaction-reminder.ts +1 -1
- package/dist/extensions/pi-powerline-footer/index.ts +43 -2
- package/dist/extensions/pi-powerline-footer/session-usage.ts +44 -0
- package/dist/extensions/pi-powerline-footer/tests/session-usage.test.ts +47 -0
- package/dist/extensions/pi-subagents/README.md +1 -1
- package/dist/extensions/pi-subagents/agents/architect.md +150 -22
- package/dist/extensions/pi-subagents/agents/builder.md +1 -1
- package/dist/extensions/pi-subagents/agents/commentator.md +2 -2
- package/dist/extensions/pi-subagents/agents/explorer.md +2 -3
- package/dist/extensions/pi-subagents/agents/recapper.md +2 -2
- package/dist/extensions/pi-subagents/agents/researcher.md +2 -2
- package/dist/extensions/pi-subagents/src/agents/agents.ts +46 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +25 -1
- package/dist/extensions/workflow/adapter.ts +34 -174
- package/dist/extensions/workflow/modes/prototype.ts +12 -14
- package/dist/extensions/workflow/modes/quick.ts +12 -14
- package/dist/extensions/workflow/modes/task.ts +8 -5
- package/dist/extensions/workflow/state-machine.ts +3 -0
- package/dist/extensions/workflow/task-validators.ts +69 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +8 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +8 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +12 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +14 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +20 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/workflows.md +9 -4
- package/package.json +1 -1
|
@@ -5,36 +5,164 @@ tools: read, grep, find, ls
|
|
|
5
5
|
systemPromptMode: replace
|
|
6
6
|
inheritProjectContext: true
|
|
7
7
|
inheritSkills: false
|
|
8
|
-
skill: ponytail
|
|
9
|
-
output: plan.md
|
|
8
|
+
skill: ponytail, caveman, planger
|
|
10
9
|
defaultContext: fork
|
|
11
10
|
---
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
## Goal
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
- Read supplied artifacts and relevant code before planning. Follow callers and tests when needed.
|
|
17
|
-
- Name exact files, symbols, and validation commands whenever evidence permits.
|
|
18
|
-
- Prefer the smallest maintainable change. Reuse existing code and avoid speculative abstractions or dependencies.
|
|
19
|
-
- Surface unresolved requirements or risks instead of inventing product decisions.
|
|
20
|
-
- The configured output artifact is allowed; do not write any other file.
|
|
14
|
+
Create implementation plans that can be executed by a small coding model with:
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
- Limited context window
|
|
17
|
+
- No project knowledge
|
|
18
|
+
- No memory of previous conversation
|
|
19
|
+
- Weak architectural understanding
|
|
20
|
+
- No ability to infer missing steps
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
Assume the executor only knows what is written in the plan. Return the complete plan in your final response; do not write an output file.
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
# Core Principles
|
|
25
|
+
|
|
26
|
+
## Discovery First
|
|
27
|
+
|
|
28
|
+
Never assume:
|
|
29
|
+
|
|
30
|
+
- File names
|
|
31
|
+
- File locations
|
|
32
|
+
- Ownership of behavior
|
|
33
|
+
- Existing abstractions
|
|
34
|
+
- Existing utilities
|
|
35
|
+
|
|
36
|
+
If the code has not been inspected, the plan must begin with discovery.
|
|
37
|
+
You research the codebase (using explore agent) → clarify with the user (using questions tool) → capture findings and decisions into a comprehensive plan. This iterative approach catches edge cases and non-obvious requirements BEFORE implementation begins.
|
|
38
|
+
|
|
39
|
+
## Simplicity First
|
|
40
|
+
|
|
41
|
+
Prefer the smallest maintainable solution that satisfies the requirement.
|
|
42
|
+
|
|
43
|
+
Avoid:
|
|
44
|
+
|
|
45
|
+
- New abstractions
|
|
46
|
+
- New services
|
|
47
|
+
- New dependencies
|
|
48
|
+
- Large refactors
|
|
49
|
+
- Generic frameworks
|
|
50
|
+
- Future-proofing for hypothetical requirements
|
|
51
|
+
|
|
52
|
+
Choose the lowest-complexity solution that works.
|
|
53
|
+
|
|
54
|
+
## Reuse Before Build
|
|
55
|
+
|
|
56
|
+
Before creating anything new (use explorer agent):
|
|
57
|
+
|
|
58
|
+
- Search for existing implementations
|
|
59
|
+
- Search for existing utilities
|
|
60
|
+
- Search for existing patterns
|
|
61
|
+
- Search for existing tests
|
|
62
|
+
|
|
63
|
+
Reuse existing code when reasonable.
|
|
64
|
+
|
|
65
|
+
Do not duplicate behavior unless duplication is clearly preferable.
|
|
66
|
+
|
|
67
|
+
## Scope Discipline
|
|
68
|
+
|
|
69
|
+
Only modify code required for the task.
|
|
70
|
+
|
|
71
|
+
Allowed:
|
|
72
|
+
|
|
73
|
+
- Small cleanup in touched files
|
|
74
|
+
- Remove unused imports
|
|
75
|
+
- Remove obvious dead code
|
|
76
|
+
- Improve nearby naming
|
|
77
|
+
|
|
78
|
+
Not allowed:
|
|
79
|
+
|
|
80
|
+
- Unrelated refactors
|
|
81
|
+
- Architecture changes
|
|
82
|
+
- Broad cleanup efforts
|
|
83
|
+
- Dependency migrations
|
|
84
|
+
|
|
85
|
+
# Task Structure
|
|
86
|
+
|
|
87
|
+
Every implementation task must contain:
|
|
88
|
+
|
|
89
|
+
## 1. Discovery
|
|
90
|
+
|
|
91
|
+
Describe:
|
|
92
|
+
|
|
93
|
+
- What to search for
|
|
94
|
+
- Where to search
|
|
95
|
+
- How to identify relevant code
|
|
96
|
+
|
|
97
|
+
Example:
|
|
98
|
+
|
|
99
|
+
Search for:
|
|
100
|
+
|
|
101
|
+
- Authorization
|
|
102
|
+
- Bearer
|
|
103
|
+
- Interceptor
|
|
104
|
+
- Refresh token
|
|
105
|
+
|
|
106
|
+
Inspect matching files and identify where authentication headers are attached.
|
|
107
|
+
|
|
108
|
+
## 2. Identification
|
|
109
|
+
|
|
110
|
+
Describe:
|
|
111
|
+
|
|
112
|
+
- Exact file(s) to modify
|
|
113
|
+
- Why those files own the behavior
|
|
114
|
+
- Why other files should not be modified
|
|
115
|
+
|
|
116
|
+
## 3. Change
|
|
117
|
+
|
|
118
|
+
Describe:
|
|
119
|
+
|
|
120
|
+
- Exact modification required
|
|
121
|
+
- Functions/classes affected
|
|
122
|
+
- Existing code to reuse
|
|
123
|
+
- New code to add
|
|
124
|
+
- Code explicitly not to add
|
|
125
|
+
|
|
126
|
+
The executor should know exactly what to implement.
|
|
127
|
+
|
|
128
|
+
## 4. Verification
|
|
129
|
+
|
|
130
|
+
Include:
|
|
131
|
+
|
|
132
|
+
### Success Cases
|
|
133
|
+
|
|
134
|
+
Expected working behavior.
|
|
135
|
+
|
|
136
|
+
### Failure Cases
|
|
137
|
+
|
|
138
|
+
Expected error behavior.
|
|
139
|
+
|
|
140
|
+
### Regression Checks
|
|
141
|
+
|
|
142
|
+
Existing behavior that must remain unchanged.
|
|
143
|
+
|
|
144
|
+
# Granularity Rule
|
|
145
|
+
|
|
146
|
+
A task is too large if it can be split into smaller independently verifiable work.
|
|
147
|
+
|
|
148
|
+
Keep decomposing until each task:
|
|
149
|
+
|
|
150
|
+
- Has one objective
|
|
151
|
+
- Has clear ownership
|
|
152
|
+
- Can be implemented independently
|
|
153
|
+
- Can be verified independently
|
|
27
154
|
|
|
28
|
-
|
|
29
|
-
- Relevant files, existing behavior, and constraints.
|
|
155
|
+
Prefer 5 small tasks over 1 large task.
|
|
30
156
|
|
|
31
|
-
|
|
32
|
-
1. Exact file and change.
|
|
33
|
-
2. Exact file and change.
|
|
157
|
+
# Final Review
|
|
34
158
|
|
|
35
|
-
|
|
36
|
-
- Success cases
|
|
37
|
-
- Failure/regression cases
|
|
38
|
-
- Commands or manual checks
|
|
159
|
+
Before returning a plan verify:
|
|
39
160
|
|
|
40
|
-
|
|
161
|
+
- Discovery exists
|
|
162
|
+
- Ownership is justified
|
|
163
|
+
- Solution is the simplest acceptable approach
|
|
164
|
+
- Existing code is reused when possible
|
|
165
|
+
- No unnecessary abstractions are introduced
|
|
166
|
+
- Scope remains limited
|
|
167
|
+
- Verification is included
|
|
168
|
+
- Every step is executable without additional assumptions
|
|
@@ -7,11 +7,11 @@ systemPromptMode: replace
|
|
|
7
7
|
inheritProjectContext: true
|
|
8
8
|
inheritSkills: false
|
|
9
9
|
defaultContext: fresh
|
|
10
|
-
|
|
10
|
+
skill: ponytail, caveman, planger
|
|
11
11
|
completionGuard: false
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
You are a review-only subagent. Inspect and report evidence-backed findings; do not edit project files,
|
|
14
|
+
You are a review-only subagent. Inspect and report evidence-backed findings; do not edit project files, write output files, use shell commands that mutate state, or launch subagents.
|
|
15
15
|
|
|
16
16
|
Review the supplied target directly. For code, inspect the actual diff, callers, relevant tests, and requirements—not just another agent's summary. Use `bash` only for read-only inspection or test commands.
|
|
17
17
|
|
|
@@ -5,12 +5,11 @@ tools: read, grep, find, ls
|
|
|
5
5
|
systemPromptMode: replace
|
|
6
6
|
inheritProjectContext: true
|
|
7
7
|
inheritSkills: false
|
|
8
|
-
skill: caveman
|
|
9
|
-
output: context.md
|
|
8
|
+
skill: ponytail, caveman
|
|
10
9
|
defaultContext: fresh
|
|
11
10
|
---
|
|
12
11
|
|
|
13
|
-
You are a codebase reconnaissance subagent. Inspect the repository and return only the minimum verified context another agent needs to act. Do not edit project files
|
|
12
|
+
You are a codebase reconnaissance subagent. Inspect the repository and return only the minimum verified context another agent needs to act. Do not edit project files, write output files, or launch subagents.
|
|
14
13
|
|
|
15
14
|
Use targeted `grep`, `find`, `ls`, and `read`. Follow imports, callers, tests, and configuration far enough to establish the real behavior. Do not guess.
|
|
16
15
|
|
|
@@ -5,11 +5,11 @@ tools: read, grep, find, ls
|
|
|
5
5
|
systemPromptMode: replace
|
|
6
6
|
inheritProjectContext: true
|
|
7
7
|
inheritSkills: false
|
|
8
|
+
skill: ponytail, caveman
|
|
8
9
|
defaultContext: fork
|
|
9
|
-
output: handoff.md
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
Create a concise, self-contained handoff for a fresh agent. Use the inherited conversation, supplied artifacts, and relevant repository evidence. Do not edit project files or launch subagents.
|
|
12
|
+
Create a concise, self-contained handoff for a fresh agent. Use the inherited conversation, supplied artifacts, and relevant repository evidence. Do not edit project files, write output files, or launch subagents.
|
|
13
13
|
|
|
14
14
|
Do not duplicate plans, ADRs, issues, commits, diffs, or other artifacts: reference them by exact path or URL. Redact secrets and personal data. If the task names a next focus, tailor the handoff to it.
|
|
15
15
|
|
|
@@ -6,11 +6,11 @@ thinking: medium
|
|
|
6
6
|
systemPromptMode: replace
|
|
7
7
|
inheritProjectContext: false
|
|
8
8
|
inheritSkills: false
|
|
9
|
-
output: research.md
|
|
10
9
|
defaultContext: fresh
|
|
10
|
+
skill: ponytail, caveman
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
You are a web research subagent. Answer the supplied question with a concise, well-sourced brief. Do not edit project files or launch subagents.
|
|
13
|
+
You are a web research subagent. Answer the supplied question with a concise, well-sourced brief. Do not edit project files, write output files, or launch subagents.
|
|
14
14
|
|
|
15
15
|
Use `web_explore` for focused search/fetch/source ranking. Start with 2–4 distinct angles, prioritize primary and official sources, then narrow follow-ups only for material gaps. Do not fetch URLs through shell commands.
|
|
16
16
|
|
|
@@ -543,6 +543,52 @@ function getUserAgentSettingsPath(): string {
|
|
|
543
543
|
return path.join(getAgentDir(), "settings.json");
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
/**
|
|
547
|
+
* Seed the user-visible subagent configuration on first session startup.
|
|
548
|
+
*
|
|
549
|
+
* Builtin agents normally inherit the parent session model. Recording that
|
|
550
|
+
* model as `subagents.defaultModel` makes the default explicit. Each bundled
|
|
551
|
+
* role is also written to `agentOverrides`, so users can see and edit its
|
|
552
|
+
* effective model without changing unrelated user settings.
|
|
553
|
+
*/
|
|
554
|
+
export function ensureDefaultUserSubagentSettings(currentModel: { provider: string; id: string } | undefined): boolean {
|
|
555
|
+
if (!currentModel?.provider || !currentModel.id) return false;
|
|
556
|
+
|
|
557
|
+
const filePath = getUserAgentSettingsPath();
|
|
558
|
+
const settings = readSettingsFileStrict(filePath);
|
|
559
|
+
const existing = settings.subagents;
|
|
560
|
+
if (existing !== undefined && (!existing || typeof existing !== "object" || Array.isArray(existing))) return false;
|
|
561
|
+
|
|
562
|
+
const subagents = (existing ?? {}) as Record<string, unknown>;
|
|
563
|
+
const currentModelId = `${currentModel.provider}/${currentModel.id}`;
|
|
564
|
+
if ("defaultModel" in subagents && (typeof subagents.defaultModel !== "string" || !subagents.defaultModel.trim())) return false;
|
|
565
|
+
|
|
566
|
+
let changed = false;
|
|
567
|
+
if (!("defaultModel" in subagents)) {
|
|
568
|
+
subagents.defaultModel = currentModelId;
|
|
569
|
+
changed = true;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const defaultModel = subagents.defaultModel as string;
|
|
573
|
+
const overrides = subagents.agentOverrides;
|
|
574
|
+
const shouldSeedOverrides = overrides === undefined
|
|
575
|
+
|| (overrides !== null && typeof overrides === "object" && !Array.isArray(overrides) && Object.keys(overrides).length === 0);
|
|
576
|
+
if (shouldSeedOverrides) {
|
|
577
|
+
subagents.agentOverrides = Object.fromEntries(
|
|
578
|
+
loadAgentsFromDir(BUILTIN_AGENTS_DIR, "builtin").map((agent) => [
|
|
579
|
+
agent.name,
|
|
580
|
+
{ model: agent.model ?? defaultModel },
|
|
581
|
+
]),
|
|
582
|
+
);
|
|
583
|
+
changed = true;
|
|
584
|
+
}
|
|
585
|
+
if (!changed) return false;
|
|
586
|
+
|
|
587
|
+
settings.subagents = subagents;
|
|
588
|
+
writeSettingsFile(filePath, settings);
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
|
|
546
592
|
function getProjectAgentSettingsPath(cwd: string): string | null {
|
|
547
593
|
const projectRoot = findNearestProjectRoot(cwd);
|
|
548
594
|
return projectRoot ? path.join(getProjectConfigDir(projectRoot), "settings.json") : null;
|
|
@@ -19,7 +19,7 @@ import * as path from "node:path";
|
|
|
19
19
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
20
20
|
import { keyText, type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@selesai/code";
|
|
21
21
|
import { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from "@earendil-works/pi-tui";
|
|
22
|
-
import { discoverAgents } from "../agents/agents.ts";
|
|
22
|
+
import { discoverAgents, ensureDefaultUserSubagentSettings } from "../agents/agents.ts";
|
|
23
23
|
import { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from "../shared/artifacts.ts";
|
|
24
24
|
import { resolveCurrentSessionId } from "../shared/session-identity.ts";
|
|
25
25
|
import { cleanupOldChainDirs } from "../shared/settings.ts";
|
|
@@ -584,6 +584,7 @@ wait also returns when a run needs attention (a child that went idle or blocked
|
|
|
584
584
|
};
|
|
585
585
|
|
|
586
586
|
const resetSessionState = (ctx: ExtensionContext) => {
|
|
587
|
+
ensureDefaultUserSubagentSettings(ctx.model);
|
|
587
588
|
state.baseCwd = ctx.cwd;
|
|
588
589
|
state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
589
590
|
state.subagentSpawns = { sessionId: state.currentSessionId, count: 0 };
|
|
@@ -5,6 +5,7 @@ import { createFileCoalescer } from "../../shared/file-coalescer.ts";
|
|
|
5
5
|
import {
|
|
6
6
|
SUBAGENT_ASYNC_COMPLETE_EVENT,
|
|
7
7
|
type IntercomEventBus,
|
|
8
|
+
type Usage,
|
|
8
9
|
type NestedRunSummary,
|
|
9
10
|
type SubagentResultIntercomChild,
|
|
10
11
|
type SubagentState,
|
|
@@ -61,6 +62,7 @@ type ResultFileData = {
|
|
|
61
62
|
sessionFile?: string;
|
|
62
63
|
asyncDir?: string;
|
|
63
64
|
intercomTarget?: string;
|
|
65
|
+
totalChildUsage?: Usage;
|
|
64
66
|
};
|
|
65
67
|
|
|
66
68
|
function sanitizeNestedResultChildren(value: unknown, resultPath: string, label: string): NestedRunSummary[] | undefined {
|
|
@@ -254,6 +254,19 @@ function emptyUsage(): Usage {
|
|
|
254
254
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
+
function usageFromAttempts(attempts: ModelAttempt[] | undefined): Usage {
|
|
258
|
+
const usage = emptyUsage();
|
|
259
|
+
for (const attempt of attempts ?? []) {
|
|
260
|
+
usage.input += attempt.usage?.input ?? 0;
|
|
261
|
+
usage.output += attempt.usage?.output ?? 0;
|
|
262
|
+
usage.cacheRead += attempt.usage?.cacheRead ?? 0;
|
|
263
|
+
usage.cacheWrite += attempt.usage?.cacheWrite ?? 0;
|
|
264
|
+
usage.cost += attempt.usage?.cost ?? 0;
|
|
265
|
+
usage.turns += attempt.usage?.turns ?? 0;
|
|
266
|
+
}
|
|
267
|
+
return usage;
|
|
268
|
+
}
|
|
269
|
+
|
|
257
270
|
function tokenUsageFromAttempts(attempts: ModelAttempt[] | undefined): TokenUsage | null {
|
|
258
271
|
if (!attempts || attempts.length === 0) return null;
|
|
259
272
|
let input = 0;
|
|
@@ -2959,6 +2972,16 @@ async function runSubagent(config: SubagentRunConfig): Promise<void> {
|
|
|
2959
2972
|
costUsd: sum.costUsd + (result.totalCost?.costUsd ?? 0),
|
|
2960
2973
|
}), { inputTokens: 0, outputTokens: 0, costUsd: 0 });
|
|
2961
2974
|
const finalTotalCost = totalCost.inputTokens > 0 || totalCost.outputTokens > 0 || totalCost.costUsd > 0 ? totalCost : undefined;
|
|
2975
|
+
const totalChildUsage = results.reduce<Usage>((sum, result) => {
|
|
2976
|
+
const usage = usageFromAttempts(result.modelAttempts);
|
|
2977
|
+
sum.input += usage.input;
|
|
2978
|
+
sum.output += usage.output;
|
|
2979
|
+
sum.cacheRead += usage.cacheRead;
|
|
2980
|
+
sum.cacheWrite += usage.cacheWrite;
|
|
2981
|
+
sum.cost += usage.cost;
|
|
2982
|
+
sum.turns += usage.turns;
|
|
2983
|
+
return sum;
|
|
2984
|
+
}, emptyUsage());
|
|
2962
2985
|
const finalFlatAgents = statusPayload.steps.map((step) => step.agent);
|
|
2963
2986
|
const agentName = finalFlatAgents.length === 1
|
|
2964
2987
|
? finalFlatAgents[0]!
|
|
@@ -3113,6 +3136,7 @@ async function runSubagent(config: SubagentRunConfig): Promise<void> {
|
|
|
3113
3136
|
timestamp: runEndedAt,
|
|
3114
3137
|
durationMs: runEndedAt - overallStartTime,
|
|
3115
3138
|
totalTokens: statusPayload.totalTokens,
|
|
3139
|
+
totalChildUsage,
|
|
3116
3140
|
totalCost: finalTotalCost,
|
|
3117
3141
|
truncated,
|
|
3118
3142
|
artifactsDir,
|
|
@@ -3,7 +3,7 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { afterEach, beforeEach, describe, it } from "node:test";
|
|
6
|
-
import { discoverAgentsAll } from "../../src/agents/agents.ts";
|
|
6
|
+
import { discoverAgentsAll, ensureDefaultUserSubagentSettings } from "../../src/agents/agents.ts";
|
|
7
7
|
import { handleCreate } from "../../src/agents/agent-management.ts";
|
|
8
8
|
import { clearSkillCache, discoverAvailableSkills, resolveSkillPath } from "../../src/agents/skills.ts";
|
|
9
9
|
import { loadConfig } from "../../src/extension/config.ts";
|
|
@@ -86,6 +86,30 @@ describe("SELESAI_CODING_AGENT_DIR runtime paths", () => {
|
|
|
86
86
|
assert.equal(config.maxSubagentDepth, 3);
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
it("seeds an editable user subagent model default without replacing existing settings", () => {
|
|
90
|
+
const settingsPath = path.join(agentDir, "settings.json");
|
|
91
|
+
writeFile(settingsPath, JSON.stringify({ defaultModel: "openai/gpt-5", packages: ["npm:example"] }, null, 2));
|
|
92
|
+
|
|
93
|
+
assert.equal(ensureDefaultUserSubagentSettings({ provider: "anthropic", id: "claude-sonnet-4" }), true);
|
|
94
|
+
assert.deepEqual(JSON.parse(fs.readFileSync(settingsPath, "utf-8")), {
|
|
95
|
+
defaultModel: "openai/gpt-5",
|
|
96
|
+
packages: ["npm:example"],
|
|
97
|
+
subagents: {
|
|
98
|
+
defaultModel: "anthropic/claude-sonnet-4",
|
|
99
|
+
agentOverrides: {
|
|
100
|
+
architect: { model: "anthropic/claude-sonnet-4" },
|
|
101
|
+
builder: { model: "anthropic/claude-sonnet-4" },
|
|
102
|
+
commentator: { model: "anthropic/claude-sonnet-4" },
|
|
103
|
+
explorer: { model: "anthropic/claude-sonnet-4" },
|
|
104
|
+
recapper: { model: "anthropic/claude-sonnet-4" },
|
|
105
|
+
researcher: { model: "anthropic/claude-sonnet-4" },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
assert.equal(ensureDefaultUserSubagentSettings({ provider: "openai", id: "gpt-5-mini" }), false);
|
|
110
|
+
assert.equal(ensureDefaultUserSubagentSettings(undefined), false);
|
|
111
|
+
});
|
|
112
|
+
|
|
89
113
|
it("discovers user agents, chains, and settings under the configured agent dir", () => {
|
|
90
114
|
const settingsPath = path.join(agentDir, "settings.json");
|
|
91
115
|
writeFile(path.join(agentDir, "agents", "env-agent.md"), `---
|