@agentchatme/agent-core 0.0.1313111111112 → 0.0.1313111111113

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,7 +1,7 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { z } from 'zod';
3
- import { T as TurnContext, a as TurnDisposition, R as RuntimeAdapter } from './adapter-types-C_kf-KtV.js';
4
- export { A as AutonomyMode, F as FullAutonomyTurnContext, P as PendingReason, b as PendingTurnRequest, S as SilentReason, c as TurnBatchContext, d as TurnMentionContext, e as TurnResult } from './adapter-types-C_kf-KtV.js';
3
+ import { T as TurnContext, a as TurnDisposition, R as RuntimeAdapter } from './adapter-types-DrrsKZYk.js';
4
+ export { A as AutonomyMode, F as FullAutonomyTurnContext, P as PendingReason, b as PendingTurnRequest, S as SilentReason, c as TurnBatchContext, d as TurnMentionContext, e as TurnResult } from './adapter-types-DrrsKZYk.js';
5
5
 
6
6
  declare const SyncRowSchema: z.ZodObject<{
7
7
  id: z.ZodString;
@@ -214,15 +214,11 @@ declare class Daemon {
214
214
  private readonly foregroundDeferrals;
215
215
  private stopping;
216
216
  private heartbeatTimer;
217
- private readonly installation;
218
- private mirroredPendingFingerprint;
219
- private pendingMirrorSyncedAt;
220
217
  constructor(cfg: DaemonConfig, adapter: RuntimeAdapter, ws?: AgentWsClient, // injectable for tests; defaults to a real socket
221
218
  /** Called when the socket gives up for good (auth refused). The supervisor
222
219
  * above decides what happens next — this class does not end the process. */
223
220
  onTerminal?: ((failure: DaemonFailure) => void) | undefined);
224
221
  start(): Promise<void>;
225
- private syncPendingMirror;
226
222
  stop(): void;
227
223
  private onInbound;
228
224
  /** Queue one already-tracked row and ensure exactly one worker for its conversation. */
@@ -2,6 +2,7 @@ import {
2
2
  CODING_AGENTS_CLIENT_HEADERS,
3
3
  PendingReasonSchema,
4
4
  acquireLeaderLock,
5
+ atomicWriteFile,
5
6
  beat,
6
7
  credentialsPath,
7
8
  external_exports,
@@ -9,17 +10,12 @@ import {
9
10
  fullAutonomyAllows,
10
11
  getMeLite,
11
12
  idle,
12
- installationId,
13
- listPendingRequests,
14
13
  log,
15
- notifyPendingRequest,
16
- pendingRequestsFingerprint,
17
14
  readFullAutonomyPolicy,
18
15
  recordDaemonActivity,
19
- recordPendingRequestWithStatus,
20
- resolveIdentity,
21
- syncPendingReviewMirror
22
- } from "./chunk-KIP2JKPQ.js";
16
+ recordPendingRequest,
17
+ resolveIdentity
18
+ } from "./chunk-ATDAOJ27.js";
23
19
 
24
20
  // src/daemon/ws-client.ts
25
21
  import { WebSocket } from "ws";
@@ -562,8 +558,8 @@ function resolveTurnDisposition(sent, reported) {
562
558
  }
563
559
 
564
560
  // src/daemon/run.ts
565
- import * as path2 from "path";
566
- import * as fs from "fs";
561
+ import * as path3 from "path";
562
+ import * as fs2 from "fs";
567
563
 
568
564
  // src/daemon/config.ts
569
565
  import * as path from "path";
@@ -597,6 +593,9 @@ async function resolveDaemonConfig(opts) {
597
593
  }
598
594
 
599
595
  // src/daemon/loop.ts
596
+ import * as crypto from "crypto";
597
+ import * as fs from "fs";
598
+ import * as path2 from "path";
600
599
  var MAX_TIMER_MS = 2147483647;
601
600
  function positiveBoundedEnv(name, fallback) {
602
601
  const parsed = Number(process.env[name]);
@@ -611,7 +610,6 @@ var MAX_BATCH_MESSAGES = 30;
611
610
  var BATCH_SETTLE_MS = nonNegativeBoundedEnv("AGENTCHATD_BATCH_SETTLE_MS", 100);
612
611
  var MENTION_PREVIEW_MAX = 280;
613
612
  var HEARTBEAT_MS = 3e4;
614
- var PENDING_MIRROR_REFRESH_MS = 12 * 60 * 6e4;
615
613
  var SEEN_TTL_MS = 24 * 60 * 6e4;
616
614
  var MAX_COMPLETED_SEEN = 1e4;
617
615
  var PAUSE_AT_PENDING = Math.max(
@@ -651,12 +649,27 @@ function dispositionOf(result) {
651
649
  if (result.disposition) return result.disposition;
652
650
  return result.detail === "replied" ? { action: "replied" } : { action: "silent", reason: "other" };
653
651
  }
652
+ function installationId(home) {
653
+ const file = path2.join(home, "daemon.installation-id");
654
+ try {
655
+ const existing = fs.readFileSync(file, "utf-8").trim();
656
+ if (/^[0-9a-f-]{36}$/i.test(existing)) return existing;
657
+ } catch {
658
+ }
659
+ const id = crypto.randomUUID();
660
+ try {
661
+ atomicWriteFile(file, `${id}
662
+ `, 384);
663
+ } catch (err) {
664
+ log.warn(`could not persist daemon installation id: ${String(err)}`);
665
+ }
666
+ return id;
667
+ }
654
668
  var Daemon = class {
655
669
  constructor(cfg, adapter, ws, onTerminal) {
656
670
  this.cfg = cfg;
657
671
  this.adapter = adapter;
658
672
  this.onTerminal = onTerminal;
659
- this.installation = installationId(cfg.home);
660
673
  this.coord = new ReplyCoord({
661
674
  apiKey: cfg.apiKey,
662
675
  apiBase: cfg.apiBase,
@@ -693,41 +706,18 @@ var Daemon = class {
693
706
  foregroundDeferrals = /* @__PURE__ */ new Map();
694
707
  stopping = false;
695
708
  heartbeatTimer = null;
696
- installation;
697
- mirroredPendingFingerprint = null;
698
- pendingMirrorSyncedAt = 0;
699
709
  async start() {
700
710
  const pre = await this.adapter.preflight();
701
711
  if (!pre.ok) {
702
712
  throw new Error(`runtime (${this.adapter.name}) not ready: ${pre.detail}`);
703
713
  }
704
714
  log.info(`agentchat daemon up as @${this.cfg.handle} via ${this.adapter.name}; holding the wire`);
705
- void this.syncPendingMirror(true);
706
715
  this.ws.start();
707
716
  this.heartbeatTimer = setInterval(() => {
708
- if (this.ws.connected) {
709
- beat(this.cfg.home);
710
- void this.syncPendingMirror();
711
- }
717
+ if (this.ws.connected) beat(this.cfg.home);
712
718
  }, HEARTBEAT_MS);
713
719
  this.heartbeatTimer.unref();
714
720
  }
715
- async syncPendingMirror(force = false) {
716
- const records = listPendingRequests(this.cfg.home, this.cfg.handle);
717
- const fingerprint2 = pendingRequestsFingerprint(records);
718
- if (!force && fingerprint2 === this.mirroredPendingFingerprint && Date.now() - this.pendingMirrorSyncedAt < PENDING_MIRROR_REFRESH_MS) return;
719
- try {
720
- await syncPendingReviewMirror(
721
- { apiKey: this.cfg.apiKey, apiBase: this.cfg.apiBase },
722
- this.installation,
723
- records
724
- );
725
- this.mirroredPendingFingerprint = fingerprint2;
726
- this.pendingMirrorSyncedAt = Date.now();
727
- } catch (err) {
728
- log.warn(`pending-review dashboard mirror unavailable: ${String(err)}`);
729
- }
730
- }
731
721
  stop() {
732
722
  this.stopping = true;
733
723
  if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
@@ -920,12 +910,7 @@ var Daemon = class {
920
910
  summary: disposition.pending.summary
921
911
  };
922
912
  try {
923
- const persisted = recordPendingRequestWithStatus(
924
- this.cfg.home,
925
- pendingInput
926
- );
927
- if (persisted.changed) notifyPendingRequest(persisted.record);
928
- await this.syncPendingMirror();
913
+ recordPendingRequest(this.cfg.home, pendingInput);
929
914
  pendingPersistence = null;
930
915
  } catch (err) {
931
916
  pendingPersistence = { result, input: pendingInput };
@@ -1140,28 +1125,28 @@ function fingerprint(home) {
1140
1125
  return id === null ? null : `${id.apiKey}:${id.handle ?? ""}`;
1141
1126
  }
1142
1127
  function boundDaemonLog(home) {
1143
- const file = path2.join(home, "daemon.log");
1128
+ const file = path3.join(home, "daemon.log");
1144
1129
  try {
1145
- const size = fs.statSync(file).size;
1130
+ const size = fs2.statSync(file).size;
1146
1131
  if (size <= MAX_LOG_BYTES) return;
1147
- const fd = fs.openSync(file, "r");
1132
+ const fd = fs2.openSync(file, "r");
1148
1133
  try {
1149
1134
  const keep = Buffer.alloc(Math.min(KEEP_LOG_BYTES, size));
1150
- fs.readSync(fd, keep, 0, keep.length, size - keep.length);
1151
- fs.writeFileSync(
1135
+ fs2.readSync(fd, keep, 0, keep.length, size - keep.length);
1136
+ fs2.writeFileSync(
1152
1137
  file,
1153
1138
  `[agentchat:info] older daemon log output truncated at ${(/* @__PURE__ */ new Date()).toISOString()}
1154
1139
  ${keep.toString("utf-8")}`
1155
1140
  );
1156
1141
  } finally {
1157
- fs.closeSync(fd);
1142
+ fs2.closeSync(fd);
1158
1143
  }
1159
1144
  } catch {
1160
1145
  }
1161
1146
  }
1162
1147
  async function runDaemon(opts) {
1163
- const home = path2.resolve(opts.home);
1164
- const workdir = opts.workdir ?? path2.join(home, "daemon-workdir");
1148
+ const home = path3.resolve(opts.home);
1149
+ const workdir = opts.workdir ?? path3.join(home, "daemon-workdir");
1165
1150
  boundDaemonLog(home);
1166
1151
  if (process.env["AGENTCHAT_LOG_LEVEL"] === void 0) process.env["AGENTCHAT_LOG_LEVEL"] = "info";
1167
1152
  const lock = acquireLeaderLock(home);
@@ -1195,8 +1180,8 @@ async function runDaemon(opts) {
1195
1180
  process.on("SIGTERM", () => shutdown("SIGTERM"));
1196
1181
  let nudged = false;
1197
1182
  try {
1198
- fs.mkdirSync(home, { recursive: true });
1199
- const watcher = fs.watch(home, (_event, filename) => {
1183
+ fs2.mkdirSync(home, { recursive: true });
1184
+ const watcher = fs2.watch(home, (_event, filename) => {
1200
1185
  if (filename === null || String(filename).startsWith("credentials")) nudged = true;
1201
1186
  });
1202
1187
  watcher.on("error", (err) => {