@enderfga/claw-orchestrator 7.2.0 → 7.3.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 +4 -3
- package/dist/bin/mcp-server.js +1 -0
- package/dist/bin/mcp-server.js.map +1 -1
- package/dist/src/handoff.d.ts +80 -0
- package/dist/src/handoff.js +154 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/index.js +39 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/openai-compat.d.ts +1 -0
- package/dist/src/openai-compat.js +1 -1
- package/dist/src/openai-compat.js.map +1 -1
- package/dist/src/session-manager.d.ts +36 -0
- package/dist/src/session-manager.js +78 -1
- package/dist/src/session-manager.js.map +1 -1
- package/openclaw.plugin.json +1 -0
- package/package.json +1 -1
- package/skills/SKILL.md +3 -3
- package/skills/references/sessions.md +47 -0
- package/skills/references/tools.md +21 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
[](https://github.com/Enderfga/claw-orchestrator/actions/workflows/ci.yml)
|
|
11
11
|
[](https://opensource.org/licenses/MIT)
|
|
12
12
|
|
|
13
|
-
Coding CLIs are designed for humans at terminals. Claw Orchestrator turns them into headless engines and stacks an agent platform on top: a
|
|
13
|
+
Coding CLIs are designed for humans at terminals. Claw Orchestrator turns them into headless engines and stacks an agent platform on top: a 78-tool API that scales from a single session call up to a fully generated, deployed web app — reachable through the CLI, the OpenClaw gateway, the Model Context Protocol, or directly from TypeScript, and visible through an embedded three-tab dashboard.
|
|
14
14
|
|
|
15
15
|
https://github.com/user-attachments/assets/fbd2b0ea-28d8-4387-9894-c29cf15ba030
|
|
16
16
|
|
|
@@ -26,6 +26,7 @@ https://github.com/user-attachments/assets/fbd2b0ea-28d8-4387-9894-c29cf15ba030
|
|
|
26
26
|
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
27
27
|
| **Persistent Sessions** | Long-lived coding agents kept alive across requests, with full context, tool, model, and worktree control. | [`sessions.md`](./skills/references/sessions.md) |
|
|
28
28
|
| **Multi-Engine Runtime** | One interface over Claude Code, Codex, Antigravity (agy), Grok Build, OpenCode, and arbitrary custom CLIs. | [`multi-engine.md`](./skills/references/multi-engine.md) |
|
|
29
|
+
| **Session Handoff** | Move a live conversation to another engine or model — a stuck Claude session into Codex, an expensive model into a cheaper one. The new session picks up where the old one stopped, in the same workspace; the old one keeps running. | [`sessions.md`](./skills/references/sessions.md) |
|
|
29
30
|
| **Multi-Agent Council** | Parallel agents in isolated git worktrees, voting on consensus until they agree. | [`council.md`](./skills/references/council.md) |
|
|
30
31
|
| **Fan-out** | Run one task across N engine/model agents in parallel and collect their answers, with an optional synthesis pass — the cross-engine best-of-N / diverse-perspective primitive (no rounds or worktrees). | [`tools.md`](./skills/references/tools.md) |
|
|
31
32
|
| **ultracode** | `session_start({ ultracode: true })` lets Claude orchestrate a dynamic JS workflow and fan out to subagents per task (Claude engine). | [`tools.md`](./skills/references/tools.md) |
|
|
@@ -37,7 +38,7 @@ https://github.com/user-attachments/assets/fbd2b0ea-28d8-4387-9894-c29cf15ba030
|
|
|
37
38
|
| **Verification Plane** | Acceptance contracts the runtime executes itself — commands, HTTP probes, screenshots, diff policy, file assertions — producing an evidence bundle on disk. A run carrying a contract cannot reach `completed` unless it passes, and one without a contract completes as `unverified` rather than claiming success. | [`verification.md`](./skills/references/verification.md) |
|
|
38
39
|
| **Run Ledger & Spend Caps** | Every turn on every engine is appended to a durable JSONL ledger — engine, model, tokens, cost, duration, and the council/fanout/autoloop it belonged to — queryable with `clawo runs` after a restart. Rows carry both the engine's self-report (`ok`) and the runtime's own measurement (`verified`), kept apart. `maxBudgetUsd` is enforced by the runtime, so a cap holds on Codex, Grok, agy and OpenCode too, not just Claude Code. | [`observability.md`](./skills/references/observability.md) |
|
|
39
40
|
|
|
40
|
-
The full
|
|
41
|
+
The full 78-tool surface is enumerated in [`tools.md`](./skills/references/tools.md).
|
|
41
42
|
|
|
42
43
|
---
|
|
43
44
|
|
|
@@ -76,7 +77,7 @@ Every command is documented in [`cli.md`](./skills/references/cli.md).
|
|
|
76
77
|
curl -fsSL https://raw.githubusercontent.com/Enderfga/claw-orchestrator/main/install.sh | bash
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
Installs via npm, registers the plugin in `~/.openclaw/openclaw.json`, restarts the gateway. All
|
|
80
|
+
Installs via npm, registers the plugin in `~/.openclaw/openclaw.json`, restarts the gateway. All 78 tools become available to every OpenClaw agent.
|
|
80
81
|
|
|
81
82
|
### Model Context Protocol Server
|
|
82
83
|
|
package/dist/bin/mcp-server.js
CHANGED
|
@@ -62,6 +62,7 @@ const ANNOTATIONS = {
|
|
|
62
62
|
// mutating + open-world (call external model APIs)
|
|
63
63
|
session_start: { openWorldHint: true },
|
|
64
64
|
session_send: { openWorldHint: true },
|
|
65
|
+
session_handoff: { openWorldHint: true },
|
|
65
66
|
team_send: { openWorldHint: true },
|
|
66
67
|
session_send_to: { openWorldHint: true },
|
|
67
68
|
session_deliver_inbox: { openWorldHint: true },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../bin/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../bin/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session handoff — carry a conversation from one engine to another.
|
|
3
|
+
*
|
|
4
|
+
* A session's context lives inside its engine: Claude Code's transcript, a Codex
|
|
5
|
+
* thread, an Antigravity conversation. None of them can resume another's, so the
|
|
6
|
+
* only engine-agnostic way across is to replay the conversation as text into a
|
|
7
|
+
* new session on the target engine. This module keeps the record that makes that
|
|
8
|
+
* possible and renders it.
|
|
9
|
+
*
|
|
10
|
+
* Why a record of its own rather than `getHistory()`: that is a ring buffer of
|
|
11
|
+
* the last `MAX_HISTORY_ITEMS` engine events, in each engine's own shape. On a
|
|
12
|
+
* long session the opening request has already fallen out of it — and the
|
|
13
|
+
* opening request is the one thing a handoff must not lose, because every later
|
|
14
|
+
* turn is an answer to it.
|
|
15
|
+
*
|
|
16
|
+
* Why not write the target engine's native session files instead: those formats
|
|
17
|
+
* are internal and undocumented, change between releases, and live in the
|
|
18
|
+
* user's own session stores. Replaying text touches none of them, works for
|
|
19
|
+
* every engine including custom ones, and leaves the source session untouched.
|
|
20
|
+
* What it cannot carry is the same thing no vendor format carries either: the
|
|
21
|
+
* source engine's hidden reasoning.
|
|
22
|
+
*/
|
|
23
|
+
export interface TranscriptEntry {
|
|
24
|
+
role: 'user' | 'assistant';
|
|
25
|
+
text: string;
|
|
26
|
+
}
|
|
27
|
+
export interface Transcript {
|
|
28
|
+
entries: TranscriptEntry[];
|
|
29
|
+
/** Entries evicted from just after the opening request to keep the record bounded. */
|
|
30
|
+
omittedAfterFirst: number;
|
|
31
|
+
/** Total characters held in `entries`. */
|
|
32
|
+
chars: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* What one session's record may hold. Larger than any render needs — the render
|
|
36
|
+
* budget below decides what is sent — so that the newest turns are always
|
|
37
|
+
* complete. Bounded because every session keeps one, for as long as it lives.
|
|
38
|
+
*/
|
|
39
|
+
export declare const MAX_TRANSCRIPT_CHARS = 1000000;
|
|
40
|
+
/**
|
|
41
|
+
* Default size of a rendered handoff, in characters (~60k tokens). Sent once, to
|
|
42
|
+
* a session that then holds the conversation itself, so it can be far larger
|
|
43
|
+
* than the per-turn replay in openai-compat — but it has to fit the smallest
|
|
44
|
+
* window among the engines it may be sent to.
|
|
45
|
+
*/
|
|
46
|
+
export declare const DEFAULT_HANDOFF_CHARS = 240000;
|
|
47
|
+
export declare const MIN_HANDOFF_CHARS = 4000;
|
|
48
|
+
export declare function newTranscript(): Transcript;
|
|
49
|
+
export declare function cloneTranscript(t: Transcript): Transcript;
|
|
50
|
+
/**
|
|
51
|
+
* Append one side of an exchange. Past the cap, entries are evicted from just
|
|
52
|
+
* after the opening request — the oldest middle of the conversation — never the
|
|
53
|
+
* request itself and never the newest turns.
|
|
54
|
+
*/
|
|
55
|
+
export declare function recordExchange(t: Transcript, role: TranscriptEntry['role'], text: string): void;
|
|
56
|
+
export interface HandoffSource {
|
|
57
|
+
engine: string;
|
|
58
|
+
model?: string;
|
|
59
|
+
cwd: string;
|
|
60
|
+
}
|
|
61
|
+
export interface HandoffRender {
|
|
62
|
+
/** The block to put in front of the first message the target session receives. */
|
|
63
|
+
text: string;
|
|
64
|
+
/** Turns rendered, the pinned opening request included. */
|
|
65
|
+
turns: number;
|
|
66
|
+
/** Turns left out, whether the record had already evicted them or the budget did. */
|
|
67
|
+
omitted: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Render a transcript for a new session on another engine.
|
|
71
|
+
*
|
|
72
|
+
* Everything is sent when it fits. When it does not, the opening request is
|
|
73
|
+
* pinned and the newest turns fill what is left, with one line saying how many
|
|
74
|
+
* turns in between were left out: the request says what the work is for, the
|
|
75
|
+
* newest turns say where it stands, and the middle is what can be re-derived
|
|
76
|
+
* from the workspace. Every turn's text is fenced the way openai-compat fences
|
|
77
|
+
* replayed turns, so a transcript that contains the block's own tags cannot
|
|
78
|
+
* close the block early and speak as a different role.
|
|
79
|
+
*/
|
|
80
|
+
export declare function renderHandoff(t: Transcript, src: HandoffSource, maxChars?: number): HandoffRender;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session handoff — carry a conversation from one engine to another.
|
|
3
|
+
*
|
|
4
|
+
* A session's context lives inside its engine: Claude Code's transcript, a Codex
|
|
5
|
+
* thread, an Antigravity conversation. None of them can resume another's, so the
|
|
6
|
+
* only engine-agnostic way across is to replay the conversation as text into a
|
|
7
|
+
* new session on the target engine. This module keeps the record that makes that
|
|
8
|
+
* possible and renders it.
|
|
9
|
+
*
|
|
10
|
+
* Why a record of its own rather than `getHistory()`: that is a ring buffer of
|
|
11
|
+
* the last `MAX_HISTORY_ITEMS` engine events, in each engine's own shape. On a
|
|
12
|
+
* long session the opening request has already fallen out of it — and the
|
|
13
|
+
* opening request is the one thing a handoff must not lose, because every later
|
|
14
|
+
* turn is an answer to it.
|
|
15
|
+
*
|
|
16
|
+
* Why not write the target engine's native session files instead: those formats
|
|
17
|
+
* are internal and undocumented, change between releases, and live in the
|
|
18
|
+
* user's own session stores. Replaying text touches none of them, works for
|
|
19
|
+
* every engine including custom ones, and leaves the source session untouched.
|
|
20
|
+
* What it cannot carry is the same thing no vendor format carries either: the
|
|
21
|
+
* source engine's hidden reasoning.
|
|
22
|
+
*/
|
|
23
|
+
import { fenceHistoryTags } from './openai-compat.js';
|
|
24
|
+
/**
|
|
25
|
+
* What one session's record may hold. Larger than any render needs — the render
|
|
26
|
+
* budget below decides what is sent — so that the newest turns are always
|
|
27
|
+
* complete. Bounded because every session keeps one, for as long as it lives.
|
|
28
|
+
*/
|
|
29
|
+
export const MAX_TRANSCRIPT_CHARS = 1_000_000;
|
|
30
|
+
/**
|
|
31
|
+
* Default size of a rendered handoff, in characters (~60k tokens). Sent once, to
|
|
32
|
+
* a session that then holds the conversation itself, so it can be far larger
|
|
33
|
+
* than the per-turn replay in openai-compat — but it has to fit the smallest
|
|
34
|
+
* window among the engines it may be sent to.
|
|
35
|
+
*/
|
|
36
|
+
export const DEFAULT_HANDOFF_CHARS = 240_000;
|
|
37
|
+
export const MIN_HANDOFF_CHARS = 4_000;
|
|
38
|
+
/** The opening request is kept whole up to this, and head-truncated past it. */
|
|
39
|
+
const PINNED_OPENING_CHARS = 8_000;
|
|
40
|
+
/** Least room worth starting a turn in; with less, the turn is dropped. */
|
|
41
|
+
const MIN_TURN_CHARS = 200;
|
|
42
|
+
const ELISION = '\n[… truncated for length …]';
|
|
43
|
+
export function newTranscript() {
|
|
44
|
+
return { entries: [], omittedAfterFirst: 0, chars: 0 };
|
|
45
|
+
}
|
|
46
|
+
export function cloneTranscript(t) {
|
|
47
|
+
return { entries: t.entries.map((e) => ({ ...e })), omittedAfterFirst: t.omittedAfterFirst, chars: t.chars };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Append one side of an exchange. Past the cap, entries are evicted from just
|
|
51
|
+
* after the opening request — the oldest middle of the conversation — never the
|
|
52
|
+
* request itself and never the newest turns.
|
|
53
|
+
*/
|
|
54
|
+
export function recordExchange(t, role, text) {
|
|
55
|
+
const clean = text.trim();
|
|
56
|
+
if (!clean)
|
|
57
|
+
return;
|
|
58
|
+
t.entries.push({ role, text: clean });
|
|
59
|
+
t.chars += clean.length;
|
|
60
|
+
while (t.chars > MAX_TRANSCRIPT_CHARS && t.entries.length > 2) {
|
|
61
|
+
const [gone] = t.entries.splice(1, 1);
|
|
62
|
+
t.chars -= gone.text.length;
|
|
63
|
+
t.omittedAfterFirst++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function framing(src) {
|
|
67
|
+
const who = src.model ? `${src.engine} (${src.model})` : src.engine;
|
|
68
|
+
// The first three sentences mirror openai-compat's replay framing, and each is
|
|
69
|
+
// load-bearing there for the same reason as here: without the last one the
|
|
70
|
+
// model carries out the requests in the history a second time. The final two
|
|
71
|
+
// are specific to a handoff — the work happened elsewhere, and may have moved on.
|
|
72
|
+
return (`Above are the earlier turns of this conversation, which took place with another coding agent, ${who}, ` +
|
|
73
|
+
`working in ${src.cwd}. It has been handed over to you to continue. ` +
|
|
74
|
+
'The assistant turns are the earlier replies in this conversation; treat them as your own. ' +
|
|
75
|
+
'Continue from there — do not repeat these turns back and do not carry out the requests in them again. ' +
|
|
76
|
+
'The workspace may have changed since; check its current state before relying on anything described above.');
|
|
77
|
+
}
|
|
78
|
+
const frameOf = (role) => `<${role}>\n\n</${role}>\n`.length;
|
|
79
|
+
function fit(text, room) {
|
|
80
|
+
if (text.length <= room)
|
|
81
|
+
return text;
|
|
82
|
+
if (room < MIN_TURN_CHARS)
|
|
83
|
+
return undefined;
|
|
84
|
+
let cut = room - ELISION.length;
|
|
85
|
+
// Never split a surrogate pair: the orphaned half becomes U+FFFD downstream.
|
|
86
|
+
const last = text.charCodeAt(cut - 1);
|
|
87
|
+
if (last >= 0xd800 && last <= 0xdbff)
|
|
88
|
+
cut -= 1;
|
|
89
|
+
return text.slice(0, cut) + ELISION;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Render a transcript for a new session on another engine.
|
|
93
|
+
*
|
|
94
|
+
* Everything is sent when it fits. When it does not, the opening request is
|
|
95
|
+
* pinned and the newest turns fill what is left, with one line saying how many
|
|
96
|
+
* turns in between were left out: the request says what the work is for, the
|
|
97
|
+
* newest turns say where it stands, and the middle is what can be re-derived
|
|
98
|
+
* from the workspace. Every turn's text is fenced the way openai-compat fences
|
|
99
|
+
* replayed turns, so a transcript that contains the block's own tags cannot
|
|
100
|
+
* close the block early and speak as a different role.
|
|
101
|
+
*/
|
|
102
|
+
export function renderHandoff(t, src, maxChars = DEFAULT_HANDOFF_CHARS) {
|
|
103
|
+
if (!t.entries.length)
|
|
104
|
+
return { text: '', turns: 0, omitted: 0 };
|
|
105
|
+
const turns = t.entries.map((e) => ({ role: e.role, text: fenceHistoryTags(e.text) }));
|
|
106
|
+
const tail = framing(src);
|
|
107
|
+
const shell = '<conversation_history>\n</conversation_history>\n\n'.length + tail.length;
|
|
108
|
+
let budget = Math.max(maxChars, MIN_HANDOFF_CHARS) - shell;
|
|
109
|
+
const renderedLen = turns.reduce((n, x) => n + frameOf(x.role) + x.text.length, 0);
|
|
110
|
+
let kept;
|
|
111
|
+
let omitted = t.omittedAfterFirst;
|
|
112
|
+
let markerAfterFirst = t.omittedAfterFirst > 0;
|
|
113
|
+
if (renderedLen <= budget) {
|
|
114
|
+
kept = turns;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const opening = turns[0];
|
|
118
|
+
// A quarter of the budget, capped. MIN_HANDOFF_CHARS keeps this above
|
|
119
|
+
// MIN_TURN_CHARS, so the opening request always renders, if only its head.
|
|
120
|
+
const pinnedRoom = Math.min(PINNED_OPENING_CHARS, Math.floor(budget / 4)) - frameOf(opening.role);
|
|
121
|
+
const pinned = { role: opening.role, text: fit(opening.text, pinnedRoom) ?? '' };
|
|
122
|
+
budget -= frameOf(pinned.role) + pinned.text.length;
|
|
123
|
+
const markerReserve = '[… 99999 earlier turns omitted …]\n'.length;
|
|
124
|
+
budget -= markerReserve;
|
|
125
|
+
const newest = [];
|
|
126
|
+
for (let i = turns.length - 1; i >= 1; i--) {
|
|
127
|
+
const room = budget - frameOf(turns[i].role);
|
|
128
|
+
const text = fit(turns[i].text, room);
|
|
129
|
+
if (text === undefined)
|
|
130
|
+
break;
|
|
131
|
+
newest.unshift({ role: turns[i].role, text });
|
|
132
|
+
budget -= frameOf(turns[i].role) + text.length;
|
|
133
|
+
if (text !== turns[i].text)
|
|
134
|
+
break; // the boundary turn was cut; nothing older fits
|
|
135
|
+
}
|
|
136
|
+
omitted += turns.length - 1 - newest.length;
|
|
137
|
+
markerAfterFirst = omitted > 0;
|
|
138
|
+
kept = [pinned, ...newest];
|
|
139
|
+
}
|
|
140
|
+
const lines = [];
|
|
141
|
+
kept.forEach((turn, i) => {
|
|
142
|
+
if (turn.text)
|
|
143
|
+
lines.push(`<${turn.role}>\n${turn.text}\n</${turn.role}>`);
|
|
144
|
+
if (i === 0 && markerAfterFirst) {
|
|
145
|
+
lines.push(`[… ${omitted} earlier turn${omitted === 1 ? '' : 's'} omitted …]`);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
text: `<conversation_history>\n${lines.join('\n')}\n</conversation_history>\n\n${tail}`,
|
|
150
|
+
turns: kept.filter((k) => k.text).length,
|
|
151
|
+
omitted,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/handoff.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -378,6 +378,45 @@ const plugin = {
|
|
|
378
378
|
};
|
|
379
379
|
},
|
|
380
380
|
});
|
|
381
|
+
// ─── Tool: session_handoff ────────────────────────────────────────────
|
|
382
|
+
registerTool({
|
|
383
|
+
name: 'session_handoff',
|
|
384
|
+
description: "Continue a session's conversation on another engine (or another model). Starts a new session on the target engine in the same working directory and carries the conversation into it as text, so the new agent picks up where the old one left off. The source session keeps running untouched — stop it yourself if you are done with it. Pass `message` to send the next instruction immediately; otherwise the history travels with whatever you send next via session_send.",
|
|
385
|
+
parameters: {
|
|
386
|
+
type: 'object',
|
|
387
|
+
properties: {
|
|
388
|
+
name: { type: 'string', description: 'The session to hand off from' },
|
|
389
|
+
engine: {
|
|
390
|
+
type: 'string',
|
|
391
|
+
enum: ENGINE_TYPES,
|
|
392
|
+
description: 'Engine for the new session. May be the same engine with a different model.',
|
|
393
|
+
},
|
|
394
|
+
model: { type: 'string', description: 'Model for the new session (default: the engine default)' },
|
|
395
|
+
newName: { type: 'string', description: 'Name for the new session (default: `<name>-<engine>`)' },
|
|
396
|
+
message: {
|
|
397
|
+
type: 'string',
|
|
398
|
+
description: 'Send this as the first message now and return the reply (default: wait for session_send)',
|
|
399
|
+
},
|
|
400
|
+
maxChars: {
|
|
401
|
+
type: 'number',
|
|
402
|
+
description: 'Upper bound on the carried history, in characters (default 240000, minimum 4000). When the conversation is longer, the opening request and the newest turns are kept and the turns between them are left out.',
|
|
403
|
+
},
|
|
404
|
+
customEngine: CUSTOM_ENGINE_SCHEMA,
|
|
405
|
+
},
|
|
406
|
+
required: ['name', 'engine'],
|
|
407
|
+
},
|
|
408
|
+
execute: async (_id, args) => {
|
|
409
|
+
const result = await getManager().handoffSession(args.name, {
|
|
410
|
+
engine: args.engine,
|
|
411
|
+
model: args.model,
|
|
412
|
+
newName: args.newName,
|
|
413
|
+
message: args.message,
|
|
414
|
+
maxChars: args.maxChars,
|
|
415
|
+
customEngine: args.customEngine,
|
|
416
|
+
});
|
|
417
|
+
return { ok: true, ...result };
|
|
418
|
+
},
|
|
419
|
+
});
|
|
381
420
|
// ─── Tool: session_stop ───────────────────────────────────────────────
|
|
382
421
|
registerTool({
|
|
383
422
|
name: 'session_stop',
|