@engineeros/connector 0.8.8 → 0.9.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 +29 -11
- package/bin/engineeros-connector.mjs +168 -78
- package/package.json +2 -2
- package/src/acp-client.mjs +348 -84
- package/src/agent-harness.mjs +108 -0
- package/src/agent-registry.mjs +643 -0
- package/src/capabilities.mjs +2 -0
- package/src/config.mjs +7 -0
- package/src/runner.mjs +78 -23
- package/src/skills/change-planning/SKILL.md +12 -0
- package/src/skills/change-verification/SKILL.md +12 -0
- package/src/skills/codebase-research/SKILL.md +12 -0
- package/src/skills/goal-execution/SKILL.md +12 -0
package/src/runner.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import path from "node:path";
|
|
|
12
12
|
import { promisify } from "node:util";
|
|
13
13
|
import { deflateRaw } from "node:zlib";
|
|
14
14
|
import { launchAcpAgent } from "./acp-client.mjs";
|
|
15
|
+
import { buildAgentHarnessPrompt } from "./agent-harness.mjs";
|
|
15
16
|
|
|
16
17
|
const deflate = promisify(deflateRaw);
|
|
17
18
|
const MAX_ARCHIVE_BYTES = 25 * 1024 * 1024;
|
|
@@ -117,7 +118,15 @@ export async function executeAssignment(assignment, config, callbacks) {
|
|
|
117
118
|
);
|
|
118
119
|
const verifier = launchAgentProcess(
|
|
119
120
|
runWorkspace,
|
|
120
|
-
|
|
121
|
+
buildAgentHarnessPrompt({
|
|
122
|
+
agentRole: "verification",
|
|
123
|
+
prompt: verificationPrompt(
|
|
124
|
+
assignment,
|
|
125
|
+
committed.revision,
|
|
126
|
+
committed.changedFiles,
|
|
127
|
+
),
|
|
128
|
+
sandboxMode: "read-only",
|
|
129
|
+
}),
|
|
121
130
|
"read-only",
|
|
122
131
|
config,
|
|
123
132
|
callbacks,
|
|
@@ -485,7 +494,12 @@ export async function executeConnectedPrompt(assignment, config, callbacks) {
|
|
|
485
494
|
callbacks,
|
|
486
495
|
execution.profile,
|
|
487
496
|
previousSessionId,
|
|
497
|
+
{
|
|
498
|
+
persistentAcp: true,
|
|
499
|
+
sessionKey: execution.sessionKey,
|
|
500
|
+
},
|
|
488
501
|
);
|
|
502
|
+
callbacks.onController?.(controller);
|
|
489
503
|
callbacks.onProcess?.(controller.child);
|
|
490
504
|
const completed = await controller.completed;
|
|
491
505
|
const content = completed.finalMessage.trim();
|
|
@@ -510,7 +524,7 @@ export async function inspectCodingAgent(config, workspace = process.cwd()) {
|
|
|
510
524
|
return {
|
|
511
525
|
protocol: "acp",
|
|
512
526
|
name: config.agent_name || path.basename(config.agent_command),
|
|
513
|
-
version: "ACP v1",
|
|
527
|
+
version: config.agent_version || "ACP v1",
|
|
514
528
|
};
|
|
515
529
|
}
|
|
516
530
|
const codex = await inspectCodexCli(workspace);
|
|
@@ -595,17 +609,35 @@ export function promptProgressMessage(event) {
|
|
|
595
609
|
return null;
|
|
596
610
|
}
|
|
597
611
|
|
|
598
|
-
export function
|
|
599
|
-
if (
|
|
600
|
-
|
|
612
|
+
export function promptStreamEvent(event) {
|
|
613
|
+
if (!event || typeof event !== "object") return null;
|
|
614
|
+
if (
|
|
615
|
+
event.type === "acp.agent_message_chunk" &&
|
|
616
|
+
event.update?.content?.type === "text"
|
|
617
|
+
) {
|
|
618
|
+
return { kind: "message", delta: event.update.content.text };
|
|
619
|
+
}
|
|
620
|
+
if (event.type === "acp.agent_thought_chunk") {
|
|
621
|
+
return {
|
|
622
|
+
kind: "thought",
|
|
623
|
+
message: "Agent is reasoning through the request",
|
|
624
|
+
};
|
|
601
625
|
}
|
|
602
|
-
if (
|
|
603
|
-
return "
|
|
626
|
+
if (event.type === "acp.plan") {
|
|
627
|
+
return { kind: "plan", message: "Agent updated the working plan" };
|
|
604
628
|
}
|
|
605
|
-
if (
|
|
606
|
-
return
|
|
629
|
+
if (event.type === "acp.tool_call" || event.type === "acp.tool_call_update") {
|
|
630
|
+
return {
|
|
631
|
+
kind: "tool",
|
|
632
|
+
message: event.update?.title || "Agent is inspecting the workspace",
|
|
633
|
+
status: event.update?.status,
|
|
634
|
+
};
|
|
607
635
|
}
|
|
608
|
-
|
|
636
|
+
if (event.type === "item.completed" && event.item?.type === "agent_message") {
|
|
637
|
+
return { kind: "message", delta: event.item.text };
|
|
638
|
+
}
|
|
639
|
+
const message = promptProgressMessage(event);
|
|
640
|
+
return message ? { kind: "status", message } : null;
|
|
609
641
|
}
|
|
610
642
|
|
|
611
643
|
function assessmentCommandMilestone(command) {
|
|
@@ -633,8 +665,8 @@ function assessmentCommandMilestone(command) {
|
|
|
633
665
|
}
|
|
634
666
|
|
|
635
667
|
export function connectorExecution(assignment) {
|
|
636
|
-
const
|
|
637
|
-
if (typeof
|
|
668
|
+
const rawPrompt = assignment?.prompt_markdown;
|
|
669
|
+
if (typeof rawPrompt !== "string" || !rawPrompt.trim()) {
|
|
638
670
|
throw new Error("EngineerOS assignment is missing prompt_markdown.");
|
|
639
671
|
}
|
|
640
672
|
const sandboxMode = assignment?.sandbox_mode;
|
|
@@ -653,13 +685,26 @@ export function connectorExecution(assignment) {
|
|
|
653
685
|
"EngineerOS assignment has an unsupported reasoning effort.",
|
|
654
686
|
);
|
|
655
687
|
}
|
|
688
|
+
const agentRole = assignment?.agent_role;
|
|
689
|
+
const prompt = buildAgentHarnessPrompt({
|
|
690
|
+
agentRole,
|
|
691
|
+
prompt: rawPrompt,
|
|
692
|
+
sandboxMode,
|
|
693
|
+
});
|
|
656
694
|
return {
|
|
657
695
|
prompt,
|
|
696
|
+
agentRole,
|
|
658
697
|
sandboxMode,
|
|
659
698
|
sessionKey:
|
|
660
|
-
typeof assignment.session_key === "string" &&
|
|
699
|
+
typeof assignment.session_key === "string" &&
|
|
700
|
+
assignment.session_key.trim()
|
|
661
701
|
? assignment.session_key.trim()
|
|
662
|
-
: `project-${String(
|
|
702
|
+
: `project-${String(agentRole)}-${String(
|
|
703
|
+
assignment.purpose || "general",
|
|
704
|
+
)
|
|
705
|
+
.toLowerCase()
|
|
706
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
707
|
+
.slice(0, 80)}`,
|
|
663
708
|
profile: {
|
|
664
709
|
...(model ? { model } : {}),
|
|
665
710
|
...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),
|
|
@@ -830,7 +875,10 @@ function launchCodexProcess(
|
|
|
830
875
|
if (!line.trim()) continue;
|
|
831
876
|
try {
|
|
832
877
|
const event = JSON.parse(line);
|
|
833
|
-
if (
|
|
878
|
+
if (
|
|
879
|
+
event.type === "thread.started" &&
|
|
880
|
+
typeof event.thread_id === "string"
|
|
881
|
+
) {
|
|
834
882
|
sessionId = event.thread_id;
|
|
835
883
|
}
|
|
836
884
|
if (
|
|
@@ -860,8 +908,14 @@ function launchCodexProcess(
|
|
|
860
908
|
const completed = new Promise((resolve, reject) => {
|
|
861
909
|
child.once("error", reject);
|
|
862
910
|
child.once("close", (code) => {
|
|
863
|
-
if (code === 0 && sessionId)
|
|
864
|
-
|
|
911
|
+
if (code === 0 && sessionId)
|
|
912
|
+
resolve({ output: output.slice(-20_000), finalMessage, sessionId });
|
|
913
|
+
else if (code === 0)
|
|
914
|
+
reject(
|
|
915
|
+
new Error(
|
|
916
|
+
"Codex completed without announcing a resumable session id.",
|
|
917
|
+
),
|
|
918
|
+
);
|
|
865
919
|
else reject(new Error(codexFailureMessage(output, code)));
|
|
866
920
|
});
|
|
867
921
|
});
|
|
@@ -937,12 +991,13 @@ function launchAgentProcess(
|
|
|
937
991
|
mcpContext,
|
|
938
992
|
) {
|
|
939
993
|
if (config.agent_protocol === "acp") {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
994
|
+
return launchAcpAgent(workspace, prompt, config, callbacks, {
|
|
995
|
+
persistent: mcpContext?.persistentAcp === true,
|
|
996
|
+
sessionKey: mcpContext?.sessionKey,
|
|
997
|
+
previousSessionId,
|
|
998
|
+
sandbox,
|
|
999
|
+
profile,
|
|
1000
|
+
});
|
|
946
1001
|
}
|
|
947
1002
|
return launchCodexProcess(
|
|
948
1003
|
workspace,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: change-planning
|
|
3
|
+
description: Produce a decision-complete implementation plan grounded in the connected repository.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Change Planning
|
|
7
|
+
|
|
8
|
+
1. Inspect current behavior, ownership boundaries, call paths, tests, and project instructions before proposing changes.
|
|
9
|
+
2. Define the intended outcome, affected components, non-goals, risks, and proof of completion.
|
|
10
|
+
3. Resolve questions answerable from the repository. Label only genuinely unavailable facts as assumptions.
|
|
11
|
+
4. Sequence bounded implementation steps with the files or symbols each step affects and the verification it requires.
|
|
12
|
+
5. Stay read-only and hand off a plan that an implementation Agent can execute without rediscovering the problem.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: change-verification
|
|
3
|
+
description: Independently verify a completed change against its explicit proof contract.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Change Verification
|
|
7
|
+
|
|
8
|
+
1. Inspect the exact supplied revision, changed paths, Goal boundaries, constraints, and every Proof item.
|
|
9
|
+
2. Run or inspect each check independently; do not rely on the implementation Agent's claims.
|
|
10
|
+
3. Stay read-only. Do not repair failures, edit files, install dependencies, commit, or push.
|
|
11
|
+
4. Mark a check passed only when directly observed evidence matches its expected result.
|
|
12
|
+
5. Return the requested structured verification report with concise commands, exit codes, and evidence.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-research
|
|
3
|
+
description: Investigate a connected repository and answer from directly observed evidence.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Codebase Research
|
|
7
|
+
|
|
8
|
+
1. Define the exact question and inspect the smallest relevant surface first.
|
|
9
|
+
2. Trace callers, dependencies, data flow, configuration, and tests when they materially affect the answer.
|
|
10
|
+
3. Separate observed facts from inferences and cite concrete repository paths for important claims.
|
|
11
|
+
4. Stay read-only. Do not install, generate, edit, delete, commit, or start long-running services.
|
|
12
|
+
5. Return the answer first, followed by supporting evidence and unresolved gaps only when they matter.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: goal-execution
|
|
3
|
+
description: Implement one bounded EngineerOS Goal and prove the resulting behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Goal Execution
|
|
7
|
+
|
|
8
|
+
1. Read the complete Goal packet, repository instructions, current Git state, and relevant implementation paths.
|
|
9
|
+
2. Implement the smallest coherent change that satisfies the included outcome and constraints.
|
|
10
|
+
3. Preserve unrelated user changes and stay inside the stated boundary; stop only for a genuine missing authority or prerequisite.
|
|
11
|
+
4. Run focused checks while working, then the proportionate final tests, lint, type checks, or build required by the Goal.
|
|
12
|
+
5. Do not commit or push. EngineerOS creates the isolated run commit after the implementation completes.
|