@framers/agentos 0.15.71 → 0.15.73

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 (95) hide show
  1. package/.github/badges/tests.json +1 -1
  2. package/dist/api/generateText.d.ts.map +1 -1
  3. package/dist/api/generateText.js +28 -64
  4. package/dist/api/generateText.js.map +1 -1
  5. package/dist/api/runtime/responseFormatForProvider.d.ts +2 -3
  6. package/dist/api/runtime/responseFormatForProvider.d.ts.map +1 -1
  7. package/dist/api/runtime/responseFormatForProvider.js +2 -3
  8. package/dist/api/runtime/responseFormatForProvider.js.map +1 -1
  9. package/dist/api/server/AgentOSServer.d.ts +9 -0
  10. package/dist/api/server/AgentOSServer.d.ts.map +1 -1
  11. package/dist/api/server/AgentOSServer.js +92 -6
  12. package/dist/api/server/AgentOSServer.js.map +1 -1
  13. package/dist/api/streamText.d.ts.map +1 -1
  14. package/dist/api/streamText.js +26 -56
  15. package/dist/api/streamText.js.map +1 -1
  16. package/dist/core/llm/providers/AIModelProviderManager.d.ts +5 -5
  17. package/dist/core/llm/providers/AIModelProviderManager.d.ts.map +1 -1
  18. package/dist/core/llm/providers/AIModelProviderManager.js +11 -14
  19. package/dist/core/llm/providers/AIModelProviderManager.js.map +1 -1
  20. package/dist/core/llm/providers/implementations/OpenAIProvider.d.ts +7 -6
  21. package/dist/core/llm/providers/implementations/OpenAIProvider.d.ts.map +1 -1
  22. package/dist/core/llm/providers/implementations/OpenAIProvider.js +39 -54
  23. package/dist/core/llm/providers/implementations/OpenAIProvider.js.map +1 -1
  24. package/dist/core/llm/providers/implementations/OpenRouterProvider.d.ts.map +1 -1
  25. package/dist/core/llm/providers/implementations/OpenRouterProvider.js +20 -30
  26. package/dist/core/llm/providers/implementations/OpenRouterProvider.js.map +1 -1
  27. package/dist/core/logging/ILogger.d.ts +12 -0
  28. package/dist/core/logging/ILogger.d.ts.map +1 -1
  29. package/dist/core/logging/ILogger.js +5 -0
  30. package/dist/core/logging/ILogger.js.map +1 -1
  31. package/dist/core/logging/Logger.d.ts +52 -0
  32. package/dist/core/logging/Logger.d.ts.map +1 -0
  33. package/dist/core/logging/Logger.js +11 -0
  34. package/dist/core/logging/Logger.js.map +1 -0
  35. package/dist/core/logging/PinoLogger.d.ts +24 -2
  36. package/dist/core/logging/PinoLogger.d.ts.map +1 -1
  37. package/dist/core/logging/PinoLogger.js +39 -3
  38. package/dist/core/logging/PinoLogger.js.map +1 -1
  39. package/dist/core/logging/contentSafeTelemetry.d.ts +1 -1
  40. package/dist/core/logging/contentSafeTelemetry.d.ts.map +1 -1
  41. package/dist/core/logging/contentSafeTelemetry.js +1 -1
  42. package/dist/core/logging/contentSafeTelemetry.js.map +1 -1
  43. package/dist/core/logging/events.d.ts +349 -0
  44. package/dist/core/logging/events.d.ts.map +1 -0
  45. package/dist/core/logging/events.js +164 -0
  46. package/dist/core/logging/events.js.map +1 -0
  47. package/dist/core/logging/forward.d.ts +93 -0
  48. package/dist/core/logging/forward.d.ts.map +1 -0
  49. package/dist/core/logging/forward.js +167 -0
  50. package/dist/core/logging/forward.js.map +1 -0
  51. package/dist/core/logging/index.d.ts +8 -3
  52. package/dist/core/logging/index.d.ts.map +1 -1
  53. package/dist/core/logging/index.js +7 -3
  54. package/dist/core/logging/index.js.map +1 -1
  55. package/dist/core/logging/kit/allowList.d.ts +68 -0
  56. package/dist/core/logging/kit/allowList.d.ts.map +1 -0
  57. package/dist/core/logging/kit/allowList.js +219 -0
  58. package/dist/core/logging/kit/allowList.js.map +1 -0
  59. package/dist/core/logging/kit/burst.d.ts +38 -0
  60. package/dist/core/logging/kit/burst.d.ts.map +1 -0
  61. package/dist/core/logging/kit/burst.js +91 -0
  62. package/dist/core/logging/kit/burst.js.map +1 -0
  63. package/dist/core/logging/kit/consoleCapture.d.ts +47 -0
  64. package/dist/core/logging/kit/consoleCapture.d.ts.map +1 -0
  65. package/dist/core/logging/kit/consoleCapture.js +121 -0
  66. package/dist/core/logging/kit/consoleCapture.js.map +1 -0
  67. package/dist/core/logging/kit/index.d.ts +12 -0
  68. package/dist/core/logging/kit/index.d.ts.map +1 -0
  69. package/dist/core/logging/kit/index.js +12 -0
  70. package/dist/core/logging/kit/index.js.map +1 -0
  71. package/dist/core/logging/kit/processHandlers.d.ts +48 -0
  72. package/dist/core/logging/kit/processHandlers.d.ts.map +1 -0
  73. package/dist/core/logging/kit/processHandlers.js +77 -0
  74. package/dist/core/logging/kit/processHandlers.js.map +1 -0
  75. package/dist/core/logging/level.d.ts +33 -0
  76. package/dist/core/logging/level.d.ts.map +1 -0
  77. package/dist/core/logging/level.js +36 -0
  78. package/dist/core/logging/level.js.map +1 -0
  79. package/dist/core/logging/loggerFactory.d.ts +74 -15
  80. package/dist/core/logging/loggerFactory.d.ts.map +1 -1
  81. package/dist/core/logging/loggerFactory.js +138 -18
  82. package/dist/core/logging/loggerFactory.js.map +1 -1
  83. package/dist/core/logging/state.d.ts +77 -0
  84. package/dist/core/logging/state.d.ts.map +1 -0
  85. package/dist/core/logging/state.js +25 -0
  86. package/dist/core/logging/state.js.map +1 -0
  87. package/dist/core/utils/terminal.d.ts +22 -0
  88. package/dist/core/utils/terminal.d.ts.map +1 -0
  89. package/dist/core/utils/terminal.js +27 -0
  90. package/dist/core/utils/terminal.js.map +1 -0
  91. package/dist/io/voice-pipeline/providers/OpenAIRealtimeTTS.d.ts +23 -4
  92. package/dist/io/voice-pipeline/providers/OpenAIRealtimeTTS.d.ts.map +1 -1
  93. package/dist/io/voice-pipeline/providers/OpenAIRealtimeTTS.js +296 -71
  94. package/dist/io/voice-pipeline/providers/OpenAIRealtimeTTS.js.map +1 -1
  95. package/package.json +6 -1
@@ -0,0 +1,219 @@
1
+ /**
2
+ * @fileoverview The allow-list logger: a typed logger over a product's event map that writes
3
+ * only declared events with fields of their declared kinds.
4
+ *
5
+ * A line the product writes through the kit is refused when its event is undeclared, or when a
6
+ * field or the context breaks its kind. A refusal is written as `log_refused` at `warn` with a
7
+ * fixed reason (`unknown_event`, `unknown_key`, `bad_value` or `bad_context`), plus the
8
+ * event's name only when the event is declared, and never the key or the value; under
9
+ * `NODE_ENV=test` it is thrown as a `LogValidationError` instead. A line that reaches the
10
+ * kit's pino-shaped form, `asLogger()`, with an undeclared event is written as
11
+ * `agentos.untyped` with only its component and its level, so a sentence from code that has
12
+ * not moved to events never reaches the log. Every line counts against the burst budgets the
13
+ * process shares.
14
+ *
15
+ * @module agentos/core/logging/kit/allowList
16
+ */
17
+ import { AGENTOS_CONTEXT, AGENTOS_EVENTS, errorFields, safeWord, valid } from '../events.js';
18
+ import { checkContext, checkFields, isValidationError, LogValidationError, sinkCall } from '../forward.js';
19
+ import { admit, burstOwner, closeOwner } from './burst.js';
20
+ const own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
21
+ // Whether two field kinds are the same: the same word, or enums of the same values in any order.
22
+ function sameKind(a, b) {
23
+ if (typeof a === 'string' || typeof b === 'string')
24
+ return a === b;
25
+ if (!a || !b || !Array.isArray(a.enum) || !Array.isArray(b.enum))
26
+ return false;
27
+ return a.enum.length === b.enum.length && a.enum.every(value => b.enum.includes(value));
28
+ }
29
+ // Whether two event declarations name the same fields with the same kinds.
30
+ function sameFields(a, b) {
31
+ const keys = Object.keys(a);
32
+ return keys.length === Object.keys(b).length && keys.every(key => own(b, key) && sameKind(a[key], b[key]));
33
+ }
34
+ /**
35
+ * Creates an allow-list logger over a product's event map. AgentOS's own events are always
36
+ * declared; the product's map adds its own and those of the packs it uses, and may name one of
37
+ * AgentOS's events again only with the same fields. No process listener is installed by
38
+ * importing or creating a kit.
39
+ *
40
+ * @param options - The kit's settings.
41
+ * @param options.logger - The pino logger, or pino child, the kit writes through.
42
+ * @param options.events - The product's event map.
43
+ * @param options.context - The context keys a child may bind beyond AgentOS's own, which stay in the schema because AgentOS's lines carry them.
44
+ * @param options.burst - Lines a minute for each event and each refusal reason, 30 unless set. Every kit in the process shares the budgets, at the smallest bound asked for.
45
+ * @returns The kit, typed over AgentOS's events and the product's map, so it also takes the
46
+ * `console_line` and `process.*` lines `captureConsole` and `installProcessHandlers` write.
47
+ * @throws {TypeError} When `burst` is not a positive integer, an event's name is not a word of at most 64 characters or is `log_refused` or `log_held`, an event declares a context key, `event`, `level` or `time` as a field, the product's map declares one of AgentOS's events with other fields than AgentOS gives it, or `context` gives one of AgentOS's context keys another kind.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import pino from 'pino';
52
+ * const kit = createAllowListLogger({ logger: pino(), events: { 'job.done': { ms: 'int' } } });
53
+ * kit.info('job.done', { ms: 120 });
54
+ * setLogger(kit.asLogger());
55
+ * ```
56
+ */
57
+ export function createAllowListLogger(options) {
58
+ const events = { ...AGENTOS_EVENTS, ...options.events };
59
+ // AgentOS's own lines carry its context keys, so a host's keys extend them and may name one again only with its kind.
60
+ for (const [key, kind] of Object.entries(options.context ?? {})) {
61
+ if (own(AGENTOS_CONTEXT, key) && !sameKind(kind, AGENTOS_CONTEXT[key]))
62
+ throw new TypeError('context key redeclared with another kind');
63
+ }
64
+ const schema = { ...AGENTOS_CONTEXT, ...options.context };
65
+ const limit = options.burst ?? 30;
66
+ if (!Number.isInteger(limit) || limit < 1)
67
+ throw new TypeError('burst must be a positive integer');
68
+ // The refusal and held-lines records are the kit's own, so a product map can neither declare nor overwrite them.
69
+ // An AgentOS event the product's map names again keeps AgentOS's fields, so AgentOS's own lines are never refused.
70
+ for (const [name, fields] of Object.entries(events)) {
71
+ if (own(AGENTOS_EVENTS, name) && !sameFields(fields, AGENTOS_EVENTS[name]))
72
+ throw new TypeError('event redeclared with other fields');
73
+ if (name === 'log_refused' || name === 'log_held' || !/^[A-Za-z0-9_.:-]{1,64}$/.test(name))
74
+ throw new TypeError('invalid event declaration');
75
+ for (const key of Object.keys(fields))
76
+ if (own(schema, key) || key === 'event' || key === 'level' || key === 'time')
77
+ throw new TypeError('reserved field declaration');
78
+ }
79
+ let closed = false;
80
+ const raw = (level, fields) => { if (!closed)
81
+ sinkCall(() => options.logger[level](fields)); };
82
+ const owner = burstOwner((name, n) => raw('info', { event: 'log_held', name, n }));
83
+ function refuse(reason, event) {
84
+ if (process.env.NODE_ENV === 'test')
85
+ throw new LogValidationError(reason);
86
+ if (admit(owner, `reason:${reason}`, reason, limit))
87
+ raw('warn', { event: 'log_refused', reason, ...(event && own(events, event) ? { name: event } : {}) });
88
+ }
89
+ // One logger over `bindings`. A child whose bindings fail the context schema writes one refusal and is then
90
+ // disabled, so it writes nothing.
91
+ function make(bindings, disabled = false) {
92
+ function write(level, event, fields = {}, adapter = false) {
93
+ if (closed || disabled)
94
+ return;
95
+ if (adapter && !own(events, event)) {
96
+ if (admit(owner, 'event:agentos.untyped', 'agentos.untyped', limit))
97
+ raw(level, { event: 'agentos.untyped', ...(bindings.component ? { component: bindings.component } : {}), sourceLevel: level });
98
+ return;
99
+ }
100
+ try {
101
+ checkContext(schema, bindings);
102
+ checkFields(events, schema, event, fields);
103
+ }
104
+ catch (error) {
105
+ if (isValidationError(error)) {
106
+ refuse(error.reason, event);
107
+ return;
108
+ }
109
+ throw error;
110
+ }
111
+ if (admit(owner, `event:${event}`, event, limit))
112
+ raw(level, { ...bindings, ...fields, event });
113
+ }
114
+ function child(next) {
115
+ const merged = { ...bindings, ...next };
116
+ try {
117
+ checkContext(schema, merged);
118
+ }
119
+ catch (error) {
120
+ if (isValidationError(error)) {
121
+ refuse('bad_context');
122
+ return make({}, true);
123
+ }
124
+ throw error;
125
+ }
126
+ return make(merged, disabled);
127
+ }
128
+ const api = {
129
+ debug: (event, fields) => write('debug', event, fields),
130
+ info: (event, fields) => write('info', event, fields),
131
+ warn: (event, fields) => write('warn', event, fields),
132
+ error: (event, fields) => write('error', event, fields),
133
+ fatal: (event, fields) => write('fatal', event, fields),
134
+ child,
135
+ terminal(event, fields = {}) {
136
+ if (closed || disabled)
137
+ return;
138
+ // Terminal never routes an unsafe value into a refusal or echoes it.
139
+ const safe = {};
140
+ const shape = events[event];
141
+ if (shape) {
142
+ for (const [key, value] of Object.entries(fields)) {
143
+ try {
144
+ checkFields(events, schema, event, { [key]: value });
145
+ safe[key] = value;
146
+ }
147
+ catch { /* Omit an invalid terminal field. */ }
148
+ }
149
+ raw('fatal', { ...bindings, ...safe, event });
150
+ }
151
+ else
152
+ raw('fatal', { event: 'process.uncaught', ...errorFields(undefined) });
153
+ },
154
+ close() { if (!closed) {
155
+ closeOwner(owner);
156
+ closed = true;
157
+ } },
158
+ // The pino-shaped form. A host's line arrives as one object holding its event, its context and its fields;
159
+ // a message alone has no event, so it is written as agentos.untyped. A refusal another layer forwards is
160
+ // written again as this kit's own, from its reason and declared name alone.
161
+ asLogger() {
162
+ const method = (level) => ((obj) => {
163
+ if (closed || disabled)
164
+ return;
165
+ if (typeof obj === 'string') {
166
+ write(level, '', {}, true);
167
+ return;
168
+ }
169
+ if (obj === null) {
170
+ write(level, '', {}, true);
171
+ return;
172
+ }
173
+ const input = obj;
174
+ const event = typeof input.event === 'string' ? input.event : '';
175
+ if (event === 'log_refused') {
176
+ const reasons = ['unknown_event', 'unknown_key', 'bad_value', 'bad_context'];
177
+ const reason = reasons.includes(input.reason) ? input.reason : 'bad_value';
178
+ refuse(reason, typeof input.name === 'string' && own(events, input.name) ? input.name : undefined);
179
+ return;
180
+ }
181
+ if (!own(events, event)) {
182
+ const component = valid('word', input.component) ? input.component : bindings.component;
183
+ if (admit(owner, 'event:agentos.untyped', 'agentos.untyped', limit)) {
184
+ raw(level, { event: 'agentos.untyped', ...(component ? { component } : {}), sourceLevel: level });
185
+ }
186
+ return;
187
+ }
188
+ const context = { ...bindings };
189
+ const fields = {};
190
+ for (const [key, value] of Object.entries(input)) {
191
+ if (key === 'event')
192
+ continue;
193
+ if (own(schema, key))
194
+ context[key] = value;
195
+ else
196
+ fields[key] = value;
197
+ }
198
+ try {
199
+ checkContext(schema, context);
200
+ }
201
+ catch (error) {
202
+ if (isValidationError(error)) {
203
+ refuse('bad_context', event);
204
+ return;
205
+ }
206
+ throw error;
207
+ }
208
+ make(context)[level](event, fields);
209
+ });
210
+ return { debug: method('debug'), info: method('info'), warn: method('warn'), error: method('error'), fatal: method('fatal'), child: next => child(next).asLogger() };
211
+ },
212
+ };
213
+ return api;
214
+ }
215
+ // The map the kit checks against always holds AgentOS's own events, so its type does too.
216
+ return make({});
217
+ }
218
+ export { safeWord };
219
+ //# sourceMappingURL=allowList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allowList.js","sourceRoot":"","sources":["../../../../src/core/logging/kit/allowList.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview The burst budgets every allow-list kit in the process shares.
3
+ *
4
+ * Each declared event, and each refusal reason, writes the first `limit` lines of a minute;
5
+ * the rest are held, and once the minute has turned one `log_held` line gives the name and
6
+ * the count held. The budgets live in the process-wide logging state, so every kit instance,
7
+ * child, adapter and lazy handle that writes through a kit counts against the same minute.
8
+ * The timer that reports held lines is unreferenced, so it never holds the process open, and
9
+ * closing the last kit clears it with the counters.
10
+ *
11
+ * @module agentos/core/logging/kit/burst
12
+ */
13
+ /**
14
+ * Registers a kit as an owner of burst budgets.
15
+ *
16
+ * @param emit - Writes the kit's `log_held` line: the event or refusal reason held, and how many lines were held.
17
+ * @returns The owner's key, which {@link admit} and {@link closeOwner} take.
18
+ */
19
+ export declare function burstOwner(emit: (name: string, n: number) => void): symbol;
20
+ /**
21
+ * Counts one line against its minute's budget. A budget's bound is the smallest any kit asked
22
+ * for in that minute.
23
+ *
24
+ * @param owner - The kit writing the line; a minute it opens reports its held lines through it.
25
+ * @param key - The budget's key, built from a declared event's name or a fixed refusal reason, so the keys are finite.
26
+ * @param name - The event's name or the refusal reason, as the `log_held` line gives it.
27
+ * @param limit - The kit's bound on lines a minute.
28
+ * @returns `true` when the line may be written, `false` when it is held.
29
+ */
30
+ export declare function admit(owner: symbol, key: string, name: string, limit: number): boolean;
31
+ /**
32
+ * Removes a kit from the owners. A minute it opened still reports through a kit that remains
33
+ * open; when no kit remains, the counters and the timer are cleared.
34
+ *
35
+ * @param owner - The key {@link burstOwner} returned.
36
+ */
37
+ export declare function closeOwner(owner: symbol): void;
38
+ //# sourceMappingURL=burst.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"burst.d.ts","sourceRoot":"","sources":["../../../../src/core/logging/kit/burst.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA6BH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,CAE1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOtF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAI9C"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview The burst budgets every allow-list kit in the process shares.
3
+ *
4
+ * Each declared event, and each refusal reason, writes the first `limit` lines of a minute;
5
+ * the rest are held, and once the minute has turned one `log_held` line gives the name and
6
+ * the count held. The budgets live in the process-wide logging state, so every kit instance,
7
+ * child, adapter and lazy handle that writes through a kit counts against the same minute.
8
+ * The timer that reports held lines is unreferenced, so it never holds the process open, and
9
+ * closing the last kit clears it with the counters.
10
+ *
11
+ * @module agentos/core/logging/kit/burst
12
+ */
13
+ import { getLoggingState } from '../state.js';
14
+ // Ends every minute that has turned and reports what it held through the writer of the kit that opened it, or,
15
+ // when that kit has closed, through any kit still open.
16
+ function flush() {
17
+ const state = getLoggingState();
18
+ const now = Date.now();
19
+ for (const [key, minute] of state.minutes) {
20
+ if (now - minute.start < 60000)
21
+ continue;
22
+ state.minutes.delete(key);
23
+ const emit = state.owners.get(minute.owner) ?? state.owners.values().next().value;
24
+ if (minute.held)
25
+ emit?.(minute.name, minute.held);
26
+ }
27
+ }
28
+ // Keeps one unreferenced timer for the earliest minute that holds lines, and none when no minute holds any or no
29
+ // kit is open to report it.
30
+ function schedule() {
31
+ const state = getLoggingState();
32
+ if (state.timer)
33
+ clearTimeout(state.timer);
34
+ state.timer = undefined;
35
+ const ends = [...state.minutes.values()].filter(m => m.held > 0).map(m => m.start + 60000);
36
+ if (!ends.length || !state.owners.size)
37
+ return;
38
+ const delay = Math.min(60000, Math.max(0, Math.min(...ends) - Date.now()));
39
+ state.timer = setTimeout(() => { state.timer = undefined; flush(); schedule(); }, delay);
40
+ state.timer.unref();
41
+ }
42
+ /**
43
+ * Registers a kit as an owner of burst budgets.
44
+ *
45
+ * @param emit - Writes the kit's `log_held` line: the event or refusal reason held, and how many lines were held.
46
+ * @returns The owner's key, which {@link admit} and {@link closeOwner} take.
47
+ */
48
+ export function burstOwner(emit) {
49
+ const owner = Symbol();
50
+ getLoggingState().owners.set(owner, emit);
51
+ return owner;
52
+ }
53
+ /**
54
+ * Counts one line against its minute's budget. A budget's bound is the smallest any kit asked
55
+ * for in that minute.
56
+ *
57
+ * @param owner - The kit writing the line; a minute it opens reports its held lines through it.
58
+ * @param key - The budget's key, built from a declared event's name or a fixed refusal reason, so the keys are finite.
59
+ * @param name - The event's name or the refusal reason, as the `log_held` line gives it.
60
+ * @param limit - The kit's bound on lines a minute.
61
+ * @returns `true` when the line may be written, `false` when it is held.
62
+ */
63
+ export function admit(owner, key, name, limit) {
64
+ const state = getLoggingState();
65
+ flush();
66
+ const minute = state.minutes.get(key) ?? { start: Date.now(), written: 0, held: 0, limit, owner, name };
67
+ minute.limit = Math.min(minute.limit, limit);
68
+ state.minutes.set(key, minute);
69
+ if (minute.written < minute.limit) {
70
+ minute.written++;
71
+ schedule();
72
+ return true;
73
+ }
74
+ minute.held++;
75
+ schedule();
76
+ return false;
77
+ }
78
+ /**
79
+ * Removes a kit from the owners. A minute it opened still reports through a kit that remains
80
+ * open; when no kit remains, the counters and the timer are cleared.
81
+ *
82
+ * @param owner - The key {@link burstOwner} returned.
83
+ */
84
+ export function closeOwner(owner) {
85
+ const state = getLoggingState();
86
+ state.owners.delete(owner);
87
+ if (!state.owners.size)
88
+ state.minutes.clear();
89
+ schedule();
90
+ }
91
+ //# sourceMappingURL=burst.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"burst.js","sourceRoot":"","sources":["../../../../src/core/logging/kit/burst.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @fileoverview Console capture: each console call becomes one content-free `console_line`
3
+ * event.
4
+ *
5
+ * The event carries the console method and, when one of the values is an error, its type and
6
+ * code. The text is never written. For an error, the frames of its stack after the exact
7
+ * opening (its name, `: ` and its message) go to standard error through the terminal writer,
8
+ * so an operator sees where it was thrown; a stack that opens any other way gives no frames,
9
+ * since a value inside a message could be shaped like a frame. Only lines with a frame's form
10
+ * (`at ` after the indent) are written, at most 50, and a line over 512 characters or holding
11
+ * a control or direction character is left out, so a stack set by hand cannot put text or
12
+ * terminal sequences on standard error. An error whose properties throw when read gives the
13
+ * event with `unknown` fields and no frames, and the console call does not throw.
14
+ *
15
+ * @module agentos/core/logging/kit/consoleCapture
16
+ */
17
+ /**
18
+ * What console capture writes through: the `warn` method of an allow-list kit whose map
19
+ * declares AgentOS's `console_line` event.
20
+ */
21
+ export interface ConsoleKit {
22
+ warn(event: 'console_line', fields: {
23
+ method: (typeof METHODS)[number];
24
+ type?: string;
25
+ code?: string;
26
+ }): void;
27
+ }
28
+ declare const METHODS: readonly ["debug", "info", "log", "warn", "error", "trace", "dir", "table", "assert", "count", "countReset", "time", "timeEnd", "timeLog", "group", "groupCollapsed", "groupEnd", "clear", "dirxml", "profile", "profileEnd", "timeStamp"];
29
+ /**
30
+ * Replaces each console method with one that writes a `console_line` event through the kit.
31
+ * Capturing is idempotent across every copy of AgentOS in the process: a second call returns
32
+ * the first call's restore function and changes nothing. A console call made while a captured
33
+ * call is being written is dropped.
34
+ *
35
+ * @param kit - The kit the events are written through.
36
+ * @returns A function that puts the original console methods back.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const restore = captureConsole(kit);
41
+ * console.error(new Error('text that is never written')); // one console_line line: method, type, code
42
+ * restore();
43
+ * ```
44
+ */
45
+ export declare function captureConsole(kit: ConsoleKit): () => void;
46
+ export {};
47
+ //# sourceMappingURL=consoleCapture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleCapture.d.ts","sourceRoot":"","sources":["../../../../src/core/logging/kit/consoleCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH;;;GAGG;AACH,MAAM,WAAW,UAAU;IAAG,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE;QAAE,MAAM,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAAE;AAC7I,QAAA,MAAM,OAAO,4OAA6O,CAAC;AA6C3P;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,IAAI,CAyB1D"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @fileoverview Console capture: each console call becomes one content-free `console_line`
3
+ * event.
4
+ *
5
+ * The event carries the console method and, when one of the values is an error, its type and
6
+ * code. The text is never written. For an error, the frames of its stack after the exact
7
+ * opening (its name, `: ` and its message) go to standard error through the terminal writer,
8
+ * so an operator sees where it was thrown; a stack that opens any other way gives no frames,
9
+ * since a value inside a message could be shaped like a frame. Only lines with a frame's form
10
+ * (`at ` after the indent) are written, at most 50, and a line over 512 characters or holding
11
+ * a control or direction character is left out, so a stack set by hand cannot put text or
12
+ * terminal sequences on standard error. An error whose properties throw when read gives the
13
+ * event with `unknown` fields and no frames, and the console call does not throw.
14
+ *
15
+ * @module agentos/core/logging/kit/consoleCapture
16
+ */
17
+ import { errorFields } from '../events.js';
18
+ import { terminal } from '../../utils/terminal.js';
19
+ const METHODS = ['debug', 'info', 'log', 'warn', 'error', 'trace', 'dir', 'table', 'assert', 'count', 'countReset', 'time', 'timeEnd', 'timeLog', 'group', 'groupCollapsed', 'groupEnd', 'clear', 'dirxml', 'profile', 'profileEnd', 'timeStamp'];
20
+ // The restore function of the capture in place, shared by every copy of AgentOS in the process.
21
+ const KEY = Symbol.for('agentos.logging.console.v1');
22
+ // A frame line, and the bounds on the frames written.
23
+ const FRAME = /^ +at \S/;
24
+ const MAX_FRAMES = 50;
25
+ const MAX_FRAME_LENGTH = 512;
26
+ // Whether a line holds a C0 or C1 control, DEL, or a direction mark or override. A loop, not a regular
27
+ // expression, since eslint's no-control-regex refuses control characters in one.
28
+ function unsafe(line) {
29
+ for (let index = 0; index < line.length; index += 1) {
30
+ const code = line.charCodeAt(index);
31
+ if (code < 0x20 || (code >= 0x7f && code <= 0x9f) || code === 0x200e || code === 0x200f
32
+ || (code >= 0x202a && code <= 0x202e) || (code >= 0x2066 && code <= 0x2069))
33
+ return true;
34
+ }
35
+ return false;
36
+ }
37
+ // The first value that is an error; a value whose prototype throws when read is passed over.
38
+ function firstError(values) {
39
+ for (const value of values) {
40
+ try {
41
+ if (value instanceof Error)
42
+ return value;
43
+ }
44
+ catch { /* Not an error that can be read. */ }
45
+ }
46
+ return undefined;
47
+ }
48
+ // The frame lines of an error's stack after its exact opening, bounded, or '' when there are none or reading fails.
49
+ function framesOf(error) {
50
+ try {
51
+ const stack = error.stack;
52
+ if (typeof stack !== 'string')
53
+ return '';
54
+ const message = error.message;
55
+ for (const name of [error.name, 'Error']) {
56
+ const opening = `${name}: ${message}\n`;
57
+ if (!stack.startsWith(opening))
58
+ continue;
59
+ const lines = stack.slice(opening.length).split('\n')
60
+ .filter(line => line.length <= MAX_FRAME_LENGTH && FRAME.test(line) && !unsafe(line))
61
+ .slice(0, MAX_FRAMES);
62
+ return lines.length ? `${lines.join('\n')}\n` : '';
63
+ }
64
+ return '';
65
+ }
66
+ catch {
67
+ return '';
68
+ }
69
+ }
70
+ /**
71
+ * Replaces each console method with one that writes a `console_line` event through the kit.
72
+ * Capturing is idempotent across every copy of AgentOS in the process: a second call returns
73
+ * the first call's restore function and changes nothing. A console call made while a captured
74
+ * call is being written is dropped.
75
+ *
76
+ * @param kit - The kit the events are written through.
77
+ * @returns A function that puts the original console methods back.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const restore = captureConsole(kit);
82
+ * console.error(new Error('text that is never written')); // one console_line line: method, type, code
83
+ * restore();
84
+ * ```
85
+ */
86
+ export function captureConsole(kit) {
87
+ const holder = globalThis;
88
+ if (holder[KEY])
89
+ return holder[KEY];
90
+ const target = console;
91
+ const originals = new Map();
92
+ let writing = false;
93
+ for (const method of METHODS) {
94
+ if (typeof target[method] !== 'function')
95
+ continue;
96
+ originals.set(method, target[method]);
97
+ target[method] = (...values) => {
98
+ if (writing)
99
+ return;
100
+ writing = true;
101
+ try {
102
+ const error = firstError(values);
103
+ kit.warn('console_line', { method, ...(error ? errorFields(error) : {}) });
104
+ const frames = error ? framesOf(error) : '';
105
+ if (frames)
106
+ terminal(frames, 'stderr');
107
+ }
108
+ finally {
109
+ writing = false;
110
+ }
111
+ };
112
+ }
113
+ const restore = () => {
114
+ for (const [method, original] of originals)
115
+ target[method] = original;
116
+ delete holder[KEY];
117
+ };
118
+ holder[KEY] = restore;
119
+ return restore;
120
+ }
121
+ //# sourceMappingURL=consoleCapture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleCapture.js","sourceRoot":"","sources":["../../../../src/core/logging/kit/consoleCapture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview The allow-list kit: a typed logger over a product's event map with fixed
3
+ * refusal reasons and burst budgets shared across the process, console capture, and opt-in
4
+ * process handlers.
5
+ *
6
+ * @module agentos/core/logging/kit
7
+ */
8
+ export { createAllowListLogger, type AllowListLogger } from './allowList.js';
9
+ export { captureConsole } from './consoleCapture.js';
10
+ export { installProcessHandlers } from './processHandlers.js';
11
+ export { LogValidationError } from '../forward.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/logging/kit/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview The allow-list kit: a typed logger over a product's event map with fixed
3
+ * refusal reasons and burst budgets shared across the process, console capture, and opt-in
4
+ * process handlers.
5
+ *
6
+ * @module agentos/core/logging/kit
7
+ */
8
+ export { createAllowListLogger } from './allowList.js';
9
+ export { captureConsole } from './consoleCapture.js';
10
+ export { installProcessHandlers } from './processHandlers.js';
11
+ export { LogValidationError } from '../forward.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/logging/kit/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,qBAAqB,EAAwB,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Opt-in process handlers: the shutdown line and the process's last line.
3
+ *
4
+ * AgentOS never installs these. A host with handlers of its own calls the kit's `terminal()`
5
+ * from them instead.
6
+ *
7
+ * @module agentos/core/logging/kit/processHandlers
8
+ */
9
+ /** What the process handlers write through: an allow-list kit whose map declares AgentOS's process events. */
10
+ export interface ProcessKit {
11
+ info(event: 'process.shutdown', fields: {
12
+ signal: 'SIGTERM' | 'SIGINT';
13
+ }): void;
14
+ terminal(event: 'process.uncaught', fields: {
15
+ type: string;
16
+ code: string;
17
+ }): void;
18
+ }
19
+ /**
20
+ * Installs handlers for SIGTERM, SIGINT, uncaught exceptions and unhandled rejections.
21
+ *
22
+ * - On SIGTERM or SIGINT, the first signal writes `process.shutdown` with the signal, then
23
+ * calls `onShutdown`, which owns closing the host's servers and pools and ending the
24
+ * process. A later signal is ignored.
25
+ * - On an uncaught exception or an unhandled rejection, or when `onShutdown` fails, it writes
26
+ * `process.uncaught` with the error's type and code through `terminal()`, which bypasses the
27
+ * burst budget at `fatal`, then calls `onFatal`, which exits with status 1 unless the host
28
+ * gives its own.
29
+ *
30
+ * Installing is idempotent across every copy of AgentOS in the process: while the handlers are
31
+ * installed, a second call returns the first call's remover and installs nothing.
32
+ *
33
+ * @param kit - The kit the lines are written through.
34
+ * @param options - The host's callbacks.
35
+ * @param options.onShutdown - Called once, after the shutdown line, with the signal.
36
+ * @param options.onFatal - Called after the last line with the error; `process.exit(1)` unless given.
37
+ * @returns A function that removes every handler it installed.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * installProcessHandlers(kit, { onShutdown: async () => { await server.close(); process.exit(0); } });
42
+ * ```
43
+ */
44
+ export declare function installProcessHandlers(kit: ProcessKit, options: {
45
+ onShutdown: (signal: 'SIGTERM' | 'SIGINT') => void | Promise<void>;
46
+ onFatal?: (error: unknown) => void;
47
+ }): () => void;
48
+ //# sourceMappingURL=processHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processHandlers.d.ts","sourceRoot":"","sources":["../../../../src/core/logging/kit/processHandlers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,8GAA8G;AAC9G,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE;QAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE;IAC/D,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,MAAM,IAAI,CAuBb"}