@sideboard-ai/core 0.1.310 → 0.1.311
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/{chunk-IT6A4FZF.js → chunk-2ER7DQJP.js} +42 -2
- package/dist/{chunk-JXOW5JAW.js → chunk-7ORMOP3D.js} +42 -2
- package/dist/{chunk-VBVSJUM2.js → chunk-QC2TQMPJ.js} +31 -20
- package/dist/{chunk-AILQRQ26.js → chunk-ZW7RSQHY.js} +25 -9
- package/dist/{conductor-AMZ5SKG2.js → conductor-CTWR6NH4.js} +1 -1
- package/dist/{conductor-OFXA5BST.js → conductor-YOBSYPLT.js} +1 -1
- package/dist/index.cjs +250 -186
- package/dist/index.d.cts +42 -10
- package/dist/index.d.ts +42 -10
- package/dist/index.js +28 -14
- package/dist/mcp/run-stdio.cjs +64 -8
- package/dist/mcp/run-stdio.js +2 -2
- package/dist/{orchestrator-XFE3U3RP.js → orchestrator-2CCFGYAA.js} +2 -2
- package/dist/{orchestrator-7374OI7T.js → orchestrator-3W5S6TNP.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6720,6 +6720,191 @@ var init_message_parts = __esm({
|
|
|
6720
6720
|
}
|
|
6721
6721
|
});
|
|
6722
6722
|
|
|
6723
|
+
// src/plan/ask-user.ts
|
|
6724
|
+
function planQuestionsSignature(questions2) {
|
|
6725
|
+
return questions2.map((q) => {
|
|
6726
|
+
const opts = q.options.map((o) => o.label).join("");
|
|
6727
|
+
return `${q.question}${opts}`;
|
|
6728
|
+
}).join("");
|
|
6729
|
+
}
|
|
6730
|
+
function asRecord2(v) {
|
|
6731
|
+
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
6732
|
+
}
|
|
6733
|
+
function parseOptions(raw) {
|
|
6734
|
+
if (!Array.isArray(raw)) return [];
|
|
6735
|
+
const out = [];
|
|
6736
|
+
for (const item of raw) {
|
|
6737
|
+
if (typeof item === "string" && item.trim()) {
|
|
6738
|
+
out.push({ label: item.trim() });
|
|
6739
|
+
continue;
|
|
6740
|
+
}
|
|
6741
|
+
const o = asRecord2(item);
|
|
6742
|
+
if (!o) continue;
|
|
6743
|
+
const label = typeof o.label === "string" ? o.label.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.title === "string" ? o.title.trim() : "";
|
|
6744
|
+
if (!label) continue;
|
|
6745
|
+
const description = typeof o.description === "string" && o.description.trim() ? o.description.trim() : void 0;
|
|
6746
|
+
out.push({ label, description });
|
|
6747
|
+
}
|
|
6748
|
+
return out;
|
|
6749
|
+
}
|
|
6750
|
+
function parseOneQuestion(raw) {
|
|
6751
|
+
const o = asRecord2(raw);
|
|
6752
|
+
if (!o) return null;
|
|
6753
|
+
const question = typeof o.question === "string" ? o.question.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.prompt === "string" ? o.prompt.trim() : "";
|
|
6754
|
+
if (!question) return null;
|
|
6755
|
+
const options = parseOptions(o.options);
|
|
6756
|
+
if (options.length < 1) return null;
|
|
6757
|
+
const header = typeof o.header === "string" && o.header.trim() ? o.header.trim() : void 0;
|
|
6758
|
+
const multiSelect = Boolean(o.multiSelect ?? o.multi_select);
|
|
6759
|
+
return { question, header, multiSelect, options };
|
|
6760
|
+
}
|
|
6761
|
+
function parsePlanQuestionsInput(input) {
|
|
6762
|
+
const root = asRecord2(input);
|
|
6763
|
+
if (!root) return [];
|
|
6764
|
+
const list = Array.isArray(root.questions) ? root.questions : Array.isArray(root.question) ? root.question : root.question || root.prompt ? [root] : [];
|
|
6765
|
+
const out = [];
|
|
6766
|
+
for (const item of list) {
|
|
6767
|
+
const q = parseOneQuestion(item);
|
|
6768
|
+
if (q) out.push(q);
|
|
6769
|
+
}
|
|
6770
|
+
return out;
|
|
6771
|
+
}
|
|
6772
|
+
function isAskUserToolName(name) {
|
|
6773
|
+
if (!name) return false;
|
|
6774
|
+
const base = name.replace(/^mcp__sideboard__/i, "");
|
|
6775
|
+
return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
|
|
6776
|
+
}
|
|
6777
|
+
function lastTopLevelToolIsAskUser(parts) {
|
|
6778
|
+
if (!parts?.length) return false;
|
|
6779
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
6780
|
+
const part = parts[i];
|
|
6781
|
+
if (part.type === "tool" && !part.parentId) {
|
|
6782
|
+
return isAskUserToolName(part.name);
|
|
6783
|
+
}
|
|
6784
|
+
}
|
|
6785
|
+
return false;
|
|
6786
|
+
}
|
|
6787
|
+
function hasTopLevelTool(parts) {
|
|
6788
|
+
return Boolean(parts?.some((part) => part.type === "tool" && !part.parentId));
|
|
6789
|
+
}
|
|
6790
|
+
function questionsFromToolPart(part) {
|
|
6791
|
+
const fromInput = parsePlanQuestionsInput(part.input);
|
|
6792
|
+
if (fromInput.length) return fromInput;
|
|
6793
|
+
const raw = part.result?.trim();
|
|
6794
|
+
if (!raw || !raw.startsWith("{")) return [];
|
|
6795
|
+
try {
|
|
6796
|
+
return parsePlanQuestionsInput(JSON.parse(raw));
|
|
6797
|
+
} catch {
|
|
6798
|
+
return [];
|
|
6799
|
+
}
|
|
6800
|
+
}
|
|
6801
|
+
function extractPendingPlanQuestions(parts) {
|
|
6802
|
+
if (!parts?.length) return null;
|
|
6803
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
6804
|
+
const p = parts[i];
|
|
6805
|
+
if (p.type !== "tool" || !isAskUserToolName(p.name)) continue;
|
|
6806
|
+
const questions2 = questionsFromToolPart(p);
|
|
6807
|
+
if (!questions2.length) continue;
|
|
6808
|
+
return {
|
|
6809
|
+
id: p.id || `ask-${i}`,
|
|
6810
|
+
signature: planQuestionsSignature(questions2),
|
|
6811
|
+
questions: questions2,
|
|
6812
|
+
source: p.name || "ask_user"
|
|
6813
|
+
};
|
|
6814
|
+
}
|
|
6815
|
+
return null;
|
|
6816
|
+
}
|
|
6817
|
+
function pendingFromAskBlock(block, dismissedQuestionSignature) {
|
|
6818
|
+
if (!block || block.source !== "ask_user" || !block.questions?.length) return null;
|
|
6819
|
+
const dismissed = dismissedQuestionSignature?.trim();
|
|
6820
|
+
if (dismissed && (!block.questionSignature || block.questionSignature === dismissed)) {
|
|
6821
|
+
return null;
|
|
6822
|
+
}
|
|
6823
|
+
const signature = block.questionSignature?.trim() || planQuestionsSignature(block.questions);
|
|
6824
|
+
return {
|
|
6825
|
+
id: `ask-block:${signature}`,
|
|
6826
|
+
signature,
|
|
6827
|
+
questions: block.questions,
|
|
6828
|
+
source: "ask_user"
|
|
6829
|
+
};
|
|
6830
|
+
}
|
|
6831
|
+
function askBlockStillWaiting(block, messages) {
|
|
6832
|
+
if (!messages?.length) return Boolean(block?.at);
|
|
6833
|
+
const askedAt = block?.at;
|
|
6834
|
+
if (!askedAt) return false;
|
|
6835
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
6836
|
+
const message = messages[i];
|
|
6837
|
+
if (message.role !== "user" || message.origin === "continue") continue;
|
|
6838
|
+
if (!message.ts) return true;
|
|
6839
|
+
return askedAt > message.ts;
|
|
6840
|
+
}
|
|
6841
|
+
return true;
|
|
6842
|
+
}
|
|
6843
|
+
function latestPendingPlanQuestions(input) {
|
|
6844
|
+
if (input.userReplied) return null;
|
|
6845
|
+
const fromBlock = () => pendingFromAskBlock(input.agentBlock, input.dismissedQuestionSignature);
|
|
6846
|
+
if (lastTopLevelToolIsAskUser(input.liveParts)) {
|
|
6847
|
+
return extractPendingPlanQuestions(input.liveParts) ?? fromBlock();
|
|
6848
|
+
}
|
|
6849
|
+
const last = input.messages[input.messages.length - 1];
|
|
6850
|
+
if (last?.role === "agent" && lastTopLevelToolIsAskUser(last.parts)) {
|
|
6851
|
+
return extractPendingPlanQuestions(last.parts) ?? fromBlock();
|
|
6852
|
+
}
|
|
6853
|
+
if (hasTopLevelTool(input.liveParts) || last?.role === "agent" && hasTopLevelTool(last.parts)) {
|
|
6854
|
+
return null;
|
|
6855
|
+
}
|
|
6856
|
+
if (input.status === "running" || input.status === "queued") return null;
|
|
6857
|
+
const stamped = fromBlock();
|
|
6858
|
+
if (stamped && askBlockStillWaiting(input.agentBlock, input.messages)) {
|
|
6859
|
+
return stamped;
|
|
6860
|
+
}
|
|
6861
|
+
return null;
|
|
6862
|
+
}
|
|
6863
|
+
function isPlanQuestionAnswersMessage(text7) {
|
|
6864
|
+
return text7.startsWith(PLAN_QUESTION_ANSWERS_PREFIX);
|
|
6865
|
+
}
|
|
6866
|
+
function formatPlanQuestionAnswers(questions2, answers) {
|
|
6867
|
+
const lines = [PLAN_QUESTION_ANSWERS_PREFIX, ""];
|
|
6868
|
+
for (let i = 0; i < questions2.length; i++) {
|
|
6869
|
+
const q = questions2[i];
|
|
6870
|
+
const a = answers.find((x) => x.questionIndex === i);
|
|
6871
|
+
const header = q.header ? `**${q.header}** \u2014 ` : "";
|
|
6872
|
+
const parts = [];
|
|
6873
|
+
if (a?.selected.length) parts.push(a.selected.join(", "));
|
|
6874
|
+
if (a?.other?.trim()) parts.push(a.other.trim());
|
|
6875
|
+
const body = parts.length ? parts.join(" \xB7 ") : "(no answer)";
|
|
6876
|
+
lines.push(`${i + 1}. ${header}${q.question} `);
|
|
6877
|
+
lines.push(` \u2192 ${body}`);
|
|
6878
|
+
}
|
|
6879
|
+
return lines.join("\n");
|
|
6880
|
+
}
|
|
6881
|
+
function formatPlanQuestionsForChat(questions2) {
|
|
6882
|
+
const lines = ["### Questions for you", ""];
|
|
6883
|
+
for (let i = 0; i < questions2.length; i++) {
|
|
6884
|
+
const q = questions2[i];
|
|
6885
|
+
const header = q.header ? `**${q.header}** \u2014 ` : "";
|
|
6886
|
+
lines.push(`${i + 1}. ${header}${q.question}`);
|
|
6887
|
+
for (let oi = 0; oi < q.options.length; oi++) {
|
|
6888
|
+
const opt = q.options[oi];
|
|
6889
|
+
const desc = opt.description?.trim();
|
|
6890
|
+
lines.push(
|
|
6891
|
+
desc ? ` - **${opt.label}** \u2014 ${desc}` : ` - **${opt.label}**`
|
|
6892
|
+
);
|
|
6893
|
+
}
|
|
6894
|
+
lines.push("");
|
|
6895
|
+
}
|
|
6896
|
+
lines.push("_Answer in the composer below._");
|
|
6897
|
+
return lines.join("\n").trimEnd();
|
|
6898
|
+
}
|
|
6899
|
+
var ASK_USER_TOOL_RE, PLAN_QUESTION_ANSWERS_PREFIX;
|
|
6900
|
+
var init_ask_user = __esm({
|
|
6901
|
+
"src/plan/ask-user.ts"() {
|
|
6902
|
+
"use strict";
|
|
6903
|
+
ASK_USER_TOOL_RE = /^(AskUserQuestion|ask_user|mcp__sideboard__ask_user)$/i;
|
|
6904
|
+
PLAN_QUESTION_ANSWERS_PREFIX = "Answers to your questions:";
|
|
6905
|
+
}
|
|
6906
|
+
});
|
|
6907
|
+
|
|
6723
6908
|
// src/board/agent-block-view.ts
|
|
6724
6909
|
function worktreeBoardStatus(group) {
|
|
6725
6910
|
const order = ["running", "queued", "error", "broken"];
|
|
@@ -6742,6 +6927,11 @@ function visibleAgentBlock(thread) {
|
|
|
6742
6927
|
const block = thread.agentBlock;
|
|
6743
6928
|
if (!block?.reason?.trim()) return null;
|
|
6744
6929
|
if (isDismissedAskUserBlock(block, thread.dismissedQuestionSignature)) return null;
|
|
6930
|
+
if (block.source === "ask_user") {
|
|
6931
|
+
const inFlight = thread.status === "running" || thread.status === "queued";
|
|
6932
|
+
if (inFlight && !block.onScreen) return null;
|
|
6933
|
+
if (!askBlockStillWaiting(block, thread.messages)) return null;
|
|
6934
|
+
}
|
|
6745
6935
|
return block;
|
|
6746
6936
|
}
|
|
6747
6937
|
function worktreeAgentBlock(group) {
|
|
@@ -6777,6 +6967,7 @@ function threadCardBlockFields(group) {
|
|
|
6777
6967
|
var init_agent_block_view = __esm({
|
|
6778
6968
|
"src/board/agent-block-view.ts"() {
|
|
6779
6969
|
"use strict";
|
|
6970
|
+
init_ask_user();
|
|
6780
6971
|
}
|
|
6781
6972
|
});
|
|
6782
6973
|
|
|
@@ -8309,175 +8500,6 @@ var init_injected_notices = __esm({
|
|
|
8309
8500
|
}
|
|
8310
8501
|
});
|
|
8311
8502
|
|
|
8312
|
-
// src/plan/ask-user.ts
|
|
8313
|
-
function planQuestionsSignature(questions2) {
|
|
8314
|
-
return questions2.map((q) => {
|
|
8315
|
-
const opts = q.options.map((o) => o.label).join("");
|
|
8316
|
-
return `${q.question}${opts}`;
|
|
8317
|
-
}).join("");
|
|
8318
|
-
}
|
|
8319
|
-
function asRecord2(v) {
|
|
8320
|
-
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
8321
|
-
}
|
|
8322
|
-
function parseOptions(raw) {
|
|
8323
|
-
if (!Array.isArray(raw)) return [];
|
|
8324
|
-
const out = [];
|
|
8325
|
-
for (const item of raw) {
|
|
8326
|
-
if (typeof item === "string" && item.trim()) {
|
|
8327
|
-
out.push({ label: item.trim() });
|
|
8328
|
-
continue;
|
|
8329
|
-
}
|
|
8330
|
-
const o = asRecord2(item);
|
|
8331
|
-
if (!o) continue;
|
|
8332
|
-
const label = typeof o.label === "string" ? o.label.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.title === "string" ? o.title.trim() : "";
|
|
8333
|
-
if (!label) continue;
|
|
8334
|
-
const description = typeof o.description === "string" && o.description.trim() ? o.description.trim() : void 0;
|
|
8335
|
-
out.push({ label, description });
|
|
8336
|
-
}
|
|
8337
|
-
return out;
|
|
8338
|
-
}
|
|
8339
|
-
function parseOneQuestion(raw) {
|
|
8340
|
-
const o = asRecord2(raw);
|
|
8341
|
-
if (!o) return null;
|
|
8342
|
-
const question = typeof o.question === "string" ? o.question.trim() : typeof o.text === "string" ? o.text.trim() : typeof o.prompt === "string" ? o.prompt.trim() : "";
|
|
8343
|
-
if (!question) return null;
|
|
8344
|
-
const options = parseOptions(o.options);
|
|
8345
|
-
if (options.length < 1) return null;
|
|
8346
|
-
const header = typeof o.header === "string" && o.header.trim() ? o.header.trim() : void 0;
|
|
8347
|
-
const multiSelect = Boolean(o.multiSelect ?? o.multi_select);
|
|
8348
|
-
return { question, header, multiSelect, options };
|
|
8349
|
-
}
|
|
8350
|
-
function parsePlanQuestionsInput(input) {
|
|
8351
|
-
const root = asRecord2(input);
|
|
8352
|
-
if (!root) return [];
|
|
8353
|
-
const list = Array.isArray(root.questions) ? root.questions : Array.isArray(root.question) ? root.question : root.question || root.prompt ? [root] : [];
|
|
8354
|
-
const out = [];
|
|
8355
|
-
for (const item of list) {
|
|
8356
|
-
const q = parseOneQuestion(item);
|
|
8357
|
-
if (q) out.push(q);
|
|
8358
|
-
}
|
|
8359
|
-
return out;
|
|
8360
|
-
}
|
|
8361
|
-
function isAskUserToolName(name) {
|
|
8362
|
-
if (!name) return false;
|
|
8363
|
-
const base = name.replace(/^mcp__sideboard__/i, "");
|
|
8364
|
-
return ASK_USER_TOOL_RE.test(name) || /^ask_user$/i.test(base);
|
|
8365
|
-
}
|
|
8366
|
-
function questionsFromToolPart(part) {
|
|
8367
|
-
const fromInput = parsePlanQuestionsInput(part.input);
|
|
8368
|
-
if (fromInput.length) return fromInput;
|
|
8369
|
-
const raw = part.result?.trim();
|
|
8370
|
-
if (!raw || !raw.startsWith("{")) return [];
|
|
8371
|
-
try {
|
|
8372
|
-
return parsePlanQuestionsInput(JSON.parse(raw));
|
|
8373
|
-
} catch {
|
|
8374
|
-
return [];
|
|
8375
|
-
}
|
|
8376
|
-
}
|
|
8377
|
-
function extractPendingPlanQuestions(parts) {
|
|
8378
|
-
if (!parts?.length) return null;
|
|
8379
|
-
for (let i = parts.length - 1; i >= 0; i--) {
|
|
8380
|
-
const p = parts[i];
|
|
8381
|
-
if (p.type !== "tool" || !isAskUserToolName(p.name)) continue;
|
|
8382
|
-
const questions2 = questionsFromToolPart(p);
|
|
8383
|
-
if (!questions2.length) continue;
|
|
8384
|
-
return {
|
|
8385
|
-
id: p.id || `ask-${i}`,
|
|
8386
|
-
signature: planQuestionsSignature(questions2),
|
|
8387
|
-
questions: questions2,
|
|
8388
|
-
source: p.name || "ask_user"
|
|
8389
|
-
};
|
|
8390
|
-
}
|
|
8391
|
-
return null;
|
|
8392
|
-
}
|
|
8393
|
-
function pendingFromAskBlock(block, dismissedQuestionSignature) {
|
|
8394
|
-
if (!block || block.source !== "ask_user" || !block.questions?.length) return null;
|
|
8395
|
-
const dismissed = dismissedQuestionSignature?.trim();
|
|
8396
|
-
if (dismissed && (!block.questionSignature || block.questionSignature === dismissed)) {
|
|
8397
|
-
return null;
|
|
8398
|
-
}
|
|
8399
|
-
const signature = block.questionSignature?.trim() || planQuestionsSignature(block.questions);
|
|
8400
|
-
return {
|
|
8401
|
-
id: `ask-block:${signature}`,
|
|
8402
|
-
signature,
|
|
8403
|
-
questions: block.questions,
|
|
8404
|
-
source: "ask_user"
|
|
8405
|
-
};
|
|
8406
|
-
}
|
|
8407
|
-
function askBlockStillWaiting(block, messages) {
|
|
8408
|
-
const askedAt = block?.at;
|
|
8409
|
-
if (!askedAt) return false;
|
|
8410
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8411
|
-
const message = messages[i];
|
|
8412
|
-
if (message.role !== "user" || message.origin === "continue") continue;
|
|
8413
|
-
if (!message.ts) return true;
|
|
8414
|
-
return askedAt > message.ts;
|
|
8415
|
-
}
|
|
8416
|
-
return true;
|
|
8417
|
-
}
|
|
8418
|
-
function latestPendingPlanQuestions(input) {
|
|
8419
|
-
if (input.userReplied) return null;
|
|
8420
|
-
const fromLive = extractPendingPlanQuestions(input.liveParts);
|
|
8421
|
-
if (fromLive) return fromLive;
|
|
8422
|
-
const last = input.messages[input.messages.length - 1];
|
|
8423
|
-
if (last?.role === "agent") {
|
|
8424
|
-
const fromParts = extractPendingPlanQuestions(last.parts);
|
|
8425
|
-
if (fromParts) return fromParts;
|
|
8426
|
-
}
|
|
8427
|
-
const fromBlock = pendingFromAskBlock(
|
|
8428
|
-
input.agentBlock,
|
|
8429
|
-
input.dismissedQuestionSignature
|
|
8430
|
-
);
|
|
8431
|
-
if (fromBlock && askBlockStillWaiting(input.agentBlock, input.messages)) {
|
|
8432
|
-
return fromBlock;
|
|
8433
|
-
}
|
|
8434
|
-
return null;
|
|
8435
|
-
}
|
|
8436
|
-
function isPlanQuestionAnswersMessage(text7) {
|
|
8437
|
-
return text7.startsWith(PLAN_QUESTION_ANSWERS_PREFIX);
|
|
8438
|
-
}
|
|
8439
|
-
function formatPlanQuestionAnswers(questions2, answers) {
|
|
8440
|
-
const lines = [PLAN_QUESTION_ANSWERS_PREFIX, ""];
|
|
8441
|
-
for (let i = 0; i < questions2.length; i++) {
|
|
8442
|
-
const q = questions2[i];
|
|
8443
|
-
const a = answers.find((x) => x.questionIndex === i);
|
|
8444
|
-
const header = q.header ? `**${q.header}** \u2014 ` : "";
|
|
8445
|
-
const parts = [];
|
|
8446
|
-
if (a?.selected.length) parts.push(a.selected.join(", "));
|
|
8447
|
-
if (a?.other?.trim()) parts.push(a.other.trim());
|
|
8448
|
-
const body = parts.length ? parts.join(" \xB7 ") : "(no answer)";
|
|
8449
|
-
lines.push(`${i + 1}. ${header}${q.question} `);
|
|
8450
|
-
lines.push(` \u2192 ${body}`);
|
|
8451
|
-
}
|
|
8452
|
-
return lines.join("\n");
|
|
8453
|
-
}
|
|
8454
|
-
function formatPlanQuestionsForChat(questions2) {
|
|
8455
|
-
const lines = ["### Questions for you", ""];
|
|
8456
|
-
for (let i = 0; i < questions2.length; i++) {
|
|
8457
|
-
const q = questions2[i];
|
|
8458
|
-
const header = q.header ? `**${q.header}** \u2014 ` : "";
|
|
8459
|
-
lines.push(`${i + 1}. ${header}${q.question}`);
|
|
8460
|
-
for (let oi = 0; oi < q.options.length; oi++) {
|
|
8461
|
-
const opt = q.options[oi];
|
|
8462
|
-
const desc = opt.description?.trim();
|
|
8463
|
-
lines.push(
|
|
8464
|
-
desc ? ` - **${opt.label}** \u2014 ${desc}` : ` - **${opt.label}**`
|
|
8465
|
-
);
|
|
8466
|
-
}
|
|
8467
|
-
lines.push("");
|
|
8468
|
-
}
|
|
8469
|
-
lines.push("_Answer in the composer below._");
|
|
8470
|
-
return lines.join("\n").trimEnd();
|
|
8471
|
-
}
|
|
8472
|
-
var ASK_USER_TOOL_RE, PLAN_QUESTION_ANSWERS_PREFIX;
|
|
8473
|
-
var init_ask_user = __esm({
|
|
8474
|
-
"src/plan/ask-user.ts"() {
|
|
8475
|
-
"use strict";
|
|
8476
|
-
ASK_USER_TOOL_RE = /^(AskUserQuestion|ask_user|mcp__sideboard__ask_user)$/i;
|
|
8477
|
-
PLAN_QUESTION_ANSWERS_PREFIX = "Answers to your questions:";
|
|
8478
|
-
}
|
|
8479
|
-
});
|
|
8480
|
-
|
|
8481
8503
|
// src/orchestrator/task-state.ts
|
|
8482
8504
|
function isTerminalTaskState(state) {
|
|
8483
8505
|
return state !== "submitted" && state !== "working";
|
|
@@ -8489,14 +8511,7 @@ function needsCoordinatorAction(state) {
|
|
|
8489
8511
|
return isIncompleteTaskState(state) || state === "input-required";
|
|
8490
8512
|
}
|
|
8491
8513
|
function endedOnAskUser(parts) {
|
|
8492
|
-
|
|
8493
|
-
for (let i = parts.length - 1; i >= 0; i--) {
|
|
8494
|
-
const p = parts[i];
|
|
8495
|
-
if (p.type === "tool" && !p.parentId) {
|
|
8496
|
-
return isAskUserToolName(p.name);
|
|
8497
|
-
}
|
|
8498
|
-
}
|
|
8499
|
-
return false;
|
|
8514
|
+
return lastTopLevelToolIsAskUser(parts);
|
|
8500
8515
|
}
|
|
8501
8516
|
function deriveTaskState(input) {
|
|
8502
8517
|
if (input.stillRunning) {
|
|
@@ -22259,6 +22274,7 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
|
|
|
22259
22274
|
const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
|
|
22260
22275
|
return {
|
|
22261
22276
|
...makeAgentBlock("ask_user", reason, at),
|
|
22277
|
+
onScreen: true,
|
|
22262
22278
|
...pending ? { questionSignature: pending.signature, questions: pending.questions } : {}
|
|
22263
22279
|
};
|
|
22264
22280
|
}
|
|
@@ -22316,6 +22332,38 @@ function dismissAskUserQuestion(threadId, signature) {
|
|
|
22316
22332
|
...clearBlock ? { agentBlock: null } : {}
|
|
22317
22333
|
});
|
|
22318
22334
|
}
|
|
22335
|
+
function askBlocksEqual(a, b) {
|
|
22336
|
+
if (a === b) return true;
|
|
22337
|
+
if (!a || !b) return false;
|
|
22338
|
+
return a.source === b.source && a.reason === b.reason && a.at === b.at && a.onScreen === b.onScreen && a.questionSignature === b.questionSignature;
|
|
22339
|
+
}
|
|
22340
|
+
function askBlockAfterLiveParts(existing, parts) {
|
|
22341
|
+
const last = lastTopLevelTool(parts);
|
|
22342
|
+
if (last?.type === "tool" && isAskUserToolName(last.name)) {
|
|
22343
|
+
if (existing?.source === "ask_user" && existing.onScreen) return existing;
|
|
22344
|
+
const pending = extractPendingPlanQuestions(parts);
|
|
22345
|
+
const questions2 = pending?.questions ?? existing?.questions;
|
|
22346
|
+
if (!questions2?.length) {
|
|
22347
|
+
return existing?.source === "ask_user" ? { ...existing, onScreen: true } : existing ?? null;
|
|
22348
|
+
}
|
|
22349
|
+
const at = existing?.source === "ask_user" ? existing.at : void 0;
|
|
22350
|
+
return {
|
|
22351
|
+
...makeAgentBlock("ask_user", formatAskUserNotifyMessage(questions2), at),
|
|
22352
|
+
onScreen: true,
|
|
22353
|
+
questionSignature: pending?.signature ?? existing?.questionSignature,
|
|
22354
|
+
questions: questions2
|
|
22355
|
+
};
|
|
22356
|
+
}
|
|
22357
|
+
if (last && existing?.source === "ask_user") return null;
|
|
22358
|
+
return existing ?? null;
|
|
22359
|
+
}
|
|
22360
|
+
function syncAskUserBlockFromLive(threadId, parts) {
|
|
22361
|
+
const thread = readThread(threadId);
|
|
22362
|
+
if (!thread || thread.status === "archived") return;
|
|
22363
|
+
const next = askBlockAfterLiveParts(thread.agentBlock, parts);
|
|
22364
|
+
if (askBlocksEqual(thread.agentBlock, next)) return;
|
|
22365
|
+
updateThread(threadId, { agentBlock: next });
|
|
22366
|
+
}
|
|
22319
22367
|
function writeAgentBlock(threadId, block) {
|
|
22320
22368
|
const thread = readThread(threadId);
|
|
22321
22369
|
if (!thread || thread.status === "archived") return;
|
|
@@ -25168,6 +25216,7 @@ function noteTurnLiveEvent(threadId, event) {
|
|
|
25168
25216
|
const prev = buffers.get(threadId) ?? { parts: [], timer: null };
|
|
25169
25217
|
prev.parts = trimParts(applyAgentEvent(prev.parts, event));
|
|
25170
25218
|
buffers.set(threadId, prev);
|
|
25219
|
+
syncAskUserBlockFromLive(threadId, prev.parts);
|
|
25171
25220
|
if (event.type === "exit") {
|
|
25172
25221
|
flush(threadId);
|
|
25173
25222
|
const cur = buffers.get(threadId);
|
|
@@ -25224,6 +25273,7 @@ var init_turn_live = __esm({
|
|
|
25224
25273
|
import_node_fs57 = require("fs");
|
|
25225
25274
|
init_message_parts();
|
|
25226
25275
|
init_paths();
|
|
25276
|
+
init_agent_block();
|
|
25227
25277
|
buffers = /* @__PURE__ */ new Map();
|
|
25228
25278
|
FLUSH_MS = 800;
|
|
25229
25279
|
MAX_PARTS = 80;
|
|
@@ -32117,6 +32167,7 @@ __export(index_exports, {
|
|
|
32117
32167
|
archiveRemovedWorkspaceChats: () => archiveRemovedWorkspaceChats,
|
|
32118
32168
|
archivesWithRemovedWorkspace: () => archivesWithRemovedWorkspace,
|
|
32119
32169
|
armSchedules: () => armSchedules,
|
|
32170
|
+
askBlockStillWaiting: () => askBlockStillWaiting,
|
|
32120
32171
|
assertAbleTimeCredential: () => assertAbleTimeCredential,
|
|
32121
32172
|
assertAbleTimeMcpCredential: () => assertAbleTimeMcpCredential,
|
|
32122
32173
|
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
@@ -32557,6 +32608,7 @@ __export(index_exports, {
|
|
|
32557
32608
|
lastAgentReply: () => lastAgentReply,
|
|
32558
32609
|
lastAssistantMessageText: () => lastAssistantMessageText,
|
|
32559
32610
|
lastRequestOccupancy: () => lastRequestOccupancy,
|
|
32611
|
+
lastTopLevelToolIsAskUser: () => lastTopLevelToolIsAskUser,
|
|
32560
32612
|
latestPendingPlanQuestions: () => latestPendingPlanQuestions,
|
|
32561
32613
|
linearAuthorizationHeader: () => linearAuthorizationHeader,
|
|
32562
32614
|
linearCycleIsActive: () => linearCycleIsActive,
|
|
@@ -34828,6 +34880,7 @@ function parsePhoneCreate(value) {
|
|
|
34828
34880
|
}
|
|
34829
34881
|
function summarize(thread) {
|
|
34830
34882
|
const pr = phonePrPill(thread);
|
|
34883
|
+
const block = visibleAgentBlock(thread);
|
|
34831
34884
|
return {
|
|
34832
34885
|
id: thread.id,
|
|
34833
34886
|
title: thread.title?.trim() || "Untitled",
|
|
@@ -34838,14 +34891,12 @@ function summarize(thread) {
|
|
|
34838
34891
|
...pr?.url ? { prUrl: pr.url } : {},
|
|
34839
34892
|
...pr?.number ? { prNumber: pr.number } : {},
|
|
34840
34893
|
...pr?.status ? { prStatus: pr.status } : {},
|
|
34841
|
-
...
|
|
34894
|
+
...block ? { needsYou: true, blockedReason: block.reason } : {}
|
|
34842
34895
|
};
|
|
34843
34896
|
}
|
|
34844
34897
|
function previewOf2(thread) {
|
|
34845
|
-
const
|
|
34846
|
-
|
|
34847
|
-
if (!last) return "";
|
|
34848
|
-
return clip(last.text.replace(/\s+/g, " ").trim(), PREVIEW_LIMIT2);
|
|
34898
|
+
const last = listPhoneMessages(thread).at(-1);
|
|
34899
|
+
return last ? clip(last.text.replace(/\s+/g, " ").trim(), PREVIEW_LIMIT2) : "";
|
|
34849
34900
|
}
|
|
34850
34901
|
function repoName2(repoPath) {
|
|
34851
34902
|
return repoPath.replace(/\/$/, "").split("/").pop() || repoPath;
|
|
@@ -35201,7 +35252,8 @@ function emitChatTurn(opts, chatId, threadId) {
|
|
|
35201
35252
|
const pending = latestPendingPlanQuestions({
|
|
35202
35253
|
messages: thread.messages,
|
|
35203
35254
|
agentBlock: thread.agentBlock,
|
|
35204
|
-
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
35255
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature,
|
|
35256
|
+
status: thread.status
|
|
35205
35257
|
});
|
|
35206
35258
|
if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
|
|
35207
35259
|
emitControl(opts, {
|
|
@@ -35572,7 +35624,8 @@ function republishPendingAsk(opts, chatId) {
|
|
|
35572
35624
|
const pending = latestPendingPlanQuestions({
|
|
35573
35625
|
messages: thread.messages,
|
|
35574
35626
|
agentBlock: thread.agentBlock,
|
|
35575
|
-
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
35627
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature,
|
|
35628
|
+
status: thread.status
|
|
35576
35629
|
});
|
|
35577
35630
|
if (!pending) return;
|
|
35578
35631
|
emitControl(opts, {
|
|
@@ -37835,7 +37888,8 @@ function runCoordinatorPrompt(opts, body, generation) {
|
|
|
37835
37888
|
const pending = latestPendingPlanQuestions({
|
|
37836
37889
|
messages: thread.messages,
|
|
37837
37890
|
agentBlock: thread.agentBlock,
|
|
37838
|
-
dismissedQuestionSignature: thread.dismissedQuestionSignature
|
|
37891
|
+
dismissedQuestionSignature: thread.dismissedQuestionSignature,
|
|
37892
|
+
status: thread.status
|
|
37839
37893
|
});
|
|
37840
37894
|
if (pending && result.taskState !== "failed" && result.taskState !== "canceled" && (result.taskState === "input-required" || thread.agentBlock?.source === "ask_user")) {
|
|
37841
37895
|
opts.onOutbound({
|
|
@@ -38284,7 +38338,15 @@ init_paths();
|
|
|
38284
38338
|
init_thread_store();
|
|
38285
38339
|
var PHONE_BOARD_SYNC_MS = 300;
|
|
38286
38340
|
function chatKey(row2) {
|
|
38287
|
-
return [
|
|
38341
|
+
return [
|
|
38342
|
+
row2.id,
|
|
38343
|
+
row2.title,
|
|
38344
|
+
row2.status,
|
|
38345
|
+
row2.agent,
|
|
38346
|
+
row2.preview,
|
|
38347
|
+
row2.needsYou ? "1" : "0",
|
|
38348
|
+
row2.blockedReason ?? ""
|
|
38349
|
+
].join(" ");
|
|
38288
38350
|
}
|
|
38289
38351
|
function phoneBoardKey(sidebar) {
|
|
38290
38352
|
const orchestration = sidebar.orchestration.map(chatKey).join("\n");
|
|
@@ -47003,6 +47065,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47003
47065
|
archiveRemovedWorkspaceChats,
|
|
47004
47066
|
archivesWithRemovedWorkspace,
|
|
47005
47067
|
armSchedules,
|
|
47068
|
+
askBlockStillWaiting,
|
|
47006
47069
|
assertAbleTimeCredential,
|
|
47007
47070
|
assertAbleTimeMcpCredential,
|
|
47008
47071
|
assertOrchestratorCapableAgent,
|
|
@@ -47443,6 +47506,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47443
47506
|
lastAgentReply,
|
|
47444
47507
|
lastAssistantMessageText,
|
|
47445
47508
|
lastRequestOccupancy,
|
|
47509
|
+
lastTopLevelToolIsAskUser,
|
|
47446
47510
|
latestPendingPlanQuestions,
|
|
47447
47511
|
linearAuthorizationHeader,
|
|
47448
47512
|
linearCycleIsActive,
|