@axiom-lattice/core 2.1.77 → 2.1.79

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
@@ -1665,6 +1665,7 @@ var InMemoryProjectStore = class {
1665
1665
  workspaceId,
1666
1666
  name: data.name,
1667
1667
  description: data.description,
1668
+ config: data.config,
1668
1669
  createdAt: now,
1669
1670
  updatedAt: now
1670
1671
  };
@@ -1672,6 +1673,13 @@ var InMemoryProjectStore = class {
1672
1673
  this.projects.set(key, project);
1673
1674
  return project;
1674
1675
  }
1676
+ /**
1677
+ * Update an existing project
1678
+ *
1679
+ * @remarks
1680
+ * - The `config` field uses **replace** semantics: if provided, it completely
1681
+ * overwrites the existing config. To preserve the current config, omit this field.
1682
+ */
1675
1683
  async updateProject(tenantId, id, updates) {
1676
1684
  const key = this.getKey(tenantId, id);
1677
1685
  const existing = this.projects.get(key);
@@ -2679,6 +2687,87 @@ var InMemoryBindingStore = class {
2679
2687
  }
2680
2688
  };
2681
2689
 
2690
+ // src/store_lattice/InMemoryA2AApiKeyStore.ts
2691
+ import { randomUUID as randomUUID2 } from "crypto";
2692
+ function generateApiKey() {
2693
+ return `a2a_${randomUUID2().replace(/-/g, "")}`;
2694
+ }
2695
+ var InMemoryA2AApiKeyStore = class {
2696
+ constructor() {
2697
+ this.keys = /* @__PURE__ */ new Map();
2698
+ }
2699
+ async findByKey(key) {
2700
+ for (const record of this.keys.values()) {
2701
+ if (record.key === key && record.enabled) return record;
2702
+ }
2703
+ return null;
2704
+ }
2705
+ async list(params) {
2706
+ let records = Array.from(this.keys.values());
2707
+ if (params.tenantId) {
2708
+ records = records.filter((r) => r.tenantId === params.tenantId);
2709
+ }
2710
+ const offset = params.offset || 0;
2711
+ const limit = params.limit;
2712
+ records = records.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2713
+ return limit ? records.slice(offset, offset + limit) : records.slice(offset);
2714
+ }
2715
+ async create(input) {
2716
+ const now = /* @__PURE__ */ new Date();
2717
+ const record = {
2718
+ id: randomUUID2(),
2719
+ key: generateApiKey(),
2720
+ tenantId: input.tenantId,
2721
+ projectId: input.projectId,
2722
+ workspaceId: input.workspaceId,
2723
+ label: input.label,
2724
+ enabled: true,
2725
+ createdAt: now,
2726
+ updatedAt: now
2727
+ };
2728
+ this.keys.set(record.id, record);
2729
+ return record;
2730
+ }
2731
+ async disable(id) {
2732
+ const record = this.keys.get(id);
2733
+ if (!record) throw new Error(`A2A API key not found: ${id}`);
2734
+ const updated = { ...record, enabled: false, updatedAt: /* @__PURE__ */ new Date() };
2735
+ this.keys.set(id, updated);
2736
+ return updated;
2737
+ }
2738
+ async enable(id) {
2739
+ const record = this.keys.get(id);
2740
+ if (!record) throw new Error(`A2A API key not found: ${id}`);
2741
+ const updated = { ...record, enabled: true, updatedAt: /* @__PURE__ */ new Date() };
2742
+ this.keys.set(id, updated);
2743
+ return updated;
2744
+ }
2745
+ async rotate(id) {
2746
+ const record = this.keys.get(id);
2747
+ if (!record) throw new Error(`A2A API key not found: ${id}`);
2748
+ const updated = { ...record, key: generateApiKey(), updatedAt: /* @__PURE__ */ new Date() };
2749
+ this.keys.set(id, updated);
2750
+ return updated;
2751
+ }
2752
+ async delete(id) {
2753
+ this.keys.delete(id);
2754
+ }
2755
+ async loadIntoMap() {
2756
+ const map = /* @__PURE__ */ new Map();
2757
+ for (const record of this.keys.values()) {
2758
+ if (record.enabled) {
2759
+ map.set(record.key, {
2760
+ key: record.key,
2761
+ tenantId: record.tenantId,
2762
+ projectId: record.projectId,
2763
+ workspaceId: record.workspaceId
2764
+ });
2765
+ }
2766
+ }
2767
+ return map;
2768
+ }
2769
+ };
2770
+
2682
2771
  // src/store_lattice/StoreLatticeManager.ts
2683
2772
  var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
2684
2773
  /**
@@ -2853,6 +2942,12 @@ storeLatticeManager.registerLattice(
2853
2942
  "channelBinding",
2854
2943
  defaultChannelBindingStore
2855
2944
  );
2945
+ var defaultA2AApiKeyStore = new InMemoryA2AApiKeyStore();
2946
+ storeLatticeManager.registerLattice(
2947
+ "default",
2948
+ "a2aApiKey",
2949
+ defaultA2AApiKeyStore
2950
+ );
2856
2951
 
2857
2952
  // src/tool_lattice/manage_binding/index.ts
2858
2953
  function getInstallationStore() {
@@ -6949,6 +7044,7 @@ import {
6949
7044
  isDeepAgentConfig,
6950
7045
  isProcessingAgentConfig,
6951
7046
  isTeamAgentConfig,
7047
+ isA2ARemoteAgentConfig,
6952
7048
  getToolsFromConfig,
6953
7049
  getSubAgentsFromConfig
6954
7050
  } from "@axiom-lattice/protocols";
@@ -18093,6 +18189,227 @@ var ProcessingAgentGraphBuilder = class {
18093
18189
  }
18094
18190
  };
18095
18191
 
18192
+ // src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
18193
+ import { StateGraph as StateGraph2, MessagesAnnotation } from "@langchain/langgraph";
18194
+ import { AIMessage as AIMessage4 } from "@langchain/core/messages";
18195
+
18196
+ // src/services/a2a-client.ts
18197
+ import { v4 as v42 } from "uuid";
18198
+ var A2ARemoteError = class extends Error {
18199
+ constructor(message, statusCode, body) {
18200
+ super(message);
18201
+ this.statusCode = statusCode;
18202
+ this.body = body;
18203
+ this.name = "A2ARemoteError";
18204
+ }
18205
+ };
18206
+ var A2ARemoteClient = class {
18207
+ constructor(config) {
18208
+ this.config = config;
18209
+ this.jsonRpcUrl = null;
18210
+ this.card = null;
18211
+ }
18212
+ // ── Resolution ───────────────────────────────────────────────────────────
18213
+ /**
18214
+ * Fetch the agent card and resolve the JSON-RPC endpoint.
18215
+ */
18216
+ async resolve() {
18217
+ if (this.card) return this.card;
18218
+ const resp = await fetch(this.config.agentCardUrl, {
18219
+ signal: AbortSignal.timeout(this.config.timeout ?? 3e4)
18220
+ });
18221
+ if (!resp.ok) {
18222
+ throw new A2ARemoteError(
18223
+ `Failed to fetch agent card: HTTP ${resp.status}`,
18224
+ resp.status
18225
+ );
18226
+ }
18227
+ this.card = await resp.json();
18228
+ const card = this.card;
18229
+ const jsonRpc = card.additionalInterfaces?.find(
18230
+ (i) => i.transport === "JSONRPC"
18231
+ );
18232
+ this.jsonRpcUrl = jsonRpc?.url ?? card.url;
18233
+ return this.card;
18234
+ }
18235
+ // ── Execute ──────────────────────────────────────────────────────────────
18236
+ /**
18237
+ * Send a text prompt to the remote A2A agent and return the response.
18238
+ *
18239
+ * Supports SSE streaming (parses status-update events) and falls back
18240
+ * to polling the task status for non-streaming agents.
18241
+ */
18242
+ async sendMessage(text) {
18243
+ await this.resolve();
18244
+ const taskId = v42();
18245
+ const body = JSON.stringify({
18246
+ jsonrpc: "2.0",
18247
+ method: "tasks/send",
18248
+ params: {
18249
+ id: taskId,
18250
+ message: {
18251
+ role: "user",
18252
+ parts: [{ kind: "text", text }]
18253
+ }
18254
+ },
18255
+ id: taskId
18256
+ });
18257
+ const headers = {
18258
+ "Content-Type": "application/json",
18259
+ "Accept": "text/event-stream"
18260
+ };
18261
+ if (this.config.apiKey) {
18262
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
18263
+ }
18264
+ const resp = await fetch(this.jsonRpcUrl, {
18265
+ method: "POST",
18266
+ headers,
18267
+ body,
18268
+ signal: AbortSignal.timeout(this.config.timeout ?? 3e5)
18269
+ });
18270
+ if (!resp.ok) {
18271
+ const text2 = await resp.text().catch(() => "");
18272
+ throw new A2ARemoteError(
18273
+ `A2A request failed: HTTP ${resp.status}`,
18274
+ resp.status,
18275
+ text2
18276
+ );
18277
+ }
18278
+ const contentType = resp.headers.get("content-type") ?? "";
18279
+ if (contentType.includes("text/event-stream")) {
18280
+ return this.parseSSE(resp);
18281
+ }
18282
+ const json = await resp.json();
18283
+ return this.extractArtifactText(json);
18284
+ }
18285
+ // ── SSE Parsing ──────────────────────────────────────────────────────────
18286
+ async parseSSE(resp) {
18287
+ if (!resp.body) {
18288
+ throw new A2ARemoteError("Empty response body");
18289
+ }
18290
+ const reader = resp.body.getReader();
18291
+ const decoder = new TextDecoder();
18292
+ let buffer2 = "";
18293
+ let accumulatedText = "";
18294
+ try {
18295
+ while (true) {
18296
+ const { done, value } = await reader.read();
18297
+ if (done) break;
18298
+ buffer2 += decoder.decode(value, { stream: true });
18299
+ const lines = buffer2.split("\n");
18300
+ buffer2 = lines.pop() ?? "";
18301
+ for (const line of lines) {
18302
+ if (line.startsWith("data: ")) {
18303
+ const data = line.slice(6).trim();
18304
+ if (!data) continue;
18305
+ try {
18306
+ const event = JSON.parse(data);
18307
+ this.handleSSEEvent(event, (t) => {
18308
+ accumulatedText += t;
18309
+ });
18310
+ } catch {
18311
+ }
18312
+ }
18313
+ }
18314
+ }
18315
+ if (buffer2.startsWith("data: ")) {
18316
+ const data = buffer2.slice(6).trim();
18317
+ if (data) {
18318
+ try {
18319
+ const event = JSON.parse(data);
18320
+ this.handleSSEEvent(event, (t) => {
18321
+ accumulatedText += t;
18322
+ });
18323
+ } catch {
18324
+ }
18325
+ }
18326
+ }
18327
+ } finally {
18328
+ reader.releaseLock();
18329
+ }
18330
+ return accumulatedText;
18331
+ }
18332
+ handleSSEEvent(event, onText) {
18333
+ const e = event;
18334
+ const messageParts = e.status?.message?.parts;
18335
+ if (messageParts) {
18336
+ for (const part of messageParts) {
18337
+ if (part.text) onText(part.text);
18338
+ }
18339
+ }
18340
+ }
18341
+ // ── Artifact Extraction ──────────────────────────────────────────────────
18342
+ extractArtifactText(task) {
18343
+ const artifacts = task.artifacts ?? [];
18344
+ return artifacts.flatMap((a) => a.parts ?? []).filter((p) => p.text).map((p) => p.text).join("\n");
18345
+ }
18346
+ };
18347
+
18348
+ // src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
18349
+ import { AgentType as AgentType2 } from "@axiom-lattice/protocols";
18350
+ var RemoteAgentGraphBuilder = class {
18351
+ async build(agentLattice, params) {
18352
+ if (agentLattice.config.type !== AgentType2.A2A_REMOTE) {
18353
+ throw new Error(
18354
+ `RemoteAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
18355
+ );
18356
+ }
18357
+ const config = agentLattice.config;
18358
+ const client = new A2ARemoteClient({
18359
+ agentCardUrl: config.agentCardUrl,
18360
+ apiKey: config.apiKey,
18361
+ timeout: config.timeout
18362
+ });
18363
+ await client.resolve();
18364
+ const remoteCallNode = async (state) => {
18365
+ const messages = state.messages ?? [];
18366
+ const text = extractLastHumanMessage(messages);
18367
+ if (!text) {
18368
+ return {
18369
+ messages: [
18370
+ new AIMessage4("No text input provided to remote agent.")
18371
+ ]
18372
+ };
18373
+ }
18374
+ try {
18375
+ const fullPrompt = params.prompt ? `${params.prompt}
18376
+
18377
+ User request:
18378
+ ${text}` : text;
18379
+ const response = await client.sendMessage(fullPrompt);
18380
+ return {
18381
+ messages: [new AIMessage4(response)]
18382
+ };
18383
+ } catch (error) {
18384
+ const msg = error.message ?? String(error);
18385
+ return {
18386
+ messages: [
18387
+ new AIMessage4(`Remote A2A agent error: ${msg}`)
18388
+ ]
18389
+ };
18390
+ }
18391
+ };
18392
+ const workflow = new StateGraph2(MessagesAnnotation).addNode("remote_call", remoteCallNode).addEdge("__start__", "remote_call").addEdge("remote_call", "__end__");
18393
+ return workflow.compile();
18394
+ }
18395
+ };
18396
+ function extractLastHumanMessage(messages) {
18397
+ for (let i = messages.length - 1; i >= 0; i--) {
18398
+ const msg = messages[i];
18399
+ if (msg._getType() === "human") {
18400
+ const content = msg.content;
18401
+ if (typeof content === "string") return content;
18402
+ if (Array.isArray(content)) {
18403
+ return content.filter(
18404
+ (c) => typeof c === "object" && c !== null && c.type === "text"
18405
+ ).map((c) => c.text).join("\n");
18406
+ }
18407
+ return String(content);
18408
+ }
18409
+ }
18410
+ return "";
18411
+ }
18412
+
18096
18413
  // src/agent_lattice/builders/AgentGraphBuilderFactory.ts
18097
18414
  var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
18098
18415
  constructor() {
@@ -18116,6 +18433,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
18116
18433
  this.builders.set(AgentType.DEEP_AGENT, new DeepAgentGraphBuilder());
18117
18434
  this.builders.set(AgentType.TEAM, new TeamAgentGraphBuilder());
18118
18435
  this.builders.set(AgentType.PROCESSING, new ProcessingAgentGraphBuilder());
18436
+ this.builders.set(AgentType.A2A_REMOTE, new RemoteAgentGraphBuilder());
18119
18437
  }
18120
18438
  /**
18121
18439
  * 注册自定义Builder
@@ -18792,8 +19110,8 @@ ${body}` : `${frontmatter}
18792
19110
 
18793
19111
  // src/agent_lattice/agentArchitectTools.ts
18794
19112
  import z55 from "zod";
18795
- import { v4 as v42 } from "uuid";
18796
- import { AgentType as AgentType2 } from "@axiom-lattice/protocols";
19113
+ import { v4 as v43 } from "uuid";
19114
+ import { AgentType as AgentType3 } from "@axiom-lattice/protocols";
18797
19115
  function getTenantId(exeConfig) {
18798
19116
  const runConfig = exeConfig?.configurable?.runConfig || {};
18799
19117
  return runConfig.tenantId || "default";
@@ -18901,7 +19219,7 @@ registerToolLattice(
18901
19219
  key: id,
18902
19220
  name: input.name,
18903
19221
  description: input.description || "",
18904
- type: input.type === "deep_agent" ? AgentType2.DEEP_AGENT : AgentType2.REACT,
19222
+ type: input.type === "deep_agent" ? AgentType3.DEEP_AGENT : AgentType3.REACT,
18905
19223
  prompt: input.prompt,
18906
19224
  ...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
18907
19225
  ...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
@@ -18990,7 +19308,7 @@ registerToolLattice(
18990
19308
  key: id,
18991
19309
  name: input.name,
18992
19310
  description: input.description || "",
18993
- type: AgentType2.PROCESSING,
19311
+ type: AgentType3.PROCESSING,
18994
19312
  prompt: input.prompt,
18995
19313
  ...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
18996
19314
  middleware,
@@ -19058,7 +19376,7 @@ registerToolLattice(
19058
19376
  return JSON.stringify({ error: `Agent '${input.id}' not found` });
19059
19377
  }
19060
19378
  const existingConfig = existing.graphDefinition || {};
19061
- if (existingConfig.type !== AgentType2.PROCESSING) {
19379
+ if (existingConfig.type !== AgentType3.PROCESSING) {
19062
19380
  return JSON.stringify({ error: `Agent '${input.id}' is not a PROCESSING agent (type: ${existingConfig.type})` });
19063
19381
  }
19064
19382
  const normalize = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
@@ -19266,7 +19584,7 @@ registerToolLattice(
19266
19584
  if (!existing) {
19267
19585
  return JSON.stringify({ error: `Agent '${id}' not found` });
19268
19586
  }
19269
- const threadId = v42();
19587
+ const threadId = v43();
19270
19588
  const agent = new Agent({
19271
19589
  tenant_id: tenantId,
19272
19590
  assistant_id: id,
@@ -19290,7 +19608,7 @@ registerToolLattice(
19290
19608
  );
19291
19609
 
19292
19610
  // src/agent_lattice/agentArchitectConfig.ts
19293
- import { AgentType as AgentType4 } from "@axiom-lattice/protocols";
19611
+ import { AgentType as AgentType5 } from "@axiom-lattice/protocols";
19294
19612
 
19295
19613
  // src/agent_lattice/agentArchitectPrompt.ts
19296
19614
  var AGENT_ARCHITECT_PROMPT = `# Agent Architect
@@ -19930,7 +20248,7 @@ Updates a PROCESSING agent's topology edges, name, prompt, or sub-agents. Unlike
19930
20248
  `;
19931
20249
 
19932
20250
  // src/agent_lattice/agentReviewerConfig.ts
19933
- import { AgentType as AgentType3 } from "@axiom-lattice/protocols";
20251
+ import { AgentType as AgentType4 } from "@axiom-lattice/protocols";
19934
20252
 
19935
20253
  // src/agent_lattice/agentReviewerPrompt.ts
19936
20254
  var AGENT_REVIEWER_PROMPT = `# Agent Reviewer
@@ -19993,7 +20311,7 @@ var agentReviewerConfig = {
19993
20311
  key: AGENT_REVIEWER_KEY,
19994
20312
  name: "Agent Reviewer",
19995
20313
  description: "Review and test AI agents. Use this agent to check agent configurations for correctness and to test agents by invoking them with realistic messages.",
19996
- type: AgentType3.REACT,
20314
+ type: AgentType4.REACT,
19997
20315
  prompt: AGENT_REVIEWER_PROMPT,
19998
20316
  tools: [
19999
20317
  "invoke_agent",
@@ -20019,7 +20337,7 @@ var agentArchitectConfig = {
20019
20337
  key: AGENT_ARCHITECT_KEY,
20020
20338
  name: "Agent Architect",
20021
20339
  description: "Design and manage AI agents through natural language conversation. Use this agent when you want to create a new agent, modify an existing agent, or manage your agent collection (list, view, update, delete).",
20022
- type: AgentType4.DEEP_AGENT,
20340
+ type: AgentType5.DEEP_AGENT,
20023
20341
  prompt: AGENT_ARCHITECT_PROMPT,
20024
20342
  tools: [
20025
20343
  "list_agents",
@@ -22849,6 +23167,7 @@ export {
22849
23167
  FileSystemSkillStore,
22850
23168
  FilesystemBackend,
22851
23169
  HumanMessage3 as HumanMessage,
23170
+ InMemoryA2AApiKeyStore,
22852
23171
  InMemoryAssistantStore,
22853
23172
  InMemoryBindingStore,
22854
23173
  InMemoryChannelInstallationStore,