chainlesschain 0.45.74 → 0.45.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -15
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-BhJ3YFWt.js → AppLayout-2RCrdXxl.js} +1 -1
- package/src/assets/web-panel/assets/AppLayout-D9pBLPC3.css +1 -0
- package/src/assets/web-panel/assets/{Chat-DaxTP3x8.js → Chat-B2nB8o_F.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-CjlX4CrX.js → Dashboard-DanoHPSI.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BCvgBkD3.js → Skills-CLlblJcG.js} +1 -1
- package/src/assets/web-panel/assets/chat-DWBA4-cl.js +1 -0
- package/src/assets/web-panel/assets/{index-DrmEk9S3.js → index-CyGtHm63.js} +2 -2
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/learning.js +273 -0
- package/src/commands/lowcode.js +23 -8
- package/src/gateways/discord/discord-formatter.js +89 -0
- package/src/gateways/gateway-base.js +189 -0
- package/src/gateways/telegram/telegram-formatter.js +93 -0
- package/src/index.js +2 -0
- package/src/lib/app-builder.js +136 -8
- package/src/lib/autonomous-agent.js +8 -1
- package/src/lib/cli-context-engineering.js +15 -0
- package/src/lib/execution-backend.js +239 -0
- package/src/lib/hook-manager.js +2 -0
- package/src/lib/iteration-budget.js +175 -0
- package/src/lib/learning/learning-hooks.js +117 -0
- package/src/lib/learning/learning-tables.js +66 -0
- package/src/lib/learning/outcome-feedback.js +243 -0
- package/src/lib/learning/reflection-engine.js +323 -0
- package/src/lib/learning/skill-improver.js +536 -0
- package/src/lib/learning/skill-synthesizer.js +315 -0
- package/src/lib/learning/trajectory-store.js +409 -0
- package/src/lib/plugin-autodiscovery.js +224 -0
- package/src/lib/session-search.js +193 -0
- package/src/lib/sub-agent-context.js +7 -2
- package/src/lib/user-profile.js +172 -0
- package/src/lib/web-ui-server.js +1 -1
- package/src/repl/agent-repl.js +109 -0
- package/src/runtime/agent-core.js +75 -4
- package/src/runtime/coding-agent-contract-shared.cjs +35 -0
- package/src/runtime/coding-agent-policy.cjs +10 -0
- package/src/assets/web-panel/assets/AppLayout-Cr2lWhF-.css +0 -1
- package/src/assets/web-panel/assets/chat-BmwHBi9M.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -51,6 +51,7 @@ import { feature } from "../lib/feature-flags.js";
|
|
|
51
51
|
import { recordCompressionMetric } from "../lib/compression-telemetry.js";
|
|
52
52
|
import { fireSessionHook } from "../lib/session-hooks.js";
|
|
53
53
|
import { HookEvents } from "../lib/hook-manager.js";
|
|
54
|
+
import { IterationBudget } from "../lib/iteration-budget.js";
|
|
54
55
|
import {
|
|
55
56
|
AGENT_TOOLS,
|
|
56
57
|
buildSystemPrompt,
|
|
@@ -91,6 +92,12 @@ async function agentLoop(messages, options) {
|
|
|
91
92
|
} else if (event.result?.success) {
|
|
92
93
|
process.stdout.write(chalk.green(` Done\n`));
|
|
93
94
|
}
|
|
95
|
+
} else if (event.type === "iteration-warning") {
|
|
96
|
+
process.stdout.write(chalk.yellow(`\n ${event.message}\n`));
|
|
97
|
+
} else if (event.type === "iteration-budget-exhausted") {
|
|
98
|
+
process.stdout.write(
|
|
99
|
+
chalk.red(`\n [Budget Exhausted] ${event.budget}\n`),
|
|
100
|
+
);
|
|
94
101
|
} else if (event.type === "response-complete") {
|
|
95
102
|
return event.content;
|
|
96
103
|
}
|
|
@@ -314,6 +321,12 @@ export async function startAgentRepl(options = {}) {
|
|
|
314
321
|
logger.log(
|
|
315
322
|
` ${chalk.cyan("/cowork")} Multi-agent collaboration (debate, compare)`,
|
|
316
323
|
);
|
|
324
|
+
logger.log(
|
|
325
|
+
` ${chalk.cyan("/search")} Search past sessions (/search <query>)`,
|
|
326
|
+
);
|
|
327
|
+
logger.log(
|
|
328
|
+
` ${chalk.cyan("/profile")} Show/edit user profile (USER.md)`,
|
|
329
|
+
);
|
|
317
330
|
logger.log(
|
|
318
331
|
` ${chalk.cyan("/plan")} Enter plan mode (read-only analysis first)`,
|
|
319
332
|
);
|
|
@@ -559,6 +572,100 @@ export async function startAgentRepl(options = {}) {
|
|
|
559
572
|
return;
|
|
560
573
|
}
|
|
561
574
|
|
|
575
|
+
// Session search
|
|
576
|
+
if (trimmed.startsWith("/search")) {
|
|
577
|
+
const searchQuery = trimmed.slice(7).trim();
|
|
578
|
+
if (!searchQuery) {
|
|
579
|
+
logger.info("Usage: /search <query>");
|
|
580
|
+
prompt();
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
if (!db) {
|
|
584
|
+
logger.info("Database not available for session search");
|
|
585
|
+
prompt();
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
try {
|
|
589
|
+
const { SessionSearchIndex } = await import("../lib/session-search.js");
|
|
590
|
+
const index = new SessionSearchIndex(db);
|
|
591
|
+
index.ensureTables();
|
|
592
|
+
const results = index.search(searchQuery, { limit: 10 });
|
|
593
|
+
if (results.length === 0) {
|
|
594
|
+
logger.info(
|
|
595
|
+
"No results found. Try /search after a few sessions, or run reindex.",
|
|
596
|
+
);
|
|
597
|
+
} else {
|
|
598
|
+
logger.log(chalk.bold(`\nSearch results for "${searchQuery}":\n`));
|
|
599
|
+
for (const r of results) {
|
|
600
|
+
const snippet = (r.snippet || "").substring(0, 120);
|
|
601
|
+
logger.log(
|
|
602
|
+
` ${chalk.cyan(r.sessionId.substring(0, 20))} [${chalk.dim(r.role)}] ${snippet}`,
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
logger.log("");
|
|
606
|
+
}
|
|
607
|
+
} catch (err) {
|
|
608
|
+
logger.error(`Search failed: ${err.message}`);
|
|
609
|
+
}
|
|
610
|
+
prompt();
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// User profile commands
|
|
615
|
+
if (trimmed.startsWith("/profile")) {
|
|
616
|
+
const profileArg = trimmed.slice(8).trim();
|
|
617
|
+
try {
|
|
618
|
+
const { readUserProfile, updateUserProfile, getUserProfilePath } =
|
|
619
|
+
await import("../lib/user-profile.js");
|
|
620
|
+
|
|
621
|
+
if (!profileArg || profileArg === "show") {
|
|
622
|
+
const content = readUserProfile();
|
|
623
|
+
if (content) {
|
|
624
|
+
logger.log(chalk.bold("\nUser Profile (USER.md):\n"));
|
|
625
|
+
logger.log(content);
|
|
626
|
+
logger.log(chalk.dim(`\nPath: ${getUserProfilePath()}`));
|
|
627
|
+
logger.log("");
|
|
628
|
+
} else {
|
|
629
|
+
logger.info(
|
|
630
|
+
`No user profile yet. Use /profile set <content> or let the agent learn your preferences.`,
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
} else if (profileArg.startsWith("set ")) {
|
|
634
|
+
const newContent = profileArg.slice(4).trim();
|
|
635
|
+
if (!newContent) {
|
|
636
|
+
logger.info("Usage: /profile set <content>");
|
|
637
|
+
} else {
|
|
638
|
+
const result = updateUserProfile(newContent);
|
|
639
|
+
if (result.written) {
|
|
640
|
+
logger.info(
|
|
641
|
+
`Profile updated (${result.length} chars${result.truncated ? ", truncated" : ""})`,
|
|
642
|
+
);
|
|
643
|
+
} else {
|
|
644
|
+
logger.error("Failed to write profile");
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
} else if (profileArg === "clear") {
|
|
648
|
+
updateUserProfile("");
|
|
649
|
+
logger.info("Profile cleared.");
|
|
650
|
+
} else if (profileArg === "path") {
|
|
651
|
+
logger.info(`Profile path: ${getUserProfilePath()}`);
|
|
652
|
+
} else {
|
|
653
|
+
logger.log(chalk.bold("\nProfile Commands:"));
|
|
654
|
+
logger.log(` ${chalk.cyan("/profile")} Show user profile`);
|
|
655
|
+
logger.log(
|
|
656
|
+
` ${chalk.cyan("/profile set <content>")} Update profile`,
|
|
657
|
+
);
|
|
658
|
+
logger.log(` ${chalk.cyan("/profile clear")} Clear profile`);
|
|
659
|
+
logger.log(` ${chalk.cyan("/profile path")} Show file path`);
|
|
660
|
+
logger.log("");
|
|
661
|
+
}
|
|
662
|
+
} catch (err) {
|
|
663
|
+
logger.error(`Profile command failed: ${err.message}`);
|
|
664
|
+
}
|
|
665
|
+
prompt();
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
|
|
562
669
|
// Cowork commands
|
|
563
670
|
if (trimmed.startsWith("/cowork")) {
|
|
564
671
|
const coworkArgs = trimmed.slice(7).trim();
|
|
@@ -1108,12 +1215,14 @@ export async function startAgentRepl(options = {}) {
|
|
|
1108
1215
|
|
|
1109
1216
|
try {
|
|
1110
1217
|
process.stdout.write("\n");
|
|
1218
|
+
const iterationBudget = new IterationBudget({ owner: sessionId });
|
|
1111
1219
|
const response = await agentLoop(messages, {
|
|
1112
1220
|
provider,
|
|
1113
1221
|
model: activeModel,
|
|
1114
1222
|
baseUrl,
|
|
1115
1223
|
apiKey,
|
|
1116
1224
|
contextEngine,
|
|
1225
|
+
iterationBudget,
|
|
1117
1226
|
});
|
|
1118
1227
|
|
|
1119
1228
|
if (response) {
|
|
@@ -780,6 +780,33 @@ async function executeToolInner(
|
|
|
780
780
|
);
|
|
781
781
|
}
|
|
782
782
|
|
|
783
|
+
case "search_sessions": {
|
|
784
|
+
try {
|
|
785
|
+
const { SessionSearchIndex } = await import("../lib/session-search.js");
|
|
786
|
+
const { bootstrap } = await import("./bootstrap.js");
|
|
787
|
+
const ctx = await bootstrap({ verbose: false });
|
|
788
|
+
if (!ctx.db) {
|
|
789
|
+
return attachDescriptor({
|
|
790
|
+
error: "Database not available for session search",
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
const index = new SessionSearchIndex(ctx.db);
|
|
794
|
+
index.ensureTables();
|
|
795
|
+
const results = index.search(args.query, {
|
|
796
|
+
limit: args.limit || 10,
|
|
797
|
+
});
|
|
798
|
+
return attachDescriptor({
|
|
799
|
+
query: args.query,
|
|
800
|
+
results,
|
|
801
|
+
count: results.length,
|
|
802
|
+
});
|
|
803
|
+
} catch (err) {
|
|
804
|
+
return attachDescriptor({
|
|
805
|
+
error: `Session search failed: ${err.message}`,
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
783
810
|
case "search_files": {
|
|
784
811
|
const dir = args.directory ? path.resolve(cwd, args.directory) : cwd;
|
|
785
812
|
try {
|
|
@@ -1583,7 +1610,12 @@ function _normalizeAnthropicResponse(data) {
|
|
|
1583
1610
|
* @param {object} options - provider, model, baseUrl, apiKey, contextEngine, hookDb, skillLoader, cwd, slotFiller, interaction
|
|
1584
1611
|
*/
|
|
1585
1612
|
export async function* agentLoop(messages, options) {
|
|
1586
|
-
|
|
1613
|
+
// Shared iteration budget — replaces hardcoded MAX_ITERATIONS.
|
|
1614
|
+
// When options.iterationBudget is provided (e.g. from parent agent),
|
|
1615
|
+
// the same budget instance is shared, so parent+child consume from one pool.
|
|
1616
|
+
const { IterationBudget, WarningLevel } =
|
|
1617
|
+
await import("../lib/iteration-budget.js");
|
|
1618
|
+
const budget = options.iterationBudget || new IterationBudget();
|
|
1587
1619
|
const signal = options.signal || null;
|
|
1588
1620
|
const toolContext = {
|
|
1589
1621
|
hookDb: options.hookDb || null,
|
|
@@ -1656,8 +1688,36 @@ export async function* agentLoop(messages, options) {
|
|
|
1656
1688
|
// real `chatWithTools`.
|
|
1657
1689
|
const llmCall = options.chatFn || chatWithTools;
|
|
1658
1690
|
|
|
1659
|
-
|
|
1691
|
+
while (budget.hasRemaining()) {
|
|
1692
|
+
budget.consume();
|
|
1660
1693
|
throwIfAborted(signal);
|
|
1694
|
+
|
|
1695
|
+
// Emit progressive warnings (once per level)
|
|
1696
|
+
const level = budget.warningLevel();
|
|
1697
|
+
if (
|
|
1698
|
+
level === WarningLevel.WARNING &&
|
|
1699
|
+
!budget.hasWarned(WarningLevel.WARNING)
|
|
1700
|
+
) {
|
|
1701
|
+
budget.recordWarning(WarningLevel.WARNING);
|
|
1702
|
+
yield {
|
|
1703
|
+
type: "iteration-warning",
|
|
1704
|
+
level,
|
|
1705
|
+
message: budget.toWarningMessage(),
|
|
1706
|
+
budget: budget.toSummary(),
|
|
1707
|
+
};
|
|
1708
|
+
} else if (
|
|
1709
|
+
level === WarningLevel.WRAPPING_UP &&
|
|
1710
|
+
!budget.hasWarned(WarningLevel.WRAPPING_UP)
|
|
1711
|
+
) {
|
|
1712
|
+
budget.recordWarning(WarningLevel.WRAPPING_UP);
|
|
1713
|
+
yield {
|
|
1714
|
+
type: "iteration-warning",
|
|
1715
|
+
level,
|
|
1716
|
+
message: budget.toWarningMessage(),
|
|
1717
|
+
budget: budget.toSummary(),
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1661
1721
|
const result = await llmCall(messages, options);
|
|
1662
1722
|
throwIfAborted(signal);
|
|
1663
1723
|
const msg = result?.message;
|
|
@@ -1705,6 +1765,13 @@ export async function* agentLoop(messages, options) {
|
|
|
1705
1765
|
|
|
1706
1766
|
throwIfAborted(signal);
|
|
1707
1767
|
|
|
1768
|
+
// Append budget warning to tool result so the LLM sees it
|
|
1769
|
+
const warningMsg = budget.toWarningMessage();
|
|
1770
|
+
const resultStr = JSON.stringify(toolResult).substring(0, 5000);
|
|
1771
|
+
const toolContent = warningMsg
|
|
1772
|
+
? `${resultStr}\n\n${warningMsg}`
|
|
1773
|
+
: resultStr;
|
|
1774
|
+
|
|
1708
1775
|
yield {
|
|
1709
1776
|
type: "tool-result",
|
|
1710
1777
|
tool: toolName,
|
|
@@ -1714,15 +1781,17 @@ export async function* agentLoop(messages, options) {
|
|
|
1714
1781
|
|
|
1715
1782
|
messages.push({
|
|
1716
1783
|
role: "tool",
|
|
1717
|
-
content:
|
|
1784
|
+
content: toolContent,
|
|
1718
1785
|
tool_call_id: call.id,
|
|
1719
1786
|
});
|
|
1720
1787
|
}
|
|
1721
1788
|
}
|
|
1722
1789
|
|
|
1790
|
+
// Budget exhausted — yield exhaustion event + final message
|
|
1791
|
+
yield { type: "iteration-budget-exhausted", budget: budget.toSummary() };
|
|
1723
1792
|
yield {
|
|
1724
1793
|
type: "response-complete",
|
|
1725
|
-
content:
|
|
1794
|
+
content: `(Iteration budget exhausted — ${budget.toSummary()})`,
|
|
1726
1795
|
};
|
|
1727
1796
|
}
|
|
1728
1797
|
|
|
@@ -1754,6 +1823,8 @@ export function formatToolArgs(name, args) {
|
|
|
1754
1823
|
return `${args.language} (${(args.code || "").length} chars)`;
|
|
1755
1824
|
case "spawn_sub_agent":
|
|
1756
1825
|
return `[${args.role}] ${(args.task || "").substring(0, 60)}`;
|
|
1826
|
+
case "search_sessions":
|
|
1827
|
+
return `"${(args.query || "").substring(0, 60)}"`;
|
|
1757
1828
|
default:
|
|
1758
1829
|
return JSON.stringify(args).substring(0, 60);
|
|
1759
1830
|
}
|
|
@@ -403,6 +403,41 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
403
403
|
tags: ["tool:spawn_sub_agent", "contract:coding-agent", "tier:extension"],
|
|
404
404
|
},
|
|
405
405
|
},
|
|
406
|
+
{
|
|
407
|
+
name: "search_sessions",
|
|
408
|
+
title: "Search Sessions",
|
|
409
|
+
kind: "search",
|
|
410
|
+
tier: "extension",
|
|
411
|
+
description:
|
|
412
|
+
"Search across all past agent session conversations using full-text search. Useful for finding prior context, decisions, or code discussed in previous sessions.",
|
|
413
|
+
inputSchema: {
|
|
414
|
+
type: "object",
|
|
415
|
+
properties: {
|
|
416
|
+
query: {
|
|
417
|
+
type: "string",
|
|
418
|
+
description: "Search query (supports natural language keywords)",
|
|
419
|
+
},
|
|
420
|
+
limit: {
|
|
421
|
+
type: "number",
|
|
422
|
+
description: "Maximum number of results to return (default: 10)",
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
required: ["query"],
|
|
426
|
+
},
|
|
427
|
+
...TOOL_POLICY_METADATA.search_sessions,
|
|
428
|
+
permissions: {
|
|
429
|
+
level: "readonly",
|
|
430
|
+
scopes: ["session:read"],
|
|
431
|
+
},
|
|
432
|
+
telemetry: {
|
|
433
|
+
category: "search",
|
|
434
|
+
tags: [
|
|
435
|
+
"tool:search_sessions",
|
|
436
|
+
"contract:coding-agent",
|
|
437
|
+
"tier:extension",
|
|
438
|
+
],
|
|
439
|
+
},
|
|
440
|
+
},
|
|
406
441
|
]);
|
|
407
442
|
|
|
408
443
|
const CODING_AGENT_MVP_TOOL_NAMES = Object.freeze(
|
|
@@ -125,6 +125,16 @@ const TOOL_POLICY_METADATA = Object.freeze({
|
|
|
125
125
|
approvalFlow: "auto",
|
|
126
126
|
isReadOnly: true,
|
|
127
127
|
},
|
|
128
|
+
search_sessions: {
|
|
129
|
+
riskLevel: RISK_LEVELS.LOW,
|
|
130
|
+
category: TOOL_CATEGORIES.SEARCH,
|
|
131
|
+
availableInPlanMode: true,
|
|
132
|
+
planModeBehavior: "allow",
|
|
133
|
+
requiresPlanApproval: false,
|
|
134
|
+
requiresConfirmation: false,
|
|
135
|
+
approvalFlow: "auto",
|
|
136
|
+
isReadOnly: true,
|
|
137
|
+
},
|
|
128
138
|
run_skill: {
|
|
129
139
|
riskLevel: RISK_LEVELS.MEDIUM,
|
|
130
140
|
category: TOOL_CATEGORIES.SKILL,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.app-root[data-v-d166fd5f]{min-height:100vh;background:var(--bg-base)}.sidebar[data-v-d166fd5f]{background:var(--bg-sidebar)!important;border-right:1px solid var(--border-color);transition:background .25s}.main-area[data-v-d166fd5f]{background:var(--bg-base)}.logo[data-v-d166fd5f]{height:52px;display:flex;align-items:center;padding:0 18px;gap:10px;border-bottom:1px solid var(--border-color);overflow:hidden;white-space:nowrap;flex-shrink:0}.logo.collapsed[data-v-d166fd5f]{padding:0;justify-content:center}.logo-icon[data-v-d166fd5f]{font-size:20px;flex-shrink:0}.logo-text[data-v-d166fd5f]{color:var(--logo-text);font-weight:700;font-size:14px;letter-spacing:.01em}.mode-banner[data-v-d166fd5f]{display:flex;align-items:center;gap:8px;padding:7px 10px;margin:8px 8px 4px;border-radius:7px;overflow:hidden}.mode-banner.project[data-v-d166fd5f]{background:#1677ff1a;border:1px solid rgba(22,119,255,.2)}.mode-banner.global[data-v-d166fd5f]{background:#722ed11a;border:1px solid rgba(114,46,209,.2)}.banner-icon[data-v-d166fd5f]{font-size:13px;flex-shrink:0;color:#1677ff}.mode-banner.global .banner-icon[data-v-d166fd5f]{color:#722ed1}.banner-info[data-v-d166fd5f]{flex:1;min-width:0}.banner-name[data-v-d166fd5f]{font-size:12px;font-weight:600;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.banner-sub[data-v-d166fd5f]{font-size:10px;color:#1677ff;margin-top:1px}.mode-banner.global .banner-name[data-v-d166fd5f]{color:#c084fc}.mode-icon-sm[data-v-d166fd5f]{display:flex;justify-content:center;padding:8px 0;font-size:14px}.side-menu[data-v-d166fd5f]{border:none!important;margin-top:2px;-webkit-user-select:none;user-select:none;background:transparent!important}.group-label[data-v-d166fd5f]{color:var(--group-title);font-size:10px;font-weight:700;letter-spacing:.12em;padding-left:6px}[data-v-d166fd5f] .ant-menu-item-group-title{padding:8px 16px 2px!important}[data-v-d166fd5f] .ant-menu-item{height:38px!important;line-height:38px!important;margin:1px 4px!important;border-radius:6px!important}.divider-sm[data-v-d166fd5f]{margin:4px 0!important}.sidebar-footer[data-v-d166fd5f]{position:absolute;bottom:48px;left:0;right:0;padding:8px 18px;display:flex;align-items:center;gap:8px;border-top:1px solid var(--border-color)}.sidebar-footer.collapsed[data-v-d166fd5f]{justify-content:center;padding:8px 0}.footer-text[data-v-d166fd5f]{color:var(--text-secondary);font-size:11px}.app-header[data-v-d166fd5f]{background:var(--bg-header)!important;padding:0 20px!important;border-bottom:1px solid var(--border-color);height:50px!important;line-height:50px!important;display:flex!important;align-items:center!important;justify-content:space-between!important;box-shadow:0 1px 4px #0000000f}.header-left[data-v-d166fd5f],.header-right[data-v-d166fd5f]{display:flex;align-items:center;gap:10px}.scope-tag[data-v-d166fd5f]{display:flex;align-items:center;gap:5px;padding:3px 10px;border-radius:5px;font-size:12px;font-weight:500}.scope-tag.project[data-v-d166fd5f]{background:#1677ff1a;color:#1677ff;border:1px solid rgba(22,119,255,.2)}.scope-tag.global[data-v-d166fd5f]{background:#722ed11a;color:#722ed1;border:1px solid rgba(114,46,209,.2)}.info-icon[data-v-d166fd5f]{opacity:.45;cursor:help;margin-left:2px}.theme-switcher[data-v-d166fd5f]{display:flex;align-items:center;gap:4px;background:var(--bg-card);border:1px solid var(--border-color);border-radius:20px;padding:3px 6px}.theme-btn[data-v-d166fd5f]{width:26px;height:26px;border:none;border-radius:50%;cursor:pointer;background:transparent;font-size:14px;line-height:1;display:flex;align-items:center;justify-content:center;transition:background .15s,transform .15s;opacity:.55}.theme-btn[data-v-d166fd5f]:hover{opacity:.9;transform:scale(1.15);background:var(--bg-card-hover)}.theme-btn.active[data-v-d166fd5f]{opacity:1;transform:scale(1.1);background:var(--bg-card-hover);outline:2px solid var(--text-secondary)}.version-tag[data-v-d166fd5f]{color:var(--text-muted);font-size:11px}.ws-tag[data-v-d166fd5f]{margin:0!important;font-size:11px}.page-content[data-v-d166fd5f]{padding:24px;overflow:auto;background:var(--bg-base);min-height:calc(100vh - 50px)}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{V as j,f as g,r as w}from"./vendor-CN0Iv_qZ.js";import{u as f}from"./ws-CU7Gvoom.js";const S="新对话",T="新 Agent",M={"assistant.delta":"response-token","assistant.final":"response-complete","assistant.message":"response-complete","tool.call.started":"tool-executing","tool.call.completed":"tool-result","tool.call.failed":"tool-result","slot.filling":"question","approval.requested":"question",error:"error"},N=j("chat",()=>{const c=g([]),p=g(null),i=w({}),a=w({}),m=w({}),d=g(!1);let q=null;function y(t){return i[t]||(i[t]=[]),i[t]}function h(t){if(!t?.id)return;const e=c.value.find(o=>o.id===t.id);if(e){Object.assign(e,t);return}c.value.unshift(t)}function A(t,e=f()){i[t]||(i[t]=[]),a[t]||(a[t]={content:"",active:!1}),e.onSession(t,o=>E(t,o))}function v(t=f()){q||(q=t.onRuntimeEvent(e=>{const o=e.payload||{},s=o.record||{};if(e.type==="session:start"){const n=o.sessionType||s.type||"chat";h({id:o.sessionId,type:n,provider:s.provider||null,model:s.model||null,projectRoot:s.projectRoot||null,status:s.status||"created",title:n==="chat"?S:T,createdAt:Date.now(),messageCount:s.messageCount??0})}else if(e.type==="session:resume"){const n=o.sessionId;if(!n)return;Array.isArray(o.history)&&(i[n]=o.history.map(r=>({role:r.role,content:r.content,timestamp:r.timestamp||Date.now()}))),a[n]||(a[n]={content:"",active:!1}),h({id:n,type:s.type||null,provider:s.provider||null,model:s.model||null,projectRoot:s.projectRoot||null,status:s.status||"resumed",messageCount:s.messageCount??(Array.isArray(o.history)?o.history.length:0)})}else if(e.type==="session:end"){const n=o.sessionId;c.value=c.value.filter(r=>r.id!==n),p.value===n&&(p.value=c.value[0]?.id||null)}}))}async function C(){const t=f();v(t),c.value=await t.listSessions()}async function D(t="chat"){const e=f();v(e);const o=await e.createSession(t);return h({id:o,type:t,title:t==="chat"?S:T,createdAt:Date.now(),messageCount:0}),A(o,e),p.value=o,o}function E(t,e){const o=y(t),s=M[e.type]||e.type,n=e.payload||{};if(s==="response-token"){a[t]||(a[t]={content:"",active:!0});const r=e.token||n.token||n.delta||n.content||"";a[t].content+=r,a[t].active=!0}else if(s==="response-complete"){const r=e.content||n.content||a[t]?.content||"";o.push({role:"assistant",content:r,timestamp:Date.now()}),a[t]&&(a[t].content="",a[t].active=!1);const l=c.value.find(u=>u.id===t);if(l&&(l.title===S||l.title===T)){const u=o.find(L=>L.role==="user");u&&(l.title=u.content.slice(0,30))}l&&(l.messageCount=o.filter(u=>u.role!=="tool").length),d.value=!1}else if(s==="tool-executing")o.push({role:"tool",tool:e.tool||n.tool||n.toolName||"unknown",input:e.input||n.input||n.args||null,status:"running",timestamp:Date.now()});else if(s==="tool-result"){const r=e.tool||n.tool||n.toolName||"unknown",l=[...o].reverse().find(u=>u.role==="tool"&&u.tool===r);l&&(l.result=e.result||n.result||n.output||null,l.status="done")}else if(s==="question")m[t]={requestId:e.requestId||n.requestId||e.id,question:e.question||n.question||n.message||"",choices:e.choices||n.choices||n.options||[]};else if(s==="error"){const r=e.message||n.message||"Unknown error";o.push({role:"assistant",content:`Error: ${r}`,timestamp:Date.now()}),d.value=!1,a[t]&&(a[t].active=!1)}}async function k(t,e){const o=f();v(o),y(t).push({role:"user",content:e,timestamp:Date.now()}),a[t]||(a[t]={content:"",active:!1}),a[t].active=!0,d.value=!0,o.sendSessionMessage(t,e)}function _(t,e){const o=f(),s=m[t];s&&(o.answerQuestion(t,s.requestId,e),delete m[t])}async function R(t){const e=f();if(v(e),p.value=t,A(t,e),!i[t]||i[t].length===0)try{await e.resumeSession(t)}catch{}}return{sessions:c,currentSessionId:p,messages:i,streaming:a,pendingQuestion:m,isLoading:d,loadSessions:C,createSession:D,sendMessage:k,answerQuestion:_,switchSession:R,getMessages:y}});export{N as u};
|