@tyhld/conductor 0.12.47 → 0.12.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/relay.js +52 -4
- package/package.json +1 -1
package/dist/relay.js
CHANGED
|
@@ -204,6 +204,12 @@ export const BUSY_GLYPHS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '
|
|
|
204
204
|
export function kindOf(cfg) {
|
|
205
205
|
return cfg.agentKind ?? 'claude';
|
|
206
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* 確定判断の件数と字数の上限(★中央 ai-kana の DISPATCH_CONTEXT_LIMITS と同じ値にすること)。
|
|
209
|
+
* 中央が守っているが、配り役でも同じ上限で守る(受け取った物が多すぎても本文を太らせない)。
|
|
210
|
+
*/
|
|
211
|
+
export const DISPATCH_DECISIONS_MAX = 10;
|
|
212
|
+
export const DISPATCH_DECISION_CHARS = 300;
|
|
207
213
|
/** 連続スキップ何回でアイドル誤判定の疑いをWARNするか(観測のみ・送信挙動は変えない)。 */
|
|
208
214
|
export const RELAY_SKIP_WARN_THRESHOLD = 6;
|
|
209
215
|
/** 初期状態を作る。 */
|
|
@@ -988,7 +994,7 @@ export function selectOrphanToRestore(orphans, currentPending) {
|
|
|
988
994
|
* 画面では送信エコーの末尾に出る=完了検出(hasDoneBelowAnchor)の境界になる。
|
|
989
995
|
* 末尾に置く理由: アンカーより上に来る指示文中の "DONE:{site}" を完了検出から確実に除外するため。
|
|
990
996
|
*/
|
|
991
|
-
export function buildSendText(body, site, anchor, kind = 'claude') {
|
|
997
|
+
export function buildSendText(body, site, anchor, kind = 'claude', context) {
|
|
992
998
|
// anchor から素の commandId を取り出す(conductor_complete に渡す引数。接頭辞無しなので新たな
|
|
993
999
|
// アンカー一致を作らず、sliceBelowAnchor の境界判定に干渉しない)。
|
|
994
1000
|
const commandId = anchor.startsWith(`${SEND_ANCHOR_PREFIX}:`)
|
|
@@ -997,12 +1003,31 @@ export function buildSendText(body, site, anchor, kind = 'claude') {
|
|
|
997
1003
|
// ★Claude の職人には「便の終え方」の1行だけを付ける(書き方の正本は鉄則の「便の終え方」の節)。
|
|
998
1004
|
// ★Codex の職人には今までどおり全文を付ける。鉄則(~/.claude/skills)は Codex には届かないため。
|
|
999
1005
|
const guide = kind === 'codex' ? fullCompletionGuide(site, commandId) : shortCompletionLine(site, commandId);
|
|
1000
|
-
const full = `${body}\n\n${guide}` +
|
|
1006
|
+
const full = `${body}\n\n${dispatchContextBlock(context)}${guide}` +
|
|
1001
1007
|
// アンカー(管理用ジョブ印)は必ず本文の最後に置く。完了検出の境界として使う。
|
|
1002
1008
|
`(管理用ジョブ印・変更不要: ${anchor})`;
|
|
1003
1009
|
// 改行(と連続改行)を空白1個に潰し、前後を整える。
|
|
1004
1010
|
return full.replace(/\r?\n+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
1005
1011
|
}
|
|
1012
|
+
/**
|
|
1013
|
+
* 本文に添える「親の便」と「この便の確定判断」の段(便 4147c519)。
|
|
1014
|
+
* ★中央の口から受け取った物だけ。どちらも無ければ空文字(本文は1文字も変わらない)。
|
|
1015
|
+
* ★ほかの便の報告全文・再開パック・過去会話は入れない(えふさん確定の「必要最小限」)。
|
|
1016
|
+
*/
|
|
1017
|
+
export function dispatchContextBlock(context) {
|
|
1018
|
+
if (!context)
|
|
1019
|
+
return '';
|
|
1020
|
+
const lines = [];
|
|
1021
|
+
if (context.parentCommandId) {
|
|
1022
|
+
lines.push(`【親の便】${context.parentCommandId}(この便は親の便の続きです)`);
|
|
1023
|
+
}
|
|
1024
|
+
const decisions = (context.decisions ?? []).filter((d) => d.trim().length > 0);
|
|
1025
|
+
if (decisions.length > 0) {
|
|
1026
|
+
lines.push('【この便の確定判断(管制から)】');
|
|
1027
|
+
decisions.forEach((d, i) => lines.push(`${i + 1}. ${d.trim()}`));
|
|
1028
|
+
}
|
|
1029
|
+
return lines.length > 0 ? `${lines.join('\n')}\n\n` : '';
|
|
1030
|
+
}
|
|
1006
1031
|
/** 鉄則(conductor-craftsman の SKILL.md)の中の、便の終え方の見出し。1行の案内はここを指す。 */
|
|
1007
1032
|
export const CRAFTSMAN_FINISH_HEADING = '## 便の終え方';
|
|
1008
1033
|
/**
|
|
@@ -1977,7 +2002,26 @@ export async function fetchCommand(cfg) {
|
|
|
1977
2002
|
log(`site=${cfg.site} 指示の形式が不正のためスキップ`);
|
|
1978
2003
|
return null;
|
|
1979
2004
|
}
|
|
1980
|
-
|
|
2005
|
+
const cmd = { id: String(first.id), body: first.body };
|
|
2006
|
+
// ★親の便・確定判断は、中央が返した物だけを形を確かめて受け取る(違う形は捨てる)。
|
|
2007
|
+
if (typeof first.parentCommandId === 'string' && first.parentCommandId.trim()) {
|
|
2008
|
+
cmd.parentCommandId = first.parentCommandId.trim();
|
|
2009
|
+
}
|
|
2010
|
+
else if (first.parentCommandId === null) {
|
|
2011
|
+
cmd.parentCommandId = null;
|
|
2012
|
+
}
|
|
2013
|
+
if (Array.isArray(first.decisions)) {
|
|
2014
|
+
cmd.decisions = first.decisions
|
|
2015
|
+
.filter((d) => typeof d === 'string' && d.trim().length > 0)
|
|
2016
|
+
.slice(0, DISPATCH_DECISIONS_MAX)
|
|
2017
|
+
.map((d) => {
|
|
2018
|
+
const t = d.trim();
|
|
2019
|
+
return [...t].length > DISPATCH_DECISION_CHARS
|
|
2020
|
+
? `${[...t].slice(0, DISPATCH_DECISION_CHARS - 1).join('')}…`
|
|
2021
|
+
: t;
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
return cmd;
|
|
1981
2025
|
}
|
|
1982
2026
|
catch (err) {
|
|
1983
2027
|
log(`site=${cfg.site} commands取得 -> 失敗: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -2808,7 +2852,11 @@ export async function relayTick(cfg, state, hooks) {
|
|
|
2808
2852
|
// 画面にエコーされたアンカー行を「今回ジョブの境界」として記録し、完了検出は
|
|
2809
2853
|
// アンカーより下=今回ジョブの出力だけを見る(churn・過去ジョブ DONE に強い)。
|
|
2810
2854
|
const anchor = buildAnchor(cmd.id);
|
|
2811
|
-
|
|
2855
|
+
// ★親の便と確定判断を添えるのは 1便1context のときだけ(便 4147c519)。既定オフの本文は1文字も変えない。
|
|
2856
|
+
const context = cfg.freshContext && kindOf(cfg) === 'claude'
|
|
2857
|
+
? { parentCommandId: cmd.parentCommandId ?? null, decisions: cmd.decisions ?? [] }
|
|
2858
|
+
: undefined;
|
|
2859
|
+
const text = buildSendText(cmd.body, cfg.site, anchor, kindOf(cfg), context);
|
|
2812
2860
|
const sendStartedAt = Date.now();
|
|
2813
2861
|
if (!sendToTmux(cfg.site, text)) {
|
|
2814
2862
|
// 送信失敗(sendToTmux は内部で例外も握って false を返す)。status は queued のまま据え置く。
|