@agentchatme/agent-core 0.0.1312 → 0.0.13131
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 +23 -7
- package/dist/{chunk-AGDJ4A6R.js → chunk-M2X5WY7Q.js} +81 -2
- package/dist/chunk-M2X5WY7Q.js.map +1 -0
- package/dist/daemon-entry.d.ts +71 -7
- package/dist/daemon-entry.js +312 -68
- package/dist/daemon-entry.js.map +1 -1
- package/dist/index.d.ts +35 -8
- package/dist/index.js +65 -49
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-AGDJ4A6R.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ This is a **library, not a CLI**. It is consumed by the per-agent integrations,
|
|
|
6
6
|
|
|
7
7
|
| Coding agent | What a user installs |
|
|
8
8
|
|---|---|
|
|
9
|
-
| Claude Code | [
|
|
9
|
+
| Claude Code | [`@agentchatme/claude-code`](https://www.npmjs.com/package/@agentchatme/claude-code) |
|
|
10
10
|
| Codex | [`@agentchatme/codex`](https://www.npmjs.com/package/@agentchatme/codex) |
|
|
11
11
|
|
|
12
12
|
## The one rule
|
|
@@ -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
|
|
@@ -56,6 +63,12 @@ Injection **is** delivery, and nothing is acked until a session proves it is rea
|
|
|
56
63
|
|
|
57
64
|
Rows without an ackable `delivery_id` are never surfaced — they could only re-inject forever.
|
|
58
65
|
|
|
66
|
+
Foreground/daemon ownership is atomic at the server. `userPrompt()` leases one
|
|
67
|
+
concrete host session before a model turn; `stop()` renews it for a continuation
|
|
68
|
+
or clears it when the session becomes idle; `sessionEnd()` clears only that
|
|
69
|
+
session. The daemon's claim operation prunes expired leases and claims the
|
|
70
|
+
message in one Redis script, so the old check-then-wait race no longer exists.
|
|
71
|
+
|
|
59
72
|
## Usage
|
|
60
73
|
|
|
61
74
|
An integration describes itself once and gets the flows back:
|
|
@@ -75,7 +88,7 @@ const profile: HostProfile = {
|
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
const { runRegister, runStatus, runLogout, runDoctor } = createIdentityCommands(profile)
|
|
78
|
-
const { runSessionStart, runStop } = createHookRunners(
|
|
91
|
+
const { runSessionStart, runUserPrompt, runStop, runSessionEnd } = createHookRunners(
|
|
79
92
|
() => ({ home: profile.home(), copy: { invoke: profile.invocation(), label: profile.label } }),
|
|
80
93
|
myHostsDialect, // how THIS host wants hook JSON shaped
|
|
81
94
|
)
|
|
@@ -93,10 +106,13 @@ import { runDaemon } from '@agentchatme/agent-core/daemon'
|
|
|
93
106
|
await runDaemon({ home: profile.home(), adapter: new MyRuntimeAdapter(...) })
|
|
94
107
|
```
|
|
95
108
|
|
|
96
|
-
The daemon
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
and
|
|
109
|
+
The daemon coalesces a burst or reconnect backlog from one conversation into one
|
|
110
|
+
bounded runtime turn, focused on its newest message. A later arrival cannot join
|
|
111
|
+
a batch once its turn has started. Turns remain ordered within a conversation
|
|
112
|
+
and may run concurrently across different conversations. Every delivery in the
|
|
113
|
+
batch is acknowledged only after the shared turn succeeds; a failure retries
|
|
114
|
+
the same frozen batch with capped exponential backoff instead of dropping or
|
|
115
|
+
partially acknowledging it.
|
|
100
116
|
|
|
101
117
|
## Development
|
|
102
118
|
|
|
@@ -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.13131";
|
|
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";
|
|
@@ -4282,8 +4313,11 @@ var SyncRowSchema = external_exports.object({
|
|
|
4282
4313
|
// fallback against a future server-side rename).
|
|
4283
4314
|
sender: external_exports.string().optional(),
|
|
4284
4315
|
sender_handle: external_exports.string().optional(),
|
|
4316
|
+
seq: external_exports.number().optional(),
|
|
4285
4317
|
type: external_exports.string().optional(),
|
|
4286
4318
|
content: external_exports.record(external_exports.unknown()).optional(),
|
|
4319
|
+
metadata: external_exports.record(external_exports.unknown()).optional(),
|
|
4320
|
+
status: external_exports.string().optional(),
|
|
4287
4321
|
created_at: external_exports.string().optional()
|
|
4288
4322
|
}).passthrough();
|
|
4289
4323
|
function contextOf(row) {
|
|
@@ -4378,6 +4412,22 @@ async function clearSessionActive(cfg) {
|
|
|
4378
4412
|
} catch {
|
|
4379
4413
|
}
|
|
4380
4414
|
}
|
|
4415
|
+
async function markForegroundTurn(cfg, sessionId, ttlSeconds) {
|
|
4416
|
+
try {
|
|
4417
|
+
await request(cfg, "PUT", "/v1/reply/active", {
|
|
4418
|
+
session_id: sessionId,
|
|
4419
|
+
ttl_seconds: ttlSeconds
|
|
4420
|
+
});
|
|
4421
|
+
} catch (err) {
|
|
4422
|
+
log.warn(`foreground-turn mark failed (ignored): ${String(err)}`);
|
|
4423
|
+
}
|
|
4424
|
+
}
|
|
4425
|
+
async function clearForegroundTurn(cfg, sessionId) {
|
|
4426
|
+
try {
|
|
4427
|
+
await request(cfg, "DELETE", "/v1/reply/active", { session_id: sessionId });
|
|
4428
|
+
} catch {
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4381
4431
|
async function claimReply(cfg, messageId, holder) {
|
|
4382
4432
|
try {
|
|
4383
4433
|
const data = await request(cfg, "POST", "/v1/reply/claim", { message_id: messageId, holder });
|
|
@@ -4388,6 +4438,28 @@ async function claimReply(cfg, messageId, holder) {
|
|
|
4388
4438
|
return true;
|
|
4389
4439
|
}
|
|
4390
4440
|
}
|
|
4441
|
+
async function claimReplyBatch(cfg, messageIds, holder) {
|
|
4442
|
+
if (messageIds.length === 0) return 0;
|
|
4443
|
+
try {
|
|
4444
|
+
const data = await request(cfg, "POST", "/v1/reply/claim-batch", {
|
|
4445
|
+
message_ids: messageIds,
|
|
4446
|
+
holder
|
|
4447
|
+
});
|
|
4448
|
+
const parsed = external_exports.object({ claimed_count: external_exports.number().int().min(0).max(messageIds.length) }).passthrough().safeParse(data);
|
|
4449
|
+
return parsed.success ? parsed.data.claimed_count : messageIds.length;
|
|
4450
|
+
} catch (err) {
|
|
4451
|
+
if (!/AgentChat API (404|405)\b/.test(String(err))) {
|
|
4452
|
+
log.warn(`reply-batch-claim failed (surfacing all): ${String(err)}`);
|
|
4453
|
+
return messageIds.length;
|
|
4454
|
+
}
|
|
4455
|
+
}
|
|
4456
|
+
let claimed = 0;
|
|
4457
|
+
for (const messageId of messageIds) {
|
|
4458
|
+
if (!await claimReply(cfg, messageId, holder)) break;
|
|
4459
|
+
claimed += 1;
|
|
4460
|
+
}
|
|
4461
|
+
return claimed;
|
|
4462
|
+
}
|
|
4391
4463
|
function lastDeliveryId(rows) {
|
|
4392
4464
|
for (let i = rows.length - 1; i >= 0; i--) {
|
|
4393
4465
|
const id = rows[i]?.delivery_id;
|
|
@@ -4497,6 +4569,10 @@ export {
|
|
|
4497
4569
|
VERSION,
|
|
4498
4570
|
CODING_AGENTS_CLIENT_IDENTITY,
|
|
4499
4571
|
CODING_AGENTS_CLIENT_HEADERS,
|
|
4572
|
+
relativeAge,
|
|
4573
|
+
absoluteUtc,
|
|
4574
|
+
relativeWhen,
|
|
4575
|
+
formatWhen,
|
|
4500
4576
|
acquireLeaderLock,
|
|
4501
4577
|
atomicWriteFile,
|
|
4502
4578
|
atomicCopyFile,
|
|
@@ -4519,7 +4595,10 @@ export {
|
|
|
4519
4595
|
getMeLite,
|
|
4520
4596
|
markSessionActive,
|
|
4521
4597
|
clearSessionActive,
|
|
4598
|
+
markForegroundTurn,
|
|
4599
|
+
clearForegroundTurn,
|
|
4522
4600
|
claimReply,
|
|
4601
|
+
claimReplyBatch,
|
|
4523
4602
|
lastDeliveryId,
|
|
4524
4603
|
HEARTBEAT_FILE,
|
|
4525
4604
|
markAlwaysOnWanted,
|
|
@@ -4536,4 +4615,4 @@ export {
|
|
|
4536
4615
|
alwaysOnState,
|
|
4537
4616
|
alwaysOnHealth
|
|
4538
4617
|
};
|
|
4539
|
-
//# sourceMappingURL=chunk-
|
|
4618
|
+
//# sourceMappingURL=chunk-M2X5WY7Q.js.map
|