@pi-unipi/subagents 2.4.0 → 2.5.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/README.md +3 -1
- package/dist/agent-manager.d.ts +81 -0
- package/dist/agent-manager.d.ts.map +1 -0
- package/dist/agent-manager.js +292 -0
- package/dist/agent-manager.js.map +1 -0
- package/dist/agent-runner.d.ts +51 -0
- package/dist/agent-runner.d.ts.map +1 -0
- package/dist/agent-runner.js +262 -0
- package/dist/agent-runner.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +132 -0
- package/dist/config.js.map +1 -0
- package/dist/conversation-viewer.d.ts +40 -0
- package/dist/conversation-viewer.d.ts.map +1 -0
- package/dist/conversation-viewer.js +276 -0
- package/dist/conversation-viewer.js.map +1 -0
- package/dist/core-compat.d.ts +14 -0
- package/dist/core-compat.d.ts.map +1 -0
- package/dist/core-compat.js +24 -0
- package/dist/core-compat.js.map +1 -0
- package/dist/custom-agents.d.ts +14 -0
- package/dist/custom-agents.d.ts.map +1 -0
- package/dist/custom-agents.js +106 -0
- package/dist/custom-agents.js.map +1 -0
- package/dist/file-lock.d.ts +42 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +91 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +751 -0
- package/dist/index.js.map +1 -0
- package/dist/model-resolver.d.ts +19 -0
- package/dist/model-resolver.d.ts.map +1 -0
- package/dist/model-resolver.js +61 -0
- package/dist/model-resolver.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/dist/widget.d.ts +56 -0
- package/dist/widget.d.ts.map +1 -0
- package/dist/widget.js +396 -0
- package/dist/widget.js.map +1 -0
- package/package.json +10 -6
- package/src/__tests__/badge-generation.test.ts +0 -315
- package/src/__tests__/config.test.ts +0 -240
- package/src/__tests__/esc-propagation.test.ts +0 -162
- package/src/__tests__/file-lock.test.ts +0 -244
- package/src/__tests__/shutdown-stale-ctx.test.ts +0 -185
- package/src/__tests__/workflow-integration.test.ts +0 -334
- package/src/agent-manager.ts +0 -334
- package/src/agent-runner.ts +0 -329
- package/src/config.ts +0 -147
- package/src/conversation-viewer.ts +0 -299
- package/src/custom-agents.ts +0 -118
- package/src/file-lock.ts +0 -102
- package/src/index.ts +0 -862
- package/src/model-resolver.ts +0 -79
- package/src/prompts.ts +0 -39
- package/src/skills/explore/SKILL.md +0 -32
- package/src/skills/work/SKILL.md +0 -40
- package/src/types.ts +0 -146
- package/src/widget.ts +0 -454
- package/tsconfig.json +0 -19
package/src/model-resolver.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @pi-unipi/subagents — Model resolver
|
|
3
|
-
*
|
|
4
|
-
* Resolves model strings like "haiku", "sonnet", "anthropic/claude-sonnet-4-6"
|
|
5
|
-
* to actual Model instances using the registry.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Model } from "@earendil-works/pi-ai";
|
|
9
|
-
|
|
10
|
-
export interface ModelRegistry {
|
|
11
|
-
find(provider: string, modelId: string): Model<any> | undefined;
|
|
12
|
-
getAll(): Model<any>[];
|
|
13
|
-
getAvailable?(): Model<any>[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Resolve a model string to a Model instance.
|
|
18
|
-
* Tries exact match first, then fuzzy match.
|
|
19
|
-
* Returns Model on success, error string on failure.
|
|
20
|
-
*/
|
|
21
|
-
export function resolveModel(
|
|
22
|
-
input: string,
|
|
23
|
-
registry: ModelRegistry,
|
|
24
|
-
): Model<any> | string {
|
|
25
|
-
const all = (registry.getAvailable?.() ?? registry.getAll()) as Array<{
|
|
26
|
-
id: string;
|
|
27
|
-
name?: string;
|
|
28
|
-
provider: string;
|
|
29
|
-
}>;
|
|
30
|
-
const availableSet = new Set(all.map((m) => `${m.provider}/${m.id}`.toLowerCase()));
|
|
31
|
-
|
|
32
|
-
// 1. Exact match: "provider/modelId"
|
|
33
|
-
const slashIdx = input.indexOf("/");
|
|
34
|
-
if (slashIdx !== -1) {
|
|
35
|
-
const provider = input.slice(0, slashIdx);
|
|
36
|
-
const modelId = input.slice(slashIdx + 1);
|
|
37
|
-
if (availableSet.has(input.toLowerCase())) {
|
|
38
|
-
const found = registry.find(provider, modelId);
|
|
39
|
-
if (found) return found;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 2. Fuzzy match
|
|
44
|
-
const query = input.toLowerCase();
|
|
45
|
-
let bestMatch: (typeof all)[number] | undefined;
|
|
46
|
-
let bestScore = 0;
|
|
47
|
-
|
|
48
|
-
for (const m of all) {
|
|
49
|
-
const id = m.id.toLowerCase();
|
|
50
|
-
const name = (m.name ?? m.id).toLowerCase();
|
|
51
|
-
const full = `${m.provider}/${m.id}`.toLowerCase();
|
|
52
|
-
|
|
53
|
-
let score = 0;
|
|
54
|
-
if (id === query || full === query) {
|
|
55
|
-
score = 100;
|
|
56
|
-
} else if (id.includes(query) || full.includes(query)) {
|
|
57
|
-
score = 60 + (query.length / id.length) * 30;
|
|
58
|
-
} else if (name.includes(query)) {
|
|
59
|
-
score = 40 + (query.length / name.length) * 20;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (score > bestScore) {
|
|
63
|
-
bestScore = score;
|
|
64
|
-
bestMatch = m;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (bestMatch && bestScore >= 20) {
|
|
69
|
-
const found = registry.find(bestMatch.provider, bestMatch.id);
|
|
70
|
-
if (found) return found;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// 3. No match — return error with available models
|
|
74
|
-
const modelList = all
|
|
75
|
-
.map((m) => ` ${m.provider}/${m.id}`)
|
|
76
|
-
.sort()
|
|
77
|
-
.join("\n");
|
|
78
|
-
return `Model not found: "${input}".\n\nAvailable models:\n${modelList}`;
|
|
79
|
-
}
|
package/src/prompts.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @pi-unipi/subagents — System prompt builder
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { AgentConfig } from "./types.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Build system prompt for an agent.
|
|
9
|
-
*/
|
|
10
|
-
export function buildAgentPrompt(
|
|
11
|
-
config: AgentConfig,
|
|
12
|
-
cwd: string,
|
|
13
|
-
env: { isGitRepo: boolean; branch: string; platform: string },
|
|
14
|
-
parentSystemPrompt: string,
|
|
15
|
-
): string {
|
|
16
|
-
if (config.promptMode === "append") {
|
|
17
|
-
// Append mode: parent prompt + agent additions
|
|
18
|
-
return [
|
|
19
|
-
parentSystemPrompt,
|
|
20
|
-
"",
|
|
21
|
-
"---",
|
|
22
|
-
"",
|
|
23
|
-
`## Agent Role: ${config.displayName ?? config.name}`,
|
|
24
|
-
config.systemPrompt,
|
|
25
|
-
].join("\n");
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Replace mode: standalone prompt
|
|
29
|
-
return [
|
|
30
|
-
`# ${config.displayName ?? config.name}`,
|
|
31
|
-
"",
|
|
32
|
-
config.systemPrompt,
|
|
33
|
-
"",
|
|
34
|
-
"---",
|
|
35
|
-
"",
|
|
36
|
-
`Working directory: ${cwd}`,
|
|
37
|
-
`Git: ${env.isGitRepo ? `${env.branch} on ${env.platform}` : "not a git repo"}`,
|
|
38
|
-
].join("\n");
|
|
39
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: explore
|
|
3
|
-
description: "Fast parallel codebase exploration"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Explore Helper
|
|
7
|
-
|
|
8
|
-
Read-only agent for fast parallel codebase exploration.
|
|
9
|
-
|
|
10
|
-
## Capabilities
|
|
11
|
-
|
|
12
|
-
- Read files
|
|
13
|
-
- Search with grep, find, ls
|
|
14
|
-
- Run bash commands (read-only)
|
|
15
|
-
|
|
16
|
-
## Constraints
|
|
17
|
-
|
|
18
|
-
- Cannot write or edit files
|
|
19
|
-
- Cannot modify the codebase
|
|
20
|
-
- Report findings only
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
Spawn multiple explore agents to read different parts of the codebase in parallel.
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
spawn_helper({
|
|
28
|
-
type: "explore",
|
|
29
|
-
prompt: "Find all files related to authentication",
|
|
30
|
-
description: "Find auth files"
|
|
31
|
-
})
|
|
32
|
-
```
|
package/src/skills/work/SKILL.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: work
|
|
3
|
-
description: "Parallel file writes with transparent locking"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Work Helper
|
|
7
|
-
|
|
8
|
-
Read-write agent for parallel file modifications.
|
|
9
|
-
|
|
10
|
-
## Capabilities
|
|
11
|
-
|
|
12
|
-
- Read files
|
|
13
|
-
- Write and edit files
|
|
14
|
-
- Run bash commands
|
|
15
|
-
- Search with grep, find, ls
|
|
16
|
-
|
|
17
|
-
## File Locking
|
|
18
|
-
|
|
19
|
-
When writing a file, the lock is acquired automatically. If another agent holds the lock, your write waits transparently — you won't see errors.
|
|
20
|
-
|
|
21
|
-
- Per-file granularity: locking `src/auth.ts` doesn't block `src/login.ts`
|
|
22
|
-
- Locks release automatically when the write completes
|
|
23
|
-
- On abort, all locks are released
|
|
24
|
-
|
|
25
|
-
## Constraints
|
|
26
|
-
|
|
27
|
-
- Cannot spawn sub-agents (prevents nesting)
|
|
28
|
-
- Cannot modify other agents' locked files (waits instead)
|
|
29
|
-
|
|
30
|
-
## Usage
|
|
31
|
-
|
|
32
|
-
Spawn work agents to modify different files in parallel.
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
spawn_helper({
|
|
36
|
-
type: "work",
|
|
37
|
-
prompt: "Refactor src/auth.ts to use async/await",
|
|
38
|
-
description: "Refactor auth module"
|
|
39
|
-
})
|
|
40
|
-
```
|
package/src/types.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @pi-unipi/subagents — Type definitions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
6
|
-
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
7
|
-
|
|
8
|
-
export type { ThinkingLevel };
|
|
9
|
-
|
|
10
|
-
/** Agent type name: built-in or user-defined. */
|
|
11
|
-
export type AgentType = string;
|
|
12
|
-
|
|
13
|
-
/** Built-in agent type names. */
|
|
14
|
-
export const BUILTIN_TYPES = ["explore", "work"] as const;
|
|
15
|
-
|
|
16
|
-
/** Read-only tool names for explore agents. */
|
|
17
|
-
const READ_ONLY_TOOLS = ["read", "bash", "grep", "find", "ls"];
|
|
18
|
-
|
|
19
|
-
/** All write-capable tool names. */
|
|
20
|
-
const ALL_TOOLS = ["read", "bash", "edit", "write", "grep", "find", "ls"];
|
|
21
|
-
|
|
22
|
-
/** Built-in agent configurations. */
|
|
23
|
-
export const BUILTIN_CONFIGS: Record<string, AgentConfig> = {
|
|
24
|
-
explore: {
|
|
25
|
-
name: "explore",
|
|
26
|
-
displayName: "Explore",
|
|
27
|
-
description: "Read-only exploration agent for parallel file reads and searches.",
|
|
28
|
-
builtinToolNames: READ_ONLY_TOOLS,
|
|
29
|
-
disallowedTools: ["edit", "write"],
|
|
30
|
-
extensions: false,
|
|
31
|
-
skills: false,
|
|
32
|
-
systemPrompt: "You are an explore agent. Read files, search code, and report findings. Do NOT modify any files.",
|
|
33
|
-
promptMode: "append",
|
|
34
|
-
source: "builtin",
|
|
35
|
-
},
|
|
36
|
-
work: {
|
|
37
|
-
name: "work",
|
|
38
|
-
displayName: "Worker",
|
|
39
|
-
description: "Write-capable worker agent with transparent file locking.",
|
|
40
|
-
builtinToolNames: ALL_TOOLS,
|
|
41
|
-
extensions: false,
|
|
42
|
-
skills: false,
|
|
43
|
-
systemPrompt: "You are a worker agent. Implement changes, write code, and complete tasks. Use the provided tools to make the requested modifications.",
|
|
44
|
-
promptMode: "append",
|
|
45
|
-
source: "builtin",
|
|
46
|
-
},
|
|
47
|
-
"name-gen": {
|
|
48
|
-
name: "name-gen",
|
|
49
|
-
displayName: "Name Generator",
|
|
50
|
-
description: "Minimal agent for generating session names from conversation context.",
|
|
51
|
-
builtinToolNames: [],
|
|
52
|
-
extensions: false,
|
|
53
|
-
skills: false,
|
|
54
|
-
systemPrompt: "You are a session name generator. Generate concise titles from conversation context. Reply with ONLY the title.",
|
|
55
|
-
promptMode: "replace",
|
|
56
|
-
source: "builtin",
|
|
57
|
-
},
|
|
58
|
-
} as const;
|
|
59
|
-
|
|
60
|
-
/** Memory scope for persistent agent memory. */
|
|
61
|
-
export type MemoryScope = "user" | "project" | "local";
|
|
62
|
-
|
|
63
|
-
/** Unified agent configuration. */
|
|
64
|
-
export interface AgentConfig {
|
|
65
|
-
name: string;
|
|
66
|
-
displayName?: string;
|
|
67
|
-
description: string;
|
|
68
|
-
builtinToolNames?: string[];
|
|
69
|
-
disallowedTools?: string[];
|
|
70
|
-
extensions: true | string[] | false;
|
|
71
|
-
skills: true | string[] | false;
|
|
72
|
-
model?: string;
|
|
73
|
-
thinking?: ThinkingLevel;
|
|
74
|
-
maxTurns?: number;
|
|
75
|
-
systemPrompt: string;
|
|
76
|
-
promptMode: "replace" | "append";
|
|
77
|
-
inheritContext?: boolean;
|
|
78
|
-
runInBackground?: boolean;
|
|
79
|
-
isolated?: boolean;
|
|
80
|
-
memory?: MemoryScope;
|
|
81
|
-
isDefault?: boolean;
|
|
82
|
-
enabled?: boolean;
|
|
83
|
-
source?: "builtin" | "project" | "global";
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** Agent record — tracks a running agent. */
|
|
87
|
-
export interface AgentRecord {
|
|
88
|
-
id: string;
|
|
89
|
-
type: AgentType;
|
|
90
|
-
description: string;
|
|
91
|
-
status: "queued" | "running" | "completed" | "aborted" | "stopped" | "error";
|
|
92
|
-
result?: string;
|
|
93
|
-
error?: string;
|
|
94
|
-
toolUses: number;
|
|
95
|
-
startedAt: number;
|
|
96
|
-
completedAt?: number;
|
|
97
|
-
session?: AgentSession;
|
|
98
|
-
abortController?: AbortController;
|
|
99
|
-
promise?: Promise<string>;
|
|
100
|
-
/** Set when result consumed via get_result — suppresses notification. */
|
|
101
|
-
resultConsumed?: boolean;
|
|
102
|
-
/** Files locked by this agent. */
|
|
103
|
-
lockedFiles: Set<string>;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** File lock entry. */
|
|
107
|
-
export interface FileLockEntry {
|
|
108
|
-
agentId: string;
|
|
109
|
-
filePath: string;
|
|
110
|
-
promise: Promise<void>;
|
|
111
|
-
release: () => void;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Extension config. */
|
|
115
|
-
export interface SubagentsConfig {
|
|
116
|
-
maxConcurrent: number;
|
|
117
|
-
enabled: boolean;
|
|
118
|
-
types: Record<string, { enabled?: boolean }>;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** Agent activity for widget display. */
|
|
122
|
-
export interface AgentActivity {
|
|
123
|
-
activeTools: Map<string, string>;
|
|
124
|
-
toolUses: number;
|
|
125
|
-
turnCount: number;
|
|
126
|
-
maxTurns?: number;
|
|
127
|
-
tokens: string;
|
|
128
|
-
responseText: string;
|
|
129
|
-
session?: AgentSession;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** Details attached to custom notification messages for visual rendering. */
|
|
133
|
-
export interface NotificationDetails {
|
|
134
|
-
id: string;
|
|
135
|
-
description: string;
|
|
136
|
-
status: string;
|
|
137
|
-
toolUses: number;
|
|
138
|
-
turnCount: number;
|
|
139
|
-
maxTurns?: number;
|
|
140
|
-
totalTokens: number;
|
|
141
|
-
durationMs: number;
|
|
142
|
-
error?: string;
|
|
143
|
-
resultPreview: string;
|
|
144
|
-
/** Additional agents in a group notification. */
|
|
145
|
-
others?: NotificationDetails[];
|
|
146
|
-
}
|