@compilr-dev/sdk 0.22.0 → 0.23.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/team/custom-agents.d.ts +30 -0
- package/dist/team/custom-agents.js +51 -4
- package/dist/team/team-agent.d.ts +25 -0
- package/dist/team/team-agent.js +101 -49
- package/dist/team/types.d.ts +3 -0
- package/package.json +1 -1
|
@@ -33,6 +33,36 @@ export declare const CUSTOM_MASCOTS: string[];
|
|
|
33
33
|
* Avoids mascots already in use by other custom agents.
|
|
34
34
|
*/
|
|
35
35
|
export declare function assignMascot(existingAgents: CustomAgentDefinition[]): string;
|
|
36
|
+
/**
|
|
37
|
+
* The generated scaffold for a custom agent: who it is and what it sticks to.
|
|
38
|
+
*
|
|
39
|
+
* ⚠️ COMPOSED AT `TeamAgent.initialize()`, NEVER STORED in `systemPromptAddition`. That field
|
|
40
|
+
* is the user's own words and nothing else — a host that renders it in a textarea (both of ours
|
|
41
|
+
* do) must not be shown machine-written prose to hand-edit, and must not freeze it on save.
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateCustomAgentScaffold(displayName: string, specialty: string): string;
|
|
44
|
+
/** What a legacy composite yielded up: the user's own words, and a personality to rescue. */
|
|
45
|
+
export interface LegacyCustomPromptParts {
|
|
46
|
+
/** The text the user actually typed, or undefined if they never typed any. */
|
|
47
|
+
userText?: string;
|
|
48
|
+
/** Personality recovered from a frozen `Your approach:` line — see below. */
|
|
49
|
+
personality?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Split a pre-0.23 custom-agent composite back into the parts that belong to the user.
|
|
53
|
+
*
|
|
54
|
+
* Before this change `fromCustomDefinition` stored the whole generated composite in
|
|
55
|
+
* `systemPromptAddition`, so every agent already on disk has it frozen there. This reverses that
|
|
56
|
+
* for the fields we can recover without guessing.
|
|
57
|
+
*
|
|
58
|
+
* ⚠️ `personality` is recovered, not discarded. Legacy `fromCustomDefinition` never passed the
|
|
59
|
+
* definition's personality to the live agent, so for these agents the ONLY surviving copy is the
|
|
60
|
+
* `Your approach:` line inside this string. Dropping it would silently delete a value the user set.
|
|
61
|
+
*
|
|
62
|
+
* Returns `{}` when the string does not look like a composite, which is the signal to leave the
|
|
63
|
+
* stored value exactly as it is. Guessing is worse than migrating nothing.
|
|
64
|
+
*/
|
|
65
|
+
export declare function splitLegacyCustomPrompt(stored: string): LegacyCustomPromptParts;
|
|
36
66
|
/**
|
|
37
67
|
* Generate system prompt for a custom agent.
|
|
38
68
|
* Uses a template-based approach (no LLM call).
|
|
@@ -49,6 +49,57 @@ export function assignMascot(existingAgents) {
|
|
|
49
49
|
// =============================================================================
|
|
50
50
|
// System Prompt Generation
|
|
51
51
|
// =============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* The generated scaffold for a custom agent: who it is and what it sticks to.
|
|
54
|
+
*
|
|
55
|
+
* ⚠️ COMPOSED AT `TeamAgent.initialize()`, NEVER STORED in `systemPromptAddition`. That field
|
|
56
|
+
* is the user's own words and nothing else — a host that renders it in a textarea (both of ours
|
|
57
|
+
* do) must not be shown machine-written prose to hand-edit, and must not freeze it on save.
|
|
58
|
+
*/
|
|
59
|
+
export function generateCustomAgentScaffold(displayName, specialty) {
|
|
60
|
+
return [
|
|
61
|
+
`You are a ${displayName} specialized in ${specialty}.`,
|
|
62
|
+
'',
|
|
63
|
+
'Focus on your area of expertise. When questions fall outside your specialty, suggest which team member might be better suited to help.',
|
|
64
|
+
].join('\n');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Split a pre-0.23 custom-agent composite back into the parts that belong to the user.
|
|
68
|
+
*
|
|
69
|
+
* Before this change `fromCustomDefinition` stored the whole generated composite in
|
|
70
|
+
* `systemPromptAddition`, so every agent already on disk has it frozen there. This reverses that
|
|
71
|
+
* for the fields we can recover without guessing.
|
|
72
|
+
*
|
|
73
|
+
* ⚠️ `personality` is recovered, not discarded. Legacy `fromCustomDefinition` never passed the
|
|
74
|
+
* definition's personality to the live agent, so for these agents the ONLY surviving copy is the
|
|
75
|
+
* `Your approach:` line inside this string. Dropping it would silently delete a value the user set.
|
|
76
|
+
*
|
|
77
|
+
* Returns `{}` when the string does not look like a composite, which is the signal to leave the
|
|
78
|
+
* stored value exactly as it is. Guessing is worse than migrating nothing.
|
|
79
|
+
*/
|
|
80
|
+
export function splitLegacyCustomPrompt(stored) {
|
|
81
|
+
// The identity line is what makes this recognisable as generated. No line, no migration.
|
|
82
|
+
if (!/^You are a .+ specialized in .+\.$/m.test(stored))
|
|
83
|
+
return {};
|
|
84
|
+
const parts = {};
|
|
85
|
+
const approach = /^Your approach: (.+)$/m.exec(stored);
|
|
86
|
+
if (approach)
|
|
87
|
+
parts.personality = approach[1].trim();
|
|
88
|
+
const marker = '## Custom Instructions\n\n';
|
|
89
|
+
const at = stored.indexOf(marker);
|
|
90
|
+
if (at !== -1) {
|
|
91
|
+
let body = stored.slice(at + marker.length);
|
|
92
|
+
// Tool awareness, when present, was appended after a `---` rule. Everything from there on
|
|
93
|
+
// is generated too.
|
|
94
|
+
const rule = body.indexOf('\n\n---\n\n');
|
|
95
|
+
if (rule !== -1)
|
|
96
|
+
body = body.slice(0, rule);
|
|
97
|
+
const trimmed = body.trim();
|
|
98
|
+
if (trimmed)
|
|
99
|
+
parts.userText = trimmed;
|
|
100
|
+
}
|
|
101
|
+
return parts;
|
|
102
|
+
}
|
|
52
103
|
/**
|
|
53
104
|
* Generate system prompt for a custom agent.
|
|
54
105
|
* Uses a template-based approach (no LLM call).
|
|
@@ -56,10 +107,6 @@ export function assignMascot(existingAgents) {
|
|
|
56
107
|
*/
|
|
57
108
|
export function generateCustomAgentSystemPrompt(agent) {
|
|
58
109
|
const lines = [`You are a ${agent.displayName} specialized in ${agent.specialty}.`];
|
|
59
|
-
if (agent.personality) {
|
|
60
|
-
lines.push('');
|
|
61
|
-
lines.push(`Your approach: ${agent.personality}`);
|
|
62
|
-
}
|
|
63
110
|
lines.push('');
|
|
64
111
|
lines.push('Focus on your area of expertise. When questions fall outside your specialty, suggest which team member might be better suited to help.');
|
|
65
112
|
// Append custom instructions if provided
|
|
@@ -147,6 +147,12 @@ export declare class TeamAgent {
|
|
|
147
147
|
* Tool profile name (for display)
|
|
148
148
|
*/
|
|
149
149
|
toolProfile?: TeamAgentConfig['toolProfile'];
|
|
150
|
+
/**
|
|
151
|
+
* Groups behind a `custom` profile. Needed because the capability blurb is now composed on
|
|
152
|
+
* every build rather than baked once, and a custom profile's blurb cannot be regenerated
|
|
153
|
+
* from the profile name alone.
|
|
154
|
+
*/
|
|
155
|
+
customGroups?: string[];
|
|
150
156
|
/**
|
|
151
157
|
* Enabled skills (empty = all skills)
|
|
152
158
|
*/
|
|
@@ -248,6 +254,25 @@ export declare class TeamAgent {
|
|
|
248
254
|
applyUpdate(patch: TeamAgentUpdate): {
|
|
249
255
|
rebuilt: boolean;
|
|
250
256
|
};
|
|
257
|
+
/**
|
|
258
|
+
* The generated half of the prompt, rebuilt from CURRENT state on every build.
|
|
259
|
+
*
|
|
260
|
+
* ⚠️ THIS IS WHY IT IS A METHOD AND NOT A STORED STRING. All three constructors used to bake
|
|
261
|
+
* these sections into `systemPromptAddition`, which broke three ways at once:
|
|
262
|
+
*
|
|
263
|
+
* 1. hosts render that field in a textarea, so users were shown generated prose to hand-edit
|
|
264
|
+
* (`fromRole('pm')` alone put 6,321 characters of role prompt in there) and their save
|
|
265
|
+
* froze it as if they had written it;
|
|
266
|
+
* 2. a custom agent's personality was baked in as `Your approach:` while an edit appended
|
|
267
|
+
* `Your manner:` — so editing it added a contradiction instead of changing it;
|
|
268
|
+
* 3. the capability blurb described whatever profile the agent had AT CREATION, so changing
|
|
269
|
+
* the tool profile updated the filter but left the prompt telling the agent it still had
|
|
270
|
+
* tools it no longer had.
|
|
271
|
+
*
|
|
272
|
+
* Composing here fixes all three: nothing generated is ever stored, and every section reflects
|
|
273
|
+
* the state at the moment the agent is built.
|
|
274
|
+
*/
|
|
275
|
+
private generatedPromptSections;
|
|
251
276
|
/**
|
|
252
277
|
* Initialize the agent with the given factory
|
|
253
278
|
* This allows the team to control agent creation
|
package/dist/team/team-agent.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { ROLE_METADATA } from './types.js';
|
|
11
11
|
import { getModelForTier, getModelContextWindow } from '../models/index.js';
|
|
12
|
-
import {
|
|
12
|
+
import { generateCustomAgentScaffold, getCustomAgentToolFilter, splitLegacyCustomPrompt, } from './custom-agents.js';
|
|
13
13
|
import { getToolsForProfile, PROFILE_INFO, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, } from './tool-config.js';
|
|
14
14
|
/**
|
|
15
15
|
* Estimate token count from text (approximate: ~4 chars per token)
|
|
@@ -145,6 +145,12 @@ export class TeamAgent {
|
|
|
145
145
|
* Tool profile name (for display)
|
|
146
146
|
*/
|
|
147
147
|
toolProfile;
|
|
148
|
+
/**
|
|
149
|
+
* Groups behind a `custom` profile. Needed because the capability blurb is now composed on
|
|
150
|
+
* every build rather than baked once, and a custom profile's blurb cannot be regenerated
|
|
151
|
+
* from the profile name alone.
|
|
152
|
+
*/
|
|
153
|
+
customGroups;
|
|
148
154
|
/**
|
|
149
155
|
* Enabled skills (empty = all skills)
|
|
150
156
|
*/
|
|
@@ -202,6 +208,7 @@ export class TeamAgent {
|
|
|
202
208
|
this.noTools = config.noTools;
|
|
203
209
|
this.toolFilter = config.toolFilter;
|
|
204
210
|
this.toolProfile = config.toolProfile;
|
|
211
|
+
this.customGroups = config.customGroups;
|
|
205
212
|
this.enabledSkills = config.enabledSkills;
|
|
206
213
|
this.personality = config.personality;
|
|
207
214
|
this.autoApproveHandoff = config.autoApproveHandoff;
|
|
@@ -341,6 +348,48 @@ export class TeamAgent {
|
|
|
341
348
|
this.stashForRebuild();
|
|
342
349
|
return { rebuilt: needsRebuild || tierChanged };
|
|
343
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* The generated half of the prompt, rebuilt from CURRENT state on every build.
|
|
353
|
+
*
|
|
354
|
+
* ⚠️ THIS IS WHY IT IS A METHOD AND NOT A STORED STRING. All three constructors used to bake
|
|
355
|
+
* these sections into `systemPromptAddition`, which broke three ways at once:
|
|
356
|
+
*
|
|
357
|
+
* 1. hosts render that field in a textarea, so users were shown generated prose to hand-edit
|
|
358
|
+
* (`fromRole('pm')` alone put 6,321 characters of role prompt in there) and their save
|
|
359
|
+
* froze it as if they had written it;
|
|
360
|
+
* 2. a custom agent's personality was baked in as `Your approach:` while an edit appended
|
|
361
|
+
* `Your manner:` — so editing it added a contradiction instead of changing it;
|
|
362
|
+
* 3. the capability blurb described whatever profile the agent had AT CREATION, so changing
|
|
363
|
+
* the tool profile updated the filter but left the prompt telling the agent it still had
|
|
364
|
+
* tools it no longer had.
|
|
365
|
+
*
|
|
366
|
+
* Composing here fixes all three: nothing generated is ever stored, and every section reflects
|
|
367
|
+
* the state at the moment the agent is built.
|
|
368
|
+
*/
|
|
369
|
+
generatedPromptSections() {
|
|
370
|
+
const sections = [];
|
|
371
|
+
if (this.role === 'custom') {
|
|
372
|
+
sections.push(generateCustomAgentScaffold(this.displayName, this.description ?? ''));
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
const roleScaffold = ROLE_METADATA[this.role].defaultSystemPromptAddition;
|
|
376
|
+
if (roleScaffold)
|
|
377
|
+
sections.push(roleScaffold);
|
|
378
|
+
}
|
|
379
|
+
// Capability blurb — from the live profile, never a baked copy (defect 3 above).
|
|
380
|
+
const profile = this.toolProfile;
|
|
381
|
+
if (profile && profile !== 'full') {
|
|
382
|
+
sections.push(generateToolAwarenessPrompt({ profile, customGroups: this.customGroups }));
|
|
383
|
+
}
|
|
384
|
+
// Delegation guidance. Custom agents never had it and still do not — this method reproduces
|
|
385
|
+
// what each constructor built, it does not redistribute behaviour between roles.
|
|
386
|
+
if (this.role !== 'custom') {
|
|
387
|
+
sections.push(this.role === 'default'
|
|
388
|
+
? generateCoordinatorGuidance()
|
|
389
|
+
: generateSpecialistGuidance(this.role));
|
|
390
|
+
}
|
|
391
|
+
return sections;
|
|
392
|
+
}
|
|
344
393
|
/**
|
|
345
394
|
* Initialize the agent with the given factory
|
|
346
395
|
* This allows the team to control agent creation
|
|
@@ -352,8 +401,13 @@ export class TeamAgent {
|
|
|
352
401
|
if (this._agent) {
|
|
353
402
|
return; // Already initialized
|
|
354
403
|
}
|
|
355
|
-
|
|
356
|
-
|
|
404
|
+
/*
|
|
405
|
+
Generated sections first, then the user's own words. `systemPromptAddition` holds ONLY what
|
|
406
|
+
the user typed — see `generatedPromptSections()` for why nothing generated is stored.
|
|
407
|
+
*/
|
|
408
|
+
let finalSystemPromptAddition = [...this.generatedPromptSections(), this.systemPromptAddition]
|
|
409
|
+
.filter((section) => Boolean(section?.trim()))
|
|
410
|
+
.join('\n\n');
|
|
357
411
|
// Identity preamble — every team agent gets a stable self-reference
|
|
358
412
|
// block at the top of its prompt addition. Without this, the agent
|
|
359
413
|
// knows it's "the PM" from the role prompt but doesn't connect that
|
|
@@ -575,6 +629,7 @@ export class TeamAgent {
|
|
|
575
629
|
noTools: this.noTools,
|
|
576
630
|
toolFilter: this.toolFilter,
|
|
577
631
|
toolProfile: this.toolProfile,
|
|
632
|
+
customGroups: this.customGroups,
|
|
578
633
|
enabledSkills: this.enabledSkills,
|
|
579
634
|
modelTier: this.modelTier,
|
|
580
635
|
autoApproveHandoff: this.autoApproveHandoff,
|
|
@@ -588,18 +643,46 @@ export class TeamAgent {
|
|
|
588
643
|
// Refresh tool filter from profile if available (ensures new tools are picked up)
|
|
589
644
|
// This handles the case where tools were added after the agent was created
|
|
590
645
|
const toolFilter = data.toolProfile ? getToolsForProfile(data.toolProfile) : data.toolFilter;
|
|
646
|
+
/*
|
|
647
|
+
MIGRATION — agents serialized before generated text was separated out.
|
|
648
|
+
Their `systemPromptAddition` holds the whole generated composite, because that is what the
|
|
649
|
+
constructors used to store. Recover the parts that are genuinely the user's.
|
|
650
|
+
|
|
651
|
+
⚠️ THE FAILURE MODE IS "CHANGE NOTHING", NEVER "GUESS". `splitLegacyCustomPrompt` returns an
|
|
652
|
+
empty result for anything it does not positively recognise, and we then keep the stored
|
|
653
|
+
string exactly as it is — which is the pre-migration behaviour. A generator that has since
|
|
654
|
+
changed wording costs one agent a stale prompt until its next edit; a clever guess would
|
|
655
|
+
cost the user the instructions they wrote.
|
|
656
|
+
|
|
657
|
+
Role agents are deliberately NOT migrated. Their stored string is generated in full, but an
|
|
658
|
+
edited one is indistinguishable from an unedited one, so anything removed might be the
|
|
659
|
+
user's. Their generated sections now compose on top of whatever is stored: a legacy role
|
|
660
|
+
agent shows its old prompt in the editor until someone clears it, and nothing is lost.
|
|
661
|
+
*/
|
|
662
|
+
let systemPromptAddition = data.systemPromptAddition;
|
|
663
|
+
let personality = data.personality;
|
|
664
|
+
if (data.role === 'custom' && systemPromptAddition) {
|
|
665
|
+
const legacy = splitLegacyCustomPrompt(systemPromptAddition);
|
|
666
|
+
if (legacy.userText !== undefined || legacy.personality !== undefined) {
|
|
667
|
+
systemPromptAddition = legacy.userText;
|
|
668
|
+
// Only rescue the baked personality when the live field never held one — a value set
|
|
669
|
+
// through the editor is newer than anything frozen in the prompt.
|
|
670
|
+
personality = personality ?? legacy.personality;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
591
673
|
const agent = new TeamAgent({
|
|
592
674
|
id: data.id,
|
|
593
675
|
displayName: data.displayName,
|
|
594
676
|
mascot: data.mascot,
|
|
595
677
|
role: data.role,
|
|
596
678
|
description: data.description,
|
|
597
|
-
systemPromptAddition
|
|
598
|
-
personality
|
|
679
|
+
systemPromptAddition,
|
|
680
|
+
personality,
|
|
599
681
|
useMinimalSystemPrompt: data.useMinimalSystemPrompt,
|
|
600
682
|
noTools: data.noTools,
|
|
601
683
|
toolFilter,
|
|
602
684
|
toolProfile: data.toolProfile,
|
|
685
|
+
customGroups: data.customGroups,
|
|
603
686
|
enabledSkills: data.enabledSkills,
|
|
604
687
|
modelTier: data.modelTier,
|
|
605
688
|
autoApproveHandoff: data.autoApproveHandoff,
|
|
@@ -619,36 +702,14 @@ export class TeamAgent {
|
|
|
619
702
|
// Get tool filter from default profile (if specified)
|
|
620
703
|
const profile = metadata.defaultToolProfile;
|
|
621
704
|
const toolFilter = profile ? getToolsForProfile(profile) : undefined;
|
|
622
|
-
//
|
|
623
|
-
|
|
624
|
-
if (profile && profile !== 'full') {
|
|
625
|
-
const toolAwareness = generateToolAwarenessPrompt({ profile });
|
|
626
|
-
systemPromptAddition = systemPromptAddition
|
|
627
|
-
? `${systemPromptAddition}\n\n${toolAwareness}`
|
|
628
|
-
: toolAwareness;
|
|
629
|
-
}
|
|
630
|
-
// Add delegation guidance based on role
|
|
631
|
-
if (role === 'default') {
|
|
632
|
-
// Coordinator gets delegation tool guidance
|
|
633
|
-
const coordinatorGuidance = generateCoordinatorGuidance();
|
|
634
|
-
systemPromptAddition = systemPromptAddition
|
|
635
|
-
? `${systemPromptAddition}\n\n${coordinatorGuidance}`
|
|
636
|
-
: coordinatorGuidance;
|
|
637
|
-
}
|
|
638
|
-
else {
|
|
639
|
-
// Specialists get collaboration guidance
|
|
640
|
-
const specialistGuidance = generateSpecialistGuidance(role);
|
|
641
|
-
systemPromptAddition = systemPromptAddition
|
|
642
|
-
? `${systemPromptAddition}\n\n${specialistGuidance}`
|
|
643
|
-
: specialistGuidance;
|
|
644
|
-
}
|
|
705
|
+
// The role prompt, capability blurb and delegation guidance are all generated, so they are
|
|
706
|
+
// composed at initialize() rather than stored. A fresh role agent has no user text at all.
|
|
645
707
|
return new TeamAgent({
|
|
646
708
|
id: id ?? role,
|
|
647
709
|
displayName: metadata.displayName,
|
|
648
710
|
mascot: metadata.mascot,
|
|
649
711
|
role,
|
|
650
712
|
description: metadata.description,
|
|
651
|
-
systemPromptAddition: systemPromptAddition || undefined,
|
|
652
713
|
useMinimalSystemPrompt: metadata.useMinimalSystemPrompt,
|
|
653
714
|
noTools: metadata.noTools,
|
|
654
715
|
toolFilter,
|
|
@@ -667,31 +728,15 @@ export class TeamAgent {
|
|
|
667
728
|
const metadata = ROLE_METADATA[baseRole];
|
|
668
729
|
const profile = opts.toolProfile ?? metadata.defaultToolProfile;
|
|
669
730
|
const toolFilter = profile ? getToolsForProfile(profile) : undefined;
|
|
670
|
-
//
|
|
671
|
-
|
|
672
|
-
if (opts.systemPromptAddition?.trim()) {
|
|
673
|
-
systemPromptAddition = systemPromptAddition
|
|
674
|
-
? `${systemPromptAddition}\n\n${opts.systemPromptAddition.trim()}`
|
|
675
|
-
: opts.systemPromptAddition.trim();
|
|
676
|
-
}
|
|
677
|
-
if (profile && profile !== 'full') {
|
|
678
|
-
const toolAwareness = generateToolAwarenessPrompt({ profile });
|
|
679
|
-
systemPromptAddition = systemPromptAddition
|
|
680
|
-
? `${systemPromptAddition}\n\n${toolAwareness}`
|
|
681
|
-
: toolAwareness;
|
|
682
|
-
}
|
|
683
|
-
// Specialists always get collaboration guidance (never the coordinator path).
|
|
684
|
-
const specialistGuidance = generateSpecialistGuidance(baseRole);
|
|
685
|
-
systemPromptAddition = systemPromptAddition
|
|
686
|
-
? `${systemPromptAddition}\n\n${specialistGuidance}`
|
|
687
|
-
: specialistGuidance;
|
|
731
|
+
// Only the specialist's own addition is authored text; the role prompt, capability blurb and
|
|
732
|
+
// collaboration guidance are generated and composed at initialize().
|
|
688
733
|
return new TeamAgent({
|
|
689
734
|
id: opts.id ?? baseRole,
|
|
690
735
|
displayName: opts.displayName ?? metadata.displayName,
|
|
691
736
|
mascot: metadata.mascot,
|
|
692
737
|
role: baseRole,
|
|
693
738
|
description: metadata.description,
|
|
694
|
-
systemPromptAddition: systemPromptAddition || undefined,
|
|
739
|
+
systemPromptAddition: opts.systemPromptAddition?.trim() || undefined,
|
|
695
740
|
useMinimalSystemPrompt: metadata.useMinimalSystemPrompt,
|
|
696
741
|
noTools: metadata.noTools,
|
|
697
742
|
toolFilter,
|
|
@@ -711,9 +756,16 @@ export class TeamAgent {
|
|
|
711
756
|
mascot: def.mascot,
|
|
712
757
|
role: 'custom',
|
|
713
758
|
description: def.specialty,
|
|
714
|
-
|
|
759
|
+
// The user's own words only — the identity and focus lines are composed at initialize().
|
|
760
|
+
systemPromptAddition: def.systemPromptAddition,
|
|
761
|
+
/* ⚠️ WITHOUT THIS an edit ADDS a second personality instead of changing the one in force:
|
|
762
|
+
the definition's value was baked into the prompt as `Your approach:` and never reached
|
|
763
|
+
the live field, so `updateAgent({ personality })` appended a contradicting `Your manner:`
|
|
764
|
+
while the original stayed active. */
|
|
765
|
+
personality: def.personality,
|
|
715
766
|
toolFilter, // Pass tool filter from custom agent config
|
|
716
767
|
toolProfile: def.toolConfig?.profile, // Store profile for display
|
|
768
|
+
customGroups: def.toolConfig?.customGroups,
|
|
717
769
|
enabledSkills: def.enabledSkills, // Store skills for display
|
|
718
770
|
modelTier: def.modelTier, // Store model tier
|
|
719
771
|
});
|
package/dist/team/types.d.ts
CHANGED
|
@@ -135,6 +135,8 @@ export interface TeamAgentConfig {
|
|
|
135
135
|
* Shows which profile was selected when creating the agent
|
|
136
136
|
*/
|
|
137
137
|
toolProfile?: ToolProfile;
|
|
138
|
+
/** Groups behind a `custom` profile — see TeamAgent.customGroups. */
|
|
139
|
+
customGroups?: string[];
|
|
138
140
|
/**
|
|
139
141
|
* Enabled skills for this agent
|
|
140
142
|
* Empty array means all skills, non-empty means filtered
|
|
@@ -173,6 +175,7 @@ export interface SerializedTeamAgent {
|
|
|
173
175
|
noTools?: boolean;
|
|
174
176
|
toolFilter?: string[];
|
|
175
177
|
toolProfile?: ToolProfile;
|
|
178
|
+
customGroups?: string[];
|
|
176
179
|
enabledSkills?: string[];
|
|
177
180
|
modelTier?: ModelTier;
|
|
178
181
|
autoApproveHandoff?: boolean;
|