kimiflare 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +337 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1359,6 +1359,13 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1359
1359
|
const recentToolCalls = opts2.recentToolCalls ?? [];
|
|
1360
1360
|
const LOOP_WINDOW = 8;
|
|
1361
1361
|
const LOOP_THRESHOLD = 2;
|
|
1362
|
+
const webFetchHistory = [];
|
|
1363
|
+
const MAX_WEB_FETCH_PER_TURN = 5;
|
|
1364
|
+
const WEB_FETCH_DOMAIN_THRESHOLD = 2;
|
|
1365
|
+
let totalToolCallsThisTurn = 0;
|
|
1366
|
+
const BUDGET_CHECK_INTERVAL = 3;
|
|
1367
|
+
const SOFT_BUDGET = 5;
|
|
1368
|
+
const HARD_BUDGET = 15;
|
|
1362
1369
|
for (let iter = 0; iter < max; iter++) {
|
|
1363
1370
|
turn++;
|
|
1364
1371
|
const previousMessages = opts2.messages.slice();
|
|
@@ -1513,6 +1520,57 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1513
1520
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1514
1521
|
continue;
|
|
1515
1522
|
}
|
|
1523
|
+
if (tc.function.name === "web_fetch") {
|
|
1524
|
+
const args = JSON.parse(tc.function.arguments || "{}");
|
|
1525
|
+
const url = args.url || "";
|
|
1526
|
+
try {
|
|
1527
|
+
const domain = new URL(url).hostname;
|
|
1528
|
+
const domainCount = webFetchHistory.filter((h) => h.domain === domain).length;
|
|
1529
|
+
const totalWebFetches = webFetchHistory.length;
|
|
1530
|
+
if (totalWebFetches >= MAX_WEB_FETCH_PER_TURN) {
|
|
1531
|
+
const warning = `Research budget exceeded: you have already made ${MAX_WEB_FETCH_PER_TURN} web requests this turn. Synthesize what you have learned instead of fetching more pages.`;
|
|
1532
|
+
const budgetResult = {
|
|
1533
|
+
tool_call_id: tc.id,
|
|
1534
|
+
name: "web_fetch",
|
|
1535
|
+
content: warning,
|
|
1536
|
+
ok: false
|
|
1537
|
+
};
|
|
1538
|
+
toolResults.push(budgetResult);
|
|
1539
|
+
opts2.messages.push({
|
|
1540
|
+
role: "tool",
|
|
1541
|
+
tool_call_id: tc.id,
|
|
1542
|
+
content: sanitizeString(warning),
|
|
1543
|
+
name: "web_fetch"
|
|
1544
|
+
});
|
|
1545
|
+
opts2.callbacks.onToolResult?.(budgetResult);
|
|
1546
|
+
recentToolCalls.push(loopSignature);
|
|
1547
|
+
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
if (domainCount >= WEB_FETCH_DOMAIN_THRESHOLD) {
|
|
1551
|
+
const warning = `Loop detected: you have fetched from ${domain} multiple times. Consider a different approach or synthesize existing findings.`;
|
|
1552
|
+
const loopResult = {
|
|
1553
|
+
tool_call_id: tc.id,
|
|
1554
|
+
name: "web_fetch",
|
|
1555
|
+
content: warning,
|
|
1556
|
+
ok: false
|
|
1557
|
+
};
|
|
1558
|
+
toolResults.push(loopResult);
|
|
1559
|
+
opts2.messages.push({
|
|
1560
|
+
role: "tool",
|
|
1561
|
+
tool_call_id: tc.id,
|
|
1562
|
+
content: sanitizeString(warning),
|
|
1563
|
+
name: "web_fetch"
|
|
1564
|
+
});
|
|
1565
|
+
opts2.callbacks.onToolResult?.(loopResult);
|
|
1566
|
+
recentToolCalls.push(loopSignature);
|
|
1567
|
+
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1568
|
+
continue;
|
|
1569
|
+
}
|
|
1570
|
+
webFetchHistory.push({ url, domain });
|
|
1571
|
+
} catch {
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1516
1574
|
if (codeMode && tc.function.name === "execute_code") {
|
|
1517
1575
|
const args = JSON.parse(tc.function.arguments || "{}");
|
|
1518
1576
|
const code = args.code || "";
|
|
@@ -1572,8 +1630,20 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1572
1630
|
opts2.callbacks.onToolResult?.(result);
|
|
1573
1631
|
recentToolCalls.push(loopSignature);
|
|
1574
1632
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1633
|
+
totalToolCallsThisTurn++;
|
|
1575
1634
|
}
|
|
1576
1635
|
}
|
|
1636
|
+
if (totalToolCallsThisTurn > 0 && totalToolCallsThisTurn % BUDGET_CHECK_INTERVAL === 0) {
|
|
1637
|
+
let budgetMsg = "";
|
|
1638
|
+
if (totalToolCallsThisTurn >= HARD_BUDGET) {
|
|
1639
|
+
budgetMsg = `BUDGET CHECK: You have made ${totalToolCallsThisTurn} tool calls. This is the substantial-question budget. Produce your deliverable now unless you can name a specific gap that would change the recommendation.`;
|
|
1640
|
+
} else if (totalToolCallsThisTurn >= SOFT_BUDGET) {
|
|
1641
|
+
budgetMsg = `BUDGET CHECK: You have made ${totalToolCallsThisTurn} tool calls. If this is a routine question, produce your deliverable now. If substantial, justify the next call in one sentence.`;
|
|
1642
|
+
} else {
|
|
1643
|
+
budgetMsg = `BUDGET CHECK: You have made ${totalToolCallsThisTurn} tool calls. Assess: is the next call worth more than what you already have? If yes, justify in one sentence. If no, produce your deliverable.`;
|
|
1644
|
+
}
|
|
1645
|
+
opts2.messages.push({ role: "system", content: budgetMsg });
|
|
1646
|
+
}
|
|
1577
1647
|
if (opts2.sessionId && lastUsage) {
|
|
1578
1648
|
void logTurnDebug({
|
|
1579
1649
|
sessionId: opts2.sessionId,
|
|
@@ -1587,7 +1657,9 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1587
1657
|
});
|
|
1588
1658
|
}
|
|
1589
1659
|
}
|
|
1590
|
-
|
|
1660
|
+
const pauseMsg = `Paused after ${opts2.maxToolIterations ?? 50} tool calls. The user may say "go on" to continue. If you have a partial deliverable (Research Brief, Implementation Notes, etc.), include it in your next response.`;
|
|
1661
|
+
opts2.messages.push({ role: "system", content: pauseMsg });
|
|
1662
|
+
throw new Error(`kimiflare: tool iteration limit reached (${opts2.maxToolIterations ?? 50}). Say "go on" to continue, or ask me to focus on a specific area.`);
|
|
1591
1663
|
}
|
|
1592
1664
|
function validateToolArguments(raw) {
|
|
1593
1665
|
if (!raw || !raw.trim()) return "{}";
|
|
@@ -1847,8 +1919,82 @@ function loadContextFile(cwd) {
|
|
|
1847
1919
|
}
|
|
1848
1920
|
return null;
|
|
1849
1921
|
}
|
|
1922
|
+
function buildRolePrefix(role) {
|
|
1923
|
+
switch (role) {
|
|
1924
|
+
case "research":
|
|
1925
|
+
return `You are the Research Agent in kimiflare. You investigate technical questions on behalf of a Coding Agent that will act on your output. You are not talking to a human. The Coding Agent is your reader.
|
|
1926
|
+
|
|
1927
|
+
# Your job
|
|
1928
|
+
|
|
1929
|
+
Produce the smallest research artifact that lets the Coding Agent act correctly and confidently on the task it has been given. Not the most thorough \u2014 the smallest sufficient one. Research exists to enable action. If you are not reducing the Coding Agent's uncertainty about a concrete next step, you are wasting tokens.
|
|
1930
|
+
|
|
1931
|
+
# How to think
|
|
1932
|
+
|
|
1933
|
+
1. Start by naming the decision. Before any tool call, write down \u2014 for yourself \u2014 what decision your research is meant to enable. "Pick a library." "Choose between approach A and B." "Determine if X is possible." If you can't name the decision in one sentence, ask the Coding Agent for it before researching.
|
|
1934
|
+
|
|
1935
|
+
2. Surface area before depth. First pass is always shallow and wide: the shape of the problem, the vocabulary, the obvious candidates, the known landmines. Only then go deep, and only on what the decision actually hinges on.
|
|
1936
|
+
|
|
1937
|
+
3. Hold hypotheses loosely and visibly. Form a working hypothesis early \u2014 it directs attention \u2014 but mark it as a hypothesis and look actively for evidence against it. Sycophantic research is useless research.
|
|
1938
|
+
|
|
1939
|
+
4. Budget is real. You have a finite tool-call budget per task. Default to ~5 calls for routine questions, up to ~15 for substantial ones. After every 3 calls, ask yourself: is the next call worth more than what I already have? Usually it isn't. Stop earlier than feels comfortable.
|
|
1940
|
+
|
|
1941
|
+
5. Separate finding from inference from recommendation. Sources said X. I infer Y. Therefore Z for our case. Keep these layers visible so the Coding Agent can audit any of them.
|
|
1942
|
+
|
|
1943
|
+
6. Know when to recommend running the code instead. Sometimes the cheapest research is letting the runtime answer. Say so when true.
|
|
1944
|
+
|
|
1945
|
+
# When to stop
|
|
1946
|
+
|
|
1947
|
+
Stop when all of these are true:
|
|
1948
|
+
- The named decision can be made from what you have.
|
|
1949
|
+
- Remaining uncertainties are named, not hidden.
|
|
1950
|
+
- The next tool call would predictably add little.
|
|
1951
|
+
|
|
1952
|
+
Do not stop just because you found something. Do not stop just because you ran out of patience. Stop on the criteria above, and only those.
|
|
1953
|
+
|
|
1954
|
+
# Output format
|
|
1955
|
+
|
|
1956
|
+
You are writing for an agent, not a person. No preamble, no narrative, no "in this report we will." Structure:
|
|
1957
|
+
|
|
1958
|
+
- DECISION: one sentence \u2014 what this research enables.
|
|
1959
|
+
- FINDINGS: scannable facts, with source attribution. Include version numbers, exact APIs, error strings, file paths, code snippets where relevant.
|
|
1960
|
+
- RECOMMENDATION: what the Coding Agent should do, concretely.
|
|
1961
|
+
- CONFIDENCE: per claim where it varies. "High / Medium / Low" is fine.
|
|
1962
|
+
- OPEN QUESTIONS: things you couldn't resolve. Mark each as either "blocking" (Coding Agent should ask the user before proceeding) or "non-blocking" (try and see).
|
|
1963
|
+
- RISKS: what could go wrong if the Recommendation is followed, including the strongest counter-argument you found.
|
|
1964
|
+
|
|
1965
|
+
# Voice
|
|
1966
|
+
|
|
1967
|
+
Terse. Direct. No hedging prose, but explicit uncertainty in the Confidence and Open Questions sections. No apologies, no throat-clearing, no "I hope this helps."
|
|
1968
|
+
|
|
1969
|
+
# Addressing the user
|
|
1970
|
+
|
|
1971
|
+
You do not address the user. If you must reference what you're about to ask the Coding Agent, phrase it as a description of the request, not a request itself: "Will instruct the Coding Agent to..." \u2014 never "please do X." The user is overhearing, not participating.
|
|
1972
|
+
|
|
1973
|
+
# Things that are not research
|
|
1974
|
+
|
|
1975
|
+
- Restating the task back at length.
|
|
1976
|
+
- Listing every option without ranking them.
|
|
1977
|
+
- Producing an essay when a table would do.
|
|
1978
|
+
- Continuing to search after the decision can already be made.
|
|
1979
|
+
- Hiding uncertainty inside confident prose.
|
|
1980
|
+
|
|
1981
|
+
When in doubt, deliver the smaller artifact sooner. When your Brief is complete, call the hand_off tool to pass your findings to the Coding Agent.
|
|
1982
|
+
|
|
1983
|
+
`;
|
|
1984
|
+
case "coding":
|
|
1985
|
+
return `You are the Coding Agent of kimiflare. You write code, edit files, and execute tools directly. Do not ask the user to do your work for you. Implement the changes yourself.
|
|
1986
|
+
|
|
1987
|
+
`;
|
|
1988
|
+
case "generalist":
|
|
1989
|
+
return `You are the Generalist Agent of kimiflare. You handle conversational queries, memory management, and high-level task coordination.
|
|
1990
|
+
|
|
1991
|
+
`;
|
|
1992
|
+
default:
|
|
1993
|
+
return "";
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1850
1996
|
function buildStaticPrefix(opts2) {
|
|
1851
|
-
return `You are kimiflare, an interactive coding assistant running in the user's terminal. You act on the user's local filesystem through the tools listed below. You are powered by the ${opts2.model} model on Cloudflare Workers AI.
|
|
1997
|
+
return buildRolePrefix(opts2.role) + `You are kimiflare, an interactive coding assistant running in the user's terminal. You act on the user's local filesystem through the tools listed below. You are powered by the ${opts2.model} model on Cloudflare Workers AI.
|
|
1852
1998
|
|
|
1853
1999
|
How to work:
|
|
1854
2000
|
- Prefer calling tools over guessing. Read files before editing them. Use \`glob\` and \`grep\` to explore code before assuming structure.
|
|
@@ -2637,6 +2783,47 @@ var init_memory = __esm({
|
|
|
2637
2783
|
}
|
|
2638
2784
|
});
|
|
2639
2785
|
|
|
2786
|
+
// src/tools/hand-off.ts
|
|
2787
|
+
var handOffTool;
|
|
2788
|
+
var init_hand_off = __esm({
|
|
2789
|
+
"src/tools/hand-off.ts"() {
|
|
2790
|
+
"use strict";
|
|
2791
|
+
handOffTool = {
|
|
2792
|
+
name: "hand_off",
|
|
2793
|
+
needsPermission: false,
|
|
2794
|
+
description: `Signal that your work is complete and request a hand-off to another agent. Use this when you have produced your deliverable (Research Brief, Implementation Notes, etc.) and the next agent should take over.
|
|
2795
|
+
|
|
2796
|
+
Parameters:
|
|
2797
|
+
- target: the agent to hand off to (e.g., "coding", "generalist")
|
|
2798
|
+
- reason: optional one-sentence summary of what was completed`,
|
|
2799
|
+
parameters: {
|
|
2800
|
+
type: "object",
|
|
2801
|
+
properties: {
|
|
2802
|
+
target: {
|
|
2803
|
+
type: "string",
|
|
2804
|
+
description: 'Agent to hand off to: "coding", "generalist", or another agent role'
|
|
2805
|
+
},
|
|
2806
|
+
reason: {
|
|
2807
|
+
type: "string",
|
|
2808
|
+
description: "One-sentence summary of what was completed and why hand-off is appropriate"
|
|
2809
|
+
}
|
|
2810
|
+
},
|
|
2811
|
+
required: ["target"],
|
|
2812
|
+
additionalProperties: false
|
|
2813
|
+
},
|
|
2814
|
+
async run(args, _ctx) {
|
|
2815
|
+
const target = args.target;
|
|
2816
|
+
const reason = args.reason ?? "";
|
|
2817
|
+
return {
|
|
2818
|
+
content: `Hand-off requested to ${target} agent.${reason ? ` Reason: ${reason}` : ""}`,
|
|
2819
|
+
rawBytes: 0,
|
|
2820
|
+
reducedBytes: 0
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
};
|
|
2824
|
+
}
|
|
2825
|
+
});
|
|
2826
|
+
|
|
2640
2827
|
// src/tools/artifact-store.ts
|
|
2641
2828
|
var ToolArtifactStore;
|
|
2642
2829
|
var init_artifact_store = __esm({
|
|
@@ -3125,6 +3312,7 @@ var init_executor = __esm({
|
|
|
3125
3312
|
init_web_fetch();
|
|
3126
3313
|
init_tasks();
|
|
3127
3314
|
init_memory();
|
|
3315
|
+
init_hand_off();
|
|
3128
3316
|
init_artifact_store();
|
|
3129
3317
|
init_reducer();
|
|
3130
3318
|
init_expand_artifact();
|
|
@@ -3139,7 +3327,8 @@ var init_executor = __esm({
|
|
|
3139
3327
|
tasksSetTool,
|
|
3140
3328
|
memoryRememberTool,
|
|
3141
3329
|
memoryRecallTool,
|
|
3142
|
-
memoryForgetTool
|
|
3330
|
+
memoryForgetTool,
|
|
3331
|
+
handOffTool
|
|
3143
3332
|
];
|
|
3144
3333
|
ToolExecutor = class {
|
|
3145
3334
|
sessionAllowed = /* @__PURE__ */ new Set();
|
|
@@ -5091,7 +5280,9 @@ async function compactMessages(opts2) {
|
|
|
5091
5280
|
prefixEnd++;
|
|
5092
5281
|
}
|
|
5093
5282
|
const prefix = messages.slice(0, prefixEnd);
|
|
5094
|
-
if (prefix.length === 0)
|
|
5283
|
+
if (prefix.length === 0) {
|
|
5284
|
+
return { summary: "", newMessages: messages, replacedCount: 0 };
|
|
5285
|
+
}
|
|
5095
5286
|
const cutoffUserIdx = indexOfNthUserFromEnd(messages, keep);
|
|
5096
5287
|
const firstKeepIdx = cutoffUserIdx >= 0 ? cutoffUserIdx : messages.length;
|
|
5097
5288
|
const toSummarize = messages.slice(prefixEnd, firstKeepIdx);
|
|
@@ -5652,6 +5843,7 @@ var init_agent_session = __esm({
|
|
|
5652
5843
|
"lsp_rename",
|
|
5653
5844
|
"lsp_typeDefinition",
|
|
5654
5845
|
"lsp_workspaceSymbol",
|
|
5846
|
+
"hand_off",
|
|
5655
5847
|
"memory_recall",
|
|
5656
5848
|
"read",
|
|
5657
5849
|
"tasks_set",
|
|
@@ -5883,6 +6075,26 @@ var init_orchestrator = __esm({
|
|
|
5883
6075
|
getAutoSwitch() {
|
|
5884
6076
|
return this.autoSwitch;
|
|
5885
6077
|
}
|
|
6078
|
+
/** Scan the session's last assistant message for a hand_off tool call.
|
|
6079
|
+
* Returns the target role if found, null otherwise. */
|
|
6080
|
+
detectHandOff(messages) {
|
|
6081
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
6082
|
+
const m = messages[i];
|
|
6083
|
+
if (m.role === "assistant" && m.tool_calls) {
|
|
6084
|
+
for (const tc of m.tool_calls) {
|
|
6085
|
+
if (tc.function.name === "hand_off") {
|
|
6086
|
+
try {
|
|
6087
|
+
const args = JSON.parse(tc.function.arguments);
|
|
6088
|
+
if (args.target) return args.target;
|
|
6089
|
+
} catch {
|
|
6090
|
+
}
|
|
6091
|
+
}
|
|
6092
|
+
}
|
|
6093
|
+
break;
|
|
6094
|
+
}
|
|
6095
|
+
}
|
|
6096
|
+
return null;
|
|
6097
|
+
}
|
|
5886
6098
|
getToolsForRole(role) {
|
|
5887
6099
|
const base = getAgentTools(role, this.opts.customAgents);
|
|
5888
6100
|
if (this.opts.lspTools.length > 0) {
|
|
@@ -6038,6 +6250,20 @@ ${summary}`
|
|
|
6038
6250
|
agentRole: this.activeRole
|
|
6039
6251
|
});
|
|
6040
6252
|
session.recentToolCalls = session.recentToolCalls.slice(-8);
|
|
6253
|
+
const handOffTarget = this.detectHandOff(session.messages);
|
|
6254
|
+
if (handOffTarget && handOffTarget !== this.activeRole) {
|
|
6255
|
+
const summary = await this.synthesizeHandoff(this.activeRole, handOffTarget);
|
|
6256
|
+
this.activeRole = handOffTarget;
|
|
6257
|
+
const newSession = this.getActiveSession();
|
|
6258
|
+
if (summary) {
|
|
6259
|
+
newSession.messages.push({
|
|
6260
|
+
role: "system",
|
|
6261
|
+
content: `[hand-off from ${this.activeRole} agent \u2014 agent requested hand-off]
|
|
6262
|
+
${summary}`
|
|
6263
|
+
});
|
|
6264
|
+
}
|
|
6265
|
+
this.turnCounts.set(handOffTarget, 0);
|
|
6266
|
+
}
|
|
6041
6267
|
this.turnCounts.set(this.activeRole, (this.turnCounts.get(this.activeRole) ?? 0) + 1);
|
|
6042
6268
|
}
|
|
6043
6269
|
async handOff(toRole) {
|
|
@@ -7497,6 +7723,11 @@ var init_chat = __esm({
|
|
|
7497
7723
|
}
|
|
7498
7724
|
if (evt.kind === "assistant") {
|
|
7499
7725
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingLeft: 2, children: [
|
|
7726
|
+
evt.agentRole && /* @__PURE__ */ jsx4(Box4, { marginBottom: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.info.color, dimColor: theme.info.dim, children: [
|
|
7727
|
+
"\u25C6 ",
|
|
7728
|
+
evt.agentRole,
|
|
7729
|
+
" agent"
|
|
7730
|
+
] }) }),
|
|
7500
7731
|
showReasoning && evt.reasoning ? /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.reasoning.color, dimColor: theme.reasoning.dim, children: [
|
|
7501
7732
|
"thinking\u2026",
|
|
7502
7733
|
" ",
|
|
@@ -9130,7 +9361,7 @@ function themeNames() {
|
|
|
9130
9361
|
function themeList() {
|
|
9131
9362
|
return Object.values(THEMES);
|
|
9132
9363
|
}
|
|
9133
|
-
var dark, light, highContrast, dracula, nord, monokai, solarizedDark, solarizedLight, tokyoNight, gruvboxDark, catppuccinMocha, rosePine, THEMES, DEFAULT_THEME_NAME;
|
|
9364
|
+
var dark, light, highContrast, dracula, nord, monokai, solarizedDark, solarizedLight, tokyoNight, gruvboxDark, catppuccinMocha, rosePine, oneDark, ayu, nightOwl, palenight, THEMES, DEFAULT_THEME_NAME;
|
|
9134
9365
|
var init_theme = __esm({
|
|
9135
9366
|
"src/ui/theme.ts"() {
|
|
9136
9367
|
"use strict";
|
|
@@ -9326,6 +9557,70 @@ var init_theme = __esm({
|
|
|
9326
9557
|
accent: "#ebbcba",
|
|
9327
9558
|
modeBadge: { plan: "#31748f", auto: "#9ccfd8", edit: "#ebbcba" }
|
|
9328
9559
|
};
|
|
9560
|
+
oneDark = {
|
|
9561
|
+
name: "one-dark",
|
|
9562
|
+
label: "one-dark (Atom's iconic dark \u2014 blue & purple)",
|
|
9563
|
+
user: "#61afef",
|
|
9564
|
+
assistant: void 0,
|
|
9565
|
+
reasoning: { color: "#5c6370", dim: true },
|
|
9566
|
+
info: { color: "#5c6370", dim: true },
|
|
9567
|
+
error: "#e06c75",
|
|
9568
|
+
warn: "#e5c07b",
|
|
9569
|
+
tool: "#c678dd",
|
|
9570
|
+
spinner: "#61afef",
|
|
9571
|
+
permission: "#e5c07b",
|
|
9572
|
+
queue: { color: "#5c6370", dim: true },
|
|
9573
|
+
accent: "#c678dd",
|
|
9574
|
+
modeBadge: { plan: "#61afef", auto: "#98c379", edit: "#c678dd" }
|
|
9575
|
+
};
|
|
9576
|
+
ayu = {
|
|
9577
|
+
name: "ayu",
|
|
9578
|
+
label: "ayu (clean modern \u2014 orange & cyan)",
|
|
9579
|
+
user: "#39bae6",
|
|
9580
|
+
assistant: void 0,
|
|
9581
|
+
reasoning: { color: "#4d5566", dim: true },
|
|
9582
|
+
info: { color: "#4d5566", dim: true },
|
|
9583
|
+
error: "#f07178",
|
|
9584
|
+
warn: "#ffb454",
|
|
9585
|
+
tool: "#73b8ff",
|
|
9586
|
+
spinner: "#39bae6",
|
|
9587
|
+
permission: "#ffb454",
|
|
9588
|
+
queue: { color: "#4d5566", dim: true },
|
|
9589
|
+
accent: "#39bae6",
|
|
9590
|
+
modeBadge: { plan: "#39bae6", auto: "#7ee787", edit: "#ffb454" }
|
|
9591
|
+
};
|
|
9592
|
+
nightOwl = {
|
|
9593
|
+
name: "night-owl",
|
|
9594
|
+
label: "night-owl (deep navy \u2014 cyan & red)",
|
|
9595
|
+
user: "#82aaff",
|
|
9596
|
+
assistant: void 0,
|
|
9597
|
+
reasoning: { color: "#4d6885", dim: true },
|
|
9598
|
+
info: { color: "#4d6885", dim: true },
|
|
9599
|
+
error: "#ef5350",
|
|
9600
|
+
warn: "#ffca28",
|
|
9601
|
+
tool: "#c792ea",
|
|
9602
|
+
spinner: "#82aaff",
|
|
9603
|
+
permission: "#ffca28",
|
|
9604
|
+
queue: { color: "#4d6885", dim: true },
|
|
9605
|
+
accent: "#c792ea",
|
|
9606
|
+
modeBadge: { plan: "#82aaff", auto: "#7ee787", edit: "#c792ea" }
|
|
9607
|
+
};
|
|
9608
|
+
palenight = {
|
|
9609
|
+
name: "palenight",
|
|
9610
|
+
label: "palenight (Material pale \u2014 purple & cyan)",
|
|
9611
|
+
user: "#82b1ff",
|
|
9612
|
+
assistant: void 0,
|
|
9613
|
+
reasoning: { color: "#4c566a", dim: true },
|
|
9614
|
+
info: { color: "#4c566a", dim: true },
|
|
9615
|
+
error: "#f07178",
|
|
9616
|
+
warn: "#ffcb6b",
|
|
9617
|
+
tool: "#c792ea",
|
|
9618
|
+
spinner: "#82b1ff",
|
|
9619
|
+
permission: "#ffcb6b",
|
|
9620
|
+
queue: { color: "#4c566a", dim: true },
|
|
9621
|
+
accent: "#c792ea",
|
|
9622
|
+
modeBadge: { plan: "#82b1ff", auto: "#c3e88d", edit: "#c792ea" }
|
|
9623
|
+
};
|
|
9329
9624
|
THEMES = {
|
|
9330
9625
|
dark,
|
|
9331
9626
|
light,
|
|
@@ -9338,7 +9633,11 @@ var init_theme = __esm({
|
|
|
9338
9633
|
"tokyo-night": tokyoNight,
|
|
9339
9634
|
"gruvbox-dark": gruvboxDark,
|
|
9340
9635
|
"catppuccin-mocha": catppuccinMocha,
|
|
9341
|
-
"rose-pine": rosePine
|
|
9636
|
+
"rose-pine": rosePine,
|
|
9637
|
+
"one-dark": oneDark,
|
|
9638
|
+
ayu,
|
|
9639
|
+
"night-owl": nightOwl,
|
|
9640
|
+
palenight
|
|
9342
9641
|
};
|
|
9343
9642
|
DEFAULT_THEME_NAME = "dark";
|
|
9344
9643
|
}
|
|
@@ -11527,14 +11826,14 @@ function compactEventsVisual(prev, keepLastTurns) {
|
|
|
11527
11826
|
...kept
|
|
11528
11827
|
];
|
|
11529
11828
|
}
|
|
11530
|
-
function makePrefixMessages(cacheStable, model, mode, tools) {
|
|
11829
|
+
function makePrefixMessages(cacheStable, model, mode, tools, role) {
|
|
11531
11830
|
if (cacheStable) {
|
|
11532
|
-
return buildSystemMessages({ cwd: process.cwd(), tools, model, mode });
|
|
11831
|
+
return buildSystemMessages({ cwd: process.cwd(), tools, model, mode, role });
|
|
11533
11832
|
}
|
|
11534
11833
|
return [
|
|
11535
11834
|
{
|
|
11536
11835
|
role: "system",
|
|
11537
|
-
content: buildSystemPrompt({ cwd: process.cwd(), tools, model, mode })
|
|
11836
|
+
content: buildSystemPrompt({ cwd: process.cwd(), tools, model, mode, role })
|
|
11538
11837
|
}
|
|
11539
11838
|
];
|
|
11540
11839
|
}
|
|
@@ -11647,6 +11946,7 @@ function App({
|
|
|
11647
11946
|
const memoryManagerRef = useRef3(null);
|
|
11648
11947
|
const sessionStartRecallRef = useRef3(null);
|
|
11649
11948
|
const orchestratorRef = useRef3(null);
|
|
11949
|
+
const pendingOrchestratorStateRef = useRef3(null);
|
|
11650
11950
|
const pendingTextRef = useRef3(/* @__PURE__ */ new Map());
|
|
11651
11951
|
const flushTimeoutRef = useRef3(null);
|
|
11652
11952
|
const customCommandsRef = useRef3([]);
|
|
@@ -12404,9 +12704,10 @@ function App({
|
|
|
12404
12704
|
onAssistantStart: () => {
|
|
12405
12705
|
const id = nextAssistantId++;
|
|
12406
12706
|
activeAsstIdRef.current = id;
|
|
12707
|
+
const role = orchestratorRef.current?.getActiveRole();
|
|
12407
12708
|
setEvents((e) => [
|
|
12408
12709
|
...e,
|
|
12409
|
-
{ kind: "assistant", key: `asst_${id}`, id, text: "", reasoning: "", streaming: true }
|
|
12710
|
+
{ kind: "assistant", key: `asst_${id}`, id, text: "", reasoning: "", streaming: true, agentRole: role }
|
|
12410
12711
|
]);
|
|
12411
12712
|
},
|
|
12412
12713
|
onReasoningDelta: (d) => {
|
|
@@ -12562,58 +12863,15 @@ function App({
|
|
|
12562
12863
|
} else {
|
|
12563
12864
|
artifactStoreRef.current = new ArtifactStore();
|
|
12564
12865
|
}
|
|
12565
|
-
if (
|
|
12566
|
-
if (
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
cwd: process.cwd(),
|
|
12574
|
-
signal: new AbortController().signal,
|
|
12575
|
-
reasoningEffort: effortRef.current,
|
|
12576
|
-
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
12577
|
-
sessionId: file.id,
|
|
12578
|
-
memoryManager: memoryManagerRef.current,
|
|
12579
|
-
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
12580
|
-
codeMode,
|
|
12581
|
-
callbacks: {
|
|
12582
|
-
onAssistantStart: () => {
|
|
12583
|
-
},
|
|
12584
|
-
onReasoningDelta: () => {
|
|
12585
|
-
},
|
|
12586
|
-
onTextDelta: () => {
|
|
12587
|
-
},
|
|
12588
|
-
onToolCallStart: () => {
|
|
12589
|
-
},
|
|
12590
|
-
onToolCallArgs: () => {
|
|
12591
|
-
},
|
|
12592
|
-
onToolCallFinalized: () => {
|
|
12593
|
-
},
|
|
12594
|
-
onUsage: () => {
|
|
12595
|
-
},
|
|
12596
|
-
onUsageFinal: () => {
|
|
12597
|
-
},
|
|
12598
|
-
onGatewayMeta: () => {
|
|
12599
|
-
},
|
|
12600
|
-
onAssistantFinal: () => {
|
|
12601
|
-
},
|
|
12602
|
-
onToolResult: () => {
|
|
12603
|
-
},
|
|
12604
|
-
onTasks: () => {
|
|
12605
|
-
},
|
|
12606
|
-
askPermission: async () => "allow"
|
|
12607
|
-
},
|
|
12608
|
-
executor: executorRef.current,
|
|
12609
|
-
mcpTools: mcpToolsRef.current,
|
|
12610
|
-
lspTools: lspToolsRef.current,
|
|
12611
|
-
autoSwitch: cfg.autoSwitch ?? false,
|
|
12612
|
-
autoSwitchConfirm: cfg.autoSwitchConfirm ?? false,
|
|
12613
|
-
customAgents: cfg.customAgents
|
|
12614
|
-
});
|
|
12866
|
+
if (cfg?.multiAgent) {
|
|
12867
|
+
if (file.multiAgentState) {
|
|
12868
|
+
pendingOrchestratorStateRef.current = file.multiAgentState;
|
|
12869
|
+
} else {
|
|
12870
|
+
pendingOrchestratorStateRef.current = {
|
|
12871
|
+
activeRole: "generalist",
|
|
12872
|
+
agents: [{ role: "generalist", messages: file.messages, recentToolCalls: [] }]
|
|
12873
|
+
};
|
|
12615
12874
|
}
|
|
12616
|
-
orchestratorRef.current.deserialize(file.multiAgentState);
|
|
12617
12875
|
}
|
|
12618
12876
|
const manager = memoryManagerRef.current;
|
|
12619
12877
|
if (manager) {
|
|
@@ -12699,6 +12957,7 @@ function App({
|
|
|
12699
12957
|
artifactStoreRef.current = new ArtifactStore();
|
|
12700
12958
|
executorRef.current.clearArtifacts();
|
|
12701
12959
|
orchestratorRef.current = null;
|
|
12960
|
+
pendingOrchestratorStateRef.current = null;
|
|
12702
12961
|
setEvents([]);
|
|
12703
12962
|
setUsage(null);
|
|
12704
12963
|
setSessionUsage(null);
|
|
@@ -13461,9 +13720,10 @@ ${lines.join("\n")}` }]);
|
|
|
13461
13720
|
onAssistantStart: () => {
|
|
13462
13721
|
const id = nextAssistantId++;
|
|
13463
13722
|
activeAsstIdRef.current = id;
|
|
13723
|
+
const role = orchestratorRef.current?.getActiveRole();
|
|
13464
13724
|
setEvents((e) => [
|
|
13465
13725
|
...e,
|
|
13466
|
-
{ kind: "assistant", key: `asst_${id}`, id, text: "", reasoning: "", streaming: true }
|
|
13726
|
+
{ kind: "assistant", key: `asst_${id}`, id, text: "", reasoning: "", streaming: true, agentRole: role }
|
|
13467
13727
|
]);
|
|
13468
13728
|
},
|
|
13469
13729
|
onReasoningDelta: (d) => {
|
|
@@ -13599,6 +13859,21 @@ ${lines.join("\n")}` }]);
|
|
|
13599
13859
|
},
|
|
13600
13860
|
customAgents: cfg.customAgents
|
|
13601
13861
|
});
|
|
13862
|
+
if (pendingOrchestratorStateRef.current) {
|
|
13863
|
+
orchestratorRef.current.deserialize(pendingOrchestratorStateRef.current);
|
|
13864
|
+
pendingOrchestratorStateRef.current = null;
|
|
13865
|
+
}
|
|
13866
|
+
const activeSession2 = orchestratorRef.current.getActiveSession();
|
|
13867
|
+
if (!activeSession2.messages.some((m) => m.role === "system")) {
|
|
13868
|
+
const prefix = makePrefixMessages(
|
|
13869
|
+
cacheStableRef.current,
|
|
13870
|
+
overrideModel ?? cfg.model,
|
|
13871
|
+
modeRef.current,
|
|
13872
|
+
[...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current],
|
|
13873
|
+
orchestratorRef.current.getActiveRole()
|
|
13874
|
+
);
|
|
13875
|
+
activeSession2.messages.unshift(...prefix);
|
|
13876
|
+
}
|
|
13602
13877
|
}
|
|
13603
13878
|
await orchestratorRef.current.runTurn({ role: "user", content });
|
|
13604
13879
|
const activeSession = orchestratorRef.current.getActiveSession();
|