@compilr-dev/sdk 0.19.0 → 0.20.0
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/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/team/index.d.ts +2 -1
- package/dist/team/index.js +1 -1
- package/dist/team/team-agent.d.ts +90 -8
- package/dist/team/team-agent.js +117 -20
- package/dist/team/team.d.ts +15 -0
- package/dist/team/team.js +45 -0
- package/dist/team/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
*/
|
|
36
36
|
export { createCompilrAgent } from './agent.js';
|
|
37
37
|
export type { CompilrAgentConfig, CompilrAgent, RunOptions, RunResult, ToolCallRecord, ToolConfig, UsageInfo, ProviderType, PermissionCallback, GuardrailConfig, ContextConfig, CapabilitiesConfig, } from './config.js';
|
|
38
|
-
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, createDelegateTool, createDelegateBackgroundTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, createConsultTool, buildConsultQuestionMessage, ROLE_NAME_ALIASES, normalizeRoleName, } from './team/index.js';
|
|
39
|
-
export type { AgentTeamConfig, TeamAgentConfig, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } from './team/index.js';
|
|
38
|
+
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, createDelegateTool, createDelegateBackgroundTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, createConsultTool, buildConsultQuestionMessage, ROLE_NAME_ALIASES, normalizeRoleName, isNarrowing, } from './team/index.js';
|
|
39
|
+
export type { AgentTeamConfig, TeamAgentConfig, TeamAgentUpdate, AgentUpdateResult, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } from './team/index.js';
|
|
40
40
|
export type { AgentRole, RoleMetadata, ToolProfile, MascotExpression, BackgroundSessionInfo, SerializedTeam, SerializedTeamAgent, TeamMetadata, TeamEvent, TeamEventType, TeamEventHandler, Artifact, ArtifactType as TeamArtifactType, ArtifactSummary as TeamArtifactSummary, CreateArtifactOptions, UpdateArtifactOptions, SerializedArtifact, SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry, TeamActivity, TeamActivityType, SharedDecision, TokenBudget, SerializedSharedContext, ParsedMention, ParsedInput, ResolvedMention, ResolveOptions, ResolutionSource, Delegation, DelegationStatus, DelegationResult, CompletionEvent, CreateDelegationOptions, DelegationStats, DelegationTrackerEvents, HandoffResult, HandoffToolConfig, HandoffIntent, HandoffValidationResult, DelegateResult, DelegateToolConfig, DelegateBackgroundResult, DelegateBackgroundToolConfig, ConsultInput, ConsultResult, ConsultToolConfig, NormalizedRole, SkillToolRequirement, } from './team/index.js';
|
|
41
41
|
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap, PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './team/index.js';
|
|
42
42
|
export { getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, buildContextMap, findAgentForRole, findAgentById, getAvailableSpecialists, getSpecialistsSummary, hasSpecialists, suggestOwner, suggestOwners, matchesAgentExpertise, wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmentHistory, clearAllAssignmentHistory, canReassign, resolveAgentIdCollision, setActiveSharedContext, getActiveSharedContext, recordTeamActivity, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
|
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ export { createCompilrAgent } from './agent.js';
|
|
|
41
41
|
// Multi-Agent Team Orchestration
|
|
42
42
|
// =============================================================================
|
|
43
43
|
// Core classes
|
|
44
|
-
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, createDelegateTool, createDelegateBackgroundTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, createConsultTool, buildConsultQuestionMessage, ROLE_NAME_ALIASES, normalizeRoleName, } from './team/index.js';
|
|
44
|
+
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, createDelegateTool, createDelegateBackgroundTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, createConsultTool, buildConsultQuestionMessage, ROLE_NAME_ALIASES, normalizeRoleName, isNarrowing, } from './team/index.js';
|
|
45
45
|
// Constants
|
|
46
46
|
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap,
|
|
47
47
|
// Plan mode
|
package/dist/team/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { AgentTeam } from './team.js';
|
|
8
8
|
export type { AgentTeamConfig } from './team.js';
|
|
9
|
-
export { TeamAgent } from './team-agent.js';
|
|
9
|
+
export { TeamAgent, isNarrowing } from './team-agent.js';
|
|
10
|
+
export type { TeamAgentUpdate, AgentUpdateResult } from './team-agent.js';
|
|
10
11
|
export { SharedContextManager } from './shared-context.js';
|
|
11
12
|
export type { SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry, TeamActivity, TeamActivityType, SharedDecision, TokenBudget, SerializedSharedContext, } from './shared-context.js';
|
|
12
13
|
export { ArtifactStore } from './artifacts.js';
|
package/dist/team/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// Core classes
|
|
8
8
|
export { AgentTeam } from './team.js';
|
|
9
|
-
export { TeamAgent } from './team-agent.js';
|
|
9
|
+
export { TeamAgent, isNarrowing } from './team-agent.js';
|
|
10
10
|
export { SharedContextManager } from './shared-context.js';
|
|
11
11
|
export { ArtifactStore } from './artifacts.js';
|
|
12
12
|
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS } from './types.js';
|
|
@@ -13,22 +13,78 @@ import type { ModelTier } from '../models/index.js';
|
|
|
13
13
|
import type { ProviderType } from '../config.js';
|
|
14
14
|
import type { SharedContextManager } from './shared-context.js';
|
|
15
15
|
import type { CustomAgentDefinition } from './custom-agents.js';
|
|
16
|
+
/**
|
|
17
|
+
* The editable subset of an agent.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ `id` AND `role` ARE ABSENT BY DESIGN. The id is immutable (see `TeamAgent.id`); the role
|
|
20
|
+
* is structural — it decides the preset an agent was built from, and the editor's five
|
|
21
|
+
* sections do not offer it.
|
|
22
|
+
*/
|
|
23
|
+
export interface TeamAgentUpdate {
|
|
24
|
+
displayName?: string;
|
|
25
|
+
mascot?: MascotExpression;
|
|
26
|
+
description?: string;
|
|
27
|
+
systemPromptAddition?: string;
|
|
28
|
+
toolProfile?: TeamAgentConfig['toolProfile'];
|
|
29
|
+
toolFilter?: string[];
|
|
30
|
+
enabledSkills?: string[];
|
|
31
|
+
}
|
|
32
|
+
/** What an edit did, and whether anyone needs telling. */
|
|
33
|
+
export interface AgentUpdateResult {
|
|
34
|
+
/** The underlying agent was dropped and rebuilt, carrying its history across. */
|
|
35
|
+
rebuilt: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* ⚠️ THE CASE THAT HAS TO REACH THE CONVERSATION. The agent may now touch strictly less
|
|
38
|
+
* than it could — and its own history contains it planning to do things it can no longer
|
|
39
|
+
* do. Its next turn will attempt one and get a refusal it cannot account for: a capability
|
|
40
|
+
* change an agent cannot OBSERVE reads to it as a malfunction.
|
|
41
|
+
*
|
|
42
|
+
* Widening is reported too. Nothing breaks, but a record of when an agent gained the
|
|
43
|
+
* ability to write files is worth more than the row it costs.
|
|
44
|
+
*/
|
|
45
|
+
toolsNarrowed: boolean;
|
|
46
|
+
previousProfile?: TeamAgentConfig['toolProfile'];
|
|
47
|
+
newProfile?: TeamAgentConfig['toolProfile'];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Did the tool profile get strictly smaller?
|
|
51
|
+
*
|
|
52
|
+
* ⚠️ Decided by whether the profile is READ-ONLY, not by counting tools. A profile with more
|
|
53
|
+
* tools that cannot write is a narrowing in every sense the user cares about, and tool counts
|
|
54
|
+
* shift whenever the registry grows.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isNarrowing(before: TeamAgentConfig['toolProfile'], after: TeamAgentConfig['toolProfile']): boolean;
|
|
16
57
|
/**
|
|
17
58
|
* TeamAgent wraps an Agent instance with team-specific metadata
|
|
18
59
|
*/
|
|
19
60
|
export declare class TeamAgent {
|
|
20
61
|
/**
|
|
21
|
-
* Unique identifier (e.g., 'pm', 'arch', 'qa')
|
|
62
|
+
* Unique identifier (e.g., 'pm', 'arch', 'qa').
|
|
63
|
+
*
|
|
64
|
+
* ⚠️ IMMUTABLE, AND ENFORCED HERE RATHER THAN IN THE UI. Thirteen persisted places key off
|
|
65
|
+
* this string — `work_items.owner` (indexed), `work_item_comments.author`,
|
|
66
|
+
* `projects.active_agent`, `file_locks.agent_id`, the conversation file's `agentId`,
|
|
67
|
+
* `agentIds[]`, `activeAgentId` and its `agentHistories` Record, every message's `agentId`,
|
|
68
|
+
* and both sides of every handoff marker.
|
|
69
|
+
*
|
|
70
|
+
* ⚠️ AND ONE THAT CANNOT BE MIGRATED AT ALL: the literal `$handle` is persisted inside
|
|
71
|
+
* message PROSE. Mentions are resolved when typed, not when read, so the raw text is what
|
|
72
|
+
* gets stored. A perfect cascading rename still cannot fix `$arch` in a sentence a user
|
|
73
|
+
* wrote months ago — and rewriting their words to keep a reference alive is worse than not
|
|
74
|
+
* renaming.
|
|
75
|
+
*
|
|
76
|
+
* The rename path is DUPLICATE, which already excludes handle and face because both must
|
|
77
|
+
* be unique. Explicit and reversible, where a cascading rename is neither.
|
|
22
78
|
*/
|
|
23
79
|
readonly id: string;
|
|
24
80
|
/**
|
|
25
81
|
* Display name shown in UI
|
|
26
82
|
*/
|
|
27
|
-
|
|
83
|
+
displayName: string;
|
|
28
84
|
/**
|
|
29
85
|
* Mascot expression for visual differentiation
|
|
30
86
|
*/
|
|
31
|
-
|
|
87
|
+
mascot: MascotExpression;
|
|
32
88
|
/**
|
|
33
89
|
* Role type
|
|
34
90
|
*/
|
|
@@ -36,11 +92,11 @@ export declare class TeamAgent {
|
|
|
36
92
|
/**
|
|
37
93
|
* Optional description
|
|
38
94
|
*/
|
|
39
|
-
|
|
95
|
+
description?: string;
|
|
40
96
|
/**
|
|
41
97
|
* System prompt addition specific to this agent
|
|
42
98
|
*/
|
|
43
|
-
|
|
99
|
+
systemPromptAddition?: string;
|
|
44
100
|
/**
|
|
45
101
|
* Use minimal system prompt - skip all modules
|
|
46
102
|
*/
|
|
@@ -52,15 +108,15 @@ export declare class TeamAgent {
|
|
|
52
108
|
/**
|
|
53
109
|
* Tool filter (tool names this agent can use)
|
|
54
110
|
*/
|
|
55
|
-
|
|
111
|
+
toolFilter?: string[];
|
|
56
112
|
/**
|
|
57
113
|
* Tool profile name (for display)
|
|
58
114
|
*/
|
|
59
|
-
|
|
115
|
+
toolProfile?: TeamAgentConfig['toolProfile'];
|
|
60
116
|
/**
|
|
61
117
|
* Enabled skills (empty = all skills)
|
|
62
118
|
*/
|
|
63
|
-
|
|
119
|
+
enabledSkills?: string[];
|
|
64
120
|
/**
|
|
65
121
|
* Auto-approve handoffs from this agent without user confirmation
|
|
66
122
|
*/
|
|
@@ -122,6 +178,32 @@ export declare class TeamAgent {
|
|
|
122
178
|
* @param newTier - The new model tier to use
|
|
123
179
|
*/
|
|
124
180
|
setModelTier(newTier: ModelTier): void;
|
|
181
|
+
/**
|
|
182
|
+
* Serialise the live agent, keep its history, and drop the instance so the next
|
|
183
|
+
* `initialize()` rebuilds it.
|
|
184
|
+
*
|
|
185
|
+
* ⚠️ EXTRACTED so `setModelTier` and `applyUpdate` cannot drift. Two copies of a
|
|
186
|
+
* history-transfer is exactly the kind of duplication that survives review and then
|
|
187
|
+
* silently loses a conversation when only one of them is fixed.
|
|
188
|
+
*
|
|
189
|
+
* Thinking blocks are stripped: they carry provider-specific signatures (Gemini's
|
|
190
|
+
* `thought_signature`) that do not transfer across a rebuild.
|
|
191
|
+
*/
|
|
192
|
+
private stashForRebuild;
|
|
193
|
+
/**
|
|
194
|
+
* Apply an edit to this agent in place.
|
|
195
|
+
*
|
|
196
|
+
* ⚠️ IN PLACE, NOT A REPLACEMENT INSTANCE. Other structures hold `TeamAgent` references —
|
|
197
|
+
* swapping the object in the team's map would leave every one of them pointing at a stale
|
|
198
|
+
* agent, and nothing would report it.
|
|
199
|
+
*
|
|
200
|
+
* Returns whether the change requires the underlying agent to be rebuilt. Metadata
|
|
201
|
+
* (`displayName`, `mascot`, `description`) is read from the roster at render time, so a
|
|
202
|
+
* rename is retroactive and free; anything that feeds agent CONSTRUCTION is not.
|
|
203
|
+
*/
|
|
204
|
+
applyUpdate(patch: TeamAgentUpdate): {
|
|
205
|
+
rebuilt: boolean;
|
|
206
|
+
};
|
|
125
207
|
/**
|
|
126
208
|
* Initialize the agent with the given factory
|
|
127
209
|
* This allows the team to control agent creation
|
package/dist/team/team-agent.js
CHANGED
|
@@ -17,12 +17,66 @@ import { getToolsForProfile, generateToolAwarenessPrompt, generateCoordinatorGui
|
|
|
17
17
|
function estimateTokens(text) {
|
|
18
18
|
return Math.ceil(text.length / 4);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Did the tool profile get strictly smaller?
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ Decided by whether the profile is READ-ONLY, not by counting tools. A profile with more
|
|
24
|
+
* tools that cannot write is a narrowing in every sense the user cares about, and tool counts
|
|
25
|
+
* shift whenever the registry grows.
|
|
26
|
+
*/
|
|
27
|
+
export function isNarrowing(before, after) {
|
|
28
|
+
if (before === after)
|
|
29
|
+
return false;
|
|
30
|
+
if (before === undefined || after === undefined)
|
|
31
|
+
return false;
|
|
32
|
+
return !READ_ONLY_PROFILES.has(before) && READ_ONLY_PROFILES.has(after);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The profiles that cannot change files.
|
|
36
|
+
*
|
|
37
|
+
* ⚠️ Kept in step with `PROFILE_INFO.isReadOnly` by a test, not by discipline — this module
|
|
38
|
+
* cannot import tool-config without a cycle.
|
|
39
|
+
*/
|
|
40
|
+
const READ_ONLY_PROFILES = new Set([
|
|
41
|
+
'read-only',
|
|
42
|
+
'security',
|
|
43
|
+
'qa',
|
|
44
|
+
'architect',
|
|
45
|
+
'planner',
|
|
46
|
+
'analyst',
|
|
47
|
+
'designer',
|
|
48
|
+
]);
|
|
49
|
+
/** Order-insensitive comparison — a reordered skill list is not a change. */
|
|
50
|
+
function sameStrings(a, b) {
|
|
51
|
+
if (a === undefined || b === undefined)
|
|
52
|
+
return a === b;
|
|
53
|
+
if (a.length !== b.length)
|
|
54
|
+
return false;
|
|
55
|
+
const x = [...a].sort();
|
|
56
|
+
const y = [...b].sort();
|
|
57
|
+
return x.every((v, i) => v === y[i]);
|
|
58
|
+
}
|
|
20
59
|
/**
|
|
21
60
|
* TeamAgent wraps an Agent instance with team-specific metadata
|
|
22
61
|
*/
|
|
23
62
|
export class TeamAgent {
|
|
24
63
|
/**
|
|
25
|
-
* Unique identifier (e.g., 'pm', 'arch', 'qa')
|
|
64
|
+
* Unique identifier (e.g., 'pm', 'arch', 'qa').
|
|
65
|
+
*
|
|
66
|
+
* ⚠️ IMMUTABLE, AND ENFORCED HERE RATHER THAN IN THE UI. Thirteen persisted places key off
|
|
67
|
+
* this string — `work_items.owner` (indexed), `work_item_comments.author`,
|
|
68
|
+
* `projects.active_agent`, `file_locks.agent_id`, the conversation file's `agentId`,
|
|
69
|
+
* `agentIds[]`, `activeAgentId` and its `agentHistories` Record, every message's `agentId`,
|
|
70
|
+
* and both sides of every handoff marker.
|
|
71
|
+
*
|
|
72
|
+
* ⚠️ AND ONE THAT CANNOT BE MIGRATED AT ALL: the literal `$handle` is persisted inside
|
|
73
|
+
* message PROSE. Mentions are resolved when typed, not when read, so the raw text is what
|
|
74
|
+
* gets stored. A perfect cascading rename still cannot fix `$arch` in a sentence a user
|
|
75
|
+
* wrote months ago — and rewriting their words to keep a reference alive is worse than not
|
|
76
|
+
* renaming.
|
|
77
|
+
*
|
|
78
|
+
* The rename path is DUPLICATE, which already excludes handle and face because both must
|
|
79
|
+
* be unique. Explicit and reversible, where a cascading rename is neither.
|
|
26
80
|
*/
|
|
27
81
|
id;
|
|
28
82
|
/**
|
|
@@ -154,27 +208,70 @@ export class TeamAgent {
|
|
|
154
208
|
if (newTier === this._modelTier) {
|
|
155
209
|
return; // No change needed
|
|
156
210
|
}
|
|
157
|
-
|
|
158
|
-
if (this._agent) {
|
|
159
|
-
const state = this._agent.serialize();
|
|
160
|
-
// Strip thinking blocks from messages - they contain provider-specific
|
|
161
|
-
// signatures (e.g., Gemini's thought_signature) that don't transfer
|
|
162
|
-
// between sessions or model changes
|
|
163
|
-
state.messages = state.messages.map((msg) => {
|
|
164
|
-
// Content can be string or ContentBlock[]
|
|
165
|
-
if (typeof msg.content === 'string') {
|
|
166
|
-
return msg;
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
...msg,
|
|
170
|
-
content: msg.content.filter((block) => block.type !== 'thinking'),
|
|
171
|
-
};
|
|
172
|
-
});
|
|
173
|
-
this.storedState = state;
|
|
174
|
-
this._agent = null; // Clear agent so it will be reinitialized
|
|
175
|
-
}
|
|
211
|
+
this.stashForRebuild();
|
|
176
212
|
this._modelTier = newTier;
|
|
177
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Serialise the live agent, keep its history, and drop the instance so the next
|
|
216
|
+
* `initialize()` rebuilds it.
|
|
217
|
+
*
|
|
218
|
+
* ⚠️ EXTRACTED so `setModelTier` and `applyUpdate` cannot drift. Two copies of a
|
|
219
|
+
* history-transfer is exactly the kind of duplication that survives review and then
|
|
220
|
+
* silently loses a conversation when only one of them is fixed.
|
|
221
|
+
*
|
|
222
|
+
* Thinking blocks are stripped: they carry provider-specific signatures (Gemini's
|
|
223
|
+
* `thought_signature`) that do not transfer across a rebuild.
|
|
224
|
+
*/
|
|
225
|
+
stashForRebuild() {
|
|
226
|
+
if (!this._agent)
|
|
227
|
+
return;
|
|
228
|
+
const state = this._agent.serialize();
|
|
229
|
+
state.messages = state.messages.map((msg) => {
|
|
230
|
+
if (typeof msg.content === 'string')
|
|
231
|
+
return msg;
|
|
232
|
+
return {
|
|
233
|
+
...msg,
|
|
234
|
+
content: msg.content.filter((block) => block.type !== 'thinking'),
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
this.storedState = state;
|
|
238
|
+
this._agent = null;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Apply an edit to this agent in place.
|
|
242
|
+
*
|
|
243
|
+
* ⚠️ IN PLACE, NOT A REPLACEMENT INSTANCE. Other structures hold `TeamAgent` references —
|
|
244
|
+
* swapping the object in the team's map would leave every one of them pointing at a stale
|
|
245
|
+
* agent, and nothing would report it.
|
|
246
|
+
*
|
|
247
|
+
* Returns whether the change requires the underlying agent to be rebuilt. Metadata
|
|
248
|
+
* (`displayName`, `mascot`, `description`) is read from the roster at render time, so a
|
|
249
|
+
* rename is retroactive and free; anything that feeds agent CONSTRUCTION is not.
|
|
250
|
+
*/
|
|
251
|
+
applyUpdate(patch) {
|
|
252
|
+
const needsRebuild = (patch.systemPromptAddition !== undefined &&
|
|
253
|
+
patch.systemPromptAddition !== this.systemPromptAddition) ||
|
|
254
|
+
(patch.toolProfile !== undefined && patch.toolProfile !== this.toolProfile) ||
|
|
255
|
+
(patch.toolFilter !== undefined && !sameStrings(patch.toolFilter, this.toolFilter)) ||
|
|
256
|
+
(patch.enabledSkills !== undefined && !sameStrings(patch.enabledSkills, this.enabledSkills));
|
|
257
|
+
if (patch.displayName !== undefined)
|
|
258
|
+
this.displayName = patch.displayName;
|
|
259
|
+
if (patch.mascot !== undefined)
|
|
260
|
+
this.mascot = patch.mascot;
|
|
261
|
+
if (patch.description !== undefined)
|
|
262
|
+
this.description = patch.description;
|
|
263
|
+
if (patch.systemPromptAddition !== undefined)
|
|
264
|
+
this.systemPromptAddition = patch.systemPromptAddition;
|
|
265
|
+
if (patch.toolProfile !== undefined)
|
|
266
|
+
this.toolProfile = patch.toolProfile;
|
|
267
|
+
if (patch.toolFilter !== undefined)
|
|
268
|
+
this.toolFilter = patch.toolFilter;
|
|
269
|
+
if (patch.enabledSkills !== undefined)
|
|
270
|
+
this.enabledSkills = patch.enabledSkills;
|
|
271
|
+
if (needsRebuild)
|
|
272
|
+
this.stashForRebuild();
|
|
273
|
+
return { rebuilt: needsRebuild };
|
|
274
|
+
}
|
|
178
275
|
/**
|
|
179
276
|
* Initialize the agent with the given factory
|
|
180
277
|
* This allows the team to control agent creation
|
package/dist/team/team.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { ModelTier } from '../models/index.js';
|
|
|
14
14
|
import { SharedContextManager } from './shared-context.js';
|
|
15
15
|
import { ArtifactStore } from './artifacts.js';
|
|
16
16
|
import type { CustomAgentDefinition } from './custom-agents.js';
|
|
17
|
+
import type { TeamAgentUpdate, AgentUpdateResult } from './team-agent.js';
|
|
17
18
|
import type { ISessionRegistry } from './interfaces.js';
|
|
18
19
|
/**
|
|
19
20
|
* Configuration for creating an AgentTeam
|
|
@@ -192,6 +193,20 @@ export declare class AgentTeam {
|
|
|
192
193
|
/**
|
|
193
194
|
* Remove an agent from the team
|
|
194
195
|
*/
|
|
196
|
+
/**
|
|
197
|
+
* Edit an existing agent.
|
|
198
|
+
*
|
|
199
|
+
* ⚠️ THE FIRST WAY TO CHANGE AN AGENT WITHOUT DELETING IT. Until this existed, altering a
|
|
200
|
+
* name, instruction, tool profile or skill set meant `removeAgent` + `addAgent`, which
|
|
201
|
+
* orphans every conversation the agent owned.
|
|
202
|
+
*
|
|
203
|
+
* Returns what the caller needs to decide whether to tell anyone:
|
|
204
|
+
* - `rebuilt` — the underlying agent was dropped and will rebuild on next use, carrying
|
|
205
|
+
* its history across.
|
|
206
|
+
* - `toolsNarrowed` — the agent may now touch strictly LESS than it could. See the note
|
|
207
|
+
* on the return type: this is the case that needs to reach the conversation.
|
|
208
|
+
*/
|
|
209
|
+
updateAgent(id: string, patch: TeamAgentUpdate): Promise<AgentUpdateResult>;
|
|
195
210
|
removeAgent(id: string): boolean;
|
|
196
211
|
/**
|
|
197
212
|
* Clear conversation history for all agents in the team
|
package/dist/team/team.js
CHANGED
|
@@ -11,6 +11,7 @@ import { TeamAgent } from './team-agent.js';
|
|
|
11
11
|
import { ROLE_EXPERTISE } from './types.js';
|
|
12
12
|
import { SharedContextManager } from './shared-context.js';
|
|
13
13
|
import { ArtifactStore } from './artifacts.js';
|
|
14
|
+
import { isNarrowing } from './team-agent.js';
|
|
14
15
|
import { resolveAgentIdCollision } from './collision-utils.js';
|
|
15
16
|
/**
|
|
16
17
|
* AgentTeam orchestrates multiple persistent agents
|
|
@@ -311,6 +312,50 @@ export class AgentTeam {
|
|
|
311
312
|
/**
|
|
312
313
|
* Remove an agent from the team
|
|
313
314
|
*/
|
|
315
|
+
/**
|
|
316
|
+
* Edit an existing agent.
|
|
317
|
+
*
|
|
318
|
+
* ⚠️ THE FIRST WAY TO CHANGE AN AGENT WITHOUT DELETING IT. Until this existed, altering a
|
|
319
|
+
* name, instruction, tool profile or skill set meant `removeAgent` + `addAgent`, which
|
|
320
|
+
* orphans every conversation the agent owned.
|
|
321
|
+
*
|
|
322
|
+
* Returns what the caller needs to decide whether to tell anyone:
|
|
323
|
+
* - `rebuilt` — the underlying agent was dropped and will rebuild on next use, carrying
|
|
324
|
+
* its history across.
|
|
325
|
+
* - `toolsNarrowed` — the agent may now touch strictly LESS than it could. See the note
|
|
326
|
+
* on the return type: this is the case that needs to reach the conversation.
|
|
327
|
+
*/
|
|
328
|
+
async updateAgent(id, patch) {
|
|
329
|
+
const agent = this.agents.get(id);
|
|
330
|
+
if (!agent) {
|
|
331
|
+
throw new Error(`Agent '${id}' not found in team`);
|
|
332
|
+
}
|
|
333
|
+
/*
|
|
334
|
+
⚠️ Guarded here even though `TeamAgentUpdate` has no `id`. A patch arriving over IPC is
|
|
335
|
+
a plain object that TypeScript never saw; the immutability decision has to hold against
|
|
336
|
+
data, not only against callers that compiled.
|
|
337
|
+
*/
|
|
338
|
+
if ('id' in patch) {
|
|
339
|
+
throw new Error(`Agent id is immutable — '${id}' cannot be renamed. Duplicate the agent instead: ` +
|
|
340
|
+
'mention handles are written into stored message text and cannot be migrated.');
|
|
341
|
+
}
|
|
342
|
+
const previousProfile = agent.toolProfile;
|
|
343
|
+
const { rebuilt } = agent.applyUpdate(patch);
|
|
344
|
+
if (rebuilt) {
|
|
345
|
+
// Rebuild now rather than lazily, so a failure surfaces at save time.
|
|
346
|
+
await agent.initialize(this.agentFactory, this._sharedContext);
|
|
347
|
+
}
|
|
348
|
+
// displayName/mascot feed the roster injected into every agent's context.
|
|
349
|
+
this.updateTeamRoster();
|
|
350
|
+
this.updatedAt = new Date();
|
|
351
|
+
this.emit({ type: 'agent:updated', agentId: id });
|
|
352
|
+
return {
|
|
353
|
+
rebuilt,
|
|
354
|
+
toolsNarrowed: isNarrowing(previousProfile, agent.toolProfile),
|
|
355
|
+
previousProfile,
|
|
356
|
+
newProfile: agent.toolProfile,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
314
359
|
removeAgent(id) {
|
|
315
360
|
if (id === 'default') {
|
|
316
361
|
throw new Error('Cannot remove the default agent');
|
package/dist/team/types.d.ts
CHANGED
|
@@ -211,7 +211,7 @@ export interface SerializedTeam {
|
|
|
211
211
|
/**
|
|
212
212
|
* Event types for team operations
|
|
213
213
|
*/
|
|
214
|
-
export type TeamEventType = 'agent:added' | 'agent:removed' | 'agent:switched' | 'agent:switch_warning' | 'agent:collision' | 'agent:message' | 'team:checkpoint' | 'team:restored' | 'team:reset';
|
|
214
|
+
export type TeamEventType = 'agent:added' | 'agent:updated' | 'agent:removed' | 'agent:switched' | 'agent:switch_warning' | 'agent:collision' | 'agent:message' | 'team:checkpoint' | 'team:restored' | 'team:reset';
|
|
215
215
|
/**
|
|
216
216
|
* Team event payload
|
|
217
217
|
*/
|