aemeathcli 1.0.9 → 1.0.11
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/LICENSE +21 -0
- package/README.md +609 -608
- package/dist/App-YAHJUWCX.js +4274 -0
- package/dist/App-YAHJUWCX.js.map +1 -0
- package/dist/agent-store/architect.md +32 -0
- package/dist/agent-store/debugger.md +32 -0
- package/dist/agent-store/developer.md +29 -0
- package/dist/agent-store/documenter.md +30 -0
- package/dist/agent-store/researcher.md +31 -0
- package/dist/agent-store/reviewer.md +28 -0
- package/dist/agent-store/supervisor.md +37 -0
- package/dist/agent-store/tester.md +30 -0
- package/dist/api-key-fallback-UN3TJEOO.js +11 -0
- package/dist/{api-key-fallback-YQQBOQIL.js.map → api-key-fallback-UN3TJEOO.js.map} +1 -1
- package/dist/auth-status-EIM5A5KL.js +13 -0
- package/dist/auth-status-EIM5A5KL.js.map +1 -0
- package/dist/{chunk-UY2SYSEZ.js → chunk-25UNNEHN.js} +32 -103
- package/dist/chunk-25UNNEHN.js.map +1 -0
- package/dist/{chunk-CYQNBB25.js → chunk-2GKOK6T7.js} +28 -5
- package/dist/chunk-2GKOK6T7.js.map +1 -0
- package/dist/{chunk-MFBHNWGV.js → chunk-2LF7ALGR.js} +12 -20
- package/dist/chunk-2LF7ALGR.js.map +1 -0
- package/dist/{chunk-H66O5Z2V.js → chunk-2NWNIKBK.js} +42 -7
- package/dist/chunk-2NWNIKBK.js.map +1 -0
- package/dist/chunk-3TSPZRGM.js +26 -0
- package/dist/chunk-3TSPZRGM.js.map +1 -0
- package/dist/{chunk-ZGOHARPV.js → chunk-473JN6M5.js} +2 -2
- package/dist/chunk-473JN6M5.js.map +1 -0
- package/dist/{chunk-IYW62KKR.js → chunk-5XFSV6PF.js} +66 -23
- package/dist/chunk-5XFSV6PF.js.map +1 -0
- package/dist/{chunk-HCIHOHLX.js → chunk-62HSGYQD.js} +2 -2
- package/dist/chunk-62HSGYQD.js.map +1 -0
- package/dist/{chunk-I5PZ4JTS.js → chunk-6GUD7QIM.js} +4 -4
- package/dist/chunk-6GUD7QIM.js.map +1 -0
- package/dist/{chunk-4IJD72YB.js → chunk-AQ23TYSQ.js} +7 -7
- package/dist/chunk-AQ23TYSQ.js.map +1 -0
- package/dist/{chunk-NBR3GHMT.js → chunk-BY4DAKUU.js} +39 -7
- package/dist/chunk-BY4DAKUU.js.map +1 -0
- package/dist/chunk-CC7MGWYY.js +12 -0
- package/dist/chunk-CC7MGWYY.js.map +1 -0
- package/dist/chunk-CTFZTARK.js +155 -0
- package/dist/chunk-CTFZTARK.js.map +1 -0
- package/dist/chunk-FIC7AK4Q.js +232 -0
- package/dist/chunk-FIC7AK4Q.js.map +1 -0
- package/dist/chunk-GU33WKPG.js +140 -0
- package/dist/chunk-GU33WKPG.js.map +1 -0
- package/dist/{chunk-VUG4IZ7J.js → chunk-H2SYKIMI.js} +10 -10
- package/dist/chunk-H2SYKIMI.js.map +1 -0
- package/dist/{chunk-JAXXTYID.js → chunk-HEKFAKVH.js} +2 -2
- package/dist/chunk-HEKFAKVH.js.map +1 -0
- package/dist/chunk-IARA5XYP.js +186 -0
- package/dist/chunk-IARA5XYP.js.map +1 -0
- package/dist/{chunk-HMJRPNPZ.js → chunk-LCYH4T6N.js} +95 -23
- package/dist/chunk-LCYH4T6N.js.map +1 -0
- package/dist/{chunk-CARHU3DO.js → chunk-LDVY5ELP.js} +66 -18
- package/dist/chunk-LDVY5ELP.js.map +1 -0
- package/dist/chunk-OCJPQFOR.js +88 -0
- package/dist/chunk-OCJPQFOR.js.map +1 -0
- package/dist/chunk-ODBY7S4X.js +141 -0
- package/dist/chunk-ODBY7S4X.js.map +1 -0
- package/dist/{chunk-DAHGLHNR.js → chunk-ONQ4WCUI.js} +7 -142
- package/dist/chunk-ONQ4WCUI.js.map +1 -0
- package/dist/{chunk-WPP3PEDE.js → chunk-P5TKZM3T.js} +32 -107
- package/dist/chunk-P5TKZM3T.js.map +1 -0
- package/dist/{chunk-ASGRGXYK.js → chunk-P66WDACW.js} +23 -22
- package/dist/chunk-P66WDACW.js.map +1 -0
- package/dist/{chunk-LSOYPSAT.js → chunk-QCRK4QEL.js} +4 -4
- package/dist/chunk-QCRK4QEL.js.map +1 -0
- package/dist/{chunk-YL5XFHR3.js → chunk-ROJPFPJ7.js} +2 -2
- package/dist/chunk-ROJPFPJ7.js.map +1 -0
- package/dist/chunk-RP2TAL3J.js +71 -0
- package/dist/chunk-RP2TAL3J.js.map +1 -0
- package/dist/{chunk-6PDJ45T4.js → chunk-RYOB3TLZ.js} +51 -26
- package/dist/chunk-RYOB3TLZ.js.map +1 -0
- package/dist/{chunk-Y5XVD2CD.js → chunk-SOQFMNQC.js} +110 -83
- package/dist/chunk-SOQFMNQC.js.map +1 -0
- package/dist/{chunk-TEVZS4FA.js → chunk-TDFTX32B.js} +16 -9
- package/dist/chunk-TDFTX32B.js.map +1 -0
- package/dist/chunk-VBLLDY4R.js +38 -0
- package/dist/chunk-VBLLDY4R.js.map +1 -0
- package/dist/{chunk-CGEV3ARR.js → chunk-VJNQJALF.js} +4 -4
- package/dist/chunk-VJNQJALF.js.map +1 -0
- package/dist/chunk-WAYSJMPS.js +26 -0
- package/dist/chunk-WAYSJMPS.js.map +1 -0
- package/dist/chunk-WC72BRHR.js +241 -0
- package/dist/chunk-WC72BRHR.js.map +1 -0
- package/dist/{chunk-MXZSI3AY.js → chunk-YPFOE2QJ.js} +43 -11
- package/dist/chunk-YPFOE2QJ.js.map +1 -0
- package/dist/claude-adapter-6P4SJH7P.js +7 -0
- package/dist/{claude-adapter-QMLFMSP3.js.map → claude-adapter-6P4SJH7P.js.map} +1 -1
- package/dist/{claude-login-5WELXPKT.js → claude-login-IS5WTBMP.js} +10 -10
- package/dist/claude-login-IS5WTBMP.js.map +1 -0
- package/dist/cli.js +371 -172
- package/dist/cli.js.map +1 -1
- package/dist/{codex-login-DDJBCT43.js → codex-login-GMPF64MR.js} +18 -17
- package/dist/codex-login-GMPF64MR.js.map +1 -0
- package/dist/config-store-POB6I37G.js +7 -0
- package/dist/{config-store-W6FBCQAQ.js.map → config-store-POB6I37G.js.map} +1 -1
- package/dist/conversation-store-PRBHWQMJ.js +4 -0
- package/dist/conversation-store-PRBHWQMJ.js.map +1 -0
- package/dist/detect-providers-C4SVQHFF.js +4 -0
- package/dist/detect-providers-C4SVQHFF.js.map +1 -0
- package/dist/executor-RUX7VK3T.js +4 -0
- package/dist/{executor-6RIKIGXK.js.map → executor-RUX7VK3T.js.map} +1 -1
- package/dist/first-run-GDEVRFPO.js +230 -0
- package/dist/first-run-GDEVRFPO.js.map +1 -0
- package/dist/gemini-adapter-MV3U4QFH.js +7 -0
- package/dist/{gemini-adapter-6JIHZ7WI.js.map → gemini-adapter-MV3U4QFH.js.map} +1 -1
- package/dist/{gemini-login-YEPK6GGW.js → gemini-login-KE224MSW.js} +13 -14
- package/dist/gemini-login-KE224MSW.js.map +1 -0
- package/dist/index.d.ts +47 -17
- package/dist/index.js +86 -471
- package/dist/index.js.map +1 -1
- package/dist/input-history-MIOO3FIW.js +57 -0
- package/dist/input-history-MIOO3FIW.js.map +1 -0
- package/dist/kimi-adapter-UODMNX6K.js +6 -0
- package/dist/{kimi-adapter-JN4HFFHU.js.map → kimi-adapter-UODMNX6K.js.map} +1 -1
- package/dist/{kimi-login-ZR74MIY4.js → kimi-login-DNT5YBKX.js} +18 -17
- package/dist/kimi-login-DNT5YBKX.js.map +1 -0
- package/dist/logger-PLPDWACQ.js +3 -0
- package/dist/logger-PLPDWACQ.js.map +1 -0
- package/dist/model-discovery-O64ZWPX5.js +6 -0
- package/dist/model-discovery-O64ZWPX5.js.map +1 -0
- package/dist/native-cli-adapters-JMZX2C2C.js +8 -0
- package/dist/{native-cli-adapters-OLW3XX57.js.map → native-cli-adapters-JMZX2C2C.js.map} +1 -1
- package/dist/ollama-adapter-GE67BNSS.js +5 -0
- package/dist/{ollama-adapter-OJQ3FKWK.js.map → ollama-adapter-GE67BNSS.js.map} +1 -1
- package/dist/openai-adapter-SHPLK77L.js +7 -0
- package/dist/{openai-adapter-XU46EN7B.js.map → openai-adapter-SHPLK77L.js.map} +1 -1
- package/dist/pathResolver-A6IXQQFE.js +3 -0
- package/dist/pathResolver-A6IXQQFE.js.map +1 -0
- package/dist/profile-loader-TNAXBLDX.js +162 -0
- package/dist/profile-loader-TNAXBLDX.js.map +1 -0
- package/dist/registry-3NHVCXCZ.js +6 -0
- package/dist/{registry-H7B3AHPQ.js.map → registry-3NHVCXCZ.js.map} +1 -1
- package/dist/registry-7CQ3NCAD.js +5 -0
- package/dist/{registry-OYWYT7WL.js.map → registry-7CQ3NCAD.js.map} +1 -1
- package/dist/server-manager-DES23IBQ.js +5 -0
- package/dist/{server-manager-PTGBHCLS.js.map → server-manager-DES23IBQ.js.map} +1 -1
- package/dist/session-manager-EHD7GWM2.js +12 -0
- package/dist/{session-manager-NYB2RKMS.js.map → session-manager-EHD7GWM2.js.map} +1 -1
- package/dist/skills/built-in/code-review/SKILL.md +85 -0
- package/dist/skills/built-in/commit/SKILL.md +83 -0
- package/dist/skills/built-in/debug/SKILL.md +119 -0
- package/dist/skills/built-in/plan/SKILL.md +123 -0
- package/dist/skills/built-in/refactor/SKILL.md +132 -0
- package/dist/skills/built-in/test/SKILL.md +128 -0
- package/dist/sqlite-store-7ZIVOUNI.js +5 -0
- package/dist/sqlite-store-7ZIVOUNI.js.map +1 -0
- package/dist/team-manager-6DCNLGTC.js +11 -0
- package/dist/{team-manager-HC4XGCFY.js.map → team-manager-6DCNLGTC.js.map} +1 -1
- package/dist/team-state-R2D7DT5M.js +3 -0
- package/dist/team-state-R2D7DT5M.js.map +1 -0
- package/dist/tmux-manager-WBKHUHDT.js +6 -0
- package/dist/{tmux-manager-GPYZ3WQH.js.map → tmux-manager-WBKHUHDT.js.map} +1 -1
- package/dist/tools-I6XCTEZY.js +6 -0
- package/dist/{tools-TSMXMHIF.js.map → tools-I6XCTEZY.js.map} +1 -1
- package/package.json +93 -89
- package/dist/App-TE3JJKOW.js +0 -2789
- package/dist/App-TE3JJKOW.js.map +0 -1
- package/dist/api-key-fallback-YQQBOQIL.js +0 -11
- package/dist/chunk-4IJD72YB.js.map +0 -1
- package/dist/chunk-6PDJ45T4.js.map +0 -1
- package/dist/chunk-ASGRGXYK.js.map +0 -1
- package/dist/chunk-CARHU3DO.js.map +0 -1
- package/dist/chunk-CGEV3ARR.js.map +0 -1
- package/dist/chunk-CS5X3BWX.js +0 -27
- package/dist/chunk-CS5X3BWX.js.map +0 -1
- package/dist/chunk-CYQNBB25.js.map +0 -1
- package/dist/chunk-DAHGLHNR.js.map +0 -1
- package/dist/chunk-H66O5Z2V.js.map +0 -1
- package/dist/chunk-HCIHOHLX.js.map +0 -1
- package/dist/chunk-HMJRPNPZ.js.map +0 -1
- package/dist/chunk-I5PZ4JTS.js.map +0 -1
- package/dist/chunk-IYW62KKR.js.map +0 -1
- package/dist/chunk-JAXXTYID.js.map +0 -1
- package/dist/chunk-LSOYPSAT.js.map +0 -1
- package/dist/chunk-MFBHNWGV.js.map +0 -1
- package/dist/chunk-MXZSI3AY.js.map +0 -1
- package/dist/chunk-NBR3GHMT.js.map +0 -1
- package/dist/chunk-TEVZS4FA.js.map +0 -1
- package/dist/chunk-UY2SYSEZ.js.map +0 -1
- package/dist/chunk-VUG4IZ7J.js.map +0 -1
- package/dist/chunk-WAHVZH7V.js +0 -260
- package/dist/chunk-WAHVZH7V.js.map +0 -1
- package/dist/chunk-WPP3PEDE.js.map +0 -1
- package/dist/chunk-Y5XVD2CD.js.map +0 -1
- package/dist/chunk-YL5XFHR3.js.map +0 -1
- package/dist/chunk-ZGOHARPV.js.map +0 -1
- package/dist/claude-adapter-QMLFMSP3.js +0 -6
- package/dist/claude-login-5WELXPKT.js.map +0 -1
- package/dist/codex-login-DDJBCT43.js.map +0 -1
- package/dist/config-store-W6FBCQAQ.js +0 -6
- package/dist/executor-6RIKIGXK.js +0 -4
- package/dist/gemini-adapter-6JIHZ7WI.js +0 -6
- package/dist/gemini-login-YEPK6GGW.js.map +0 -1
- package/dist/kimi-adapter-JN4HFFHU.js +0 -6
- package/dist/kimi-login-ZR74MIY4.js.map +0 -1
- package/dist/native-cli-adapters-OLW3XX57.js +0 -6
- package/dist/ollama-adapter-OJQ3FKWK.js +0 -6
- package/dist/openai-adapter-XU46EN7B.js +0 -6
- package/dist/registry-H7B3AHPQ.js +0 -5
- package/dist/registry-OYWYT7WL.js +0 -6
- package/dist/server-manager-PTGBHCLS.js +0 -5
- package/dist/session-manager-NYB2RKMS.js +0 -12
- package/dist/team-manager-HC4XGCFY.js +0 -11
- package/dist/tmux-manager-GPYZ3WQH.js +0 -6
- package/dist/tools-TSMXMHIF.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getEventBus } from './chunk-
|
|
2
|
-
import { AgentSpawnError } from './chunk-
|
|
3
|
-
import { logger } from './chunk-
|
|
1
|
+
import { getEventBus } from './chunk-ROJPFPJ7.js';
|
|
2
|
+
import { AgentSpawnError } from './chunk-473JN6M5.js';
|
|
3
|
+
import { logger } from './chunk-HEKFAKVH.js';
|
|
4
4
|
import { execa } from 'execa';
|
|
5
5
|
|
|
6
6
|
// src/panes/layout-engine.ts
|
|
@@ -63,9 +63,7 @@ var LayoutEngine = class {
|
|
|
63
63
|
*/
|
|
64
64
|
resolveAutoLayout(paneCount) {
|
|
65
65
|
if (paneCount <= 1) return "horizontal";
|
|
66
|
-
|
|
67
|
-
if (paneCount <= 4) return "grid";
|
|
68
|
-
return "grid";
|
|
66
|
+
return "hub-spoke";
|
|
69
67
|
}
|
|
70
68
|
/**
|
|
71
69
|
* Get the maximum number of panes the terminal can support.
|
|
@@ -92,6 +90,8 @@ var LayoutEngine = class {
|
|
|
92
90
|
return { gridRows: paneCount, gridCols: 1 };
|
|
93
91
|
case "grid":
|
|
94
92
|
return this.computeGridSize(paneCount);
|
|
93
|
+
case "hub-spoke":
|
|
94
|
+
return { gridRows: Math.max(1, paneCount - 1), gridCols: 2 };
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
@@ -122,8 +122,41 @@ var LayoutEngine = class {
|
|
|
122
122
|
return this.computeVerticalLayout(panes);
|
|
123
123
|
case "grid":
|
|
124
124
|
return this.computeGridLayout(panes, paneCount);
|
|
125
|
+
case "hub-spoke":
|
|
126
|
+
return this.computeHubSpokeLayout(panes);
|
|
125
127
|
}
|
|
126
128
|
}
|
|
129
|
+
computeHubSpokeLayout(panes) {
|
|
130
|
+
const [leaderPane, ...workerPanes] = panes;
|
|
131
|
+
if (!leaderPane) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
const geometries = [
|
|
135
|
+
{
|
|
136
|
+
paneId: leaderPane.paneId,
|
|
137
|
+
row: 0,
|
|
138
|
+
col: 0,
|
|
139
|
+
widthPercent: workerPanes.length > 0 ? 50 : 100,
|
|
140
|
+
heightPercent: 100,
|
|
141
|
+
splitDirection: "none"
|
|
142
|
+
}
|
|
143
|
+
];
|
|
144
|
+
if (workerPanes.length === 0) {
|
|
145
|
+
return geometries;
|
|
146
|
+
}
|
|
147
|
+
const workerHeightPercent = Math.floor(100 / workerPanes.length);
|
|
148
|
+
for (const [index, pane] of workerPanes.entries()) {
|
|
149
|
+
geometries.push({
|
|
150
|
+
paneId: pane.paneId,
|
|
151
|
+
row: index,
|
|
152
|
+
col: 1,
|
|
153
|
+
widthPercent: 50,
|
|
154
|
+
heightPercent: index === workerPanes.length - 1 ? 100 - workerHeightPercent * (workerPanes.length - 1) : workerHeightPercent,
|
|
155
|
+
splitDirection: index === 0 ? "horizontal" : "vertical"
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return geometries;
|
|
159
|
+
}
|
|
127
160
|
/**
|
|
128
161
|
* Horizontal split: all panes side by side.
|
|
129
162
|
*/
|
|
@@ -285,6 +318,7 @@ var TmuxManager = class {
|
|
|
285
318
|
* Check if tmux is available on this system.
|
|
286
319
|
*/
|
|
287
320
|
async isAvailable() {
|
|
321
|
+
if (process.platform === "win32") return false;
|
|
288
322
|
try {
|
|
289
323
|
const result = await execa("which", [TMUX_BINARY]);
|
|
290
324
|
return result.exitCode === 0;
|
|
@@ -305,6 +339,10 @@ var TmuxManager = class {
|
|
|
305
339
|
);
|
|
306
340
|
}
|
|
307
341
|
this.sessionName = `${this.sessionPrefix}-${teamName}`;
|
|
342
|
+
const stdout = {
|
|
343
|
+
columns: process.stdout.columns,
|
|
344
|
+
rows: process.stdout.rows
|
|
345
|
+
};
|
|
308
346
|
await this.killSessionSilent(this.sessionName);
|
|
309
347
|
try {
|
|
310
348
|
await execa(TMUX_BINARY, [
|
|
@@ -313,9 +351,9 @@ var TmuxManager = class {
|
|
|
313
351
|
"-s",
|
|
314
352
|
this.sessionName,
|
|
315
353
|
"-x",
|
|
316
|
-
String(
|
|
354
|
+
String(stdout.columns ?? 120),
|
|
317
355
|
"-y",
|
|
318
|
-
String(
|
|
356
|
+
String(stdout.rows ?? 40)
|
|
319
357
|
]);
|
|
320
358
|
logger.info({ sessionName: this.sessionName }, "tmux session created");
|
|
321
359
|
} catch (error) {
|
|
@@ -331,6 +369,7 @@ var TmuxManager = class {
|
|
|
331
369
|
this.assertNotDisposed();
|
|
332
370
|
this.assertSession();
|
|
333
371
|
const computed = this.layoutEngine.computeLayout(layoutConfig);
|
|
372
|
+
const resolvedLayout = layoutConfig.layout === "auto" ? this.layoutEngine.resolveAutoLayout(layoutConfig.panes.length) : layoutConfig.layout;
|
|
334
373
|
const firstGeometry = computed.panes[0];
|
|
335
374
|
const firstConfig = layoutConfig.panes[0];
|
|
336
375
|
if (firstGeometry && firstConfig) {
|
|
@@ -366,7 +405,7 @@ var TmuxManager = class {
|
|
|
366
405
|
agentName: config.agentName
|
|
367
406
|
});
|
|
368
407
|
}
|
|
369
|
-
await this.
|
|
408
|
+
await this.applyLayoutPreset(resolvedLayout);
|
|
370
409
|
logger.info(
|
|
371
410
|
{ paneCount: this.panes.size, session: this.sessionName },
|
|
372
411
|
"All panes created"
|
|
@@ -451,8 +490,8 @@ var TmuxManager = class {
|
|
|
451
490
|
*/
|
|
452
491
|
async attachSession() {
|
|
453
492
|
this.assertNotDisposed();
|
|
454
|
-
this.
|
|
455
|
-
await execa(TMUX_BINARY, ["attach-session", "-t",
|
|
493
|
+
const sessionName = this.requireSessionName();
|
|
494
|
+
await execa(TMUX_BINARY, ["attach-session", "-t", sessionName], {
|
|
456
495
|
stdio: "inherit"
|
|
457
496
|
});
|
|
458
497
|
}
|
|
@@ -498,12 +537,13 @@ var TmuxManager = class {
|
|
|
498
537
|
}
|
|
499
538
|
// ── Private Helpers ─────────────────────────────────────────────────
|
|
500
539
|
async splitPane(geometry) {
|
|
540
|
+
const sessionName = this.requireSessionName();
|
|
501
541
|
const splitFlag = geometry.splitDirection === "horizontal" ? "-h" : "-v";
|
|
502
542
|
const result = await execa(TMUX_BINARY, [
|
|
503
543
|
"split-window",
|
|
504
544
|
splitFlag,
|
|
505
545
|
"-t",
|
|
506
|
-
|
|
546
|
+
sessionName,
|
|
507
547
|
"-P",
|
|
508
548
|
"-F",
|
|
509
549
|
"#{pane_id}"
|
|
@@ -516,27 +556,29 @@ var TmuxManager = class {
|
|
|
516
556
|
return tmuxPaneId;
|
|
517
557
|
}
|
|
518
558
|
async getFirstPaneId() {
|
|
559
|
+
const sessionName = this.requireSessionName();
|
|
519
560
|
const result = await execa(TMUX_BINARY, [
|
|
520
561
|
"list-panes",
|
|
521
562
|
"-t",
|
|
522
|
-
|
|
563
|
+
sessionName,
|
|
523
564
|
"-F",
|
|
524
565
|
"#{pane_id}"
|
|
525
566
|
]);
|
|
526
567
|
const firstLine = result.stdout.trim().split("\n")[0];
|
|
527
568
|
return firstLine ?? "%0";
|
|
528
569
|
}
|
|
529
|
-
async
|
|
570
|
+
async applyLayoutPreset(layout) {
|
|
530
571
|
if (!this.sessionName) return;
|
|
572
|
+
const tmuxLayout = layout === "hub-spoke" ? "main-vertical" : "tiled";
|
|
531
573
|
try {
|
|
532
574
|
await execa(TMUX_BINARY, [
|
|
533
575
|
"select-layout",
|
|
534
576
|
"-t",
|
|
535
577
|
this.sessionName,
|
|
536
|
-
|
|
578
|
+
tmuxLayout
|
|
537
579
|
]);
|
|
538
580
|
} catch {
|
|
539
|
-
logger.debug("Failed to
|
|
581
|
+
logger.debug({ layout: tmuxLayout }, "Failed to apply tmux layout preset (non-fatal)");
|
|
540
582
|
}
|
|
541
583
|
}
|
|
542
584
|
async killSessionSilent(sessionName) {
|
|
@@ -555,8 +597,14 @@ var TmuxManager = class {
|
|
|
555
597
|
throw new AgentSpawnError("tmux", "No active tmux session. Call createSession() first.");
|
|
556
598
|
}
|
|
557
599
|
}
|
|
600
|
+
requireSessionName() {
|
|
601
|
+
if (!this.sessionName) {
|
|
602
|
+
throw new AgentSpawnError("tmux", "No active tmux session. Call createSession() first.");
|
|
603
|
+
}
|
|
604
|
+
return this.sessionName;
|
|
605
|
+
}
|
|
558
606
|
};
|
|
559
607
|
|
|
560
608
|
export { LayoutEngine, TmuxManager };
|
|
561
|
-
//# sourceMappingURL=chunk-
|
|
562
|
-
//# sourceMappingURL=chunk-
|
|
609
|
+
//# sourceMappingURL=chunk-LDVY5ELP.js.map
|
|
610
|
+
//# sourceMappingURL=chunk-LDVY5ELP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/panes/layout-engine.ts","../src/panes/tmux-manager.ts"],"names":["firstPane","bottomPanes"],"mappings":"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","file":"chunk-LDVY5ELP.js","sourcesContent":["/**\r\n * Layout engine for split-panel auto-layout computation per PRD section 9.2.\r\n * Computes pane positions based on agent count and terminal dimensions.\r\n */\r\n\r\nimport type { PaneLayout, IPaneConfig, ILayoutConfig } from \"../types/team.js\";\r\nimport { logger } from \"../utils/logger.js\";\r\n\r\n// ── Layout Geometry ─────────────────────────────────────────────────────\r\n\r\nexport interface IPaneGeometry {\r\n readonly paneId: string;\r\n readonly row: number;\r\n readonly col: number;\r\n readonly widthPercent: number;\r\n readonly heightPercent: number;\r\n readonly splitDirection: \"horizontal\" | \"vertical\" | \"none\";\r\n}\r\n\r\nexport interface IComputedLayout {\r\n readonly panes: readonly IPaneGeometry[];\r\n readonly rows: number;\r\n readonly cols: number;\r\n readonly terminalWidth: number;\r\n readonly terminalHeight: number;\r\n}\r\n\r\ninterface ITerminalSize {\r\n readonly columns: number;\r\n readonly rows: number;\r\n}\r\n\r\n// ── Constants ───────────────────────────────────────────────────────────\r\n\r\nconst MIN_PANE_WIDTH = 40;\r\nconst MIN_PANE_HEIGHT = 10;\r\nconst DEFAULT_TERMINAL_WIDTH = 120;\r\nconst DEFAULT_TERMINAL_HEIGHT = 40;\r\nconst MAX_GRID_COLUMNS = 3;\r\n\r\n// ── Layout Engine ───────────────────────────────────────────────────────\r\n\r\nexport class LayoutEngine {\r\n private readonly terminalSize: ITerminalSize;\r\n\r\n constructor(terminalSize?: Partial<ITerminalSize>) {\r\n this.terminalSize = {\r\n columns: terminalSize?.columns ?? this.detectTerminalWidth(),\r\n rows: terminalSize?.rows ?? this.detectTerminalHeight(),\r\n };\r\n logger.debug(\r\n { terminalSize: this.terminalSize },\r\n \"LayoutEngine initialized\",\r\n );\r\n }\r\n\r\n /**\r\n * Compute the full layout for a set of pane configs.\r\n */\r\n computeLayout(config: ILayoutConfig): IComputedLayout {\r\n const paneCount = config.panes.length;\r\n if (paneCount === 0) {\r\n return {\r\n panes: [],\r\n rows: 0,\r\n cols: 0,\r\n terminalWidth: this.terminalSize.columns,\r\n terminalHeight: this.terminalSize.rows,\r\n };\r\n }\r\n\r\n const effectiveCount = Math.max(\r\n 1,\r\n Math.min(paneCount, config.maxPanes, this.getMaxPanes()),\r\n );\r\n const layout = config.layout === \"auto\"\r\n ? this.resolveAutoLayout(effectiveCount)\r\n : config.layout;\r\n\r\n const geometries = this.computeGeometries(\r\n config.panes.slice(0, effectiveCount),\r\n layout,\r\n effectiveCount,\r\n );\r\n\r\n const { gridRows, gridCols } = this.getGridDimensions(effectiveCount, layout);\r\n\r\n logger.info(\r\n { layout, paneCount: effectiveCount, gridRows, gridCols },\r\n \"Layout computed\",\r\n );\r\n\r\n return {\r\n panes: geometries,\r\n rows: gridRows,\r\n cols: gridCols,\r\n terminalWidth: this.terminalSize.columns,\r\n terminalHeight: this.terminalSize.rows,\r\n };\r\n }\r\n\r\n /**\r\n * Determine the best auto-layout for a given pane count (PRD section 9.2).\r\n */\r\n resolveAutoLayout(paneCount: number): Exclude<PaneLayout, \"auto\"> {\r\n if (paneCount <= 1) return \"horizontal\";\r\n return \"hub-spoke\";\r\n }\r\n\r\n /**\r\n * Get the maximum number of panes the terminal can support.\r\n */\r\n getMaxPanes(): number {\r\n const maxByWidth = Math.floor(this.terminalSize.columns / MIN_PANE_WIDTH);\r\n const maxByHeight = Math.floor(this.terminalSize.rows / MIN_PANE_HEIGHT);\r\n return Math.max(1, maxByWidth * maxByHeight);\r\n }\r\n\r\n /**\r\n * Check if the terminal is large enough for the requested pane count.\r\n */\r\n canFitPanes(paneCount: number): boolean {\r\n return paneCount <= this.getMaxPanes();\r\n }\r\n\r\n /**\r\n * Get the grid dimensions for a given pane count and layout type.\r\n */\r\n private getGridDimensions(\r\n paneCount: number,\r\n layout: Exclude<PaneLayout, \"auto\">,\r\n ): { gridRows: number; gridCols: number } {\r\n switch (layout) {\r\n case \"horizontal\":\r\n return { gridRows: 1, gridCols: paneCount };\r\n case \"vertical\":\r\n return { gridRows: paneCount, gridCols: 1 };\r\n case \"grid\":\r\n return this.computeGridSize(paneCount);\r\n case \"hub-spoke\":\r\n return { gridRows: Math.max(1, paneCount - 1), gridCols: 2 };\r\n }\r\n }\r\n\r\n /**\r\n * Compute grid rows and columns for a given pane count.\r\n * PRD section 9.2:\r\n * 2 agents → horizontal split (50/50) → 1x2\r\n * 3 agents → 1 top + 2 bottom → 2 rows\r\n * 4 agents → 2x2 grid\r\n * 5+ agents → leader top + grid bottom\r\n */\r\n private computeGridSize(paneCount: number): { gridRows: number; gridCols: number } {\r\n if (paneCount <= 1) return { gridRows: 1, gridCols: 1 };\r\n if (paneCount === 2) return { gridRows: 1, gridCols: 2 };\r\n if (paneCount <= 4) return { gridRows: 2, gridCols: 2 };\r\n\r\n const bottomPaneCount = paneCount - 1;\r\n const gridCols = Math.min(bottomPaneCount, MAX_GRID_COLUMNS);\r\n const gridRows = 1 + Math.ceil(bottomPaneCount / gridCols);\r\n return { gridRows, gridCols };\r\n }\r\n\r\n /**\r\n * Compute per-pane geometries based on layout type.\r\n */\r\n private computeGeometries(\r\n panes: readonly IPaneConfig[],\r\n layout: Exclude<PaneLayout, \"auto\">,\r\n paneCount: number,\r\n ): IPaneGeometry[] {\r\n switch (layout) {\r\n case \"horizontal\":\r\n return this.computeHorizontalLayout(panes);\r\n case \"vertical\":\r\n return this.computeVerticalLayout(panes);\r\n case \"grid\":\r\n return this.computeGridLayout(panes, paneCount);\r\n case \"hub-spoke\":\r\n return this.computeHubSpokeLayout(panes);\r\n }\r\n }\r\n\r\n private computeHubSpokeLayout(panes: readonly IPaneConfig[]): IPaneGeometry[] {\r\n const [leaderPane, ...workerPanes] = panes;\r\n if (!leaderPane) {\r\n return [];\r\n }\r\n\r\n const geometries: IPaneGeometry[] = [\r\n {\r\n paneId: leaderPane.paneId,\r\n row: 0,\r\n col: 0,\r\n widthPercent: workerPanes.length > 0 ? 50 : 100,\r\n heightPercent: 100,\r\n splitDirection: \"none\",\r\n },\r\n ];\r\n\r\n if (workerPanes.length === 0) {\r\n return geometries;\r\n }\r\n\r\n const workerHeightPercent = Math.floor(100 / workerPanes.length);\r\n for (const [index, pane] of workerPanes.entries()) {\r\n geometries.push({\r\n paneId: pane.paneId,\r\n row: index,\r\n col: 1,\r\n widthPercent: 50,\r\n heightPercent:\r\n index === workerPanes.length - 1\r\n ? 100 - workerHeightPercent * (workerPanes.length - 1)\r\n : workerHeightPercent,\r\n splitDirection: index === 0 ? \"horizontal\" : \"vertical\",\r\n });\r\n }\r\n\r\n return geometries;\r\n }\r\n\r\n /**\r\n * Horizontal split: all panes side by side.\r\n */\r\n private computeHorizontalLayout(panes: readonly IPaneConfig[]): IPaneGeometry[] {\r\n const widthPercent = Math.floor(100 / panes.length);\r\n return panes.map((pane, index) => ({\r\n paneId: pane.paneId,\r\n row: 0,\r\n col: index,\r\n widthPercent: index === panes.length - 1\r\n ? 100 - widthPercent * (panes.length - 1)\r\n : widthPercent,\r\n heightPercent: 100,\r\n splitDirection: index === 0 ? \"none\" as const : \"horizontal\" as const,\r\n }));\r\n }\r\n\r\n /**\r\n * Vertical split: all panes stacked.\r\n */\r\n private computeVerticalLayout(panes: readonly IPaneConfig[]): IPaneGeometry[] {\r\n const heightPercent = Math.floor(100 / panes.length);\r\n return panes.map((pane, index) => ({\r\n paneId: pane.paneId,\r\n row: index,\r\n col: 0,\r\n widthPercent: 100,\r\n heightPercent: index === panes.length - 1\r\n ? 100 - heightPercent * (panes.length - 1)\r\n : heightPercent,\r\n splitDirection: index === 0 ? \"none\" as const : \"vertical\" as const,\r\n }));\r\n }\r\n\r\n /**\r\n * Grid layout per PRD section 9.2 rules:\r\n * 3 agents → leader spans top, 2 on bottom\r\n * 4 agents → 2x2 even grid\r\n * 5+ agents → leader spans top, rest in grid below\r\n */\r\n private computeGridLayout(\r\n panes: readonly IPaneConfig[],\r\n paneCount: number,\r\n ): IPaneGeometry[] {\r\n const geometries: IPaneGeometry[] = [];\r\n\r\n if (paneCount <= 2) {\r\n return this.computeHorizontalLayout(panes);\r\n }\r\n\r\n if (paneCount === 3) {\r\n // 1 top (leader, full width) + 2 bottom\r\n const firstPane = panes[0];\r\n if (firstPane) {\r\n geometries.push({\r\n paneId: firstPane.paneId,\r\n row: 0,\r\n col: 0,\r\n widthPercent: 100,\r\n heightPercent: 50,\r\n splitDirection: \"none\",\r\n });\r\n }\r\n const bottomPanes = panes.slice(1);\r\n for (let i = 0; i < bottomPanes.length; i++) {\r\n const pane = bottomPanes[i];\r\n if (pane) {\r\n geometries.push({\r\n paneId: pane.paneId,\r\n row: 1,\r\n col: i,\r\n widthPercent: 50,\r\n heightPercent: 50,\r\n splitDirection: i === 0 ? \"vertical\" : \"horizontal\",\r\n });\r\n }\r\n }\r\n return geometries;\r\n }\r\n\r\n if (paneCount === 4) {\r\n // 2x2 even grid\r\n const { gridCols } = this.computeGridSize(4);\r\n for (let i = 0; i < panes.length; i++) {\r\n const pane = panes[i];\r\n if (pane) {\r\n const row = Math.floor(i / gridCols);\r\n const col = i % gridCols;\r\n geometries.push({\r\n paneId: pane.paneId,\r\n row,\r\n col,\r\n widthPercent: 50,\r\n heightPercent: 50,\r\n splitDirection: this.determineSplitDirection(i, row, col),\r\n });\r\n }\r\n }\r\n return geometries;\r\n }\r\n\r\n // 5+ agents: leader top + grid bottom\r\n const firstPane = panes[0];\r\n if (firstPane) {\r\n geometries.push({\r\n paneId: firstPane.paneId,\r\n row: 0,\r\n col: 0,\r\n widthPercent: 100,\r\n heightPercent: 40,\r\n splitDirection: \"none\",\r\n });\r\n }\r\n\r\n const bottomPanes = panes.slice(1);\r\n const bottomCols = Math.min(bottomPanes.length, MAX_GRID_COLUMNS);\r\n const bottomRows = Math.ceil(bottomPanes.length / bottomCols);\r\n const cellWidth = Math.floor(100 / bottomCols);\r\n const cellHeight = Math.floor(60 / bottomRows);\r\n\r\n for (let i = 0; i < bottomPanes.length; i++) {\r\n const pane = bottomPanes[i];\r\n if (pane) {\r\n const row = Math.floor(i / bottomCols) + 1;\r\n const col = i % bottomCols;\r\n const isLastInRow = col === bottomCols - 1 || i === bottomPanes.length - 1;\r\n geometries.push({\r\n paneId: pane.paneId,\r\n row,\r\n col,\r\n widthPercent: isLastInRow ? 100 - cellWidth * col : cellWidth,\r\n heightPercent: cellHeight,\r\n splitDirection: this.determineSplitDirection(i + 1, row, col),\r\n });\r\n }\r\n }\r\n\r\n return geometries;\r\n }\r\n\r\n /**\r\n * Determine split direction based on position in grid.\r\n */\r\n private determineSplitDirection(\r\n index: number,\r\n row: number,\r\n col: number,\r\n ): \"horizontal\" | \"vertical\" | \"none\" {\r\n if (index === 0) return \"none\";\r\n if (col === 0) return \"vertical\";\r\n return \"horizontal\";\r\n }\r\n\r\n /**\r\n * Detect terminal width from environment.\r\n */\r\n private detectTerminalWidth(): number {\r\n const columns = process.stdout.columns;\r\n return Number.isFinite(columns) && columns > 0 ? columns : DEFAULT_TERMINAL_WIDTH;\r\n }\r\n\r\n /**\r\n * Detect terminal height from environment.\r\n */\r\n private detectTerminalHeight(): number {\r\n const rows = process.stdout.rows;\r\n return Number.isFinite(rows) && rows > 0 ? rows : DEFAULT_TERMINAL_HEIGHT;\r\n }\r\n}\r\n","/**\r\n * TmuxManager — Programmatic tmux control per PRD section 9.2.\r\n * Creates sessions, splits panes, sends commands, manages lifecycle.\r\n */\r\n\r\nimport { execa } from \"execa\";\r\nimport type { ILayoutConfig } from \"../types/team.js\";\r\nimport type { IComputedLayout, IPaneGeometry } from \"./layout-engine.js\";\r\nimport { LayoutEngine } from \"./layout-engine.js\";\r\nimport { getEventBus } from \"../core/event-bus.js\";\r\nimport { logger } from \"../utils/logger.js\";\r\nimport { AgentSpawnError } from \"../types/errors.js\";\r\n\r\n// ── Types ───────────────────────────────────────────────────────────────\r\n\r\nexport interface ITmuxPaneInfo {\r\n readonly paneId: string;\r\n readonly tmuxPaneId: string;\r\n readonly agentName: string;\r\n readonly title: string;\r\n}\r\n\r\ninterface ITmuxManagerOptions {\r\n readonly sessionPrefix?: string;\r\n}\r\n\r\n// ── Constants ───────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_SESSION_PREFIX = \"aemeathcli\";\r\nconst TMUX_BINARY = \"tmux\";\r\n\r\n// ── TmuxManager ─────────────────────────────────────────────────────────\r\n\r\nexport class TmuxManager {\r\n private readonly sessionPrefix: string;\r\n private readonly layoutEngine: LayoutEngine;\r\n private readonly panes = new Map<string, ITmuxPaneInfo>();\r\n private sessionName: string | undefined;\r\n private disposed = false;\r\n\r\n constructor(options?: ITmuxManagerOptions) {\r\n this.sessionPrefix = options?.sessionPrefix ?? DEFAULT_SESSION_PREFIX;\r\n this.layoutEngine = new LayoutEngine();\r\n }\r\n\r\n /**\r\n * Check if tmux is available on this system.\r\n */\r\n async isAvailable(): Promise<boolean> {\r\n // tmux is Unix-only — always unavailable on Windows.\r\n if (process.platform === \"win32\") return false;\r\n\r\n try {\r\n const result = await execa(\"which\", [TMUX_BINARY]);\r\n return result.exitCode === 0;\r\n } catch {\r\n logger.warn(\"tmux binary not found on PATH\");\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new tmux session for a team.\r\n */\r\n async createSession(teamName: string): Promise<string> {\r\n this.assertNotDisposed();\r\n\r\n if (!(await this.isAvailable())) {\r\n throw new AgentSpawnError(\r\n teamName,\r\n \"tmux is not installed. Install tmux or use single-pane mode.\",\r\n );\r\n }\r\n\r\n this.sessionName = `${this.sessionPrefix}-${teamName}`;\r\n const stdout = {\r\n columns: process.stdout.columns as number | undefined,\r\n rows: process.stdout.rows as number | undefined,\r\n };\r\n\r\n // Kill any existing session with the same name\r\n await this.killSessionSilent(this.sessionName);\r\n\r\n try {\r\n await execa(TMUX_BINARY, [\r\n \"new-session\",\r\n \"-d\",\r\n \"-s\", this.sessionName,\r\n \"-x\", String(stdout.columns ?? 120),\r\n \"-y\", String(stdout.rows ?? 40),\r\n ]);\r\n logger.info({ sessionName: this.sessionName }, \"tmux session created\");\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n throw new AgentSpawnError(teamName, `Failed to create tmux session: ${message}`);\r\n }\r\n\r\n return this.sessionName;\r\n }\r\n\r\n /**\r\n * Create split panes based on a layout configuration.\r\n */\r\n async createPanes(layoutConfig: ILayoutConfig): Promise<IComputedLayout> {\r\n this.assertNotDisposed();\r\n this.assertSession();\r\n\r\n const computed = this.layoutEngine.computeLayout(layoutConfig);\r\n const resolvedLayout = layoutConfig.layout === \"auto\"\r\n ? this.layoutEngine.resolveAutoLayout(layoutConfig.panes.length)\r\n : layoutConfig.layout;\r\n\r\n // First pane is already the initial pane in the session\r\n const firstGeometry = computed.panes[0];\r\n const firstConfig = layoutConfig.panes[0];\r\n if (firstGeometry && firstConfig) {\r\n const tmuxPaneId = await this.getFirstPaneId();\r\n const info: ITmuxPaneInfo = {\r\n paneId: firstConfig.paneId,\r\n tmuxPaneId,\r\n agentName: firstConfig.agentName,\r\n title: firstConfig.title,\r\n };\r\n this.panes.set(firstConfig.paneId, info);\r\n await this.setPaneTitle(tmuxPaneId, firstConfig.title);\r\n getEventBus().emit(\"pane:created\", {\r\n paneId: firstConfig.paneId,\r\n agentName: firstConfig.agentName,\r\n });\r\n }\r\n\r\n // Create remaining panes via splits\r\n for (let i = 1; i < computed.panes.length; i++) {\r\n const geometry = computed.panes[i];\r\n const config = layoutConfig.panes[i];\r\n if (!geometry || !config) continue;\r\n\r\n const tmuxPaneId = await this.splitPane(geometry);\r\n const info: ITmuxPaneInfo = {\r\n paneId: config.paneId,\r\n tmuxPaneId,\r\n agentName: config.agentName,\r\n title: config.title,\r\n };\r\n this.panes.set(config.paneId, info);\r\n await this.setPaneTitle(tmuxPaneId, config.title);\r\n getEventBus().emit(\"pane:created\", {\r\n paneId: config.paneId,\r\n agentName: config.agentName,\r\n });\r\n }\r\n\r\n await this.applyLayoutPreset(resolvedLayout);\r\n\r\n logger.info(\r\n { paneCount: this.panes.size, session: this.sessionName },\r\n \"All panes created\",\r\n );\r\n\r\n return computed;\r\n }\r\n\r\n /**\r\n * Send a command string to a specific pane.\r\n */\r\n async sendCommand(paneId: string, command: string): Promise<void> {\r\n this.assertNotDisposed();\r\n this.assertSession();\r\n\r\n const info = this.panes.get(paneId);\r\n if (!info) {\r\n logger.warn({ paneId }, \"Pane not found, cannot send command\");\r\n return;\r\n }\r\n\r\n // tmux pane IDs (%N) are globally unique — use them directly.\r\n // The format \"session:%N\" is invalid because tmux interprets\r\n // the part after \":\" as a window name, not a pane ID.\r\n await execa(TMUX_BINARY, [\r\n \"send-keys\",\r\n \"-t\", info.tmuxPaneId,\r\n command,\r\n \"Enter\",\r\n ]);\r\n\r\n logger.debug({ paneId, command: command.slice(0, 80) }, \"Command sent to pane\");\r\n }\r\n\r\n /**\r\n * Resize a pane by tmux pane target.\r\n */\r\n async resizePane(\r\n paneId: string,\r\n dimensions: { width?: number; height?: number },\r\n ): Promise<void> {\r\n this.assertNotDisposed();\r\n this.assertSession();\r\n\r\n const info = this.panes.get(paneId);\r\n if (!info) return;\r\n\r\n const target = info.tmuxPaneId;\r\n\r\n if (dimensions.width !== undefined) {\r\n await execa(TMUX_BINARY, [\"resize-pane\", \"-t\", target, \"-x\", String(dimensions.width)]);\r\n }\r\n if (dimensions.height !== undefined) {\r\n await execa(TMUX_BINARY, [\"resize-pane\", \"-t\", target, \"-y\", String(dimensions.height)]);\r\n }\r\n }\r\n\r\n /**\r\n * Set the title for a tmux pane.\r\n */\r\n private async setPaneTitle(tmuxPaneId: string, title: string): Promise<void> {\r\n if (!this.sessionName) return;\r\n try {\r\n await execa(TMUX_BINARY, [\r\n \"select-pane\",\r\n \"-t\", tmuxPaneId,\r\n \"-T\", title,\r\n ]);\r\n } catch {\r\n logger.debug({ tmuxPaneId, title }, \"Failed to set pane title (non-fatal)\");\r\n }\r\n }\r\n\r\n /**\r\n * Kill a specific pane.\r\n */\r\n async killPane(paneId: string): Promise<void> {\r\n this.assertNotDisposed();\r\n\r\n const info = this.panes.get(paneId);\r\n if (!info || !this.sessionName) return;\r\n\r\n try {\r\n await execa(TMUX_BINARY, [\r\n \"kill-pane\",\r\n \"-t\", info.tmuxPaneId,\r\n ]);\r\n this.panes.delete(paneId);\r\n getEventBus().emit(\"pane:closed\", { paneId });\r\n logger.debug({ paneId }, \"Pane killed\");\r\n } catch {\r\n logger.debug({ paneId }, \"Failed to kill pane (may already be closed)\");\r\n }\r\n }\r\n\r\n /**\r\n * Attach to the tmux session (gives control to the user).\r\n */\r\n async attachSession(): Promise<void> {\r\n this.assertNotDisposed();\r\n const sessionName = this.requireSessionName();\r\n\r\n await execa(TMUX_BINARY, [\"attach-session\", \"-t\", sessionName], {\r\n stdio: \"inherit\",\r\n });\r\n }\r\n\r\n /**\r\n * Check if the session still exists.\r\n */\r\n async isSessionAlive(): Promise<boolean> {\r\n if (!this.sessionName) return false;\r\n try {\r\n await execa(TMUX_BINARY, [\"has-session\", \"-t\", this.sessionName]);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Destroy the entire tmux session and all panes.\r\n */\r\n async destroy(): Promise<void> {\r\n if (this.disposed) return;\r\n this.disposed = true;\r\n\r\n if (this.sessionName) {\r\n await this.killSessionSilent(this.sessionName);\r\n\r\n for (const paneId of this.panes.keys()) {\r\n getEventBus().emit(\"pane:closed\", { paneId });\r\n }\r\n this.panes.clear();\r\n\r\n logger.info({ sessionName: this.sessionName }, \"tmux session destroyed\");\r\n this.sessionName = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Get the current session name.\r\n */\r\n getSessionName(): string | undefined {\r\n return this.sessionName;\r\n }\r\n\r\n /**\r\n * Get all tracked pane info.\r\n */\r\n getPanes(): ReadonlyMap<string, ITmuxPaneInfo> {\r\n return this.panes;\r\n }\r\n\r\n // ── Private Helpers ─────────────────────────────────────────────────\r\n\r\n private async splitPane(geometry: IPaneGeometry): Promise<string> {\r\n const sessionName = this.requireSessionName();\r\n const splitFlag = geometry.splitDirection === \"horizontal\" ? \"-h\" : \"-v\";\r\n\r\n const result = await execa(TMUX_BINARY, [\r\n \"split-window\",\r\n splitFlag,\r\n \"-t\", sessionName,\r\n \"-P\",\r\n \"-F\", \"#{pane_id}\",\r\n ]);\r\n\r\n const tmuxPaneId = result.stdout.trim();\r\n logger.debug(\r\n { tmuxPaneId, direction: geometry.splitDirection },\r\n \"Pane split created\",\r\n );\r\n return tmuxPaneId;\r\n }\r\n\r\n private async getFirstPaneId(): Promise<string> {\r\n const sessionName = this.requireSessionName();\r\n const result = await execa(TMUX_BINARY, [\r\n \"list-panes\",\r\n \"-t\", sessionName,\r\n \"-F\", \"#{pane_id}\",\r\n ]);\r\n const firstLine = result.stdout.trim().split(\"\\n\")[0];\r\n return firstLine ?? \"%0\";\r\n }\r\n\r\n private async applyLayoutPreset(layout: Exclude<ILayoutConfig[\"layout\"], \"auto\">): Promise<void> {\r\n if (!this.sessionName) return;\r\n const tmuxLayout = layout === \"hub-spoke\" ? \"main-vertical\" : \"tiled\";\r\n try {\r\n await execa(TMUX_BINARY, [\r\n \"select-layout\",\r\n \"-t\", this.sessionName,\r\n tmuxLayout,\r\n ]);\r\n } catch {\r\n logger.debug({ layout: tmuxLayout }, \"Failed to apply tmux layout preset (non-fatal)\");\r\n }\r\n }\r\n\r\n private async killSessionSilent(sessionName: string): Promise<void> {\r\n try {\r\n await execa(TMUX_BINARY, [\"kill-session\", \"-t\", sessionName]);\r\n } catch {\r\n // Session may not exist — ignore\r\n }\r\n }\r\n\r\n private assertNotDisposed(): void {\r\n if (this.disposed) {\r\n throw new AgentSpawnError(\"tmux\", \"TmuxManager has been disposed\");\r\n }\r\n }\r\n\r\n private assertSession(): void {\r\n if (!this.sessionName) {\r\n throw new AgentSpawnError(\"tmux\", \"No active tmux session. Call createSession() first.\");\r\n }\r\n }\r\n\r\n private requireSessionName(): string {\r\n if (!this.sessionName) {\r\n throw new AgentSpawnError(\"tmux\", \"No active tmux session. Call createSession() first.\");\r\n }\r\n return this.sessionName;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { SessionManager } from './chunk-H2SYKIMI.js';
|
|
2
|
+
import { ApiKeyFallback } from './chunk-6GUD7QIM.js';
|
|
3
|
+
|
|
4
|
+
// src/auth/auth-status.ts
|
|
5
|
+
var LOGIN_PROVIDERS = ["claude", "codex", "gemini", "kimi"];
|
|
6
|
+
var PROVIDER_MODEL_SWITCH = {
|
|
7
|
+
claude: { provider: "anthropic", model: "claude-sonnet-4-6" },
|
|
8
|
+
codex: { provider: "openai", model: "gpt-5.2" },
|
|
9
|
+
gemini: { provider: "google", model: "gemini-2.5-pro" },
|
|
10
|
+
kimi: { provider: "kimi", model: "kimi-for-coding" }
|
|
11
|
+
};
|
|
12
|
+
function formatAuthMethodLabel(method) {
|
|
13
|
+
switch (method) {
|
|
14
|
+
case "native_login":
|
|
15
|
+
return "CLI login";
|
|
16
|
+
case "api_key":
|
|
17
|
+
return "API key";
|
|
18
|
+
case "env_variable":
|
|
19
|
+
return "env var";
|
|
20
|
+
case "credential_helper":
|
|
21
|
+
return "credential helper";
|
|
22
|
+
default:
|
|
23
|
+
return "configured";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function formatCompactLoginState(email, plan) {
|
|
27
|
+
if (email !== void 0 && plan !== void 0) {
|
|
28
|
+
return `Logged in as ${email} (${plan})`;
|
|
29
|
+
}
|
|
30
|
+
if (email !== void 0) {
|
|
31
|
+
return `Logged in as ${email}`;
|
|
32
|
+
}
|
|
33
|
+
if (plan !== void 0) {
|
|
34
|
+
return `Logged in (${plan})`;
|
|
35
|
+
}
|
|
36
|
+
return "Logged in";
|
|
37
|
+
}
|
|
38
|
+
async function getAuthStatusRecord(provider) {
|
|
39
|
+
const providerName = PROVIDER_MODEL_SWITCH[provider].provider;
|
|
40
|
+
const sessionManager = new SessionManager();
|
|
41
|
+
const fallback = new ApiKeyFallback();
|
|
42
|
+
const activeCredential = await sessionManager.getActiveCredential(providerName).catch(() => void 0);
|
|
43
|
+
const storedApiKey = await fallback.getCredential(providerName);
|
|
44
|
+
const envCredential = fallback.getFromEnvironment(providerName);
|
|
45
|
+
const launchCredential = storedApiKey ?? envCredential;
|
|
46
|
+
let email;
|
|
47
|
+
let plan;
|
|
48
|
+
if (activeCredential?.method === "native_login") {
|
|
49
|
+
const status = await sessionManager.getStatus(providerName);
|
|
50
|
+
email = status.email;
|
|
51
|
+
plan = status.plan;
|
|
52
|
+
}
|
|
53
|
+
const launchReady = activeCredential !== void 0 || launchCredential !== void 0;
|
|
54
|
+
const launchMethod = launchCredential?.method ?? activeCredential?.method;
|
|
55
|
+
return {
|
|
56
|
+
provider,
|
|
57
|
+
loggedIn: activeCredential !== void 0,
|
|
58
|
+
...activeCredential?.method !== void 0 ? { authMethod: activeCredential.method } : {},
|
|
59
|
+
...email !== void 0 ? { email } : {},
|
|
60
|
+
...plan !== void 0 ? { plan } : {},
|
|
61
|
+
launchReady,
|
|
62
|
+
...launchMethod !== void 0 ? { launchMethod } : {}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async function getAuthStatusRecords() {
|
|
66
|
+
return Promise.all(LOGIN_PROVIDERS.map(async (provider) => getAuthStatusRecord(provider)));
|
|
67
|
+
}
|
|
68
|
+
function formatDetailedAuthStatusLine(record) {
|
|
69
|
+
if (!record.loggedIn) {
|
|
70
|
+
return ` \u2717 ${record.provider} \u2014 Not logged in`;
|
|
71
|
+
}
|
|
72
|
+
const identity = record.email !== void 0 ? ` as ${record.email}${record.plan !== void 0 ? ` (${record.plan})` : ""}` : record.plan !== void 0 ? ` (${record.plan})` : "";
|
|
73
|
+
const launchStatus = record.launchReady ? `swarm-ready via ${formatAuthMethodLabel(record.launchMethod)}` : "not authenticated \u2014 run `aemeathcli auth login` or set an API key";
|
|
74
|
+
return ` \u2713 ${record.provider} \u2014 ${formatAuthMethodLabel(record.authMethod)}${identity}; ${launchStatus}`;
|
|
75
|
+
}
|
|
76
|
+
function formatCompactAuthStatusLine(record) {
|
|
77
|
+
if (!record.loggedIn) {
|
|
78
|
+
return ` \u2717 ${record.provider} \u2014 Not logged in`;
|
|
79
|
+
}
|
|
80
|
+
if (record.authMethod === "native_login" || record.authMethod === void 0) {
|
|
81
|
+
return ` \u2713 ${record.provider} \u2014 ${formatCompactLoginState(record.email, record.plan)}`;
|
|
82
|
+
}
|
|
83
|
+
return ` \u2713 ${record.provider} \u2014 Configured via ${formatAuthMethodLabel(record.authMethod)}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { LOGIN_PROVIDERS, formatCompactAuthStatusLine, formatDetailedAuthStatusLine, getAuthStatusRecord, getAuthStatusRecords };
|
|
87
|
+
//# sourceMappingURL=chunk-OCJPQFOR.js.map
|
|
88
|
+
//# sourceMappingURL=chunk-OCJPQFOR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/auth-status.ts"],"names":[],"mappings":"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","file":"chunk-OCJPQFOR.js","sourcesContent":["import { ApiKeyFallback } from \"./api-key-fallback.js\";\r\nimport { SessionManager } from \"./session-manager.js\";\r\nimport type { AuthMethod, ProviderName } from \"../types/index.js\";\r\n\r\nexport const LOGIN_PROVIDERS = [\"claude\", \"codex\", \"gemini\", \"kimi\"] as const;\r\nexport type LoginProvider = (typeof LOGIN_PROVIDERS)[number];\r\n\r\nexport interface IAuthStatusRecord {\r\n readonly provider: LoginProvider;\r\n readonly loggedIn: boolean;\r\n readonly authMethod?: AuthMethod;\r\n readonly email?: string;\r\n readonly plan?: string;\r\n readonly launchReady: boolean;\r\n readonly launchMethod?: AuthMethod;\r\n}\r\n\r\nconst PROVIDER_MODEL_SWITCH: Readonly<Record<LoginProvider, { provider: ProviderName; model: string }>> = {\r\n claude: { provider: \"anthropic\", model: \"claude-sonnet-4-6\" },\r\n codex: { provider: \"openai\", model: \"gpt-5.2\" },\r\n gemini: { provider: \"google\", model: \"gemini-2.5-pro\" },\r\n kimi: { provider: \"kimi\", model: \"kimi-for-coding\" },\r\n};\r\n\r\nfunction formatAuthMethodLabel(method?: AuthMethod): string {\r\n switch (method) {\r\n case \"native_login\":\r\n return \"CLI login\";\r\n case \"api_key\":\r\n return \"API key\";\r\n case \"env_variable\":\r\n return \"env var\";\r\n case \"credential_helper\":\r\n return \"credential helper\";\r\n default:\r\n return \"configured\";\r\n }\r\n}\r\n\r\nfunction formatCompactLoginState(email?: string, plan?: string): string {\r\n if (email !== undefined && plan !== undefined) {\r\n return `Logged in as ${email} (${plan})`;\r\n }\r\n\r\n if (email !== undefined) {\r\n return `Logged in as ${email}`;\r\n }\r\n\r\n if (plan !== undefined) {\r\n return `Logged in (${plan})`;\r\n }\r\n\r\n return \"Logged in\";\r\n}\r\n\r\nexport async function getAuthStatusRecord(provider: LoginProvider): Promise<IAuthStatusRecord> {\r\n const providerName = PROVIDER_MODEL_SWITCH[provider].provider;\r\n const sessionManager = new SessionManager();\r\n const fallback = new ApiKeyFallback();\r\n const activeCredential = await sessionManager.getActiveCredential(providerName).catch(() => undefined);\r\n const storedApiKey = await fallback.getCredential(providerName);\r\n const envCredential = fallback.getFromEnvironment(providerName);\r\n const launchCredential = storedApiKey ?? envCredential;\r\n\r\n let email: string | undefined;\r\n let plan: string | undefined;\r\n if (activeCredential?.method === \"native_login\") {\r\n const status = await sessionManager.getStatus(providerName);\r\n email = status.email;\r\n plan = status.plan;\r\n }\r\n\r\n // Swarm mode is ready if ANY credential exists — native CLI login (OAuth)\r\n // is sufficient because the native CLI adapters shell out to the provider's\r\n // own CLI (claude, codex, gemini, kimi) which already holds the session.\r\n const launchReady = activeCredential !== undefined || launchCredential !== undefined;\r\n const launchMethod = launchCredential?.method ?? activeCredential?.method;\r\n\r\n return {\r\n provider,\r\n loggedIn: activeCredential !== undefined,\r\n ...(activeCredential?.method !== undefined ? { authMethod: activeCredential.method } : {}),\r\n ...(email !== undefined ? { email } : {}),\r\n ...(plan !== undefined ? { plan } : {}),\r\n launchReady,\r\n ...(launchMethod !== undefined ? { launchMethod } : {}),\r\n };\r\n}\r\n\r\nexport async function getAuthStatusRecords(): Promise<readonly IAuthStatusRecord[]> {\r\n return Promise.all(LOGIN_PROVIDERS.map(async (provider) => getAuthStatusRecord(provider)));\r\n}\r\n\r\nexport function formatDetailedAuthStatusLine(record: IAuthStatusRecord): string {\r\n if (!record.loggedIn) {\r\n return ` ✗ ${record.provider} — Not logged in`;\r\n }\r\n\r\n const identity =\r\n record.email !== undefined\r\n ? ` as ${record.email}${record.plan !== undefined ? ` (${record.plan})` : \"\"}`\r\n : record.plan !== undefined\r\n ? ` (${record.plan})`\r\n : \"\";\r\n const launchStatus = record.launchReady\r\n ? `swarm-ready via ${formatAuthMethodLabel(record.launchMethod)}`\r\n : \"not authenticated — run `aemeathcli auth login` or set an API key\";\r\n\r\n return ` ✓ ${record.provider} — ${formatAuthMethodLabel(record.authMethod)}${identity}; ${launchStatus}`;\r\n}\r\n\r\nexport function formatCompactAuthStatusLine(record: IAuthStatusRecord): string {\r\n if (!record.loggedIn) {\r\n return ` ✗ ${record.provider} — Not logged in`;\r\n }\r\n\r\n if (record.authMethod === \"native_login\" || record.authMethod === undefined) {\r\n return ` ✓ ${record.provider} — ${formatCompactLoginState(record.email, record.plan)}`;\r\n }\r\n\r\n return ` ✓ ${record.provider} — Configured via ${formatAuthMethodLabel(record.authMethod)}`;\r\n}\r\n"]}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsonSchema } from 'ai';
|
|
2
|
+
|
|
3
|
+
// src/providers/ai-sdk-shared.ts
|
|
4
|
+
function normalizeToolInput(input) {
|
|
5
|
+
if (typeof input === "object" && input !== null && !Array.isArray(input)) {
|
|
6
|
+
return input;
|
|
7
|
+
}
|
|
8
|
+
return { value: input };
|
|
9
|
+
}
|
|
10
|
+
function buildAiSdkTools(tools) {
|
|
11
|
+
if (tools === void 0 || tools.length === 0) {
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const tool of tools) {
|
|
16
|
+
const properties = {};
|
|
17
|
+
const required = [];
|
|
18
|
+
for (const param of tool.parameters) {
|
|
19
|
+
const property = {
|
|
20
|
+
type: param.type,
|
|
21
|
+
description: param.description
|
|
22
|
+
};
|
|
23
|
+
if (param.enum !== void 0) {
|
|
24
|
+
property["enum"] = param.enum;
|
|
25
|
+
}
|
|
26
|
+
if (param.default !== void 0) {
|
|
27
|
+
property["default"] = param.default;
|
|
28
|
+
}
|
|
29
|
+
properties[param.name] = property;
|
|
30
|
+
if (param.required) {
|
|
31
|
+
required.push(param.name);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const inputSchema = {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties,
|
|
37
|
+
required
|
|
38
|
+
};
|
|
39
|
+
result[tool.name] = {
|
|
40
|
+
description: tool.description,
|
|
41
|
+
inputSchema: jsonSchema(inputSchema)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
function buildModelMessages(messages, options) {
|
|
47
|
+
const mapRole = options?.mapRole ?? ((role) => role);
|
|
48
|
+
return messages.map((message) => {
|
|
49
|
+
if (message.role === "assistant" && message.toolCalls !== void 0 && message.toolCalls.length > 0) {
|
|
50
|
+
const parts = [];
|
|
51
|
+
if (message.content.length > 0) {
|
|
52
|
+
parts.push({ type: "text", text: message.content });
|
|
53
|
+
}
|
|
54
|
+
for (const toolCall of message.toolCalls) {
|
|
55
|
+
parts.push({
|
|
56
|
+
type: "tool-call",
|
|
57
|
+
toolCallId: toolCall.id,
|
|
58
|
+
toolName: toolCall.name,
|
|
59
|
+
input: toolCall.arguments
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return { role: "assistant", content: parts };
|
|
63
|
+
}
|
|
64
|
+
if (message.role === "tool") {
|
|
65
|
+
const firstToolCall = message.toolCalls?.[0];
|
|
66
|
+
if (firstToolCall !== void 0) {
|
|
67
|
+
return {
|
|
68
|
+
role: "tool",
|
|
69
|
+
content: [{
|
|
70
|
+
type: "tool-result",
|
|
71
|
+
toolCallId: firstToolCall.id,
|
|
72
|
+
toolName: firstToolCall.name,
|
|
73
|
+
output: {
|
|
74
|
+
type: "text",
|
|
75
|
+
value: message.content
|
|
76
|
+
}
|
|
77
|
+
}]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const mappedRole = mapRole(message.role);
|
|
82
|
+
if (mappedRole === "assistant") {
|
|
83
|
+
return {
|
|
84
|
+
role: "assistant",
|
|
85
|
+
content: message.content
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (mappedRole === "system") {
|
|
89
|
+
return {
|
|
90
|
+
role: "system",
|
|
91
|
+
content: message.content
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
role: "user",
|
|
96
|
+
content: message.content
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function extractAiSdkToolCalls(toolCalls) {
|
|
101
|
+
if (toolCalls === void 0 || toolCalls.length === 0) {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
return toolCalls.map((toolCall) => ({
|
|
105
|
+
id: toolCall.toolCallId,
|
|
106
|
+
name: toolCall.toolName,
|
|
107
|
+
arguments: normalizeToolInput(toolCall.input)
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
function buildTokenUsage(modelInfo, usage) {
|
|
111
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
112
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
113
|
+
const totalTokens = usage.totalTokens ?? inputTokens + outputTokens;
|
|
114
|
+
return {
|
|
115
|
+
inputTokens,
|
|
116
|
+
outputTokens,
|
|
117
|
+
totalTokens,
|
|
118
|
+
costUsd: computeCost(modelInfo, inputTokens, outputTokens)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function mapAiSdkFinishReason(reason, aliases) {
|
|
122
|
+
const stopAliases = new Set(aliases?.stop ?? []);
|
|
123
|
+
const maxTokenAliases = new Set(aliases?.maxTokens ?? []);
|
|
124
|
+
if (reason === "stop" || stopAliases.has(reason ?? "")) {
|
|
125
|
+
return "stop";
|
|
126
|
+
}
|
|
127
|
+
if (reason === "tool-calls") {
|
|
128
|
+
return "tool_calls";
|
|
129
|
+
}
|
|
130
|
+
if (reason === "length" || maxTokenAliases.has(reason ?? "")) {
|
|
131
|
+
return "max_tokens";
|
|
132
|
+
}
|
|
133
|
+
return "stop";
|
|
134
|
+
}
|
|
135
|
+
function computeCost(modelInfo, inputTokens, outputTokens) {
|
|
136
|
+
return inputTokens / 1e6 * modelInfo.inputPricePerMToken + outputTokens / 1e6 * modelInfo.outputPricePerMToken;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export { buildAiSdkTools, buildModelMessages, buildTokenUsage, extractAiSdkToolCalls, mapAiSdkFinishReason };
|
|
140
|
+
//# sourceMappingURL=chunk-ODBY7S4X.js.map
|
|
141
|
+
//# sourceMappingURL=chunk-ODBY7S4X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/ai-sdk-shared.ts"],"names":[],"mappings":"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","file":"chunk-ODBY7S4X.js","sourcesContent":["import { jsonSchema, type ModelMessage } from \"ai\";\r\nimport type { IModelInfo, ITokenUsage } from \"../types/model.js\";\r\nimport type { IChatMessage, IToolCall, IToolDefinition } from \"../types/message.js\";\r\n\r\ntype AiSdkToolEntry = {\r\n readonly description: string;\r\n readonly inputSchema: ReturnType<typeof jsonSchema<Record<string, unknown>>>;\r\n};\r\n\r\nexport type AiSdkToolSet = Record<string, AiSdkToolEntry>;\r\n\r\ntype FinishReason = \"stop\" | \"tool_calls\" | \"max_tokens\" | \"error\";\r\n\r\ntype FinishReasonAliases = {\r\n readonly stop?: readonly string[] | undefined;\r\n readonly maxTokens?: readonly string[] | undefined;\r\n};\r\n\r\nfunction normalizeToolInput(input: unknown): Record<string, unknown> {\r\n if (typeof input === \"object\" && input !== null && !Array.isArray(input)) {\r\n return input as Record<string, unknown>;\r\n }\r\n\r\n return { value: input };\r\n}\r\n\r\nexport function buildAiSdkTools(\r\n tools: readonly IToolDefinition[] | undefined,\r\n): AiSdkToolSet | undefined {\r\n if (tools === undefined || tools.length === 0) {\r\n return undefined;\r\n }\r\n\r\n const result: AiSdkToolSet = {};\r\n\r\n for (const tool of tools) {\r\n const properties: Record<string, unknown> = {};\r\n const required: string[] = [];\r\n\r\n for (const param of tool.parameters) {\r\n const property: Record<string, unknown> = {\r\n type: param.type,\r\n description: param.description,\r\n };\r\n\r\n if (param.enum !== undefined) {\r\n property[\"enum\"] = param.enum;\r\n }\r\n if (param.default !== undefined) {\r\n property[\"default\"] = param.default;\r\n }\r\n\r\n properties[param.name] = property;\r\n\r\n if (param.required) {\r\n required.push(param.name);\r\n }\r\n }\r\n\r\n const inputSchema = {\r\n type: \"object\",\r\n properties,\r\n required,\r\n } as Parameters<typeof jsonSchema<Record<string, unknown>>>[0];\r\n\r\n result[tool.name] = {\r\n description: tool.description,\r\n inputSchema: jsonSchema<Record<string, unknown>>(inputSchema),\r\n };\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function buildModelMessages(\r\n messages: readonly IChatMessage[],\r\n options?: {\r\n readonly mapRole?: ((role: IChatMessage[\"role\"]) => ModelMessage[\"role\"]) | undefined;\r\n },\r\n): ModelMessage[] {\r\n const mapRole = options?.mapRole ?? ((role: IChatMessage[\"role\"]) => role as ModelMessage[\"role\"]);\r\n\r\n return messages.map((message) => {\r\n if (message.role === \"assistant\" && message.toolCalls !== undefined && message.toolCalls.length > 0) {\r\n const parts: Array<\r\n | { type: \"text\"; text: string }\r\n | { type: \"tool-call\"; toolCallId: string; toolName: string; input: Record<string, unknown> }\r\n > = [];\r\n\r\n if (message.content.length > 0) {\r\n parts.push({ type: \"text\", text: message.content });\r\n }\r\n\r\n for (const toolCall of message.toolCalls) {\r\n parts.push({\r\n type: \"tool-call\",\r\n toolCallId: toolCall.id,\r\n toolName: toolCall.name,\r\n input: toolCall.arguments,\r\n });\r\n }\r\n\r\n return { role: \"assistant\" as const, content: parts };\r\n }\r\n\r\n if (message.role === \"tool\") {\r\n const firstToolCall = message.toolCalls?.[0];\r\n\r\n if (firstToolCall !== undefined) {\r\n return {\r\n role: \"tool\" as const,\r\n content: [{\r\n type: \"tool-result\" as const,\r\n toolCallId: firstToolCall.id,\r\n toolName: firstToolCall.name,\r\n output: {\r\n type: \"text\" as const,\r\n value: message.content,\r\n },\r\n }],\r\n };\r\n }\r\n }\r\n\r\n const mappedRole = mapRole(message.role);\r\n\r\n if (mappedRole === \"assistant\") {\r\n return {\r\n role: \"assistant\" as const,\r\n content: message.content,\r\n };\r\n }\r\n\r\n if (mappedRole === \"system\") {\r\n return {\r\n role: \"system\" as const,\r\n content: message.content,\r\n };\r\n }\r\n\r\n return {\r\n role: \"user\" as const,\r\n content: message.content,\r\n };\r\n });\r\n}\r\n\r\nexport function extractAiSdkToolCalls(\r\n toolCalls: readonly { toolCallId: string; toolName: string; input: unknown }[] | undefined,\r\n): IToolCall[] {\r\n if (toolCalls === undefined || toolCalls.length === 0) {\r\n return [];\r\n }\r\n\r\n return toolCalls.map((toolCall) => ({\r\n id: toolCall.toolCallId,\r\n name: toolCall.toolName,\r\n arguments: normalizeToolInput(toolCall.input),\r\n }));\r\n}\r\n\r\nexport function buildTokenUsage(\r\n modelInfo: IModelInfo,\r\n usage: {\r\n readonly inputTokens: number | undefined;\r\n readonly outputTokens: number | undefined;\r\n readonly totalTokens: number | undefined;\r\n },\r\n): ITokenUsage {\r\n const inputTokens = usage.inputTokens ?? 0;\r\n const outputTokens = usage.outputTokens ?? 0;\r\n const totalTokens = usage.totalTokens ?? (inputTokens + outputTokens);\r\n\r\n return {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens,\r\n costUsd: computeCost(modelInfo, inputTokens, outputTokens),\r\n };\r\n}\r\n\r\nexport function mapAiSdkFinishReason(\r\n reason: string | undefined,\r\n aliases?: FinishReasonAliases,\r\n): FinishReason {\r\n const stopAliases = new Set(aliases?.stop ?? []);\r\n const maxTokenAliases = new Set(aliases?.maxTokens ?? []);\r\n\r\n if (reason === \"stop\" || stopAliases.has(reason ?? \"\")) {\r\n return \"stop\";\r\n }\r\n\r\n if (reason === \"tool-calls\") {\r\n return \"tool_calls\";\r\n }\r\n\r\n if (reason === \"length\" || maxTokenAliases.has(reason ?? \"\")) {\r\n return \"max_tokens\";\r\n }\r\n\r\n return \"stop\";\r\n}\r\n\r\nfunction computeCost(modelInfo: IModelInfo, inputTokens: number, outputTokens: number): number {\r\n return (\r\n (inputTokens / 1_000_000) * modelInfo.inputPricePerMToken +\r\n (outputTokens / 1_000_000) * modelInfo.outputPricePerMToken\r\n );\r\n}\r\n"]}
|