@axiom-lattice/client-sdk 4.4.2 → 4.5.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.mjs CHANGED
@@ -2175,6 +2175,36 @@ var AbstractClient = class {
2175
2175
  return response.data.records;
2176
2176
  }
2177
2177
  };
2178
+ /**
2179
+ * MCP Apps namespace for resolving UI resources and proxying allow-listed
2180
+ * JSON-RPC calls to the owning MCP server.
2181
+ */
2182
+ this.mcpApps = {
2183
+ /**
2184
+ * Resolve a UI resource for an MCP App ref.
2185
+ * @param ref - Parsed UI ref from the `mcp_app` content fence.
2186
+ * @returns The resolved resource plus its ready-to-use CSP policy string.
2187
+ */
2188
+ getResource: async (ref) => {
2189
+ return await this.makeRequest(
2190
+ "/api/mcp-apps/resource",
2191
+ { method: "POST", body: { ref } }
2192
+ );
2193
+ },
2194
+ /**
2195
+ * Proxy an allow-listed JSON-RPC method for an MCP App ref.
2196
+ * @param ref - Parsed UI ref from the `mcp_app` content fence.
2197
+ * @param method - JSON-RPC method (`tools/call`, `tools/list`, `resources/read`).
2198
+ * @param params - JSON-RPC params forwarded to the backend.
2199
+ * @returns The raw backend result.
2200
+ */
2201
+ rpc: async (ref, method, params) => {
2202
+ return await this.makeRequest("/api/mcp-apps/rpc", {
2203
+ method: "POST",
2204
+ body: { ref, method, params }
2205
+ });
2206
+ }
2207
+ };
2178
2208
  /**
2179
2209
  * @deprecated Use {@link open} / `/api/keys`; kept as a compatibility alias.
2180
2210
  */
@@ -5036,6 +5066,109 @@ var WorkspaceClient = class {
5036
5066
 
5037
5067
  // src/ChunkMessageMerger.ts
5038
5068
  import { parse } from "best-effort-json-parser";
5069
+
5070
+ // src/toolResultNormalizer.ts
5071
+ var isObj = (v) => typeof v === "object" && v !== null;
5072
+ var TEXT_BLOCK_TYPES = /* @__PURE__ */ new Set(["text"]);
5073
+ var ARTIFACT_SENTINEL_TYPES = /* @__PURE__ */ new Set(["mcp_structured_content", "mcp_meta"]);
5074
+ function asBlocks(value) {
5075
+ if (Array.isArray(value))
5076
+ return value;
5077
+ if (value === void 0 || value === null)
5078
+ return [];
5079
+ return [value];
5080
+ }
5081
+ function looksLikeResource(block) {
5082
+ return typeof block.uri === "string" && ("mimeType" in block || "blob" in block || "text" in block);
5083
+ }
5084
+ function textOf(block, allowUntyped) {
5085
+ if (typeof block === "string")
5086
+ return block;
5087
+ if (!isObj(block) || typeof block.text !== "string")
5088
+ return null;
5089
+ if (block.type === "text")
5090
+ return block.text;
5091
+ if (allowUntyped && block.type === void 0 && !looksLikeResource(block))
5092
+ return block.text;
5093
+ return null;
5094
+ }
5095
+ function joinText(blocks, allowUntyped) {
5096
+ return blocks.map((block) => textOf(block, allowUntyped)).filter((t) => typeof t === "string" && t.length > 0).join("\n\n");
5097
+ }
5098
+ function structuredFromContent(content) {
5099
+ for (const block of asBlocks(content)) {
5100
+ if (isObj(block) && block.structuredContent !== void 0) {
5101
+ return block.structuredContent;
5102
+ }
5103
+ }
5104
+ return void 0;
5105
+ }
5106
+ function structuredFromArtifact(artifact) {
5107
+ for (const item of asBlocks(artifact)) {
5108
+ if (isObj(item) && item.type === "mcp_structured_content" && "data" in item) {
5109
+ return item.data;
5110
+ }
5111
+ }
5112
+ return void 0;
5113
+ }
5114
+ function metaFromContent(content) {
5115
+ for (const block of asBlocks(content)) {
5116
+ if (isObj(block) && isObj(block.meta))
5117
+ return block.meta;
5118
+ }
5119
+ return void 0;
5120
+ }
5121
+ function metaFromArtifact(artifact) {
5122
+ for (const item of asBlocks(artifact)) {
5123
+ if (isObj(item) && item.type === "mcp_meta" && isObj(item.data))
5124
+ return item.data;
5125
+ }
5126
+ return void 0;
5127
+ }
5128
+ function isNonTextBlock(block) {
5129
+ return isObj(block) && typeof block.type === "string" && !TEXT_BLOCK_TYPES.has(block.type);
5130
+ }
5131
+ function toUiBlock(block) {
5132
+ if (isNonTextBlock(block)) {
5133
+ if (block.type === "resource" && !("resource" in block) && typeof block.uri === "string") {
5134
+ return { type: "resource", resource: block };
5135
+ }
5136
+ return block;
5137
+ }
5138
+ if (isObj(block) && block.type === void 0 && looksLikeResource(block)) {
5139
+ return { type: "resource", resource: block };
5140
+ }
5141
+ return null;
5142
+ }
5143
+ function normalizeToolResult(message) {
5144
+ const contentBlocks = asBlocks(message.content).map(toUiBlock).filter(
5145
+ (b) => b !== null && !ARTIFACT_SENTINEL_TYPES.has(b.type)
5146
+ );
5147
+ let structuredContent = structuredFromContent(message.content);
5148
+ if (structuredContent === void 0) {
5149
+ structuredContent = structuredFromArtifact(message.artifact);
5150
+ }
5151
+ let meta = metaFromContent(message.content);
5152
+ if (meta === void 0)
5153
+ meta = metaFromArtifact(message.artifact);
5154
+ const artifactBlocks = asBlocks(message.artifact).map(toUiBlock).filter(
5155
+ (b) => b !== null && !ARTIFACT_SENTINEL_TYPES.has(b.type)
5156
+ );
5157
+ const allBlocks = [...contentBlocks, ...artifactBlocks];
5158
+ let text = joinText(asBlocks(message.content), true);
5159
+ if (text.length === 0)
5160
+ text = joinText(asBlocks(message.artifact), false);
5161
+ const ui = {};
5162
+ if (structuredContent !== void 0)
5163
+ ui.structuredContent = structuredContent;
5164
+ if (meta !== void 0)
5165
+ ui.meta = meta;
5166
+ if (allBlocks.length > 0)
5167
+ ui.contentBlocks = allBlocks;
5168
+ return Object.keys(ui).length > 0 ? { text, ui } : { text };
5169
+ }
5170
+
5171
+ // src/ChunkMessageMerger.ts
5039
5172
  function createSimpleMessageMerger() {
5040
5173
  let messages = [];
5041
5174
  const messageMap = /* @__PURE__ */ new Map();
@@ -5131,14 +5264,9 @@ function createSimpleMessageMerger() {
5131
5264
  return;
5132
5265
  const role = normalizeRole(chunk.type);
5133
5266
  let message = ensureMessage(chunk.data.id, role);
5134
- const isInArray = message.role !== "tool";
5135
- if (chunk.data.content) {
5267
+ if (chunk.data.content && message.role !== "tool") {
5136
5268
  const newContent = (message.content || "") + chunk.data.content;
5137
- if (isInArray) {
5138
- message = replaceMessage(chunk.data.id, { content: newContent }) || message;
5139
- } else {
5140
- message.content = newContent;
5141
- }
5269
+ message = replaceMessage(chunk.data.id, { content: newContent }) || message;
5142
5270
  }
5143
5271
  if (message.role === "ai" && chunk.data.tool_calls && chunk.data.tool_calls.length > 0) {
5144
5272
  for (const toolCall of chunk.data.tool_calls) {
@@ -5179,10 +5307,20 @@ function createSimpleMessageMerger() {
5179
5307
  return;
5180
5308
  const messageIndex = messageMap.get(messageId);
5181
5309
  if (messageIndex !== void 0) {
5310
+ const { text, ui } = normalizeToolResult({
5311
+ content: chunk.data.content,
5312
+ artifact: chunk.data.artifact
5313
+ });
5182
5314
  const aiMessage = messages[messageIndex];
5183
5315
  const updatedToolCalls = aiMessage.tool_calls?.map((tc) => {
5184
5316
  if (tc.id === chunk.data.tool_call_id) {
5185
- return { ...tc, response: chunk.data.content, status: "success", original_tool_message_id };
5317
+ return {
5318
+ ...tc,
5319
+ response: text,
5320
+ status: "success",
5321
+ original_tool_message_id,
5322
+ ...ui ? { ui } : {}
5323
+ };
5186
5324
  }
5187
5325
  return tc;
5188
5326
  });
@@ -5246,6 +5384,7 @@ export {
5246
5384
  WorkspaceClient,
5247
5385
  WorkspaceMembersClient,
5248
5386
  WorkspaceRoomsClient,
5249
- createSimpleMessageMerger
5387
+ createSimpleMessageMerger,
5388
+ normalizeToolResult
5250
5389
  };
5251
5390
  //# sourceMappingURL=index.mjs.map