@acquiredintelligence/attend 0.0.0-stage → 0.2.0

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -2
  3. package/dist/attend.d.ts +30 -0
  4. package/dist/attend.d.ts.map +1 -0
  5. package/dist/attend.js +464 -0
  6. package/dist/attend.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +4 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/core/ids.d.ts +12 -0
  12. package/dist/core/ids.d.ts.map +1 -0
  13. package/dist/core/ids.js +97 -0
  14. package/dist/core/ids.js.map +1 -0
  15. package/dist/core/reducer.d.ts +26 -0
  16. package/dist/core/reducer.d.ts.map +1 -0
  17. package/dist/core/reducer.js +437 -0
  18. package/dist/core/reducer.js.map +1 -0
  19. package/dist/core/seen.d.ts +22 -0
  20. package/dist/core/seen.d.ts.map +1 -0
  21. package/dist/core/seen.js +61 -0
  22. package/dist/core/seen.js.map +1 -0
  23. package/dist/core/state.d.ts +12 -0
  24. package/dist/core/state.d.ts.map +1 -0
  25. package/dist/core/state.js +90 -0
  26. package/dist/core/state.js.map +1 -0
  27. package/dist/core/step.d.ts +14 -0
  28. package/dist/core/step.d.ts.map +1 -0
  29. package/dist/core/step.js +17 -0
  30. package/dist/core/step.js.map +1 -0
  31. package/dist/core/threshold.d.ts +40 -0
  32. package/dist/core/threshold.d.ts.map +1 -0
  33. package/dist/core/threshold.js +72 -0
  34. package/dist/core/threshold.js.map +1 -0
  35. package/dist/core/types.d.ts +704 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +24 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/window.d.ts +38 -0
  40. package/dist/core/window.d.ts.map +1 -0
  41. package/dist/core/window.js +322 -0
  42. package/dist/core/window.js.map +1 -0
  43. package/dist/decisions.d.ts +53 -0
  44. package/dist/decisions.d.ts.map +1 -0
  45. package/dist/decisions.js +115 -0
  46. package/dist/decisions.js.map +1 -0
  47. package/dist/errors.d.ts +36 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +53 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/internal/adapter.d.ts +21 -0
  56. package/dist/internal/adapter.d.ts.map +1 -0
  57. package/dist/internal/adapter.js +62 -0
  58. package/dist/internal/adapter.js.map +1 -0
  59. package/dist/internal/assert.d.ts +5 -0
  60. package/dist/internal/assert.d.ts.map +1 -0
  61. package/dist/internal/assert.js +14 -0
  62. package/dist/internal/assert.js.map +1 -0
  63. package/dist/internal/clock.d.ts +8 -0
  64. package/dist/internal/clock.d.ts.map +1 -0
  65. package/dist/internal/clock.js +38 -0
  66. package/dist/internal/clock.js.map +1 -0
  67. package/dist/internal/http.d.ts +42 -0
  68. package/dist/internal/http.d.ts.map +1 -0
  69. package/dist/internal/http.js +122 -0
  70. package/dist/internal/http.js.map +1 -0
  71. package/dist/internal/images.d.ts +18 -0
  72. package/dist/internal/images.d.ts.map +1 -0
  73. package/dist/internal/images.js +75 -0
  74. package/dist/internal/images.js.map +1 -0
  75. package/dist/internal/json.d.ts +3 -0
  76. package/dist/internal/json.d.ts.map +1 -0
  77. package/dist/internal/json.js +5 -0
  78. package/dist/internal/json.js.map +1 -0
  79. package/dist/internal/prompt.d.ts +31 -0
  80. package/dist/internal/prompt.d.ts.map +1 -0
  81. package/dist/internal/prompt.js +149 -0
  82. package/dist/internal/prompt.js.map +1 -0
  83. package/dist/internal/shared.d.ts +12 -0
  84. package/dist/internal/shared.d.ts.map +1 -0
  85. package/dist/internal/shared.js +138 -0
  86. package/dist/internal/shared.js.map +1 -0
  87. package/dist/jev.d.ts +74 -0
  88. package/dist/jev.d.ts.map +1 -0
  89. package/dist/jev.js +156 -0
  90. package/dist/jev.js.map +1 -0
  91. package/dist/llm.d.ts +164 -0
  92. package/dist/llm.d.ts.map +1 -0
  93. package/dist/llm.js +79 -0
  94. package/dist/llm.js.map +1 -0
  95. package/dist/mcp.d.ts +130 -0
  96. package/dist/mcp.d.ts.map +1 -0
  97. package/dist/mcp.js +550 -0
  98. package/dist/mcp.js.map +1 -0
  99. package/dist/memory.d.ts +10 -0
  100. package/dist/memory.d.ts.map +1 -0
  101. package/dist/memory.js +50 -0
  102. package/dist/memory.js.map +1 -0
  103. package/dist/postgres.d.ts +25 -0
  104. package/dist/postgres.d.ts.map +1 -0
  105. package/dist/postgres.js +56 -0
  106. package/dist/postgres.js.map +1 -0
  107. package/dist/redis.d.ts +20 -0
  108. package/dist/redis.d.ts.map +1 -0
  109. package/dist/redis.js +83 -0
  110. package/dist/redis.js.map +1 -0
  111. package/dist/server/compat.d.ts +13 -0
  112. package/dist/server/compat.d.ts.map +1 -0
  113. package/dist/server/compat.js +5 -0
  114. package/dist/server/compat.js.map +1 -0
  115. package/dist/server/cursor.d.ts +15 -0
  116. package/dist/server/cursor.d.ts.map +1 -0
  117. package/dist/server/cursor.js +50 -0
  118. package/dist/server/cursor.js.map +1 -0
  119. package/dist/server/events.d.ts +42 -0
  120. package/dist/server/events.d.ts.map +1 -0
  121. package/dist/server/events.js +189 -0
  122. package/dist/server/events.js.map +1 -0
  123. package/dist/server/fanout.d.ts +28 -0
  124. package/dist/server/fanout.d.ts.map +1 -0
  125. package/dist/server/fanout.js +184 -0
  126. package/dist/server/fanout.js.map +1 -0
  127. package/dist/server/guard.d.ts +19 -0
  128. package/dist/server/guard.d.ts.map +1 -0
  129. package/dist/server/guard.js +27 -0
  130. package/dist/server/guard.js.map +1 -0
  131. package/dist/server/http.d.ts +4 -0
  132. package/dist/server/http.d.ts.map +1 -0
  133. package/dist/server/http.js +323 -0
  134. package/dist/server/http.js.map +1 -0
  135. package/dist/server/ingest.d.ts +4 -0
  136. package/dist/server/ingest.d.ts.map +1 -0
  137. package/dist/server/ingest.js +400 -0
  138. package/dist/server/ingest.js.map +1 -0
  139. package/dist/server/install.d.ts +5 -0
  140. package/dist/server/install.d.ts.map +1 -0
  141. package/dist/server/install.js +91 -0
  142. package/dist/server/install.js.map +1 -0
  143. package/dist/server/poll.d.ts +4 -0
  144. package/dist/server/poll.d.ts.map +1 -0
  145. package/dist/server/poll.js +45 -0
  146. package/dist/server/poll.js.map +1 -0
  147. package/dist/server/serve.d.ts +19 -0
  148. package/dist/server/serve.d.ts.map +1 -0
  149. package/dist/server/serve.js +238 -0
  150. package/dist/server/serve.js.map +1 -0
  151. package/dist/server/sessions.d.ts +14 -0
  152. package/dist/server/sessions.d.ts.map +1 -0
  153. package/dist/server/sessions.js +54 -0
  154. package/dist/server/sessions.js.map +1 -0
  155. package/dist/server/stream.d.ts +11 -0
  156. package/dist/server/stream.d.ts.map +1 -0
  157. package/dist/server/stream.js +216 -0
  158. package/dist/server/stream.js.map +1 -0
  159. package/dist/server/tools.d.ts +22 -0
  160. package/dist/server/tools.d.ts.map +1 -0
  161. package/dist/server/tools.js +55 -0
  162. package/dist/server/tools.js.map +1 -0
  163. package/dist/server/types.d.ts +351 -0
  164. package/dist/server/types.d.ts.map +1 -0
  165. package/dist/server/types.js +5 -0
  166. package/dist/server/types.js.map +1 -0
  167. package/dist/server.d.ts +11 -0
  168. package/dist/server.d.ts.map +1 -0
  169. package/dist/server.js +10 -0
  170. package/dist/server.js.map +1 -0
  171. package/dist/shell/budget.d.ts +4 -0
  172. package/dist/shell/budget.d.ts.map +1 -0
  173. package/dist/shell/budget.js +5 -0
  174. package/dist/shell/budget.js.map +1 -0
  175. package/dist/shell/copy.d.ts +20 -0
  176. package/dist/shell/copy.d.ts.map +1 -0
  177. package/dist/shell/copy.js +73 -0
  178. package/dist/shell/copy.js.map +1 -0
  179. package/dist/shell/decisions.d.ts +6 -0
  180. package/dist/shell/decisions.d.ts.map +1 -0
  181. package/dist/shell/decisions.js +42 -0
  182. package/dist/shell/decisions.js.map +1 -0
  183. package/dist/shell/read.d.ts +7 -0
  184. package/dist/shell/read.d.ts.map +1 -0
  185. package/dist/shell/read.js +21 -0
  186. package/dist/shell/read.js.map +1 -0
  187. package/dist/shell/scheduler.d.ts +4 -0
  188. package/dist/shell/scheduler.d.ts.map +1 -0
  189. package/dist/shell/scheduler.js +90 -0
  190. package/dist/shell/scheduler.js.map +1 -0
  191. package/dist/shell/scope.d.ts +27 -0
  192. package/dist/shell/scope.d.ts.map +1 -0
  193. package/dist/shell/scope.js +343 -0
  194. package/dist/shell/scope.js.map +1 -0
  195. package/dist/shell/types.d.ts +168 -0
  196. package/dist/shell/types.d.ts.map +1 -0
  197. package/dist/shell/types.js +2 -0
  198. package/dist/shell/types.js.map +1 -0
  199. package/dist/sqlite.d.ts +14 -0
  200. package/dist/sqlite.d.ts.map +1 -0
  201. package/dist/sqlite.js +39 -0
  202. package/dist/sqlite.js.map +1 -0
  203. package/dist/step.d.ts +18 -0
  204. package/dist/step.d.ts.map +1 -0
  205. package/dist/step.js +14 -0
  206. package/dist/step.js.map +1 -0
  207. package/dist/store/memory.d.ts +12 -0
  208. package/dist/store/memory.d.ts.map +1 -0
  209. package/dist/store/memory.js +264 -0
  210. package/dist/store/memory.js.map +1 -0
  211. package/dist/store/postgres.d.ts +24 -0
  212. package/dist/store/postgres.d.ts.map +1 -0
  213. package/dist/store/postgres.js +364 -0
  214. package/dist/store/postgres.js.map +1 -0
  215. package/dist/store/redis.d.ts +12 -0
  216. package/dist/store/redis.d.ts.map +1 -0
  217. package/dist/store/redis.js +540 -0
  218. package/dist/store/redis.js.map +1 -0
  219. package/dist/store/sqlite-worker.d.ts +91 -0
  220. package/dist/store/sqlite-worker.d.ts.map +1 -0
  221. package/dist/store/sqlite-worker.js +322 -0
  222. package/dist/store/sqlite-worker.js.map +1 -0
  223. package/dist/store/sqlite.d.ts +34 -0
  224. package/dist/store/sqlite.d.ts.map +1 -0
  225. package/dist/store/sqlite.js +238 -0
  226. package/dist/store/sqlite.js.map +1 -0
  227. package/dist/store/types.d.ts +137 -0
  228. package/dist/store/types.d.ts.map +1 -0
  229. package/dist/store/types.js +2 -0
  230. package/dist/store/types.js.map +1 -0
  231. package/dist/testing/conformance.d.ts +13 -0
  232. package/dist/testing/conformance.d.ts.map +1 -0
  233. package/dist/testing/conformance.js +542 -0
  234. package/dist/testing/conformance.js.map +1 -0
  235. package/dist/testing/wire.d.ts +16 -0
  236. package/dist/testing/wire.d.ts.map +1 -0
  237. package/dist/testing/wire.js +304 -0
  238. package/dist/testing/wire.js.map +1 -0
  239. package/dist/testing.d.ts +113 -0
  240. package/dist/testing.d.ts.map +1 -0
  241. package/dist/testing.js +655 -0
  242. package/dist/testing.js.map +1 -0
  243. package/dist/types.d.ts +5 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +5 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +130 -4
  248. package/skills/attend/SKILL.md +231 -0
  249. package/skills/attend/references/judges.md +283 -0
  250. package/skills/attend/references/kinds.md +62 -0
  251. package/skills/attend/references/mcp.md +132 -0
  252. package/skills/attend/references/sinks.md +73 -0
  253. package/skills/attend/references/stores.md +90 -0
  254. package/skills/attend/references/testing.md +120 -0
@@ -0,0 +1,55 @@
1
+ import { EventsError, eventsError, occurrenceFor } from './events.js';
2
+ import { pollEvents } from './poll.js';
3
+ /** attend_wait and attend_window. */
4
+ export function listTools() {
5
+ return [
6
+ { name: 'attend_wait', description: 'Wait for routed decisions or dead letters after your saved cursor, then persist the returned cursor.', inputSchema: {
7
+ type: 'object', additionalProperties: false, properties: { name: { type: 'string', default: 'attention.decision' }, arguments: { type: 'object' }, cursor: { type: ['string', 'null'] }, waitMs: { type: 'integer', minimum: 0, maximum: 30000, default: 30000 }, maxEvents: { type: 'integer', minimum: 1, maximum: 20, default: 20 } },
8
+ } },
9
+ { name: 'attend_window', description: 'Read the full event window for a decision you are allowed to see.', inputSchema: { type: 'object', additionalProperties: false, required: ['decisionId'], properties: { decisionId: { type: 'string' } } } },
10
+ ];
11
+ }
12
+ /** Calls a tool, preserving application errors as structured tool results. */
13
+ export async function callTool(context, name, args, principal, signal) {
14
+ if (name !== 'attend_wait' && name !== 'attend_window')
15
+ throw eventsError('InvalidParams', 'Unknown tool', { field: 'name', reason: 'unknown tool' });
16
+ try {
17
+ const value = args === undefined ? {} : args;
18
+ if (typeof value !== 'object' || value === null || (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null))
19
+ throw eventsError('InvalidParams', 'Invalid arguments', { field: 'arguments', reason: 'must be an object' });
20
+ const values = value;
21
+ const allowed = name === 'attend_wait' ? ['name', 'arguments', 'cursor', 'maxEvents', 'waitMs'] : ['decisionId'];
22
+ for (const key of Object.keys(values))
23
+ if (!allowed.includes(key))
24
+ throw eventsError('InvalidParams', 'Unknown argument', { field: `arguments.${key}`, reason: 'unknown' });
25
+ let structuredContent;
26
+ if (name === 'attend_wait') {
27
+ const cap = (key, fallback, minimum) => {
28
+ const value = values[key];
29
+ if (value === undefined)
30
+ return fallback;
31
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < minimum)
32
+ throw eventsError('InvalidParams', `Invalid ${key}`, { field: key, reason: `must be a safe integer >= ${minimum}` });
33
+ return Math.min(value, fallback);
34
+ };
35
+ const result = await pollEvents(context, { ...values, name: values.name ?? 'attention.decision', maxEvents: cap('maxEvents', 20, 1), waitMs: cap('waitMs', 30_000, 0) }, principal, signal);
36
+ structuredContent = { events: result.events.map((event) => ({ ...event })), cursor: result.cursor, truncated: result.truncated };
37
+ }
38
+ else {
39
+ if (typeof values.decisionId !== 'string')
40
+ throw eventsError('InvalidParams', 'Invalid decisionId', { field: 'decisionId', reason: 'required' });
41
+ const row = await context.log.find('decision', values.decisionId);
42
+ if (!row || !principal.scopes.some((grant) => row.scope.startsWith(grant)))
43
+ throw eventsError('NotFound', 'Decision not found', { kind: 'decision' });
44
+ const occurrence = occurrenceFor(row, 'events', context.options.payload?.maxEventsBytes);
45
+ structuredContent = { ...occurrence.data, ...(occurrence._meta?.['attend/eventsOmitted'] ? { eventsOmitted: true } : {}) };
46
+ }
47
+ return { content: [{ type: 'text', text: JSON.stringify(structuredContent) }], structuredContent };
48
+ }
49
+ catch (error) {
50
+ if (!(error instanceof EventsError))
51
+ throw error;
52
+ return { content: [{ type: 'text', text: error.message }], structuredContent: { error: { ...error.toJSON() } }, isError: true };
53
+ }
54
+ }
55
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,351 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { ToolResult } from './tools.js';
3
+ import type { Fanout } from './fanout.js';
4
+ import type { DecisionLog, Position } from '../store/types.js';
5
+ import type { DeliveredRoute, Entry, JsonObject, Route, SettleReason } from '../core/types.js';
6
+ export declare const EVENTS_EXTENSION = "io.modelcontextprotocol/events";
7
+ export declare const SUBSCRIPTION_ID_META = "io.modelcontextprotocol/subscriptionId";
8
+ export declare const DECISION_EVENT = "attention.decision";
9
+ export declare const DEAD_LETTER_EVENT = "attention.deadLetter";
10
+ export type AttendEventName = typeof DECISION_EVENT | typeof DEAD_LETTER_EVENT;
11
+ export type DeliveryMode = 'poll' | 'push';
12
+ export interface EventDescriptor {
13
+ name: string;
14
+ description: string;
15
+ delivery: DeliveryMode[];
16
+ inputSchema: JsonObject;
17
+ payloadSchema: JsonObject;
18
+ _meta?: JsonObject;
19
+ }
20
+ /** Every result this extension defines carries `resultType: "complete"`. */
21
+ export interface CompleteResult {
22
+ resultType: 'complete';
23
+ }
24
+ export interface ListEventsParams {
25
+ cursor?: string;
26
+ }
27
+ export interface ListEventsResult extends CompleteResult {
28
+ events: EventDescriptor[];
29
+ nextCursor?: string;
30
+ }
31
+ /** An absent `cursor` means null, in both directions. */
32
+ export interface EventOccurrence<D extends object = JsonObject> {
33
+ eventId: string;
34
+ name: string;
35
+ timestamp: string;
36
+ data: D;
37
+ cursor?: string | null;
38
+ _meta?: JsonObject;
39
+ }
40
+ /** `attention.decision` arguments. The schema starts strict and only loosens. `scope` and `scopePrefix` are exclusive. */
41
+ export interface DecisionArguments {
42
+ scope?: string;
43
+ scopePrefix?: string;
44
+ routes?: DeliveredRoute[];
45
+ minProbability?: number;
46
+ include?: 'notice' | 'events';
47
+ }
48
+ export interface DeadLetterArguments {
49
+ scope?: string;
50
+ scopePrefix?: string;
51
+ stage?: 'judge' | 'sink';
52
+ }
53
+ /** `attention.decision` data: triage fields only. The full window is behind `include: "events"` or the `attend_window` tool. */
54
+ export interface AttentionDecisionData {
55
+ decisionId: string;
56
+ scope: string;
57
+ route: DeliveredRoute;
58
+ probabilities: Record<Route, number>;
59
+ predicates: Record<string, number>;
60
+ confidence: number | null;
61
+ reason: SettleReason;
62
+ settledAt: string;
63
+ decidedAt: string;
64
+ eventCount: number;
65
+ eventIds: string[];
66
+ dropped: number;
67
+ gap: boolean;
68
+ waits: number;
69
+ /** `defaultNotice(decision)`. */
70
+ notice: string;
71
+ /** With `include: "events"` only, capped at 1 MiB; past the cap it is omitted and `_meta["attend/eventsOmitted"]` is set. */
72
+ events?: Entry[];
73
+ }
74
+ export interface AttentionDeadLetterData {
75
+ letterId: string;
76
+ scope: string;
77
+ stage: 'judge' | 'sink';
78
+ message: string;
79
+ permanent: boolean;
80
+ attempts: number;
81
+ decisionId: string | null;
82
+ route: DeliveredRoute | null;
83
+ reason: SettleReason;
84
+ eventCount: number;
85
+ eventIds: string[];
86
+ at: string;
87
+ }
88
+ /** `waitMs` (a long poll) is accepted, not advertised. */
89
+ export interface PollParams {
90
+ name: string;
91
+ arguments?: JsonObject;
92
+ cursor?: string | null;
93
+ maxAgeMs?: number;
94
+ maxEvents?: number;
95
+ waitMs?: number;
96
+ }
97
+ export interface PollResult extends CompleteResult {
98
+ events: EventOccurrence[];
99
+ cursor: string | null;
100
+ truncated: boolean;
101
+ hasMore: boolean;
102
+ nextPollMs: number;
103
+ }
104
+ export interface StreamParams {
105
+ name: string;
106
+ arguments?: JsonObject;
107
+ cursor?: string | null;
108
+ maxAgeMs?: number;
109
+ }
110
+ /** Carried on every `notifications/events/*` message: the parent `events/stream` request's JSON-RPC id. */
111
+ export interface SubscriptionMeta {
112
+ 'io.modelcontextprotocol/subscriptionId': string | number;
113
+ }
114
+ export interface EventsErrorObject {
115
+ code: number;
116
+ message: string;
117
+ data?: JsonObject;
118
+ }
119
+ /** `active` always comes first. Heartbeats come at least every 30 s. */
120
+ export type StreamNotification = {
121
+ method: 'notifications/events/active';
122
+ params: {
123
+ cursor: string | null;
124
+ truncated: boolean;
125
+ _meta: SubscriptionMeta;
126
+ };
127
+ } | {
128
+ method: 'notifications/events/event';
129
+ params: EventOccurrence & {
130
+ _meta: SubscriptionMeta & JsonObject;
131
+ };
132
+ } | {
133
+ method: 'notifications/events/heartbeat';
134
+ params: {
135
+ cursor: string | null;
136
+ _meta: SubscriptionMeta;
137
+ };
138
+ } | {
139
+ method: 'notifications/events/error';
140
+ params: {
141
+ error: EventsErrorObject;
142
+ _meta: SubscriptionMeta;
143
+ };
144
+ } | {
145
+ method: 'notifications/events/terminated';
146
+ params: {
147
+ error: EventsErrorObject;
148
+ _meta: SubscriptionMeta;
149
+ };
150
+ };
151
+ /** The final frame, sent only when the server closes the stream. */
152
+ export interface StreamEventsResult extends CompleteResult {
153
+ _meta: SubscriptionMeta;
154
+ }
155
+ /** `v1.<epoch>.<position>` cursors: opaque to clients, one sequence per store. */
156
+ export interface CursorParts {
157
+ epoch: string;
158
+ position: Position;
159
+ }
160
+ /** Compiled subscription arguments. Matching is O(1) once the fan-out index has found the candidate. */
161
+ export interface SubscriptionFilter {
162
+ name: AttendEventName;
163
+ scope?: string;
164
+ scopePrefix?: string;
165
+ routes: number;
166
+ minProbability: number;
167
+ stage?: 'judge' | 'sink';
168
+ include: 'notice' | 'events';
169
+ /** Granted prefixes a row's scope must start with one of: set when the principal holds several grants and the arguments name neither scope nor scopePrefix. */
170
+ grants?: readonly string[];
171
+ }
172
+ /** `scopes` are granted prefixes; `['']` grants every scope. */
173
+ export interface Principal {
174
+ id: string;
175
+ scopes: readonly string[];
176
+ }
177
+ export type PrincipalResolver = (req: IncomingMessage) => Promise<Principal | null> | Principal | null;
178
+ export interface EventsServerOptions {
179
+ name?: string;
180
+ version?: string;
181
+ /** stdio and InMemory transports use `localPrincipal`; HTTP uses `principal(req)`. */
182
+ principal?: PrincipalResolver;
183
+ localPrincipal?: Principal;
184
+ /** Default 15,000; a heartbeat must come at least every 30 s. */
185
+ heartbeatMs?: number;
186
+ /** Bytes of encoded frames one stream may buffer before it falls back to catch-up. Default 1 MiB. */
187
+ streamBufferBytes?: number;
188
+ /** A ResourceExhausted {limit: "streams"} quota per principal, not a concurrency cap. Default 256. */
189
+ maxStreamsPerPrincipal?: number;
190
+ poll?: {
191
+ defaultMaxEvents?: number;
192
+ maxEvents?: number;
193
+ nextPollMs?: number;
194
+ };
195
+ /** Registers `attend_wait` and `attend_window`. Default true. */
196
+ tools?: boolean;
197
+ payload?: {
198
+ maxEventsBytes?: number;
199
+ };
200
+ }
201
+ /** A JSON-RPC request as the MCP SDK hands it to `fallbackRequestHandler`. */
202
+ export interface McpRequestLike {
203
+ jsonrpc: '2.0';
204
+ id: string | number;
205
+ method: string;
206
+ params?: {
207
+ [key: string]: unknown;
208
+ };
209
+ }
210
+ /** The slice of the MCP SDK 2.x request context the handlers use. */
211
+ export interface McpRequestContextLike {
212
+ mcpReq: {
213
+ id: string | number;
214
+ signal: AbortSignal;
215
+ notify(notification: {
216
+ method: string;
217
+ params?: {
218
+ [key: string]: unknown;
219
+ };
220
+ }): Promise<void>;
221
+ };
222
+ }
223
+ /** The slice of an MCP SDK 2.x `Server` that `install` uses: capability registration before connect, and one zod-free fallback handler. */
224
+ export interface McpServerLike {
225
+ /** Registers a typed handler; `install` composes the app's `tools/list` and `tools/call` handlers with attend's tools through it. */
226
+ setRequestHandler(method: string, ...args: unknown[]): void;
227
+ registerCapabilities(capabilities: {
228
+ extensions?: Record<string, JsonObject>;
229
+ tools?: JsonObject;
230
+ }): void;
231
+ fallbackRequestHandler?(request: McpRequestLike, ctx: McpRequestContextLike): Promise<{
232
+ [key: string]: unknown;
233
+ }>;
234
+ }
235
+ /** A tool `inputSchema` as an MCP SDK 2.x `McpServer` takes it: a Standard Schema that also carries its JSON Schema. */
236
+ export interface McpToolSchemaLike {
237
+ readonly '~standard': {
238
+ readonly version: 1;
239
+ readonly vendor: string;
240
+ validate(value: unknown): {
241
+ value: unknown;
242
+ };
243
+ readonly jsonSchema: {
244
+ input(options: unknown): JsonObject;
245
+ output(options: unknown): JsonObject;
246
+ };
247
+ };
248
+ }
249
+ /** The slice of an MCP SDK 2.x `McpServer` that `install` uses: its tool registry, and its low-level `server` for events/*. */
250
+ export interface McpToolServerLike {
251
+ readonly server: McpServerLike;
252
+ registerTool(name: string, config: {
253
+ description: string;
254
+ inputSchema: McpToolSchemaLike;
255
+ }, callback: (args: unknown, ctx: McpRequestContextLike) => Promise<ToolResult>): unknown;
256
+ }
257
+ export type HttpRoute = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
258
+ export interface HttpHandlerOptions {
259
+ /** Default '/mcp'. */
260
+ path?: string;
261
+ /** Extra routes on the same port, such as 'POST /v1/ingest'. */
262
+ routes?: Record<string, HttpRoute>;
263
+ /** Defaults: 10,000 sessions, 1,800,000 ms idle. */
264
+ sessions?: {
265
+ max?: number;
266
+ idleMs?: number;
267
+ };
268
+ /** Builds the SDK Server or McpServer for a new session, for an app that wants its own tools on the same endpoint. `install` is applied to it. */
269
+ newServer?: () => (McpServerLike | McpToolServerLike) & {
270
+ connect(transport: unknown): Promise<void>;
271
+ };
272
+ }
273
+ export interface EventsServer {
274
+ readonly descriptors: readonly EventDescriptor[];
275
+ /** For `server/discover` and `initialize`. */
276
+ capabilities(): {
277
+ extensions: Record<string, JsonObject>;
278
+ };
279
+ /** Pass an McpServer to register attend's tools beside the app's; on a low-level Server, attend serves tools from its fallback and composes with tools/list and tools/call handlers set before or after install. Call before connect, after the app sets its own fallbackRequestHandler. */
280
+ install(server: McpServerLike | McpToolServerLike, options?: {
281
+ principal?: Principal;
282
+ }): void;
283
+ /**
284
+ * The Streamable HTTP endpoint. `events/stream` is served by attend's own SSE writer: drain on
285
+ * write() === false, abort on 'close', a setImmediate yield every 64 frames, catch-up instead of
286
+ * drop. A guard first checks session, MCP-Protocol-Version, Mcp-Method, Accept and the principal.
287
+ * Every other method goes to the SDK transport.
288
+ */
289
+ http(options: HttpHandlerOptions): HttpRoute;
290
+ close(): Promise<void>;
291
+ }
292
+ /** Server-internal: what every events/* handler reads, built once by `eventsServer`. */
293
+ export interface ServerContext {
294
+ readonly log: DecisionLog;
295
+ /** The log's epoch, read on first use and kept: it never changes for a store. */
296
+ epoch(): Promise<string>;
297
+ readonly options: EventsServerOptions;
298
+ readonly descriptors: readonly EventDescriptor[];
299
+ /** Aborts when `EventsServer.close()` runs: long polls answer at once, and P9's streams end with their final frame. */
300
+ readonly signal: AbortSignal;
301
+ /** The process's shared tail cache and fan-out index (design §6.9), built by `createFanout(log)` on first read of this property and closed by `EventsServer.close()`. Phase P9 implements it; poll and the tools never read it. */
302
+ readonly fanout: Fanout;
303
+ }
304
+ /** NDJSON lines. */
305
+ export type IngestLine = {
306
+ scope: string;
307
+ id: string;
308
+ at: number;
309
+ name: string;
310
+ data: JsonObject;
311
+ text?: string;
312
+ } | {
313
+ scope: string;
314
+ flush: true;
315
+ } | {
316
+ scope: string;
317
+ end: true;
318
+ };
319
+ export interface IngestResult {
320
+ accepted: number;
321
+ duplicates: number;
322
+ rejected: {
323
+ line: number;
324
+ scope: string | null;
325
+ error: 'invalid' | 'outbox_full' | 'backpressure' | 'too_large' | 'forbidden' | 'conflict' | 'internal';
326
+ }[];
327
+ }
328
+ export interface NdjsonIngestOptions {
329
+ /** True: a long-lived NDJSON body, answered with {ack, through} and {credit} lines. False: one request, one IngestResult. */
330
+ stream?: boolean;
331
+ maxBodyBytes?: number;
332
+ maxLineBytes?: number;
333
+ /** Lines are accepted only for scopes inside the principal's grants. */
334
+ principal?: PrincipalResolver;
335
+ /** Default 64 lines parsed per macrotask. */
336
+ slice?: number;
337
+ }
338
+ export interface ServeOptions {
339
+ listen: {
340
+ port: number;
341
+ host?: string;
342
+ } | {
343
+ path: string;
344
+ };
345
+ principal?: PrincipalResolver;
346
+ events?: Omit<EventsServerOptions, 'principal'>;
347
+ ingest?: {
348
+ stream?: boolean;
349
+ };
350
+ }
351
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export const EVENTS_EXTENSION = 'io.modelcontextprotocol/events';
2
+ export const SUBSCRIPTION_ID_META = 'io.modelcontextprotocol/subscriptionId';
3
+ export const DECISION_EVENT = 'attention.decision';
4
+ export const DEAD_LETTER_EVENT = 'attention.deadLetter';
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AACjE,MAAM,CAAC,MAAM,oBAAoB,GAAG,wCAAwC,CAAC;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `attend/server`: MCP Events over a store's decision log, with polling, streaming and
3
+ * Streamable HTTP, plus NDJSON ingestion and a combined server. A read-only process can
4
+ * serve decisions without running a judge.
5
+ */
6
+ export { eventsServer } from './server/install.js';
7
+ export { ndjsonIngest } from './server/ingest.js';
8
+ export { serve } from './server/serve.js';
9
+ export { DEAD_LETTER_EVENT, DECISION_EVENT, EVENTS_EXTENSION } from './server/types.js';
10
+ export type { AttentionDeadLetterData, AttentionDecisionData, DeadLetterArguments, DecisionArguments, EventOccurrence, EventsServer, EventsServerOptions, HttpHandlerOptions, HttpRoute, IngestLine, IngestResult, NdjsonIngestOptions, Principal, PrincipalResolver, ServeOptions } from './server/types.js';
11
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxF,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `attend/server`: MCP Events over a store's decision log, with polling, streaming and
3
+ * Streamable HTTP, plus NDJSON ingestion and a combined server. A read-only process can
4
+ * serve decisions without running a judge.
5
+ */
6
+ export { eventsServer } from './server/install.js';
7
+ export { ndjsonIngest } from './server/ingest.js';
8
+ export { serve } from './server/serve.js';
9
+ export { DEAD_LETTER_EVENT, DECISION_EVENT, EVENTS_EXTENSION } from './server/types.js';
10
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { JudgeBudget } from '../core/types.js';
2
+ /** (contextTokens − reservedTokens) × windowShare × bytesPerToken. */
3
+ export declare function windowBytesFor(budget: JudgeBudget, windowShare: number): number;
4
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/shell/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/E"}
@@ -0,0 +1,5 @@
1
+ /** (contextTokens − reservedTokens) × windowShare × bytesPerToken. */
2
+ export function windowBytesFor(budget, windowShare) {
3
+ return Math.floor((budget.contextTokens - (budget.reservedTokens ?? 0)) * windowShare * (budget.bytesPerToken ?? 4));
4
+ }
5
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/shell/budget.ts"],"names":[],"mappings":"AAEA,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,WAAmB;IACrE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC;AACvH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { DeadLetter, Decision, Event, Window } from '../core/types.js';
2
+ /** Copies and validates an event at the JSON boundary, and measures its rendered bytes. */
3
+ export declare function copyEventSized(event: Event, fill?: {
4
+ id(): string;
5
+ at(): number;
6
+ }): {
7
+ event: Event;
8
+ bytes: number;
9
+ };
10
+ /** Waits for active window copies when advancing a deterministic test clock. */
11
+ export declare function drainCopies(): Promise<void>;
12
+ /** Copies one slice synchronously and yields between any remaining slices. */
13
+ export declare function copyWindowSliced(window: Window, slice?: number): Window | Promise<Window>;
14
+ /** Copies a decision and slices the copy of its window. */
15
+ export declare function copyDecision(decision: Decision): Decision | Promise<Decision>;
16
+ /** Copies a dead letter and both windows it may contain. */
17
+ export declare function copyLetter(letter: DeadLetter): DeadLetter | Promise<DeadLetter>;
18
+ /** Estimates JSON bytes without serializing the record on the memory-store path. */
19
+ export declare function recordBytes(value: unknown): number;
20
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/shell/copy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI5E,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE;IAAE,EAAE,IAAI,MAAM,CAAC;IAAC,EAAE,IAAI,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAUnH;AAID,gFAAgF;AAChF,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjD;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrF;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAI7E;AAED,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAO/E;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOlD"}
@@ -0,0 +1,73 @@
1
+ import { copyEvent } from '../internal/shared.js';
2
+ import { estimateRenderedBytes } from '../core/window.js';
3
+ /** Copies and validates an event at the JSON boundary, and measures its rendered bytes. */
4
+ export function copyEventSized(event, fill) {
5
+ const copied = copyEvent(event, fill !== undefined);
6
+ if (fill) {
7
+ if (copied.id === undefined)
8
+ copied.id = fill.id();
9
+ if (copied.at === undefined)
10
+ copied.at = fill.at();
11
+ }
12
+ if (typeof copied.id !== 'string' || typeof copied.name !== 'string' || (copied.text !== undefined && typeof copied.text !== 'string')) {
13
+ throw new TypeError('attend: event id, name and text must be strings');
14
+ }
15
+ return { event: copied, bytes: estimateRenderedBytes(copied) };
16
+ }
17
+ const copying = new Set();
18
+ /** Waits for active window copies when advancing a deterministic test clock. */
19
+ export async function drainCopies() {
20
+ while (copying.size > 0)
21
+ await Promise.all(copying);
22
+ }
23
+ /** Copies one slice synchronously and yields between any remaining slices. */
24
+ export function copyWindowSliced(window, slice = 64) {
25
+ if (!Number.isSafeInteger(slice) || slice < 1)
26
+ throw new RangeError('attend: slice must be a positive integer');
27
+ const events = [];
28
+ let i = 0;
29
+ function copySlice() {
30
+ const end = Math.min(i + slice, window.events.length);
31
+ for (; i < end; i += 1)
32
+ events.push(structuredClone(window.events[i]));
33
+ if (i < window.events.length)
34
+ return new Promise((resolve) => setImmediate(resolve)).then(copySlice);
35
+ return { ...window, events };
36
+ }
37
+ const result = copySlice();
38
+ if (result instanceof Promise) {
39
+ copying.add(result);
40
+ void result.then(() => copying.delete(result), () => copying.delete(result));
41
+ }
42
+ return result;
43
+ }
44
+ /** Copies a decision and slices the copy of its window. */
45
+ export function copyDecision(decision) {
46
+ const copy = { ...decision, probabilities: { ...decision.probabilities }, predicates: { ...decision.predicates } };
47
+ const window = copyWindowSliced(decision.window);
48
+ return window instanceof Promise ? window.then((window) => ({ ...copy, window })) : { ...copy, window };
49
+ }
50
+ /** Copies a dead letter and both windows it may contain. */
51
+ export function copyLetter(letter) {
52
+ const window = copyWindowSliced(letter.window);
53
+ const decision = letter.decision === null ? null : copyDecision(letter.decision);
54
+ if (window instanceof Promise || decision instanceof Promise) {
55
+ return Promise.all([window, decision]).then(([window, decision]) => ({ ...letter, window, decision }));
56
+ }
57
+ return { ...letter, window, decision };
58
+ }
59
+ /** Estimates JSON bytes without serializing the record on the memory-store path. */
60
+ export function recordBytes(value) {
61
+ if (value === null)
62
+ return 4;
63
+ if (typeof value === 'string')
64
+ return Buffer.byteLength(value) + 2;
65
+ if (typeof value === 'number' || typeof value === 'boolean')
66
+ return String(value).length;
67
+ if (Array.isArray(value))
68
+ return 2 + value.reduce((sum, item) => sum + recordBytes(item) + 1, 0);
69
+ if (typeof value === 'object')
70
+ return 2 + Object.entries(value).reduce((sum, [key, item]) => sum + Buffer.byteLength(key) + 4 + recordBytes(item), 0);
71
+ return 0;
72
+ }
73
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/shell/copy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Clock } from '../core/types.js';
2
+ import type { DecisionLog } from '../store/types.js';
3
+ import type { DecisionCursorPage, DecisionFilter, DecisionReadOptions } from './types.js';
4
+ /** Streams copied decision rows, paging immediately while the log has more to scan. */
5
+ export declare function readDecisions(log: DecisionLog, clock: Clock, filter: DecisionFilter, options: DecisionReadOptions): AsyncIterable<DecisionCursorPage>;
6
+ //# sourceMappingURL=decisions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../src/shell/decisions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAY1F,uFAAuF;AACvF,wBAAuB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,mBAAmB,GAAG,aAAa,CAAC,kBAAkB,CAAC,CA0B5J"}