@themoltnet/agent-daemon 0.55.0 → 0.55.1

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 (2) hide show
  1. package/dist/cli.js +32 -33
  2. package/package.json +8 -8
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ import { AgentRuntime, ApiTaskReporter, ApiTaskSource, PollingApiTaskSource, cre
14
14
  import { GuestEnvironmentBoundaryError, assertGuestEnvironmentBoundary, createPiRetryTriage, findMainWorktree, isResolvedPathInsideRoot, normalizeRetryTriageResult, redactRetryTriageSecrets, resolveRuntimeProfileModel } from "@themoltnet/pi-runtime";
15
15
  import { FILE_SECRET_PROVIDER, FileSecretProvider, connect, createNodeSecretProviderRegistry } from "@themoltnet/sdk/node";
16
16
  import { constants, createReadStream, createWriteStream, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
17
- import { AuthenticationError, IDENTITY_ALIAS_PATTERN, MoltNetError, agentKeyKey, assertIdentityAlias, assertTrustedConfigApiUrl, createExecutorAttestor, deriveMcpUrl, formatSecretReferenceString, getConfigDir, getIdentityDir, identitySeedKey, isCanonicalConfig, parseSecretReferenceString, readConfig, register, requireSecureCredentialApiUrl, resolveAgentKey, resolveEnvSecretReference, resolveIdentitySeed, resolveOAuth2ClientSecret } from "@themoltnet/sdk";
17
+ import { AuthenticationError, IDENTITY_ALIAS_PATTERN, MoltNetError, agentKeyKey, assertIdentityAlias, assertTrustedConfigApiUrl, createExecutorAttestor, deriveMcpUrl, formatSecretReferenceString, getConfigDir, getIdentityDir, identitySeedKey, isCanonicalConfig, parseSecretReferenceString, readConfig, register, requireSecureCredentialApiUrl, resolveAgentKey, resolveEnvSecretReference, resolveIdentitySeed } from "@themoltnet/sdk";
18
18
  import { execFile, spawn } from "node:child_process";
19
19
  import { X509Certificate, createHash, createPrivateKey, createPublicKey, randomBytes, randomUUID, timingSafeEqual, webcrypto } from "node:crypto";
20
20
  import { once } from "node:events";
@@ -5292,16 +5292,16 @@ function validateTaskTypes(types) {
5292
5292
  /**
5293
5293
  * OTel SDK bootstrap for the agent daemon.
5294
5294
  *
5295
- * const shutdown = await initWorkerOtel({ serviceName, agentDir });
5295
+ * const shutdown = await initWorkerOtel({ serviceName, agent });
5296
5296
  * try { ... } finally { await shutdown(); }
5297
5297
  *
5298
5298
  * No-op when MOLTNET_OTEL_ENDPOINT is unset — `@opentelemetry/api` falls
5299
5299
  * back to no-op tracers and meters, so the runtime + pi extension still
5300
5300
  * call into it but nothing is exported.
5301
5301
  */
5302
- async function initWorkerOtel(options) {
5302
+ function initWorkerOtel(options) {
5303
5303
  const endpoint = options.endpoint;
5304
- if (!endpoint) return async () => {};
5304
+ if (!endpoint) return Promise.resolve(async () => {});
5305
5305
  const resource = resourceFromAttributes({
5306
5306
  [ATTR_SERVICE_NAME]: options.serviceName,
5307
5307
  ...options.serviceVersion && { [ATTR_SERVICE_VERSION]: options.serviceVersion },
@@ -5309,11 +5309,7 @@ async function initWorkerOtel(options) {
5309
5309
  ...options.resourceAttributes
5310
5310
  });
5311
5311
  let headersFactory;
5312
- let agent = options.agent;
5313
- if (!agent && options.agentDir) agent = await connect({
5314
- configDir: options.agentDir,
5315
- secretProviders: createNodeSecretProviderRegistry()
5316
- });
5312
+ const agent = options.agent;
5317
5313
  if (agent) headersFactory = async () => {
5318
5314
  return { Authorization: `Bearer ${await agent.getToken()}` };
5319
5315
  };
@@ -5338,7 +5334,7 @@ async function initWorkerOtel(options) {
5338
5334
  });
5339
5335
  provider.register();
5340
5336
  metrics.setGlobalMeterProvider(meterProvider);
5341
- return async () => {
5337
+ return Promise.resolve(async () => {
5342
5338
  await Promise.all([provider.forceFlush().catch((err) => {
5343
5339
  process.stderr.write(`[otel-bootstrap] trace forceFlush failed: ${err instanceof Error ? err.message : String(err)}\n`);
5344
5340
  }), meterProvider.forceFlush().catch((err) => {
@@ -5349,7 +5345,7 @@ async function initWorkerOtel(options) {
5349
5345
  }), meterProvider.shutdown().catch((err) => {
5350
5346
  process.stderr.write(`[otel-bootstrap] metric shutdown failed: ${err instanceof Error ? err.message : String(err)}\n`);
5351
5347
  })]);
5352
- };
5348
+ });
5353
5349
  }
5354
5350
  //#endregion
5355
5351
  //#region src/lib/pi-agent-dir.ts
@@ -6086,11 +6082,12 @@ async function runPolling(opts) {
6086
6082
  throw error;
6087
6083
  }
6088
6084
  })();
6085
+ const daemonRootDir = explicitAgentRootDir ?? process.cwd();
6089
6086
  const resolvedProfiles = await resolveRuntimeProfiles({
6090
6087
  agent: ctx.agent,
6091
6088
  profiles: profileValues,
6092
6089
  teamId,
6093
- cwd: ctx.agentRootDir
6090
+ cwd: daemonRootDir
6094
6091
  });
6095
6092
  const runtimeAdapter = opts.runtimeAdapter ?? defaultPiDaemonAdapter;
6096
6093
  const preparedRuntimes = /* @__PURE__ */ new Map();
@@ -6743,11 +6740,12 @@ async function runOnce(argv, runtimeAdapter = defaultPiDaemonAdapter) {
6743
6740
  throw error;
6744
6741
  }
6745
6742
  })();
6743
+ const daemonRootDir = explicitAgentRootDir ?? process.cwd();
6746
6744
  const profile = await resolveRuntimeProfile({
6747
6745
  agent: ctx.agent,
6748
6746
  profile: values.profile,
6749
6747
  teamId: values.team,
6750
- cwd: ctx.agentRootDir
6748
+ cwd: daemonRootDir
6751
6749
  });
6752
6750
  assertRuntimeAdapterSupportsProfile(runtimeAdapter, profile);
6753
6751
  const preparedRuntime = attestPreparedRuntime(await runtimeAdapter.prepare({ profile }), signingPrivateKey);
@@ -8395,8 +8393,7 @@ async function attachExternalAgent(store, secretProviders, input, connectAgent =
8395
8393
  externalAgentLocation(configPath);
8396
8394
  const config = await readCurrentConfig(configPath);
8397
8395
  const configApiUrl = requireTrustedConfigApiUrl(config, configPath);
8398
- const effectiveApiUrl = requireTrustedApiOverride(input.apiUrl, configApiUrl, configPath);
8399
- const whoami = await authenticateConfig(input.configDir, effectiveApiUrl, secretProviders, connectAgent, input.signal);
8396
+ const whoami = await authenticateConfig(config, configPath, requireTrustedApiOverride(input.apiUrl, configApiUrl, configPath), secretProviders, connectAgent, input.signal);
8400
8397
  const identity = identityFromConfig(config);
8401
8398
  assertIdentityMatches(identity, whoami, `external config ${configPath}`, "authenticated whoami");
8402
8399
  assertSubjectMatches(whoami, config, "authenticated whoami", `external config ${configPath}`);
@@ -8473,7 +8470,7 @@ async function verifyExternalActivation(activation, secretProviders, connectAgen
8473
8470
  const effectiveApiUrl = requireTrustedApiOverride(activation.apiUrl, activation.configApiUrl, activation.configPath);
8474
8471
  return {
8475
8472
  config,
8476
- whoami: await authenticateConfig(dirname(activation.configPath), effectiveApiUrl, secretProviders, connectAgent, signal)
8473
+ whoami: await authenticateConfig(config, activation.configPath, effectiveApiUrl, secretProviders, connectAgent, signal)
8477
8474
  };
8478
8475
  }
8479
8476
  /** Never let request or activation metadata redirect persisted credentials. */
@@ -8533,12 +8530,18 @@ function externalAgentLocation(configPath) {
8533
8530
  agentRoot: dirname(moltnetDir)
8534
8531
  };
8535
8532
  }
8536
- async function authenticateConfig(configDir, apiUrl, secretProviders, connectAgent, signal) {
8533
+ async function authenticateConfig(config, configPath, apiUrl, secretProviders, connectAgent, signal) {
8534
+ let agentKey;
8535
+ try {
8536
+ agentKey = await resolveAgentKey(config, secretProviders);
8537
+ } catch (cause) {
8538
+ throw verificationError(`could not resolve the daemon agent key from ${configPath}`, cause);
8539
+ }
8540
+ if (!agentKey) throw new AgentServerIdentityError("unsupported_credential", `external daemon config at ${configPath} must contain an agent_key_ref`);
8537
8541
  return callWhoami(connectAgent, {
8538
- configDir,
8539
- ...apiUrl ? { apiUrl } : {},
8540
- secretProviders
8541
- }, configDir, signal);
8542
+ agentKey,
8543
+ ...apiUrl ? { apiUrl } : {}
8544
+ }, configPath, signal);
8542
8545
  }
8543
8546
  async function callWhoami(connectAgent, options, source, signal) {
8544
8547
  try {
@@ -8730,14 +8733,9 @@ var RunManager = class {
8730
8733
  env["MOLTNET_API_URL"] = activation.apiUrl ?? activation.configApiUrl;
8731
8734
  try {
8732
8735
  const agentKey = await resolveAgentKey(config, this.options.externalSecretProviders);
8733
- if (agentKey) {
8734
- env["MOLTNET_AGENT_KEY"] = agentKey;
8735
- env["MOLTNET_PRIVATE_KEY"] = await resolveIdentitySeed(config, this.options.externalSecretProviders);
8736
- } else if (config.oauth2?.client_secret_ref) {
8737
- env["MOLTNET_CLIENT_ID"] = config.oauth2.client_id;
8738
- env["MOLTNET_CLIENT_SECRET"] = await resolveOAuth2ClientSecret(config, this.options.externalSecretProviders);
8739
- }
8740
- if (!agentKey && config.keys.private_key_ref) env["MOLTNET_PRIVATE_KEY"] = await resolveIdentitySeed(config, this.options.externalSecretProviders);
8736
+ if (!agentKey) throw new Error("external daemon config has no agent key");
8737
+ env["MOLTNET_AGENT_KEY"] = agentKey;
8738
+ env["MOLTNET_PRIVATE_KEY"] = await resolveIdentitySeed(config, this.options.externalSecretProviders);
8741
8739
  } catch {
8742
8740
  throw new AgentServerRunError("invalid_spec", `external credentials for "${activation.alias}" could not be projected`);
8743
8741
  }
@@ -8947,10 +8945,11 @@ var RunManager = class {
8947
8945
  apiUrl: activation.apiUrl
8948
8946
  });
8949
8947
  }
8948
+ const agentKey = await resolveAgentKey(config, this.options.externalSecretProviders);
8949
+ if (!agentKey) throw new AgentServerRunError("invalid_spec", `external agent "${activation.alias}" has no agent key`);
8950
8950
  return connect({
8951
- configDir: dirname(activation.configPath),
8952
- apiUrl: activation.apiUrl ?? activation.configApiUrl,
8953
- secretProviders: this.options.externalSecretProviders
8951
+ agentKey,
8952
+ apiUrl: activation.apiUrl ?? activation.configApiUrl
8954
8953
  });
8955
8954
  }
8956
8955
  stop(id) {
@@ -11053,7 +11052,7 @@ async function writeCache(cache) {
11053
11052
  }
11054
11053
  //#endregion
11055
11054
  //#region src/version.ts
11056
- var DAEMON_VERSION = "0.55.0";
11055
+ var DAEMON_VERSION = "0.55.1";
11057
11056
  //#endregion
11058
11057
  //#region src/cli.ts
11059
11058
  async function runAgentDaemonCli(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@themoltnet/agent-daemon",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "description": "Universal MoltNet agent daemon host with a built-in Pi/Gondolin runtime and support for trusted operator-owned runtime modules. CLI: moltnet-agent.",
@@ -85,10 +85,10 @@
85
85
  "proper-lockfile": "4.1.2",
86
86
  "reflect-metadata": "^0.2.2",
87
87
  "typebox": "^1.2.8",
88
- "@themoltnet/agent-runtime": "1.0.0",
89
- "@themoltnet/pi-runtime": "0.15.0",
88
+ "@themoltnet/agent-runtime": "1.0.1",
90
89
  "@themoltnet/os-keyring": "0.3.0",
91
- "@themoltnet/sdk": "0.141.0"
90
+ "@themoltnet/pi-runtime": "0.15.1",
91
+ "@themoltnet/sdk": "0.141.1"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@fastify/swagger": "^9.6.1",
@@ -99,15 +99,15 @@
99
99
  "vite-plugin-dts": "^4.5.4",
100
100
  "vitest": "^3.0.0",
101
101
  "@moltnet/bootstrap": "0.1.0",
102
- "@moltnet/crypto-service": "0.1.0",
103
- "@moltnet/execution-integrations": "0.1.0",
104
102
  "@moltnet/agent-eval": "0.1.0",
103
+ "@moltnet/crypto-service": "0.1.0",
105
104
  "@moltnet/execution-plan": "0.1.0",
105
+ "@moltnet/execution-integrations": "0.1.0",
106
106
  "@moltnet/loopback-companion": "0.1.0",
107
107
  "@moltnet/models": "0.1.0",
108
- "@moltnet/tasks": "0.1.0",
109
108
  "@moltnet/observability": "0.1.0",
110
- "@moltnet/runtime-profiles": "0.1.0"
109
+ "@moltnet/runtime-profiles": "0.1.0",
110
+ "@moltnet/tasks": "0.1.0"
111
111
  },
112
112
  "nx": {
113
113
  "projectType": "application",