agent-companion 0.1.6 → 0.1.7
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/bridge/directIngest.mjs +40 -7
- package/bridge/server.mjs +11 -9
- package/package.json +1 -1
package/bridge/directIngest.mjs
CHANGED
|
@@ -28,6 +28,8 @@ const MAX_JSONL_TAIL_BYTES = 1_500_000;
|
|
|
28
28
|
const MAX_JSONL_TAIL_LINES = 1200;
|
|
29
29
|
const DIRECT_RUNNING_FRESH_WINDOW_SEC = 20;
|
|
30
30
|
const DIRECT_RUNNING_STALE_TIMEOUT_SEC = 180;
|
|
31
|
+
const INTERNAL_PLAN_MODE_SUFFIX =
|
|
32
|
+
"You are in PLAN MODE. Do not implement changes yet. Return only a concrete plan, then end with a single explicit approval question asking whether to proceed with implementation.";
|
|
31
33
|
const PENDING_PATTERN =
|
|
32
34
|
/input required|needs input|waiting for input|approval[_\s-]*required|awaiting approval|please approve|approve (?:this|the) plan|should i (?:proceed|implement|execute)|would you like me to (?:proceed|implement|execute)|ready to (?:implement|execute)|want me to (?:implement|execute)|proceed with implementation/i;
|
|
33
35
|
|
|
@@ -217,7 +219,7 @@ function parseCodexFile(file, nowMs) {
|
|
|
217
219
|
}
|
|
218
220
|
|
|
219
221
|
if (record.type === "event_msg" && record.payload?.type === "user_message") {
|
|
220
|
-
const message =
|
|
222
|
+
const message = normalizeVisibleUserText(record.payload?.message || "");
|
|
221
223
|
flushPendingAssistant();
|
|
222
224
|
if (message && !isNoisePrompt(message) && !firstPrompt) firstPrompt = message;
|
|
223
225
|
appendDirectTurn(chatTurns, {
|
|
@@ -271,7 +273,7 @@ function parseCodexFile(file, nowMs) {
|
|
|
271
273
|
if (record.type === "response_item" && record.payload?.type === "message") {
|
|
272
274
|
const role = record.payload?.role;
|
|
273
275
|
if (role === "user") {
|
|
274
|
-
const text = extractCodexText(record.payload?.content);
|
|
276
|
+
const text = normalizeVisibleUserText(extractCodexText(record.payload?.content));
|
|
275
277
|
flushPendingAssistant();
|
|
276
278
|
if (text && !isNoisePrompt(text) && !firstPrompt) firstPrompt = text;
|
|
277
279
|
appendDirectTurn(chatTurns, {
|
|
@@ -622,7 +624,7 @@ function formatCodexToolCall(item) {
|
|
|
622
624
|
function extractClaudeUserText(message) {
|
|
623
625
|
if (!message) return "";
|
|
624
626
|
if (typeof message.content === "string") {
|
|
625
|
-
const text =
|
|
627
|
+
const text = normalizeVisibleUserText(message.content);
|
|
626
628
|
return shouldIncludeDirectUserText(text) ? text : "";
|
|
627
629
|
}
|
|
628
630
|
if (!Array.isArray(message.content)) return "";
|
|
@@ -630,7 +632,7 @@ function extractClaudeUserText(message) {
|
|
|
630
632
|
const collected = [];
|
|
631
633
|
for (const part of message.content) {
|
|
632
634
|
if (typeof part === "string") {
|
|
633
|
-
const text =
|
|
635
|
+
const text = normalizeVisibleUserText(part);
|
|
634
636
|
if (shouldIncludeDirectUserText(text)) {
|
|
635
637
|
collected.push(text);
|
|
636
638
|
}
|
|
@@ -639,20 +641,20 @@ function extractClaudeUserText(message) {
|
|
|
639
641
|
const partType = String(part?.type || "").trim().toLowerCase();
|
|
640
642
|
if (partType && partType !== "text" && partType !== "input_text") continue;
|
|
641
643
|
if (typeof part?.text === "string") {
|
|
642
|
-
const text =
|
|
644
|
+
const text = normalizeVisibleUserText(part.text);
|
|
643
645
|
if (shouldIncludeDirectUserText(text)) {
|
|
644
646
|
collected.push(text);
|
|
645
647
|
}
|
|
646
648
|
}
|
|
647
649
|
if (typeof part?.content === "string" && part.content.trim()) {
|
|
648
|
-
const text =
|
|
650
|
+
const text = normalizeVisibleUserText(part.content);
|
|
649
651
|
if (shouldIncludeDirectUserText(text)) {
|
|
650
652
|
collected.push(text);
|
|
651
653
|
}
|
|
652
654
|
}
|
|
653
655
|
}
|
|
654
656
|
|
|
655
|
-
return collected.join("\n\n").trim();
|
|
657
|
+
return dedupeCollectedText(collected).join("\n\n").trim();
|
|
656
658
|
}
|
|
657
659
|
|
|
658
660
|
function extractClaudeAssistantText(message) {
|
|
@@ -869,6 +871,37 @@ function sanitizeDirectText(value) {
|
|
|
869
871
|
.trim();
|
|
870
872
|
}
|
|
871
873
|
|
|
874
|
+
function normalizeVisibleUserText(value) {
|
|
875
|
+
const text = sanitizeDirectText(value);
|
|
876
|
+
if (!text) return "";
|
|
877
|
+
|
|
878
|
+
return text
|
|
879
|
+
.replace(new RegExp(`(?:\\n\\s*)*${escapeRegExp(INTERNAL_PLAN_MODE_SUFFIX)}\\s*$`, "i"), "")
|
|
880
|
+
.trim();
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
function dedupeCollectedText(values) {
|
|
884
|
+
const deduped = [];
|
|
885
|
+
const seen = new Set();
|
|
886
|
+
|
|
887
|
+
for (const value of values) {
|
|
888
|
+
const text = String(value || "").trim();
|
|
889
|
+
if (!text) continue;
|
|
890
|
+
|
|
891
|
+
const normalized = normalizeComparableText(text);
|
|
892
|
+
if (!normalized || seen.has(normalized)) continue;
|
|
893
|
+
|
|
894
|
+
seen.add(normalized);
|
|
895
|
+
deduped.push(text);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
return deduped;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function escapeRegExp(value) {
|
|
902
|
+
return String(value || "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
903
|
+
}
|
|
904
|
+
|
|
872
905
|
function getRecentJsonlFiles(rootDir, limit) {
|
|
873
906
|
const now = Date.now();
|
|
874
907
|
const cached = recentFilesCache.get(rootDir);
|
package/bridge/server.mjs
CHANGED
|
@@ -1333,11 +1333,7 @@ function normalizeCommandList(input, agentType, prompt) {
|
|
|
1333
1333
|
}
|
|
1334
1334
|
|
|
1335
1335
|
function buildPlanPrompt(prompt) {
|
|
1336
|
-
|
|
1337
|
-
if (!base) return "";
|
|
1338
|
-
const suffix =
|
|
1339
|
-
"\n\nYou are in PLAN MODE. Do not implement changes yet. Return only a concrete plan, then end with a single explicit approval question asking whether to proceed with implementation.";
|
|
1340
|
-
return safeTrimmedText(`${base}${suffix}`, 1900);
|
|
1336
|
+
return safeTrimmedText(prompt, 1500);
|
|
1341
1337
|
}
|
|
1342
1338
|
|
|
1343
1339
|
function createLauncherRun(input) {
|
|
@@ -2527,13 +2523,19 @@ function mergeDirectSnapshot(snapshot) {
|
|
|
2527
2523
|
.map((item) => item?.id)
|
|
2528
2524
|
.filter((id) => typeof id === "string")
|
|
2529
2525
|
);
|
|
2526
|
+
const incomingDirectTurnSessionIds = new Set(
|
|
2527
|
+
(Array.isArray(snapshot.chatTurns) ? snapshot.chatTurns : [])
|
|
2528
|
+
.map((item) => safeTrimmedText(item?.sessionId, 160))
|
|
2529
|
+
.filter(Boolean)
|
|
2530
|
+
);
|
|
2530
2531
|
state.chatTurns = (Array.isArray(state.chatTurns) ? state.chatTurns : []).filter((item) => {
|
|
2531
2532
|
const sessionId = String(item?.sessionId || "");
|
|
2532
|
-
const isDirectSession = sessionId.startsWith("codex:") || sessionId.startsWith("claude:");
|
|
2533
2533
|
const isDirectTurn = safeTrimmedText(item?.source, 48).toUpperCase() === "DIRECT" || String(item?.id || "").startsWith("direct:");
|
|
2534
|
-
if (!
|
|
2535
|
-
if (
|
|
2536
|
-
|
|
2534
|
+
if (!isDirectTurn) return true;
|
|
2535
|
+
if (incomingDirectTurnIds.has(item.id)) return true;
|
|
2536
|
+
if (incomingDirectTurnSessionIds.has(sessionId)) return false;
|
|
2537
|
+
if (incomingDirectSessionIds.has(sessionId)) return false;
|
|
2538
|
+
return true;
|
|
2537
2539
|
});
|
|
2538
2540
|
|
|
2539
2541
|
const existingTurns = new Map((Array.isArray(state.chatTurns) ? state.chatTurns : []).map((item) => [item.id, item]));
|