@compilr-dev/sdk 0.23.0 → 0.23.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/team/team-agent.d.ts +32 -0
- package/dist/team/team-agent.js +55 -0
- package/package.json +1 -1
|
@@ -13,6 +13,38 @@ 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
|
+
* Strip the composite a pre-0.23 `fromRole()` stored, so it is not composed a second time.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ WITHOUT THIS, EVERY ROLE AGENT CREATED BEFORE 0.23 SENDS ITS ROLE PROMPT TWICE. The first
|
|
20
|
+
* cut of this migration skipped role agents, reasoning that an edited stored prompt is
|
|
21
|
+
* indistinguishable from an unedited one so removing anything risks the user's text. True, and
|
|
22
|
+
* beside the point: the generated sections now compose on top of whatever is stored, so leaving
|
|
23
|
+
* the legacy copy in place duplicates it. Measured on a real `$arch`: 13,024 characters instead
|
|
24
|
+
* of ~6,900, with the role header and capability blurb appearing twice each.
|
|
25
|
+
*
|
|
26
|
+
* ⚠️ AND IT CANNOT WORK BY RECONSTRUCTION. The second cut rebuilt the old composite exactly and
|
|
27
|
+
* stripped it on an exact match. That matched 6 of 16 real agents. The capability blurb lists
|
|
28
|
+
* the profile's tool GROUPS as they stood on the day the agent was created — a `qa` agent saved
|
|
29
|
+
* before the profile gained `consult` carries a blurb nine characters shorter than today's, and
|
|
30
|
+
* no amount of care reproduces a list that has since changed.
|
|
31
|
+
*
|
|
32
|
+
* So this anchors on the two ends, which are stable, and ignores the drifting middle entirely:
|
|
33
|
+
*
|
|
34
|
+
* - the FIRST LINE must be the first line of generated content (the role header, or the
|
|
35
|
+
* guidance heading for roles with no role prompt of their own), and
|
|
36
|
+
* - the CURRENT guidance block must appear — it is always last, and unlike the tool blurb it
|
|
37
|
+
* is not derived from mutable configuration.
|
|
38
|
+
*
|
|
39
|
+
* Everything up to the end of that guidance is generated; whatever follows is the user's and is
|
|
40
|
+
* kept. If either anchor is missing the value is returned untouched, so hand-written text and a
|
|
41
|
+
* future rewording both fail safe: the agent keeps its duplication until someone clears the box,
|
|
42
|
+
* and nobody loses text they wrote.
|
|
43
|
+
*
|
|
44
|
+
* @returns the user's own remainder, `undefined` if the stored value was entirely generated, or
|
|
45
|
+
* `stored` unchanged when it is not recognisably a legacy composite.
|
|
46
|
+
*/
|
|
47
|
+
export declare function splitLegacyRolePrompt(stored: string, role: AgentRole): string | undefined;
|
|
16
48
|
/**
|
|
17
49
|
* The editable subset of an agent.
|
|
18
50
|
*
|
package/dist/team/team-agent.js
CHANGED
|
@@ -11,6 +11,58 @@ import { ROLE_METADATA } from './types.js';
|
|
|
11
11
|
import { getModelForTier, getModelContextWindow } from '../models/index.js';
|
|
12
12
|
import { generateCustomAgentScaffold, getCustomAgentToolFilter, splitLegacyCustomPrompt, } from './custom-agents.js';
|
|
13
13
|
import { getToolsForProfile, PROFILE_INFO, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, } from './tool-config.js';
|
|
14
|
+
/**
|
|
15
|
+
* Strip the composite a pre-0.23 `fromRole()` stored, so it is not composed a second time.
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ WITHOUT THIS, EVERY ROLE AGENT CREATED BEFORE 0.23 SENDS ITS ROLE PROMPT TWICE. The first
|
|
18
|
+
* cut of this migration skipped role agents, reasoning that an edited stored prompt is
|
|
19
|
+
* indistinguishable from an unedited one so removing anything risks the user's text. True, and
|
|
20
|
+
* beside the point: the generated sections now compose on top of whatever is stored, so leaving
|
|
21
|
+
* the legacy copy in place duplicates it. Measured on a real `$arch`: 13,024 characters instead
|
|
22
|
+
* of ~6,900, with the role header and capability blurb appearing twice each.
|
|
23
|
+
*
|
|
24
|
+
* ⚠️ AND IT CANNOT WORK BY RECONSTRUCTION. The second cut rebuilt the old composite exactly and
|
|
25
|
+
* stripped it on an exact match. That matched 6 of 16 real agents. The capability blurb lists
|
|
26
|
+
* the profile's tool GROUPS as they stood on the day the agent was created — a `qa` agent saved
|
|
27
|
+
* before the profile gained `consult` carries a blurb nine characters shorter than today's, and
|
|
28
|
+
* no amount of care reproduces a list that has since changed.
|
|
29
|
+
*
|
|
30
|
+
* So this anchors on the two ends, which are stable, and ignores the drifting middle entirely:
|
|
31
|
+
*
|
|
32
|
+
* - the FIRST LINE must be the first line of generated content (the role header, or the
|
|
33
|
+
* guidance heading for roles with no role prompt of their own), and
|
|
34
|
+
* - the CURRENT guidance block must appear — it is always last, and unlike the tool blurb it
|
|
35
|
+
* is not derived from mutable configuration.
|
|
36
|
+
*
|
|
37
|
+
* Everything up to the end of that guidance is generated; whatever follows is the user's and is
|
|
38
|
+
* kept. If either anchor is missing the value is returned untouched, so hand-written text and a
|
|
39
|
+
* future rewording both fail safe: the agent keeps its duplication until someone clears the box,
|
|
40
|
+
* and nobody loses text they wrote.
|
|
41
|
+
*
|
|
42
|
+
* @returns the user's own remainder, `undefined` if the stored value was entirely generated, or
|
|
43
|
+
* `stored` unchanged when it is not recognisably a legacy composite.
|
|
44
|
+
*/
|
|
45
|
+
export function splitLegacyRolePrompt(stored, role) {
|
|
46
|
+
/*
|
|
47
|
+
⚠️ TYPED AS TOTAL, NOT TOTAL AT RUNTIME. `role` is `AgentRole` to the compiler but arrives
|
|
48
|
+
from a JSON file on disk, so it can be any string — a role removed in a later version, or one
|
|
49
|
+
a fixture invented. The explicit `| undefined` is what makes the guard below legitimate
|
|
50
|
+
rather than "always falsy": lint reasons from the type, and the type is a claim about data
|
|
51
|
+
we do not control.
|
|
52
|
+
*/
|
|
53
|
+
const byRole = ROLE_METADATA;
|
|
54
|
+
const metadata = byRole[role];
|
|
55
|
+
if (!metadata)
|
|
56
|
+
return stored;
|
|
57
|
+
const guidance = role === 'default' ? generateCoordinatorGuidance() : generateSpecialistGuidance(role);
|
|
58
|
+
const generatedFirstLine = (metadata.defaultSystemPromptAddition || guidance).split('\n')[0];
|
|
59
|
+
if (stored.split('\n')[0] !== generatedFirstLine)
|
|
60
|
+
return stored;
|
|
61
|
+
const at = stored.lastIndexOf(guidance);
|
|
62
|
+
if (at === -1)
|
|
63
|
+
return stored;
|
|
64
|
+
return stored.slice(at + guidance.length).trim() || undefined;
|
|
65
|
+
}
|
|
14
66
|
/**
|
|
15
67
|
* Estimate token count from text (approximate: ~4 chars per token)
|
|
16
68
|
*/
|
|
@@ -670,6 +722,9 @@ export class TeamAgent {
|
|
|
670
722
|
personality = personality ?? legacy.personality;
|
|
671
723
|
}
|
|
672
724
|
}
|
|
725
|
+
else if (data.role !== 'custom' && systemPromptAddition) {
|
|
726
|
+
systemPromptAddition = splitLegacyRolePrompt(systemPromptAddition, data.role);
|
|
727
|
+
}
|
|
673
728
|
const agent = new TeamAgent({
|
|
674
729
|
id: data.id,
|
|
675
730
|
displayName: data.displayName,
|