negotium 0.1.34 → 0.1.35
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/dist/agent-helpers.js +25 -2
- package/dist/agent-helpers.js.map +4 -4
- package/dist/cron.js +51 -3
- package/dist/cron.js.map +4 -4
- package/dist/hosted-agent.js +25 -2
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +127 -330
- package/dist/main.js.map +9 -9
- package/dist/runtime/src/agents/tool-format.ts +48 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +2 -1
package/dist/main.js
CHANGED
|
@@ -3919,7 +3919,7 @@ var init_claude_provider = __esm(async () => {
|
|
|
3919
3919
|
});
|
|
3920
3920
|
|
|
3921
3921
|
// ../../packages/core/src/version.ts
|
|
3922
|
-
var NEGOTIUM_VERSION = "0.1.
|
|
3922
|
+
var NEGOTIUM_VERSION = "0.1.35";
|
|
3923
3923
|
|
|
3924
3924
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3925
3925
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -4275,6 +4275,29 @@ function summarizeTargets(values) {
|
|
|
4275
4275
|
return targets[0] ?? "";
|
|
4276
4276
|
return `${targets[0]} +${targets.length - 1}`;
|
|
4277
4277
|
}
|
|
4278
|
+
function summarizeSsh(words) {
|
|
4279
|
+
let destination = "";
|
|
4280
|
+
let index = 0;
|
|
4281
|
+
while (index < words.length) {
|
|
4282
|
+
const word = words[index] ?? "";
|
|
4283
|
+
if (word === "--") {
|
|
4284
|
+
destination = words[index + 1] ?? "";
|
|
4285
|
+
index += 2;
|
|
4286
|
+
break;
|
|
4287
|
+
}
|
|
4288
|
+
if (!word.startsWith("-")) {
|
|
4289
|
+
destination = word;
|
|
4290
|
+
index += 1;
|
|
4291
|
+
break;
|
|
4292
|
+
}
|
|
4293
|
+
index += SSH_OPTIONS_WITH_VALUE.has(word) ? 2 : 1;
|
|
4294
|
+
}
|
|
4295
|
+
if (!destination)
|
|
4296
|
+
return "ssh";
|
|
4297
|
+
const remoteCommand = words.slice(index).join(" ");
|
|
4298
|
+
const remoteSummary = remoteCommand ? summarizeShellCommand(remoteCommand) : "";
|
|
4299
|
+
return ["ssh", destination, remoteSummary].filter(Boolean).join(" \xB7 ");
|
|
4300
|
+
}
|
|
4278
4301
|
function summarizeShellPart(value) {
|
|
4279
4302
|
const words = shellWords(value).filter((word) => !/^\d*>/.test(word));
|
|
4280
4303
|
while (words[0] === "sudo")
|
|
@@ -4294,6 +4317,8 @@ function summarizeShellPart(value) {
|
|
|
4294
4317
|
if (executable === "command" && words[0] === "-v") {
|
|
4295
4318
|
return words[1] ? `find ${commandName(words[1])}` : "find command";
|
|
4296
4319
|
}
|
|
4320
|
+
if (executable === "ssh")
|
|
4321
|
+
return summarizeSsh(words);
|
|
4297
4322
|
if (executable === "git") {
|
|
4298
4323
|
while (words[0]?.startsWith("-")) {
|
|
4299
4324
|
const option = words.shift();
|
|
@@ -4592,8 +4617,31 @@ function formatToolUse(name, input) {
|
|
|
4592
4617
|
}
|
|
4593
4618
|
return displayName;
|
|
4594
4619
|
}
|
|
4595
|
-
var TOOL_SUMMARY_MAX_CHARS = 90, TOOL_SUMMARY_HEAD_CHARS = 52, TOOL_SUMMARY_TAIL_CHARS = 28, TOOL_DIFF_MAX_CHARS = 4000, TOOL_DIFF_SOURCE_MAX_BYTES = 2000000, SHELL_SUMMARY_MAX_PARTS = 3, SUMMARY_KEYS;
|
|
4620
|
+
var TOOL_SUMMARY_MAX_CHARS = 90, TOOL_SUMMARY_HEAD_CHARS = 52, TOOL_SUMMARY_TAIL_CHARS = 28, TOOL_DIFF_MAX_CHARS = 4000, TOOL_DIFF_SOURCE_MAX_BYTES = 2000000, SHELL_SUMMARY_MAX_PARTS = 3, SSH_OPTIONS_WITH_VALUE, SUMMARY_KEYS;
|
|
4596
4621
|
var init_tool_format = __esm(() => {
|
|
4622
|
+
SSH_OPTIONS_WITH_VALUE = new Set([
|
|
4623
|
+
"-B",
|
|
4624
|
+
"-b",
|
|
4625
|
+
"-c",
|
|
4626
|
+
"-D",
|
|
4627
|
+
"-E",
|
|
4628
|
+
"-e",
|
|
4629
|
+
"-F",
|
|
4630
|
+
"-I",
|
|
4631
|
+
"-i",
|
|
4632
|
+
"-J",
|
|
4633
|
+
"-L",
|
|
4634
|
+
"-l",
|
|
4635
|
+
"-m",
|
|
4636
|
+
"-O",
|
|
4637
|
+
"-o",
|
|
4638
|
+
"-p",
|
|
4639
|
+
"-Q",
|
|
4640
|
+
"-R",
|
|
4641
|
+
"-S",
|
|
4642
|
+
"-W",
|
|
4643
|
+
"-w"
|
|
4644
|
+
]);
|
|
4597
4645
|
SUMMARY_KEYS = [
|
|
4598
4646
|
"command",
|
|
4599
4647
|
"cmd",
|
|
@@ -22917,41 +22965,13 @@ var init_path_suggest = __esm(() => {
|
|
|
22917
22965
|
TRAILING_PUNCT = /[.,;:!?)\]}>"'`]+$/;
|
|
22918
22966
|
});
|
|
22919
22967
|
|
|
22920
|
-
// ../../adapters/terminal/src/terminal-width.ts
|
|
22921
|
-
function stripAnsi(value) {
|
|
22922
|
-
return value.replace(new RegExp("\\u001b\\[[0-?]*[ -/]*[@-~]", "g"), "");
|
|
22923
|
-
}
|
|
22924
|
-
function runeWidth(char) {
|
|
22925
|
-
const code = char.codePointAt(0) ?? 0;
|
|
22926
|
-
if (code === 8205 || code >= 65024 && code <= 65039)
|
|
22927
|
-
return 0;
|
|
22928
|
-
if (code >= 4352 && (code <= 4447 || code === 9001 || code === 9002 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 127744 && code <= 129791 || code >= 131072)) {
|
|
22929
|
-
return 2;
|
|
22930
|
-
}
|
|
22931
|
-
return 1;
|
|
22932
|
-
}
|
|
22933
|
-
function displayWidth(value) {
|
|
22934
|
-
return [...stripAnsi(value)].reduce((width, char) => width + runeWidth(char), 0);
|
|
22935
|
-
}
|
|
22936
|
-
|
|
22937
22968
|
// ../../adapters/terminal/src/subagent-graph.ts
|
|
22938
|
-
import {
|
|
22939
|
-
import { createRequire as createRequire2 } from "module";
|
|
22969
|
+
import { layoutTerminalGraph } from "orchgraph";
|
|
22940
22970
|
function adjustSubagentGraphSpacing(current3, delta) {
|
|
22941
22971
|
return Math.min(MAX_SUBAGENT_GRAPH_SPACING, Math.max(MIN_SUBAGENT_GRAPH_SPACING, current3 + delta));
|
|
22942
22972
|
}
|
|
22943
|
-
function
|
|
22944
|
-
|
|
22945
|
-
return {
|
|
22946
|
-
padding: Math.max(1, Math.round(normalized / 4)),
|
|
22947
|
-
nodeSpacing: normalized,
|
|
22948
|
-
layerSpacing: Math.max(2, Math.round(normalized * 0.75)),
|
|
22949
|
-
edgeNodeSpacing: Math.max(1, Math.round(normalized / 2)),
|
|
22950
|
-
edgeEdgeSpacing: Math.max(1, Math.round(normalized / 2))
|
|
22951
|
-
};
|
|
22952
|
-
}
|
|
22953
|
-
function textWidth(value) {
|
|
22954
|
-
return displayWidth(value);
|
|
22973
|
+
function isSubagentGraphEdgeKind(value) {
|
|
22974
|
+
return value === "owns" || value === "owns-parent-only" || value === "tell" || value === "tell-bidirectional";
|
|
22955
22975
|
}
|
|
22956
22976
|
function scopedTopics(topics, activeTopicId) {
|
|
22957
22977
|
const root = topics.find((topic) => topic.id === activeTopicId);
|
|
@@ -22978,6 +22998,18 @@ function scopedTopics(topics, activeTopicId) {
|
|
|
22978
22998
|
append(root);
|
|
22979
22999
|
return scoped;
|
|
22980
23000
|
}
|
|
23001
|
+
function edgePresentation(kind) {
|
|
23002
|
+
switch (kind) {
|
|
23003
|
+
case "owns":
|
|
23004
|
+
return { direction: "both", style: "solid" };
|
|
23005
|
+
case "owns-parent-only":
|
|
23006
|
+
return { direction: "forward", style: "solid", label: "status only \u2193" };
|
|
23007
|
+
case "tell":
|
|
23008
|
+
return { direction: "forward", style: "dashed", label: "tell" };
|
|
23009
|
+
case "tell-bidirectional":
|
|
23010
|
+
return { direction: "both", style: "dashed", label: "tell \u2194" };
|
|
23011
|
+
}
|
|
23012
|
+
}
|
|
22981
23013
|
function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
|
|
22982
23014
|
const scoped = scopedTopics(topics, activeTopicId);
|
|
22983
23015
|
const scopedIds = new Set(scoped.map((topic) => topic.id));
|
|
@@ -23000,29 +23032,29 @@ function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
|
|
|
23000
23032
|
scopedIds.add(target.id);
|
|
23001
23033
|
}
|
|
23002
23034
|
}
|
|
23003
|
-
const
|
|
23035
|
+
const domainEdges = [];
|
|
23004
23036
|
const edgeKeys = new Set;
|
|
23005
23037
|
const addEdge = (kind, source, target) => {
|
|
23006
23038
|
if (!scopedIds.has(source) || !scopedIds.has(target) || source === target)
|
|
23007
23039
|
return;
|
|
23008
23040
|
if (kind === "tell") {
|
|
23009
|
-
const reverseIndex =
|
|
23041
|
+
const reverseIndex = domainEdges.findIndex((edge) => (edge.kind === "tell" || edge.kind === "tell-bidirectional") && edge.source === target && edge.target === source);
|
|
23010
23042
|
if (reverseIndex >= 0) {
|
|
23011
|
-
const reverse =
|
|
23012
|
-
if (reverse
|
|
23043
|
+
const reverse = domainEdges[reverseIndex];
|
|
23044
|
+
if (reverse?.kind === "tell") {
|
|
23013
23045
|
edgeKeys.delete(reverse.id);
|
|
23014
|
-
const
|
|
23015
|
-
|
|
23016
|
-
edgeKeys.add(
|
|
23046
|
+
const id2 = `tell-bidirectional:${reverse.source}:${reverse.target}`;
|
|
23047
|
+
domainEdges[reverseIndex] = { ...reverse, id: id2, kind: "tell-bidirectional" };
|
|
23048
|
+
edgeKeys.add(id2);
|
|
23017
23049
|
}
|
|
23018
23050
|
return;
|
|
23019
23051
|
}
|
|
23020
23052
|
}
|
|
23021
|
-
const
|
|
23022
|
-
if (edgeKeys.has(
|
|
23053
|
+
const id = `${kind}:${source}:${target}`;
|
|
23054
|
+
if (edgeKeys.has(id))
|
|
23023
23055
|
return;
|
|
23024
|
-
edgeKeys.add(
|
|
23025
|
-
|
|
23056
|
+
edgeKeys.add(id);
|
|
23057
|
+
domainEdges.push({ id, source, target, kind });
|
|
23026
23058
|
};
|
|
23027
23059
|
for (const topic of scoped) {
|
|
23028
23060
|
if (topic.id !== activeTopicId && topic.parentTopicId) {
|
|
@@ -23032,292 +23064,40 @@ function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
|
|
|
23032
23064
|
addEdge("tell", topic.id, targetId);
|
|
23033
23065
|
}
|
|
23034
23066
|
}
|
|
23035
|
-
|
|
23036
|
-
|
|
23037
|
-
|
|
23038
|
-
|
|
23039
|
-
|
|
23040
|
-
|
|
23041
|
-
|
|
23042
|
-
})),
|
|
23043
|
-
edges
|
|
23044
|
-
};
|
|
23045
|
-
}
|
|
23046
|
-
function layoutInput(graph, spacing) {
|
|
23047
|
-
const layout = terminalGraphLayout(spacing);
|
|
23067
|
+
const nodes = scoped.map((topic) => ({
|
|
23068
|
+
id: topic.id,
|
|
23069
|
+
label: topic.title.trim() || topic.id,
|
|
23070
|
+
detail: `${topic.agent ?? "agent"} \xB7 ${topic.effectiveModel ?? topic.defaultModel ?? "default"} \xB7 ${topic.effectiveEffort ?? topic.defaultEffort ?? "default"}`,
|
|
23071
|
+
state: runningTopicIds.has(topic.id) ? "running" : "idle"
|
|
23072
|
+
}));
|
|
23073
|
+
const root = nodes[0];
|
|
23048
23074
|
return {
|
|
23049
23075
|
id: "subagents",
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23054
|
-
|
|
23055
|
-
|
|
23056
|
-
"elk.layered.spacing.nodeNodeBetweenLayers": String(layout.layerSpacing),
|
|
23057
|
-
"elk.layered.spacing.edgeNodeBetweenLayers": String(layout.edgeNodeSpacing),
|
|
23058
|
-
"elk.layered.spacing.edgeEdgeBetweenLayers": String(layout.edgeEdgeSpacing),
|
|
23059
|
-
"elk.layered.nodePlacement.favorStraightEdges": "true",
|
|
23060
|
-
"elk.layered.crossingMinimization.strategy": "LAYER_SWEEP"
|
|
23061
|
-
},
|
|
23062
|
-
children: graph.nodes.map((node) => {
|
|
23063
|
-
const contentWidth = Math.max(textWidth(node.title) + 4, textWidth(node.detail) + 2, 12);
|
|
23064
|
-
return { id: node.id, width: contentWidth + 2, height: 4 };
|
|
23065
|
-
}),
|
|
23066
|
-
edges: graph.edges.map((edge) => ({
|
|
23067
|
-
id: edge.id,
|
|
23068
|
-
sources: [edge.source],
|
|
23069
|
-
targets: [edge.target]
|
|
23070
|
-
}))
|
|
23076
|
+
title: root?.label ?? activeTopicId,
|
|
23077
|
+
direction: "DOWN",
|
|
23078
|
+
nodes,
|
|
23079
|
+
edges: domainEdges.map((edge) => ({ ...edge, ...edgePresentation(edge.kind) })),
|
|
23080
|
+
rootDetail: root?.detail,
|
|
23081
|
+
rootRunning: root?.state === "running"
|
|
23071
23082
|
};
|
|
23072
23083
|
}
|
|
23073
|
-
function
|
|
23074
|
-
|
|
23075
|
-
|
|
23076
|
-
|
|
23077
|
-
|
|
23078
|
-
|
|
23079
|
-
async function runElk(input, signal) {
|
|
23080
|
-
const require2 = createRequire2(import.meta.url);
|
|
23081
|
-
const elkPath = require2.resolve("elkjs/lib/elk.bundled.js");
|
|
23082
|
-
const nodeBinary = process.env.NEGOTIUM_NODE_BINARY?.trim() || "node";
|
|
23083
|
-
return await new Promise((resolve19, reject) => {
|
|
23084
|
-
const child = spawn7(nodeBinary, ["--eval", ELK_HOST_SOURCE, elkPath], {
|
|
23085
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
23086
|
-
signal,
|
|
23087
|
-
timeout: 15000,
|
|
23088
|
-
killSignal: "SIGKILL"
|
|
23089
|
-
});
|
|
23090
|
-
let stdout = "";
|
|
23091
|
-
let stderr = "";
|
|
23092
|
-
child.stdout.setEncoding("utf8");
|
|
23093
|
-
child.stderr.setEncoding("utf8");
|
|
23094
|
-
child.stdout.on("data", (chunk) => {
|
|
23095
|
-
try {
|
|
23096
|
-
stdout = appendElkOutput(stdout, chunk);
|
|
23097
|
-
} catch (error) {
|
|
23098
|
-
child.kill("SIGKILL");
|
|
23099
|
-
reject(error);
|
|
23100
|
-
}
|
|
23101
|
-
});
|
|
23102
|
-
child.stderr.on("data", (chunk) => {
|
|
23103
|
-
try {
|
|
23104
|
-
stderr = appendElkOutput(stderr, chunk);
|
|
23105
|
-
} catch (error) {
|
|
23106
|
-
child.kill("SIGKILL");
|
|
23107
|
-
reject(error);
|
|
23108
|
-
}
|
|
23109
|
-
});
|
|
23110
|
-
child.once("error", (error) => {
|
|
23111
|
-
reject(error.code === "ENOENT" ? new Error("Node.js 20+ is required for the agent graph (Ctrl-G)") : error);
|
|
23112
|
-
});
|
|
23113
|
-
child.once("exit", (code, signal2) => {
|
|
23114
|
-
if (code !== 0) {
|
|
23115
|
-
reject(new Error(stderr.trim() || `ELK exited with ${signal2 ? `signal ${signal2}` : `code ${String(code)}`}`));
|
|
23116
|
-
return;
|
|
23117
|
-
}
|
|
23118
|
-
try {
|
|
23119
|
-
resolve19(JSON.parse(stdout));
|
|
23120
|
-
} catch {
|
|
23121
|
-
reject(new Error("ELK returned an invalid layout"));
|
|
23122
|
-
}
|
|
23123
|
-
});
|
|
23124
|
-
child.stdin.end(JSON.stringify(input));
|
|
23125
|
-
});
|
|
23126
|
-
}
|
|
23127
|
-
function rounded(value) {
|
|
23128
|
-
return Math.max(0, Math.round(value ?? 0));
|
|
23129
|
-
}
|
|
23130
|
-
function edgeCharacter(existing, next, tell) {
|
|
23131
|
-
const glyph = tell ? next === "horizontal" ? "\u2508" : "\u250A" : next === "horizontal" ? "\u2500" : "\u2502";
|
|
23132
|
-
if (existing === " " || existing === glyph)
|
|
23133
|
-
return glyph;
|
|
23134
|
-
if ("\u2500\u2508".includes(existing) && next === "horizontal")
|
|
23135
|
-
return existing;
|
|
23136
|
-
if ("\u2502\u250A".includes(existing) && next === "vertical")
|
|
23137
|
-
return existing;
|
|
23138
|
-
return "\u253C";
|
|
23139
|
-
}
|
|
23140
|
-
function edgeMidpoint(points) {
|
|
23141
|
-
const lengths = points.slice(1).map((point, index) => {
|
|
23142
|
-
const previous = points[index];
|
|
23143
|
-
return Math.abs(point.x - previous.x) + Math.abs(point.y - previous.y);
|
|
23084
|
+
async function layoutSubagentGraph(graph, spacing = DEFAULT_SUBAGENT_GRAPH_SPACING, signal) {
|
|
23085
|
+
const canvas = await layoutTerminalGraph(graph, {
|
|
23086
|
+
direction: "DOWN",
|
|
23087
|
+
spacing,
|
|
23088
|
+
signal,
|
|
23089
|
+
timeoutMs: 15000
|
|
23144
23090
|
});
|
|
23145
|
-
let remaining = lengths.reduce((sum, length) => sum + length, 0) / 2;
|
|
23146
|
-
for (let index = 0;index < lengths.length; index += 1) {
|
|
23147
|
-
const length = lengths[index];
|
|
23148
|
-
const start = points[index];
|
|
23149
|
-
const end = points[index + 1];
|
|
23150
|
-
if (remaining <= length) {
|
|
23151
|
-
const ratio = length === 0 ? 0 : remaining / length;
|
|
23152
|
-
return {
|
|
23153
|
-
x: Math.round(start.x + (end.x - start.x) * ratio),
|
|
23154
|
-
y: Math.round(start.y + (end.y - start.y) * ratio)
|
|
23155
|
-
};
|
|
23156
|
-
}
|
|
23157
|
-
remaining -= length;
|
|
23158
|
-
}
|
|
23159
|
-
return points.at(-1) ?? { x: 0, y: 0 };
|
|
23160
|
-
}
|
|
23161
|
-
function renderCanvas(graph, layout) {
|
|
23162
|
-
const width = Math.max(1, rounded(layout.width) + 2);
|
|
23163
|
-
const height = Math.max(1, rounded(layout.height) + 2);
|
|
23164
|
-
const cells = Array.from({ length: height }, () => Array.from({ length: width }, () => " "));
|
|
23165
|
-
const put = (x, y, value) => {
|
|
23166
|
-
if (y < 0 || y >= height || x < 0 || x >= width)
|
|
23167
|
-
return;
|
|
23168
|
-
cells[y][x] = value;
|
|
23169
|
-
};
|
|
23170
|
-
const putText = (x, y, value, maxWidth) => {
|
|
23171
|
-
let column = 0;
|
|
23172
|
-
for (const character of [...value]) {
|
|
23173
|
-
const width2 = displayWidth(character);
|
|
23174
|
-
if (column + width2 > maxWidth)
|
|
23175
|
-
break;
|
|
23176
|
-
put(x + column, y, character);
|
|
23177
|
-
if (width2 === 2)
|
|
23178
|
-
put(x + column + 1, y, "");
|
|
23179
|
-
column += width2;
|
|
23180
|
-
}
|
|
23181
|
-
};
|
|
23182
|
-
const edgeById = new Map(graph.edges.map((edge) => [edge.id, edge]));
|
|
23183
|
-
const edgeLabels = [];
|
|
23184
|
-
const edges = [];
|
|
23185
|
-
for (const laidOutEdge of layout.edges ?? []) {
|
|
23186
|
-
const edge = edgeById.get(laidOutEdge.id);
|
|
23187
|
-
if (!edge)
|
|
23188
|
-
continue;
|
|
23189
|
-
const edgeCells = new Map;
|
|
23190
|
-
const recordEdgeCell = (x, y) => {
|
|
23191
|
-
edgeCells.set(`${x}:${y}`, { x, y });
|
|
23192
|
-
};
|
|
23193
|
-
for (const section of laidOutEdge.sections ?? []) {
|
|
23194
|
-
const points = [section.startPoint, ...section.bendPoints ?? [], section.endPoint].map((point) => ({ x: rounded(point.x) + 1, y: rounded(point.y) + 1 }));
|
|
23195
|
-
for (let index = 1;index < points.length; index += 1) {
|
|
23196
|
-
const from = points[index - 1];
|
|
23197
|
-
const to = points[index];
|
|
23198
|
-
const horizontal = from.y === to.y;
|
|
23199
|
-
const distance = horizontal ? Math.abs(to.x - from.x) : Math.abs(to.y - from.y);
|
|
23200
|
-
const xStep = horizontal ? Math.sign(to.x - from.x) : 0;
|
|
23201
|
-
const yStep = horizontal ? 0 : Math.sign(to.y - from.y);
|
|
23202
|
-
for (let offset = 0;offset <= distance; offset += 1) {
|
|
23203
|
-
const x = from.x + xStep * offset;
|
|
23204
|
-
const y = from.y + yStep * offset;
|
|
23205
|
-
const existing = cells[y]?.[x] ?? " ";
|
|
23206
|
-
put(x, y, edgeCharacter(existing, horizontal ? "horizontal" : "vertical", edge.kind === "tell" || edge.kind === "tell-bidirectional"));
|
|
23207
|
-
recordEdgeCell(x, y);
|
|
23208
|
-
}
|
|
23209
|
-
}
|
|
23210
|
-
const end = points.at(-1);
|
|
23211
|
-
const before = points.at(-2);
|
|
23212
|
-
if (end && before) {
|
|
23213
|
-
const arrowX = end.x - Math.sign(end.x - before.x);
|
|
23214
|
-
const arrowY = end.y - Math.sign(end.y - before.y);
|
|
23215
|
-
const arrow = end.y > before.y ? "\u25BC" : end.y < before.y ? "\u25B2" : end.x > before.x ? "\u25B6" : "\u25C0";
|
|
23216
|
-
put(arrowX, arrowY, arrow);
|
|
23217
|
-
recordEdgeCell(arrowX, arrowY);
|
|
23218
|
-
}
|
|
23219
|
-
if (edge.kind === "owns" || edge.kind === "tell-bidirectional") {
|
|
23220
|
-
const start = points[0];
|
|
23221
|
-
const after = points[1];
|
|
23222
|
-
if (start && after) {
|
|
23223
|
-
const arrowX = start.x + Math.sign(after.x - start.x);
|
|
23224
|
-
const arrowY = start.y + Math.sign(after.y - start.y);
|
|
23225
|
-
const arrow = after.y > start.y ? "\u25B2" : after.y < start.y ? "\u25BC" : after.x > start.x ? "\u25C0" : "\u25B6";
|
|
23226
|
-
put(arrowX, arrowY, arrow);
|
|
23227
|
-
recordEdgeCell(arrowX, arrowY);
|
|
23228
|
-
}
|
|
23229
|
-
}
|
|
23230
|
-
if ((edge.kind === "owns-parent-only" || edge.kind === "tell" || edge.kind === "tell-bidirectional") && points.length > 1) {
|
|
23231
|
-
const middle = edgeMidpoint(points);
|
|
23232
|
-
const label = edge.kind === "owns-parent-only" ? " status only \u2193 " : edge.kind === "tell-bidirectional" ? " tell \u2194 " : " tell ";
|
|
23233
|
-
edgeLabels.push({
|
|
23234
|
-
x: middle.x - Math.floor(label.length / 2),
|
|
23235
|
-
y: middle.y,
|
|
23236
|
-
text: label
|
|
23237
|
-
});
|
|
23238
|
-
}
|
|
23239
|
-
}
|
|
23240
|
-
edges.push({
|
|
23241
|
-
sourceTopicId: edge.source,
|
|
23242
|
-
targetTopicId: edge.target,
|
|
23243
|
-
kind: edge.kind,
|
|
23244
|
-
cells: [...edgeCells.values()]
|
|
23245
|
-
});
|
|
23246
|
-
}
|
|
23247
|
-
for (const label of edgeLabels)
|
|
23248
|
-
putText(label.x, label.y, label.text, textWidth(label.text));
|
|
23249
|
-
const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
23250
|
-
const nodes = [];
|
|
23251
|
-
for (const laidOutNode of layout.children ?? []) {
|
|
23252
|
-
const node = nodeById.get(laidOutNode.id);
|
|
23253
|
-
if (!node)
|
|
23254
|
-
continue;
|
|
23255
|
-
const x = rounded(laidOutNode.x) + 1;
|
|
23256
|
-
const y = rounded(laidOutNode.y) + 1;
|
|
23257
|
-
const nodeWidth = Math.max(4, rounded(laidOutNode.width));
|
|
23258
|
-
const nodeHeight = Math.max(4, rounded(laidOutNode.height));
|
|
23259
|
-
for (let row = 0;row < nodeHeight; row += 1) {
|
|
23260
|
-
for (let column = 0;column < nodeWidth; column += 1)
|
|
23261
|
-
put(x + column, y + row, " ");
|
|
23262
|
-
}
|
|
23263
|
-
put(x, y, "\u256D");
|
|
23264
|
-
put(x + nodeWidth - 1, y, "\u256E");
|
|
23265
|
-
put(x, y + nodeHeight - 1, "\u2570");
|
|
23266
|
-
put(x + nodeWidth - 1, y + nodeHeight - 1, "\u256F");
|
|
23267
|
-
for (let column = 1;column < nodeWidth - 1; column += 1) {
|
|
23268
|
-
put(x + column, y, "\u2500");
|
|
23269
|
-
put(x + column, y + nodeHeight - 1, "\u2500");
|
|
23270
|
-
}
|
|
23271
|
-
for (let row = 1;row < nodeHeight - 1; row += 1) {
|
|
23272
|
-
put(x, y + row, "\u2502");
|
|
23273
|
-
put(x + nodeWidth - 1, y + row, "\u2502");
|
|
23274
|
-
}
|
|
23275
|
-
putText(x + 2, y + 1, `${node.running ? "\u25CF" : "\u25CB"} ${node.title}`, nodeWidth - 3);
|
|
23276
|
-
putText(x + 2, y + 2, node.detail, nodeWidth - 3);
|
|
23277
|
-
nodes.push({
|
|
23278
|
-
topicId: node.id,
|
|
23279
|
-
title: node.title,
|
|
23280
|
-
markerX: x + 2,
|
|
23281
|
-
markerY: y + 1
|
|
23282
|
-
});
|
|
23283
|
-
}
|
|
23284
23091
|
return {
|
|
23285
|
-
|
|
23286
|
-
|
|
23287
|
-
|
|
23288
|
-
|
|
23289
|
-
edges,
|
|
23290
|
-
lines: cells.map((row) => row.join("").trimEnd()),
|
|
23291
|
-
width,
|
|
23292
|
-
height
|
|
23092
|
+
...canvas,
|
|
23093
|
+
title: graph.title,
|
|
23094
|
+
rootDetail: graph.rootDetail,
|
|
23095
|
+
rootRunning: graph.rootRunning,
|
|
23096
|
+
edges: canvas.edges.map(({ kind, ...edge }) => isSubagentGraphEdgeKind(kind) ? { ...edge, kind } : edge)
|
|
23293
23097
|
};
|
|
23294
23098
|
}
|
|
23295
|
-
|
|
23296
|
-
|
|
23297
|
-
return { title: graph.rootTitle, lines: [], width: 0, height: 0 };
|
|
23298
|
-
}
|
|
23299
|
-
return renderCanvas(graph, await runElk(layoutInput(graph, spacing), signal));
|
|
23300
|
-
}
|
|
23301
|
-
var DEFAULT_SUBAGENT_GRAPH_SPACING = 4, MIN_SUBAGENT_GRAPH_SPACING = 2, MAX_SUBAGENT_GRAPH_SPACING = 10, ELK_HOST_SOURCE = `
|
|
23302
|
-
const modulePath = process.argv[1];
|
|
23303
|
-
const imported = require(modulePath);
|
|
23304
|
-
const ELK = imported.default || imported;
|
|
23305
|
-
let input = "";
|
|
23306
|
-
process.stdin.setEncoding("utf8");
|
|
23307
|
-
process.stdin.on("data", (chunk) => input += chunk);
|
|
23308
|
-
process.stdin.on("end", async () => {
|
|
23309
|
-
try {
|
|
23310
|
-
const result = await new ELK().layout(JSON.parse(input));
|
|
23311
|
-
process.stdout.write(JSON.stringify(result));
|
|
23312
|
-
} catch (error) {
|
|
23313
|
-
process.stderr.write(error && error.stack ? error.stack : String(error));
|
|
23314
|
-
process.exitCode = 1;
|
|
23315
|
-
}
|
|
23316
|
-
});
|
|
23317
|
-
`, MAX_ELK_OUTPUT_BYTES;
|
|
23318
|
-
var init_subagent_graph = __esm(() => {
|
|
23319
|
-
MAX_ELK_OUTPUT_BYTES = 1024 * 1024;
|
|
23320
|
-
});
|
|
23099
|
+
var DEFAULT_SUBAGENT_GRAPH_SPACING = 4, MIN_SUBAGENT_GRAPH_SPACING = 2, MAX_SUBAGENT_GRAPH_SPACING = 10;
|
|
23100
|
+
var init_subagent_graph = () => {};
|
|
23321
23101
|
|
|
23322
23102
|
// ../../adapters/terminal/src/state.ts
|
|
23323
23103
|
function createInitialState(userId) {
|
|
@@ -23813,6 +23593,23 @@ var init_state2 = __esm(async () => {
|
|
|
23813
23593
|
init_subagent_graph();
|
|
23814
23594
|
});
|
|
23815
23595
|
|
|
23596
|
+
// ../../adapters/terminal/src/terminal-width.ts
|
|
23597
|
+
function stripAnsi(value) {
|
|
23598
|
+
return value.replace(new RegExp("\\u001b\\[[0-?]*[ -/]*[@-~]", "g"), "");
|
|
23599
|
+
}
|
|
23600
|
+
function runeWidth(char) {
|
|
23601
|
+
const code = char.codePointAt(0) ?? 0;
|
|
23602
|
+
if (code === 8205 || code >= 65024 && code <= 65039)
|
|
23603
|
+
return 0;
|
|
23604
|
+
if (code >= 4352 && (code <= 4447 || code === 9001 || code === 9002 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 127744 && code <= 129791 || code >= 131072)) {
|
|
23605
|
+
return 2;
|
|
23606
|
+
}
|
|
23607
|
+
return 1;
|
|
23608
|
+
}
|
|
23609
|
+
function displayWidth(value) {
|
|
23610
|
+
return [...stripAnsi(value)].reduce((width, char) => width + runeWidth(char), 0);
|
|
23611
|
+
}
|
|
23612
|
+
|
|
23816
23613
|
// ../../adapters/terminal/src/render.ts
|
|
23817
23614
|
function workingFrame(frame) {
|
|
23818
23615
|
const index = Math.abs(Math.trunc(frame)) % WORKING_FRAMES.length;
|
|
@@ -24503,14 +24300,14 @@ function subagentGraphLines(state, width, height, animationFrame) {
|
|
|
24503
24300
|
const position = maxX > 0 || maxY > 0 ? ` \xB7 view ${x + 1},${y + 1}/${maxX + 1},${maxY + 1}` : "";
|
|
24504
24301
|
const graphNodes = canvas?.nodes ?? [];
|
|
24505
24302
|
const graphEdges = canvas?.edges ?? [];
|
|
24506
|
-
const runningNodes = graphNodes.filter((node) => state.activity[node.
|
|
24507
|
-
const nodeTitleById = new Map(graphNodes.map((node) => [node.
|
|
24303
|
+
const runningNodes = graphNodes.filter((node) => state.activity[node.id]?.running);
|
|
24304
|
+
const nodeTitleById = new Map(graphNodes.map((node) => [node.id, node.label]));
|
|
24508
24305
|
const hasActiveTell = (sourceTopicId, targetTopicId) => {
|
|
24509
24306
|
const targetTitle = nodeTitleById.get(targetTopicId);
|
|
24510
24307
|
const activity = state.activity[sourceTopicId];
|
|
24511
24308
|
return Boolean(activity?.running && activity.tools.some((tool) => tool.sessionAction === "tell" && (tool.sessionTarget === targetTopicId || tool.sessionTarget === targetTitle)));
|
|
24512
24309
|
};
|
|
24513
|
-
const activeEdges = graphEdges.filter((edge) => hasActiveTell(edge.
|
|
24310
|
+
const activeEdges = graphEdges.filter((edge) => hasActiveTell(edge.source, edge.target) || (edge.kind === "owns" || edge.kind === "tell-bidirectional") && hasActiveTell(edge.target, edge.source));
|
|
24514
24311
|
const highlightedCellsByRow = new Map;
|
|
24515
24312
|
for (const edge of activeEdges) {
|
|
24516
24313
|
for (const cell of edge.cells) {
|
|
@@ -24519,7 +24316,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
|
|
|
24519
24316
|
highlightedCellsByRow.set(cell.y, columns);
|
|
24520
24317
|
}
|
|
24521
24318
|
}
|
|
24522
|
-
const rootTopicId = graphNodes[0]?.
|
|
24319
|
+
const rootTopicId = graphNodes[0]?.id;
|
|
24523
24320
|
const rootRunning = rootTopicId ? Boolean(state.activity[rootTopicId]?.running) : Boolean(canvas?.rootRunning);
|
|
24524
24321
|
const header = [
|
|
24525
24322
|
line(" Agent graph", {
|
|
@@ -24527,7 +24324,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
|
|
|
24527
24324
|
bold: true
|
|
24528
24325
|
}),
|
|
24529
24326
|
line(canvas ? ` ${rootRunning ? workingFrame(animationFrame) : "\u25CB"} ${canvas.title}${canvas.rootDetail ? ` \xB7 ${canvas.rootDetail}` : ""}` : " Current topic", { fg: rootRunning ? theme.green : theme.text, bold: true }),
|
|
24530
|
-
line(runningNodes.length > 0 ? ` Working: ${runningNodes.map((node) => node.
|
|
24327
|
+
line(runningNodes.length > 0 ? ` Working: ${runningNodes.map((node) => node.label).join(", ")}` : " Working: none", { fg: runningNodes.length > 0 ? theme.green : theme.muted }),
|
|
24531
24328
|
line(` [/] spacing ${state.subagentGraphSpacing} \xB7 drag: all directions \xB7 wheel: up/down \xB7 arrows/hjkl move \xB7 Ctrl-G/Esc close${position}`, {
|
|
24532
24329
|
fg: theme.muted
|
|
24533
24330
|
}),
|
|
@@ -24537,7 +24334,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
|
|
|
24537
24334
|
line("")
|
|
24538
24335
|
];
|
|
24539
24336
|
if (state.subagentGraphLoading) {
|
|
24540
|
-
return [...header, line(" Laying out graph with
|
|
24337
|
+
return [...header, line(" Laying out graph with Orchgraph\u2026", { fg: theme.cyan })].slice(0, height);
|
|
24541
24338
|
}
|
|
24542
24339
|
if (!canvas || canvas.lines.length === 0) {
|
|
24543
24340
|
return [...header, line(" No graph data", { fg: theme.muted })].slice(0, height);
|
|
@@ -24550,7 +24347,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
|
|
|
24550
24347
|
for (const node of graphNodes) {
|
|
24551
24348
|
if (node.markerY !== canvasY)
|
|
24552
24349
|
continue;
|
|
24553
|
-
const marker = state.activity[node.
|
|
24350
|
+
const marker = state.activity[node.id]?.running ? workingFrame(animationFrame) : "\u25CB";
|
|
24554
24351
|
canvasLine = replaceAtDisplayColumn(canvasLine, node.markerX, marker);
|
|
24555
24352
|
}
|
|
24556
24353
|
const text2 = sliceWidthRange(canvasLine, x, viewportWidth);
|
|
@@ -36161,4 +35958,4 @@ switch (command) {
|
|
|
36161
35958
|
}
|
|
36162
35959
|
}
|
|
36163
35960
|
|
|
36164
|
-
//# debugId=
|
|
35961
|
+
//# debugId=6D26E247972E960464756E2164756E21
|