@relayflows/sdk 2.0.22 → 2.0.23

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.
Files changed (193) hide show
  1. package/dist/agent-artifacts.d.ts +18 -9
  2. package/dist/agent-artifacts.d.ts.map +1 -1
  3. package/dist/agent-artifacts.js +27 -11
  4. package/dist/agent-artifacts.js.map +1 -1
  5. package/dist/authored-flow-error.d.ts +33 -1
  6. package/dist/authored-flow-error.d.ts.map +1 -1
  7. package/dist/authored-flow-error.js +20 -1
  8. package/dist/authored-flow-error.js.map +1 -1
  9. package/dist/authored-flow-executor.d.ts.map +1 -1
  10. package/dist/authored-flow-executor.js +4 -1
  11. package/dist/authored-flow-executor.js.map +1 -1
  12. package/dist/authored-node-entry.js +5 -1
  13. package/dist/authored-node-entry.js.map +1 -1
  14. package/dist/authored-node-runner.d.ts +11 -0
  15. package/dist/authored-node-runner.d.ts.map +1 -1
  16. package/dist/authored-node-runner.js +30 -1
  17. package/dist/authored-node-runner.js.map +1 -1
  18. package/dist/authored-root.js +3 -1
  19. package/dist/authored-root.js.map +1 -1
  20. package/dist/authored-source-authority.js +13 -0
  21. package/dist/authored-source-authority.js.map +1 -1
  22. package/dist/authored-step-index.d.ts +82 -0
  23. package/dist/authored-step-index.d.ts.map +1 -0
  24. package/dist/authored-step-index.js +120 -0
  25. package/dist/authored-step-index.js.map +1 -0
  26. package/dist/authored-step-output.d.ts +23 -2
  27. package/dist/authored-step-output.d.ts.map +1 -1
  28. package/dist/authored-step-output.js +47 -5
  29. package/dist/authored-step-output.js.map +1 -1
  30. package/dist/authored-worker-step.d.ts +10 -2
  31. package/dist/authored-worker-step.d.ts.map +1 -1
  32. package/dist/authored-worker-step.js +81 -7
  33. package/dist/authored-worker-step.js.map +1 -1
  34. package/dist/cli/check.d.ts.map +1 -1
  35. package/dist/cli/check.js +67 -12
  36. package/dist/cli/check.js.map +1 -1
  37. package/dist/cli/cloud-read.d.ts +31 -0
  38. package/dist/cli/cloud-read.d.ts.map +1 -0
  39. package/dist/cli/cloud-read.js +482 -0
  40. package/dist/cli/cloud-read.js.map +1 -0
  41. package/dist/cli/run.d.ts +2 -0
  42. package/dist/cli/run.d.ts.map +1 -1
  43. package/dist/cli/run.js +53 -25
  44. package/dist/cli/run.js.map +1 -1
  45. package/dist/cli/status.d.ts +9 -0
  46. package/dist/cli/status.d.ts.map +1 -1
  47. package/dist/cli/status.js +14 -0
  48. package/dist/cli/status.js.map +1 -1
  49. package/dist/cli/step-failure.d.ts +26 -0
  50. package/dist/cli/step-failure.d.ts.map +1 -1
  51. package/dist/cli/step-failure.js +68 -3
  52. package/dist/cli/step-failure.js.map +1 -1
  53. package/dist/cli-commands.d.ts +29 -1
  54. package/dist/cli-commands.d.ts.map +1 -1
  55. package/dist/cli-commands.js +23 -1
  56. package/dist/cli-commands.js.map +1 -1
  57. package/dist/cli.d.ts +2 -1
  58. package/dist/cli.d.ts.map +1 -1
  59. package/dist/cli.js +19 -2
  60. package/dist/cli.js.map +1 -1
  61. package/dist/cloud-http.d.ts +12 -0
  62. package/dist/cloud-http.d.ts.map +1 -1
  63. package/dist/cloud-http.js +14 -6
  64. package/dist/cloud-http.js.map +1 -1
  65. package/dist/cloud-read.d.ts +154 -0
  66. package/dist/cloud-read.d.ts.map +1 -0
  67. package/dist/cloud-read.js +373 -0
  68. package/dist/cloud-read.js.map +1 -0
  69. package/dist/cloud-transcript.d.ts +94 -0
  70. package/dist/cloud-transcript.d.ts.map +1 -0
  71. package/dist/cloud-transcript.js +342 -0
  72. package/dist/cloud-transcript.js.map +1 -0
  73. package/dist/communication/environment.d.ts +3 -0
  74. package/dist/communication/environment.d.ts.map +1 -0
  75. package/dist/communication/environment.js +34 -0
  76. package/dist/communication/environment.js.map +1 -0
  77. package/dist/communication/history.d.ts +6 -0
  78. package/dist/communication/history.d.ts.map +1 -0
  79. package/dist/communication/history.js +38 -0
  80. package/dist/communication/history.js.map +1 -0
  81. package/dist/communication/local.d.ts +6 -0
  82. package/dist/communication/local.d.ts.map +1 -0
  83. package/dist/communication/local.js +56 -0
  84. package/dist/communication/local.js.map +1 -0
  85. package/dist/communication/preflight.d.ts +6 -0
  86. package/dist/communication/preflight.d.ts.map +1 -0
  87. package/dist/communication/preflight.js +37 -0
  88. package/dist/communication/preflight.js.map +1 -0
  89. package/dist/communication/projection.d.ts +8 -0
  90. package/dist/communication/projection.d.ts.map +1 -0
  91. package/dist/communication/projection.js +23 -0
  92. package/dist/communication/projection.js.map +1 -0
  93. package/dist/communication/relay.d.ts +78 -0
  94. package/dist/communication/relay.d.ts.map +1 -0
  95. package/dist/communication/relay.js +89 -0
  96. package/dist/communication/relay.js.map +1 -0
  97. package/dist/communication/session.d.ts +24 -0
  98. package/dist/communication/session.d.ts.map +1 -0
  99. package/dist/communication/session.js +100 -0
  100. package/dist/communication/session.js.map +1 -0
  101. package/dist/communication/spec.d.ts +20 -0
  102. package/dist/communication/spec.d.ts.map +1 -0
  103. package/dist/communication/spec.js +113 -0
  104. package/dist/communication/spec.js.map +1 -0
  105. package/dist/communication/tool.d.ts +3 -0
  106. package/dist/communication/tool.d.ts.map +1 -0
  107. package/dist/communication/tool.js +23 -0
  108. package/dist/communication/tool.js.map +1 -0
  109. package/dist/communication/tools.d.ts +11 -0
  110. package/dist/communication/tools.d.ts.map +1 -0
  111. package/dist/communication/tools.js +65 -0
  112. package/dist/communication/tools.js.map +1 -0
  113. package/dist/communication/worker.d.ts +6 -0
  114. package/dist/communication/worker.d.ts.map +1 -0
  115. package/dist/communication/worker.js +120 -0
  116. package/dist/communication/worker.js.map +1 -0
  117. package/dist/compile.d.ts.map +1 -1
  118. package/dist/compile.js +8 -1
  119. package/dist/compile.js.map +1 -1
  120. package/dist/failure-kinds.d.ts +16 -1
  121. package/dist/failure-kinds.d.ts.map +1 -1
  122. package/dist/failure-kinds.js +1 -0
  123. package/dist/failure-kinds.js.map +1 -1
  124. package/dist/index.d.ts +3 -1
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +2 -0
  127. package/dist/index.js.map +1 -1
  128. package/dist/journal-client.d.ts +4 -1
  129. package/dist/journal-client.d.ts.map +1 -1
  130. package/dist/journal-client.js +11 -2
  131. package/dist/journal-client.js.map +1 -1
  132. package/dist/preflight.d.ts +13 -2
  133. package/dist/preflight.d.ts.map +1 -1
  134. package/dist/preflight.js +23 -6
  135. package/dist/preflight.js.map +1 -1
  136. package/dist/protocol.d.ts +39 -1
  137. package/dist/protocol.d.ts.map +1 -1
  138. package/dist/spec.d.ts +8 -0
  139. package/dist/spec.d.ts.map +1 -1
  140. package/dist/spec.js.map +1 -1
  141. package/dist/worker-cli.d.ts.map +1 -1
  142. package/dist/worker-cli.js +29 -50
  143. package/dist/worker-cli.js.map +1 -1
  144. package/dist/worker.d.ts +1 -0
  145. package/dist/worker.d.ts.map +1 -1
  146. package/dist/worker.js +10 -1
  147. package/dist/worker.js.map +1 -1
  148. package/dist/wrapper-session.d.ts +8 -0
  149. package/dist/wrapper-session.d.ts.map +1 -1
  150. package/dist/wrapper-session.js +156 -23
  151. package/dist/wrapper-session.js.map +1 -1
  152. package/package.json +14 -2
  153. package/src/agent-artifacts.ts +27 -11
  154. package/src/authored-flow-error.ts +17 -0
  155. package/src/authored-flow-executor.ts +4 -1
  156. package/src/authored-node-entry.ts +5 -1
  157. package/src/authored-node-runner.ts +33 -1
  158. package/src/authored-root.ts +2 -1
  159. package/src/authored-source-authority.ts +13 -0
  160. package/src/authored-step-index.ts +157 -0
  161. package/src/authored-step-output.ts +66 -14
  162. package/src/authored-worker-step.ts +88 -15
  163. package/src/cli/check.ts +69 -11
  164. package/src/cli/cloud-read.ts +518 -0
  165. package/src/cli/run.ts +43 -25
  166. package/src/cli/status.ts +20 -0
  167. package/src/cli/step-failure.ts +68 -3
  168. package/src/cli-commands.ts +23 -1
  169. package/src/cli.ts +20 -1
  170. package/src/cloud-http.ts +32 -6
  171. package/src/cloud-read.ts +515 -0
  172. package/src/cloud-transcript.ts +422 -0
  173. package/src/communication/environment.ts +33 -0
  174. package/src/communication/history.ts +38 -0
  175. package/src/communication/local.ts +41 -0
  176. package/src/communication/preflight.ts +34 -0
  177. package/src/communication/projection.ts +23 -0
  178. package/src/communication/relay.ts +102 -0
  179. package/src/communication/session.ts +84 -0
  180. package/src/communication/spec.ts +106 -0
  181. package/src/communication/tool.ts +22 -0
  182. package/src/communication/tools.ts +50 -0
  183. package/src/communication/worker.ts +95 -0
  184. package/src/compile.ts +4 -1
  185. package/src/failure-kinds.ts +16 -0
  186. package/src/index.ts +10 -1
  187. package/src/journal-client.ts +12 -2
  188. package/src/preflight.ts +36 -7
  189. package/src/protocol.ts +15 -0
  190. package/src/spec.ts +2 -0
  191. package/src/worker-cli.ts +28 -47
  192. package/src/worker.ts +10 -0
  193. package/src/wrapper-session.ts +159 -24
@@ -0,0 +1,23 @@
1
+ /** Observer publication never participates in delivery, acknowledgement, or completion. */
2
+ export function createProjection(messaging, channel, runId, diagnostic = (value) => { process.stderr.write(`${JSON.stringify(value)}\n`); }) {
3
+ let ready;
4
+ return (message) => {
5
+ const publish = async () => {
6
+ ready ??= (async () => {
7
+ try {
8
+ await messaging.channels.create({ name: channel });
9
+ }
10
+ catch {
11
+ await messaging.channels.get(channel);
12
+ await messaging.channels.join(channel);
13
+ }
14
+ })().catch(error => { ready = undefined; throw error; });
15
+ await ready;
16
+ await messaging.messages.send({ channel, ...message });
17
+ };
18
+ void publish().catch(() => diagnostic({ kind: 'communication_projection_failed', run_id: runId,
19
+ channel, idempotency_key: message.idempotencyKey,
20
+ message: 'Observer publication failed; the durable conversation continues.' }));
21
+ };
22
+ }
23
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/communication/projection.ts"],"names":[],"mappings":"AAEA,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,SAAyB,EAAE,OAAe,EAAE,KAAa,EACxF,aAAa,CAAC,KAAa,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,KAAgC,CAAC;IACrC,OAAO,CAAC,OAAoF,EAAQ,EAAE;QACpG,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;YACzB,KAAK,KAAK,CAAC,KAAK,IAAI,EAAE;gBACpB,IAAI,CAAC;oBAAC,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAC3D,MAAM,CAAC;oBACL,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACtC,MAAM,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,KAAK,CAAC;YACZ,MAAM,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC;QACF,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,MAAM,EAAE,KAAK;YAC5F,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,cAAc;YAChD,OAAO,EAAE,kEAAkE,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { createProjection } from './projection.js';
2
+ export interface RelayEvent {
3
+ kind: string;
4
+ name?: string;
5
+ event_id?: string;
6
+ delivery_id?: string;
7
+ verification?: string;
8
+ [key: string]: unknown;
9
+ }
10
+ export interface RelayHandle {
11
+ name: string;
12
+ generation?: string;
13
+ waitForReady(timeout?: number): Promise<{
14
+ reason: string;
15
+ }>;
16
+ release(reason?: string, options?: {
17
+ deleteIdentity?: boolean;
18
+ }): Promise<unknown>;
19
+ }
20
+ export interface RelayBroker {
21
+ spawnPty(input: Record<string, unknown>): Promise<RelayHandle>;
22
+ onEvent(callback: (event: RelayEvent) => void): () => void;
23
+ shutdown(): Promise<void>;
24
+ }
25
+ export interface RelayMessaging {
26
+ agents: {
27
+ register(input: {
28
+ name: string;
29
+ type: string;
30
+ }): Promise<{
31
+ token: string;
32
+ }>;
33
+ delete(name: string): Promise<void>;
34
+ };
35
+ channels: {
36
+ create(input: {
37
+ name: string;
38
+ }): Promise<unknown>;
39
+ get(name: string): Promise<unknown>;
40
+ join(name: string): Promise<void>;
41
+ };
42
+ messages: {
43
+ direct(input: {
44
+ to: string;
45
+ text: string;
46
+ idempotencyKey: string;
47
+ metadata: Record<string, unknown>;
48
+ mode: 'wait';
49
+ }): Promise<{
50
+ id: string;
51
+ }>;
52
+ send(input: {
53
+ channel: string;
54
+ text: string;
55
+ idempotencyKey: string;
56
+ metadata: Record<string, unknown>;
57
+ }): Promise<unknown>;
58
+ };
59
+ }
60
+ interface RelayModules {
61
+ HarnessDriverClient: {
62
+ spawn(options: Record<string, unknown>): Promise<RelayBroker>;
63
+ };
64
+ RelaycastMessagingClient: new (options: Record<string, unknown>) => RelayMessaging;
65
+ }
66
+ export declare function loadRelayModules(): Promise<RelayModules>;
67
+ export declare function relayWorkspaceKey(env?: NodeJS.ProcessEnv): string;
68
+ export interface RelayRuntime {
69
+ broker: RelayBroker;
70
+ messaging: RelayMessaging;
71
+ prefix: string;
72
+ channel: string;
73
+ project: ReturnType<typeof createProjection>;
74
+ close(): Promise<void>;
75
+ }
76
+ export declare function acquireRelayRuntime(dataDir: string, runId: string): Promise<RelayRuntime>;
77
+ export {};
78
+ //# sourceMappingURL=relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/communication/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { randomUUID, createHash } from 'node:crypto';
2
+ import { mkdir } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { createProjection } from './projection.js';
5
+ import { brokerEnvironment } from './environment.js';
6
+ export async function loadRelayModules() {
7
+ // Variable imports keep optional packages out of ordinary execution and bundles.
8
+ const driver = '@agent-relay/harness-driver';
9
+ const sdk = '@agent-relay/sdk';
10
+ try {
11
+ const [harness, messaging] = await Promise.all([import(driver), import(sdk)]);
12
+ return { HarnessDriverClient: harness.HarnessDriverClient, RelaycastMessagingClient: messaging.RelaycastMessagingClient };
13
+ }
14
+ catch {
15
+ throw new Error('Agent communication requires optional @agent-relay/harness-driver and @agent-relay/sdk packages (>=12.3.1).');
16
+ }
17
+ }
18
+ export function relayWorkspaceKey(env = process.env) {
19
+ const key = env.RELAY_API_KEY?.trim();
20
+ if (!key?.startsWith('rk_live_'))
21
+ throw new Error('Agent communication requires RELAY_API_KEY for an existing workspace.');
22
+ return key;
23
+ }
24
+ const runtimes = new Map();
25
+ export async function acquireRelayRuntime(dataDir, runId) {
26
+ const key = `${dataDir}\0${runId}`;
27
+ let entry = runtimes.get(key);
28
+ if (!entry) {
29
+ entry = { references: 0, runtime: createRuntime(dataDir, runId) };
30
+ runtimes.set(key, entry);
31
+ }
32
+ entry.references++;
33
+ try {
34
+ const runtime = await entry.runtime;
35
+ let closed = false;
36
+ return { ...runtime, close: async () => {
37
+ if (closed)
38
+ return;
39
+ closed = true;
40
+ if (--entry.references === 0) {
41
+ runtimes.delete(key);
42
+ await runtime.close();
43
+ }
44
+ } };
45
+ }
46
+ catch (error) {
47
+ if (--entry.references === 0)
48
+ runtimes.delete(key);
49
+ throw error;
50
+ }
51
+ }
52
+ async function createRuntime(dataDir, runId) {
53
+ const workspaceKey = relayWorkspaceKey();
54
+ const { HarnessDriverClient, RelaycastMessagingClient } = await loadRelayModules();
55
+ const hash = createHash('sha256').update(runId).digest('hex').slice(0, 12);
56
+ const prefix = `flow-${hash}-${randomUUID().slice(0, 8)}`;
57
+ const channel = `wf-${runId.toLowerCase()}`;
58
+ const options = { workspaceKey, ...(process.env.RELAY_BASE_URL ? { baseUrl: process.env.RELAY_BASE_URL } : {}) };
59
+ const workspace = new RelaycastMessagingClient(options);
60
+ const publisher = `${prefix}-journal`;
61
+ const registration = await workspace.agents.register({ name: publisher, type: 'agent' });
62
+ let broker;
63
+ try {
64
+ const messaging = new RelaycastMessagingClient({ ...options, agentToken: registration.token });
65
+ const cwd = join(dataDir, 'communication', prefix);
66
+ await mkdir(cwd, { recursive: true, mode: 0o700 });
67
+ broker = await HarnessDriverClient.spawn({ workspaceKey, brokerName: prefix, cwd, channels: [],
68
+ ...(process.env.RELAYFLOW_RELAY_BROKER_BIN ? { binaryPath: process.env.RELAYFLOW_RELAY_BROKER_BIN } : {}),
69
+ env: brokerEnvironment(process.env) });
70
+ return { broker, messaging, prefix, channel, project: createProjection(messaging, channel, runId), close: async () => {
71
+ try {
72
+ await broker.shutdown();
73
+ }
74
+ finally {
75
+ await workspace.agents.delete(publisher);
76
+ }
77
+ } };
78
+ }
79
+ catch (error) {
80
+ try {
81
+ await broker?.shutdown();
82
+ }
83
+ finally {
84
+ await workspace.agents.delete(publisher);
85
+ }
86
+ throw error;
87
+ }
88
+ }
89
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/communication/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { JournalClient } from '../journal-client.js';
2
+ import type { StepDispatchEvent } from '../protocol.js';
3
+ import type { CommunicationInstruction } from './spec.js';
4
+ import type { RelayRuntime } from './relay.js';
5
+ import type { CommunicationToolRequest } from './tools.js';
6
+ /** Journal operations belong to the dispatched worker connection, never the broker. */
7
+ export declare class CommunicationSession {
8
+ private readonly client;
9
+ private readonly dispatch;
10
+ private readonly spec;
11
+ private readonly relay;
12
+ private readonly complete;
13
+ private readonly fatal;
14
+ private readonly pending;
15
+ private finished;
16
+ private serial;
17
+ constructor(client: JournalClient, dispatch: StepDispatchEvent, spec: CommunicationInstruction, relay: RelayRuntime, complete: (summary: string) => void, fatal?: (error: unknown) => void);
18
+ private identity;
19
+ private lock;
20
+ private journal;
21
+ invoke(request: CommunicationToolRequest): Promise<unknown>;
22
+ pump(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/communication/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,uFAAuF;AACvF,qBAAa,oBAAoB;IAInB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAiB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAC3E,OAAO,CAAC,QAAQ,CAAC,IAAI;IAA4B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IANxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAuC;gBACxB,MAAM,EAAE,aAAa,EAAmB,QAAQ,EAAE,iBAAiB,EAC7E,IAAI,EAAE,wBAAwB,EAAmB,KAAK,EAAE,YAAY,EACpE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EACnC,KAAK,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAe;IAE7D,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,IAAI;YAKE,OAAO;IAIrB,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B3D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBtB"}
@@ -0,0 +1,100 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { channelName } from './spec.js';
3
+ /** Journal operations belong to the dispatched worker connection, never the broker. */
4
+ export class CommunicationSession {
5
+ client;
6
+ dispatch;
7
+ spec;
8
+ relay;
9
+ complete;
10
+ fatal;
11
+ pending = new Map();
12
+ finished = false;
13
+ serial = Promise.resolve();
14
+ constructor(client, dispatch, spec, relay, complete, fatal = () => { }) {
15
+ this.client = client;
16
+ this.dispatch = dispatch;
17
+ this.spec = spec;
18
+ this.relay = relay;
19
+ this.complete = complete;
20
+ this.fatal = fatal;
21
+ }
22
+ identity(from, to) {
23
+ const { run_id, step_id, attempt, idempotency_key } = this.dispatch;
24
+ return { run_id, step_id, attempt, idempotency_key, channel: channelName(from, to) };
25
+ }
26
+ lock(work) {
27
+ const next = this.serial.then(work);
28
+ this.serial = next.catch(() => { });
29
+ return next;
30
+ }
31
+ async journal(write) {
32
+ try {
33
+ return await write();
34
+ }
35
+ catch (error) {
36
+ this.fatal(error);
37
+ throw error;
38
+ }
39
+ }
40
+ invoke(request) {
41
+ return this.lock(async () => {
42
+ if (this.finished)
43
+ throw new Error('Communication session has completed');
44
+ const { operation, values } = request;
45
+ const [peer, id, text] = values;
46
+ if (operation === 'send') {
47
+ if (values.length !== 3 || !peer || !this.spec.outgoing.includes(peer) || !id || !text)
48
+ throw new Error('Use send DECLARED_PEER STABLE_MESSAGE_ID TEXT');
49
+ // Only the kernel deduplicates sends across worker attempts.
50
+ return this.journal(() => this.client.channelAppend({ ...this.identity(this.dispatch.step_id, peer), message_id: id, message: text }));
51
+ }
52
+ if (operation === 'ack') {
53
+ if (values.length !== 2 || !peer || !this.spec.incoming.includes(peer)
54
+ || !Number.isSafeInteger(Number(id)) || this.pending.get(peer) !== Number(id))
55
+ throw new Error('Use ack PEER DELIVERY_SEQ from a received message');
56
+ const result = await this.journal(() => this.client.channelAck({ ...this.identity(peer, this.dispatch.step_id), delivery_seq: Number(id) }));
57
+ this.pending.delete(peer);
58
+ return result;
59
+ }
60
+ if (operation === 'complete') {
61
+ if (values.length !== 1 || !peer)
62
+ throw new Error('Use complete SUMMARY');
63
+ if (this.pending.size)
64
+ throw new Error('Acknowledge processed messages before completing');
65
+ this.finished = true;
66
+ // Let the tool response flush before releasing its managed process.
67
+ setTimeout(() => this.complete(peer), 100);
68
+ return { completed: true };
69
+ }
70
+ throw new Error('Unknown communication operation');
71
+ });
72
+ }
73
+ pump() {
74
+ return this.lock(async () => {
75
+ if (this.finished)
76
+ return;
77
+ for (const peer of this.spec.incoming) {
78
+ if (this.pending.has(peer))
79
+ continue;
80
+ const entry = await this.client.channelReceive(this.identity(peer, this.dispatch.step_id));
81
+ if (!entry)
82
+ continue;
83
+ const key = createHash('sha256').update(JSON.stringify([
84
+ this.dispatch.run_id, this.dispatch.step_id, this.dispatch.attempt, entry.seq,
85
+ ])).digest('hex');
86
+ const text = `Flow message from ${peer}; delivery_seq=${entry.seq}.\n${JSON.stringify(entry.payload.message)}\nAfter processing, use the flow helper: ack ${peer} ${entry.seq}.`;
87
+ const metadata = { run_id: this.dispatch.run_id, step_id: this.dispatch.step_id, delivery_seq: entry.seq };
88
+ // A successful injection is not a processing acknowledgement.
89
+ await this.relay.messaging.messages.direct({ to: `${this.relay.prefix}-${this.dispatch.step_id}`,
90
+ text, metadata, idempotencyKey: key, mode: 'wait' });
91
+ this.pending.set(peer, entry.seq);
92
+ this.relay.project({
93
+ text: `${peer} -> ${this.dispatch.step_id}: ${JSON.stringify(entry.payload.message)}`,
94
+ metadata, idempotencyKey: `${key}-projection`
95
+ });
96
+ }
97
+ });
98
+ }
99
+ }
100
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/communication/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { StepSpec } from '../spec.js';
2
+ export declare const COMMUNICATION_TYPE = "relayflows.communication.v1";
3
+ export interface CommunicationEdge {
4
+ from: string;
5
+ to: string;
6
+ }
7
+ export interface CommunicationInstruction {
8
+ type: typeof COMMUNICATION_TYPE;
9
+ instruction: string;
10
+ incoming: string[];
11
+ outgoing: string[];
12
+ timeoutMs: number;
13
+ }
14
+ export declare function channelName(from: string, to: string): string;
15
+ export declare function communicationInstruction(instruction: unknown): CommunicationInstruction | undefined;
16
+ /** Authoring sugar only: kernel vocabulary remains agent + declared streams. */
17
+ export declare function expandCommunication(value: unknown): unknown;
18
+ /** Check normalized dependencies too, including implicit input bindings. */
19
+ export declare function validateCommunicationTopology(steps: StepSpec[]): void;
20
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/communication/spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAChE,MAAM,WAAW,iBAAiB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE;AAC/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,kBAAkB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AACD,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,OAAO,GAAG,wBAAwB,GAAG,SAAS,CAanG;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAqD3D;AAED,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAgBrE"}
@@ -0,0 +1,113 @@
1
+ import { createHash } from 'node:crypto';
2
+ export const COMMUNICATION_TYPE = 'relayflows.communication.v1';
3
+ const record = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
4
+ const name = (v) => typeof v === 'string' && /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(v);
5
+ export function channelName(from, to) {
6
+ return `a2a-${createHash('sha256').update(JSON.stringify([from, to])).digest('hex').slice(0, 24)}`;
7
+ }
8
+ export function communicationInstruction(instruction) {
9
+ if (typeof instruction !== 'string' || !instruction.startsWith('{'))
10
+ return;
11
+ let value;
12
+ try {
13
+ value = JSON.parse(instruction);
14
+ }
15
+ catch {
16
+ return;
17
+ }
18
+ if (!record(value) || value.type !== COMMUNICATION_TYPE)
19
+ return;
20
+ if (Object.keys(value).some(k => !['type', 'instruction', 'incoming', 'outgoing', 'timeoutMs'].includes(k))
21
+ || typeof value.instruction !== 'string' || !Array.isArray(value.incoming) || !value.incoming.every(name)
22
+ || !Array.isArray(value.outgoing) || !value.outgoing.every(name)
23
+ || value.incoming.length + value.outgoing.length === 0
24
+ || !Number.isSafeInteger(value.timeoutMs) || Number(value.timeoutMs) < 1 || Number(value.timeoutMs) > 900_000) {
25
+ throw new Error('Invalid agent communication instruction');
26
+ }
27
+ return value;
28
+ }
29
+ /** Authoring sugar only: kernel vocabulary remains agent + declared streams. */
30
+ export function expandCommunication(value) {
31
+ if (!record(value) || !('communication' in value))
32
+ return value;
33
+ const { communication, ...flow } = value;
34
+ if (!record(communication) || Object.keys(communication).some(k => !['links', 'timeoutMs'].includes(k))
35
+ || !Array.isArray(communication.links) || !Array.isArray(flow.steps)) {
36
+ throw new Error('communication requires links: [{ from, to }] and optional timeoutMs');
37
+ }
38
+ const timeoutMs = communication.timeoutMs ?? 300_000;
39
+ if (!Number.isSafeInteger(timeoutMs) || Number(timeoutMs) < 1 || Number(timeoutMs) > 900_000) {
40
+ throw new Error('communication.timeoutMs must be between 1 and 900000');
41
+ }
42
+ const steps = flow.steps;
43
+ const byId = new Map(steps.filter(record).map(step => [step.id, step]));
44
+ const edges = [];
45
+ for (const link of communication.links) {
46
+ if (!record(link) || Object.keys(link).some(k => !['from', 'to'].includes(k))
47
+ || !name(link.from) || !name(link.to) || link.from === link.to
48
+ || byId.get(link.from)?.type !== 'agent' || byId.get(link.to)?.type !== 'agent') {
49
+ throw new Error('communication links must name two different agent step ids');
50
+ }
51
+ if (edges.some(e => e.from === link.from && e.to === link.to))
52
+ throw new Error('Duplicate communication link');
53
+ edges.push({ from: link.from, to: link.to });
54
+ }
55
+ const ancestors = (id, visited = new Set()) => {
56
+ if (visited.has(id))
57
+ return visited;
58
+ visited.add(id);
59
+ const step = byId.get(id);
60
+ for (const dependency of Array.isArray(step?.dependsOn) ? step.dependsOn : []) {
61
+ if (typeof dependency === 'string')
62
+ ancestors(dependency, visited);
63
+ }
64
+ return visited;
65
+ };
66
+ for (const edge of edges) {
67
+ if (ancestors(edge.from).has(edge.to) || ancestors(edge.to).has(edge.from)) {
68
+ throw new Error('Communicating agents must be concurrent, not dependency ancestors');
69
+ }
70
+ }
71
+ return { ...flow, steps: steps.map(step => {
72
+ const incoming = edges.filter(e => e.to === step.id).map(e => e.from);
73
+ const outgoing = edges.filter(e => e.from === step.id).map(e => e.to);
74
+ if (!incoming.length && !outgoing.length)
75
+ return step;
76
+ if (step.transport === 'relay')
77
+ throw new Error('communication cannot be combined with task transport: relay');
78
+ if (typeof step.instruction !== 'string')
79
+ throw new Error('Communicating agents require an instruction');
80
+ const surfaces = record(step.surfaces) ? step.surfaces : {};
81
+ const streams = Array.isArray(surfaces.streams) ? surfaces.streams : [];
82
+ return { ...step,
83
+ instruction: JSON.stringify({ type: COMMUNICATION_TYPE, instruction: step.instruction, incoming, outgoing, timeoutMs }),
84
+ // One writer per directed channel; shared writable channels serialize agents.
85
+ surfaces: { ...surfaces, streams: [...streams,
86
+ { stream: channelName(String(step.id), '$receipts') },
87
+ ...outgoing.map(to => ({ stream: channelName(String(step.id), to) }))] },
88
+ };
89
+ }) };
90
+ }
91
+ /** Check normalized dependencies too, including implicit input bindings. */
92
+ export function validateCommunicationTopology(steps) {
93
+ const byId = new Map(steps.map(step => [step.id, step]));
94
+ const communicating = steps.filter(step => step.type === 'agent' && communicationInstruction(step.instruction));
95
+ const depends = (id, target, visited = new Set()) => {
96
+ if (visited.has(id))
97
+ return false;
98
+ visited.add(id);
99
+ return byId.get(id)?.dependsOn?.some(parent => parent === target || depends(parent, target, visited)) ?? false;
100
+ };
101
+ for (const a of communicating)
102
+ for (const b of communicating) {
103
+ if (a.id === b.id || a.type !== 'agent' || b.type !== 'agent')
104
+ continue;
105
+ if (depends(a.id, b.id))
106
+ throw new Error('Communicating agents must be concurrent, not dependency ancestors');
107
+ if (a.surfaces?.streams?.some(s => b.surfaces?.streams?.some(t => s.stream === t.stream))
108
+ || a.surfaces?.workspace?.some(s => b.surfaces?.workspace?.some(t => s.surface === t.surface))) {
109
+ throw new Error('Communicating agents cannot share writable surfaces: the kernel would serialize them');
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/communication/spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Standalone helper source also works when the SDK is bundled into a binary. */
2
+ export declare const toolSource: string;
3
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/communication/tool.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,eAAO,MAAM,UAAU,QAoBtB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** Standalone helper source also works when the SDK is bundled into a binary. */
2
+ export const toolSource = String.raw `
3
+ import { createConnection } from 'node:net';
4
+ import { once } from 'node:events';
5
+ async function main() {
6
+ const path = process.env.RELAYFLOW_COMMUNICATION_SOCKET;
7
+ const token = process.env.RELAYFLOW_COMMUNICATION_TOKEN;
8
+ if (!path || !token) throw new Error('No communication session attached to this agent');
9
+ const [operation, ...values] = process.argv.slice(2);
10
+ if (!['send', 'ack', 'complete'].includes(operation)) throw new Error('Use send PEER ID TEXT, ack PEER SEQ, or complete SUMMARY');
11
+ const socket = createConnection(path);
12
+ await once(socket, 'connect');
13
+ socket.setTimeout(30_000, () => socket.destroy(new Error('Communication tool timed out')));
14
+ socket.end(JSON.stringify({ token, operation, values }) + '\n');
15
+ let text = '';
16
+ for await (const chunk of socket) text += chunk;
17
+ const result = JSON.parse(text);
18
+ if (typeof result.error === 'string') throw new Error(result.error);
19
+ process.stdout.write(JSON.stringify(result.result) + '\n');
20
+ }
21
+ void main().catch(error => { console.error(error.message); process.exitCode = 1; });
22
+ `;
23
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/communication/tool.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;CAoBnC,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface CommunicationToolRequest {
2
+ operation: string;
3
+ values: string[];
4
+ }
5
+ export declare function openCommunicationTools(invoke: (request: CommunicationToolRequest) => Promise<unknown>): Promise<{
6
+ path: string;
7
+ helperPath: string;
8
+ token: string;
9
+ close: () => Promise<void>;
10
+ }>;
11
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/communication/tools.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,wBAAwB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;AACjF,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,OAAO,CAAC;;;;;GAyC3G"}
@@ -0,0 +1,65 @@
1
+ import { toolSource } from './tool.js';
2
+ import { createServer } from 'node:net';
3
+ import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { randomBytes, timingSafeEqual } from 'node:crypto';
7
+ export async function openCommunicationTools(invoke) {
8
+ const directory = await mkdtemp(join(tmpdir(), 'flows-comm-'));
9
+ const path = join(directory, 'agent.sock');
10
+ const helperPath = join(directory, 'tool.mjs');
11
+ const token = randomBytes(32).toString('hex');
12
+ const sockets = new Set();
13
+ let busy = false;
14
+ const server = createServer({ allowHalfOpen: true }, socket => {
15
+ sockets.add(socket);
16
+ socket.on('close', () => sockets.delete(socket));
17
+ socket.on('error', () => { });
18
+ socket.setTimeout(30_000, () => socket.destroy());
19
+ let text = '';
20
+ socket.on('data', chunk => {
21
+ text += chunk;
22
+ if (Buffer.byteLength(text) > 32_768)
23
+ socket.destroy();
24
+ });
25
+ socket.on('end', async () => {
26
+ if (busy) {
27
+ socket.end(JSON.stringify({ error: 'Call communication tools sequentially' }));
28
+ return;
29
+ }
30
+ busy = true;
31
+ try {
32
+ const input = JSON.parse(text);
33
+ if (typeof input.token !== 'string' || Buffer.byteLength(input.token) !== Buffer.byteLength(token)
34
+ || !timingSafeEqual(Buffer.from(input.token), Buffer.from(token)))
35
+ throw new Error('Unauthorized communication session');
36
+ if (typeof input.operation !== 'string' || !Array.isArray(input.values)
37
+ || !input.values.every((value) => typeof value === 'string'))
38
+ throw new Error('Invalid communication tool request');
39
+ socket.end(JSON.stringify({ result: await invoke({ operation: input.operation, values: input.values }) }));
40
+ }
41
+ catch (error) {
42
+ socket.end(JSON.stringify({ error: error instanceof Error ? error.message : 'Communication tool failed' }));
43
+ }
44
+ finally {
45
+ busy = false;
46
+ }
47
+ });
48
+ });
49
+ try {
50
+ await new Promise((resolve, reject) => { server.once('error', reject); server.listen(path, resolve); });
51
+ await chmod(path, 0o600);
52
+ await writeFile(helperPath, toolSource, { mode: 0o600 });
53
+ }
54
+ catch (error) {
55
+ await rm(directory, { recursive: true, force: true });
56
+ throw error;
57
+ }
58
+ return { path, helperPath, token, close: async () => {
59
+ for (const socket of sockets)
60
+ socket.destroy();
61
+ await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
62
+ await rm(directory, { recursive: true, force: true });
63
+ } };
64
+ }
65
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/communication/tools.ts"],"names":[],"mappings":"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"}