@aiassesstech/sam 0.3.15 → 0.4.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 +41 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/types.d.ts +26 -0
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/pipeline/types.js +9 -0
- package/dist/pipeline/types.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +240 -12
- package/dist/plugin.js.map +1 -1
- package/dist/tools/engine-session-manager.d.ts +18 -0
- package/dist/tools/engine-session-manager.d.ts.map +1 -0
- package/dist/tools/engine-session-manager.js +29 -0
- package/dist/tools/engine-session-manager.js.map +1 -0
- package/dist/tools/sam-artifact.d.ts +2 -1
- package/dist/tools/sam-artifact.d.ts.map +1 -1
- package/dist/tools/sam-artifact.js +15 -2
- package/dist/tools/sam-artifact.js.map +1 -1
- package/dist/tools/sam-engineer-diff.d.ts +39 -0
- package/dist/tools/sam-engineer-diff.d.ts.map +1 -0
- package/dist/tools/sam-engineer-diff.js +61 -0
- package/dist/tools/sam-engineer-diff.js.map +1 -0
- package/dist/tools/sam-engineer-resume.d.ts +34 -0
- package/dist/tools/sam-engineer-resume.d.ts.map +1 -0
- package/dist/tools/sam-engineer-resume.js +91 -0
- package/dist/tools/sam-engineer-resume.js.map +1 -0
- package/dist/tools/sam-engineer-status.d.ts +34 -0
- package/dist/tools/sam-engineer-status.d.ts.map +1 -0
- package/dist/tools/sam-engineer-status.js +66 -0
- package/dist/tools/sam-engineer-status.js.map +1 -0
- package/dist/tools/sam-engineer-terminate.d.ts +41 -0
- package/dist/tools/sam-engineer-terminate.d.ts.map +1 -0
- package/dist/tools/sam-engineer-terminate.js +88 -0
- package/dist/tools/sam-engineer-terminate.js.map +1 -0
- package/dist/tools/sam-engineer.d.ts +60 -0
- package/dist/tools/sam-engineer.d.ts.map +1 -0
- package/dist/tools/sam-engineer.js +195 -0
- package/dist/tools/sam-engineer.js.map +1 -0
- package/dist/tools/sam-pipeline.d.ts.map +1 -1
- package/dist/tools/sam-pipeline.js +10 -0
- package/dist/tools/sam-pipeline.js.map +1 -1
- package/dist/tools/sam-status.d.ts +2 -1
- package/dist/tools/sam-status.d.ts.map +1 -1
- package/dist/tools/sam-status.js +11 -3
- package/dist/tools/sam-status.js.map +1 -1
- package/openclaw.plugin.json +62 -0
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# @aiassesstech/sam
|
|
2
|
+
|
|
3
|
+
Sam — Chief Engineer plugin for OpenClaw. Engineering pipeline management, Docker sandbox execution, autonomous code execution, and fleet-bus communications.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @aiassesstech/sam
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @aiassesstech/sam setup --model anthropic/claude-haiku-4-5
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Tools
|
|
18
|
+
|
|
19
|
+
| Tool | Description |
|
|
20
|
+
|------|-------------|
|
|
21
|
+
| `sam_status` | Current agent state, pipeline summary, sandbox/fleet status |
|
|
22
|
+
| `sam_pipeline` | View engineering pipeline with filters (active/blocked/complete) |
|
|
23
|
+
| `sam_request` | Create, update, or close Engineering Requests |
|
|
24
|
+
| `sam_report` | Generate summary, detailed, or debt reports |
|
|
25
|
+
| `sam_execute` | Run code in Docker sandbox (Node.js, Python, bash) |
|
|
26
|
+
| `sam_sandbox` | Manage sandbox lifecycle (status, build, cleanup) |
|
|
27
|
+
| `sam_test` | Run test suites in sandbox (vitest, jest, pytest, custom) |
|
|
28
|
+
| `sam_artifact` | List, package, and clean up build artifacts |
|
|
29
|
+
| `sam_fleet_task_status` | Report ER status to Jessie via fleet-bus |
|
|
30
|
+
| `sam_fleet_task_complete` | Report ER completion with artifact reference |
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
- **PipelineManager** — Engineering Request lifecycle (INTAKE → ANALYSIS → BUILD → SELF-REVIEW → ARCHIE-REVIEW → DELIVERED)
|
|
35
|
+
- **SandboxManager** — Docker container lifecycle with resource limits
|
|
36
|
+
- **DirectMemoryWriter** — Filesystem-based memory persistence (compatible with Mighty Mark vector search)
|
|
37
|
+
- **Fleet-bus integration** — Cross-agent task coordination with Jessie
|
|
38
|
+
|
|
39
|
+
## Repository
|
|
40
|
+
|
|
41
|
+
Part of the [compsi](https://github.com/spehargreg/compsi) monorepo — `packages/sam/`.
|
package/dist/index.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export type { PipelineStage, EngineeringRequest, PipelineData, SamStatusResult,
|
|
|
8
8
|
export { PIPELINE_STAGES, STAGE_ORDER, DEFAULT_CONFIG } from './pipeline/types.js';
|
|
9
9
|
export type { FleetContext } from './tools/sam-fleet-tools.js';
|
|
10
10
|
export type { MemoryWriterLike } from './memory/sam-memory.js';
|
|
11
|
+
export { EngineSessionManager } from './tools/engine-session-manager.js';
|
|
11
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnF,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnF,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,4 +5,5 @@ export { SamMemory } from './memory/sam-memory.js';
|
|
|
5
5
|
export { DirectMemoryWriter } from './memory/direct-writer.js';
|
|
6
6
|
export { SandboxManager } from './sandbox/sandbox-manager.js';
|
|
7
7
|
export { PIPELINE_STAGES, STAGE_ORDER, DEFAULT_CONFIG } from './pipeline/types.js';
|
|
8
|
+
export { EngineSessionManager } from './tools/engine-session-manager.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAa9D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAInF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/pipeline/types.d.ts
CHANGED
|
@@ -19,6 +19,12 @@ export interface EngineeringRequest {
|
|
|
19
19
|
deliveredAt?: string;
|
|
20
20
|
buildAttempts: number;
|
|
21
21
|
notes: string[];
|
|
22
|
+
engineSessionId?: string;
|
|
23
|
+
engineTurnCount?: number;
|
|
24
|
+
engineCostUsd?: number;
|
|
25
|
+
engineAuditHead?: string;
|
|
26
|
+
engineWorktreePath?: string;
|
|
27
|
+
engineLastGrilloVerdict?: 'allow' | 'allow_with_comment' | 'block';
|
|
22
28
|
}
|
|
23
29
|
export interface PipelineData {
|
|
24
30
|
version: number;
|
|
@@ -44,6 +50,13 @@ export interface SamStatusResult {
|
|
|
44
50
|
status: 'unavailable' | 'available' | 'busy';
|
|
45
51
|
};
|
|
46
52
|
fleetBus: 'connected' | 'observer' | 'standalone';
|
|
53
|
+
engine?: {
|
|
54
|
+
status: 'disabled' | 'enabled' | 'active';
|
|
55
|
+
activeSessions: number;
|
|
56
|
+
activeErIds: string[];
|
|
57
|
+
model: string;
|
|
58
|
+
grilloFailMode: string;
|
|
59
|
+
};
|
|
47
60
|
}
|
|
48
61
|
export interface PipelineFilter {
|
|
49
62
|
filter?: 'all' | 'active' | 'blocked' | 'complete';
|
|
@@ -68,6 +81,19 @@ export interface SamPluginConfig {
|
|
|
68
81
|
artifactRetentionDays: number;
|
|
69
82
|
telegramToken?: string;
|
|
70
83
|
telegramChatId?: string;
|
|
84
|
+
engineEnabled: boolean;
|
|
85
|
+
anthropicApiKey?: string;
|
|
86
|
+
engineModel?: string;
|
|
87
|
+
worktreeBasePath?: string;
|
|
88
|
+
maxBudgetUsd?: number;
|
|
89
|
+
maxBudgetTokens?: number;
|
|
90
|
+
maxIterations?: number;
|
|
91
|
+
sessionTimeoutMs?: number;
|
|
92
|
+
grilloFailMode?: 'fail_closed' | 'fail_open';
|
|
93
|
+
jessieResponseTimeoutMs?: number;
|
|
94
|
+
grilloEndpoint?: string;
|
|
95
|
+
noahEndpoint?: string;
|
|
96
|
+
jessieEndpoint?: string;
|
|
71
97
|
}
|
|
72
98
|
export declare const DEFAULT_CONFIG: SamPluginConfig;
|
|
73
99
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,aAAa,GACb,eAAe,GACf,WAAW,CAAC;AAEhB,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAO1C,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAOrD,CAAC;AAIF,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline/types.js
CHANGED
|
@@ -26,5 +26,14 @@ export const DEFAULT_CONFIG = {
|
|
|
26
26
|
sandboxImage: 'sam-sandbox:latest',
|
|
27
27
|
artifactDir: '.sam-artifacts',
|
|
28
28
|
artifactRetentionDays: 7,
|
|
29
|
+
engineEnabled: false,
|
|
30
|
+
engineModel: 'claude-sonnet-4-6',
|
|
31
|
+
worktreeBasePath: '/root/sam/worktrees',
|
|
32
|
+
maxBudgetUsd: 10.0,
|
|
33
|
+
maxBudgetTokens: 500_000,
|
|
34
|
+
maxIterations: 50,
|
|
35
|
+
sessionTimeoutMs: 1_800_000,
|
|
36
|
+
grilloFailMode: 'fail_closed',
|
|
37
|
+
jessieResponseTimeoutMs: 1_800_000,
|
|
29
38
|
};
|
|
30
39
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,QAAQ;IACR,UAAU;IACV,OAAO;IACP,aAAa;IACb,eAAe;IACf,WAAW;CACH,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,CAAC;CACf,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,QAAQ;IACR,UAAU;IACV,OAAO;IACP,aAAa;IACb,eAAe;IACf,WAAW;CACH,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,eAAe,EAAE,CAAC;IAClB,WAAW,EAAE,CAAC;CACf,CAAC;AA6GF,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,WAAW;IACpB,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,oBAAoB;IAClC,WAAW,EAAE,gBAAgB;IAC7B,qBAAqB,EAAE,CAAC;IACxB,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,mBAAmB;IAChC,gBAAgB,EAAE,qBAAqB;IACvC,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,OAAO;IACxB,aAAa,EAAE,EAAE;IACjB,gBAAgB,EAAE,SAAS;IAC3B,cAAc,EAAE,aAAa;IAC7B,uBAAuB,EAAE,SAAS;CACnC,CAAC"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA4GH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QAucxC"}
|
package/dist/plugin.js
CHANGED
|
@@ -34,6 +34,12 @@ import { createExecuteTool } from './tools/sam-execute.js';
|
|
|
34
34
|
import { createSandboxTool } from './tools/sam-sandbox.js';
|
|
35
35
|
import { createTestTool } from './tools/sam-test.js';
|
|
36
36
|
import { createArtifactTool } from './tools/sam-artifact.js';
|
|
37
|
+
import { createEngineerTool } from './tools/sam-engineer.js';
|
|
38
|
+
import { createEngineerStatusTool } from './tools/sam-engineer-status.js';
|
|
39
|
+
import { createEngineerDiffTool } from './tools/sam-engineer-diff.js';
|
|
40
|
+
import { createEngineerResumeTool } from './tools/sam-engineer-resume.js';
|
|
41
|
+
import { createEngineerTerminateTool } from './tools/sam-engineer-terminate.js';
|
|
42
|
+
import { EngineSessionManager } from './tools/engine-session-manager.js';
|
|
37
43
|
import { SamMemory } from './memory/sam-memory.js';
|
|
38
44
|
import { SandboxManager } from './sandbox/sandbox-manager.js';
|
|
39
45
|
import { DEFAULT_CONFIG } from './pipeline/types.js';
|
|
@@ -45,7 +51,6 @@ function resolveOpenClawHome() {
|
|
|
45
51
|
function loadOpenClawConfig() {
|
|
46
52
|
const candidates = [
|
|
47
53
|
path.join(resolveOpenClawHome(), 'openclaw.json'),
|
|
48
|
-
path.join(process.env.HOME || '~', '.clawdbot', 'openclaw.json'),
|
|
49
54
|
];
|
|
50
55
|
for (const configPath of candidates) {
|
|
51
56
|
try {
|
|
@@ -76,6 +81,19 @@ function resolveConfig(api) {
|
|
|
76
81
|
artifactRetentionDays: raw.artifactRetentionDays ?? DEFAULT_CONFIG.artifactRetentionDays,
|
|
77
82
|
telegramToken: raw.telegramToken,
|
|
78
83
|
telegramChatId: raw.telegramChatId,
|
|
84
|
+
engineEnabled: raw.engineEnabled ?? DEFAULT_CONFIG.engineEnabled,
|
|
85
|
+
anthropicApiKey: raw.anthropicApiKey,
|
|
86
|
+
engineModel: raw.engineModel ?? DEFAULT_CONFIG.engineModel,
|
|
87
|
+
worktreeBasePath: raw.worktreeBasePath ?? DEFAULT_CONFIG.worktreeBasePath,
|
|
88
|
+
maxBudgetUsd: raw.maxBudgetUsd ?? DEFAULT_CONFIG.maxBudgetUsd,
|
|
89
|
+
maxBudgetTokens: raw.maxBudgetTokens ?? DEFAULT_CONFIG.maxBudgetTokens,
|
|
90
|
+
maxIterations: raw.maxIterations ?? DEFAULT_CONFIG.maxIterations,
|
|
91
|
+
sessionTimeoutMs: raw.sessionTimeoutMs ?? DEFAULT_CONFIG.sessionTimeoutMs,
|
|
92
|
+
grilloFailMode: raw.grilloFailMode ?? DEFAULT_CONFIG.grilloFailMode,
|
|
93
|
+
jessieResponseTimeoutMs: raw.jessieResponseTimeoutMs ?? DEFAULT_CONFIG.jessieResponseTimeoutMs,
|
|
94
|
+
grilloEndpoint: raw.grilloEndpoint,
|
|
95
|
+
noahEndpoint: raw.noahEndpoint,
|
|
96
|
+
jessieEndpoint: raw.jessieEndpoint,
|
|
79
97
|
};
|
|
80
98
|
}
|
|
81
99
|
// ── Tool Registration Helper ─────────────────────────────────────
|
|
@@ -106,6 +124,14 @@ export default function register(api) {
|
|
|
106
124
|
let validatedToolFactory = null;
|
|
107
125
|
let validationSchemas = {};
|
|
108
126
|
let validationBusinessRules = {};
|
|
127
|
+
// Engine Bridge (Phase 3) — session manager + deferred bridge loader
|
|
128
|
+
const engineSessions = new EngineSessionManager();
|
|
129
|
+
let bridgeLoader = null;
|
|
130
|
+
if (cfg.engineEnabled) {
|
|
131
|
+
const bridgeMod = '@aiassesstech/sam-engine-bridge';
|
|
132
|
+
bridgeLoader = () => import(bridgeMod);
|
|
133
|
+
console.log(`[sam] Engine bridge enabled — model: ${cfg.engineModel}, grilloFailMode: ${cfg.grilloFailMode}`);
|
|
134
|
+
}
|
|
109
135
|
const getFleetBusStatus = () => fleetBusState;
|
|
110
136
|
function validationErrorResponse(message) {
|
|
111
137
|
return {
|
|
@@ -113,7 +139,7 @@ export default function register(api) {
|
|
|
113
139
|
isError: true,
|
|
114
140
|
};
|
|
115
141
|
}
|
|
116
|
-
const ENFORCE_TOOLS = new Set(['sam_execute', 'sam_sandbox']);
|
|
142
|
+
const ENFORCE_TOOLS = new Set(['sam_execute', 'sam_sandbox', 'sam_engineer']);
|
|
117
143
|
let alertBus = null;
|
|
118
144
|
const fleetAlertingMod = '@aiassesstech/fleet-alerting';
|
|
119
145
|
import(fleetAlertingMod)
|
|
@@ -138,7 +164,7 @@ export default function register(api) {
|
|
|
138
164
|
return { ok: true, params: result };
|
|
139
165
|
}
|
|
140
166
|
// ── Phase 1: Management Tools (always available) ────────────
|
|
141
|
-
const statusTool = createStatusTool(pipeline, cfg, getFleetBusStatus);
|
|
167
|
+
const statusTool = createStatusTool(pipeline, cfg, getFleetBusStatus, engineSessions);
|
|
142
168
|
const origStatusExec = statusTool.execute.bind(statusTool);
|
|
143
169
|
statusTool.execute = async function (_toolCallId, params) {
|
|
144
170
|
const v = await validateToolParams('sam_status', _toolCallId, params);
|
|
@@ -208,7 +234,7 @@ export default function register(api) {
|
|
|
208
234
|
return origTestExec(_toolCallId, v.params);
|
|
209
235
|
};
|
|
210
236
|
registerTool(api, testTool);
|
|
211
|
-
const artifactTool = createArtifactTool(sandbox);
|
|
237
|
+
const artifactTool = createArtifactTool(sandbox, engineSessions);
|
|
212
238
|
const origArtifactExec = artifactTool.execute.bind(artifactTool);
|
|
213
239
|
artifactTool.execute = async function (_toolCallId, params) {
|
|
214
240
|
const v = await validateToolParams('sam_artifact', _toolCallId, params);
|
|
@@ -240,6 +266,54 @@ export default function register(api) {
|
|
|
240
266
|
};
|
|
241
267
|
registerTool(api, fleetTaskCompleteTool);
|
|
242
268
|
console.log('[sam] Fleet tools registered: sam_fleet_task_status, sam_fleet_task_complete (fleet context pending)');
|
|
269
|
+
// ── Phase 4: Engine Tools (always registered, engine checked at call time) ───
|
|
270
|
+
// Per rule 155: unconditional registration — availability checked in execute().
|
|
271
|
+
const engineerTool = createEngineerTool(pipeline, cfg, engineSessions, () => samMemory, bridgeLoader);
|
|
272
|
+
const origEngineerExec = engineerTool.execute.bind(engineerTool);
|
|
273
|
+
engineerTool.execute = async function (_toolCallId, params) {
|
|
274
|
+
const v = await validateToolParams('sam_engineer', _toolCallId, params);
|
|
275
|
+
if (!v.ok)
|
|
276
|
+
return validationErrorResponse(v.message);
|
|
277
|
+
return origEngineerExec(_toolCallId, v.params);
|
|
278
|
+
};
|
|
279
|
+
registerTool(api, engineerTool);
|
|
280
|
+
const engineerStatusTool = createEngineerStatusTool(engineSessions);
|
|
281
|
+
const origEngStatusExec = engineerStatusTool.execute.bind(engineerStatusTool);
|
|
282
|
+
engineerStatusTool.execute = async function (_toolCallId, params) {
|
|
283
|
+
const v = await validateToolParams('sam_engineer_status', _toolCallId, params);
|
|
284
|
+
if (!v.ok)
|
|
285
|
+
return validationErrorResponse(v.message);
|
|
286
|
+
return origEngStatusExec(_toolCallId, v.params);
|
|
287
|
+
};
|
|
288
|
+
registerTool(api, engineerStatusTool);
|
|
289
|
+
const engineerDiffTool = createEngineerDiffTool(engineSessions);
|
|
290
|
+
const origEngDiffExec = engineerDiffTool.execute.bind(engineerDiffTool);
|
|
291
|
+
engineerDiffTool.execute = async function (_toolCallId, params) {
|
|
292
|
+
const v = await validateToolParams('sam_engineer_diff', _toolCallId, params);
|
|
293
|
+
if (!v.ok)
|
|
294
|
+
return validationErrorResponse(v.message);
|
|
295
|
+
return origEngDiffExec(_toolCallId, v.params);
|
|
296
|
+
};
|
|
297
|
+
registerTool(api, engineerDiffTool);
|
|
298
|
+
const engineerResumeTool = createEngineerResumeTool(pipeline, engineSessions);
|
|
299
|
+
const origEngResumeExec = engineerResumeTool.execute.bind(engineerResumeTool);
|
|
300
|
+
engineerResumeTool.execute = async function (_toolCallId, params) {
|
|
301
|
+
const v = await validateToolParams('sam_engineer_resume', _toolCallId, params);
|
|
302
|
+
if (!v.ok)
|
|
303
|
+
return validationErrorResponse(v.message);
|
|
304
|
+
return origEngResumeExec(_toolCallId, v.params);
|
|
305
|
+
};
|
|
306
|
+
registerTool(api, engineerResumeTool);
|
|
307
|
+
const engineerTerminateTool = createEngineerTerminateTool(pipeline, engineSessions, () => samMemory);
|
|
308
|
+
const origEngTermExec = engineerTerminateTool.execute.bind(engineerTerminateTool);
|
|
309
|
+
engineerTerminateTool.execute = async function (_toolCallId, params) {
|
|
310
|
+
const v = await validateToolParams('sam_engineer_terminate', _toolCallId, params);
|
|
311
|
+
if (!v.ok)
|
|
312
|
+
return validationErrorResponse(v.message);
|
|
313
|
+
return origEngTermExec(_toolCallId, v.params);
|
|
314
|
+
};
|
|
315
|
+
registerTool(api, engineerTerminateTool);
|
|
316
|
+
console.log(`[sam] Engine tools registered: sam_engineer, sam_engineer_status, sam_engineer_diff, sam_engineer_resume, sam_engineer_terminate (engine=${cfg.engineEnabled ? 'active' : 'inactive'})`);
|
|
243
317
|
// ── Command: /sam ──────────────────────────────────────────
|
|
244
318
|
api.registerCommand({
|
|
245
319
|
name: 'sam',
|
|
@@ -250,14 +324,20 @@ export default function register(api) {
|
|
|
250
324
|
text: '# Sam — Chief Engineer\n\n' +
|
|
251
325
|
'Use Sam\'s tools for engineering pipeline management:\n\n' +
|
|
252
326
|
'**Pipeline Management:**\n' +
|
|
253
|
-
'- **sam_status** — Current state: active ERs, sandbox, fleet-bus\n' +
|
|
327
|
+
'- **sam_status** — Current state: active ERs, sandbox, fleet-bus, engine\n' +
|
|
254
328
|
'- **sam_pipeline** — Full engineering pipeline view with filters\n' +
|
|
255
329
|
'- **sam_request** — Create, update, or close Engineering Requests\n' +
|
|
256
330
|
'- **sam_report** — Engineering reports (summary, detailed, debt)\n\n' +
|
|
257
|
-
'**
|
|
331
|
+
'**Autonomous Engineering Engine:**\n' +
|
|
332
|
+
'- **sam_engineer** — Start/continue an autonomous engineering session for an ER\n' +
|
|
333
|
+
'- **sam_engineer_status** — Session state, cost, files changed, Grillo verdicts\n' +
|
|
334
|
+
'- **sam_engineer_diff** — Git diff from the engine\'s worktree\n' +
|
|
335
|
+
'- **sam_engineer_resume** — Resume a paused session with optional new guidance\n' +
|
|
336
|
+
'- **sam_engineer_terminate** — Hard stop a session (commits in-flight work)\n\n' +
|
|
337
|
+
'**Fleet Communications:**\n' +
|
|
258
338
|
'- **sam_fleet_task_status** — Report ER stage change to Jessie\n' +
|
|
259
339
|
'- **sam_fleet_task_complete** — Signal ER completion to Jessie\n\n' +
|
|
260
|
-
'**Sandbox
|
|
340
|
+
'**Sandbox:**\n' +
|
|
261
341
|
'- **sam_execute** — Run code in Docker sandbox\n' +
|
|
262
342
|
'- **sam_sandbox** — Manage sandbox lifecycle\n' +
|
|
263
343
|
'- **sam_test** — Run test suites in sandbox\n' +
|
|
@@ -281,7 +361,7 @@ export default function register(api) {
|
|
|
281
361
|
// ── Prompt Shield Integration (Behavioral Validation) ───────────
|
|
282
362
|
const promptShieldMod = '@aiassesstech/prompt-shield';
|
|
283
363
|
import(promptShieldMod)
|
|
284
|
-
.then(({ createValidatedToolHandler, sam_execute: samExecuteSchema, SAM_EXECUTE_BUSINESS_RULES, sam_sandbox: samSandboxSchema, sam_status: samStatusSchema, sam_pipeline: samPipelineSchema, sam_request: samRequestSchema, sam_report: samReportSchema, sam_test: samTestSchema, sam_artifact: samArtifactSchema, sam_fleet_task_status: samFleetTaskStatusSchema, sam_fleet_task_complete: samFleetTaskCompleteSchema, }) => {
|
|
364
|
+
.then(({ createValidatedToolHandler, sam_execute: samExecuteSchema, SAM_EXECUTE_BUSINESS_RULES, sam_sandbox: samSandboxSchema, sam_status: samStatusSchema, sam_pipeline: samPipelineSchema, sam_request: samRequestSchema, sam_report: samReportSchema, sam_test: samTestSchema, sam_artifact: samArtifactSchema, sam_fleet_task_status: samFleetTaskStatusSchema, sam_fleet_task_complete: samFleetTaskCompleteSchema, sam_engineer: samEngineerSchema, SAM_ENGINEER_BUSINESS_RULES, sam_engineer_status: samEngineerStatusSchema, sam_engineer_diff: samEngineerDiffSchema, sam_engineer_resume: samEngineerResumeSchema, sam_engineer_terminate: samEngineerTerminateSchema, }) => {
|
|
285
365
|
validatedToolFactory = createValidatedToolHandler;
|
|
286
366
|
validationSchemas = {
|
|
287
367
|
sam_execute: samExecuteSchema,
|
|
@@ -294,11 +374,17 @@ export default function register(api) {
|
|
|
294
374
|
sam_artifact: samArtifactSchema,
|
|
295
375
|
sam_fleet_task_status: samFleetTaskStatusSchema,
|
|
296
376
|
sam_fleet_task_complete: samFleetTaskCompleteSchema,
|
|
377
|
+
sam_engineer: samEngineerSchema,
|
|
378
|
+
sam_engineer_status: samEngineerStatusSchema,
|
|
379
|
+
sam_engineer_diff: samEngineerDiffSchema,
|
|
380
|
+
sam_engineer_resume: samEngineerResumeSchema,
|
|
381
|
+
sam_engineer_terminate: samEngineerTerminateSchema,
|
|
297
382
|
};
|
|
298
383
|
validationBusinessRules = {
|
|
299
384
|
sam_execute: SAM_EXECUTE_BUSINESS_RULES,
|
|
385
|
+
sam_engineer: SAM_ENGINEER_BUSINESS_RULES,
|
|
300
386
|
};
|
|
301
|
-
console.log('[sam] Behavioral validation active:
|
|
387
|
+
console.log('[sam] Behavioral validation active: 15 tools (sam_execute/sam_sandbox/sam_engineer enforce, rest monitor)');
|
|
302
388
|
})
|
|
303
389
|
.catch(() => {
|
|
304
390
|
console.warn('[sam] Prompt shield unavailable — behavioral validation disabled');
|
|
@@ -326,6 +412,9 @@ export default function register(api) {
|
|
|
326
412
|
'task/assign',
|
|
327
413
|
'task/cancel',
|
|
328
414
|
'task/priority_change',
|
|
415
|
+
'task/budget-request',
|
|
416
|
+
'task/escalation',
|
|
417
|
+
'task/redirect',
|
|
329
418
|
'veto/issue',
|
|
330
419
|
'fleet/ping',
|
|
331
420
|
'fleet/pong',
|
|
@@ -344,11 +433,20 @@ export default function register(api) {
|
|
|
344
433
|
else if (method === 'task/priority_change') {
|
|
345
434
|
await handleTaskPriorityChange(msg, pipeline, fleetContext);
|
|
346
435
|
}
|
|
436
|
+
else if (method === 'task/budget-request') {
|
|
437
|
+
await handleBudgetRequest(msg, pipeline, fleetContext, engineSessions);
|
|
438
|
+
}
|
|
439
|
+
else if (method === 'task/escalation') {
|
|
440
|
+
await handleEscalation(msg, pipeline, fleetContext, engineSessions);
|
|
441
|
+
}
|
|
442
|
+
else if (method === 'task/redirect') {
|
|
443
|
+
await handleRedirect(msg, pipeline, fleetContext, engineSessions);
|
|
444
|
+
}
|
|
347
445
|
else if (method === 'veto/issue') {
|
|
348
446
|
await handleVetoIssue(msg, pipeline, samMemory);
|
|
349
447
|
}
|
|
350
448
|
else if (method === 'fleet/ping') {
|
|
351
|
-
await handleFleetPing(msg, pipeline, cfg, fleetContext);
|
|
449
|
+
await handleFleetPing(msg, pipeline, cfg, fleetContext, engineSessions);
|
|
352
450
|
}
|
|
353
451
|
},
|
|
354
452
|
});
|
|
@@ -368,6 +466,8 @@ export default function register(api) {
|
|
|
368
466
|
'sam_status', 'sam_pipeline', 'sam_request', 'sam_report',
|
|
369
467
|
'sam_execute', 'sam_sandbox', 'sam_test', 'sam_artifact',
|
|
370
468
|
'sam_fleet_task_status', 'sam_fleet_task_complete',
|
|
469
|
+
'sam_engineer', 'sam_engineer_status', 'sam_engineer_diff',
|
|
470
|
+
'sam_engineer_resume', 'sam_engineer_terminate',
|
|
371
471
|
].join(', ');
|
|
372
472
|
let capturedWorkspaceDir = null;
|
|
373
473
|
api.registerHook("agent:bootstrap", async (event) => {
|
|
@@ -557,7 +657,7 @@ async function handleTaskPriorityChange(msg, pipeline, fleet) {
|
|
|
557
657
|
console.error(`[sam] Failed to handle task/priority_change: ${err}`);
|
|
558
658
|
}
|
|
559
659
|
}
|
|
560
|
-
async function handleFleetPing(msg, pipeline, cfg, fleet) {
|
|
660
|
+
async function handleFleetPing(msg, pipeline, cfg, fleet, engineSessions) {
|
|
561
661
|
const summary = pipeline.getSummary();
|
|
562
662
|
try {
|
|
563
663
|
await fleet.fleetSend(fleet.bus, fleet.transport, {
|
|
@@ -566,11 +666,13 @@ async function handleFleetPing(msg, pipeline, cfg, fleet) {
|
|
|
566
666
|
params: {
|
|
567
667
|
agentId: 'sam',
|
|
568
668
|
currentStatus: 'active',
|
|
569
|
-
toolCount:
|
|
669
|
+
toolCount: 15,
|
|
570
670
|
pendingTasks: summary.active,
|
|
571
671
|
activeERs: summary.active,
|
|
572
672
|
blockedERs: summary.blocked,
|
|
573
673
|
sandboxStatus: cfg.sandboxEnabled ? 'available' : 'unavailable',
|
|
674
|
+
engineStatus: cfg.engineEnabled ? 'enabled' : 'disabled',
|
|
675
|
+
activeEngineSessions: engineSessions?.activeCount() ?? 0,
|
|
574
676
|
memoryUsageMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
|
|
575
677
|
uptimeMs: process.uptime() * 1000,
|
|
576
678
|
},
|
|
@@ -581,4 +683,130 @@ async function handleFleetPing(msg, pipeline, cfg, fleet) {
|
|
|
581
683
|
console.error(`[sam] Failed to send fleet/pong: ${err}`);
|
|
582
684
|
}
|
|
583
685
|
}
|
|
686
|
+
// ── Engine-related Fleet Inbound Handlers ────────────────────────
|
|
687
|
+
async function handleBudgetRequest(msg, pipeline, fleet, engineSessions) {
|
|
688
|
+
const p = msg.params ?? {};
|
|
689
|
+
const erId = p.taskId ?? p.er_id;
|
|
690
|
+
if (!erId) {
|
|
691
|
+
console.warn('[sam] task/budget-request received without taskId — ignoring');
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
const session = engineSessions.get(erId);
|
|
695
|
+
if (!session) {
|
|
696
|
+
await fleet.fleetSend(fleet.bus, fleet.transport, {
|
|
697
|
+
to: msg.from ?? 'jessie',
|
|
698
|
+
method: 'task/status',
|
|
699
|
+
params: {
|
|
700
|
+
taskId: erId,
|
|
701
|
+
agentId: 'sam',
|
|
702
|
+
status: 'no_session',
|
|
703
|
+
details: `No active engine session for ${erId}`,
|
|
704
|
+
},
|
|
705
|
+
correlationId: msg.id,
|
|
706
|
+
});
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
try {
|
|
710
|
+
const usage = await session.getUsage();
|
|
711
|
+
await fleet.fleetSend(fleet.bus, fleet.transport, {
|
|
712
|
+
to: msg.from ?? 'jessie',
|
|
713
|
+
method: 'task/status',
|
|
714
|
+
params: {
|
|
715
|
+
taskId: erId,
|
|
716
|
+
agentId: 'sam',
|
|
717
|
+
status: 'budget_report',
|
|
718
|
+
usage: {
|
|
719
|
+
totalInputTokens: usage.totalInputTokens,
|
|
720
|
+
totalOutputTokens: usage.totalOutputTokens,
|
|
721
|
+
totalCostUsd: usage.totalCostUsdCents / 100,
|
|
722
|
+
turns: usage.turnCount,
|
|
723
|
+
},
|
|
724
|
+
},
|
|
725
|
+
correlationId: msg.id,
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
catch (err) {
|
|
729
|
+
console.error(`[sam] Failed to handle task/budget-request for ${erId}: ${err}`);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
async function handleEscalation(msg, pipeline, fleet, engineSessions) {
|
|
733
|
+
const p = msg.params ?? {};
|
|
734
|
+
const erId = p.taskId ?? p.er_id;
|
|
735
|
+
const action = p.action ?? 'terminate';
|
|
736
|
+
const reason = p.reason ?? 'Escalation from fleet';
|
|
737
|
+
if (!erId) {
|
|
738
|
+
console.warn('[sam] task/escalation received without taskId — ignoring');
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
const session = engineSessions.get(erId);
|
|
742
|
+
if (!session) {
|
|
743
|
+
console.warn(`[sam] task/escalation for ${erId} but no active session`);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
try {
|
|
747
|
+
if (action === 'terminate') {
|
|
748
|
+
await session.terminate();
|
|
749
|
+
engineSessions.delete(erId);
|
|
750
|
+
await pipeline.handleRequest({
|
|
751
|
+
action: 'update',
|
|
752
|
+
er_id: erId,
|
|
753
|
+
blocker: `ESCALATION TERMINATED: ${reason}`,
|
|
754
|
+
notes: `Engine terminated via fleet escalation from ${msg.from}: ${reason}`,
|
|
755
|
+
}).catch(() => { });
|
|
756
|
+
await fleet.fleetSend(fleet.bus, fleet.transport, {
|
|
757
|
+
to: msg.from ?? 'jessie',
|
|
758
|
+
method: 'task/complete',
|
|
759
|
+
params: {
|
|
760
|
+
taskId: erId,
|
|
761
|
+
success: false,
|
|
762
|
+
result: `Terminated via escalation: ${reason}`,
|
|
763
|
+
status: 'terminated',
|
|
764
|
+
},
|
|
765
|
+
correlationId: msg.id,
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
console.log(`[sam] Escalation handled for ${erId}: ${action} — ${reason}`);
|
|
769
|
+
}
|
|
770
|
+
catch (err) {
|
|
771
|
+
console.error(`[sam] Failed to handle task/escalation for ${erId}: ${err}`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
async function handleRedirect(msg, pipeline, fleet, engineSessions) {
|
|
775
|
+
const p = msg.params ?? {};
|
|
776
|
+
const erId = p.taskId ?? p.er_id;
|
|
777
|
+
const newGuidance = p.guidance ?? p.instructions ?? 'Redirect received — adjust approach.';
|
|
778
|
+
if (!erId) {
|
|
779
|
+
console.warn('[sam] task/redirect received without taskId — ignoring');
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
const session = engineSessions.get(erId);
|
|
783
|
+
if (!session) {
|
|
784
|
+
console.warn(`[sam] task/redirect for ${erId} but no active session`);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
try {
|
|
788
|
+
const result = await session.sendTurn(newGuidance);
|
|
789
|
+
await pipeline.handleRequest({
|
|
790
|
+
action: 'update',
|
|
791
|
+
er_id: erId,
|
|
792
|
+
notes: `[redirect] from ${msg.from}: ${newGuidance.slice(0, 100)}`,
|
|
793
|
+
}).catch(() => { });
|
|
794
|
+
await fleet.fleetSend(fleet.bus, fleet.transport, {
|
|
795
|
+
to: msg.from ?? 'jessie',
|
|
796
|
+
method: 'task/status',
|
|
797
|
+
params: {
|
|
798
|
+
taskId: erId,
|
|
799
|
+
agentId: 'sam',
|
|
800
|
+
status: result.success ? 'completed' : 'in_progress',
|
|
801
|
+
details: `Redirect processed: ${result.iterations} iterations, ${result.toolCalls.length} tool calls`,
|
|
802
|
+
success: result.success,
|
|
803
|
+
},
|
|
804
|
+
correlationId: msg.id,
|
|
805
|
+
});
|
|
806
|
+
console.log(`[sam] Redirect processed for ${erId} from ${msg.from}`);
|
|
807
|
+
}
|
|
808
|
+
catch (err) {
|
|
809
|
+
console.error(`[sam] Failed to handle task/redirect for ${erId}: ${err}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
584
812
|
//# sourceMappingURL=plugin.js.map
|