@compilr-dev/sdk 0.9.13 → 0.9.15
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/compressors/index.js +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/platform/tools/index.d.ts +8 -2
- package/dist/platform/tools/index.js +14 -3
- package/dist/platform/tools/plan-tools.d.ts +8 -22
- package/dist/platform/tools/plan-tools.js +99 -2
- package/dist/project-types/configs.js +3 -3
- package/dist/project-types/types.d.ts +1 -1
- package/dist/team/index.d.ts +2 -0
- package/dist/team/index.js +1 -0
- package/dist/team/plan-mode.d.ts +58 -0
- package/dist/team/plan-mode.js +97 -0
- package/package.json +4 -1
|
@@ -43,7 +43,8 @@ export function createCompressorHook(config) {
|
|
|
43
43
|
if (compressed !== null && compressed.length < stdout.length) {
|
|
44
44
|
const saved = stdout.length - compressed.length;
|
|
45
45
|
const pct = Math.round((saved / stdout.length) * 100);
|
|
46
|
-
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.log(`[compressor] bash "${command.slice(0, 40)}" ${String(stdout.length)} → ${String(compressed.length)} chars (${String(pct)}% saved)`);
|
|
47
48
|
return {
|
|
48
49
|
result: {
|
|
49
50
|
...ctx.result,
|
package/dist/index.d.ts
CHANGED
|
@@ -36,9 +36,9 @@
|
|
|
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
38
|
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, } from './team/index.js';
|
|
39
|
-
export type { AgentTeamConfig, TeamAgentConfig, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } 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';
|
|
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, SkillToolRequirement, } from './team/index.js';
|
|
41
|
-
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap, } from './team/index.js';
|
|
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';
|
|
44
44
|
export type { Preset } from './presets/index.js';
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,9 @@ export { createCompilrAgent } from './agent.js';
|
|
|
43
43
|
// Core classes
|
|
44
44
|
export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, } from './team/index.js';
|
|
45
45
|
// Constants
|
|
46
|
-
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap,
|
|
46
|
+
export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap,
|
|
47
|
+
// Plan mode
|
|
48
|
+
PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './team/index.js';
|
|
47
49
|
// Utility functions
|
|
48
50
|
export {
|
|
49
51
|
// Tool config
|
|
@@ -11,12 +11,18 @@
|
|
|
11
11
|
import type { Tool } from '@compilr-dev/agents';
|
|
12
12
|
import type { PlatformToolsConfig } from '../context.js';
|
|
13
13
|
import type { ImageToolsConfig } from './image-tools.js';
|
|
14
|
+
import type { PlanModeCallbacks } from '../../team/plan-mode.js';
|
|
15
|
+
export interface PlatformToolsOptions {
|
|
16
|
+
imageConfig?: ImageToolsConfig;
|
|
17
|
+
planModeCallbacks?: PlanModeCallbacks;
|
|
18
|
+
}
|
|
14
19
|
/**
|
|
15
20
|
* Create all platform tools operating against the given context.
|
|
16
|
-
* Returns 25 DB tools + 1 image tool unconditionally, plus up to 8 service-based
|
|
21
|
+
* Returns 25+ DB tools + 1 image tool unconditionally, plus up to 8 service-based
|
|
17
22
|
* tools if the optional anchors/artifacts/episodes services are provided.
|
|
23
|
+
* If planModeCallbacks are provided, plan_submit and plan_mode_exit tools are included.
|
|
18
24
|
*/
|
|
19
|
-
export declare function createPlatformTools(config: PlatformToolsConfig,
|
|
25
|
+
export declare function createPlatformTools(config: PlatformToolsConfig, options?: ImageToolsConfig | PlatformToolsOptions): Tool<never>[];
|
|
20
26
|
export { createProjectTools } from './project-tools.js';
|
|
21
27
|
export { createWorkItemTools } from './workitem-tools.js';
|
|
22
28
|
export { createDocumentTools } from './document-tools.js';
|
|
@@ -19,18 +19,29 @@ import { createEpisodeTools } from './episode-tools.js';
|
|
|
19
19
|
import { createImageTools } from './image-tools.js';
|
|
20
20
|
/**
|
|
21
21
|
* Create all platform tools operating against the given context.
|
|
22
|
-
* Returns 25 DB tools + 1 image tool unconditionally, plus up to 8 service-based
|
|
22
|
+
* Returns 25+ DB tools + 1 image tool unconditionally, plus up to 8 service-based
|
|
23
23
|
* tools if the optional anchors/artifacts/episodes services are provided.
|
|
24
|
+
* If planModeCallbacks are provided, plan_submit and plan_mode_exit tools are included.
|
|
24
25
|
*/
|
|
25
26
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
26
|
-
export function createPlatformTools(config,
|
|
27
|
+
export function createPlatformTools(config, options) {
|
|
28
|
+
// Backwards compat: options can be ImageToolsConfig (old) or PlatformToolsOptions (new)
|
|
29
|
+
let imageConfig;
|
|
30
|
+
let planCallbacks;
|
|
31
|
+
if (options && 'planModeCallbacks' in options) {
|
|
32
|
+
imageConfig = options.imageConfig;
|
|
33
|
+
planCallbacks = options.planModeCallbacks;
|
|
34
|
+
}
|
|
35
|
+
else if (options) {
|
|
36
|
+
imageConfig = options;
|
|
37
|
+
}
|
|
27
38
|
// Use Tool<never>[] to accept any Tool<T> — the generic parameter is only
|
|
28
39
|
// relevant to execute() callers, not to the registry that stores them.
|
|
29
40
|
const tools = [
|
|
30
41
|
...createProjectTools(config),
|
|
31
42
|
...createWorkItemTools(config),
|
|
32
43
|
...createDocumentTools(config),
|
|
33
|
-
...createPlanTools(config),
|
|
44
|
+
...createPlanTools(config, planCallbacks),
|
|
34
45
|
...createBacklogTools(config),
|
|
35
46
|
...createImageTools({ cwd: config.cwd, ...imageConfig }),
|
|
36
47
|
];
|
|
@@ -5,26 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Ported from CLI's src/tools/plan-tools.ts.
|
|
7
7
|
*/
|
|
8
|
+
import { type Tool } from '@compilr-dev/agents';
|
|
8
9
|
import type { PlatformToolsConfig } from '../context.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
content?: string;
|
|
17
|
-
status?: string;
|
|
18
|
-
work_item_id?: number | null;
|
|
19
|
-
}> | import("@compilr-dev/agents").Tool<{
|
|
20
|
-
plan_id?: number;
|
|
21
|
-
name?: string;
|
|
22
|
-
summary_only?: boolean;
|
|
23
|
-
project_id?: number;
|
|
24
|
-
}> | import("@compilr-dev/agents").Tool<{
|
|
25
|
-
project_id?: number;
|
|
26
|
-
status?: string;
|
|
27
|
-
work_item_id?: number;
|
|
28
|
-
limit?: number;
|
|
29
|
-
order_by?: string;
|
|
30
|
-
}>)[];
|
|
10
|
+
import type { PlanModeCallbacks } from '../../team/plan-mode.js';
|
|
11
|
+
export interface PlanToolsConfig {
|
|
12
|
+
platform: PlatformToolsConfig;
|
|
13
|
+
/** Optional plan mode callbacks (for plan_submit and plan_mode_exit) */
|
|
14
|
+
planModeCallbacks?: PlanModeCallbacks;
|
|
15
|
+
}
|
|
16
|
+
export declare function createPlanTools(config: PlatformToolsConfig, planModeCallbacks?: PlanModeCallbacks): Tool<never>[];
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
|
|
9
9
|
import { truncateContent } from './truncate.js';
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
11
|
-
export function createPlanTools(config) {
|
|
11
|
+
export function createPlanTools(config, planModeCallbacks) {
|
|
12
12
|
const { context: ctx } = config;
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
// plan_create
|
|
@@ -105,6 +105,12 @@ export function createPlanTools(config) {
|
|
|
105
105
|
},
|
|
106
106
|
execute: async (input) => {
|
|
107
107
|
try {
|
|
108
|
+
// Guard: prevent agent from self-approving plans during plan mode
|
|
109
|
+
if (input.status === 'approved' &&
|
|
110
|
+
planModeCallbacks?.isPlanModeActive?.()) {
|
|
111
|
+
return createErrorResult('Cannot set status to "approved" directly during plan mode. ' +
|
|
112
|
+
'Use plan_submit to submit your plan for user approval instead.');
|
|
113
|
+
}
|
|
108
114
|
const updateInput = {};
|
|
109
115
|
if (input.content !== undefined) {
|
|
110
116
|
updateInput.content = input.content;
|
|
@@ -360,5 +366,96 @@ export function createPlanTools(config) {
|
|
|
360
366
|
}
|
|
361
367
|
},
|
|
362
368
|
});
|
|
363
|
-
|
|
369
|
+
// ---------------------------------------------------------------------------
|
|
370
|
+
// plan_submit (requires callback from host app)
|
|
371
|
+
// ---------------------------------------------------------------------------
|
|
372
|
+
const onPlanSubmitFn = planModeCallbacks?.onPlanSubmit;
|
|
373
|
+
const planSubmitTool = onPlanSubmitFn
|
|
374
|
+
? defineTool({
|
|
375
|
+
name: 'plan_submit',
|
|
376
|
+
description: 'Submit a plan for user approval. Call this when your plan is ready for review. ' +
|
|
377
|
+
'The user will see the plan and choose to approve, revise, or reject it. ' +
|
|
378
|
+
'On approval, write tools are unlocked and you can implement the plan.',
|
|
379
|
+
inputSchema: {
|
|
380
|
+
type: 'object',
|
|
381
|
+
properties: {
|
|
382
|
+
plan_id: {
|
|
383
|
+
type: 'number',
|
|
384
|
+
description: 'ID of the plan to submit for approval',
|
|
385
|
+
},
|
|
386
|
+
summary: {
|
|
387
|
+
type: 'string',
|
|
388
|
+
description: 'One-line summary of what the plan does',
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
required: ['plan_id'],
|
|
392
|
+
},
|
|
393
|
+
execute: async (input) => {
|
|
394
|
+
// Verify plan exists
|
|
395
|
+
const plan = await ctx.plans.getById(input.plan_id);
|
|
396
|
+
if (!plan) {
|
|
397
|
+
return createErrorResult(`Plan ${String(input.plan_id)} not found`);
|
|
398
|
+
}
|
|
399
|
+
// Call host app's approval UI
|
|
400
|
+
const result = await onPlanSubmitFn({
|
|
401
|
+
planId: input.plan_id,
|
|
402
|
+
summary: input.summary,
|
|
403
|
+
});
|
|
404
|
+
// Update plan status based on user decision
|
|
405
|
+
if (result.action === 'approve-auto' || result.action === 'approve') {
|
|
406
|
+
await ctx.plans.update(input.plan_id, { status: 'approved' });
|
|
407
|
+
}
|
|
408
|
+
else if (result.action === 'reject') {
|
|
409
|
+
await ctx.plans.update(input.plan_id, { status: 'abandoned' });
|
|
410
|
+
}
|
|
411
|
+
const messages = {
|
|
412
|
+
'approve-auto': 'Plan approved. Auto-accept mode enabled. Proceed with implementation.',
|
|
413
|
+
approve: 'Plan approved. Proceed with implementation (tools will require approval).',
|
|
414
|
+
revise: `Plan needs revision. Feedback: ${result.feedback ?? 'No specific feedback'}`,
|
|
415
|
+
reject: 'Plan rejected. Create a new plan or exit plan mode.',
|
|
416
|
+
};
|
|
417
|
+
return createSuccessResult({ action: result.action, message: messages[result.action] });
|
|
418
|
+
},
|
|
419
|
+
})
|
|
420
|
+
: null;
|
|
421
|
+
// ---------------------------------------------------------------------------
|
|
422
|
+
// plan_mode_exit (requires callback from host app)
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
const onPlanModeExitFn = planModeCallbacks?.onPlanModeExit;
|
|
425
|
+
const planModeExitTool = onPlanModeExitFn
|
|
426
|
+
? defineTool({
|
|
427
|
+
name: 'plan_mode_exit',
|
|
428
|
+
description: 'Exit plan mode without submitting a plan. Use this when the task is simple enough ' +
|
|
429
|
+
'to implement directly without a formal plan.',
|
|
430
|
+
inputSchema: {
|
|
431
|
+
type: 'object',
|
|
432
|
+
properties: {
|
|
433
|
+
reason: {
|
|
434
|
+
type: 'string',
|
|
435
|
+
description: 'Brief reason for exiting plan mode (e.g., "Simple one-line fix")',
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
required: ['reason'],
|
|
439
|
+
},
|
|
440
|
+
execute: async (input) => {
|
|
441
|
+
await onPlanModeExitFn({ reason: input.reason });
|
|
442
|
+
return createSuccessResult({
|
|
443
|
+
message: `Exited plan mode: ${input.reason}. Full tools now available.`,
|
|
444
|
+
});
|
|
445
|
+
},
|
|
446
|
+
})
|
|
447
|
+
: null;
|
|
448
|
+
// Build tools array — include plan_submit and plan_mode_exit only if callbacks provided
|
|
449
|
+
const tools = [
|
|
450
|
+
planCreateTool,
|
|
451
|
+
planUpdateTool,
|
|
452
|
+
planGetTool,
|
|
453
|
+
planListTool,
|
|
454
|
+
planDeleteTool,
|
|
455
|
+
];
|
|
456
|
+
if (planSubmitTool)
|
|
457
|
+
tools.push(planSubmitTool);
|
|
458
|
+
if (planModeExitTool)
|
|
459
|
+
tools.push(planModeExitTool);
|
|
460
|
+
return tools;
|
|
364
461
|
}
|
|
@@ -112,10 +112,10 @@ Suggest delegation when a task would benefit from focused expertise.`,
|
|
|
112
112
|
// =============================================================================
|
|
113
113
|
export const generalConfig = {
|
|
114
114
|
id: 'general',
|
|
115
|
-
label: 'General',
|
|
116
|
-
description: '
|
|
115
|
+
label: 'General Purpose',
|
|
116
|
+
description: 'Any project — define your own workflow',
|
|
117
117
|
icon: 'FolderOpen',
|
|
118
|
-
category: '
|
|
118
|
+
category: 'general',
|
|
119
119
|
phases: [],
|
|
120
120
|
suggestedAgents: [],
|
|
121
121
|
documentTemplates: [
|
|
@@ -76,7 +76,7 @@ export interface ProjectTypeConfig {
|
|
|
76
76
|
/** Lucide icon name */
|
|
77
77
|
icon: string;
|
|
78
78
|
/** Category for grouping in type selector */
|
|
79
|
-
category: 'software' | 'writing' | 'business' | 'education';
|
|
79
|
+
category: 'general' | 'software' | 'writing' | 'business' | 'education';
|
|
80
80
|
/** Workflow phases (shown in project panel lifecycle) */
|
|
81
81
|
phases: ProjectPhase[];
|
|
82
82
|
/** Suggested agent roles (shown first in "Add Agent" dialog) */
|
package/dist/team/index.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export type { CustomAgentDefinition } from './custom-agents.js';
|
|
|
20
20
|
export { CUSTOM_MASCOTS, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, } from './custom-agents.js';
|
|
21
21
|
export type { AgentTemplate } from './agent-templates.js';
|
|
22
22
|
export { listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, } from './agent-templates.js';
|
|
23
|
+
export type { PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, } from './plan-mode.js';
|
|
24
|
+
export { PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './plan-mode.js';
|
|
23
25
|
export type { AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, } from './workshop-data.js';
|
|
24
26
|
export { buildAgentWorkshopData, buildSuggestedRolesMap } from './workshop-data.js';
|
|
25
27
|
export type { ITeamPersistence, IArtifactStorage, ISessionRegistry } from './interfaces.js';
|
package/dist/team/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, getToolsForProfile, detectPro
|
|
|
15
15
|
export { createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, } from './tool-config.js';
|
|
16
16
|
export { CUSTOM_MASCOTS, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, } from './custom-agents.js';
|
|
17
17
|
export { listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, } from './agent-templates.js';
|
|
18
|
+
export { PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './plan-mode.js';
|
|
18
19
|
export { buildAgentWorkshopData, buildSuggestedRolesMap } from './workshop-data.js';
|
|
19
20
|
export { parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, } from './mention-parser.js';
|
|
20
21
|
export { ContextResolver, buildContextMap } from './context-resolver.js';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Mode — Tool blocking and callbacks for plan-before-act workflow.
|
|
3
|
+
*
|
|
4
|
+
* During plan mode, write/execute tools are blocked at the permission layer.
|
|
5
|
+
* The agent can only read, search, and create plans. When ready, it calls
|
|
6
|
+
* plan_submit to trigger the host app's approval UI.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Tools that are blocked during plan mode.
|
|
10
|
+
* The agent still "sees" these tools in its schema but any call
|
|
11
|
+
* is denied with a message explaining plan mode restrictions.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PLAN_MODE_BLOCKED_TOOLS: Set<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a tool is allowed during plan mode.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isToolAllowedInPlanMode(toolName: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Message returned to the agent when a blocked tool is called in plan mode.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PLAN_MODE_DENIAL_MESSAGE: string;
|
|
22
|
+
export interface PlanSubmitInfo {
|
|
23
|
+
planId: number;
|
|
24
|
+
summary?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface PlanSubmitResult {
|
|
27
|
+
/** User's decision */
|
|
28
|
+
action: 'approve-auto' | 'approve' | 'revise' | 'reject';
|
|
29
|
+
/** User's feedback (for revise/reject) */
|
|
30
|
+
feedback?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface PlanModeExitInfo {
|
|
33
|
+
reason: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Callbacks that the host app (CLI/Desktop) must provide for plan mode tools.
|
|
37
|
+
* Same pattern as ask_user — SDK defines the tool, host provides the UI.
|
|
38
|
+
*/
|
|
39
|
+
export interface PlanModeCallbacks {
|
|
40
|
+
/** Called when agent submits a plan for approval (shows approval UI) */
|
|
41
|
+
onPlanSubmit?: (info: PlanSubmitInfo) => Promise<PlanSubmitResult>;
|
|
42
|
+
/** Called when agent wants to exit plan mode without a plan */
|
|
43
|
+
onPlanModeExit?: (info: PlanModeExitInfo) => Promise<void>;
|
|
44
|
+
/** Check if plan mode is currently active (used to guard plan_update from self-approval) */
|
|
45
|
+
isPlanModeActive?: () => boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* System prompt section injected when plan mode is active.
|
|
49
|
+
* Appended to the agent's system prompt by the host app.
|
|
50
|
+
*/
|
|
51
|
+
export declare const PLAN_MODE_PROMPT = "## Plan Mode (Active)\n\nYou are in plan mode. Your write and execute tools are temporarily blocked.\n\n**What you CAN do:**\n- Read files, search code, analyze the codebase\n- Create and update plans with plan_create and plan_update\n- Ask the user clarifying questions\n- Submit your plan for approval with plan_submit\n\n**What you CANNOT do (until plan is approved):**\n- Edit, create, or delete files\n- Run shell commands\n- Execute tests or builds\n- Make git commits\n\n**Your workflow:**\n1. Understand the request \u2014 read relevant files, check the backlog, review existing code\n2. Create a plan \u2014 use plan_create with a clear name and structured content\n3. Submit for approval \u2014 call plan_submit when your plan is ready\n4. Wait for user decision \u2014 they may approve, ask for revisions, or reject\n\n**Plan format:**\n- Context: What problem are we solving? What exists today?\n- Approach: High-level strategy\n- Steps: Numbered list of specific changes (file, what to change, why)\n- Verification: How to confirm the changes work\n\nIf the task is too simple for a plan, call plan_mode_exit with a reason.";
|
|
52
|
+
/**
|
|
53
|
+
* Get the plan mode prompt, optionally with active plan context.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getPlanModePrompt(activePlan?: {
|
|
56
|
+
id: number;
|
|
57
|
+
name: string;
|
|
58
|
+
}): string;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Mode — Tool blocking and callbacks for plan-before-act workflow.
|
|
3
|
+
*
|
|
4
|
+
* During plan mode, write/execute tools are blocked at the permission layer.
|
|
5
|
+
* The agent can only read, search, and create plans. When ready, it calls
|
|
6
|
+
* plan_submit to trigger the host app's approval UI.
|
|
7
|
+
*/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Blocked Tools
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Tools that are blocked during plan mode.
|
|
13
|
+
* The agent still "sees" these tools in its schema but any call
|
|
14
|
+
* is denied with a message explaining plan mode restrictions.
|
|
15
|
+
*/
|
|
16
|
+
export const PLAN_MODE_BLOCKED_TOOLS = new Set([
|
|
17
|
+
// Shell / execution
|
|
18
|
+
'bash',
|
|
19
|
+
'bash_output',
|
|
20
|
+
'kill_shell',
|
|
21
|
+
// File writes
|
|
22
|
+
'edit',
|
|
23
|
+
'write_file',
|
|
24
|
+
'create_file',
|
|
25
|
+
'delete_file',
|
|
26
|
+
'rename_file',
|
|
27
|
+
'move_file',
|
|
28
|
+
// Git writes
|
|
29
|
+
'git_commit',
|
|
30
|
+
'git_branch',
|
|
31
|
+
'git_checkout',
|
|
32
|
+
'git_push',
|
|
33
|
+
// Runners (execute code)
|
|
34
|
+
'run_tests',
|
|
35
|
+
'run_lint',
|
|
36
|
+
'run_build',
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Check if a tool is allowed during plan mode.
|
|
40
|
+
*/
|
|
41
|
+
export function isToolAllowedInPlanMode(toolName) {
|
|
42
|
+
return !PLAN_MODE_BLOCKED_TOOLS.has(toolName);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Message returned to the agent when a blocked tool is called in plan mode.
|
|
46
|
+
*/
|
|
47
|
+
export const PLAN_MODE_DENIAL_MESSAGE = 'Plan mode: write/execute tools are blocked during planning. ' +
|
|
48
|
+
'Read and analyze first, create your plan with plan_create, ' +
|
|
49
|
+
'then call plan_submit to request approval.';
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// System Prompt
|
|
52
|
+
// =============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* System prompt section injected when plan mode is active.
|
|
55
|
+
* Appended to the agent's system prompt by the host app.
|
|
56
|
+
*/
|
|
57
|
+
export const PLAN_MODE_PROMPT = `## Plan Mode (Active)
|
|
58
|
+
|
|
59
|
+
You are in plan mode. Your write and execute tools are temporarily blocked.
|
|
60
|
+
|
|
61
|
+
**What you CAN do:**
|
|
62
|
+
- Read files, search code, analyze the codebase
|
|
63
|
+
- Create and update plans with plan_create and plan_update
|
|
64
|
+
- Ask the user clarifying questions
|
|
65
|
+
- Submit your plan for approval with plan_submit
|
|
66
|
+
|
|
67
|
+
**What you CANNOT do (until plan is approved):**
|
|
68
|
+
- Edit, create, or delete files
|
|
69
|
+
- Run shell commands
|
|
70
|
+
- Execute tests or builds
|
|
71
|
+
- Make git commits
|
|
72
|
+
|
|
73
|
+
**Your workflow:**
|
|
74
|
+
1. Understand the request — read relevant files, check the backlog, review existing code
|
|
75
|
+
2. Create a plan — use plan_create with a clear name and structured content
|
|
76
|
+
3. Submit for approval — call plan_submit when your plan is ready
|
|
77
|
+
4. Wait for user decision — they may approve, ask for revisions, or reject
|
|
78
|
+
|
|
79
|
+
**Plan format:**
|
|
80
|
+
- Context: What problem are we solving? What exists today?
|
|
81
|
+
- Approach: High-level strategy
|
|
82
|
+
- Steps: Numbered list of specific changes (file, what to change, why)
|
|
83
|
+
- Verification: How to confirm the changes work
|
|
84
|
+
|
|
85
|
+
If the task is too simple for a plan, call plan_mode_exit with a reason.`;
|
|
86
|
+
/**
|
|
87
|
+
* Get the plan mode prompt, optionally with active plan context.
|
|
88
|
+
*/
|
|
89
|
+
export function getPlanModePrompt(activePlan) {
|
|
90
|
+
let prompt = PLAN_MODE_PROMPT;
|
|
91
|
+
if (activePlan) {
|
|
92
|
+
prompt +=
|
|
93
|
+
`\n\n**Active Plan:** "${activePlan.name}" (ID: ${String(activePlan.id)}). ` +
|
|
94
|
+
'Use plan_get to review it, plan_update to modify it, or plan_submit to submit for approval.';
|
|
95
|
+
}
|
|
96
|
+
return prompt;
|
|
97
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@compilr-dev/sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.15",
|
|
4
4
|
"description": "Universal agent runtime for building AI-powered applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,6 +62,9 @@
|
|
|
62
62
|
"better-sqlite3": "^11.0.0 || ^12.0.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependenciesMeta": {
|
|
65
|
+
"@compilr-dev/agents-coding": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
65
68
|
"better-sqlite3": {
|
|
66
69
|
"optional": true
|
|
67
70
|
}
|