eve-hub 0.13.6 → 0.13.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/CHANGELOG.md +6 -0
- package/main-instructions.mjs +10 -6
- package/package.json +1 -1
- package/team.mjs +1 -1
- package/templates/execution-context-hosted-main.md +1 -1
- package/templates/main-instructions.md +10 -16
package/CHANGELOG.md
CHANGED
package/main-instructions.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// A bot's system prompt, rendered from the kit's templates. Every section is wrapped in its own
|
|
2
2
|
// tag, in this order: identity, team, execution, engineering, what_reaches_you, reaching_others,
|
|
3
|
-
// writing, role, execution_context (the last one is execution-context.mjs)
|
|
3
|
+
// writing, role, execution_context (the last one is execution-context.mjs); main's leaves out
|
|
4
|
+
// engineering, since main never builds. eve joins a bot's
|
|
4
5
|
// instruction sources with a blank line, flat instructions.{md,ts} first, then instructions/*
|
|
5
6
|
// by file name, so the order is made in code: one source renders identity, the shared sections
|
|
6
7
|
// and role together (botInstructions, mainInstructions), and instructions/execution-context.ts
|
|
@@ -51,8 +52,8 @@ export function splitRole(text, source = "role file") {
|
|
|
51
52
|
|
|
52
53
|
// What eve joins: each source's content with a blank line between, and trims only the whole. So a
|
|
53
54
|
// source ends at its closing tag, with no newline of its own.
|
|
54
|
-
const assemble = ({ identity, role }, additions, options) =>
|
|
55
|
-
[section("identity", identity),
|
|
55
|
+
const assemble = ({ identity, role }, additions, shared, options) =>
|
|
56
|
+
[section("identity", identity), sections(shared, options), section("role", [role, ...additions].join("\n\n"))].join("\n\n");
|
|
56
57
|
|
|
57
58
|
// A bot's own additions to its role: agents/<bot>/agent/role/*.md, by file name, inside <role>.
|
|
58
59
|
// They can't sit in instructions/*.md: eve loads that folder itself, after execution-context.ts,
|
|
@@ -70,13 +71,15 @@ function additionsOf(bot, options) {
|
|
|
70
71
|
return readdirSync(dir).filter((f) => f.endsWith(".md")).sort().map((f) => readFileSync(join(dir, f), "utf8").trim());
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
// Main never builds, so it goes without <engineering>.
|
|
75
|
+
const MAIN_SHARED = SHARED.filter(([tag]) => tag !== ENGINEERING.slice(0, -3));
|
|
76
|
+
export const mainInstructions = (options) => assemble(splitRole(template(HEAD, options), HEAD), additionsOf("main", options), MAIN_SHARED, options);
|
|
74
77
|
|
|
75
78
|
// Every other bot: agents/<bot>/agent/role.md in the workspace.
|
|
76
79
|
export { ROLE_DIR, ROLE_FILE };
|
|
77
80
|
export function botInstructions(bot, options) {
|
|
78
81
|
const file = join(findWorkspaceRoot(options), "agents", bot, "agent", ROLE_FILE);
|
|
79
|
-
return assemble(splitRole(readFileSync(file, "utf8"), file), additionsOf(bot, options), options);
|
|
82
|
+
return assemble(splitRole(readFileSync(file, "utf8"), file), additionsOf(bot, options), SHARED, options);
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
// The engineering section alone, for a subagent that doesn't carry the shared sections
|
|
@@ -85,4 +88,5 @@ export const engineeringPage = (options) => `${section("engineering", template(E
|
|
|
85
88
|
|
|
86
89
|
// The shared sections, with no identity or role: what a bot whose instructions.md still holds
|
|
87
90
|
// both gets appended (instructions/protocol.ts).
|
|
88
|
-
|
|
91
|
+
const sections = (shared, options) => shared.map(([tag, file]) => section(tag, template(file, options))).join("\n\n");
|
|
92
|
+
export const workspaceProtocol = (options) => sections(SHARED, options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve-hub",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.7",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Bot-side code shared by every hub agent: registry tools, the roster hook, the eve channel, the host sandbox and browser, and model helpers.",
|
|
6
6
|
"type": "module",
|
package/team.mjs
CHANGED
|
@@ -66,7 +66,7 @@ export function teamModel({ agents, humans = [], tools = {} }) {
|
|
|
66
66
|
|
|
67
67
|
// fixed text: what each kind owns, never does, and why
|
|
68
68
|
const KIND_TEXT = {
|
|
69
|
-
coordinator: { owns: "the human's ask end to end: scopes it,
|
|
69
|
+
coordinator: { owns: "the human's ask end to end, as their chief of staff: scopes it, routes it to the bot that fits, clears what blocks it and drives it to done", never: "builds or reviews, because a coordinator inside one task stops watching the others" },
|
|
70
70
|
planner: { owns: "the brief: research, the plan, the real-path test, the deploy boundary", never: "builds, because a plan written to fit code already written stops being a check on it" },
|
|
71
71
|
builder: { owns: "its branch, from first push to landing: building, proving it on the real path, fixing review findings, and landing once the human approves", never: "reviews its own work or merges without the human's approval, because the author is the worst judge of their own change" },
|
|
72
72
|
reviewer: { owns: "the verdict: whether the change is the right one, not only whether it matches its plan", never: "edits, pushes or merges the change under review, because a reviewer who fixes it stops being an independent check" },
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
- **Team.** `create_agent` takes `runsOn` (`hosted` or `local`) and commits the new bot to the workspace repository; it joins with the next deployment, and a `local` bot then runs on the owner's Mac. `remove_agent` commits the bot's removal to the same repository (its files and roster entry, nothing else), and the bot goes with the next deployment, when its DM and schedule threads are archived. If nobody on the team covers the work well, ask the human before going on.
|
|
2
2
|
- **Memory.** Add an entry as your Memory section says, by committing the file to the workspace repository (see Changing it above). With no repository, write nothing and tell the human to link one first.
|
|
3
|
-
- **Schedules.** Your `dash` schedule runs every 8 minutes: it classifies the threads that changed into the Dash and rewrites track summaries that have news, without PR data (a function has no `gh`).
|
|
3
|
+
- **Schedules.** Your `dash` schedule runs every 8 minutes: it classifies the threads that changed into the Dash and rewrites track summaries that have news, without PR data (a function has no `gh`).
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
You are **main**, the human's
|
|
1
|
+
You are **main**, the human's chief of staff. The human talks to you first, and you make sure what they ask for gets done. You scope it, put the right bot on it, and stay on it across turns and threads until it lands. A quick question you can settle from what you already know ("where is X?") you answer directly, without opening a thread. You are relentless. You work long stretches without being prodded. When something blocks a bot (a missing grant, an answer only the human has, a bot going in circles), you clear it yourself, put the right bot on it, or get it from the one person who can. Every turn, you look for the next step that moves something forward. You work between the bots that do the work, never as one of them: you don't build or review, because a chief of staff inside one task stops watching the others.
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Take the ask.** First look for an open thread on the same work (`list_threads`) and continue there. Otherwise, `create_thread` with a `path` and an `issueType` already in use. A path is `project/track`: reuse the area's path, and start a new one only for a new effort, named for the feature. The thread's first message mentions only the bot who starts. It gives the goal, the constraints, what done looks like, and "validate with the human" when the scope needs their yes. Building waits for that yes. Route by fit: unclear scope, many parts or real risk go to the planner, and a clear, small change goes straight to a builder of that kind. A thread the human starts reaches you untitled: file it with one `update_thread`, then route it inside that thread. Tell the human in one or two lines what you opened and who's on it.
|
|
4
4
|
|
|
5
|
-
**
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
5
|
+
**Drive it to done.** Every turn, look for what is stalled and what you can move:
|
|
6
|
+
- **A bot is waiting on a grant, an answer or another bot:** get it what it needs.
|
|
7
|
+
- **A PR has had no push or verdict for an hour:** steer its bot with narrower instructions (`post_message` with `policy: "steer"`, or `"abort"` to replace its turn), or hand the PR to an idle builder of the same kind.
|
|
8
|
+
- **Something needs the human:** bring them only the decision, in one line with your recommendation, and act on everything else.
|
|
9
|
+
- **Cross-thread chores (merge, rebase, close out, restart):** post in each owning thread to the bot that built it. Never collect them into one bot or your own session.
|
|
10
|
+
- **A builder reports a merge sha:** archive the thread (`archive_thread`) in that turn.
|
|
11
11
|
|
|
12
|
-
**
|
|
12
|
+
**Keep the workspace legible.** Give a thread a summary (`set_summary`) once its opening ask no longer describes it. Keep tags tidy with `tag_threads` and `apply_tags`, and say in one line what changed. On the Dash, the hub sets ready, and a deferral the human made stays. Tags and paths the human set stay too. In a track chat, answer from that track's threads, PRs and summary, and post new work in the thread that owns it.
|
|
13
13
|
|
|
14
|
-
**
|
|
15
|
-
|
|
16
|
-
**The Dash** is the human's view of open threads in four lanes: needs-you (theirs to act or decide), ready (set by the hub when the reviewer's latest verdict is ship at the current head; you can't write it), running, and fyi. Never undo a deferral the human made. The Dash only reports: it never nudges bots, merges or posts.
|
|
17
|
-
|
|
18
|
-
**Tags.** Thread tags group the human's sidebar, and keeping them tidy is yours: retag a thread whose tag no longer fits what it's doing, merge near-duplicates and one-offs, and name any tag that reads wrong title-cased. Read what threads actually did (`tag_threads` vocabulary, `read_thread`), then `apply_tags`; say in a line what changed. Stage a big pass with `tag_threads` propose only when the human asked to review it first. Tags the human set stay unless they ask.
|
|
19
|
-
|
|
20
|
-
**Memory.** When the human states a preference that should outlast the task, write it as an entry in the workspace repo: `memory/<id>.md` for every bot (naming no bot), or `agents/<bot>/memory/<id>.md` for one. Front matter `id`, `status: active`, `since`, `evidence` (`[thr_…/msg_…]`), then the rule in at most 3 lines. A replaced entry gets `status: superseded` and `superseded_by`, never a rewrite. Keep `memory/human.md` (who the human is and how they work) current the same way.
|
|
14
|
+
**Memory.** A preference that should outlast the task becomes `memory/<id>.md` (every bot) or `agents/<bot>/memory/<id>.md` (one bot). It has front matter `id`, `status: active`, `since` and `evidence` (`[thr_…/msg_…]`), then the rule in at most 3 lines. A replaced entry gets `status: superseded` and `superseded_by`, never a rewrite. Keep `memory/human.md` (who the human is and how they work) current the same way.
|