@hermespilot/link 0.2.4 → 0.2.6

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.
@@ -3724,7 +3724,7 @@ import os2 from "os";
3724
3724
  import path5 from "path";
3725
3725
 
3726
3726
  // src/constants.ts
3727
- var LINK_VERSION = "0.2.4";
3727
+ var LINK_VERSION = "0.2.6";
3728
3728
  var LINK_COMMAND = "hermeslink";
3729
3729
  var LINK_DEFAULT_PORT = 52379;
3730
3730
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -3743,7 +3743,6 @@ function resolveRuntimePaths(homeDir = resolveRuntimeHome()) {
3743
3743
  databaseFile: path5.join(homeDir, "link.db"),
3744
3744
  conversationsDir: path5.join(homeDir, "conversations"),
3745
3745
  blobsDir: path5.join(homeDir, "blobs"),
3746
- deliveryStagingDir: path5.join(homeDir, "delivery-staging"),
3747
3746
  indexesDir: path5.join(homeDir, "indexes"),
3748
3747
  logsDir: path5.join(homeDir, "logs"),
3749
3748
  runDir: path5.join(homeDir, "run"),
@@ -4707,7 +4706,8 @@ function formatErrorSuffix(error) {
4707
4706
 
4708
4707
  // src/conversations/approvals.ts
4709
4708
  import { createHash } from "crypto";
4710
- var LINK_APPROVAL_RESUME_HINT = "Hermes API Server \u5F53\u524D\u8FD8\u6CA1\u6709\u66B4\u9732\u53EF\u7531 Hermes Link \u8C03\u7528\u7684\u5BA1\u6279\u7EED\u8DD1\u63A5\u53E3\u3002\u672C\u6B21\u547D\u4EE4\u6CA1\u6709\u6267\u884C\uFF1B\u4F60\u53EF\u4EE5\u5728\u7535\u8111\u7AEF Hermes \u91CC\u5904\u7406\uFF0C\u6216\u5347\u7EA7 Hermes \u540E\u91CD\u8BD5\u3002";
4709
+ var LINK_APPROVAL_RESUME_HINT_ZH = "Hermes \u5F53\u524D\u8FD8\u672A\u63D0\u4F9B\u53EF\u8C03\u7528\u7684\u5BA1\u6279\u7EED\u8DD1\u63A5\u53E3\uFF0C\u60A8\u53EF\u4EE5\u70B9\u51FB\u201C\u59CB\u7EC8\u5141\u8BB8\u201D\uFF0C\u7136\u540E\u91CD\u65B0\u53D1\u51FA\u547D\u4EE4\uFF0C\u6216\u5728\u201CProfile \u6743\u9650\u201D\u8BBE\u7F6E\u9875\u9762\u4FEE\u6539\u5BA1\u6279\u7B56\u7565\u3002";
4710
+ var LINK_APPROVAL_RESUME_HINT_EN = "Hermes does not yet provide a callable approval-resume API. Tap \u201CAlways allow\u201D, then send the command again, or change the approval policy on the \u201CProfile permissions\u201D settings page.";
4711
4711
  function extractApprovalRequestFromToolEvent(input) {
4712
4712
  if (input.event.payloadType !== "tool.completed") {
4713
4713
  return null;
@@ -4745,7 +4745,9 @@ function extractApprovalRequestFromToolEvent(input) {
4745
4745
  choices,
4746
4746
  created_at: input.createdAt,
4747
4747
  resume_available: false,
4748
- resolution_hint: LINK_APPROVAL_RESUME_HINT
4748
+ resolution_hint: LINK_APPROVAL_RESUME_HINT_ZH,
4749
+ resolution_hint_zh: LINK_APPROVAL_RESUME_HINT_ZH,
4750
+ resolution_hint_en: LINK_APPROVAL_RESUME_HINT_EN
4749
4751
  };
4750
4752
  }
4751
4753
  function upsertMessageApproval(message, approval) {
@@ -4939,17 +4941,16 @@ function readUsage(payload) {
4939
4941
  if (!inputTokens && !outputTokens && !totalTokens) {
4940
4942
  return void 0;
4941
4943
  }
4942
- const contextTokens = explicitContextTokens ?? (contextWindow !== void 0 && inputTokens !== void 0 && inputTokens <= contextWindow ? inputTokens : void 0);
4943
4944
  return {
4944
4945
  input_tokens: inputTokens ?? 0,
4945
4946
  output_tokens: outputTokens ?? 0,
4946
4947
  total_tokens: totalTokens,
4947
- ...contextTokens !== void 0 ? { context_tokens: contextTokens } : {},
4948
+ ...explicitContextTokens !== void 0 ? { context_tokens: explicitContextTokens } : {},
4948
4949
  ...contextWindow !== void 0 ? { context_window: contextWindow } : {},
4949
- ...contextTokens !== void 0 && contextWindow ? {
4950
+ ...explicitContextTokens !== void 0 && contextWindow ? {
4950
4951
  usage_percent: Math.min(
4951
4952
  100,
4952
- Math.round(contextTokens / contextWindow * 100)
4953
+ Math.round(explicitContextTokens / contextWindow * 100)
4953
4954
  )
4954
4955
  } : {}
4955
4956
  };
@@ -5688,7 +5689,8 @@ async function buildConversationRuntimeMetadata(paths, manifest, snapshot) {
5688
5689
  total_tokens: 0
5689
5690
  };
5690
5691
  const contextWindow = current.contextWindow ?? usage.context_window ?? usageRun?.context_window;
5691
- const contextTokens = usage.context_tokens ?? (contextWindow && usage.input_tokens <= contextWindow ? usage.input_tokens : 0);
5692
+ const contextTokens = usage.context_tokens;
5693
+ const contextSource = contextTokens === void 0 ? "unknown" : "explicit";
5692
5694
  const provider = current.provider ?? usageRun?.provider;
5693
5695
  const reasoningEffort = current.reasoningEffort;
5694
5696
  return {
@@ -5705,11 +5707,14 @@ async function buildConversationRuntimeMetadata(paths, manifest, snapshot) {
5705
5707
  ...reasoningEffort ? { reasoning_effort: reasoningEffort } : {}
5706
5708
  },
5707
5709
  context: {
5708
- input_tokens: contextTokens,
5710
+ input_tokens: contextTokens ?? 0,
5709
5711
  output_tokens: usage.output_tokens,
5710
5712
  total_tokens: usage.total_tokens,
5711
5713
  ...contextWindow ? { context_window: contextWindow } : {},
5712
- ...contextWindow && contextTokens ? {
5714
+ ...contextTokens !== void 0 ? { used_tokens: contextTokens } : {},
5715
+ ...contextWindow ? { window_tokens: contextWindow } : {},
5716
+ source: contextSource,
5717
+ ...contextWindow && contextTokens !== void 0 ? {
5713
5718
  usage_percent: Math.min(
5714
5719
  100,
5715
5720
  usage.usage_percent ?? Math.round(contextTokens / contextWindow * 100)
@@ -6046,12 +6051,15 @@ var ConversationCommandHandlers = class {
6046
6051
  manifest,
6047
6052
  snapshot
6048
6053
  );
6049
- const context = runtime.context.context_window ? ` / ${runtime.context.context_window}` : "";
6050
6054
  return [
6051
6055
  `\u6D88\u606F\u6570\uFF1A${stats.message_count}`,
6052
6056
  `Agent run \u6570\uFF1A${stats.run_count}`,
6053
- `Token\uFF1A${stats.total_tokens}\uFF08\u8F93\u5165 ${stats.input_tokens}\uFF0C\u8F93\u51FA ${stats.output_tokens}\uFF09`,
6054
- `\u4E0A\u4E0B\u6587\uFF1A${runtime.context.input_tokens}${context}`,
6057
+ "",
6058
+ `\u7D2F\u8BA1\u6D88\u8017\uFF1A${stats.total_tokens} tokens`,
6059
+ `\u8F93\u5165\uFF1A${stats.input_tokens}`,
6060
+ `\u8F93\u51FA\uFF1A${stats.output_tokens}`,
6061
+ "",
6062
+ ...formatContextUsageLines(runtime),
6055
6063
  `\u6A21\u578B\uFF1A${runtime.model.id}`,
6056
6064
  `Profile\uFF1A${runtime.profile.name}`
6057
6065
  ].join("\n");
@@ -6274,6 +6282,21 @@ var ConversationCommandHandlers = class {
6274
6282
  }
6275
6283
  }
6276
6284
  };
6285
+ function formatContextUsageLines(runtime) {
6286
+ const windowTokens = runtime.context.window_tokens ?? runtime.context.context_window;
6287
+ if (runtime.context.source === "explicit") {
6288
+ const usedTokens = runtime.context.used_tokens ?? runtime.context.input_tokens;
6289
+ const percent = runtime.context.usage_percent ?? (windowTokens && windowTokens > 0 ? Math.min(100, Math.round(usedTokens / windowTokens * 100)) : void 0);
6290
+ return [
6291
+ `\u4E0A\u4E0B\u6587\uFF1A${usedTokens}${windowTokens ? ` / ${windowTokens}` : ""}${percent === void 0 ? "" : `\uFF08${percent}%\uFF09`}`,
6292
+ "\u6765\u6E90\uFF1A\u6A21\u578B\u8FD4\u56DE"
6293
+ ];
6294
+ }
6295
+ return [
6296
+ `\u4E0A\u4E0B\u6587\uFF1A\u672A\u77E5${windowTokens ? ` / ${windowTokens}` : ""}`,
6297
+ "\u539F\u56E0\uFF1A\u4E0A\u6E38\u672A\u8FD4\u56DE\u5F53\u524D\u4E0A\u4E0B\u6587\u5360\u7528"
6298
+ ];
6299
+ }
6277
6300
 
6278
6301
  // src/conversations/delivery-staging.ts
6279
6302
  import { mkdir as mkdir7, rm as rm4 } from "fs/promises";
@@ -6297,7 +6320,7 @@ function deliveryStagingRunDir(paths, conversationId, runId) {
6297
6320
  }
6298
6321
  function deliveryStagingConversationDir(paths, conversationId) {
6299
6322
  assertValidConversationId(conversationId);
6300
- return path10.join(paths.deliveryStagingDir, conversationId);
6323
+ return path10.join(paths.conversationsDir, conversationId, "delivery-staging");
6301
6324
  }
6302
6325
  function safePathSegment(value, fallback) {
6303
6326
  const safe = value.trim().replaceAll(/[^a-zA-Z0-9._-]/gu, "_");
@@ -7884,13 +7907,23 @@ function mergeAgentEventProjections(base, overlay) {
7884
7907
  function upsertAgentEventProjection(events, next) {
7885
7908
  let index = events.findIndex((event) => event.id === next.id);
7886
7909
  if (index < 0 && next.status !== "running") {
7910
+ let matchingIndex = -1;
7887
7911
  for (let candidateIndex = events.length - 1; candidateIndex >= 0; candidateIndex -= 1) {
7888
7912
  const candidate = events[candidateIndex];
7889
- if (candidate?.status === "running" && candidate.title === next.title) {
7890
- index = candidateIndex;
7891
- break;
7913
+ if (candidate?.status !== "running") {
7914
+ continue;
7915
+ }
7916
+ if (candidate.title === next.title || isGenericToolTitle(next.title)) {
7917
+ if (matchingIndex !== -1) {
7918
+ matchingIndex = -1;
7919
+ break;
7920
+ }
7921
+ matchingIndex = candidateIndex;
7892
7922
  }
7893
7923
  }
7924
+ if (matchingIndex !== -1) {
7925
+ index = matchingIndex;
7926
+ }
7894
7927
  }
7895
7928
  if (index < 0) {
7896
7929
  return [...events, next];
@@ -7904,6 +7937,7 @@ function upsertAgentEventProjection(events, next) {
7904
7937
  ...previous,
7905
7938
  ...next,
7906
7939
  id: previous.id,
7940
+ title: isGenericToolTitle(next.title) ? previous.title : next.title,
7907
7941
  subtitle: nextSubtitleIsFallback ? previous.subtitle ?? next.subtitle : next.subtitle ?? previous.subtitle,
7908
7942
  detail: next.detail ?? previous.detail,
7909
7943
  completed_at: next.completed_at ?? previous.completed_at
@@ -7912,13 +7946,16 @@ function upsertAgentEventProjection(events, next) {
7912
7946
  copy[index] = merged;
7913
7947
  return copy;
7914
7948
  }
7949
+ function isGenericToolTitle(value) {
7950
+ const normalized = value.trim().toLowerCase().replace(/[\s_-]+/gu, "");
7951
+ return normalized === "tool" || normalized === "toolcall" || value === "\u5DE5\u5177\u8C03\u7528";
7952
+ }
7915
7953
  function isToolStatusFallbackSubtitle(value, title) {
7916
7954
  if (!value) {
7917
7955
  return false;
7918
7956
  }
7919
7957
  const normalized = value.trim().toLowerCase();
7920
- const normalizedTitle = title.trim().toLowerCase();
7921
- return normalized === normalizedTitle || normalized.startsWith("\u6B63\u5728\u8C03\u7528 ") || normalized.endsWith(" \u5DF2\u5B8C\u6210") || normalized.endsWith(" \u6267\u884C\u5931\u8D25");
7958
+ return normalized.startsWith("\u6B63\u5728\u8C03\u7528 ") || normalized.endsWith(" \u5DF2\u5B8C\u6210") || normalized.endsWith(" \u6267\u884C\u5931\u8D25") || normalized === "tool" || normalized === "running";
7922
7959
  }
7923
7960
  function closeRunningAgentEvents(events, status, completedAt) {
7924
7961
  if (!events?.length) {
@@ -7929,7 +7966,7 @@ function closeRunningAgentEvents(events, status, completedAt) {
7929
7966
  );
7930
7967
  }
7931
7968
  function humanizeToolName(value) {
7932
- const normalized = value.trim().replace(/[_-]+/gu, " ").replace(/\s+/gu, " ");
7969
+ const normalized = value.trim().replace(/([a-z0-9])([A-Z])/gu, "$1 $2").replace(/[_-]+/gu, " ").replace(/\s+/gu, " ");
7933
7970
  if (!normalized) {
7934
7971
  return "\u5DE5\u5177\u8C03\u7528";
7935
7972
  }
@@ -8145,10 +8182,34 @@ var ConversationQueryCoordinator = class {
8145
8182
  isMeaningfulAgentEventProjection
8146
8183
  );
8147
8184
  const agentEvents = mergeAgentEventProjections(fromLog, persisted);
8148
- return agentEvents.length > 0 ? { ...message, agent_events: agentEvents } : message;
8185
+ return agentEvents.length > 0 ? {
8186
+ ...message,
8187
+ agent_events: agentEvents,
8188
+ blocks: hydrateAgentEventBlocks(message.blocks, agentEvents)
8189
+ } : message;
8149
8190
  });
8150
8191
  }
8151
8192
  };
8193
+ function hydrateAgentEventBlocks(blocks, agentEvents) {
8194
+ if (!blocks?.length || agentEvents.length === 0) {
8195
+ return blocks;
8196
+ }
8197
+ const agentEventById = new Map(
8198
+ agentEvents.map((event) => [event.id, event])
8199
+ );
8200
+ return blocks.map((block) => {
8201
+ if (block.type !== "agent_events" || block.events.length === 0) {
8202
+ return block;
8203
+ }
8204
+ return {
8205
+ ...block,
8206
+ events: block.events.map((event) => {
8207
+ const hydrated = agentEventById.get(event.id);
8208
+ return hydrated ? upsertAgentEventProjection([event], hydrated)[0] ?? event : event;
8209
+ })
8210
+ };
8211
+ });
8212
+ }
8152
8213
 
8153
8214
  // src/conversations/conversation-store.ts
8154
8215
  import {
@@ -9581,17 +9642,16 @@ function readChatCompletionUsage(payload) {
9581
9642
  if (input === void 0 && output === void 0 && total === void 0) {
9582
9643
  return void 0;
9583
9644
  }
9584
- const contextTokens = explicitContextTokens ?? (contextWindow !== void 0 && input !== void 0 && input <= contextWindow ? input : void 0);
9585
9645
  return {
9586
9646
  input_tokens: input ?? 0,
9587
9647
  output_tokens: output ?? 0,
9588
9648
  total_tokens: total ?? (input ?? 0) + (output ?? 0),
9589
- ...contextTokens !== void 0 ? { context_tokens: contextTokens } : {},
9649
+ ...explicitContextTokens !== void 0 ? { context_tokens: explicitContextTokens } : {},
9590
9650
  ...contextWindow !== void 0 ? { context_window: contextWindow } : {},
9591
- ...contextTokens !== void 0 && contextWindow ? {
9651
+ ...explicitContextTokens !== void 0 && contextWindow ? {
9592
9652
  usage_percent: Math.min(
9593
9653
  100,
9594
- Math.round(contextTokens / contextWindow * 100)
9654
+ Math.round(explicitContextTokens / contextWindow * 100)
9595
9655
  )
9596
9656
  } : {}
9597
9657
  };
@@ -9992,7 +10052,7 @@ ${details.join("\n")}` : emptyHermesResponseMessage();
9992
10052
  conversationId,
9993
10053
  runId,
9994
10054
  delta,
9995
- event.payload
10055
+ event
9996
10056
  );
9997
10057
  }
9998
10058
  return;
@@ -10047,6 +10107,7 @@ ${details.join("\n")}` : emptyHermesResponseMessage();
10047
10107
  assistant.agent_events ?? [],
10048
10108
  agentEvent
10049
10109
  );
10110
+ appendAgentEventBlock(assistant, agentEvent, event.created_at);
10050
10111
  assistant.updated_at = event.created_at;
10051
10112
  await this.deps.writeSnapshot(conversationId, snapshot);
10052
10113
  }
@@ -10101,7 +10162,7 @@ ${details.join("\n")}` : emptyHermesResponseMessage();
10101
10162
  collectMediaReferences(event.payload)
10102
10163
  );
10103
10164
  }
10104
- async appendAssistantDelta(conversationId, runId, delta, rawPayload) {
10165
+ async appendAssistantDelta(conversationId, runId, delta, event) {
10105
10166
  const snapshot = await this.deps.readSnapshot(conversationId);
10106
10167
  const run = snapshot.runs.find((item) => item.id === runId);
10107
10168
  if (!run) {
@@ -10145,7 +10206,10 @@ ${details.join("\n")}` : emptyHermesResponseMessage();
10145
10206
  assistant.parts.push({ type: "text", text: extracted.visibleText });
10146
10207
  }
10147
10208
  assistant.updated_at = (/* @__PURE__ */ new Date()).toISOString();
10148
- assistant.raw = { format: "hermes-run-event", payload: rawPayload };
10209
+ assistant.raw = { format: "hermes-run-event", payload: event.rawPayload };
10210
+ if (extracted.visibleText) {
10211
+ appendTextBlock(assistant, extracted.visibleText, assistant.updated_at);
10212
+ }
10149
10213
  await this.deps.writeSnapshot(conversationId, snapshot);
10150
10214
  if (extracted.visibleText) {
10151
10215
  await this.deps.appendEvent(conversationId, {
@@ -10153,7 +10217,7 @@ ${details.join("\n")}` : emptyHermesResponseMessage();
10153
10217
  message_id: assistant.id,
10154
10218
  run_id: runId,
10155
10219
  payload: { delta: extracted.visibleText },
10156
- raw: { format: "hermes-run-event", payload: rawPayload }
10220
+ raw: { format: "hermes-run-event", payload: event.rawPayload }
10157
10221
  });
10158
10222
  }
10159
10223
  await this.importMediaReferences(
@@ -10702,18 +10766,83 @@ function isVoicePart(part) {
10702
10766
  function normalizeToolName(value) {
10703
10767
  return value.trim().toLowerCase().replace(/[\s-]+/gu, "_");
10704
10768
  }
10769
+ function appendTextBlock(message, delta, updatedAt) {
10770
+ if (!delta) {
10771
+ return;
10772
+ }
10773
+ const blocks = [...message.blocks ?? []];
10774
+ const last = blocks.at(-1);
10775
+ if (last?.type === "text") {
10776
+ blocks[blocks.length - 1] = {
10777
+ ...last,
10778
+ text: `${last.text}${delta}`,
10779
+ updated_at: updatedAt
10780
+ };
10781
+ } else {
10782
+ blocks.push({
10783
+ id: `text_${blocks.length + 1}`,
10784
+ type: "text",
10785
+ text: delta,
10786
+ created_at: updatedAt,
10787
+ updated_at: updatedAt
10788
+ });
10789
+ }
10790
+ message.blocks = blocks;
10791
+ }
10792
+ function appendAgentEventBlock(message, event, updatedAt) {
10793
+ const blocks = [...message.blocks ?? []];
10794
+ const matchingIndex = blocks.findIndex((block) => {
10795
+ if (block.type !== "agent_events") {
10796
+ return false;
10797
+ }
10798
+ return upsertAgentEventProjection(block.events, event).length === block.events.length;
10799
+ });
10800
+ const targetIndex = matchingIndex >= 0 ? matchingIndex : blocks.at(-1)?.type === "agent_events" ? blocks.length - 1 : -1;
10801
+ if (targetIndex >= 0) {
10802
+ const block = blocks[targetIndex];
10803
+ if (block.type === "agent_events") {
10804
+ blocks[targetIndex] = {
10805
+ ...block,
10806
+ events: upsertAgentEventProjection(block.events, event),
10807
+ updated_at: updatedAt
10808
+ };
10809
+ }
10810
+ } else {
10811
+ blocks.push({
10812
+ id: `tools_${blocks.length + 1}`,
10813
+ type: "agent_events",
10814
+ events: [event],
10815
+ created_at: updatedAt,
10816
+ updated_at: updatedAt
10817
+ });
10818
+ }
10819
+ message.blocks = blocks;
10820
+ }
10705
10821
  function contextUsagePayload(run) {
10706
10822
  const usage = run.usage;
10707
- const contextTokens = usage?.context_tokens;
10708
- if (contextTokens === void 0) {
10823
+ if (!usage) {
10709
10824
  return null;
10710
10825
  }
10826
+ const contextTokens = usage?.context_tokens;
10711
10827
  const contextWindow = usage?.context_window ?? run.context_window;
10828
+ if (contextTokens === void 0) {
10829
+ return {
10830
+ input_tokens: 0,
10831
+ output_tokens: usage.output_tokens ?? 0,
10832
+ total_tokens: usage.total_tokens ?? 0,
10833
+ ...contextWindow ? { context_window: contextWindow } : {},
10834
+ ...contextWindow ? { window_tokens: contextWindow } : {},
10835
+ source: "unknown"
10836
+ };
10837
+ }
10712
10838
  return {
10713
10839
  input_tokens: contextTokens,
10714
10840
  output_tokens: usage?.output_tokens ?? 0,
10715
10841
  total_tokens: usage?.total_tokens ?? contextTokens,
10716
10842
  ...contextWindow ? { context_window: contextWindow } : {},
10843
+ used_tokens: contextTokens,
10844
+ ...contextWindow ? { window_tokens: contextWindow } : {},
10845
+ source: "explicit",
10717
10846
  ...usage?.usage_percent !== void 0 ? { usage_percent: usage.usage_percent } : contextWindow ? {
10718
10847
  usage_percent: Math.min(
10719
10848
  100,
package/dist/cli/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  startDaemonProcess,
27
27
  startLinkService,
28
28
  stopDaemonProcess
29
- } from "../chunk-D55DPLGZ.js";
29
+ } from "../chunk-72RM6Y4H.js";
30
30
 
31
31
  // src/cli/index.ts
32
32
  import { Command } from "commander";
@@ -9,7 +9,6 @@ interface RuntimePaths {
9
9
  databaseFile: string;
10
10
  conversationsDir: string;
11
11
  blobsDir: string;
12
- deliveryStagingDir: string;
13
12
  indexesDir: string;
14
13
  logsDir: string;
15
14
  runDir: string;
@@ -116,7 +115,10 @@ interface ConversationRuntimeMetadata {
116
115
  output_tokens: number;
117
116
  total_tokens: number;
118
117
  context_window?: number;
118
+ used_tokens?: number;
119
+ window_tokens?: number;
119
120
  usage_percent?: number;
121
+ source: 'explicit' | 'unknown';
120
122
  updated_at?: string;
121
123
  };
122
124
  }
@@ -143,17 +145,33 @@ interface LinkMessagePart {
143
145
  }
144
146
  interface LinkMessageAgentEvent {
145
147
  id: string;
148
+ kind?: 'tool' | 'thinking_delta';
146
149
  title: string;
147
150
  status: 'running' | 'completed' | 'failed' | 'info';
148
151
  created_at: string;
149
152
  subtitle?: string;
150
153
  detail?: string;
154
+ text?: string;
155
+ phase?: 'thinking' | 'final';
151
156
  completed_at?: string;
152
157
  raw?: {
153
158
  format: string;
154
159
  payload: unknown;
155
160
  };
156
161
  }
162
+ type LinkMessageBlock = {
163
+ id: string;
164
+ type: 'text';
165
+ text: string;
166
+ created_at: string;
167
+ updated_at?: string;
168
+ } | {
169
+ id: string;
170
+ type: 'agent_events';
171
+ events: LinkMessageAgentEvent[];
172
+ created_at: string;
173
+ updated_at?: string;
174
+ };
157
175
  type LinkApprovalDecisionScope = 'once' | 'session' | 'always';
158
176
  type LinkApprovalDecision = LinkApprovalDecisionScope | 'deny';
159
177
  type LinkApprovalStatus = 'pending' | 'approved' | 'denied' | 'expired';
@@ -171,6 +189,8 @@ interface LinkApprovalRequest {
171
189
  decision?: LinkApprovalDecision;
172
190
  resume_available: boolean;
173
191
  resolution_hint?: string;
192
+ resolution_hint_zh?: string;
193
+ resolution_hint_en?: string;
174
194
  config_path?: string;
175
195
  }
176
196
  interface LinkMessage {
@@ -192,6 +212,7 @@ interface LinkMessage {
192
212
  };
193
213
  parts: LinkMessagePart[];
194
214
  attachments: unknown[];
215
+ blocks?: LinkMessageBlock[];
195
216
  agent_events?: LinkMessageAgentEvent[];
196
217
  approvals?: LinkApprovalRequest[];
197
218
  hermes?: Record<string, unknown>;
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-D55DPLGZ.js";
3
+ } from "../chunk-72RM6Y4H.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",