@epoch-agent/core 2.3.0 → 2.4.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 CHANGED
@@ -1,4 +1,4 @@
1
- import { ToolProvider, EpochTool, EpochPlugin, ToolExposure, EpochSkill, HookType, EpochHook, PluginContext, QuestionRequest, QuestionAnswer, ComplianceCategory, ComplianceAction, ToolArtifactInput, ToolArtifact, TrustLevel, TrustManager as TrustManager$1, TokenUsage, EpochConfig, BudgetBreach, NoticeCode, ProviderType, EpochMessage, JsonSchema, ModelSelection, BackgroundTaskInfo, EpochToolCall, Telemetry, HookManager as HookManager$1, Lang, PermissionManager as PermissionManager$1, ApprovalRequest, ApprovalReply, AgentRoleScope, AgentRoleSource, EpochUserContent, EpochContentPart, AgentRole, PermissionLevel, PlanProposal, ScheduleRunnerSpec, ScheduleBackendKind, ScheduleTrigger, OperationType, ScheduleAllowlist, ScheduleDefinition, ScheduleRunStatus, ScheduleRun, SchedulePendingApproval, DiagnosticSink, CustomCommandDef, ModelRef, ExpandedCommand, CustomCommandSource, ContextBreakdown, WireMcpConnector, AgentEvent, SelectionContext, SetSelectionResult, ModelEntry, ReasoningState, ReasoningChoice, PermissionRuleLists, MoneyDigits, CurrencyDisplay, KeybindingTable, Diagnostic, KeybindingReport, FileOmitReason, SessionOmitReason, EpochToolResult, EpochTurnFacts, LocalizedDetail, ApprovalScope, RuleValue, Operation, ApprovalOutcome, PermissionDecision, ScheduleDraft, ScheduleWideningKind, WireAgentEvent, WireAgentEnvelope, HookEvent, LogFn, HookRegistration, HookHandler, HookContext, VerifyResult, EpochFilePart, EpochSessionPart, MentionSet, EpochImagePart, TrustExecGrant, DecidedTrustLevel, TrustScope, TrustGrant, TrustRecord } from '@epoch-agent/protocol';
1
+ import { ToolProvider, EpochTool, EpochPlugin, ToolExposure, EpochSkill, HookType, EpochHook, PluginContext, QuestionRequest, QuestionAnswer, ComplianceCategory, ComplianceAction, ToolArtifactInput, ToolArtifact, TrustLevel, TrustManager as TrustManager$1, TokenUsage, EpochConfig, BudgetBreach, NoticeCode, ProviderType, EpochMessage, JsonSchema, ModelSelection, BackgroundTaskInfo, EpochToolCall, Telemetry, HookManager as HookManager$1, Lang, PermissionManager as PermissionManager$1, ApprovalRequest, ApprovalReply, AgentRoleScope, AgentRoleSource, EpochUserContent, EpochContentPart, AgentRole, PermissionLevel, PlanProposal, ScheduleRunnerSpec, ScheduleBackendKind, ScheduleTrigger, OperationType, ScheduleAllowlist, ScheduleDefinition, ScheduleRunStatus, ScheduleRun, SchedulePendingApproval, DiagnosticSink, CustomCommandDef, ModelRef, ExpandedCommand, CustomCommandSource, ContextBreakdown, WireMcpConnector, AgentEvent, SelectionContext, SetSelectionResult, ModelEntry, ReasoningState, ReasoningChoice, PermissionRuleLists, MoneyDigits, CurrencyDisplay, KeybindingTable, Diagnostic, KeybindingReport, FileOmitReason, SessionOmitReason, EpochToolResult, EpochUserCommand, EpochTurnFacts, LocalizedDetail, ApprovalScope, RuleValue, Operation, ApprovalOutcome, PermissionDecision, ScheduleDraft, ScheduleWideningKind, WireAgentEvent, WireAgentEnvelope, HookEvent, LogFn, HookRegistration, HookHandler, HookContext, VerifyResult, EpochFilePart, EpochSessionPart, MentionSet, EpochImagePart, TrustExecGrant, DecidedTrustLevel, TrustScope, TrustGrant, TrustRecord } from '@epoch-agent/protocol';
2
2
  export { API_KEY_ENV_VARS, AgentEvent, AgentEventOf, AgentEventType, ApprovalAnswer, ApprovalOutcome, ApprovalReply, ApprovalRequest, ApprovalScope, BudgetBreach, COMPLIANCE_ACTIONS, COMPLIANCE_CATEGORIES, ComplianceAction, ComplianceCategory, DecidedTrustLevel, EpochConfig, EpochHook, EpochPlugin, EpochSkill, EpochTool, FinishReason, HookContext, HookEvent, HookHandler, HookRegistration, HookType, HookManager as IHookManager, PermissionManager as IPermissionManager, TrustManager as ITrustManager, JsonSchema, MAX_ATTACH_BYTES, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_ATTACH_BYTES, MAX_SESSION_REFS, OPERATION_TYPES, Operation, OperationType, PERMISSION_LEVELS, PLAN_OUTCOMES, PROVIDER_INFOS, PROVIDER_TYPES, PermissionDecision, PermissionLevel, PlanApprovalOutcome, PlanProposal, PluginContext, ProviderInfo, ProviderType, TokenUsage, ToolContext, ToolDefinition, ToolExposure, ToolResult, TrustExecGrant, TrustGrant, TrustLevel, TrustRecord, TrustScope, TrustTier, VerifyResult, apiKeyEnvVar, extractAllMentions, extractMentions, extractSessionMentions, getProviderInfo, isOperationType, isPermissionLevel, isPlanOutcome, isProviderType, normalizeApproval } from '@epoch-agent/protocol';
3
3
  import { IsolationBackend, SqliteDatabase, ParseIssue, ShellFlavor } from '@epoch-agent/infra';
4
4
  export { BubblewrapOptions, DangerMatch, IS_WINDOWS, IsolationBackend, IsolationOptions, LogLevel, SeatbeltOptions, WINDOWS_HIDE_FLAGS, buildBwrapArgs, buildProfile, checkDangerousCommand, checkObfuscation, createLogger, detectBackend, getDefaultShell, getPythonCommand, isInWorkspace, isReadOnlyCommand, isolate, maskApiKey, probeBubblewrap, probeSeatbelt, complianceDir as resolveComplianceDir, policiesDir as resolvePoliciesDir, setLogLevel } from '@epoch-agent/infra';
@@ -13016,7 +13016,7 @@ declare class ModelFailureTracker {
13016
13016
  *
13017
13017
  * - `design/web-ui/README.md`「8.2 决定 8」那条 ⚠️ 划掉重写,稿子
13018
13018
  * `index.html` 那枚「估算」徽标上面那段注释同改(它是同一句话的第二处)。
13019
- * - `.agents/plans/README.md`「42 划出来的底座缺口」里那一条划掉。
13019
+ * - `.epoch/plans/README.md`「42 划出来的底座缺口」里那一条划掉。
13020
13020
  *
13021
13021
  * ⚠️ **「要拿掉徽标得先换真 tokenizer」按交代的一个字没动** —— 它是
13022
13022
  * **必要条件**,而充分条件(同一份稿子 `thread.css` 里 `.est` 那条:
@@ -15563,6 +15563,16 @@ interface Message {
15563
15563
  toolResults?: EpochToolResult[];
15564
15564
  /** 多模态部件的落盘形态(图片是路径引用,不是 base64) */
15565
15565
  parts?: PersistedPart[];
15566
+ /**
15567
+ * 这一条是**按哪条自定义斜杠命令**发出来的(会话库 v15,2026-10-21)。
15568
+ *
15569
+ * 只长在 user 行上,而且和 `content` **互不替代**:`content` 是展开之后的正文
15570
+ * (模型看到的那份),这一格是「这行字是怎么来的」。界面上按它画成
15571
+ * 一行 `/命令名 参数`,不再把那一大段正文冒充成用户说的话。
15572
+ *
15573
+ * 缺席 = 普通消息,或者这条是 v15 之前的库写的(那时候就是没有这个信息)。
15574
+ */
15575
+ command?: EpochUserCommand;
15566
15576
  /**
15567
15577
  * 一轮跑完那笔账(`turn_facts` 列,v6)。
15568
15578
  *
@@ -15646,6 +15656,13 @@ interface AppendMessageInput {
15646
15656
  toolResults?: EpochToolResult[];
15647
15657
  /** 已经落过盘的部件。别把带 base64 的 `EpochContentPart` 直接传进来 */
15648
15658
  parts?: PersistedPart[];
15659
+ /**
15660
+ * 这条用户消息是按哪条命令发出来的(2026-10-21)。**只该传给 user 行**。
15661
+ *
15662
+ * 它跟 `content` 一起落盘、一起回放,但两者读者不同:`content` 喂模型,
15663
+ * 这一格喂界面。判据全文在 `EpochUserCommand` 上。
15664
+ */
15665
+ command?: EpochUserCommand;
15649
15666
  /** 一轮的账。**只该传给这一轮最后一条 assistant 行**,见 {@link Message.turnFacts} */
15650
15667
  turnFacts?: EpochTurnFacts;
15651
15668
  toolName?: string;
package/dist/index.js CHANGED
@@ -6083,6 +6083,7 @@ var CommandFrontmatterSchema = z.object({
6083
6083
  });
6084
6084
  var FRONTMATTER_KEYS3 = Object.keys(CommandFrontmatterSchema.shape);
6085
6085
  var MAX_POSITIONAL = 9;
6086
+ var ARG_PREVIEW_MAX = 120;
6086
6087
  var UTILITY_KEYWORD = "utility";
6087
6088
  function loadCommands(files, source, prefix) {
6088
6089
  const commands = [];
@@ -6188,6 +6189,14 @@ function expandCommand(def, args, opts = {}) {
6188
6189
  })
6189
6190
  );
6190
6191
  }
6192
+ if (trimmed !== "" && used.size === 0 && !def.prompt.includes("$ARGUMENTS")) {
6193
+ warnings.push(
6194
+ t("custom_command.unused_args", {
6195
+ name: def.name,
6196
+ args: trimmed.length > ARG_PREVIEW_MAX ? `${trimmed.slice(0, ARG_PREVIEW_MAX)}\u2026` : trimmed
6197
+ })
6198
+ );
6199
+ }
6191
6200
  const model = resolveCommandModel(def, opts, warnings);
6192
6201
  return {
6193
6202
  prompt: out,
@@ -17735,6 +17744,28 @@ function parseTurnFacts(json) {
17735
17744
  function encodeTurnFacts(facts) {
17736
17745
  return facts ? JSON.stringify(facts) : null;
17737
17746
  }
17747
+ function parseUserCommand(json) {
17748
+ if (typeof json !== "string" || json.length === 0) return void 0;
17749
+ let raw;
17750
+ try {
17751
+ raw = JSON.parse(json);
17752
+ } catch {
17753
+ return void 0;
17754
+ }
17755
+ if (!isRecord4(raw)) return void 0;
17756
+ const name = str3(raw["name"]);
17757
+ if (!name) return void 0;
17758
+ const displayName = str3(raw["displayName"]);
17759
+ const args = str3(raw["args"]);
17760
+ return {
17761
+ name,
17762
+ ...displayName ? { displayName } : {},
17763
+ ...args ? { args } : {}
17764
+ };
17765
+ }
17766
+ function encodeUserCommand(command) {
17767
+ return command ? JSON.stringify(command) : null;
17768
+ }
17738
17769
  // src/session/db.ts
17739
17770
  var NS3 = "session";
17740
17771
  var log2 = createLogger("session-db");
@@ -18030,7 +18061,7 @@ var FTS_EXTERNAL_SCHEMA = `
18030
18061
  var FTS_EXTERNAL_MIGRATIONS = [
18031
18062
  {
18032
18063
  id: "fts-external-content",
18033
- version: 14,
18064
+ version: 16,
18034
18065
  description: "\u4E24\u5F20 FTS \u8868\u6539\u6210\u5916\u90E8\u5185\u5BB9\u8868\uFF08\u6B63\u6587\u4E0D\u518D\u5B58\u4E09\u4EFD\uFF0C2026-08-21\uFF09",
18035
18066
  up: (db) => {
18036
18067
  db.exec(FTS_EXTERNAL_SCHEMA);
@@ -18042,6 +18073,14 @@ var FTS_EXTERNAL_MIGRATIONS = [
18042
18073
  db.prepare(`INSERT INTO ${table}(${table}, rank) VALUES('integrity-check', 1)`).run();
18043
18074
  }
18044
18075
  }
18076
+ },
18077
+ {
18078
+ id: "messages-command",
18079
+ version: 15,
18080
+ description: "\u6D88\u606F\u8868\u52A0 command \u4E00\u5217\uFF08\u8FD9\u6761\u7528\u6237\u6D88\u606F\u662F\u6309\u54EA\u6761\u659C\u6760\u547D\u4EE4\u53D1\u7684\uFF0C2026-10-21\uFF09",
18081
+ up: (db) => {
18082
+ db.exec(`ALTER TABLE messages ADD COLUMN command TEXT`);
18083
+ }
18045
18084
  }
18046
18085
  ];
18047
18086
  var SessionDB = class {
@@ -18235,8 +18274,8 @@ var SessionDB = class {
18235
18274
  insertMessage(msg) {
18236
18275
  const info = this.db.prepare(
18237
18276
  `
18238
- INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
18239
- VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, 1, 0, 0)
18277
+ INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
18278
+ VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, 1, 0, 0)
18240
18279
  `
18241
18280
  ).run({
18242
18281
  ...msg,
@@ -18244,6 +18283,7 @@ var SessionDB = class {
18244
18283
  toolCalls: encodeColumn(msg.toolCalls),
18245
18284
  toolResults: encodeColumn(msg.toolResults),
18246
18285
  parts: encodeColumn(msg.parts),
18286
+ command: encodeUserCommand(msg.command),
18247
18287
  toolName: msg.toolName ?? null,
18248
18288
  tokenCount: msg.tokenCount ?? null,
18249
18289
  finishReason: msg.finishReason ?? null,
@@ -18509,8 +18549,8 @@ var SessionDB = class {
18509
18549
  forkMessages(fromSessionId, toSessionId, upToIndex) {
18510
18550
  const messages = this.db.prepare("SELECT * FROM messages WHERE session_id = ? AND id <= ? ORDER BY timestamp ASC").all(fromSessionId, upToIndex);
18511
18551
  const stmt = this.db.prepare(`
18512
- INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
18513
- VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, @active, @compacted, @observed)
18552
+ INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
18553
+ VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, @active, @compacted, @observed)
18514
18554
  `);
18515
18555
  for (const m of messages) {
18516
18556
  const { id: _id, ...rest } = m;
@@ -18522,6 +18562,7 @@ var SessionDB = class {
18522
18562
  toolCalls: rest["tool_calls"] ?? null,
18523
18563
  toolResults: rest["tool_results"] ?? null,
18524
18564
  parts: rest["parts"] ?? null,
18565
+ command: rest["command"] ?? null,
18525
18566
  toolName: rest["tool_name"] ?? null,
18526
18567
  timestamp: rest["timestamp"] ?? Date.now(),
18527
18568
  tokenCount: rest["token_count"] ?? null,
@@ -18603,6 +18644,7 @@ var SessionDB = class {
18603
18644
  toolCalls: parseToolCalls(row["tool_calls"]),
18604
18645
  toolResults: parseToolResults(row["tool_results"]),
18605
18646
  parts: parseParts(row["parts"]),
18647
+ command: parseUserCommand(row["command"]),
18606
18648
  turnFacts: parseTurnFacts(row["turn_facts"]),
18607
18649
  toolName: row["tool_name"],
18608
18650
  timestamp: row["timestamp"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epoch-agent/core",
3
- "version": "2.3.0",
3
+ "version": "2.4.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": "2.3.0",
31
- "@epoch-agent/protocol": "2.3.0"
30
+ "@epoch-agent/infra": "2.4.0",
31
+ "@epoch-agent/protocol": "2.4.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@ai-sdk/alibaba": "^2.0.69",