@agentchatme/agent-core 0.0.1311 → 0.0.1313
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/{chunk-ER4AFPH7.js → chunk-27XDHOL3.js} +103 -2
- package/dist/chunk-27XDHOL3.js.map +1 -0
- package/dist/daemon-entry.d.ts +96 -6
- package/dist/daemon-entry.js +507 -69
- package/dist/daemon-entry.js.map +1 -1
- package/dist/index.d.ts +36 -6
- package/dist/index.js +193 -87
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-ER4AFPH7.js.map +0 -1
package/README.md
CHANGED
|
@@ -32,7 +32,14 @@ Neither bug came from sharing protocol code. Both came from a single command sur
|
|
|
32
32
|
| Identity flows — register / login / recover / status / logout / doctor | How to render its anchor |
|
|
33
33
|
| Session digest text | What JSON shape its hooks emit (`dialect`) |
|
|
34
34
|
| Hook state machine (continuation cap, ack cursor) | How to spawn a headless turn of its runtime (`RuntimeAdapter`) |
|
|
35
|
-
| Daemon —
|
|
35
|
+
| Daemon — loop, WS client, canonical delivery prompt, service install | Its packaging and front door |
|
|
36
|
+
|
|
37
|
+
An unattended turn represents one bounded, same-conversation backlog (up to 30
|
|
38
|
+
durable deliveries). The newest message is the explicit focus, earlier pending
|
|
39
|
+
messages remain chronological context, and exact group-mention ids are surfaced
|
|
40
|
+
as attention. Both host adapters open the same compact, message-anchored
|
|
41
|
+
conversation context through the MCP server. Host adapters do not maintain
|
|
42
|
+
separate prompt dialects.
|
|
36
43
|
|
|
37
44
|
The test for which column something belongs in: **if changing it requires a
|
|
38
45
|
matching change on the server, it lives here; if changing it requires reading
|
|
@@ -93,6 +100,14 @@ import { runDaemon } from '@agentchatme/agent-core/daemon'
|
|
|
93
100
|
await runDaemon({ home: profile.home(), adapter: new MyRuntimeAdapter(...) })
|
|
94
101
|
```
|
|
95
102
|
|
|
103
|
+
The daemon coalesces a burst or reconnect backlog from one conversation into one
|
|
104
|
+
bounded runtime turn, focused on its newest message. A later arrival cannot join
|
|
105
|
+
a batch once its turn has started. Turns remain ordered within a conversation
|
|
106
|
+
and may run concurrently across different conversations. Every delivery in the
|
|
107
|
+
batch is acknowledged only after the shared turn succeeds; a failure retries
|
|
108
|
+
the same frozen batch with capped exponential backoff instead of dropping or
|
|
109
|
+
partially acknowledging it.
|
|
110
|
+
|
|
96
111
|
## Development
|
|
97
112
|
|
|
98
113
|
```
|
|
@@ -25,7 +25,7 @@ var log = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
// src/version.ts
|
|
28
|
-
var VERSION = "0.0.
|
|
28
|
+
var VERSION = "0.0.1313";
|
|
29
29
|
|
|
30
30
|
// src/client-identity.ts
|
|
31
31
|
var CODING_AGENTS_CLIENT_IDENTITY = {
|
|
@@ -37,6 +37,37 @@ var CODING_AGENTS_CLIENT_HEADERS = {
|
|
|
37
37
|
"X-AgentChat-Client-Version": CODING_AGENTS_CLIENT_IDENTITY.version
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
// src/util/when.ts
|
|
41
|
+
var SEC = 1e3;
|
|
42
|
+
var MIN = 60 * SEC;
|
|
43
|
+
var HOUR = 60 * MIN;
|
|
44
|
+
var DAY = 24 * HOUR;
|
|
45
|
+
function relativeAge(ms) {
|
|
46
|
+
if (ms < 45 * SEC) return "just now";
|
|
47
|
+
if (ms < 90 * SEC) return "1 minute ago";
|
|
48
|
+
if (ms < 45 * MIN) return `${Math.round(ms / MIN)} minutes ago`;
|
|
49
|
+
if (ms < 90 * MIN) return "1 hour ago";
|
|
50
|
+
if (ms < 22 * HOUR) return `${Math.round(ms / HOUR)} hours ago`;
|
|
51
|
+
if (ms < 36 * HOUR) return "1 day ago";
|
|
52
|
+
return `${Math.round(ms / DAY)} days ago`;
|
|
53
|
+
}
|
|
54
|
+
function absoluteUtc(t) {
|
|
55
|
+
const iso = new Date(t).toISOString();
|
|
56
|
+
return `${iso.slice(0, 10)} ${iso.slice(11, 16)} UTC`;
|
|
57
|
+
}
|
|
58
|
+
function relativeWhen(createdAt, now = Date.now()) {
|
|
59
|
+
if (!createdAt) return "";
|
|
60
|
+
const t = Date.parse(createdAt);
|
|
61
|
+
if (Number.isNaN(t)) return "";
|
|
62
|
+
return relativeAge(Math.max(0, now - t));
|
|
63
|
+
}
|
|
64
|
+
function formatWhen(createdAt, now = Date.now()) {
|
|
65
|
+
if (!createdAt) return "at an unknown time";
|
|
66
|
+
const t = Date.parse(createdAt);
|
|
67
|
+
if (Number.isNaN(t)) return "at an unknown time";
|
|
68
|
+
return `${relativeAge(Math.max(0, now - t))} (${absoluteUtc(t)})`;
|
|
69
|
+
}
|
|
70
|
+
|
|
40
71
|
// src/daemon/leader-lock.ts
|
|
41
72
|
import * as fs from "fs";
|
|
42
73
|
import * as path from "path";
|
|
@@ -108,6 +139,23 @@ function atomicWriteFile(filePath, data, mode) {
|
|
|
108
139
|
fs2.chmodSync(filePath, mode);
|
|
109
140
|
}
|
|
110
141
|
}
|
|
142
|
+
function atomicCopyFile(source, destination, mode = 493) {
|
|
143
|
+
const dir = path2.dirname(destination);
|
|
144
|
+
fs2.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
145
|
+
const tmp = path2.join(dir, `.${path2.basename(destination)}.${process.pid}.tmp`);
|
|
146
|
+
try {
|
|
147
|
+
fs2.copyFileSync(source, tmp);
|
|
148
|
+
fs2.chmodSync(tmp, mode);
|
|
149
|
+
fs2.renameSync(tmp, destination);
|
|
150
|
+
fs2.chmodSync(destination, mode);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
try {
|
|
153
|
+
fs2.rmSync(tmp, { force: true });
|
|
154
|
+
} catch {
|
|
155
|
+
}
|
|
156
|
+
throw err;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
111
159
|
function readJsonFile(filePath) {
|
|
112
160
|
try {
|
|
113
161
|
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
@@ -4265,8 +4313,11 @@ var SyncRowSchema = external_exports.object({
|
|
|
4265
4313
|
// fallback against a future server-side rename).
|
|
4266
4314
|
sender: external_exports.string().optional(),
|
|
4267
4315
|
sender_handle: external_exports.string().optional(),
|
|
4316
|
+
seq: external_exports.number().optional(),
|
|
4268
4317
|
type: external_exports.string().optional(),
|
|
4269
4318
|
content: external_exports.record(external_exports.unknown()).optional(),
|
|
4319
|
+
metadata: external_exports.record(external_exports.unknown()).optional(),
|
|
4320
|
+
status: external_exports.string().optional(),
|
|
4270
4321
|
created_at: external_exports.string().optional()
|
|
4271
4322
|
}).passthrough();
|
|
4272
4323
|
function contextOf(row) {
|
|
@@ -4371,6 +4422,28 @@ async function claimReply(cfg, messageId, holder) {
|
|
|
4371
4422
|
return true;
|
|
4372
4423
|
}
|
|
4373
4424
|
}
|
|
4425
|
+
async function claimReplyBatch(cfg, messageIds, holder) {
|
|
4426
|
+
if (messageIds.length === 0) return 0;
|
|
4427
|
+
try {
|
|
4428
|
+
const data = await request(cfg, "POST", "/v1/reply/claim-batch", {
|
|
4429
|
+
message_ids: messageIds,
|
|
4430
|
+
holder
|
|
4431
|
+
});
|
|
4432
|
+
const parsed = external_exports.object({ claimed_count: external_exports.number().int().min(0).max(messageIds.length) }).passthrough().safeParse(data);
|
|
4433
|
+
return parsed.success ? parsed.data.claimed_count : messageIds.length;
|
|
4434
|
+
} catch (err) {
|
|
4435
|
+
if (!/AgentChat API (404|405)\b/.test(String(err))) {
|
|
4436
|
+
log.warn(`reply-batch-claim failed (surfacing all): ${String(err)}`);
|
|
4437
|
+
return messageIds.length;
|
|
4438
|
+
}
|
|
4439
|
+
}
|
|
4440
|
+
let claimed = 0;
|
|
4441
|
+
for (const messageId of messageIds) {
|
|
4442
|
+
if (!await claimReply(cfg, messageId, holder)) break;
|
|
4443
|
+
claimed += 1;
|
|
4444
|
+
}
|
|
4445
|
+
return claimed;
|
|
4446
|
+
}
|
|
4374
4447
|
function lastDeliveryId(rows) {
|
|
4375
4448
|
for (let i = rows.length - 1; i >= 0; i--) {
|
|
4376
4449
|
const id = rows[i]?.delivery_id;
|
|
@@ -4383,6 +4456,7 @@ function lastDeliveryId(rows) {
|
|
|
4383
4456
|
import * as fs4 from "fs";
|
|
4384
4457
|
import * as path4 from "path";
|
|
4385
4458
|
var ALWAYS_ON_WANTED = "always-on.wanted";
|
|
4459
|
+
var ALWAYS_ON_INSTALLED_VERSION = "always-on.installed-version";
|
|
4386
4460
|
var HEARTBEAT_FILE = "daemon.heartbeat";
|
|
4387
4461
|
var HEARTBEAT_STALE_MS = 3 * 6e4;
|
|
4388
4462
|
function markAlwaysOnWanted(home) {
|
|
@@ -4401,6 +4475,24 @@ function clearAlwaysOnWanted(home) {
|
|
|
4401
4475
|
function alwaysOnWanted(home) {
|
|
4402
4476
|
return fs4.existsSync(path4.join(home, ALWAYS_ON_WANTED));
|
|
4403
4477
|
}
|
|
4478
|
+
function readAlwaysOnInstalledVersion(home) {
|
|
4479
|
+
try {
|
|
4480
|
+
const version = fs4.readFileSync(path4.join(home, ALWAYS_ON_INSTALLED_VERSION), "utf-8").trim();
|
|
4481
|
+
return version.length > 0 ? version : null;
|
|
4482
|
+
} catch {
|
|
4483
|
+
return null;
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
function markAlwaysOnInstalledVersion(home, version) {
|
|
4487
|
+
atomicWriteFile(path4.join(home, ALWAYS_ON_INSTALLED_VERSION), `${version}
|
|
4488
|
+
`, 384);
|
|
4489
|
+
}
|
|
4490
|
+
function clearAlwaysOnInstalledVersion(home) {
|
|
4491
|
+
try {
|
|
4492
|
+
fs4.rmSync(path4.join(home, ALWAYS_ON_INSTALLED_VERSION), { force: true });
|
|
4493
|
+
} catch {
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
4404
4496
|
var ALWAYS_ON_OPTOUT = "always-on.optout";
|
|
4405
4497
|
function markAlwaysOnOptOut(home) {
|
|
4406
4498
|
try {
|
|
@@ -4461,8 +4553,13 @@ export {
|
|
|
4461
4553
|
VERSION,
|
|
4462
4554
|
CODING_AGENTS_CLIENT_IDENTITY,
|
|
4463
4555
|
CODING_AGENTS_CLIENT_HEADERS,
|
|
4556
|
+
relativeAge,
|
|
4557
|
+
absoluteUtc,
|
|
4558
|
+
relativeWhen,
|
|
4559
|
+
formatWhen,
|
|
4464
4560
|
acquireLeaderLock,
|
|
4465
4561
|
atomicWriteFile,
|
|
4562
|
+
atomicCopyFile,
|
|
4466
4563
|
readJsonFile,
|
|
4467
4564
|
DEFAULT_API_BASE,
|
|
4468
4565
|
credentialsPath,
|
|
@@ -4483,11 +4580,15 @@ export {
|
|
|
4483
4580
|
markSessionActive,
|
|
4484
4581
|
clearSessionActive,
|
|
4485
4582
|
claimReply,
|
|
4583
|
+
claimReplyBatch,
|
|
4486
4584
|
lastDeliveryId,
|
|
4487
4585
|
HEARTBEAT_FILE,
|
|
4488
4586
|
markAlwaysOnWanted,
|
|
4489
4587
|
clearAlwaysOnWanted,
|
|
4490
4588
|
alwaysOnWanted,
|
|
4589
|
+
readAlwaysOnInstalledVersion,
|
|
4590
|
+
markAlwaysOnInstalledVersion,
|
|
4591
|
+
clearAlwaysOnInstalledVersion,
|
|
4491
4592
|
markAlwaysOnOptOut,
|
|
4492
4593
|
clearAlwaysOnOptOut,
|
|
4493
4594
|
alwaysOnOptedOut,
|
|
@@ -4496,4 +4597,4 @@ export {
|
|
|
4496
4597
|
alwaysOnState,
|
|
4497
4598
|
alwaysOnHealth
|
|
4498
4599
|
};
|
|
4499
|
-
//# sourceMappingURL=chunk-
|
|
4600
|
+
//# sourceMappingURL=chunk-27XDHOL3.js.map
|