@epoch-agent/core 0.30.0 → 1.1.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.d.ts +16 -2
- package/dist/index.js +108 -81
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -7265,13 +7265,17 @@ declare function loadPlugins(opts: PluginLoadOptions): PluginArtifacts;
|
|
|
7265
7265
|
* | 族 | 谁读它 |
|
|
7266
7266
|
* | ----------------------------------------------- | ---------------------------------------- |
|
|
7267
7267
|
* | `name` / `version` / `epochVersion` / `author` | **epoch 自己** —— 装不装得上、叫什么 |
|
|
7268
|
-
* | `displayName` / `category` / `visibility` / `changelog` |
|
|
7268
|
+
* | `displayName` / `category` / `visibility` / `changelog` | **上传那一屏的预填**(`displayName` 例外,见下) |
|
|
7269
7269
|
* | `description` / `homepage` / `keywords` / `icon` | 两边都读(`icon` 见它那一格) |
|
|
7270
7270
|
* | `dependencies` | **epoch 自己** —— 装它时要一起装谁 |
|
|
7271
7271
|
*
|
|
7272
7272
|
* 第二族 2026-09-15 加的,判据在它们自己那几格上。要紧的一条:它们是**预填**,
|
|
7273
7273
|
* 用户在那一屏上改得动,改了之后发出去的是改后的 —— 包里这一份原地不动。
|
|
7274
7274
|
*
|
|
7275
|
+
* ⚠️ **`displayName` 不只是预填**(这张表原来写的「epoch 一个字不读」早就不成立了):
|
|
7276
|
+
* 安装前那一屏预览和依赖清单读它(`install.ts`),已装那一栏在市场目录说不出名字时
|
|
7277
|
+
* 也拿它兜底(2026-10-14,runtime 的 `PluginEntryView.packageDisplayName`)。
|
|
7278
|
+
*
|
|
7275
7279
|
* 文件名放在**插件根**,不学竞品的 `.claude-plugin/` 子目录 —— 多一层目录没带来
|
|
7276
7280
|
* 任何好处,而「插件根下有没有 `epoch-plugin.json`」是判定「这是不是一个插件」
|
|
7277
7281
|
* 最省事的问法。
|
|
@@ -12332,11 +12336,15 @@ declare const EpochConfigSchema: z.ZodObject<{
|
|
|
12332
12336
|
}, z.core.$strip>>;
|
|
12333
12337
|
}, z.core.$strip>>;
|
|
12334
12338
|
brand: z.ZodOptional<z.ZodString>;
|
|
12339
|
+
brandWhenSidebarCollapsed: z.ZodOptional<z.ZodEnum<{
|
|
12340
|
+
hide: "hide";
|
|
12341
|
+
show: "show";
|
|
12342
|
+
}>>;
|
|
12335
12343
|
sidebarMenu: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
12336
12344
|
id: z.ZodString;
|
|
12337
12345
|
label: z.ZodString;
|
|
12338
12346
|
icon: z.ZodOptional<z.ZodString>;
|
|
12339
|
-
|
|
12347
|
+
primary: z.ZodOptional<z.ZodBoolean>;
|
|
12340
12348
|
}, z.core.$strip>>>;
|
|
12341
12349
|
userMenu: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
12342
12350
|
id: z.ZodString;
|
|
@@ -15527,6 +15535,12 @@ interface StoredAppearance {
|
|
|
15527
15535
|
theme?: string;
|
|
15528
15536
|
/** 语言偏好(`system | zh | en`)。缺席 = 没选过 */
|
|
15529
15537
|
lang?: string;
|
|
15538
|
+
/**
|
|
15539
|
+
* 宽屏侧栏宽度(px,2026-10-14 侧栏可拖之后)。缺席 = 没拖过。
|
|
15540
|
+
* 同上面两格:这一层**只判结构**(正整数),上下限归 protocol 的
|
|
15541
|
+
* `isAppearanceSidebarWidth`,由写入口和首屏那段脚本各自把关 —— 盘上一个越界的数是惰性的
|
|
15542
|
+
*/
|
|
15543
|
+
sidebarWidth?: number;
|
|
15530
15544
|
}
|
|
15531
15545
|
declare class AppearanceStore {
|
|
15532
15546
|
private readonly filePath;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROVIDER_TYPES, OPERATION_TYPES as OPERATION_TYPES$1, COMPLIANCE_CATEGORIES, COMPLIANCE_ACTIONS, SEARCH_PROVIDER_TYPES, CURRENCIES, LANGS, isSettingsPaneId, SETTINGS_PANE_IDS, PERMISSION_LEVELS, SHELL_KINDS, cronTimes, SCHEDULE_MAX_TIMES_PER_DAY, SCHEDULE_INTERVAL_MIN_MINUTES, SCHEDULE_INTERVAL_MAX_MINUTES, ToolExposure, MAX_OPTIONS, MIN_OPTIONS, MAX_HEADER_CHARS, MAX_QUESTIONS, isPermissionLevel, SCHEDULE_DRAFT_TOOL, isValidAgentRoleName, DEFAULT_AGENT_ROLE, isValidCommandName, RESERVED_COMMAND_NAMES, parseModelRef, isWirePluginArchiveName, systemNote, formatMoney, totalUsageTokens, NOOP_TELEMETRY, METRIC, contentToText, GEN_AI, isPromptOversize, promptTokens, apiKeyEnvVar, PROVIDER_INFOS, isProviderType, API_KEY_ENV_VARS, KEY_ACTIONS, tableOf, perAction, isKeyAction, parseSequence, RESERVED_CHORDS, chordId, sequenceId, ACTION_CONTEXTS, SEQUENCE_CONTEXTS, assertNeverPart, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_REFS, utf8ByteLength, truncateToBudget, attachSessionSurface, isContextNearlyFull, isOperationType, normalizeApproval, imagePartOmittedSummary, MAX_ATTACH_BYTES, SIMULTANEOUS_CONTEXTS, SESSION_REFERENCE_ERROR_CODES, filePartSummary, sessionPartSummary } from '@epoch-agent/protocol';
|
|
1
|
+
import { PROVIDER_TYPES, OPERATION_TYPES as OPERATION_TYPES$1, COMPLIANCE_CATEGORIES, COMPLIANCE_ACTIONS, SEARCH_PROVIDER_TYPES, CURRENCIES, LANGS, isSettingsPaneId, SETTINGS_PANE_IDS, BRAND_WHEN_SIDEBAR_COLLAPSED, PERMISSION_LEVELS, SHELL_KINDS, cronTimes, SCHEDULE_MAX_TIMES_PER_DAY, SCHEDULE_INTERVAL_MIN_MINUTES, SCHEDULE_INTERVAL_MAX_MINUTES, ToolExposure, MAX_OPTIONS, MIN_OPTIONS, MAX_HEADER_CHARS, MAX_QUESTIONS, isPermissionLevel, SCHEDULE_DRAFT_TOOL, isValidAgentRoleName, DEFAULT_AGENT_ROLE, isValidCommandName, RESERVED_COMMAND_NAMES, parseModelRef, isWirePluginArchiveName, systemNote, formatMoney, totalUsageTokens, NOOP_TELEMETRY, METRIC, contentToText, GEN_AI, isPromptOversize, promptTokens, apiKeyEnvVar, PROVIDER_INFOS, isProviderType, API_KEY_ENV_VARS, KEY_ACTIONS, tableOf, perAction, isKeyAction, parseSequence, RESERVED_CHORDS, chordId, sequenceId, ACTION_CONTEXTS, SEQUENCE_CONTEXTS, assertNeverPart, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_REFS, utf8ByteLength, truncateToBudget, attachSessionSurface, isContextNearlyFull, isOperationType, normalizeApproval, imagePartOmittedSummary, MAX_ATTACH_BYTES, SIMULTANEOUS_CONTEXTS, SESSION_REFERENCE_ERROR_CODES, filePartSummary, sessionPartSummary } from '@epoch-agent/protocol';
|
|
2
2
|
export { API_KEY_ENV_VARS, COMPLIANCE_ACTIONS, COMPLIANCE_CATEGORIES, MAX_ATTACH_BYTES, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_ATTACH_BYTES, MAX_SESSION_REFS, OPERATION_TYPES, PERMISSION_LEVELS, PLAN_OUTCOMES, PROVIDER_INFOS, PROVIDER_TYPES, ToolExposure, apiKeyEnvVar, extractAllMentions, extractMentions, extractSessionMentions, getProviderInfo, isOperationType, isPermissionLevel, isPlanOutcome, isProviderType, normalizeApproval } from '@epoch-agent/protocol';
|
|
3
3
|
import { existsSync, statSync, readdirSync, readFileSync, mkdirSync, writeFileSync, rmSync, renameSync, realpathSync, symlinkSync, cpSync, lstatSync, unlinkSync, rmdirSync, mkdtempSync, copyFileSync, openSync, writeSync, closeSync, readSync } from 'fs';
|
|
4
4
|
import { homedir, platform, tmpdir, hostname } from 'os';
|
|
@@ -1568,7 +1568,7 @@ async function* runTurnStreaming(opts) {
|
|
|
1568
1568
|
if (chunk.warnings) warnings = chunk.warnings;
|
|
1569
1569
|
break;
|
|
1570
1570
|
case "error":
|
|
1571
|
-
streamError = chunk.error
|
|
1571
|
+
streamError = chunk.error || t("provider_route.no_detail");
|
|
1572
1572
|
break;
|
|
1573
1573
|
case "tool-result":
|
|
1574
1574
|
break;
|
|
@@ -8953,14 +8953,28 @@ function describeBackgroundTask(task) {
|
|
|
8953
8953
|
}
|
|
8954
8954
|
var HEAVY_SOURCE_RATIO = 0.15;
|
|
8955
8955
|
var HEAVY_SKILL_RATIO = 0.02;
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8956
|
+
var SEG_KEY = {
|
|
8957
|
+
system: "context_breakdown.seg_system",
|
|
8958
|
+
instructions: "context_breakdown.seg_instructions",
|
|
8959
|
+
tools: "context_breakdown.seg_tools",
|
|
8960
|
+
skills: "context_breakdown.seg_skills",
|
|
8961
|
+
memory: "context_breakdown.seg_memory",
|
|
8962
|
+
history: "context_breakdown.seg_history"
|
|
8963
|
+
};
|
|
8964
|
+
var NOTE_KEY = {
|
|
8965
|
+
heavy_mcp: "context_breakdown.heavy_mcp",
|
|
8966
|
+
heavy_tools: "context_breakdown.heavy_tools",
|
|
8967
|
+
heavy_skills: "context_breakdown.heavy_skills",
|
|
8968
|
+
heavy_skills_owner: "context_breakdown.heavy_skills_owner",
|
|
8969
|
+
skills_capped: "context_breakdown.skills_capped",
|
|
8970
|
+
near_limit: "context_breakdown.near_limit"
|
|
8971
|
+
};
|
|
8972
|
+
function seg(kind, text, detail) {
|
|
8973
|
+
return segOf(kind, text ? estimateTokens(text) : 0, detail);
|
|
8960
8974
|
}
|
|
8961
|
-
function segOf(
|
|
8975
|
+
function segOf(kind, tokens, detail, extra) {
|
|
8962
8976
|
if (tokens === 0) return null;
|
|
8963
|
-
return { label, tokens, ...detail ? { detail } : {} };
|
|
8977
|
+
return { label: t(SEG_KEY[kind]), tokens, kind, ...detail ? { detail } : {}, ...extra };
|
|
8964
8978
|
}
|
|
8965
8979
|
function toolDetail(input, toolTokens) {
|
|
8966
8980
|
const bySource = /* @__PURE__ */ new Map();
|
|
@@ -8971,93 +8985,80 @@ function toolDetail(input, toolTokens) {
|
|
|
8971
8985
|
bySource.set(source, entry);
|
|
8972
8986
|
}
|
|
8973
8987
|
const mcp = [...bySource.entries()].filter(([source]) => source.startsWith("mcp:"));
|
|
8974
|
-
const
|
|
8975
|
-
const
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
}) : t("context_breakdown.tools_local_only", { local: localCount });
|
|
8979
|
-
const hints = [];
|
|
8988
|
+
const mcpCount = mcp.reduce((n, [, e]) => n + e.count, 0);
|
|
8989
|
+
const localCount = input.tools.length - mcpCount;
|
|
8990
|
+
const detail = mcp.length > 0 ? t("context_breakdown.tools_mixed", { local: localCount, mcp: mcpCount }) : t("context_breakdown.tools_local_only", { local: localCount });
|
|
8991
|
+
const notes = [];
|
|
8980
8992
|
if (input.limit > 0) {
|
|
8981
8993
|
for (const [source, entry] of mcp) {
|
|
8982
8994
|
const ratio = entry.tokens / input.limit;
|
|
8983
8995
|
if (ratio < HEAVY_SOURCE_RATIO) continue;
|
|
8984
8996
|
const server = source.slice("mcp:".length);
|
|
8985
|
-
|
|
8986
|
-
|
|
8997
|
+
notes.push({
|
|
8998
|
+
code: "heavy_mcp",
|
|
8999
|
+
params: {
|
|
8987
9000
|
server,
|
|
8988
9001
|
count: entry.count,
|
|
8989
9002
|
percent: Math.round(ratio * 100),
|
|
8990
9003
|
tokens: Math.round(entry.tokens / 100) / 10
|
|
8991
|
-
}
|
|
8992
|
-
);
|
|
9004
|
+
}
|
|
9005
|
+
});
|
|
8993
9006
|
}
|
|
8994
9007
|
}
|
|
8995
|
-
if (input.limit > 0 && toolTokens / input.limit > 0.3 &&
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
);
|
|
9008
|
+
if (input.limit > 0 && toolTokens / input.limit > 0.3 && notes.length === 0) {
|
|
9009
|
+
notes.push({
|
|
9010
|
+
code: "heavy_tools",
|
|
9011
|
+
params: { percent: Math.round(toolTokens / input.limit * 100) }
|
|
9012
|
+
});
|
|
9001
9013
|
}
|
|
9002
|
-
return { detail,
|
|
9014
|
+
return { detail, counts: { local: localCount, mcp: mcpCount }, notes };
|
|
9003
9015
|
}
|
|
9004
|
-
function
|
|
9016
|
+
function skillNotes(input, skillTokens) {
|
|
9005
9017
|
const stats = input.skillIndex;
|
|
9006
9018
|
if (!stats || stats.total === 0 || skillTokens === 0) return [];
|
|
9007
9019
|
if (stats.dropped > 0) {
|
|
9008
|
-
return [
|
|
9009
|
-
t("context_breakdown.skills_capped", {
|
|
9010
|
-
indexed: stats.indexed,
|
|
9011
|
-
dropped: stats.dropped
|
|
9012
|
-
})
|
|
9013
|
-
];
|
|
9020
|
+
return [{ code: "skills_capped", params: { indexed: stats.indexed, dropped: stats.dropped } }];
|
|
9014
9021
|
}
|
|
9015
|
-
const
|
|
9022
|
+
const notes = [];
|
|
9016
9023
|
if (input.limit > 0 && skillTokens / input.limit >= HEAVY_SKILL_RATIO) {
|
|
9017
|
-
|
|
9018
|
-
|
|
9024
|
+
notes.push({
|
|
9025
|
+
code: "heavy_skills",
|
|
9026
|
+
params: {
|
|
9019
9027
|
count: stats.indexed,
|
|
9020
9028
|
percent: Math.round(skillTokens / input.limit * 100)
|
|
9021
|
-
}
|
|
9022
|
-
);
|
|
9029
|
+
}
|
|
9030
|
+
});
|
|
9023
9031
|
if (stats.heaviest) {
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
})
|
|
9029
|
-
);
|
|
9032
|
+
notes.push({
|
|
9033
|
+
code: "heavy_skills_owner",
|
|
9034
|
+
params: { owner: stats.heaviest.owner, count: stats.heaviest.count }
|
|
9035
|
+
});
|
|
9030
9036
|
}
|
|
9031
9037
|
}
|
|
9032
|
-
return
|
|
9038
|
+
return notes;
|
|
9033
9039
|
}
|
|
9034
9040
|
function buildContextBreakdown(input) {
|
|
9035
9041
|
const toolTokens = input.tools.reduce((sum, { tool }) => sum + toolDefinitionTokens(tool), 0);
|
|
9036
|
-
const { detail,
|
|
9037
|
-
const skillsSeg = seg(
|
|
9042
|
+
const { detail, counts, notes } = toolDetail(input, toolTokens);
|
|
9043
|
+
const skillsSeg = seg("skills", input.system.skills);
|
|
9038
9044
|
const segments = [
|
|
9039
|
-
seg("system
|
|
9045
|
+
seg("system", `${input.system.identity}
|
|
9040
9046
|
${input.system.head}
|
|
9041
9047
|
${input.system.rules}`),
|
|
9042
|
-
seg(
|
|
9043
|
-
|
|
9044
|
-
input.projectBlock,
|
|
9045
|
-
t("context_breakdown.seg_instructions_detail")
|
|
9046
|
-
),
|
|
9047
|
-
segOf(t("context_breakdown.seg_tools"), toolTokens, detail),
|
|
9048
|
+
seg("instructions", input.projectBlock, t("context_breakdown.seg_instructions_detail")),
|
|
9049
|
+
segOf("tools", toolTokens, detail, { toolCounts: counts }),
|
|
9048
9050
|
skillsSeg,
|
|
9049
|
-
seg(
|
|
9050
|
-
seg(
|
|
9051
|
+
seg("memory", input.memoryBlock),
|
|
9052
|
+
seg("history", input.historyText)
|
|
9051
9053
|
].filter((s) => s !== null);
|
|
9052
|
-
|
|
9054
|
+
notes.push(...skillNotes(input, skillsSeg?.tokens ?? 0));
|
|
9053
9055
|
const used = segments.reduce((sum, s) => sum + s.tokens, 0);
|
|
9054
9056
|
const remaining = input.limit > 0 ? Math.max(0, input.limit - used) : 0;
|
|
9055
9057
|
if (input.limit > 0 && used / input.limit > 0.8) {
|
|
9056
|
-
|
|
9057
|
-
t("context_breakdown.near_limit", { percent: Math.round(used / input.limit * 100) })
|
|
9058
|
-
);
|
|
9058
|
+
notes.push({ code: "near_limit", params: { percent: Math.round(used / input.limit * 100) } });
|
|
9059
9059
|
}
|
|
9060
|
-
|
|
9060
|
+
const hints = notes.map((note) => t(NOTE_KEY[note.code], note.params));
|
|
9061
|
+
return { limit: input.limit, used, remaining, segments, hints, notes };
|
|
9061
9062
|
}
|
|
9062
9063
|
// src/cost/display.ts
|
|
9063
9064
|
var currency;
|
|
@@ -10738,8 +10739,12 @@ var NETWORK_MESSAGE_RE = /timeout|timed.?out|etimedout|econnreset|enotfound|sock
|
|
|
10738
10739
|
function describeProviderError(err) {
|
|
10739
10740
|
const chain = causeChain(err);
|
|
10740
10741
|
const head = chain[0]?.message ?? (typeof err === "string" ? err : String(err));
|
|
10741
|
-
if (chain.length === 0) return head;
|
|
10742
10742
|
const root = [...chain].reverse().find((link) => link.message !== "" && link.message !== head)?.message;
|
|
10743
|
+
if (!head.trim()) {
|
|
10744
|
+
if (root) return root;
|
|
10745
|
+
const status = extractStatus(err);
|
|
10746
|
+
return status === void 0 ? t("provider_route.no_detail") : t("provider_route.no_detail_status", { status });
|
|
10747
|
+
}
|
|
10743
10748
|
return root ? t("provider_route.root_cause", { message: head, cause: root }) : head;
|
|
10744
10749
|
}
|
|
10745
10750
|
function extractStatus(err) {
|
|
@@ -13096,7 +13101,7 @@ var SidebarMenuItemSchema = z.object({
|
|
|
13096
13101
|
icon: z.string().min(1).optional()
|
|
13097
13102
|
});
|
|
13098
13103
|
var SidebarNavItemSchema = SidebarMenuItemSchema.extend({
|
|
13099
|
-
|
|
13104
|
+
primary: z.boolean().optional()
|
|
13100
13105
|
});
|
|
13101
13106
|
var BlankCardSchema = z.object({
|
|
13102
13107
|
id: z.string().min(1),
|
|
@@ -13181,8 +13186,11 @@ var EpochConfigSchema = z.object({
|
|
|
13181
13186
|
statusLine: StatusLineSchema.optional(),
|
|
13182
13187
|
display: DisplaySchema2.optional(),
|
|
13183
13188
|
brand: z.string().min(1).optional(),
|
|
13189
|
+
brandWhenSidebarCollapsed: z.enum(BRAND_WHEN_SIDEBAR_COLLAPSED).optional(),
|
|
13184
13190
|
sidebarMenu: z.array(SidebarNavItemSchema).min(1).refine((items) => new Set(items.map((item) => item.id)).size === items.length, {
|
|
13185
13191
|
message: "sidebarMenu: id must be unique"
|
|
13192
|
+
}).refine((items) => items.filter((item) => item.primary === true).length <= 1, {
|
|
13193
|
+
message: "sidebarMenu: at most one item can be primary"
|
|
13186
13194
|
}).optional(),
|
|
13187
13195
|
userMenu: z.array(SidebarMenuItemSchema).min(1).refine((items) => new Set(items.map((item) => item.id)).size === items.length, {
|
|
13188
13196
|
message: "userMenu: id must be unique"
|
|
@@ -14876,7 +14884,10 @@ var ProviderRouter = class {
|
|
|
14876
14884
|
if (next) return next;
|
|
14877
14885
|
return {
|
|
14878
14886
|
kind: "give-up",
|
|
14879
|
-
message: recovery === "rotate_credential" ? t("provider_route.
|
|
14887
|
+
message: recovery === "rotate_credential" ? t("provider_route.root_cause", {
|
|
14888
|
+
message: t("provider_route.credential_rejected"),
|
|
14889
|
+
cause: message
|
|
14890
|
+
}) : message,
|
|
14880
14891
|
code
|
|
14881
14892
|
};
|
|
14882
14893
|
}
|
|
@@ -17589,21 +17600,32 @@ var SessionDB = class {
|
|
|
17589
17600
|
search(input) {
|
|
17590
17601
|
const limit = input.limit ?? 5;
|
|
17591
17602
|
const scope = input.scope ?? "all";
|
|
17592
|
-
if (scope === "title") {
|
|
17593
|
-
|
|
17594
|
-
|
|
17595
|
-
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
|
|
17603
|
-
|
|
17604
|
-
|
|
17605
|
-
const
|
|
17606
|
-
|
|
17603
|
+
if (scope === "title") return { results: this.searchTitles(input.query, limit) };
|
|
17604
|
+
const content = this.searchContent(input.query, limit);
|
|
17605
|
+
if (scope === "content") return { results: content };
|
|
17606
|
+
const titles = this.searchTitles(input.query, limit);
|
|
17607
|
+
const seen = new Set(titles.map((r) => r.session.id));
|
|
17608
|
+
return {
|
|
17609
|
+
results: [...titles, ...content.filter((r) => !seen.has(r.session.id))].slice(0, limit)
|
|
17610
|
+
};
|
|
17611
|
+
}
|
|
17612
|
+
searchTitles(query, limit) {
|
|
17613
|
+
const needle = query.trim();
|
|
17614
|
+
if (!needle) return [];
|
|
17615
|
+
const like = "%" + needle.replace(/[\\%_]/g, "\\$&") + "%";
|
|
17616
|
+
const rows = this.db.prepare(
|
|
17617
|
+
`SELECT * FROM sessions WHERE archived = 0 AND title LIKE @q ESCAPE '\\'
|
|
17618
|
+
ORDER BY started_at DESC LIMIT @limit`
|
|
17619
|
+
).all({ q: like, limit });
|
|
17620
|
+
return rows.map((r) => ({
|
|
17621
|
+
session: this.rowToMeta(r),
|
|
17622
|
+
matches: [{ messageIndex: -1, snippet: r["title"] ?? "", score: 1 }],
|
|
17623
|
+
score: 1
|
|
17624
|
+
}));
|
|
17625
|
+
}
|
|
17626
|
+
searchContent(query, limit) {
|
|
17627
|
+
const safeQuery = sanitizeFtsQuery(query);
|
|
17628
|
+
if (!safeQuery) return [];
|
|
17607
17629
|
const ftsQuery = buildFtsMatchQuery(safeQuery);
|
|
17608
17630
|
const ftsRows = this.db.prepare(
|
|
17609
17631
|
`
|
|
@@ -17650,7 +17672,7 @@ var SessionDB = class {
|
|
|
17650
17672
|
score: 1
|
|
17651
17673
|
});
|
|
17652
17674
|
}
|
|
17653
|
-
return
|
|
17675
|
+
return results2;
|
|
17654
17676
|
}
|
|
17655
17677
|
const seen = /* @__PURE__ */ new Set();
|
|
17656
17678
|
const results = [];
|
|
@@ -17671,7 +17693,7 @@ var SessionDB = class {
|
|
|
17671
17693
|
score: 1
|
|
17672
17694
|
});
|
|
17673
17695
|
}
|
|
17674
|
-
return
|
|
17696
|
+
return results;
|
|
17675
17697
|
}
|
|
17676
17698
|
pruneCandidates(input) {
|
|
17677
17699
|
const clauses = ["ended_at IS NOT NULL", "updated_at < @cutoff", "ended_at < @cutoff"];
|
|
@@ -19084,6 +19106,7 @@ function isLastOpenSession(value) {
|
|
|
19084
19106
|
const v = value;
|
|
19085
19107
|
return typeof v["root"] === "string" && v["root"].length > 0 && typeof v["sessionId"] === "string" && v["sessionId"].length > 0 && typeof v["at"] === "number";
|
|
19086
19108
|
}
|
|
19109
|
+
var isWidthShaped = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
19087
19110
|
var FILE_VERSION4 = 1;
|
|
19088
19111
|
function describe9(err) {
|
|
19089
19112
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -19106,7 +19129,10 @@ var AppearanceStore = class {
|
|
|
19106
19129
|
const value = patch[key];
|
|
19107
19130
|
if (typeof value === "string" && value.length > 0) next[key] = value;
|
|
19108
19131
|
}
|
|
19109
|
-
if (
|
|
19132
|
+
if (isWidthShaped(patch.sidebarWidth)) next.sidebarWidth = patch.sidebarWidth;
|
|
19133
|
+
if (next.theme === this.prefs.theme && next.lang === this.prefs.lang && next.sidebarWidth === this.prefs.sidebarWidth) {
|
|
19134
|
+
return;
|
|
19135
|
+
}
|
|
19110
19136
|
this.prefs = next;
|
|
19111
19137
|
this.save();
|
|
19112
19138
|
}
|
|
@@ -19130,6 +19156,7 @@ var AppearanceStore = class {
|
|
|
19130
19156
|
if (file.version !== FILE_VERSION4) return;
|
|
19131
19157
|
if (typeof file.theme === "string" && file.theme.length > 0) this.prefs.theme = file.theme;
|
|
19132
19158
|
if (typeof file.lang === "string" && file.lang.length > 0) this.prefs.lang = file.lang;
|
|
19159
|
+
if (isWidthShaped(file.sidebarWidth)) this.prefs.sidebarWidth = file.sidebarWidth;
|
|
19133
19160
|
}
|
|
19134
19161
|
save() {
|
|
19135
19162
|
const body2 = JSON.stringify(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epoch-agent/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "epoch-agent 核心引擎:ReAct 循环、Provider 路由、工具调度、记忆管理",
|
|
6
6
|
"repository": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"gpt-tokenizer": "^3.4.0",
|
|
28
28
|
"js-yaml": "^5.2.3",
|
|
29
29
|
"zod": "^4.4.3",
|
|
30
|
-
"@epoch-agent/infra": "
|
|
31
|
-
"@epoch-agent/protocol": "
|
|
30
|
+
"@epoch-agent/infra": "1.1.0",
|
|
31
|
+
"@epoch-agent/protocol": "1.1.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@ai-sdk/alibaba": "^2.0.59",
|