@blade-hq/agent-client 2608.0.8-beta.0 → 2608.0.8

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 CHANGED
@@ -2,9 +2,6 @@
2
2
  function isAuthCallbackMessage(value) {
3
3
  return typeof value === "object" && value !== null && value.type === "blade-agent:sdk-auth";
4
4
  }
5
- var AUTH_ERROR_HINTS = {
6
- pat_unavailable: "\u6CA1\u80FD\u4E3A\u4F60\u51C6\u5907\u8BBF\u95EE\u51ED\u636E\u3002\u8BF7\u9000\u51FA\u540E\u91CD\u65B0\u767B\u5F55 Blade \u518D\u8BD5\u4E00\u6B21\uFF1B\u82E5\u4ECD\u7136\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u3002"
7
- };
8
5
  function randomState() {
9
6
  const bytes = new Uint8Array(24);
10
7
  crypto.getRandomValues(bytes);
@@ -82,22 +79,18 @@ async function loginWithPopup(client, options = {}) {
82
79
  if (event.data.state !== state) return;
83
80
  const message = event.data;
84
81
  stopCloseWatch();
85
- const closePopup = () => {
86
- try {
87
- popup.close();
88
- } catch {
89
- }
90
- };
82
+ try {
83
+ popup.close();
84
+ } catch {
85
+ }
91
86
  if (message.status === "denied") {
92
- closePopup();
93
87
  settle(() => reject(new Error("\u4F60\u53D6\u6D88\u4E86\u6388\u6743\uFF0C\u672A\u5B8C\u6210\u767B\u5F55\u3002")));
94
88
  return;
95
89
  }
96
90
  if (message.status !== "success" || !message.code) {
97
- settle(() => reject(new Error(AUTH_ERROR_HINTS[message.error ?? ""] ?? message.error ?? "\u767B\u5F55\u5931\u8D25\uFF0C\u672A\u53D6\u5F97\u6388\u6743\u7801\u3002")));
91
+ settle(() => reject(new Error(message.error || "\u767B\u5F55\u5931\u8D25\uFF0C\u672A\u53D6\u5F97\u6388\u6743\u7801\u3002")));
98
92
  return;
99
93
  }
100
- closePopup();
101
94
  client.json("POST", "/api/auth/sdk/token", {
102
95
  code: message.code,
103
96
  state,
@@ -181,24 +174,6 @@ var AuthResource = class {
181
174
  login(options) {
182
175
  return this.client.login(options);
183
176
  }
184
- /**
185
- * 用一次性 code 换 PAT。给**服务端**用:浏览器把 code 交给你自己的后端,
186
- * 后端换到的 PAT 不进浏览器。浏览器里直接用 `login()` 就够了。
187
- *
188
- * 服务端调用时会自己补上 `Origin` 头(浏览器会自动带,服务端不会,缺了
189
- * 后端报 `missing_request_origin`)。
190
- */
191
- exchangeCode(params) {
192
- return this.client.jsonFromInit("/api/auth/sdk/token", {
193
- method: "POST",
194
- headers: { Origin: params.clientOrigin },
195
- body: JSON.stringify({
196
- code: params.code,
197
- state: params.state,
198
- client_origin: params.clientOrigin
199
- })
200
- });
201
- }
202
177
  /** 清除 login() 存储的令牌。 */
203
178
  logoutToken() {
204
179
  this.client.logoutToken();
@@ -432,47 +407,6 @@ var ModelsResource = class {
432
407
  }
433
408
  };
434
409
 
435
- // src/schemas/session.ts
436
- import { type } from "arktype";
437
- var SessionStatus = type(
438
- "'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'"
439
- );
440
- var DEFAULT_REPLAY_SPEED = 5;
441
- var SessionInfo = type({
442
- id: "string",
443
- intent: "string",
444
- status: SessionStatus,
445
- created_at: "string",
446
- updated_at: "string",
447
- "shared?": "boolean",
448
- "memory_enabled?": "boolean",
449
- "is_persistent?": "boolean",
450
- "is_headless?": "boolean",
451
- "viewer_role?": "'owner' | 'viewer'",
452
- "template_id?": "string | null",
453
- "model?": "string | null",
454
- "enable_thinking?": "boolean | null",
455
- "solution_id?": "string | null",
456
- "solution_ref?": "unknown",
457
- "biz_role_id?": "string | null",
458
- "solution?": "unknown",
459
- "plan_summary?": "string | null",
460
- "primary_skill_id?": "string | null",
461
- // ship-attack v2:后端 engine.set_bound_skill 写入的"绑定 skill id"。
462
- // 未绑定 / 非 ship-attack session 为 null。
463
- "bound_skill_id?": "string | null",
464
- "replay_state?": "unknown",
465
- "is_pinned?": "boolean",
466
- "pinned_at?": "string | null",
467
- "is_example?": "boolean",
468
- "ports?": "unknown",
469
- "disable_tools?": "string[]",
470
- "runtime_type?": "string | null",
471
- "daemon_id?": "string | null",
472
- "workspace_path?": "string | null",
473
- "match?": "unknown"
474
- });
475
-
476
410
  // src/session/definition.ts
477
411
  var SessionSetupError = class extends Error {
478
412
  constructor(message, stage, sessionId, options) {
@@ -893,28 +827,6 @@ function sourceLoopFor(loopId, loopDescriptions) {
893
827
  if (!description) return null;
894
828
  return { loop_name: loopId, description };
895
829
  }
896
- var MAX_FINAL_ARTIFACTS = 3;
897
- function normalizeFinalArtifacts(raw) {
898
- if (!Array.isArray(raw)) return [];
899
- const artifacts = [];
900
- const seen = /* @__PURE__ */ new Set();
901
- for (const item of raw) {
902
- if (typeof item !== "object" || item === null) continue;
903
- const record = item;
904
- const target = String(record.target ?? "").trim();
905
- if (!target || seen.has(target)) continue;
906
- const isLink = /^https?:\/\//i.test(target);
907
- if (!isLink && target.split("/").includes("..")) continue;
908
- seen.add(target);
909
- artifacts.push({
910
- kind: isLink ? "link" : "file",
911
- target,
912
- label: String(record.label ?? "").trim()
913
- });
914
- if (artifacts.length === MAX_FINAL_ARTIFACTS) break;
915
- }
916
- return artifacts;
917
- }
918
830
  function normalizePostChatFollowup(data, assistantEntryId) {
919
831
  const raw = data.suggestions;
920
832
  const suggestions = [];
@@ -926,13 +838,11 @@ function normalizePostChatFollowup(data, assistantEntryId) {
926
838
  }
927
839
  }
928
840
  const recaption = String(data.recaption ?? "");
929
- const finalArtifacts = normalizeFinalArtifacts(data.final_artifacts);
930
- if (suggestions.length === 0 && !recaption && finalArtifacts.length === 0) return null;
841
+ if (suggestions.length === 0 && !recaption) return null;
931
842
  return {
932
843
  assistant_entry_id: assistantEntryId,
933
844
  recaption,
934
- suggestions: suggestions.slice(0, 3),
935
- final_artifacts: finalArtifacts
845
+ suggestions: suggestions.slice(0, 3)
936
846
  };
937
847
  }
938
848
  function normalizeChildPause(pausePayload) {
@@ -2220,16 +2130,12 @@ var SessionsResource = class {
2220
2130
  pinSession(sessionId, pinned) {
2221
2131
  return this.client.json("PATCH", `/api/sessions/${sessionId}/pin`, { pinned });
2222
2132
  }
2223
- startReplaySession(sourceSessionId, speed = DEFAULT_REPLAY_SPEED) {
2133
+ startReplaySession(sourceSessionId, speed = 5) {
2224
2134
  return this.client.json("POST", `/api/sessions/${sourceSessionId}/replay`, { speed });
2225
2135
  }
2226
2136
  updateReplaySession(sessionId, payload) {
2227
2137
  return this.client.json("PATCH", `/api/sessions/${sessionId}/replay`, payload);
2228
2138
  }
2229
- /** 查询会话能否作为回放来源;不支持时 reason 可直接展示,用来提前禁用入口。 */
2230
- getReplayPreview(sessionId) {
2231
- return this.client.json("GET", `/api/sessions/${sessionId}/replay/preview`);
2232
- }
2233
2139
  updateSharing(sessionId, shared) {
2234
2140
  return this.client.json("PATCH", `/api/sessions/${sessionId}/sharing`, { shared });
2235
2141
  }
@@ -2683,15 +2589,10 @@ function contentPreview(content, maxLen = 80) {
2683
2589
  const text = getTextContent(content).trim();
2684
2590
  return text.length > maxLen ? `${text.slice(0, maxLen)}\u2026` : text;
2685
2591
  }
2686
- function transformSlashCommand(skillName, rawInput, { local = true, installed = true } = {}) {
2592
+ function transformSlashCommand(skillName, rawInput) {
2687
2593
  const prompt = rawInput.replace(`<skill>${skillName}</skill>`, "").trim();
2688
- if (local) {
2689
- return prompt ? `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1
2594
+ return prompt ? `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1
2690
2595
  ${prompt}` : `\u8BF7\u4F7F\u7528 ${skillName} skill \u5B8C\u6210\u4EFB\u52A1`;
2691
- }
2692
- const steps = installed ? `\u8BF7\u5148\u8FD0\u884C blade hub skill use ${skillName} \u52A0\u8F7D\u6280\u80FD` : `\u8BE5\u6280\u80FD\u5C1A\u672A\u5B89\u88C5\u3002\u8BF7\u5148\u8FD0\u884C blade hub skill install ${skillName} \u5B89\u88C5\uFF0C\u518D\u8FD0\u884C blade hub skill use ${skillName} \u52A0\u8F7D`;
2693
- return prompt ? `${steps}\uFF0C\u7136\u540E\u5B8C\u6210\u4EFB\u52A1\uFF1A
2694
- ${prompt}` : `${steps}\uFF0C\u7136\u540E\u4F7F\u7528\u5B83\u5B8C\u6210\u4EFB\u52A1`;
2695
2596
  }
2696
2597
  var ATTACHMENT_TAG_RE = /\[附件:\s*([^\]]+)\](?:[ \t]*已上传到工作区路径:[ \t]*([^\r\n]+))?/g;
2697
2598
  var CONTEXT_PART_RE = /^\[上下文:\s*([^\]]+)\]\n([\s\S]*)$/;
@@ -2777,14 +2678,6 @@ function groupMessagesByLoop(messages) {
2777
2678
  }
2778
2679
 
2779
2680
  // src/session/state.ts
2780
- function toReplaySnapshot(raw) {
2781
- if (!raw || !raw.status) return null;
2782
- return {
2783
- isReplay: raw.status === "replay",
2784
- speed: raw.speed ?? 1,
2785
- sourceSessionId: raw.source_session_id ?? null
2786
- };
2787
- }
2788
2681
  function createInitialSessionState(sessionId) {
2789
2682
  return {
2790
2683
  sessionId,
@@ -2797,9 +2690,7 @@ function createInitialSessionState(sessionId) {
2797
2690
  errorMessage: null,
2798
2691
  askAnswers: {},
2799
2692
  agentLoops: {},
2800
- activeCompaction: null,
2801
- replay: null,
2802
- viewerRole: null
2693
+ activeCompaction: null
2803
2694
  };
2804
2695
  }
2805
2696
  function parseAgentDescription(argumentsJson) {
@@ -3250,11 +3141,6 @@ var AgentSession = class _AgentSession {
3250
3141
  patchFlushCancel = null;
3251
3142
  joined = false;
3252
3143
  joinPending = null;
3253
- // 回放控制请求排成一条队列。连着点"5x"再点"退出回放"时,并发发出去的两个
3254
- // 请求响应可能乱序回来,晚到的旧值会把已经退出的会话又显示成回放中;用
3255
- // 序号丢弃过期响应又会在失败时留下中间态。串行执行就没有这些情况:每个
3256
- // 响应都是当时最新的,失败也只影响自己。
3257
- replayQueue = Promise.resolve();
3258
3144
  pendingReplayMessage = null;
3259
3145
  pendingReplayMode;
3260
3146
  recentChatEndAt = 0;
@@ -3285,10 +3171,6 @@ var AgentSession = class _AgentSession {
3285
3171
  emitWithAck: async () => readonlyError(),
3286
3172
  ensureConnected: readonlyError,
3287
3173
  fetchTurns: async () => turns,
3288
- // 静态历史没有回放身份可言,给个空详情即可,不要抛错——_bootstrap
3289
- // 不会跑到这里,但保持只读语义一致。
3290
- fetchSessionInfo: async () => ({ replay_state: null }),
3291
- updateReplay: async () => readonlyError(),
3292
3174
  listDir: async () => readonlyError(),
3293
3175
  countFiles: async () => readonlyError(),
3294
3176
  downloadFile: async () => readonlyError(),
@@ -3580,13 +3462,10 @@ var AgentSession = class _AgentSession {
3580
3462
  this.joinPending = null;
3581
3463
  try {
3582
3464
  await this.ensureJoined();
3583
- await Promise.all([
3584
- this.syncTurnsFromHistory({
3585
- clearOnEmpty: true,
3586
- preserveChangesSince: turnsBeforeRejoin
3587
- }),
3588
- this.syncReplayFromSession()
3589
- ]);
3465
+ await this.syncTurnsFromHistory({
3466
+ clearOnEmpty: true,
3467
+ preserveChangesSince: turnsBeforeRejoin
3468
+ });
3590
3469
  } catch {
3591
3470
  }
3592
3471
  }
@@ -3594,40 +3473,6 @@ var AgentSession = class _AgentSession {
3594
3473
  async _bootstrap() {
3595
3474
  await this.syncTurnsFromHistory({ suppressErrors: false });
3596
3475
  await this.ensureJoined();
3597
- await this.syncReplayFromSession();
3598
- }
3599
- /** 改回放是 owner 专属(服务端 PATCH 走 _get_owned_session)。 */
3600
- get canControlReplay() {
3601
- return this.state.viewerRole !== "viewer";
3602
- }
3603
- /** 拉一次会话详情,填回放状态和只读身份;失败按非回放会话处理,不挡启动。 */
3604
- async syncReplayFromSession() {
3605
- try {
3606
- const info = await this.runtime.fetchSessionInfo(this.sessionId);
3607
- const replay = toReplaySnapshot(info.replay_state);
3608
- const viewerRole = info.viewer_role ?? null;
3609
- this.update((s) => ({ ...s, replay, viewerRole }));
3610
- } catch {
3611
- }
3612
- }
3613
- /** 调整回放倍速;不是回放会话、或只读身份时什么都不做。 */
3614
- async setReplaySpeed(speed) {
3615
- if (!this.state.replay?.isReplay || !this.canControlReplay) return;
3616
- await this.applyReplayControl({ speed });
3617
- }
3618
- /** 退出回放,之后的对话交给真实模型运行;不是回放会话、或只读身份时什么都不做。 */
3619
- async exitReplay() {
3620
- if (!this.state.replay?.isReplay || !this.canControlReplay) return;
3621
- await this.applyReplayControl({ status: "autonomous" });
3622
- }
3623
- /** 把一次回放控制请求排进队列;前一个完成后才发出,响应直接安装。 */
3624
- applyReplayControl(payload) {
3625
- const run = this.replayQueue.then(async () => {
3626
- const result = await this.runtime.updateReplay(this.sessionId, payload);
3627
- this.update((s) => ({ ...s, replay: toReplaySnapshot(result) }));
3628
- });
3629
- this.replayQueue = run.catch(() => void 0);
3630
- return run;
3631
3476
  }
3632
3477
  /** @internal */
3633
3478
  _handleTurnStart(turn) {
@@ -3707,10 +3552,6 @@ var AgentSession = class _AgentSession {
3707
3552
  if (data.status) {
3708
3553
  this.update((s) => ({ ...s, status: data.status ?? s.status }));
3709
3554
  }
3710
- if (data.replay_state !== void 0) {
3711
- const replay = toReplaySnapshot(data.replay_state);
3712
- this.update((s) => ({ ...s, replay }));
3713
- }
3714
3555
  this.emitter.emit("sessionUpdated", {
3715
3556
  intent: data.intent,
3716
3557
  status: data.status,
@@ -4160,8 +4001,6 @@ var SessionHub = class {
4160
4001
  }),
4161
4002
  ensureConnected: () => this.ensureConnected(),
4162
4003
  fetchTurns: (sessionId) => this.client.sessions.getSessionTurns(sessionId),
4163
- fetchSessionInfo: (sessionId) => this.client.sessions.getSession(sessionId),
4164
- updateReplay: (sessionId, payload) => this.client.sessions.updateReplaySession(sessionId, payload).then((result) => result.replay_state ?? null),
4165
4004
  listDir: (sessionId, dirPath) => this.client.sessions.listDir(sessionId, dirPath),
4166
4005
  countFiles: (sessionId, dirPath) => this.client.sessions.countFiles(sessionId, dirPath),
4167
4006
  downloadFile: (sessionId, filePath, downloadName) => this.client.sessions.downloadFile(sessionId, filePath, downloadName),
@@ -4383,7 +4222,7 @@ function resolveAuthToken(options) {
4383
4222
 
4384
4223
  // src/version.ts
4385
4224
  var SDK_NAME = "agent-client";
4386
- var SDK_VERSION = true ? "2608.0.8-beta.0" : "1.1.1";
4225
+ var SDK_VERSION = true ? "2608.0.8" : "1.1.1";
4387
4226
 
4388
4227
  // src/socket.ts
4389
4228
  function withSdkIdentity(auth) {
@@ -4776,6 +4615,87 @@ function parseXhrHeaders(rawHeaders) {
4776
4615
  return headers;
4777
4616
  }
4778
4617
 
4618
+ // src/platform-endpoints.ts
4619
+ var PLATFORM_SERVICE_NAMES = [
4620
+ "os",
4621
+ "hub",
4622
+ "agent",
4623
+ "oauth",
4624
+ "llmGateway",
4625
+ "gitea"
4626
+ ];
4627
+ var EMPTY_PLATFORM_ENDPOINTS = Object.freeze({
4628
+ services: Object.freeze({})
4629
+ });
4630
+ function defaultDocumentBaseUrl() {
4631
+ if (typeof document === "undefined") return void 0;
4632
+ if (document.querySelector("base[href]")) return document.baseURI;
4633
+ if (typeof location !== "undefined" && location.origin) return `${location.origin}/`;
4634
+ return document.baseURI;
4635
+ }
4636
+ function isRecord6(value) {
4637
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4638
+ }
4639
+ function normalizeServiceUrl(value) {
4640
+ if (typeof value !== "string" || !value.trim()) return null;
4641
+ if (value.includes("?") || value.includes("#")) return null;
4642
+ try {
4643
+ const url = new URL(value.trim());
4644
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null;
4645
+ if (url.username || url.password || url.search || url.hash) return null;
4646
+ return url.toString().replace(/\/$/, "");
4647
+ } catch {
4648
+ return null;
4649
+ }
4650
+ }
4651
+ function parsePlatformEndpoints(value) {
4652
+ if (!isRecord6(value) || !isRecord6(value.services)) return null;
4653
+ const services = {};
4654
+ for (const name of PLATFORM_SERVICE_NAMES) {
4655
+ if (!(name in value.services)) continue;
4656
+ const url = normalizeServiceUrl(value.services[name]);
4657
+ if (!url) return null;
4658
+ services[name] = url;
4659
+ }
4660
+ return { services };
4661
+ }
4662
+ async function loadPlatformEndpoints(options = {}) {
4663
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
4664
+ const baseUrl = options.baseUrl ?? defaultDocumentBaseUrl();
4665
+ if (!fetchImpl || !baseUrl) return EMPTY_PLATFORM_ENDPOINTS;
4666
+ const controller = new AbortController();
4667
+ const timeout = globalThis.setTimeout(() => controller.abort(), options.timeoutMs ?? 3e3);
4668
+ try {
4669
+ const response = await fetchImpl(new URL("config.json", baseUrl), {
4670
+ cache: "no-store",
4671
+ credentials: "same-origin",
4672
+ headers: { Accept: "application/json" },
4673
+ signal: controller.signal
4674
+ });
4675
+ if (!response.ok) return EMPTY_PLATFORM_ENDPOINTS;
4676
+ return parsePlatformEndpoints(await response.json()) ?? EMPTY_PLATFORM_ENDPOINTS;
4677
+ } catch {
4678
+ return EMPTY_PLATFORM_ENDPOINTS;
4679
+ } finally {
4680
+ globalThis.clearTimeout(timeout);
4681
+ }
4682
+ }
4683
+ function resolveServiceUrl(endpoints, name, path = "") {
4684
+ const baseUrl = endpoints.services[name];
4685
+ if (!baseUrl) return null;
4686
+ if (!path) return baseUrl;
4687
+ const pathReference = path.trimStart();
4688
+ if (path.includes("\\") || pathReference.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(pathReference)) {
4689
+ return null;
4690
+ }
4691
+ const base = new URL(`${baseUrl}/`);
4692
+ const target = new URL(path.replace(/^\/+/, ""), base);
4693
+ if (target.origin !== base.origin || !target.pathname.startsWith(base.pathname)) {
4694
+ return null;
4695
+ }
4696
+ return target.toString();
4697
+ }
4698
+
4779
4699
  // src/commands/protocol.ts
4780
4700
  function isCommandEnvelope(value) {
4781
4701
  if (typeof value !== "object" || value === null) return false;
@@ -4835,6 +4755,46 @@ function connectEmbedded(options) {
4835
4755
  };
4836
4756
  }
4837
4757
 
4758
+ // src/schemas/session.ts
4759
+ import { type } from "arktype";
4760
+ var SessionStatus = type(
4761
+ "'created' | 'running' | 'completed' | 'failed' | 'interrupted' | 'waiting_for_input'"
4762
+ );
4763
+ var SessionInfo = type({
4764
+ id: "string",
4765
+ intent: "string",
4766
+ status: SessionStatus,
4767
+ created_at: "string",
4768
+ updated_at: "string",
4769
+ "shared?": "boolean",
4770
+ "memory_enabled?": "boolean",
4771
+ "is_persistent?": "boolean",
4772
+ "is_headless?": "boolean",
4773
+ "viewer_role?": "'owner' | 'viewer'",
4774
+ "template_id?": "string | null",
4775
+ "model?": "string | null",
4776
+ "enable_thinking?": "boolean | null",
4777
+ "solution_id?": "string | null",
4778
+ "solution_ref?": "unknown",
4779
+ "biz_role_id?": "string | null",
4780
+ "solution?": "unknown",
4781
+ "plan_summary?": "string | null",
4782
+ "primary_skill_id?": "string | null",
4783
+ // ship-attack v2:后端 engine.set_bound_skill 写入的"绑定 skill id"。
4784
+ // 未绑定 / 非 ship-attack session 为 null。
4785
+ "bound_skill_id?": "string | null",
4786
+ "replay_state?": "unknown",
4787
+ "is_pinned?": "boolean",
4788
+ "pinned_at?": "string | null",
4789
+ "is_example?": "boolean",
4790
+ "ports?": "unknown",
4791
+ "disable_tools?": "string[]",
4792
+ "runtime_type?": "string | null",
4793
+ "daemon_id?": "string | null",
4794
+ "workspace_path?": "string | null",
4795
+ "match?": "unknown"
4796
+ });
4797
+
4838
4798
  // src/schemas/solution.ts
4839
4799
  var LayoutType = /* @__PURE__ */ ((LayoutType2) => {
4840
4800
  LayoutType2["Default"] = "default";
@@ -4866,7 +4826,7 @@ export {
4866
4826
  BladeApiError,
4867
4827
  BladeClient,
4868
4828
  ClientProjectionBuilder,
4869
- DEFAULT_REPLAY_SPEED,
4829
+ EMPTY_PLATFORM_ENDPOINTS,
4870
4830
  LayoutType,
4871
4831
  ModelsResource,
4872
4832
  SDK_NAME,
@@ -4890,8 +4850,9 @@ export {
4890
4850
  isCommandEnvelope,
4891
4851
  isHiddenInternalMessage,
4892
4852
  isInboundEnvelope,
4853
+ loadPlatformEndpoints,
4893
4854
  normalizeMessageContent,
4894
- toReplaySnapshot,
4855
+ resolveServiceUrl,
4895
4856
  transformSlashCommand
4896
4857
  };
4897
4858
  //# sourceMappingURL=index.js.map