@animalabs/agent-framework 0.6.3 → 0.6.5

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 (66) hide show
  1. package/README.md +5 -0
  2. package/dist/src/agent.d.ts +3 -1
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +27 -2
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/framework.d.ts +46 -1
  7. package/dist/src/framework.d.ts.map +1 -1
  8. package/dist/src/framework.js +280 -146
  9. package/dist/src/framework.js.map +1 -1
  10. package/dist/src/index.d.ts +1 -0
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +1 -0
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/modules/discord/index.d.ts +1 -0
  15. package/dist/src/modules/discord/index.d.ts.map +1 -1
  16. package/dist/src/modules/discord/index.js +4 -1
  17. package/dist/src/modules/discord/index.js.map +1 -1
  18. package/dist/src/modules/discord/types.d.ts +2 -0
  19. package/dist/src/modules/discord/types.d.ts.map +1 -1
  20. package/dist/src/modules/health/index.d.ts +2 -0
  21. package/dist/src/modules/health/index.d.ts.map +1 -1
  22. package/dist/src/modules/health/index.js +15 -4
  23. package/dist/src/modules/health/index.js.map +1 -1
  24. package/dist/src/timezone.d.ts +14 -0
  25. package/dist/src/timezone.d.ts.map +1 -0
  26. package/dist/src/timezone.js +74 -0
  27. package/dist/src/timezone.js.map +1 -0
  28. package/dist/src/types/agent.d.ts +5 -2
  29. package/dist/src/types/agent.d.ts.map +1 -1
  30. package/dist/src/types/framework.d.ts +15 -0
  31. package/dist/src/types/framework.d.ts.map +1 -1
  32. package/dist/test/activation-request-sanitize.test.d.ts +2 -0
  33. package/dist/test/activation-request-sanitize.test.d.ts.map +1 -0
  34. package/dist/test/activation-request-sanitize.test.js +89 -0
  35. package/dist/test/activation-request-sanitize.test.js.map +1 -0
  36. package/dist/test/agent-cache-ttl.test.js +18 -2
  37. package/dist/test/agent-cache-ttl.test.js.map +1 -1
  38. package/dist/test/ephemeral-settle.test.d.ts +2 -0
  39. package/dist/test/ephemeral-settle.test.d.ts.map +1 -0
  40. package/dist/test/ephemeral-settle.test.js +351 -0
  41. package/dist/test/ephemeral-settle.test.js.map +1 -0
  42. package/dist/test/health-snapshot.test.d.ts +2 -0
  43. package/dist/test/health-snapshot.test.d.ts.map +1 -0
  44. package/dist/test/health-snapshot.test.js +74 -0
  45. package/dist/test/health-snapshot.test.js.map +1 -0
  46. package/dist/test/maintenance-timer.test.js +49 -0
  47. package/dist/test/maintenance-timer.test.js.map +1 -1
  48. package/dist/test/overbudget-drain-breaker.test.d.ts +2 -0
  49. package/dist/test/overbudget-drain-breaker.test.d.ts.map +1 -0
  50. package/dist/test/overbudget-drain-breaker.test.js +157 -0
  51. package/dist/test/overbudget-drain-breaker.test.js.map +1 -0
  52. package/dist/test/timezone.test.d.ts +2 -0
  53. package/dist/test/timezone.test.d.ts.map +1 -0
  54. package/dist/test/timezone.test.js +18 -0
  55. package/dist/test/timezone.test.js.map +1 -0
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +1 -1
  58. package/src/agent.ts +30 -3
  59. package/src/framework.ts +313 -146
  60. package/src/index.ts +1 -0
  61. package/src/modules/discord/index.ts +4 -1
  62. package/src/modules/discord/types.ts +3 -0
  63. package/src/modules/health/index.ts +20 -4
  64. package/src/timezone.ts +90 -0
  65. package/src/types/agent.ts +6 -2
  66. package/src/types/framework.ts +17 -0
@@ -19,6 +19,18 @@ class QueuedStrategy {
19
19
  return [];
20
20
  }
21
21
  }
22
+ class FailingStrategy {
23
+ name = 'failing-maintenance-test';
24
+ checkReadiness() {
25
+ return { ready: false, description: 'compression blocked' };
26
+ }
27
+ async tick(_ctx) {
28
+ throw new Error('provider rejected maintenance request');
29
+ }
30
+ select(_store, _log, _budget) {
31
+ return [];
32
+ }
33
+ }
22
34
  class ToolModule {
23
35
  name = 'maintenance-tools';
24
36
  async start(_ctx) { }
@@ -110,5 +122,42 @@ describe('queued context maintenance timer', () => {
110
122
  rmSync(dir, { recursive: true, force: true });
111
123
  }
112
124
  });
125
+ it('routes a maintenance failure through the ops-alert pipeline', async () => {
126
+ const dir = mkdtempSync(join(tmpdir(), 'af-maintenance-alert-'));
127
+ const framework = await AgentFramework.create({
128
+ storePath: join(dir, 'store'),
129
+ membrane,
130
+ agents: [{
131
+ name: 'agent',
132
+ model: 'test-model',
133
+ systemPrompt: 'test',
134
+ strategy: new FailingStrategy(),
135
+ }],
136
+ modules: [],
137
+ syncIntervalMs: 0,
138
+ maintenanceIntervalMs: 10,
139
+ });
140
+ const alerts = [];
141
+ framework.opsAlert = (kind, agentName, message, opts) => alerts.push({ kind, agentName, message, data: opts?.data });
142
+ try {
143
+ framework.start();
144
+ await waitFor(() => alerts.length > 0);
145
+ assert.deepEqual(alerts[0], {
146
+ kind: 'context-maintenance-failed',
147
+ agentName: 'agent',
148
+ message: 'provider rejected maintenance request',
149
+ data: {
150
+ scope: 'agent',
151
+ pending: 'compression blocked',
152
+ },
153
+ });
154
+ await waitFor(() => framework.getContextMaintenanceSnapshot().history.length > 0);
155
+ assert.equal(framework.getContextMaintenanceSnapshot().history[0].agents[0].error, 'provider rejected maintenance request');
156
+ }
157
+ finally {
158
+ await framework.stop();
159
+ rmSync(dir, { recursive: true, force: true });
160
+ }
161
+ });
113
162
  });
114
163
  //# sourceMappingURL=maintenance-timer.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"maintenance-timer.test.js","sourceRoot":"","sources":["../../test/maintenance-timer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoBjC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,cAAc;IACT,IAAI,GAAG,aAAa,CAAC;IAC9B,KAAK,GAAG,CAAC,CAAC;IACV,UAAU,GAAa,EAAE,CAAC;IAE1B,cAAc;QACZ,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAoB;QAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED,MAAM,CACJ,MAAwB,EACxB,IAAoB,EACpB,OAAoB;QAEpB,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,UAAU;IACL,IAAI,GAAG,mBAAmB,CAAC;IAEpC,KAAK,CAAC,KAAK,CAAC,IAAmB,IAAkB,CAAC;IAClD,KAAK,CAAC,IAAI,KAAmB,CAAC;IAE9B,QAAQ;QACN,OAAO,CAAC;gBACN,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,WAAW;gBACxB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;aAChD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAe;QAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAoB,EAAE,MAAoB;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED,MAAM,QAAQ,GAAG;IACf,KAAK,CAAC,QAAQ,CAAC,QAA2B;QACxC,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;CACmD,CAAC;AAEvD,KAAK,UAAU,OAAO,CAAC,SAAwB,EAAE,SAAS,GAAG,IAAI;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACjF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC;YAC5C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;YAC7B,QAAQ;YACR,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,YAAY;oBACnB,YAAY,EAAE,MAAM;oBACpB,QAAQ;oBACR,YAAY,EAAE,KAAK;iBACpB,CAAC;YACF,OAAO,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,cAAc,EAAE,CAAC;YACjB,qBAAqB,EAAE,EAAE;SAC1B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,6BAA6B,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;YACpF,MAAM,QAAQ,GAAG,SAAS,CAAC,6BAA6B,EAAE,CAAC;YAC3D,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;gBAAS,CAAC;YACT,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC;YAC5C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;YAC7B,QAAQ;YACR,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,YAAY;oBACnB,YAAY,EAAE,MAAM;oBACpB,QAAQ;iBACT,CAAC;YACF,OAAO,EAAE,EAAE;YACX,cAAc,EAAE,CAAC;YACjB,qBAAqB,EAAE,CAAC;SACzB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAClC,CAAC;gBAAS,CAAC;YACT,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"maintenance-timer.test.js","sourceRoot":"","sources":["../../test/maintenance-timer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=overbudget-drain-breaker.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overbudget-drain-breaker.test.d.ts","sourceRoot":"","sources":["../../test/overbudget-drain-breaker.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * OverBudget deadlock breaker (PR #58, 15befaa): when compile throws
3
+ * context-manager's OverBudgetError, the compression drain never runs — it is
4
+ * driven by successful activity, which the over-budget state prevents. A
5
+ * closed loop with no internal exit (field data 2026-07-10: 36 minutes
6
+ * hard-down, zero self-rescue). noteInferenceExhausted breaks it by kicking
7
+ * the strategy drain (cm.tick()) directly.
8
+ *
9
+ * The trigger is the classified errorType 'over_budget' (err.name ===
10
+ * 'OverBudgetError' — CM does not export the class, so no cross-package
11
+ * instanceof; the message-prose match is only a fallback). These tests pin
12
+ * that classification so a CM message rewording cannot silently kill the
13
+ * breaker.
14
+ */
15
+ import { test } from 'node:test';
16
+ import assert from 'node:assert/strict';
17
+ import { AgentFramework } from '../src/framework.js';
18
+ import { MembraneError } from '@animalabs/membrane';
19
+ function makeHarness(tick) {
20
+ const cm = {
21
+ addMessage: () => 'marker-id',
22
+ tick,
23
+ };
24
+ const fw = Object.create(AgentFramework.prototype);
25
+ fw.consecutiveInferenceFailures = new Map();
26
+ fw.exhaustionRewinds = new Map();
27
+ fw.rewindEpisode = new Map();
28
+ fw.lastInferenceAt = new Map();
29
+ fw.overBudgetDrainInFlight = new Set();
30
+ fw.opsAlertLastSent = new Map();
31
+ fw.pendingRequests = [];
32
+ fw.traceListeners = [];
33
+ fw.inferenceFailureEscalationThreshold = 3;
34
+ fw.agents = new Map([['cairn', {
35
+ name: 'cairn',
36
+ refusalHandling: { maxRewinds: 3 },
37
+ getContextManager: () => cm,
38
+ }]]);
39
+ const errs = [];
40
+ const orig = console.error;
41
+ console.error = (...a) => { errs.push(a.join(' ')); };
42
+ const restore = () => { console.error = orig; };
43
+ return { fw, errs, restore };
44
+ }
45
+ /** Let the fire-and-forget drain IIFE's microtask chain run to quiescence. */
46
+ async function settle(rounds = 3) {
47
+ for (let i = 0; i < rounds; i++)
48
+ await new Promise((r) => setImmediate(r));
49
+ }
50
+ const OVER_BUDGET_REASON = 'Compile plan would exceed hard budget: head=41200 tail=8100 middle=62000 budget=100000';
51
+ test('classification: err.name OverBudgetError → over_budget, regardless of message wording', () => {
52
+ const fw = Object.create(AgentFramework.prototype);
53
+ // The load-bearing pin: classification must NOT depend on CM's message
54
+ // prose, which CM can reword without knowing AF gates a breaker on it.
55
+ const reworded = new Error('context plan no longer fits (reworded in some future CM)');
56
+ reworded.name = 'OverBudgetError';
57
+ assert.deepEqual(fw.classifyInferenceError(reworded), { errorType: 'over_budget' });
58
+ // Membrane errors keep their own typed classification.
59
+ const membraneErr = new MembraneError({
60
+ type: 'invalid_request',
61
+ message: '400 bad request',
62
+ retryable: false,
63
+ rawError: null,
64
+ });
65
+ assert.deepEqual(fw.classifyInferenceError(membraneErr), { retryable: false, errorType: 'invalid_request' });
66
+ // Anything else stays unclassified.
67
+ assert.deepEqual(fw.classifyInferenceError(new Error('boom')), {});
68
+ });
69
+ test('errorType over_budget kicks the drain: 8 ticks, honest success log', async () => {
70
+ let ticks = 0;
71
+ const { fw, errs, restore } = makeHarness(async () => { ticks++; });
72
+ try {
73
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
74
+ await settle(20);
75
+ }
76
+ finally {
77
+ restore();
78
+ }
79
+ assert.equal(ticks, 8);
80
+ assert.ok(errs.some((e) => e.includes('drain kicked for cairn') && e.includes('8 ticks')), `success log with real tick count, got: ${errs.join(' | ')}`);
81
+ });
82
+ test('message fallback: "exceed hard budget" prose kicks even without errorType', async () => {
83
+ let ticks = 0;
84
+ const { fw, restore } = makeHarness(async () => { ticks++; });
85
+ try {
86
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, undefined);
87
+ await settle(20);
88
+ }
89
+ finally {
90
+ restore();
91
+ }
92
+ assert.equal(ticks, 8);
93
+ });
94
+ test('unrelated failures never kick the drain', async () => {
95
+ let ticks = 0;
96
+ const { fw, restore } = makeHarness(async () => { ticks++; });
97
+ try {
98
+ fw.noteInferenceExhausted('cairn', '529 overloaded', true, 'server');
99
+ fw.noteInferenceExhausted('cairn', '400 invalid request', false, 'invalid_request');
100
+ fw.noteInferenceExhausted('cairn', 'weird transport error', undefined, undefined);
101
+ await settle(20);
102
+ }
103
+ finally {
104
+ restore();
105
+ }
106
+ assert.equal(ticks, 0);
107
+ });
108
+ test('overlapping kicks are suppressed: one drain per agent at a time', async () => {
109
+ let started = 0;
110
+ const gates = [];
111
+ const { fw, errs, restore } = makeHarness(() => { started++; return new Promise((r) => { gates.push(r); }); });
112
+ try {
113
+ // The scenario the breaker exists for: every activation fails, repeatedly.
114
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
115
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
116
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
117
+ await settle();
118
+ // Only ONE kick started; its first tick is still in flight.
119
+ assert.equal(started, 1);
120
+ // Release ticks one at a time — exactly 8 run, then the drain finishes.
121
+ for (let i = 0; i < 8; i++) {
122
+ gates[i]();
123
+ await settle();
124
+ }
125
+ assert.equal(started, 8, 'exactly one drain worth of ticks, not three');
126
+ assert.equal(errs.filter((e) => e.includes('drain kicked for cairn')).length, 1);
127
+ // The in-flight flag was cleared: a NEW failure kicks again.
128
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
129
+ await settle();
130
+ assert.equal(started, 9);
131
+ }
132
+ finally {
133
+ restore();
134
+ }
135
+ });
136
+ test('a failing tick is logged with the real count and clears the in-flight flag', async () => {
137
+ let calls = 0;
138
+ const { fw, errs, restore } = makeHarness(async () => {
139
+ calls++;
140
+ if (calls === 3)
141
+ throw new Error('strategy exploded');
142
+ });
143
+ try {
144
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
145
+ await settle(20);
146
+ assert.ok(errs.some((e) => e.includes('drain kick failed for cairn after 2 ticks')));
147
+ assert.equal(fw.overBudgetDrainInFlight.size, 0, 'flag cleared on failure');
148
+ // Recovery: the next failure can kick again.
149
+ fw.noteInferenceExhausted('cairn', OVER_BUDGET_REASON, undefined, 'over_budget');
150
+ await settle(20);
151
+ assert.ok(calls > 3, 'subsequent kick ran');
152
+ }
153
+ finally {
154
+ restore();
155
+ }
156
+ });
157
+ //# sourceMappingURL=overbudget-drain-breaker.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overbudget-drain-breaker.test.js","sourceRoot":"","sources":["../../test/overbudget-drain-breaker.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=timezone.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.test.d.ts","sourceRoot":"","sources":["../../test/timezone.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { formatZonedDateTime, formatZonedTime, isValidTimeZone, resolveTimeZone } from '../src/timezone.js';
4
+ describe('agent-visible timezone formatting', () => {
5
+ const winter = new Date('2026-01-15T12:34:56.789Z');
6
+ const summer = new Date('2026-07-15T12:34:56.789Z');
7
+ it('renders the configured zone with the correct DST offset', () => {
8
+ assert.equal(formatZonedDateTime(winter, 'America/Los_Angeles'), '2026-01-15T04:34:56.789-08:00 [America/Los_Angeles]');
9
+ assert.equal(formatZonedDateTime(summer, 'America/Los_Angeles'), '2026-07-15T05:34:56.789-07:00 [America/Los_Angeles]');
10
+ assert.equal(formatZonedTime(summer, 'America/Los_Angeles'), '05:34');
11
+ });
12
+ it('validates IANA zones', () => {
13
+ assert.equal(isValidTimeZone('Europe/Paris'), true);
14
+ assert.equal(isValidTimeZone('Definitely/Not_A_Zone'), false);
15
+ assert.throws(() => resolveTimeZone('Definitely/Not_A_Zone'), /Invalid IANA time zone/);
16
+ });
17
+ });
18
+ //# sourceMappingURL=timezone.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.test.js","sourceRoot":"","sources":["../../test/timezone.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE5G,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAEpD,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,KAAK,CACV,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAClD,qDAAqD,CACtD,CAAC;QACF,MAAM,CAAC,KAAK,CACV,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAClD,qDAAqD,CACtD,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,uBAAuB,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,uBAAuB,CAAC,EAAE,wBAAwB,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}