speexor 0.2.0 → 0.2.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/BENCHMARKS.md +21 -0
- package/CHANGELOG.md +24 -0
- package/CONTRIBUTING.md +5 -10
- package/FAQ.md +28 -1
- package/GLOSSARY.md +1 -0
- package/PUBLISH.md +7 -2
- package/README.md +2 -2
- package/ROADMAP.md +29 -62
- package/SECURITY.md +2 -1
- package/SUMMARY.md +1 -1
- package/dist/{agent-D4BRWEOZ.js → agent-C64T66XT.js} +4 -4
- package/dist/{agent-D4BRWEOZ.js.map → agent-C64T66XT.js.map} +1 -1
- package/dist/{chunk-7VZHDGRQ.js → chunk-5OD5UWB5.js} +322 -121
- package/dist/chunk-5OD5UWB5.js.map +1 -0
- package/dist/chunk-GOGI3JQD.js +1637 -0
- package/dist/chunk-GOGI3JQD.js.map +1 -0
- package/dist/{chunk-2DX54KIM.js → chunk-VEZQT5SX.js} +80 -8
- package/dist/chunk-VEZQT5SX.js.map +1 -0
- package/dist/cli/index.js +2058 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.d.ts +682 -3
- package/dist/core/index.js +1 -1
- package/dist/index.d.ts +102 -14
- package/dist/index.js +55 -29
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/types-BOMap-tI.d.ts +389 -0
- package/docs/PRD03.md +119 -0
- package/docs/PRD06.md +125 -0
- package/package.json +3 -3
- package/dist/chunk-2DX54KIM.js.map +0 -1
- package/dist/chunk-7VZHDGRQ.js.map +0 -1
- package/dist/chunk-AOFWQZWY.js +0 -345
- package/dist/chunk-AOFWQZWY.js.map +0 -1
- package/dist/types-0q_okI2g.d.ts +0 -205
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
type AgentStatus = 'idle' | 'running' | 'stuck' | 'needs-review' | 'done' | 'error';
|
|
2
|
+
type AgentProvider = 'opencode' | 'claude-code' | 'aider' | 'codex';
|
|
3
|
+
type RuntimeType = 'tmux' | 'process';
|
|
4
|
+
type SessionStatus = 'initializing' | 'active' | 'paused' | 'completed' | 'failed' | 'cancelled';
|
|
5
|
+
interface PluginModule {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
type: PluginSlot;
|
|
9
|
+
initialize(context: PluginContext): Promise<void>;
|
|
10
|
+
destroy(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
type PluginSlot = 'agent' | 'runtime' | 'workspace' | 'tracker' | 'scm' | 'notifier' | 'terminal';
|
|
13
|
+
interface PluginContext {
|
|
14
|
+
config: SpeexorConfig;
|
|
15
|
+
eventBus: EventBus;
|
|
16
|
+
logger: (msg: string) => void;
|
|
17
|
+
}
|
|
18
|
+
interface AgentPlugin extends PluginModule {
|
|
19
|
+
type: 'agent';
|
|
20
|
+
spawn(task: AgentTask, runtime: RuntimeSession): Promise<AgentSession>;
|
|
21
|
+
sendInput(sessionId: string, input: string): Promise<void>;
|
|
22
|
+
getStatus(sessionId: string): Promise<AgentStatus>;
|
|
23
|
+
kill(sessionId: string): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
interface AgentTask {
|
|
26
|
+
id: string;
|
|
27
|
+
title: string;
|
|
28
|
+
description: string;
|
|
29
|
+
repository: string;
|
|
30
|
+
branch: string;
|
|
31
|
+
provider?: AgentProvider;
|
|
32
|
+
model?: string;
|
|
33
|
+
}
|
|
34
|
+
interface AgentSession {
|
|
35
|
+
id: string;
|
|
36
|
+
taskId: string;
|
|
37
|
+
provider: AgentProvider;
|
|
38
|
+
status: AgentStatus;
|
|
39
|
+
startedAt: Date;
|
|
40
|
+
runtimeSessionId: string;
|
|
41
|
+
}
|
|
42
|
+
interface RuntimePlugin extends PluginModule {
|
|
43
|
+
type: 'runtime';
|
|
44
|
+
createSession(worktreePath: string): Promise<RuntimeSession>;
|
|
45
|
+
destroySession(sessionId: string): Promise<void>;
|
|
46
|
+
sendInput(sessionId: string, input: string): Promise<void>;
|
|
47
|
+
getOutput(sessionId: string): Promise<string>;
|
|
48
|
+
getLiveStream(sessionId: string): AsyncIterable<string>;
|
|
49
|
+
getStatus(sessionId: string): Promise<'running' | 'stopped' | 'error'>;
|
|
50
|
+
}
|
|
51
|
+
interface RuntimeSession {
|
|
52
|
+
id: string;
|
|
53
|
+
type: RuntimeType;
|
|
54
|
+
worktreePath: string;
|
|
55
|
+
pid?: number;
|
|
56
|
+
createdAt: Date;
|
|
57
|
+
}
|
|
58
|
+
interface WorkspacePlugin extends PluginModule {
|
|
59
|
+
type: 'workspace';
|
|
60
|
+
createWorktree(task: AgentTask): Promise<WorktreeSession>;
|
|
61
|
+
removeWorktree(sessionId: string): Promise<void>;
|
|
62
|
+
getWorktreePath(sessionId: string): string;
|
|
63
|
+
listActive(): Promise<WorktreeSession[]>;
|
|
64
|
+
cleanupStale(): Promise<string[]>;
|
|
65
|
+
}
|
|
66
|
+
type WorkspaceSession = WorktreeSession;
|
|
67
|
+
interface WorktreeSession {
|
|
68
|
+
id: string;
|
|
69
|
+
taskId: string;
|
|
70
|
+
repository: string;
|
|
71
|
+
branch: string;
|
|
72
|
+
path: string;
|
|
73
|
+
createdAt: Date;
|
|
74
|
+
}
|
|
75
|
+
interface TrackerPlugin extends PluginModule {
|
|
76
|
+
type: 'tracker';
|
|
77
|
+
fetchIssues(filter?: TrackerFilter): Promise<TrackerIssue[]>;
|
|
78
|
+
getIssue(id: string): Promise<TrackerIssue | null>;
|
|
79
|
+
onEvent(handler: (event: TrackerEvent) => void): void;
|
|
80
|
+
}
|
|
81
|
+
interface TrackerFilter {
|
|
82
|
+
state?: 'open' | 'closed' | 'all';
|
|
83
|
+
labels?: string[];
|
|
84
|
+
since?: Date;
|
|
85
|
+
limit?: number;
|
|
86
|
+
}
|
|
87
|
+
interface TrackerIssue {
|
|
88
|
+
id: string;
|
|
89
|
+
title: string;
|
|
90
|
+
description: string;
|
|
91
|
+
state: 'open' | 'closed';
|
|
92
|
+
labels: string[];
|
|
93
|
+
url: string;
|
|
94
|
+
createdAt: Date;
|
|
95
|
+
updatedAt: Date;
|
|
96
|
+
}
|
|
97
|
+
type TrackerEventType = 'issue-opened' | 'issue-closed' | 'ci-failed' | 'ci-passed' | 'changes-requested' | 'approved';
|
|
98
|
+
interface TrackerEvent {
|
|
99
|
+
type: TrackerEventType;
|
|
100
|
+
issueId: string;
|
|
101
|
+
timestamp: Date;
|
|
102
|
+
data: Record<string, unknown>;
|
|
103
|
+
}
|
|
104
|
+
interface SCMPlugin extends PluginModule {
|
|
105
|
+
type: 'scm';
|
|
106
|
+
createBranch(baseBranch: string, newBranch: string): Promise<void>;
|
|
107
|
+
commitAndPush(branch: string, message: string): Promise<string>;
|
|
108
|
+
createPullRequest(title: string, description: string, head: string, base: string): Promise<PRInfo>;
|
|
109
|
+
getPRStatus(prId: string): Promise<PRStatus>;
|
|
110
|
+
getPRComments(prId: string): Promise<PRComment[]>;
|
|
111
|
+
getCIRuns(prId: string): Promise<CIRun[]>;
|
|
112
|
+
mergePR(prId: string, method?: 'merge' | 'squash' | 'rebase'): Promise<void>;
|
|
113
|
+
onEvent(handler: (event: TrackerEvent) => void): void;
|
|
114
|
+
}
|
|
115
|
+
interface PRInfo {
|
|
116
|
+
id: string;
|
|
117
|
+
url: string;
|
|
118
|
+
title: string;
|
|
119
|
+
state: 'open' | 'closed' | 'merged';
|
|
120
|
+
headBranch: string;
|
|
121
|
+
baseBranch: string;
|
|
122
|
+
createdAt: Date;
|
|
123
|
+
}
|
|
124
|
+
interface PRStatus {
|
|
125
|
+
id: string;
|
|
126
|
+
state: 'open' | 'closed' | 'merged';
|
|
127
|
+
mergeable: boolean;
|
|
128
|
+
ciStatus: 'pending' | 'passing' | 'failing' | 'unknown';
|
|
129
|
+
reviewStatus: 'approved' | 'changes-requested' | 'pending' | 'none';
|
|
130
|
+
}
|
|
131
|
+
interface PRComment {
|
|
132
|
+
id: string;
|
|
133
|
+
author: string;
|
|
134
|
+
body: string;
|
|
135
|
+
file?: string;
|
|
136
|
+
line?: number;
|
|
137
|
+
createdAt: Date;
|
|
138
|
+
}
|
|
139
|
+
interface CIRun {
|
|
140
|
+
id: string;
|
|
141
|
+
name: string;
|
|
142
|
+
status: 'queued' | 'in_progress' | 'completed';
|
|
143
|
+
conclusion: 'success' | 'failure' | 'cancelled' | 'skipped' | null;
|
|
144
|
+
url: string;
|
|
145
|
+
}
|
|
146
|
+
interface NotifierPlugin extends PluginModule {
|
|
147
|
+
type: 'notifier';
|
|
148
|
+
notify(level: 'info' | 'warn' | 'error' | 'success', title: string, message: string): Promise<void>;
|
|
149
|
+
}
|
|
150
|
+
interface TerminalPlugin extends PluginModule {
|
|
151
|
+
type: 'terminal';
|
|
152
|
+
attach(sessionId: string): Promise<void>;
|
|
153
|
+
detach(sessionId: string): Promise<void>;
|
|
154
|
+
write(sessionId: string, data: string): Promise<void>;
|
|
155
|
+
onData(sessionId: string, handler: (data: string) => void): void;
|
|
156
|
+
}
|
|
157
|
+
interface EventBus {
|
|
158
|
+
emit(event: string, data: unknown): void;
|
|
159
|
+
on(event: string, handler: (data: unknown) => void): void;
|
|
160
|
+
off(event: string, handler: (data: unknown) => void): void;
|
|
161
|
+
once(event: string, handler: (data: unknown) => void): void;
|
|
162
|
+
}
|
|
163
|
+
interface ReactionConfig {
|
|
164
|
+
'ci-failed': ReactionRule;
|
|
165
|
+
'changes-requested': ReactionRule;
|
|
166
|
+
'approved-and-green': ReactionRule;
|
|
167
|
+
}
|
|
168
|
+
interface ReactionRule {
|
|
169
|
+
auto: boolean;
|
|
170
|
+
action: 'fix' | 'notify' | 'escalate' | 'skip';
|
|
171
|
+
retries: number;
|
|
172
|
+
escalateAfter: number;
|
|
173
|
+
}
|
|
174
|
+
interface ProviderRouting {
|
|
175
|
+
primary: AgentProvider;
|
|
176
|
+
fallback?: AgentProvider[];
|
|
177
|
+
concurrentLimit?: number;
|
|
178
|
+
costLimit?: number;
|
|
179
|
+
}
|
|
180
|
+
type TaskNodeStatus = 'pending' | 'decomposing' | 'ready' | 'in_progress' | 'blocked' | 'review' | 'done' | 'failed';
|
|
181
|
+
type TaskOrigin = 'user' | 'agent' | 'subagent';
|
|
182
|
+
interface TaskNode {
|
|
183
|
+
id: string;
|
|
184
|
+
title: string;
|
|
185
|
+
description: string;
|
|
186
|
+
status: TaskNodeStatus;
|
|
187
|
+
parentId: string | null;
|
|
188
|
+
depth: number;
|
|
189
|
+
dependsOn: string[];
|
|
190
|
+
createdBy: TaskOrigin;
|
|
191
|
+
createdByAgentId?: string;
|
|
192
|
+
assignedAgentId?: string | null;
|
|
193
|
+
worktreePath?: string | null;
|
|
194
|
+
skillsUsed: string[];
|
|
195
|
+
commandsExecuted: CommandExecution[];
|
|
196
|
+
result?: TaskResult;
|
|
197
|
+
proposedBy?: string;
|
|
198
|
+
proposedReason?: string;
|
|
199
|
+
createdAt: Date;
|
|
200
|
+
updatedAt: Date;
|
|
201
|
+
}
|
|
202
|
+
interface CommandExecution {
|
|
203
|
+
command: string;
|
|
204
|
+
timestamp: Date;
|
|
205
|
+
exitCode: number | null;
|
|
206
|
+
output?: string;
|
|
207
|
+
}
|
|
208
|
+
interface TaskResult {
|
|
209
|
+
summary: string;
|
|
210
|
+
prUrl?: string;
|
|
211
|
+
filesChanged?: string[];
|
|
212
|
+
newTasksProposed: string[];
|
|
213
|
+
}
|
|
214
|
+
interface TaskGraph {
|
|
215
|
+
id: string;
|
|
216
|
+
rootTaskId: string;
|
|
217
|
+
projectName: string;
|
|
218
|
+
nodes: Map<string, TaskNode>;
|
|
219
|
+
status: 'decomposing' | 'executing' | 'completed' | 'failed';
|
|
220
|
+
createdAt: Date;
|
|
221
|
+
updatedAt: Date;
|
|
222
|
+
}
|
|
223
|
+
interface DecompositionConfig {
|
|
224
|
+
maxTaskGraphDepth: number;
|
|
225
|
+
maxAgentSpawnDepth: number;
|
|
226
|
+
maxNodesPerGraph: number;
|
|
227
|
+
plannerProvider?: string;
|
|
228
|
+
plannerModel?: string;
|
|
229
|
+
}
|
|
230
|
+
interface SchedulerConfig {
|
|
231
|
+
maxConcurrentAgents: number | 'auto';
|
|
232
|
+
retryOnFailure: number;
|
|
233
|
+
providerFallbackChain: string[];
|
|
234
|
+
maxAfkDurationHours?: number;
|
|
235
|
+
}
|
|
236
|
+
interface GovernanceConfig {
|
|
237
|
+
autoApproveProposedTasks: boolean;
|
|
238
|
+
autoApproveCategories: string[];
|
|
239
|
+
duplicateSimilarityThreshold: number;
|
|
240
|
+
}
|
|
241
|
+
type ApprovalAxis = 'task-origin-gate' | 'action-risk-gate';
|
|
242
|
+
type ApprovalStatus = 'pending' | 'approved' | 'rejected' | 'escalated';
|
|
243
|
+
interface ApprovalItem {
|
|
244
|
+
id: string;
|
|
245
|
+
axis: ApprovalAxis;
|
|
246
|
+
taskId: string;
|
|
247
|
+
agentId?: string;
|
|
248
|
+
title: string;
|
|
249
|
+
description: string;
|
|
250
|
+
riskLevel?: 'low' | 'medium' | 'high';
|
|
251
|
+
proposedBy?: string;
|
|
252
|
+
reason?: string;
|
|
253
|
+
status: ApprovalStatus;
|
|
254
|
+
createdAt: Date;
|
|
255
|
+
expiresAt?: Date;
|
|
256
|
+
defaultAction?: 'approve' | 'skip' | 'escalate';
|
|
257
|
+
}
|
|
258
|
+
type AgentEventType = 'skill_invoked' | 'command_executed' | 'file_changed' | 'task_proposed' | 'status_changed';
|
|
259
|
+
interface AgentEvent {
|
|
260
|
+
eventType: AgentEventType;
|
|
261
|
+
agentId: string;
|
|
262
|
+
taskId: string;
|
|
263
|
+
timestamp: Date;
|
|
264
|
+
payload: Record<string, unknown>;
|
|
265
|
+
}
|
|
266
|
+
interface CostGuardConfig {
|
|
267
|
+
budgetLimitUSD?: number;
|
|
268
|
+
trackByProvider: boolean;
|
|
269
|
+
trackByProject: boolean;
|
|
270
|
+
trackByTaskNode: boolean;
|
|
271
|
+
}
|
|
272
|
+
interface ProviderCostEntry {
|
|
273
|
+
provider: string;
|
|
274
|
+
taskId: string;
|
|
275
|
+
projectName: string;
|
|
276
|
+
tokensIn: number;
|
|
277
|
+
tokensOut: number;
|
|
278
|
+
estimatedCostUSD: number;
|
|
279
|
+
timestamp: Date;
|
|
280
|
+
}
|
|
281
|
+
type ExtensionType = 'agent-backend' | 'skill' | 'plugin' | 'action-adapter' | 'library' | 'mcp-server';
|
|
282
|
+
type PermissionAxis = 'fileSystem' | 'network' | 'shell' | 'secrets';
|
|
283
|
+
type PermissionLevel = 'none' | 'read-only' | 'read-write' | 'scoped' | 'full';
|
|
284
|
+
interface ExtensionManifest {
|
|
285
|
+
name: string;
|
|
286
|
+
type: ExtensionType;
|
|
287
|
+
version: string;
|
|
288
|
+
speexorApiVersion: string;
|
|
289
|
+
permissions: ExtensionPermissions;
|
|
290
|
+
entry: string;
|
|
291
|
+
description: string;
|
|
292
|
+
author: string;
|
|
293
|
+
signature?: string;
|
|
294
|
+
}
|
|
295
|
+
interface ExtensionPermissions {
|
|
296
|
+
fileSystem: PermissionLevel;
|
|
297
|
+
network: PermissionLevel;
|
|
298
|
+
shell: PermissionLevel;
|
|
299
|
+
secrets: string[];
|
|
300
|
+
}
|
|
301
|
+
interface WorktreeHierarchyConfig {
|
|
302
|
+
pinToCommitHash: boolean;
|
|
303
|
+
serializeMerges: boolean;
|
|
304
|
+
conflictEscalatesToApproval: boolean;
|
|
305
|
+
}
|
|
306
|
+
interface DecisionLogEntry {
|
|
307
|
+
id: string;
|
|
308
|
+
taskId: string;
|
|
309
|
+
agentId: string;
|
|
310
|
+
action: string;
|
|
311
|
+
confidence: number;
|
|
312
|
+
wasAutoExecuted: boolean;
|
|
313
|
+
approvedBy?: 'user' | 'auto';
|
|
314
|
+
outcome?: 'correct' | 'incorrect' | 'partial' | 'unknown';
|
|
315
|
+
outcomeLabeledBy?: 'user' | 'llm-judge';
|
|
316
|
+
createdAt: Date;
|
|
317
|
+
}
|
|
318
|
+
interface SpeexorConfig {
|
|
319
|
+
version: '1' | '2' | '3' | '4' | '5';
|
|
320
|
+
dataDir?: string;
|
|
321
|
+
projects: ProjectConfig[];
|
|
322
|
+
decomposition?: DecompositionConfig;
|
|
323
|
+
scheduler?: SchedulerConfig;
|
|
324
|
+
governance?: GovernanceConfig;
|
|
325
|
+
riskPolicy?: RiskPolicyConfig;
|
|
326
|
+
worktreeHierarchy?: WorktreeHierarchyConfig;
|
|
327
|
+
costGuard?: CostGuardConfig;
|
|
328
|
+
extensions?: ExtensionsConfig;
|
|
329
|
+
security?: SecurityConfig;
|
|
330
|
+
performance?: PerformanceConfig;
|
|
331
|
+
logging?: LoggingConfig;
|
|
332
|
+
}
|
|
333
|
+
interface RiskPolicyConfig {
|
|
334
|
+
autoApprove: string[];
|
|
335
|
+
requireApproval: string[];
|
|
336
|
+
approvalTimeout: string;
|
|
337
|
+
approvalDefaultAction: 'approve' | 'skip' | 'escalate';
|
|
338
|
+
budgetLimitUSD?: number;
|
|
339
|
+
defaultRiskTierForUnknownActions: 'low' | 'medium' | 'high-stakes';
|
|
340
|
+
}
|
|
341
|
+
interface ExtensionsConfig {
|
|
342
|
+
marketplaceIndex?: string;
|
|
343
|
+
enabled: string[];
|
|
344
|
+
permissionsMode: 'strict' | 'relaxed';
|
|
345
|
+
}
|
|
346
|
+
interface SecurityConfig {
|
|
347
|
+
secretsBackend: 'os-keychain' | 'file';
|
|
348
|
+
encryptAtRest: boolean;
|
|
349
|
+
sandboxModel: 'process' | 'isolated-vm';
|
|
350
|
+
}
|
|
351
|
+
interface PerformanceConfig {
|
|
352
|
+
maxConcurrentAgents: number | 'auto';
|
|
353
|
+
workerThreadPoolSize: number;
|
|
354
|
+
}
|
|
355
|
+
interface LoggingConfig {
|
|
356
|
+
level: 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
357
|
+
}
|
|
358
|
+
interface RollbackRecord {
|
|
359
|
+
approvalId: string;
|
|
360
|
+
taskId: string;
|
|
361
|
+
action: string;
|
|
362
|
+
reason: string;
|
|
363
|
+
rolledBackAt: Date;
|
|
364
|
+
success: boolean;
|
|
365
|
+
error?: string;
|
|
366
|
+
}
|
|
367
|
+
interface ProjectConfig {
|
|
368
|
+
name: string;
|
|
369
|
+
repository: string;
|
|
370
|
+
path?: string;
|
|
371
|
+
branch?: string;
|
|
372
|
+
provider: ProviderRouting;
|
|
373
|
+
reactions?: Partial<ReactionConfig>;
|
|
374
|
+
plugins?: {
|
|
375
|
+
tracker?: string;
|
|
376
|
+
scm?: string;
|
|
377
|
+
runtime?: string;
|
|
378
|
+
notifier?: string;
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
interface SpeexorState {
|
|
382
|
+
sessions: AgentSession[];
|
|
383
|
+
worktrees: WorktreeSession[];
|
|
384
|
+
runtimes: RuntimeSession[];
|
|
385
|
+
projects: ProjectConfig[];
|
|
386
|
+
}
|
|
387
|
+
type SessionEventType = 'session:created' | 'session:status-changed' | 'session:completed' | 'session:failed' | 'worktree:created' | 'worktree:removed' | 'reaction:triggered' | 'reaction:completed' | 'task:created' | 'task:status-changed' | 'task:completed' | 'task:blocked' | 'agent:event' | 'approval:created' | 'approval:resolved' | 'cost:recorded' | 'cost:warning' | 'cost:exceeded' | 'session:afk-warning' | 'error';
|
|
388
|
+
|
|
389
|
+
export type { TaskNodeStatus as $, AgentSession as A, PluginSlot as B, CIRun as C, DecisionLogEntry as D, EventBus as E, ProviderRouting as F, GovernanceConfig as G, ReactionConfig as H, ReactionRule as I, RiskPolicyConfig as J, RollbackRecord as K, LoggingConfig as L, RuntimePlugin as M, NotifierPlugin as N, RuntimeType as O, PluginModule as P, SCMPlugin as Q, RuntimeSession as R, SpeexorState as S, TaskGraph as T, SchedulerConfig as U, SecurityConfig as V, WorktreeSession as W, SessionEventType as X, SessionStatus as Y, SpeexorConfig as Z, TaskNode as _, ProviderCostEntry as a, TaskOrigin as a0, TaskResult as a1, TerminalPlugin as a2, TrackerEventType as a3, TrackerFilter as a4, TrackerIssue as a5, TrackerPlugin as a6, WorkspacePlugin as a7, WorkspaceSession as a8, WorktreeHierarchyConfig as a9, ProjectConfig as b, AgentEvent as c, ApprovalItem as d, TrackerEvent as e, AgentEventType as f, AgentPlugin as g, AgentProvider as h, AgentStatus as i, AgentTask as j, ApprovalAxis as k, ApprovalStatus as l, CommandExecution as m, CostGuardConfig as n, DecompositionConfig as o, ExtensionManifest as p, ExtensionPermissions as q, ExtensionType as r, ExtensionsConfig as s, PRComment as t, PRInfo as u, PRStatus as v, PerformanceConfig as w, PermissionAxis as x, PermissionLevel as y, PluginContext as z };
|
package/docs/PRD03.md
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# PRD: Speexor v3 — "Never-Ask, Always-Decide" Autonomy Layer
|
|
2
|
+
|
|
3
|
+
**Codename:** Speexor — Autonomous Decision Engine
|
|
4
|
+
**Version:** 3.0 — Pengembangan dari v2
|
|
5
|
+
**Author:** Aditya (drafted with Claude)
|
|
6
|
+
**Date:** June 30, 2026
|
|
7
|
+
**Status:** Reconstructed (original file was lost — restored from PRD04/PRD05 cross-references and architectural context)
|
|
8
|
+
|
|
9
|
+
> **⚠️ REKONSTRUKSI RETROAKTIF:** Dokumen ini direkonstruksi dari referensi di PRD04 dan PRD05 setelah file asli `PRD03.md` ditemukan kosong (0 byte) saat audit PRD06. Konten here mewakili fitur-fitur v3 yang dirujuk oleh PRD04 dan PRD05, direkonstruksi berdasarkan konteks arsitektur dan kebutuhan produk. Lihat PRD06 C1 untuk detail.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Apa yang Berubah dari v2
|
|
14
|
+
|
|
15
|
+
| Aspek | v2 | v3 |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Keputusan | Task graph dihasilkan otomatis, tapi masih butuh approval manusia untuk banyak titik | **Never-Ask, Always-Decide** — agent membuat keputusan secara otonom berdasarkan confidence score dan risk classification |
|
|
18
|
+
| Interupsi | Tidak ada mekanisme interupsi — agent berjalan sampai selesai atau gagal | **Interrupt/Override Protocol** — user bisa menginterupsi agent di tengah jalan, mengubah arah, atau membatalkan dengan graceful handoff |
|
|
19
|
+
| Universal actions | Terbatas pada coding任务 (read/write file, git operations) | **Universal Action Layer** — agent bisa melakukan aksi di luar coding: dokumentasi, web scraping, komunikasi, scheduling |
|
|
20
|
+
| Notification | Desktop notification pasif | **Multi-channel proactive communication** — agent bisa mengirim update, meminta klarifikasi, dan melapor via Slack/Discord/Telegram |
|
|
21
|
+
| Session management | Manual start/stop | **Persistent background daemon** — sesi berjalan terus meski terminal ditutup, auto-restart on crash |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. Tujuan Produk v3
|
|
26
|
+
|
|
27
|
+
| # | Goal | Metrik Keberhasilan |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| G1 | Agent mengambil keputusan sendiri tanpa bertanya untuk >80% aksi rutin | ≥80% aksi berjalan otomatis tanpa intervensi manusia |
|
|
30
|
+
| G2 | User bisa menginterupsi agent kapan saja dengan aman | Interupsi menghasilkan state konsisten (tidak ada half-written files) dalam <5 detik |
|
|
31
|
+
| G3 | Agent bisa melakukan aksi non-coding (dokumen, web, komunikasi) | ≥3 action adapter terimplementasi: Document, Web/Browser, Communication |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 3. Konsep Inti: Never-Ask Decision Engine
|
|
36
|
+
|
|
37
|
+
### 3.1 Decision Ladder
|
|
38
|
+
|
|
39
|
+
Setiap keputusan agent dievaluasi dalam 4 tingkat:
|
|
40
|
+
|
|
41
|
+
1. **Confidence Scoring** — agent memberikan confidence score (0.0-1.0) untuk setiap keputusan
|
|
42
|
+
2. **Risk Classification** — setiap aksi diklasifikasikan sebagai `reversible-low`, `reversible-medium`, `irreversible-high-stakes`
|
|
43
|
+
3. **Auto-Execute Threshold** — jika confidence > threshold DAN risk = low/medium, eksekusi otomatis
|
|
44
|
+
4. **Human Gate** — jika confidence < threshold ATAU risk = high-stakes, minta approval
|
|
45
|
+
|
|
46
|
+
### 3.2 Confidence Threshold Configuration
|
|
47
|
+
|
|
48
|
+
Dikonfigurasi per project di `speexor.config.yaml`:
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
decision:
|
|
52
|
+
confidenceThreshold: 0.8
|
|
53
|
+
riskClassification:
|
|
54
|
+
autoApprove: ["reversible-low", "reversible-medium"]
|
|
55
|
+
requireApproval: ["irreversible-high-stakes"]
|
|
56
|
+
approvalTimeout: 4h
|
|
57
|
+
approvalDefaultAction: "skip"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 4. Interrupt/Override Protocol
|
|
63
|
+
|
|
64
|
+
- **Graceful Handoff**: Agent menyelesaikan Atomic Unit of Work (1 fungsi, 1 file edit, 1 commit) sebelum pause
|
|
65
|
+
- **Interrupt Levels**: `pause` (selesai AUW lalu pause), `redirect` (ganti task), `cancel` (batalkan + cleanup), `hard-stop` (kill paksa, hanya darurat)
|
|
66
|
+
- **State Checkpoint**: Setiap interrupt menghasilkan checkpoint yang bisa di-resume nanti
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 5. Universal Action Layer
|
|
71
|
+
|
|
72
|
+
Action Adapters adalah plugin type baru (slot ke-8 implisit) yang memungkinkan agent melakukan:
|
|
73
|
+
|
|
74
|
+
| Action Type | Contoh | Status di v3 |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| Document | Menulis dokumentasi API, README, changelog | ✅ Implemented |
|
|
77
|
+
| Web/Browser | Scrape web, cek dokumentasi, test UI | ✅ Implemented |
|
|
78
|
+
| Communication | Kirim notifikasi ke Slack/Discord/Telegram | 🔄 Partial (desktop only) |
|
|
79
|
+
| Scheduling | Buat reminder, jadwalkan task | 📅 Planned |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 6. Perubahan Arsitektur
|
|
84
|
+
|
|
85
|
+
| Komponen Baru | Tanggung Jawab |
|
|
86
|
+
|---|---|
|
|
87
|
+
| DecisionEngine | Confidence scoring, risk classification, auto-execute gating |
|
|
88
|
+
| ActionAdapterPlugin | Interface untuk universal action adapters |
|
|
89
|
+
| CheckpointManager | State persistence untuk resume/interrupt |
|
|
90
|
+
| SessionDaemon | Background process management, auto-restart |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 7. Referensi di PRD04 & PRD05
|
|
95
|
+
|
|
96
|
+
PRD04 dan PRD05 merujuk ke v3 untuk:
|
|
97
|
+
|
|
98
|
+
- **Action Adapters** (PRD04 §5.1) — sebagai extension type ke-4
|
|
99
|
+
- **Decision Engine & Confidence Scoring** (PRD05 §3.2/3.3) — di-refine menjadi unified Approval Model
|
|
100
|
+
- **Graceful Handoff** (PRD05 §3.4) — digunakan dalam Worktree Hierarchy Protocol
|
|
101
|
+
- **Simple Mode** (PRD04 §10.3) — toggle UI complexity
|
|
102
|
+
- **maxAfkDurationHours** (PRD05 §4.7) — session guard configuration
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 8. Status Implementasi
|
|
107
|
+
|
|
108
|
+
| Komponen | Status | Catatan |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| Decision Engine | ✅ Implemented | GovernanceEngine + ApprovalManager |
|
|
111
|
+
| Confidence Scoring | ✅ Implemented | CalibrationAnalyzer + DecisionLog |
|
|
112
|
+
| Action Adapters | 🔄 Partial | Document adapter di extension-manager |
|
|
113
|
+
| Checkpoint Manager | 🔄 Partial | TaskGraph store sudah ada checkpoint |
|
|
114
|
+
| Session Daemon | ✅ Implemented | Scheduler + SessionGuard |
|
|
115
|
+
| Interrupt Protocol | 📅 Not yet | Worktree Hierarchy Protocol sudah mencakup bagian merge interrupt |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
*Dokumen ini direkonstruksi untuk menjaga kontinuitas rantai keputusan produk. Lihat PRD04 untuk platform layer di atas v1-v3, dan PRD05 untuk gap analysis yang mengoreksi v1-v4.*
|