@compilr-dev/sdk 0.20.1 → 0.20.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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/team/index.d.ts +1 -1
- package/dist/team/index.js +1 -1
- package/dist/team/team-agent.d.ts +30 -4
- package/dist/team/team-agent.js +69 -21
- package/dist/team/team.js +11 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
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, isNarrowing, } 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, lostWriteAccess, } from './team/index.js';
|
|
39
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';
|
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, isNarrowing, } 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, lostWriteAccess, } 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,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { AgentTeam } from './team.js';
|
|
8
8
|
export type { AgentTeamConfig } from './team.js';
|
|
9
|
-
export { TeamAgent, isNarrowing } from './team-agent.js';
|
|
9
|
+
export { TeamAgent, isNarrowing, lostWriteAccess } from './team-agent.js';
|
|
10
10
|
export type { TeamAgentUpdate, AgentUpdateResult } from './team-agent.js';
|
|
11
11
|
export { SharedContextManager } from './shared-context.js';
|
|
12
12
|
export type { SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry, TeamActivity, TeamActivityType, SharedDecision, TokenBudget, SerializedSharedContext, } from './shared-context.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, isNarrowing } from './team-agent.js';
|
|
9
|
+
export { TeamAgent, isNarrowing, lostWriteAccess } 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';
|
|
@@ -49,17 +49,43 @@ export interface AgentUpdateResult {
|
|
|
49
49
|
* ability to write files is worth more than the row it costs.
|
|
50
50
|
*/
|
|
51
51
|
toolsNarrowed: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* ⚠️ NARROWER THAN `toolsNarrowed`, and the host needs both. "Fewer tools" and "cannot
|
|
54
|
+
* write any more" are different facts; a transcript saying "it can no longer change files"
|
|
55
|
+
* when six tools were dropped is a false statement in the record.
|
|
56
|
+
*/
|
|
57
|
+
lostWriteAccess: boolean;
|
|
52
58
|
previousProfile?: TeamAgentConfig['toolProfile'];
|
|
53
59
|
newProfile?: TeamAgentConfig['toolProfile'];
|
|
54
60
|
}
|
|
55
61
|
/**
|
|
56
|
-
* Did the
|
|
62
|
+
* Did the agent's reach get strictly smaller?
|
|
63
|
+
*
|
|
64
|
+
* ⚠️ TWO TESTS, NOT ONE, and the first version had only half of the first.
|
|
65
|
+
*
|
|
66
|
+
* Losing the ability to WRITE is the narrowing that matters most, so a move into a read-only
|
|
67
|
+
* profile counts however the tool counts land. But it is not the only one: `full` → `custom`
|
|
68
|
+
* with no groups is total tool removal — the largest narrowing there is — and neither profile
|
|
69
|
+
* is read-only, so a read-only test alone called it no change at all.
|
|
57
70
|
*
|
|
58
|
-
* ⚠️
|
|
59
|
-
*
|
|
60
|
-
*
|
|
71
|
+
* ⚠️ `undefined` IS NOT "UNKNOWN". `initialize` passes `toolFilter` straight to the factory,
|
|
72
|
+
* and an absent filter means NO filter — every tool. So `undefined` → `read-only` is the
|
|
73
|
+
* maximal narrowing, and the original returned false for it. My own test asserted exactly
|
|
74
|
+
* that under the name "says nothing when either side is unknown", which is how it survived:
|
|
75
|
+
* the suite encoded the defect as intended behaviour.
|
|
61
76
|
*/
|
|
62
77
|
export declare function isNarrowing(before: TeamAgentConfig['toolProfile'], after: TeamAgentConfig['toolProfile']): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Did the agent specifically lose the ability to change files?
|
|
80
|
+
*
|
|
81
|
+
* ⚠️ A NARROWER QUESTION THAN `isNarrowing`, and the host needs both. "Fewer tools" and
|
|
82
|
+
* "cannot write any more" are different facts, and a notice that says "it can no longer
|
|
83
|
+
* change files" when the agent merely dropped six tools is a false statement in the
|
|
84
|
+
* transcript — exactly the class of error this whole review found.
|
|
85
|
+
*/
|
|
86
|
+
export declare function lostWriteAccess(before: TeamAgentConfig['toolProfile'], after: TeamAgentConfig['toolProfile']): boolean;
|
|
87
|
+
/** Is this a profile the registry actually knows? Used to refuse bad IPC data. */
|
|
88
|
+
export declare function isKnownProfile(p: unknown): p is NonNullable<TeamAgentConfig['toolProfile']>;
|
|
63
89
|
/**
|
|
64
90
|
* TeamAgent wraps an Agent instance with team-specific metadata
|
|
65
91
|
*/
|
package/dist/team/team-agent.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { ROLE_METADATA } from './types.js';
|
|
11
11
|
import { getModelForTier, getModelContextWindow } from '../models/index.js';
|
|
12
12
|
import { generateCustomAgentSystemPrompt, getCustomAgentToolFilter } from './custom-agents.js';
|
|
13
|
-
import { getToolsForProfile, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, } from './tool-config.js';
|
|
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)
|
|
16
16
|
*/
|
|
@@ -18,34 +18,64 @@ function estimateTokens(text) {
|
|
|
18
18
|
return Math.ceil(text.length / 4);
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Did the
|
|
21
|
+
* Did the agent's reach get strictly smaller?
|
|
22
22
|
*
|
|
23
|
-
* ⚠️
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* ⚠️ TWO TESTS, NOT ONE, and the first version had only half of the first.
|
|
24
|
+
*
|
|
25
|
+
* Losing the ability to WRITE is the narrowing that matters most, so a move into a read-only
|
|
26
|
+
* profile counts however the tool counts land. But it is not the only one: `full` → `custom`
|
|
27
|
+
* with no groups is total tool removal — the largest narrowing there is — and neither profile
|
|
28
|
+
* is read-only, so a read-only test alone called it no change at all.
|
|
29
|
+
*
|
|
30
|
+
* ⚠️ `undefined` IS NOT "UNKNOWN". `initialize` passes `toolFilter` straight to the factory,
|
|
31
|
+
* and an absent filter means NO filter — every tool. So `undefined` → `read-only` is the
|
|
32
|
+
* maximal narrowing, and the original returned false for it. My own test asserted exactly
|
|
33
|
+
* that under the name "says nothing when either side is unknown", which is how it survived:
|
|
34
|
+
* the suite encoded the defect as intended behaviour.
|
|
26
35
|
*/
|
|
27
36
|
export function isNarrowing(before, after) {
|
|
28
37
|
if (before === after)
|
|
29
38
|
return false;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
39
|
+
const couldWrite = before === undefined || !isReadOnlyProfile(before);
|
|
40
|
+
const canWrite = after === undefined || !isReadOnlyProfile(after);
|
|
41
|
+
if (couldWrite && !canWrite)
|
|
42
|
+
return true;
|
|
43
|
+
// Otherwise compare what it may actually reach — `undefined` is every tool.
|
|
44
|
+
return toolReach(after) < toolReach(before);
|
|
33
45
|
}
|
|
34
46
|
/**
|
|
35
|
-
*
|
|
47
|
+
* Did the agent specifically lose the ability to change files?
|
|
36
48
|
*
|
|
37
|
-
* ⚠️
|
|
38
|
-
* cannot
|
|
49
|
+
* ⚠️ A NARROWER QUESTION THAN `isNarrowing`, and the host needs both. "Fewer tools" and
|
|
50
|
+
* "cannot write any more" are different facts, and a notice that says "it can no longer
|
|
51
|
+
* change files" when the agent merely dropped six tools is a false statement in the
|
|
52
|
+
* transcript — exactly the class of error this whole review found.
|
|
39
53
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
export function lostWriteAccess(before, after) {
|
|
55
|
+
if (before === after)
|
|
56
|
+
return false;
|
|
57
|
+
const couldWrite = before === undefined || !isReadOnlyProfile(before);
|
|
58
|
+
const canWrite = after === undefined || !isReadOnlyProfile(after);
|
|
59
|
+
return couldWrite && !canWrite;
|
|
60
|
+
}
|
|
61
|
+
/*
|
|
62
|
+
⚠️ NO DEFENSIVE LOOKUP HERE — the profile is validated at the boundary instead.
|
|
63
|
+
`PROFILE_INFO` is a total Record over `ToolProfile`, so a guard here is dead code by the
|
|
64
|
+
type system's reckoning and ESLint says so. The real risk is a bogus string arriving over
|
|
65
|
+
IPC, and the honest place to refuse that is once, on the way in, rather than to absorb it
|
|
66
|
+
silently at every reader. See `isKnownProfile` and its use in `updateAgent`.
|
|
67
|
+
*/
|
|
68
|
+
const isReadOnlyProfile = (p) => PROFILE_INFO[p].isReadOnly;
|
|
69
|
+
/** Is this a profile the registry actually knows? Used to refuse bad IPC data. */
|
|
70
|
+
export function isKnownProfile(p) {
|
|
71
|
+
return typeof p === 'string' && Object.prototype.hasOwnProperty.call(PROFILE_INFO, p);
|
|
72
|
+
}
|
|
73
|
+
/** How many tools a profile grants. `undefined` means no filter, i.e. all of them. */
|
|
74
|
+
function toolReach(p) {
|
|
75
|
+
if (p === undefined)
|
|
76
|
+
return Number.POSITIVE_INFINITY;
|
|
77
|
+
return getToolsForProfile(p).length;
|
|
78
|
+
}
|
|
49
79
|
/** Order-insensitive comparison — a reordered skill list is not a change. */
|
|
50
80
|
function sameStrings(a, b) {
|
|
51
81
|
if (a === undefined || b === undefined)
|
|
@@ -269,8 +299,26 @@ export class TeamAgent {
|
|
|
269
299
|
this.description = patch.description;
|
|
270
300
|
if (patch.systemPromptAddition !== undefined)
|
|
271
301
|
this.systemPromptAddition = patch.systemPromptAddition;
|
|
272
|
-
|
|
302
|
+
/*
|
|
303
|
+
⚠️ THE PROFILE IS A LABEL; `toolFilter` IS THE ENFORCEMENT. `initialize()` passes
|
|
304
|
+
`toolFilter` to the factory and never looks at `toolProfile`, so setting the profile
|
|
305
|
+
alone changed the word on screen and nothing else: an agent switched to `read-only`
|
|
306
|
+
kept `write_file` and 168 other tools, while `toolsNarrowed` truthfully reported that
|
|
307
|
+
its reach had shrunk. A security control that confirms and does not engage.
|
|
308
|
+
|
|
309
|
+
All four CONSTRUCTION sites already derive it — `fromSerialized`, `fromRole`,
|
|
310
|
+
`fromSpecialist`, `fromCustomDefinition` — which is why a restart applied the
|
|
311
|
+
restriction the running session had ignored, and why creating a read-only agent was
|
|
312
|
+
correct all along. Update was the only path that did not.
|
|
313
|
+
|
|
314
|
+
An explicit `toolFilter` still wins: `custom` profiles carry their own list.
|
|
315
|
+
*/
|
|
316
|
+
if (patch.toolProfile !== undefined) {
|
|
273
317
|
this.toolProfile = patch.toolProfile;
|
|
318
|
+
if (patch.toolFilter === undefined) {
|
|
319
|
+
this.toolFilter = getToolsForProfile(patch.toolProfile);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
274
322
|
if (patch.toolFilter !== undefined)
|
|
275
323
|
this.toolFilter = patch.toolFilter;
|
|
276
324
|
if (patch.enabledSkills !== undefined)
|
package/dist/team/team.js
CHANGED
|
@@ -11,7 +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
|
+
import { isNarrowing, isKnownProfile, lostWriteAccess } from './team-agent.js';
|
|
15
15
|
import { resolveAgentIdCollision } from './collision-utils.js';
|
|
16
16
|
/**
|
|
17
17
|
* AgentTeam orchestrates multiple persistent agents
|
|
@@ -339,6 +339,14 @@ export class AgentTeam {
|
|
|
339
339
|
throw new Error(`Agent id is immutable — '${id}' cannot be renamed. Duplicate the agent instead: ` +
|
|
340
340
|
'mention handles are written into stored message text and cannot be migrated.');
|
|
341
341
|
}
|
|
342
|
+
/*
|
|
343
|
+
⚠️ An unknown profile would otherwise be absorbed silently: `getToolsForProfile` returns
|
|
344
|
+
nothing for it, so the agent would end up with an empty filter — every tool removed —
|
|
345
|
+
while the UI showed whatever string was sent. Refuse it here, once.
|
|
346
|
+
*/
|
|
347
|
+
if (patch.toolProfile !== undefined && !isKnownProfile(patch.toolProfile)) {
|
|
348
|
+
throw new Error(`Unknown tool profile '${String(patch.toolProfile)}'`);
|
|
349
|
+
}
|
|
342
350
|
const previousProfile = agent.toolProfile;
|
|
343
351
|
const { rebuilt } = agent.applyUpdate(patch);
|
|
344
352
|
if (rebuilt) {
|
|
@@ -352,6 +360,8 @@ export class AgentTeam {
|
|
|
352
360
|
return {
|
|
353
361
|
rebuilt,
|
|
354
362
|
toolsNarrowed: isNarrowing(previousProfile, agent.toolProfile),
|
|
363
|
+
/* ⚠️ The narrower fact, so the host can word the notice truthfully. */
|
|
364
|
+
lostWriteAccess: lostWriteAccess(previousProfile, agent.toolProfile),
|
|
355
365
|
previousProfile,
|
|
356
366
|
newProfile: agent.toolProfile,
|
|
357
367
|
};
|