@compilr-dev/sdk 0.10.17 → 0.10.18
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/handoff-orchestration.d.ts +124 -0
- package/dist/team/handoff-orchestration.js +128 -0
- package/dist/team/index.d.ts +2 -0
- package/dist/team/index.js +3 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -35,9 +35,9 @@
|
|
|
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, } from './team/index.js';
|
|
38
|
+
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, } from './team/index.js';
|
|
39
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';
|
|
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, SkillToolRequirement, } from './team/index.js';
|
|
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, 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';
|
|
43
43
|
export { codingPreset, readOnlyPreset, resolvePreset } from './presets/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, } from './team/index.js';
|
|
44
|
+
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, createDelegationStatusTool, createHandoffTool, buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, } 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
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff orchestration helpers.
|
|
3
|
+
*
|
|
4
|
+
* The `createHandoffTool` factory (delegation-tools.ts) covers the
|
|
5
|
+
* tool-side of handoffs: validation, one-hop enforcement, `team.recordHandoff`.
|
|
6
|
+
* What it does NOT cover is the post-turn orchestration pattern shared by
|
|
7
|
+
* all hosts that surface this tool — stashing the dispatched intent during
|
|
8
|
+
* the source agent's turn, picking it back up once the turn ends, and
|
|
9
|
+
* dispatching the task to the target agent.
|
|
10
|
+
*
|
|
11
|
+
* Hosts (CLI, Desktop) used to implement that pattern independently,
|
|
12
|
+
* which is exactly the kind of drift that produced the desktop's
|
|
13
|
+
* silent-stub bug. This module centralises:
|
|
14
|
+
*
|
|
15
|
+
* - **HandoffIntent** — the shape both hosts pass between "tool fired"
|
|
16
|
+
* and "source turn ended."
|
|
17
|
+
* - **buildHandoffTaskMessage** — canonical `[Handoff from $arch]\n\nTask:`
|
|
18
|
+
* format so the synthesised message the target receives is identical
|
|
19
|
+
* across hosts.
|
|
20
|
+
* - **validateHandoffIntent** — re-checks team state at dispatch time
|
|
21
|
+
* (target could have been removed between stash and pickup).
|
|
22
|
+
* - **HandoffStash** — optional convenience for hosts that have multiple
|
|
23
|
+
* independent conversations (Desktop). CLI's single-REPL pattern is
|
|
24
|
+
* simpler than this class warrants; it can use the type + helpers
|
|
25
|
+
* directly without the stash.
|
|
26
|
+
*
|
|
27
|
+
* Storage location is intentionally platform-shaped (CLI: one global,
|
|
28
|
+
* Desktop: per-conversation map) — only the *what* gets standardised,
|
|
29
|
+
* not the *where*.
|
|
30
|
+
*/
|
|
31
|
+
import type { AgentTeam } from './team.js';
|
|
32
|
+
/**
|
|
33
|
+
* The intent recorded when a specialist agent calls `handoff(...)`.
|
|
34
|
+
* Stashed during the source agent's turn, consumed when the turn ends so
|
|
35
|
+
* the target agent can be invoked with the task.
|
|
36
|
+
*
|
|
37
|
+
* `conversationId` is opaque to the SDK — hosts use it to scope stashed
|
|
38
|
+
* intents (Desktop's per-conversation map; CLI can use a constant like
|
|
39
|
+
* `'default'` because there's only one REPL session).
|
|
40
|
+
*/
|
|
41
|
+
export interface HandoffIntent {
|
|
42
|
+
/** Host-defined conversation key. Opaque to the SDK. */
|
|
43
|
+
conversationId: string;
|
|
44
|
+
/** Agent that called `handoff`. */
|
|
45
|
+
sourceAgentId: string;
|
|
46
|
+
/** Agent receiving the handoff. */
|
|
47
|
+
targetAgentId: string;
|
|
48
|
+
/** Task description passed verbatim to the target. */
|
|
49
|
+
task: string;
|
|
50
|
+
/** Optional reason text the source provided. */
|
|
51
|
+
reason?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build the synthesised user-style message handed to the target agent
|
|
55
|
+
* after a successful handoff. Wrapping the body with a `[Handoff from $X]`
|
|
56
|
+
* marker keeps the target oriented and gives future tooling a way to
|
|
57
|
+
* distinguish handoff-injected messages from direct user input.
|
|
58
|
+
*
|
|
59
|
+
* Format:
|
|
60
|
+
*
|
|
61
|
+
* [Handoff from $arch]
|
|
62
|
+
*
|
|
63
|
+
* Task: <verbatim task>
|
|
64
|
+
*
|
|
65
|
+
* Reason: <verbatim reason — omitted when absent>
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildHandoffTaskMessage(intent: HandoffIntent): string;
|
|
68
|
+
/**
|
|
69
|
+
* Result of `validateHandoffIntent`. A discriminated union so call sites
|
|
70
|
+
* can `if (!result.valid) ... result.reason`.
|
|
71
|
+
*/
|
|
72
|
+
export type HandoffValidationResult = {
|
|
73
|
+
valid: true;
|
|
74
|
+
} | {
|
|
75
|
+
valid: false;
|
|
76
|
+
reason: string;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Re-validate a stashed `HandoffIntent` against the current team state.
|
|
80
|
+
*
|
|
81
|
+
* The intent was validated by `createHandoffTool` at the moment the tool
|
|
82
|
+
* fired, but team state can change between stash and dispatch — an agent
|
|
83
|
+
* may have been removed, the team may have been swapped out, etc. Hosts
|
|
84
|
+
* should call this before invoking the target agent.
|
|
85
|
+
*
|
|
86
|
+
* Returns `{ valid: false, reason }` with a user-readable message when
|
|
87
|
+
* the intent is no longer dispatchable.
|
|
88
|
+
*/
|
|
89
|
+
export declare function validateHandoffIntent(team: AgentTeam, intent: HandoffIntent): HandoffValidationResult;
|
|
90
|
+
/**
|
|
91
|
+
* Per-conversation stash for `HandoffIntent`s. Hosts that manage multiple
|
|
92
|
+
* independent conversations (the Desktop app) can use this directly; the
|
|
93
|
+
* CLI's single-REPL pattern is simpler than this class warrants and can
|
|
94
|
+
* use plain fields on its shared-state object.
|
|
95
|
+
*
|
|
96
|
+
* Usage:
|
|
97
|
+
*
|
|
98
|
+
* // Inside the handoff tool's `onHandoff` adapter callback:
|
|
99
|
+
* stash.set({ conversationId, sourceAgentId, targetAgentId, task, reason });
|
|
100
|
+
*
|
|
101
|
+
* // After the source agent's turn ends:
|
|
102
|
+
* const intent = stash.consume(conversationId);
|
|
103
|
+
* if (intent) {
|
|
104
|
+
* const check = validateHandoffIntent(team, intent);
|
|
105
|
+
* if (check.valid) {
|
|
106
|
+
* await runTargetAgent(intent.targetAgentId, buildHandoffTaskMessage(intent));
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
*/
|
|
110
|
+
export declare class HandoffStash {
|
|
111
|
+
private readonly intents;
|
|
112
|
+
/** Stash an intent. Replaces any prior intent for the same conversation
|
|
113
|
+
* — only one handoff can be in flight per conversation at a time. */
|
|
114
|
+
set(intent: HandoffIntent): void;
|
|
115
|
+
/** Read without removing. Useful for "is there a handoff pending?" UI checks. */
|
|
116
|
+
peek(conversationId: string): HandoffIntent | undefined;
|
|
117
|
+
/** Read and remove. The normal post-turn pickup pattern. */
|
|
118
|
+
consume(conversationId: string): HandoffIntent | undefined;
|
|
119
|
+
/** Explicitly clear without consuming — used by error paths so a failed
|
|
120
|
+
* source turn doesn't leave a phantom intent for the next turn. */
|
|
121
|
+
clear(conversationId: string): void;
|
|
122
|
+
/** Whether a stashed intent exists for this conversation. */
|
|
123
|
+
has(conversationId: string): boolean;
|
|
124
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff orchestration helpers.
|
|
3
|
+
*
|
|
4
|
+
* The `createHandoffTool` factory (delegation-tools.ts) covers the
|
|
5
|
+
* tool-side of handoffs: validation, one-hop enforcement, `team.recordHandoff`.
|
|
6
|
+
* What it does NOT cover is the post-turn orchestration pattern shared by
|
|
7
|
+
* all hosts that surface this tool — stashing the dispatched intent during
|
|
8
|
+
* the source agent's turn, picking it back up once the turn ends, and
|
|
9
|
+
* dispatching the task to the target agent.
|
|
10
|
+
*
|
|
11
|
+
* Hosts (CLI, Desktop) used to implement that pattern independently,
|
|
12
|
+
* which is exactly the kind of drift that produced the desktop's
|
|
13
|
+
* silent-stub bug. This module centralises:
|
|
14
|
+
*
|
|
15
|
+
* - **HandoffIntent** — the shape both hosts pass between "tool fired"
|
|
16
|
+
* and "source turn ended."
|
|
17
|
+
* - **buildHandoffTaskMessage** — canonical `[Handoff from $arch]\n\nTask:`
|
|
18
|
+
* format so the synthesised message the target receives is identical
|
|
19
|
+
* across hosts.
|
|
20
|
+
* - **validateHandoffIntent** — re-checks team state at dispatch time
|
|
21
|
+
* (target could have been removed between stash and pickup).
|
|
22
|
+
* - **HandoffStash** — optional convenience for hosts that have multiple
|
|
23
|
+
* independent conversations (Desktop). CLI's single-REPL pattern is
|
|
24
|
+
* simpler than this class warrants; it can use the type + helpers
|
|
25
|
+
* directly without the stash.
|
|
26
|
+
*
|
|
27
|
+
* Storage location is intentionally platform-shaped (CLI: one global,
|
|
28
|
+
* Desktop: per-conversation map) — only the *what* gets standardised,
|
|
29
|
+
* not the *where*.
|
|
30
|
+
*/
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// Canonical task-message format
|
|
33
|
+
// =============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Build the synthesised user-style message handed to the target agent
|
|
36
|
+
* after a successful handoff. Wrapping the body with a `[Handoff from $X]`
|
|
37
|
+
* marker keeps the target oriented and gives future tooling a way to
|
|
38
|
+
* distinguish handoff-injected messages from direct user input.
|
|
39
|
+
*
|
|
40
|
+
* Format:
|
|
41
|
+
*
|
|
42
|
+
* [Handoff from $arch]
|
|
43
|
+
*
|
|
44
|
+
* Task: <verbatim task>
|
|
45
|
+
*
|
|
46
|
+
* Reason: <verbatim reason — omitted when absent>
|
|
47
|
+
*/
|
|
48
|
+
export function buildHandoffTaskMessage(intent) {
|
|
49
|
+
return intent.reason
|
|
50
|
+
? `[Handoff from $${intent.sourceAgentId}]\n\nTask: ${intent.task}\n\nReason: ${intent.reason}`
|
|
51
|
+
: `[Handoff from $${intent.sourceAgentId}]\n\nTask: ${intent.task}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Re-validate a stashed `HandoffIntent` against the current team state.
|
|
55
|
+
*
|
|
56
|
+
* The intent was validated by `createHandoffTool` at the moment the tool
|
|
57
|
+
* fired, but team state can change between stash and dispatch — an agent
|
|
58
|
+
* may have been removed, the team may have been swapped out, etc. Hosts
|
|
59
|
+
* should call this before invoking the target agent.
|
|
60
|
+
*
|
|
61
|
+
* Returns `{ valid: false, reason }` with a user-readable message when
|
|
62
|
+
* the intent is no longer dispatchable.
|
|
63
|
+
*/
|
|
64
|
+
export function validateHandoffIntent(team, intent) {
|
|
65
|
+
if (!team.has(intent.targetAgentId)) {
|
|
66
|
+
return {
|
|
67
|
+
valid: false,
|
|
68
|
+
reason: `Agent '${intent.targetAgentId}' no longer exists in team.`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (!team.has(intent.sourceAgentId)) {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
reason: `Source agent '${intent.sourceAgentId}' no longer exists in team.`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return { valid: true };
|
|
78
|
+
}
|
|
79
|
+
// =============================================================================
|
|
80
|
+
// Optional stash for multi-conversation hosts (Desktop)
|
|
81
|
+
// =============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* Per-conversation stash for `HandoffIntent`s. Hosts that manage multiple
|
|
84
|
+
* independent conversations (the Desktop app) can use this directly; the
|
|
85
|
+
* CLI's single-REPL pattern is simpler than this class warrants and can
|
|
86
|
+
* use plain fields on its shared-state object.
|
|
87
|
+
*
|
|
88
|
+
* Usage:
|
|
89
|
+
*
|
|
90
|
+
* // Inside the handoff tool's `onHandoff` adapter callback:
|
|
91
|
+
* stash.set({ conversationId, sourceAgentId, targetAgentId, task, reason });
|
|
92
|
+
*
|
|
93
|
+
* // After the source agent's turn ends:
|
|
94
|
+
* const intent = stash.consume(conversationId);
|
|
95
|
+
* if (intent) {
|
|
96
|
+
* const check = validateHandoffIntent(team, intent);
|
|
97
|
+
* if (check.valid) {
|
|
98
|
+
* await runTargetAgent(intent.targetAgentId, buildHandoffTaskMessage(intent));
|
|
99
|
+
* }
|
|
100
|
+
* }
|
|
101
|
+
*/
|
|
102
|
+
export class HandoffStash {
|
|
103
|
+
intents = new Map();
|
|
104
|
+
/** Stash an intent. Replaces any prior intent for the same conversation
|
|
105
|
+
* — only one handoff can be in flight per conversation at a time. */
|
|
106
|
+
set(intent) {
|
|
107
|
+
this.intents.set(intent.conversationId, intent);
|
|
108
|
+
}
|
|
109
|
+
/** Read without removing. Useful for "is there a handoff pending?" UI checks. */
|
|
110
|
+
peek(conversationId) {
|
|
111
|
+
return this.intents.get(conversationId);
|
|
112
|
+
}
|
|
113
|
+
/** Read and remove. The normal post-turn pickup pattern. */
|
|
114
|
+
consume(conversationId) {
|
|
115
|
+
const intent = this.intents.get(conversationId);
|
|
116
|
+
this.intents.delete(conversationId);
|
|
117
|
+
return intent;
|
|
118
|
+
}
|
|
119
|
+
/** Explicitly clear without consuming — used by error paths so a failed
|
|
120
|
+
* source turn doesn't leave a phantom intent for the next turn. */
|
|
121
|
+
clear(conversationId) {
|
|
122
|
+
this.intents.delete(conversationId);
|
|
123
|
+
}
|
|
124
|
+
/** Whether a stashed intent exists for this conversation. */
|
|
125
|
+
has(conversationId) {
|
|
126
|
+
return this.intents.has(conversationId);
|
|
127
|
+
}
|
|
128
|
+
}
|
package/dist/team/index.d.ts
CHANGED
|
@@ -40,3 +40,5 @@ export { SKILL_REQUIREMENTS, getDefinedSkillNames, getSkillRequirements, checkSk
|
|
|
40
40
|
export { resolveAgentIdCollision } from './collision-utils.js';
|
|
41
41
|
export { createDelegationStatusTool, createHandoffTool } from './delegation-tools.js';
|
|
42
42
|
export type { HandoffResult, HandoffToolConfig } from './delegation-tools.js';
|
|
43
|
+
export { buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, } from './handoff-orchestration.js';
|
|
44
|
+
export type { HandoffIntent, HandoffValidationResult } from './handoff-orchestration.js';
|
package/dist/team/index.js
CHANGED
|
@@ -33,3 +33,6 @@ export { SKILL_REQUIREMENTS, getDefinedSkillNames, getSkillRequirements, checkSk
|
|
|
33
33
|
export { resolveAgentIdCollision } from './collision-utils.js';
|
|
34
34
|
// Delegation & Handoff tools (factory functions)
|
|
35
35
|
export { createDelegationStatusTool, createHandoffTool } from './delegation-tools.js';
|
|
36
|
+
// Handoff orchestration helpers — shared between CLI and Desktop for the
|
|
37
|
+
// post-turn stash/dispatch pattern. See handoff-orchestration.ts header.
|
|
38
|
+
export { buildHandoffTaskMessage, validateHandoffIntent, HandoffStash, } from './handoff-orchestration.js';
|