electric-ax 0.2.0 → 0.2.2

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.
@@ -1,4 +1,4 @@
1
- import { ElectricCliEnv } from "./index-BQ4JyfkG.cjs";
1
+ import { ElectricCliEnv } from "./index-cwCTPq6Y.cjs";
2
2
 
3
3
  //#region src/completions.d.ts
4
4
  declare function fetchEntityTypeNames(env: ElectricCliEnv): Promise<Array<string>>;
@@ -1,4 +1,4 @@
1
- import { ElectricCliEnv } from "./index-D6TZ88Yg.js";
1
+ import { ElectricCliEnv } from "./index-BSHO_Rei.js";
2
2
 
3
3
  //#region src/completions.d.ts
4
4
  declare function fetchEntityTypeNames(env: ElectricCliEnv): Promise<Array<string>>;
@@ -12,18 +12,8 @@ function entityApiPath(entityUrl, suffix = ``) {
12
12
  function entityApiUrl(baseUrl, entityUrl, suffix = ``) {
13
13
  return (0, __electric_ax_agents_runtime.appendPathToUrl)(baseUrl, entityApiPath(entityUrl, suffix));
14
14
  }
15
- function assertedIdentityHeaders(identity) {
16
- const trimmed = identity?.trim();
17
- return trimmed ? { "x-electric-asserted-email": trimmed } : {};
18
- }
19
15
 
20
16
  //#endregion
21
- Object.defineProperty(exports, 'assertedIdentityHeaders', {
22
- enumerable: true,
23
- get: function () {
24
- return assertedIdentityHeaders;
25
- }
26
- });
27
17
  Object.defineProperty(exports, 'entityApiPath', {
28
18
  enumerable: true,
29
19
  get: function () {
@@ -10,10 +10,6 @@ function entityApiPath(entityUrl, suffix = ``) {
10
10
  function entityApiUrl(baseUrl, entityUrl, suffix = ``) {
11
11
  return appendPathToUrl(baseUrl, entityApiPath(entityUrl, suffix));
12
12
  }
13
- function assertedIdentityHeaders(identity) {
14
- const trimmed = identity?.trim();
15
- return trimmed ? { "x-electric-asserted-email": trimmed } : {};
16
- }
17
13
 
18
14
  //#endregion
19
- export { assertedIdentityHeaders, entityApiPath, entityApiUrl };
15
+ export { entityApiPath, entityApiUrl };
@@ -6,8 +6,6 @@ declare function createEntityStreamDB(opts: {
6
6
  baseUrl: string;
7
7
  entityUrl: string;
8
8
  initialOffset?: string;
9
- assertedAuthEmail?: string;
10
- assertedAuthName?: string;
11
9
  headers?: Record<string, string>;
12
10
  }): Promise<{
13
11
  db: EntityStreamDB;
@@ -6,8 +6,6 @@ declare function createEntityStreamDB(opts: {
6
6
  baseUrl: string;
7
7
  entityUrl: string;
8
8
  initialOffset?: string;
9
- assertedAuthEmail?: string;
10
- assertedAuthName?: string;
11
9
  headers?: Record<string, string>;
12
10
  }): Promise<{
13
11
  db: EntityStreamDB;
@@ -1,4 +1,4 @@
1
- import { assertedIdentityHeaders, entityApiUrl } from "./entity-api-Dh28Mz7H.js";
1
+ import { entityApiUrl } from "./entity-api-DWMhkYbl.js";
2
2
  import { createStreamDB } from "@durable-streams/state";
3
3
  import { appendPathToUrl, entityStateSchema } from "@electric-ax/agents-runtime";
4
4
 
@@ -7,12 +7,10 @@ function getMainStreamPath(entityUrl, entity) {
7
7
  return entity.streams?.main ?? `${entityUrl}/main`;
8
8
  }
9
9
  async function createEntityStreamDB(opts) {
10
- const { baseUrl, entityUrl, initialOffset, assertedAuthEmail, assertedAuthName, headers: serverHeaders } = opts;
10
+ const { baseUrl, entityUrl, initialOffset, headers: serverHeaders } = opts;
11
11
  console.log(`[createEntityStreamDB] Creating entity stream DB for ${baseUrl}${entityUrl}`);
12
12
  const requestHeaders = {
13
13
  "content-type": `application/json`,
14
- ...assertedIdentityHeaders(assertedAuthEmail),
15
- ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
16
14
  ...serverHeaders
17
15
  };
18
16
  let res;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
- const require_entity_api = require('./entity-api-ClpnLxWJ.cjs');
3
+ const require_entity_api = require('./entity-api-Cvo55yZx.cjs');
4
4
  const __durable_streams_state = require_chunk.__toESM(require("@durable-streams/state"));
5
5
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
6
6
 
@@ -9,12 +9,10 @@ function getMainStreamPath(entityUrl, entity) {
9
9
  return entity.streams?.main ?? `${entityUrl}/main`;
10
10
  }
11
11
  async function createEntityStreamDB(opts) {
12
- const { baseUrl, entityUrl, initialOffset, assertedAuthEmail, assertedAuthName, headers: serverHeaders } = opts;
12
+ const { baseUrl, entityUrl, initialOffset, headers: serverHeaders } = opts;
13
13
  console.log(`[createEntityStreamDB] Creating entity stream DB for ${baseUrl}${entityUrl}`);
14
14
  const requestHeaders = {
15
15
  "content-type": `application/json`,
16
- ...require_entity_api.assertedIdentityHeaders(assertedAuthEmail),
17
- ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
18
16
  ...serverHeaders
19
17
  };
20
18
  let res;
@@ -1,4 +1,4 @@
1
- require('./entity-api-ClpnLxWJ.cjs');
2
- const require_entity_stream_db = require('./entity-stream-db-BLbPedyR.cjs');
1
+ require('./entity-api-Cvo55yZx.cjs');
2
+ const require_entity_stream_db = require('./entity-stream-db-CIv6uC2d.cjs');
3
3
 
4
4
  exports.createEntityStreamDB = require_entity_stream_db.createEntityStreamDB
@@ -1,2 +1,2 @@
1
- import { EntityStreamDB, createEntityStreamDB } from "./entity-stream-db-CmDwc49J.cjs";
1
+ import { EntityStreamDB, createEntityStreamDB } from "./entity-stream-db-BV4N31MR.cjs";
2
2
  export { EntityStreamDB, createEntityStreamDB };
@@ -1,2 +1,2 @@
1
- import { EntityStreamDB, createEntityStreamDB$1 as createEntityStreamDB } from "./entity-stream-db-DgzxI6C_.js";
1
+ import { EntityStreamDB, createEntityStreamDB$1 as createEntityStreamDB } from "./entity-stream-db-Bl6AT5hR.js";
2
2
  export { EntityStreamDB, createEntityStreamDB };
@@ -1,4 +1,4 @@
1
- import "./entity-api-Dh28Mz7H.js";
2
- import { createEntityStreamDB } from "./entity-stream-db-Czz3S8YF.js";
1
+ import "./entity-api-DWMhkYbl.js";
2
+ import { createEntityStreamDB } from "./entity-stream-db-CDOlZYc2.js";
3
3
 
4
4
  export { createEntityStreamDB };
@@ -52,8 +52,6 @@ declare const DEFAULT_ELECTRIC_AGENTS_URL = "http://localhost:4437";
52
52
  interface ElectricCliEnv {
53
53
  electricAgentsUrl: string;
54
54
  electricAgentsIdentity: string;
55
- electricAssertedAuthEmail?: string;
56
- electricAssertedAuthName?: string;
57
55
  electricAgentsHeaders?: Record<string, string>;
58
56
  }
59
57
  interface SpawnCommandOptions {
@@ -52,8 +52,6 @@ declare const DEFAULT_ELECTRIC_AGENTS_URL = "http://localhost:4437";
52
52
  interface ElectricCliEnv {
53
53
  electricAgentsUrl: string;
54
54
  electricAgentsIdentity: string;
55
- electricAssertedAuthEmail?: string;
56
- electricAssertedAuthName?: string;
57
55
  electricAgentsHeaders?: Record<string, string>;
58
56
  }
59
57
  interface SpawnCommandOptions {
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
4
4
  const require_completions = require('./completions-Bj4D5DRa.cjs');
5
- const require_entity_api = require('./entity-api-ClpnLxWJ.cjs');
5
+ const require_entity_api = require('./entity-api-Cvo55yZx.cjs');
6
6
  const require_env = require('./env-CFKgT8o2.cjs');
7
7
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
8
8
  const node_fs = require_chunk.__toESM(require("node:fs"));
@@ -11,6 +11,7 @@ const node_path = require_chunk.__toESM(require("node:path"));
11
11
  const node_url = require_chunk.__toESM(require("node:url"));
12
12
  const commander = require_chunk.__toESM(require("commander"));
13
13
  const node_readline_promises = require_chunk.__toESM(require("node:readline/promises"));
14
+ const __electric_ax_agents_server_headers = require_chunk.__toESM(require("@electric-ax/agents/server-headers"));
14
15
 
15
16
  //#region src/prompt-api-key.ts
16
17
  const FRIENDLY_INTRO = `\n${[
@@ -162,19 +163,20 @@ function parseElectricAgentsHeaders(raw) {
162
163
  }
163
164
  function getElectricCliEnv(env = process.env) {
164
165
  const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
166
+ const headers = parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS);
165
167
  return {
166
168
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
167
169
  electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
168
- electricAssertedAuthEmail: env.ELECTRIC_ASSERTED_AUTH_EMAIL?.trim() || explicitIdentity || void 0,
169
- electricAssertedAuthName: env.ELECTRIC_ASSERTED_AUTH_NAME?.trim(),
170
- electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
170
+ electricAgentsHeaders: (0, __electric_ax_agents_server_headers.mergeElectricPrincipalHeader)(headers, env.ELECTRIC_AGENTS_PRINCIPAL)
171
171
  };
172
172
  }
173
173
  function getErrorMessage(error) {
174
- return error instanceof Error ? error.message : String(error);
174
+ if (error instanceof Error) return error.message || error.name || `Unknown error`;
175
+ const message = String(error);
176
+ return message || `Unknown error`;
175
177
  }
176
178
  function fail(message) {
177
- throw new CliError(message);
179
+ throw new CliError(message || `Unknown error`);
178
180
  }
179
181
  function relativeTime(epochMs) {
180
182
  const seconds = Math.floor((Date.now() - epochMs) / 1e3);
@@ -298,8 +300,6 @@ async function electricAgentsFetch(env, path, opts = {}) {
298
300
  ...opts,
299
301
  headers: {
300
302
  "content-type": `application/json`,
301
- ...require_entity_api.assertedIdentityHeaders(env.electricAssertedAuthEmail),
302
- ...env.electricAssertedAuthName ? { "x-electric-asserted-name": env.electricAssertedAuthName } : {},
303
303
  ...env.electricAgentsHeaders,
304
304
  ...opts.headers
305
305
  }
@@ -314,17 +314,36 @@ async function parseJsonResponse(res) {
314
314
  return JSON.parse(text);
315
315
  } catch (error) {
316
316
  if (!(error instanceof SyntaxError)) throw error;
317
- return { error: { message: text || res.statusText } };
317
+ return { error: { message: text || fallbackResponseMessage(res) } };
318
318
  }
319
319
  }
320
+ function fallbackResponseMessage(res) {
321
+ const status = res.status ? `HTTP ${res.status}` : `HTTP error`;
322
+ return res.statusText ? `${status}: ${res.statusText}` : status;
323
+ }
324
+ function stringMessage(value) {
325
+ if (typeof value !== `string`) return void 0;
326
+ const trimmed = value.trim();
327
+ if (trimmed.length === 0) return void 0;
328
+ return trimmed;
329
+ }
330
+ function errorMessageFromValue(value) {
331
+ const direct = stringMessage(value);
332
+ if (direct) return direct;
333
+ if (!value || typeof value !== `object` || Array.isArray(value)) return void 0;
334
+ const record = value;
335
+ return errorMessageFromValue(record.message) ?? errorMessageFromValue(record.error) ?? errorMessageFromValue(record.reason) ?? errorMessageFromValue(record.detail);
336
+ }
337
+ function responseErrorMessage(data, res) {
338
+ return errorMessageFromValue(data) ?? fallbackResponseMessage(res);
339
+ }
320
340
  function failFromResponse(data, res) {
321
- const err = data.error;
322
- fail(String(err?.message ?? res.statusText));
341
+ fail(responseErrorMessage(data, res));
323
342
  }
324
343
  async function fetchEntityTypes(env) {
325
344
  const res = await electricAgentsFetch(env, `/_electric/entity-types`);
326
- const data = await res.json();
327
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
345
+ const data = await parseJsonResponse(res);
346
+ if (!res.ok) failFromResponse(data, res);
328
347
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entity types`);
329
348
  return data;
330
349
  }
@@ -349,8 +368,8 @@ async function fetchEntities(env, options = {}) {
349
368
  if (options.parent) searchParams.set(`parent`, options.parent);
350
369
  const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : ``;
351
370
  const res = await electricAgentsFetch(env, `/_electric/entities${suffix}`);
352
- const data = await res.json();
353
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
371
+ const data = await parseJsonResponse(res);
372
+ if (!res.ok) failFromResponse(data, res);
354
373
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entities`);
355
374
  return data;
356
375
  }
@@ -409,8 +428,6 @@ async function observeEntity(env, url, options) {
409
428
  entityUrl: url,
410
429
  baseUrl: env.electricAgentsUrl,
411
430
  identity: env.electricAgentsIdentity,
412
- assertedAuthEmail: env.electricAssertedAuthEmail,
413
- assertedAuthName: env.electricAssertedAuthName,
414
431
  headers: env.electricAgentsHeaders,
415
432
  initialOffset: options.from
416
433
  });
@@ -531,6 +548,8 @@ function getHelpText(commandName) {
531
548
  Environment:
532
549
  ELECTRIC_AGENTS_URL Base URL of the server (default: ${DEFAULT_ELECTRIC_AGENTS_URL})
533
550
  ELECTRIC_AGENTS_IDENTITY Sender identity for messages (default: ${getDefaultElectricAgentsIdentity()})
551
+ ELECTRIC_AGENTS_PRINCIPAL Optional principal key sent as the Electric-Principal header
552
+ ELECTRIC_AGENTS_SERVER_HEADERS Optional JSON object of additional server headers
534
553
  ANTHROPIC_API_KEY Required for '${agentsCommand} start-builtin' and '${agentsCommand} quickstart'
535
554
 
536
555
  Examples:
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-BQ4JyfkG.cjs";
2
+ import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-cwCTPq6Y.cjs";
3
3
  export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-D6TZ88Yg.js";
2
+ import { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run } from "./index-BSHO_Rei.js";
3
3
  export { DEFAULT_ELECTRIC_AGENTS_URL, ElectricCliEnv, ElectricCliHandlers, ObserveCommandOptions, PsCommandOptions, SendCommandOptions, SpawnCommandOptions, StartBuiltinCommandOptions, StartCommandOptions, StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StopCommandOptions, StoppedDevEnvironment, createElectricCliHandlers, createElectricProgram, formatQuickstartBackendStartedMessage, getElectricCliEnv, resolveCommandPrefix, run };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { installCompletions, setupCompletions } from "./completions-B-Lf28Wy.js";
3
- import { assertedIdentityHeaders, entityApiPath } from "./entity-api-Dh28Mz7H.js";
3
+ import { entityApiPath } from "./entity-api-DWMhkYbl.js";
4
4
  import { resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-DIhTv987.js";
5
5
  import { appendPathToUrl } from "@electric-ax/agents-runtime";
6
6
  import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
@@ -9,6 +9,7 @@ import { basename, resolve } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { Command } from "commander";
11
11
  import { createInterface } from "node:readline/promises";
12
+ import { mergeElectricPrincipalHeader } from "@electric-ax/agents/server-headers";
12
13
 
13
14
  //#region src/prompt-api-key.ts
14
15
  const FRIENDLY_INTRO = `\n${[
@@ -160,19 +161,20 @@ function parseElectricAgentsHeaders(raw) {
160
161
  }
161
162
  function getElectricCliEnv(env = process.env) {
162
163
  const explicitIdentity = env.ELECTRIC_AGENTS_IDENTITY?.trim();
164
+ const headers = parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS);
163
165
  return {
164
166
  electricAgentsUrl: env.ELECTRIC_AGENTS_URL || DEFAULT_ELECTRIC_AGENTS_URL,
165
167
  electricAgentsIdentity: explicitIdentity || getDefaultElectricAgentsIdentity(),
166
- electricAssertedAuthEmail: env.ELECTRIC_ASSERTED_AUTH_EMAIL?.trim() || explicitIdentity || void 0,
167
- electricAssertedAuthName: env.ELECTRIC_ASSERTED_AUTH_NAME?.trim(),
168
- electricAgentsHeaders: parseElectricAgentsHeaders(env.ELECTRIC_AGENTS_SERVER_HEADERS)
168
+ electricAgentsHeaders: mergeElectricPrincipalHeader(headers, env.ELECTRIC_AGENTS_PRINCIPAL)
169
169
  };
170
170
  }
171
171
  function getErrorMessage(error) {
172
- return error instanceof Error ? error.message : String(error);
172
+ if (error instanceof Error) return error.message || error.name || `Unknown error`;
173
+ const message = String(error);
174
+ return message || `Unknown error`;
173
175
  }
174
176
  function fail(message) {
175
- throw new CliError(message);
177
+ throw new CliError(message || `Unknown error`);
176
178
  }
177
179
  function relativeTime(epochMs) {
178
180
  const seconds = Math.floor((Date.now() - epochMs) / 1e3);
@@ -296,8 +298,6 @@ async function electricAgentsFetch(env, path$1, opts = {}) {
296
298
  ...opts,
297
299
  headers: {
298
300
  "content-type": `application/json`,
299
- ...assertedIdentityHeaders(env.electricAssertedAuthEmail),
300
- ...env.electricAssertedAuthName ? { "x-electric-asserted-name": env.electricAssertedAuthName } : {},
301
301
  ...env.electricAgentsHeaders,
302
302
  ...opts.headers
303
303
  }
@@ -312,17 +312,36 @@ async function parseJsonResponse(res) {
312
312
  return JSON.parse(text);
313
313
  } catch (error) {
314
314
  if (!(error instanceof SyntaxError)) throw error;
315
- return { error: { message: text || res.statusText } };
315
+ return { error: { message: text || fallbackResponseMessage(res) } };
316
316
  }
317
317
  }
318
+ function fallbackResponseMessage(res) {
319
+ const status = res.status ? `HTTP ${res.status}` : `HTTP error`;
320
+ return res.statusText ? `${status}: ${res.statusText}` : status;
321
+ }
322
+ function stringMessage(value) {
323
+ if (typeof value !== `string`) return void 0;
324
+ const trimmed = value.trim();
325
+ if (trimmed.length === 0) return void 0;
326
+ return trimmed;
327
+ }
328
+ function errorMessageFromValue(value) {
329
+ const direct = stringMessage(value);
330
+ if (direct) return direct;
331
+ if (!value || typeof value !== `object` || Array.isArray(value)) return void 0;
332
+ const record = value;
333
+ return errorMessageFromValue(record.message) ?? errorMessageFromValue(record.error) ?? errorMessageFromValue(record.reason) ?? errorMessageFromValue(record.detail);
334
+ }
335
+ function responseErrorMessage(data, res) {
336
+ return errorMessageFromValue(data) ?? fallbackResponseMessage(res);
337
+ }
318
338
  function failFromResponse(data, res) {
319
- const err = data.error;
320
- fail(String(err?.message ?? res.statusText));
339
+ fail(responseErrorMessage(data, res));
321
340
  }
322
341
  async function fetchEntityTypes(env) {
323
342
  const res = await electricAgentsFetch(env, `/_electric/entity-types`);
324
- const data = await res.json();
325
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
343
+ const data = await parseJsonResponse(res);
344
+ if (!res.ok) failFromResponse(data, res);
326
345
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entity types`);
327
346
  return data;
328
347
  }
@@ -347,8 +366,8 @@ async function fetchEntities(env, options = {}) {
347
366
  if (options.parent) searchParams.set(`parent`, options.parent);
348
367
  const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : ``;
349
368
  const res = await electricAgentsFetch(env, `/_electric/entities${suffix}`);
350
- const data = await res.json();
351
- if (!res.ok) fail(typeof data === `object` && data !== null ? String(data.error?.message ?? res.statusText) : res.statusText);
369
+ const data = await parseJsonResponse(res);
370
+ if (!res.ok) failFromResponse(data, res);
352
371
  if (!Array.isArray(data)) fail(`Unexpected response from server when listing entities`);
353
372
  return data;
354
373
  }
@@ -407,8 +426,6 @@ async function observeEntity(env, url, options) {
407
426
  entityUrl: url,
408
427
  baseUrl: env.electricAgentsUrl,
409
428
  identity: env.electricAgentsIdentity,
410
- assertedAuthEmail: env.electricAssertedAuthEmail,
411
- assertedAuthName: env.electricAssertedAuthName,
412
429
  headers: env.electricAgentsHeaders,
413
430
  initialOffset: options.from
414
431
  });
@@ -529,6 +546,8 @@ function getHelpText(commandName) {
529
546
  Environment:
530
547
  ELECTRIC_AGENTS_URL Base URL of the server (default: ${DEFAULT_ELECTRIC_AGENTS_URL})
531
548
  ELECTRIC_AGENTS_IDENTITY Sender identity for messages (default: ${getDefaultElectricAgentsIdentity()})
549
+ ELECTRIC_AGENTS_PRINCIPAL Optional principal key sent as the Electric-Principal header
550
+ ELECTRIC_AGENTS_SERVER_HEADERS Optional JSON object of additional server headers
532
551
  ANTHROPIC_API_KEY Required for '${agentsCommand} start-builtin' and '${agentsCommand} quickstart'
533
552
 
534
553
  Examples:
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
- const require_entity_api = require('./entity-api-ClpnLxWJ.cjs');
4
- const require_entity_stream_db = require('./entity-stream-db-BLbPedyR.cjs');
3
+ const require_entity_api = require('./entity-api-Cvo55yZx.cjs');
4
+ const require_entity_stream_db = require('./entity-stream-db-CIv6uC2d.cjs');
5
5
  const __durable_streams_state = require_chunk.__toESM(require("@durable-streams/state"));
6
6
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
7
7
  const react = require_chunk.__toESM(require("react"));
@@ -119,7 +119,7 @@ function ToolResultView({ result }) {
119
119
  }) : null]
120
120
  });
121
121
  }
122
- function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, assertedAuthName, headers, disabled }) {
122
+ function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
123
123
  const [value, setValue] = (0, react.useState)(``);
124
124
  const [error, setError] = (0, react.useState)(null);
125
125
  const sendAction = (0, react.useMemo)(() => (0, __durable_streams_state.createOptimisticAction)({
@@ -136,8 +136,6 @@ function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, ass
136
136
  method: `POST`,
137
137
  headers: {
138
138
  "content-type": `application/json`,
139
- ...require_entity_api.assertedIdentityHeaders(assertedAuthEmail),
140
- ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
141
139
  ...headers
142
140
  },
143
141
  body: JSON.stringify({
@@ -164,8 +162,6 @@ function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, ass
164
162
  baseUrl,
165
163
  entityUrl,
166
164
  identity,
167
- assertedAuthEmail,
168
- assertedAuthName,
169
165
  headers
170
166
  ]);
171
167
  (0, ink.useInput)((input, key) => {
@@ -265,7 +261,7 @@ function WakeView({ section }) {
265
261
  })]
266
262
  });
267
263
  }
268
- function ObserveView({ db, entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers }) {
264
+ function ObserveView({ db, entityUrl, baseUrl, identity, headers }) {
269
265
  const timelineQuery = (0, react.useMemo)(() => (0, __electric_ax_agents_runtime.createEntityIncludesQuery)(db), [db]);
270
266
  const { data: timelineRows = [] } = (0, __tanstack_react_db.useLiveQuery)(timelineQuery, [timelineQuery]);
271
267
  const timelineData = (0, __electric_ax_agents_runtime.normalizeEntityTimelineData)(timelineRows[0] ?? {
@@ -338,15 +334,13 @@ function ObserveView({ db, entityUrl, baseUrl, identity, assertedAuthEmail, asse
338
334
  baseUrl,
339
335
  entityUrl,
340
336
  identity,
341
- assertedAuthEmail,
342
- assertedAuthName,
343
337
  headers,
344
338
  disabled: closed
345
339
  })
346
340
  ]
347
341
  });
348
342
  }
349
- function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers, initialOffset }) {
343
+ function ObserveApp({ entityUrl, baseUrl, identity, headers, initialOffset }) {
350
344
  const [db, setDb] = (0, react.useState)(null);
351
345
  const [error, setError] = (0, react.useState)(null);
352
346
  const closeRef = (0, react.useRef)(null);
@@ -356,8 +350,6 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
356
350
  baseUrl,
357
351
  entityUrl,
358
352
  initialOffset,
359
- assertedAuthEmail,
360
- assertedAuthName,
361
353
  headers
362
354
  }).then((result) => {
363
355
  if (cancelled) {
@@ -377,8 +369,6 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
377
369
  baseUrl,
378
370
  entityUrl,
379
371
  initialOffset,
380
- assertedAuthEmail,
381
- assertedAuthName,
382
372
  headers
383
373
  ]);
384
374
  if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Box, {
@@ -397,19 +387,15 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
397
387
  entityUrl,
398
388
  baseUrl,
399
389
  identity,
400
- assertedAuthEmail,
401
- assertedAuthName,
402
390
  headers
403
391
  });
404
392
  }
405
393
  function renderObserve(opts) {
406
- const { entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers, initialOffset } = opts;
394
+ const { entityUrl, baseUrl, identity, headers, initialOffset } = opts;
407
395
  const app = (0, ink.render)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ObserveApp, {
408
396
  entityUrl,
409
397
  baseUrl,
410
398
  identity,
411
- assertedAuthEmail,
412
- assertedAuthName,
413
399
  headers,
414
400
  initialOffset
415
401
  }));
@@ -1,4 +1,4 @@
1
- import { EntityStreamDB } from "./entity-stream-db-CmDwc49J.cjs";
1
+ import { EntityStreamDB } from "./entity-stream-db-BV4N31MR.cjs";
2
2
  import { EntityTimelineContentItem, MessageReceived } from "@electric-ax/agents-runtime";
3
3
  import React from "react";
4
4
 
@@ -40,8 +40,6 @@ declare function MessageInput({
40
40
  baseUrl,
41
41
  entityUrl,
42
42
  identity,
43
- assertedAuthEmail,
44
- assertedAuthName,
45
43
  headers,
46
44
  disabled
47
45
  }: {
@@ -49,8 +47,6 @@ declare function MessageInput({
49
47
  baseUrl: string;
50
48
  entityUrl: string;
51
49
  identity: string;
52
- assertedAuthEmail?: string;
53
- assertedAuthName?: string;
54
50
  headers?: Record<string, string>;
55
51
  disabled: boolean;
56
52
  }): React.ReactElement;
@@ -58,8 +54,6 @@ declare function renderObserve(opts: {
58
54
  entityUrl: string;
59
55
  baseUrl: string;
60
56
  identity: string;
61
- assertedAuthEmail?: string;
62
- assertedAuthName?: string;
63
57
  headers?: Record<string, string>;
64
58
  initialOffset?: string;
65
59
  }): void;
@@ -1,4 +1,4 @@
1
- import { EntityStreamDB } from "./entity-stream-db-DgzxI6C_.js";
1
+ import { EntityStreamDB } from "./entity-stream-db-Bl6AT5hR.js";
2
2
  import { EntityTimelineContentItem, MessageReceived } from "@electric-ax/agents-runtime";
3
3
  import React from "react";
4
4
 
@@ -40,8 +40,6 @@ declare function MessageInput({
40
40
  baseUrl,
41
41
  entityUrl,
42
42
  identity,
43
- assertedAuthEmail,
44
- assertedAuthName,
45
43
  headers,
46
44
  disabled
47
45
  }: {
@@ -49,8 +47,6 @@ declare function MessageInput({
49
47
  baseUrl: string;
50
48
  entityUrl: string;
51
49
  identity: string;
52
- assertedAuthEmail?: string;
53
- assertedAuthName?: string;
54
50
  headers?: Record<string, string>;
55
51
  disabled: boolean;
56
52
  }): React.ReactElement;
@@ -58,8 +54,6 @@ declare function renderObserve(opts: {
58
54
  entityUrl: string;
59
55
  baseUrl: string;
60
56
  identity: string;
61
- assertedAuthEmail?: string;
62
- assertedAuthName?: string;
63
57
  headers?: Record<string, string>;
64
58
  initialOffset?: string;
65
59
  }): void;
@@ -1,5 +1,5 @@
1
- import { assertedIdentityHeaders, entityApiUrl } from "./entity-api-Dh28Mz7H.js";
2
- import { createEntityStreamDB } from "./entity-stream-db-Czz3S8YF.js";
1
+ import { entityApiUrl } from "./entity-api-DWMhkYbl.js";
2
+ import { createEntityStreamDB } from "./entity-stream-db-CDOlZYc2.js";
3
3
  import { createOptimisticAction } from "@durable-streams/state";
4
4
  import { buildSections, createEntityIncludesQuery, normalizeEntityTimelineData } from "@electric-ax/agents-runtime";
5
5
  import React, { useEffect, useMemo, useRef, useState } from "react";
@@ -117,7 +117,7 @@ function ToolResultView({ result }) {
117
117
  }) : null]
118
118
  });
119
119
  }
120
- function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, assertedAuthName, headers, disabled }) {
120
+ function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
121
121
  const [value, setValue] = useState(``);
122
122
  const [error, setError] = useState(null);
123
123
  const sendAction = useMemo(() => createOptimisticAction({
@@ -134,8 +134,6 @@ function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, ass
134
134
  method: `POST`,
135
135
  headers: {
136
136
  "content-type": `application/json`,
137
- ...assertedIdentityHeaders(assertedAuthEmail),
138
- ...assertedAuthName ? { "x-electric-asserted-name": assertedAuthName } : {},
139
137
  ...headers
140
138
  },
141
139
  body: JSON.stringify({
@@ -162,8 +160,6 @@ function MessageInput({ db, baseUrl, entityUrl, identity, assertedAuthEmail, ass
162
160
  baseUrl,
163
161
  entityUrl,
164
162
  identity,
165
- assertedAuthEmail,
166
- assertedAuthName,
167
163
  headers
168
164
  ]);
169
165
  useInput((input, key) => {
@@ -263,7 +259,7 @@ function WakeView({ section }) {
263
259
  })]
264
260
  });
265
261
  }
266
- function ObserveView({ db, entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers }) {
262
+ function ObserveView({ db, entityUrl, baseUrl, identity, headers }) {
267
263
  const timelineQuery = useMemo(() => createEntityIncludesQuery(db), [db]);
268
264
  const { data: timelineRows = [] } = useLiveQuery(timelineQuery, [timelineQuery]);
269
265
  const timelineData = normalizeEntityTimelineData(timelineRows[0] ?? {
@@ -336,15 +332,13 @@ function ObserveView({ db, entityUrl, baseUrl, identity, assertedAuthEmail, asse
336
332
  baseUrl,
337
333
  entityUrl,
338
334
  identity,
339
- assertedAuthEmail,
340
- assertedAuthName,
341
335
  headers,
342
336
  disabled: closed
343
337
  })
344
338
  ]
345
339
  });
346
340
  }
347
- function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers, initialOffset }) {
341
+ function ObserveApp({ entityUrl, baseUrl, identity, headers, initialOffset }) {
348
342
  const [db, setDb] = useState(null);
349
343
  const [error, setError] = useState(null);
350
344
  const closeRef = useRef(null);
@@ -354,8 +348,6 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
354
348
  baseUrl,
355
349
  entityUrl,
356
350
  initialOffset,
357
- assertedAuthEmail,
358
- assertedAuthName,
359
351
  headers
360
352
  }).then((result) => {
361
353
  if (cancelled) {
@@ -375,8 +367,6 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
375
367
  baseUrl,
376
368
  entityUrl,
377
369
  initialOffset,
378
- assertedAuthEmail,
379
- assertedAuthName,
380
370
  headers
381
371
  ]);
382
372
  if (error) return /* @__PURE__ */ jsx(Box, {
@@ -395,19 +385,15 @@ function ObserveApp({ entityUrl, baseUrl, identity, assertedAuthEmail, assertedA
395
385
  entityUrl,
396
386
  baseUrl,
397
387
  identity,
398
- assertedAuthEmail,
399
- assertedAuthName,
400
388
  headers
401
389
  });
402
390
  }
403
391
  function renderObserve(opts) {
404
- const { entityUrl, baseUrl, identity, assertedAuthEmail, assertedAuthName, headers, initialOffset } = opts;
392
+ const { entityUrl, baseUrl, identity, headers, initialOffset } = opts;
405
393
  const app = render(/* @__PURE__ */ jsx(ObserveApp, {
406
394
  entityUrl,
407
395
  baseUrl,
408
396
  identity,
409
- assertedAuthEmail,
410
- assertedAuthName,
411
397
  headers,
412
398
  initialOffset
413
399
  }));
package/dist/start.cjs CHANGED
@@ -3,6 +3,7 @@ const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
3
  const require_env = require('./env-CFKgT8o2.cjs');
4
4
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
5
5
  const node_url = require_chunk.__toESM(require("node:url"));
6
+ const __electric_ax_agents_server_headers = require_chunk.__toESM(require("@electric-ax/agents/server-headers"));
6
7
  const node_child_process = require_chunk.__toESM(require("node:child_process"));
7
8
  const __electric_ax_agents = require_chunk.__toESM(require("@electric-ax/agents"));
8
9
 
@@ -23,7 +24,6 @@ const DEFAULT_ELECTRIC_AGENTS_PORT = 4437;
23
24
  const DEFAULT_COMPOSE_PROJECT_NAME = `electric-agents`;
24
25
  const DEFAULT_PULL_WAKE_RUNNER_ID = `builtin-agents`;
25
26
  const DEFAULT_PULL_WAKE_OWNER_ID = `builtin-agents`;
26
- const DEFAULT_PULL_WAKE_OWNER_NAME = `Built-in agents`;
27
27
  const DOCKER_COMPOSE_FILE = (0, node_url.fileURLToPath)(new URL(`../docker-compose.full.yml`, require("url").pathToFileURL(__filename).href));
28
28
  function resolveElectricAgentsPort(env = process.env, fileEnv = require_env.readDotEnvFile()) {
29
29
  const raw = env.ELECTRIC_AGENTS_PORT?.trim() || fileEnv.ELECTRIC_AGENTS_PORT?.trim();
@@ -67,22 +67,10 @@ function runnerIdFromIdentity(identity) {
67
67
  return slug ? `builtin-${slug}` : DEFAULT_PULL_WAKE_RUNNER_ID;
68
68
  }
69
69
  function resolvePullWakeRunnerId(env = process.env, fileEnv = require_env.readDotEnvFile()) {
70
- return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_EMAIL`, `ELECTRIC_AGENTS_IDENTITY`]));
70
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]));
71
71
  }
72
72
  function resolvePullWakeOwnerId(env = process.env, fileEnv = require_env.readDotEnvFile()) {
73
- return readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_EMAIL`, `ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
74
- }
75
- function buildAssertedAuthHeaders(env, fileEnv) {
76
- const email = resolvePullWakeOwnerId(env, fileEnv);
77
- const name = readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_NAME`]) ?? DEFAULT_PULL_WAKE_OWNER_NAME;
78
- const headers = {};
79
- headers[`X-Electric-Asserted-Email`] = email;
80
- headers[`X-Electric-Asserted-Name`] = name;
81
- return {
82
- headers,
83
- ownerUserId: email,
84
- name
85
- };
73
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]) ?? readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
86
74
  }
87
75
  function parseAdditionalServerHeaders(env, fileEnv) {
88
76
  const raw = readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
@@ -102,6 +90,9 @@ function parseAdditionalServerHeaders(env, fileEnv) {
102
90
  const normalized = Object.fromEntries(headers.entries());
103
91
  return Object.keys(normalized).length > 0 ? normalized : void 0;
104
92
  }
93
+ function resolveServerHeaders(env, fileEnv) {
94
+ return (0, __electric_ax_agents_server_headers.mergeElectricPrincipalHeader)(parseAdditionalServerHeaders(env, fileEnv), readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]));
95
+ }
105
96
  function mergeHeaders(...sources) {
106
97
  const headers = new Headers();
107
98
  for (const source of sources) {
@@ -169,7 +160,6 @@ async function startElectricAgentsDevEnvironment(_options = {}, env = process.en
169
160
  const fileEnv = require_env.readDotEnvFile(cwd);
170
161
  const port = resolveElectricAgentsPort(env, fileEnv);
171
162
  const composeProjectName = resolveComposeProjectName(cwd, env);
172
- const assertedAuth = buildAssertedAuthHeaders(env, fileEnv);
173
163
  await runDockerCompose([
174
164
  `compose`,
175
165
  `-f`,
@@ -181,10 +171,7 @@ async function startElectricAgentsDevEnvironment(_options = {}, env = process.en
181
171
  COMPOSE_PROJECT_NAME: composeProjectName,
182
172
  ELECTRIC_AGENTS_PORT: String(port),
183
173
  ELECTRIC_IMAGE_TAG: env.ELECTRIC_IMAGE_TAG ?? ELECTRIC_IMAGE_TAG,
184
- ELECTRIC_AGENTS_SERVER_IMAGE_TAG: env.ELECTRIC_AGENTS_SERVER_IMAGE_TAG ?? ELECTRIC_AGENTS_SERVER_IMAGE_TAG,
185
- ELECTRIC_AGENTS_DEV_ASSERTED_AUTH: env.ELECTRIC_AGENTS_DEV_ASSERTED_AUTH ?? fileEnv.ELECTRIC_AGENTS_DEV_ASSERTED_AUTH ?? `1`,
186
- ELECTRIC_ASSERTED_AUTH_EMAIL: env.ELECTRIC_ASSERTED_AUTH_EMAIL ?? fileEnv.ELECTRIC_ASSERTED_AUTH_EMAIL ?? assertedAuth.ownerUserId,
187
- ELECTRIC_ASSERTED_AUTH_NAME: env.ELECTRIC_ASSERTED_AUTH_NAME ?? fileEnv.ELECTRIC_ASSERTED_AUTH_NAME ?? assertedAuth.name
174
+ ELECTRIC_AGENTS_SERVER_IMAGE_TAG: env.ELECTRIC_AGENTS_SERVER_IMAGE_TAG ?? ELECTRIC_AGENTS_SERVER_IMAGE_TAG
188
175
  });
189
176
  const uiUrl = `http://localhost:${port}`;
190
177
  await waitForElectricAgentsServer(uiUrl);
@@ -243,8 +230,8 @@ async function startBuiltinAgentsServer(options, params = {}) {
243
230
  const fileEnv = require_env.readDotEnvFile(cwd);
244
231
  const anthropicApiKey = require_env.resolveAnthropicApiKey(options, env, fileEnv);
245
232
  const runnerId = resolvePullWakeRunnerId(env, fileEnv);
246
- const assertedAuth = buildAssertedAuthHeaders(env, fileEnv);
247
- const serverHeaders = mergeHeaders(assertedAuth.headers, parseAdditionalServerHeaders(env, fileEnv));
233
+ const ownerUserId = resolvePullWakeOwnerId(env, fileEnv);
234
+ const serverHeaders = mergeHeaders(resolveServerHeaders(env, fileEnv));
248
235
  const agentServerUrl = params.agentServerUrl ?? env.ELECTRIC_AGENTS_URL?.trim() ?? `http://localhost:${resolveElectricAgentsPort(env, fileEnv)}`;
249
236
  process.env.ANTHROPIC_API_KEY = anthropicApiKey;
250
237
  await waitForElectricAgentsServer(agentServerUrl, { headers: serverHeaders });
@@ -254,7 +241,7 @@ async function startBuiltinAgentsServer(options, params = {}) {
254
241
  loadProjectMcpConfig: true,
255
242
  pullWake: {
256
243
  runnerId,
257
- ownerUserId: assertedAuth.ownerUserId,
244
+ ownerUserId,
258
245
  registerRunner: true,
259
246
  headers: serverHeaders,
260
247
  claimHeaders: serverHeaders,
package/dist/start.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer } from "./index-BQ4JyfkG.cjs";
1
+ import { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer } from "./index-cwCTPq6Y.cjs";
2
2
  export { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
package/dist/start.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer } from "./index-D6TZ88Yg.js";
1
+ import { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer } from "./index-BSHO_Rei.js";
2
2
  export { StartedBuiltinAgentsEnvironment, StartedDevEnvironment, StoppedDevEnvironment, getStartedBuiltinAgentsMessage, getStartedEnvironmentMessage, getStoppedEnvironmentMessage, readDotEnvFile, resolveAnthropicApiKey, resolveComposeProjectName, resolveElectricAgentsPort, resolvePullWakeOwnerId, resolvePullWakeRunnerId, startBuiltinAgentsServer, startElectricAgentsDevEnvironment, stopElectricAgentsDevEnvironment, waitForElectricAgentsServer };
package/dist/start.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readDotEnvFile$1 as readDotEnvFile, resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-DIhTv987.js";
2
2
  import { appendPathToUrl } from "@electric-ax/agents-runtime";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { mergeElectricPrincipalHeader } from "@electric-ax/agents/server-headers";
4
5
  import { spawn } from "node:child_process";
5
6
  import { BuiltinAgentsServer } from "@electric-ax/agents";
6
7
 
@@ -21,7 +22,6 @@ const DEFAULT_ELECTRIC_AGENTS_PORT = 4437;
21
22
  const DEFAULT_COMPOSE_PROJECT_NAME = `electric-agents`;
22
23
  const DEFAULT_PULL_WAKE_RUNNER_ID = `builtin-agents`;
23
24
  const DEFAULT_PULL_WAKE_OWNER_ID = `builtin-agents`;
24
- const DEFAULT_PULL_WAKE_OWNER_NAME = `Built-in agents`;
25
25
  const DOCKER_COMPOSE_FILE = fileURLToPath(new URL(`../docker-compose.full.yml`, import.meta.url));
26
26
  function resolveElectricAgentsPort(env = process.env, fileEnv = readDotEnvFile()) {
27
27
  const raw = env.ELECTRIC_AGENTS_PORT?.trim() || fileEnv.ELECTRIC_AGENTS_PORT?.trim();
@@ -65,22 +65,10 @@ function runnerIdFromIdentity(identity) {
65
65
  return slug ? `builtin-${slug}` : DEFAULT_PULL_WAKE_RUNNER_ID;
66
66
  }
67
67
  function resolvePullWakeRunnerId(env = process.env, fileEnv = readDotEnvFile()) {
68
- return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_EMAIL`, `ELECTRIC_AGENTS_IDENTITY`]));
68
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`]) ?? runnerIdFromIdentity(readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]));
69
69
  }
70
70
  function resolvePullWakeOwnerId(env = process.env, fileEnv = readDotEnvFile()) {
71
- return readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_EMAIL`, `ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
72
- }
73
- function buildAssertedAuthHeaders(env, fileEnv) {
74
- const email = resolvePullWakeOwnerId(env, fileEnv);
75
- const name = readConfigValue(env, fileEnv, [`ELECTRIC_ASSERTED_AUTH_NAME`]) ?? DEFAULT_PULL_WAKE_OWNER_NAME;
76
- const headers = {};
77
- headers[`X-Electric-Asserted-Email`] = email;
78
- headers[`X-Electric-Asserted-Name`] = name;
79
- return {
80
- headers,
81
- ownerUserId: email,
82
- name
83
- };
71
+ return readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]) ?? readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_IDENTITY`]) ?? DEFAULT_PULL_WAKE_OWNER_ID;
84
72
  }
85
73
  function parseAdditionalServerHeaders(env, fileEnv) {
86
74
  const raw = readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
@@ -100,6 +88,9 @@ function parseAdditionalServerHeaders(env, fileEnv) {
100
88
  const normalized = Object.fromEntries(headers.entries());
101
89
  return Object.keys(normalized).length > 0 ? normalized : void 0;
102
90
  }
91
+ function resolveServerHeaders(env, fileEnv) {
92
+ return mergeElectricPrincipalHeader(parseAdditionalServerHeaders(env, fileEnv), readConfigValue(env, fileEnv, [`ELECTRIC_AGENTS_PRINCIPAL`]));
93
+ }
103
94
  function mergeHeaders(...sources) {
104
95
  const headers = new Headers();
105
96
  for (const source of sources) {
@@ -167,7 +158,6 @@ async function startElectricAgentsDevEnvironment(_options = {}, env = process.en
167
158
  const fileEnv = readDotEnvFile(cwd);
168
159
  const port = resolveElectricAgentsPort(env, fileEnv);
169
160
  const composeProjectName = resolveComposeProjectName(cwd, env);
170
- const assertedAuth = buildAssertedAuthHeaders(env, fileEnv);
171
161
  await runDockerCompose([
172
162
  `compose`,
173
163
  `-f`,
@@ -179,10 +169,7 @@ async function startElectricAgentsDevEnvironment(_options = {}, env = process.en
179
169
  COMPOSE_PROJECT_NAME: composeProjectName,
180
170
  ELECTRIC_AGENTS_PORT: String(port),
181
171
  ELECTRIC_IMAGE_TAG: env.ELECTRIC_IMAGE_TAG ?? ELECTRIC_IMAGE_TAG,
182
- ELECTRIC_AGENTS_SERVER_IMAGE_TAG: env.ELECTRIC_AGENTS_SERVER_IMAGE_TAG ?? ELECTRIC_AGENTS_SERVER_IMAGE_TAG,
183
- ELECTRIC_AGENTS_DEV_ASSERTED_AUTH: env.ELECTRIC_AGENTS_DEV_ASSERTED_AUTH ?? fileEnv.ELECTRIC_AGENTS_DEV_ASSERTED_AUTH ?? `1`,
184
- ELECTRIC_ASSERTED_AUTH_EMAIL: env.ELECTRIC_ASSERTED_AUTH_EMAIL ?? fileEnv.ELECTRIC_ASSERTED_AUTH_EMAIL ?? assertedAuth.ownerUserId,
185
- ELECTRIC_ASSERTED_AUTH_NAME: env.ELECTRIC_ASSERTED_AUTH_NAME ?? fileEnv.ELECTRIC_ASSERTED_AUTH_NAME ?? assertedAuth.name
172
+ ELECTRIC_AGENTS_SERVER_IMAGE_TAG: env.ELECTRIC_AGENTS_SERVER_IMAGE_TAG ?? ELECTRIC_AGENTS_SERVER_IMAGE_TAG
186
173
  });
187
174
  const uiUrl = `http://localhost:${port}`;
188
175
  await waitForElectricAgentsServer(uiUrl);
@@ -241,8 +228,8 @@ async function startBuiltinAgentsServer(options, params = {}) {
241
228
  const fileEnv = readDotEnvFile(cwd);
242
229
  const anthropicApiKey = resolveAnthropicApiKey(options, env, fileEnv);
243
230
  const runnerId = resolvePullWakeRunnerId(env, fileEnv);
244
- const assertedAuth = buildAssertedAuthHeaders(env, fileEnv);
245
- const serverHeaders = mergeHeaders(assertedAuth.headers, parseAdditionalServerHeaders(env, fileEnv));
231
+ const ownerUserId = resolvePullWakeOwnerId(env, fileEnv);
232
+ const serverHeaders = mergeHeaders(resolveServerHeaders(env, fileEnv));
246
233
  const agentServerUrl = params.agentServerUrl ?? env.ELECTRIC_AGENTS_URL?.trim() ?? `http://localhost:${resolveElectricAgentsPort(env, fileEnv)}`;
247
234
  process.env.ANTHROPIC_API_KEY = anthropicApiKey;
248
235
  await waitForElectricAgentsServer(agentServerUrl, { headers: serverHeaders });
@@ -252,7 +239,7 @@ async function startBuiltinAgentsServer(options, params = {}) {
252
239
  loadProjectMcpConfig: true,
253
240
  pullWake: {
254
241
  runnerId,
255
- ownerUserId: assertedAuth.ownerUserId,
242
+ ownerUserId,
256
243
  registerRunner: true,
257
244
  headers: serverHeaders,
258
245
  claimHeaders: serverHeaders,
@@ -59,9 +59,6 @@ services:
59
59
  ELECTRIC_AGENTS_STREAMS_PORT: ${ELECTRIC_AGENTS_STREAMS_PORT:-0}
60
60
  ELECTRIC_AGENTS_ELECTRIC_URL: ${ELECTRIC_AGENTS_ELECTRIC_URL:-http://electric:3000}
61
61
  ELECTRIC_AGENTS_REWRITE_LOOPBACK_WEBHOOKS_TO: ${ELECTRIC_AGENTS_REWRITE_LOOPBACK_WEBHOOKS_TO:-host.docker.internal}
62
- ELECTRIC_AGENTS_DEV_ASSERTED_AUTH: ${ELECTRIC_AGENTS_DEV_ASSERTED_AUTH:-1}
63
- ELECTRIC_ASSERTED_AUTH_EMAIL: ${ELECTRIC_ASSERTED_AUTH_EMAIL:-builtin-agents}
64
- ELECTRIC_ASSERTED_AUTH_NAME: ${ELECTRIC_ASSERTED_AUTH_NAME:-Built-in agents}
65
62
  ports:
66
63
  - '${ELECTRIC_AGENTS_PORT:-4437}:4437'
67
64
  volumes:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electric-ax",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "CLI for Electric Agents",
5
5
  "author": "ElectricSQL team and contributors",
6
6
  "license": "Apache-2.0",
@@ -39,15 +39,15 @@
39
39
  "dependencies": {
40
40
  "@durable-streams/client": "https://pkg.pr.new/durable-streams/durable-streams/@durable-streams/client@350",
41
41
  "@durable-streams/state": "https://pkg.pr.new/durable-streams/durable-streams/@durable-streams/state@350",
42
- "@electric-sql/client": "^1.5.17",
42
+ "@electric-sql/client": "^1.5.18",
43
43
  "@tanstack/db": "^0.6.4",
44
44
  "@tanstack/react-db": "^0.1.82",
45
45
  "commander": "^13.1.0",
46
46
  "ink": "^6.8.0",
47
47
  "omelette": "^0.4.17",
48
48
  "react": "^19.2.0",
49
- "@electric-ax/agents": "0.4.0",
50
- "@electric-ax/agents-runtime": "0.2.0"
49
+ "@electric-ax/agents": "0.4.2",
50
+ "@electric-ax/agents-runtime": "0.2.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@vitest/coverage-v8": "^4.1.0",