@ziggs-ai/agent-sdk 0.10.0 → 0.10.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.
- package/CHANGELOG.md +23 -0
- package/dist/AgentHost.d.ts +50 -14
- package/dist/AgentHost.js +129 -7
- package/dist/agent/ClaudeSdkAgent.d.ts +23 -1
- package/dist/agent/ClaudeSdkAgent.js +145 -75
- package/dist/context/applyEffects.js +4 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/runtime/bootstrapCtx.js +6 -8
- package/dist/runtime/buildOutcome.d.ts +9 -1
- package/dist/runtime/buildOutcome.js +29 -6
- package/dist/runtime/taskIntake.js +6 -4
- package/dist/runtime/wakeWriteKeys.js +14 -21
- package/dist/server/ConnectionPool.d.ts +10 -52
- package/dist/server/ConnectionPool.js +26 -57
- package/dist/server/EventQueue.d.ts +6 -0
- package/dist/server/EventQueue.js +21 -6
- package/dist/server/SeenMessages.d.ts +7 -0
- package/dist/server/SeenMessages.js +15 -0
- package/dist/server/ZiggsEffectHandler.d.ts +1 -0
- package/dist/server/ZiggsEffectHandler.js +14 -7
- package/dist/server/inboxLoop.d.ts +17 -2
- package/dist/server/inboxLoop.js +92 -16
- package/dist/server/polls/PollKind.d.ts +72 -0
- package/dist/server/polls/PollKind.js +53 -0
- package/dist/server/polls/PollRunner.d.ts +62 -0
- package/dist/server/polls/PollRunner.js +138 -0
- package/dist/server/questMatch.d.ts +5 -0
- package/dist/server/questMatch.js +14 -0
- package/dist/server/runLauncher.d.ts +0 -6
- package/dist/server/runLauncher.js +54 -27
- package/dist/server/tools/tier1/protocolRunner.d.ts +3 -1
- package/dist/server/tools/tier1/protocolRunner.js +24 -28
- package/dist/server/tools/tier1/protocolTools.js +23 -13
- package/dist/server/tools/tier2/connectionTools.js +12 -1
- package/dist/tasks/protocolRegistry.d.ts +27 -0
- package/dist/tasks/protocolRegistry.js +36 -0
- package/dist/types.d.ts +0 -9
- package/package.json +2 -2
- package/dist/server/staleBacklogGate.d.ts +0 -57
- package/dist/server/staleBacklogGate.js +0 -100
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { runtimeLog } from '../shared/runtimeLog.js';
|
|
2
|
-
export const DEFAULT_REPLAY_MAX_AGE_MS = 3 * 24 * 60 * 60 * 1000;
|
|
3
|
-
/**
|
|
4
|
-
* "3d" | "12h" | "30m" | "45s"; a bare number means days (the knob's natural
|
|
5
|
-
* granularity). Returns null on garbage so the caller can warn and fall back.
|
|
6
|
-
*/
|
|
7
|
-
export function parseReplayMaxAge(raw) {
|
|
8
|
-
const m = /^\s*(\d+(?:\.\d+)?)\s*([dhms]?)\s*$/i.exec(raw);
|
|
9
|
-
if (!m)
|
|
10
|
-
return null;
|
|
11
|
-
const value = Number(m[1]);
|
|
12
|
-
if (!Number.isFinite(value) || value <= 0)
|
|
13
|
-
return null;
|
|
14
|
-
const unitMs = { d: 86_400_000, h: 3_600_000, m: 60_000, s: 1_000 }[(m[2] || 'd').toLowerCase()];
|
|
15
|
-
return value * unitMs;
|
|
16
|
-
}
|
|
17
|
-
export function resolveReplayPolicy(env = process.env) {
|
|
18
|
-
const replayAll = env.FLEET_REPLAY_STALE === '1' || env.FLEET_REPLAY_STALE === 'true';
|
|
19
|
-
const raw = env.FLEET_REPLAY_MAX_AGE?.trim();
|
|
20
|
-
let maxAgeMs = DEFAULT_REPLAY_MAX_AGE_MS;
|
|
21
|
-
if (raw) {
|
|
22
|
-
const parsed = parseReplayMaxAge(raw);
|
|
23
|
-
if (parsed == null) {
|
|
24
|
-
runtimeLog.warn('staleBacklogGate', `FLEET_REPLAY_MAX_AGE="${raw}" is not a duration (use e.g. "3d", "12h", "30m") — using default ${formatAge(DEFAULT_REPLAY_MAX_AGE_MS)}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
maxAgeMs = parsed;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return { maxAgeMs, replayAll };
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Newest actionable instant for an agent, from its operator-sweep entry.
|
|
34
|
-
*
|
|
35
|
-
* The sweep hands this over directly now — it is the agent's delivery
|
|
36
|
-
* watermark — where this used to fold together the max timestamp across every
|
|
37
|
-
* channel of a whole envelope. An agent surfaced only for open work carries no
|
|
38
|
-
* delivery instant: age is unprovable, so it is treated as fresh and started.
|
|
39
|
-
* Stale-skipping a half-finished task would strand it.
|
|
40
|
-
*/
|
|
41
|
-
export function newestActionableAt(entry) {
|
|
42
|
-
if (!entry.deliveredUpTo)
|
|
43
|
-
return null;
|
|
44
|
-
const t = Date.parse(entry.deliveredUpTo);
|
|
45
|
-
return Number.isNaN(t) ? null : t;
|
|
46
|
-
}
|
|
47
|
-
export function formatAge(ms) {
|
|
48
|
-
if (ms >= 86_400_000)
|
|
49
|
-
return `${trimNum(ms / 86_400_000)}d`;
|
|
50
|
-
if (ms >= 3_600_000)
|
|
51
|
-
return `${trimNum(ms / 3_600_000)}h`;
|
|
52
|
-
if (ms >= 60_000)
|
|
53
|
-
return `${trimNum(ms / 60_000)}m`;
|
|
54
|
-
return `${trimNum(ms / 1_000)}s`;
|
|
55
|
-
}
|
|
56
|
-
function trimNum(n) {
|
|
57
|
-
return Number(n.toFixed(1)).toString();
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Build the `shouldLazyStart` gate for the operator poll. Skipped agents
|
|
61
|
-
* resurface in every envelope (reading never acks), so announcements are
|
|
62
|
-
* per-agent-once: each poll pass that skips agents not yet announced emits one
|
|
63
|
-
* aggregated warn line covering them.
|
|
64
|
-
*/
|
|
65
|
-
export function createStaleBacklogGate({ maxAgeMs, replayAll, label = 'launcher', now = Date.now, log, }) {
|
|
66
|
-
const emit = log ?? ((line) => runtimeLog.warn(label, line));
|
|
67
|
-
const announced = new Set();
|
|
68
|
-
let pendingAgents = [];
|
|
69
|
-
let flushScheduled = false;
|
|
70
|
-
// One envelope's entries are gated synchronously; a microtask-deferred
|
|
71
|
-
// flush turns a whole boot flood into a single summary line.
|
|
72
|
-
const flush = () => {
|
|
73
|
-
flushScheduled = false;
|
|
74
|
-
if (pendingAgents.length === 0)
|
|
75
|
-
return;
|
|
76
|
-
const preview = pendingAgents.slice(0, 5).join(', ');
|
|
77
|
-
const more = pendingAgents.length > 5 ? `, +${pendingAgents.length - 5} more` : '';
|
|
78
|
-
emit(`startup backlog policy: skipped ${pendingAgents.length} agent(s) whose newest mail is older than ${formatAge(maxAgeMs)} (${preview}${more}) — set FLEET_REPLAY_STALE=1 to replay them`);
|
|
79
|
-
pendingAgents = [];
|
|
80
|
-
};
|
|
81
|
-
return (entry) => {
|
|
82
|
-
if (replayAll)
|
|
83
|
-
return true;
|
|
84
|
-
// Open work always starts, however old: the task is unfinished, not stale.
|
|
85
|
-
if (entry.hasOpenTasks)
|
|
86
|
-
return true;
|
|
87
|
-
const newest = newestActionableAt(entry);
|
|
88
|
-
if (newest == null || now() - newest <= maxAgeMs)
|
|
89
|
-
return true;
|
|
90
|
-
if (!announced.has(entry.agentId)) {
|
|
91
|
-
announced.add(entry.agentId);
|
|
92
|
-
pendingAgents.push(entry.agentId);
|
|
93
|
-
if (!flushScheduled) {
|
|
94
|
-
flushScheduled = true;
|
|
95
|
-
queueMicrotask(flush);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return false;
|
|
99
|
-
};
|
|
100
|
-
}
|