@zigil/agent-react 0.1.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.
@@ -0,0 +1,358 @@
1
+ // src/attention.tsx
2
+ import {
3
+ createContext,
4
+ createElement,
5
+ useContext
6
+ } from "react";
7
+ var MAX_SERIALIZED_BYTES = 4 * 1024;
8
+ var MAX_REQUIRED_FIELD_LENGTH = 128;
9
+ var MAX_SELECTIONS = 12;
10
+ var MAX_HISTORY = 40;
11
+ var MAX_FOCUSED_HISTORY = 8;
12
+ var MAX_HOVER_HISTORY = 2;
13
+ var ATTENTION_ACTIVITY_ACTIONS = [
14
+ "focus",
15
+ "select",
16
+ "navigate",
17
+ "edit",
18
+ "execute",
19
+ "approve",
20
+ "dismiss",
21
+ "hover"
22
+ ];
23
+ var AttentionContextReact = createContext(null);
24
+ function AttentionProvider({
25
+ children,
26
+ context
27
+ }) {
28
+ return createElement(
29
+ AttentionContextReact.Provider,
30
+ { value: context },
31
+ children
32
+ );
33
+ }
34
+ function useAttention() {
35
+ return useContext(AttentionContextReact);
36
+ }
37
+ function formatAttentionLabel(attention) {
38
+ const primary = attention?.selection?.label ?? attention?.selection?.id ?? attention?.workspace?.label ?? "this workspace";
39
+ const extraSelections = Math.max(0, (attention?.selections?.length ?? 0) - 1);
40
+ return extraSelections > 0 ? `${primary} +${extraSelections}` : primary;
41
+ }
42
+ var AttentionContextSchema = standardSchema(
43
+ (value) => {
44
+ const issues = validateAttentionContext(value);
45
+ return issues.length > 0 ? issues : value;
46
+ }
47
+ );
48
+ function serializeAttention(context, privacy = "focused") {
49
+ const normalized = normalizeAttention(context, privacy);
50
+ assertClosedAttention(normalized);
51
+ let serialized = JSON.stringify(normalized);
52
+ if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;
53
+ warnOversizedAttention();
54
+ while (normalized.history?.some((event) => event.action === "hover")) {
55
+ const hoverIndex = normalized.history.findIndex(
56
+ (event) => event.action === "hover"
57
+ );
58
+ normalized.history.splice(hoverIndex, 1);
59
+ if (normalized.history.length === 0) delete normalized.history;
60
+ serialized = JSON.stringify(normalized);
61
+ if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;
62
+ }
63
+ while ((normalized.history?.length ?? 0) > 0) {
64
+ normalized.history?.shift();
65
+ if (normalized.history?.length === 0) delete normalized.history;
66
+ serialized = JSON.stringify(normalized);
67
+ if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;
68
+ }
69
+ delete normalized.hover;
70
+ serialized = JSON.stringify(normalized);
71
+ if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;
72
+ removeOptionalSelectionFields(normalized);
73
+ serialized = JSON.stringify(normalized);
74
+ if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;
75
+ const required = truncateRequiredFields(normalized);
76
+ serialized = JSON.stringify(required);
77
+ while (byteLength(serialized) > MAX_SERIALIZED_BYTES && (required.selections?.length ?? 0) > 0) {
78
+ required.selections?.pop();
79
+ if (required.selections?.length === 0) delete required.selections;
80
+ serialized = JSON.stringify(required);
81
+ }
82
+ return serialized;
83
+ }
84
+ function validateAttentionContext(value, path = []) {
85
+ if (!isRecord(value)) return [issue("Expected attention context", ...path)];
86
+ const issues = [];
87
+ if (!hasOnlyKeys(value, [
88
+ "application",
89
+ "route",
90
+ "workspace",
91
+ "selection",
92
+ "selections",
93
+ "hover",
94
+ "history"
95
+ ]))
96
+ issues.push(issue("Unexpected attention field", ...path));
97
+ if (typeof value.application !== "string")
98
+ issues.push(issue("Expected a string", ...path, "application"));
99
+ if (typeof value.route !== "string")
100
+ issues.push(issue("Expected a string", ...path, "route"));
101
+ if (value.workspace !== void 0)
102
+ issues.push(...validateWorkspace(value.workspace, [...path, "workspace"]));
103
+ if (value.selection !== void 0)
104
+ issues.push(...validateSelection(value.selection, [...path, "selection"]));
105
+ if (value.hover !== void 0)
106
+ issues.push(...validateSelection(value.hover, [...path, "hover"]));
107
+ if (value.selections !== void 0) {
108
+ if (!Array.isArray(value.selections))
109
+ issues.push(issue("Expected selections", ...path, "selections"));
110
+ else
111
+ value.selections.forEach(
112
+ (selection, index) => issues.push(
113
+ ...validateSelection(selection, [...path, "selections", index])
114
+ )
115
+ );
116
+ }
117
+ if (value.history !== void 0) {
118
+ if (!Array.isArray(value.history))
119
+ issues.push(issue("Expected activity history", ...path, "history"));
120
+ else
121
+ value.history.forEach(
122
+ (event, index) => issues.push(...validateActivity(event, [...path, "history", index]))
123
+ );
124
+ }
125
+ return issues;
126
+ }
127
+ function normalizeAttention(context, privacy) {
128
+ const workspace = context.workspace ? {
129
+ kind: context.workspace.kind,
130
+ id: context.workspace.id,
131
+ ...context.workspace.revision === void 0 ? {} : { revision: context.workspace.revision },
132
+ ...privacy === "minimal" || context.workspace.label === void 0 ? {} : { label: context.workspace.label }
133
+ } : void 0;
134
+ const primary = context.selection ? normalizeSelection(context.selection, privacy !== "minimal") : void 0;
135
+ if (privacy === "minimal") {
136
+ return {
137
+ application: context.application,
138
+ route: context.route,
139
+ ...workspace ? { workspace } : {},
140
+ ...primary ? { selection: primary } : {}
141
+ };
142
+ }
143
+ const selections = normalizeSelections(context.selections, primary);
144
+ const history = normalizeHistory(
145
+ context.history,
146
+ privacy === "focused" ? MAX_FOCUSED_HISTORY : MAX_HISTORY,
147
+ privacy === "expanded"
148
+ );
149
+ return {
150
+ application: context.application,
151
+ route: context.route,
152
+ ...workspace ? { workspace } : {},
153
+ ...primary ? { selection: primary } : {},
154
+ ...selections.length > 0 ? { selections } : {},
155
+ ...privacy === "expanded" && context.hover ? { hover: normalizeSelection(context.hover, true) } : {},
156
+ ...history.length > 0 ? { history } : {}
157
+ };
158
+ }
159
+ function normalizeSelections(selections, primary) {
160
+ const ordered = primary ? [
161
+ primary,
162
+ ...(selections ?? []).map((item) => normalizeSelection(item, true))
163
+ ] : (selections ?? []).map((item) => normalizeSelection(item, true));
164
+ const seen = /* @__PURE__ */ new Set();
165
+ return ordered.filter((item) => {
166
+ const key = selectionKey(item);
167
+ if (seen.has(key)) return false;
168
+ seen.add(key);
169
+ return true;
170
+ }).slice(0, MAX_SELECTIONS);
171
+ }
172
+ function normalizeHistory(history, limit, includeHover) {
173
+ const semantic = [];
174
+ const hovers = [];
175
+ for (const event of history ?? []) {
176
+ const normalized = normalizeEvent(event);
177
+ if (normalized.action !== "hover") semantic.push(normalized);
178
+ else if (includeHover) {
179
+ const previous = hovers.at(-1);
180
+ if (previous && selectionKey(previous.target) === selectionKey(normalized.target))
181
+ hovers[hovers.length - 1] = normalized;
182
+ else hovers.push(normalized);
183
+ }
184
+ }
185
+ const retainedSemantic = semantic.slice(-limit);
186
+ const remaining = Math.max(0, limit - retainedSemantic.length);
187
+ const hoverLimit = Math.min(MAX_HOVER_HISTORY, remaining);
188
+ const retainedHover = hoverLimit > 0 ? hovers.slice(-hoverLimit) : [];
189
+ return [...retainedSemantic, ...retainedHover].sort(
190
+ (left, right) => left.timestamp - right.timestamp
191
+ );
192
+ }
193
+ function normalizeEvent(event) {
194
+ return {
195
+ action: event.action,
196
+ target: normalizeSelection(event.target, true),
197
+ timestamp: event.timestamp,
198
+ ...event.summary === void 0 ? {} : { summary: event.summary },
199
+ ...event.detail === void 0 ? {} : { detail: sortRecord(event.detail) }
200
+ };
201
+ }
202
+ function normalizeSelection(selection, includeOptional) {
203
+ return {
204
+ kind: selection.kind,
205
+ id: selection.id,
206
+ ...includeOptional && selection.label !== void 0 ? { label: selection.label } : {},
207
+ ...includeOptional && selection.detail !== void 0 ? { detail: sortRecord(selection.detail) } : {}
208
+ };
209
+ }
210
+ function removeOptionalSelectionFields(context) {
211
+ const selections = [
212
+ context.selection,
213
+ ...context.selections ?? [],
214
+ context.hover
215
+ ].filter((selection) => Boolean(selection));
216
+ for (const selection of selections.reverse()) {
217
+ for (const key of Object.keys(selection.detail ?? {}).reverse()) {
218
+ if (!selection.detail) break;
219
+ delete selection.detail[key];
220
+ if (Object.keys(selection.detail).length === 0) delete selection.detail;
221
+ }
222
+ delete selection.label;
223
+ }
224
+ if (context.workspace) delete context.workspace.label;
225
+ }
226
+ function truncateRequiredFields(context) {
227
+ return {
228
+ application: truncateText(context.application),
229
+ route: truncateText(context.route),
230
+ ...context.workspace ? {
231
+ workspace: {
232
+ kind: truncateText(context.workspace.kind),
233
+ id: truncateText(context.workspace.id),
234
+ ...context.workspace.revision === void 0 ? {} : { revision: context.workspace.revision }
235
+ }
236
+ } : {},
237
+ ...context.selection ? {
238
+ selection: {
239
+ kind: truncateText(context.selection.kind),
240
+ id: truncateText(context.selection.id)
241
+ }
242
+ } : {},
243
+ ...context.selections ? {
244
+ selections: context.selections.slice(0, MAX_SELECTIONS).map((item) => ({
245
+ kind: truncateText(item.kind),
246
+ id: truncateText(item.id)
247
+ }))
248
+ } : {}
249
+ };
250
+ }
251
+ function validateWorkspace(value, path) {
252
+ if (!isRecord(value)) return [issue("Expected a workspace", ...path)];
253
+ const issues = [];
254
+ if (!hasOnlyKeys(value, ["kind", "id", "label", "revision"]))
255
+ issues.push(issue("Unexpected workspace field", ...path));
256
+ for (const key of ["kind", "id"])
257
+ if (typeof value[key] !== "string")
258
+ issues.push(issue("Expected a string", ...path, key));
259
+ if (value.label !== void 0 && typeof value.label !== "string")
260
+ issues.push(issue("Expected a string", ...path, "label"));
261
+ if (value.revision !== void 0 && (typeof value.revision !== "number" || !Number.isFinite(value.revision)))
262
+ issues.push(issue("Expected a finite revision", ...path, "revision"));
263
+ return issues;
264
+ }
265
+ function validateSelection(value, path) {
266
+ if (!isRecord(value)) return [issue("Expected a selection", ...path)];
267
+ const issues = [];
268
+ if (!hasOnlyKeys(value, ["kind", "id", "label", "detail"]))
269
+ issues.push(issue("Unexpected selection field", ...path));
270
+ for (const key of ["kind", "id"])
271
+ if (typeof value[key] !== "string")
272
+ issues.push(issue("Expected a string", ...path, key));
273
+ if (value.label !== void 0 && typeof value.label !== "string")
274
+ issues.push(issue("Expected a string", ...path, "label"));
275
+ issues.push(...validateStringRecord(value.detail, [...path, "detail"]));
276
+ return issues;
277
+ }
278
+ function validateActivity(value, path) {
279
+ if (!isRecord(value)) return [issue("Expected activity", ...path)];
280
+ const issues = [];
281
+ if (!hasOnlyKeys(value, ["action", "target", "timestamp", "summary", "detail"]))
282
+ issues.push(issue("Unexpected activity field", ...path));
283
+ if (typeof value.action !== "string" || !ATTENTION_ACTIVITY_ACTIONS.includes(
284
+ value.action
285
+ ))
286
+ issues.push(issue("Expected an action", ...path, "action"));
287
+ if (typeof value.timestamp !== "number" || !Number.isFinite(value.timestamp))
288
+ issues.push(issue("Expected a finite timestamp", ...path, "timestamp"));
289
+ if (value.summary !== void 0 && typeof value.summary !== "string")
290
+ issues.push(issue("Expected a string", ...path, "summary"));
291
+ issues.push(...validateSelection(value.target, [...path, "target"]));
292
+ issues.push(...validateStringRecord(value.detail, [...path, "detail"]));
293
+ return issues;
294
+ }
295
+ function validateStringRecord(value, path) {
296
+ if (value === void 0) return [];
297
+ if (!isRecord(value) || !Object.values(value).every((item) => typeof item === "string"))
298
+ return [issue("Expected string details", ...path)];
299
+ return [];
300
+ }
301
+ function assertClosedAttention(value) {
302
+ const issues = validateAttentionContext(value);
303
+ if (issues.length > 0)
304
+ throw new Error(`Invalid attention serialization: ${issues[0]?.message}`);
305
+ }
306
+ function standardSchema(validate) {
307
+ return {
308
+ "~standard": {
309
+ version: 1,
310
+ vendor: "sigil-agent",
311
+ validate(value) {
312
+ const result = validate(value);
313
+ return Array.isArray(result) ? { issues: result } : { value: result };
314
+ }
315
+ }
316
+ };
317
+ }
318
+ function issue(message, ...path) {
319
+ return { message, path };
320
+ }
321
+ function isRecord(value) {
322
+ return typeof value === "object" && value !== null && !Array.isArray(value);
323
+ }
324
+ function hasOnlyKeys(value, allowed) {
325
+ const keys = new Set(allowed);
326
+ return Object.keys(value).every((key) => keys.has(key));
327
+ }
328
+ function sortRecord(record) {
329
+ return Object.fromEntries(
330
+ Object.entries(record).sort(([left], [right]) => left.localeCompare(right))
331
+ );
332
+ }
333
+ function selectionKey(selection) {
334
+ return `${selection.kind}\0${selection.id}`;
335
+ }
336
+ function truncateText(value) {
337
+ return value.length <= MAX_REQUIRED_FIELD_LENGTH ? value : `${value.slice(0, MAX_REQUIRED_FIELD_LENGTH - 1)}\u2026`;
338
+ }
339
+ function byteLength(value) {
340
+ return new TextEncoder().encode(value).byteLength;
341
+ }
342
+ function warnOversizedAttention() {
343
+ const isDevelopment = import.meta.env?.DEV === true;
344
+ if (isDevelopment)
345
+ console.warn(
346
+ "Agent attention exceeded 4 KB; optional context was removed before sending."
347
+ );
348
+ }
349
+ export {
350
+ ATTENTION_ACTIVITY_ACTIONS,
351
+ AttentionContextSchema,
352
+ AttentionProvider,
353
+ formatAttentionLabel,
354
+ serializeAttention,
355
+ useAttention,
356
+ validateAttentionContext
357
+ };
358
+ //# sourceMappingURL=attention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/attention.tsx"],"sourcesContent":["import {\n createContext,\n createElement,\n useContext,\n type ReactNode,\n} from \"react\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\nimport type { AttentionPrivacyLevel } from \"./context-privacy.js\";\n\nconst MAX_SERIALIZED_BYTES = 4 * 1024;\nconst MAX_REQUIRED_FIELD_LENGTH = 128;\nconst MAX_SELECTIONS = 12;\nconst MAX_HISTORY = 40;\nconst MAX_FOCUSED_HISTORY = 8;\nconst MAX_HOVER_HISTORY = 2;\n\nexport interface AttentionSelection {\n readonly kind: string;\n readonly id: string;\n readonly label?: string;\n readonly detail?: Readonly<Record<string, string>>;\n}\n\nexport const ATTENTION_ACTIVITY_ACTIONS = [\n \"focus\",\n \"select\",\n \"navigate\",\n \"edit\",\n \"execute\",\n \"approve\",\n \"dismiss\",\n \"hover\",\n] as const;\n\nexport type AttentionActivityAction =\n (typeof ATTENTION_ACTIVITY_ACTIONS)[number];\n\nexport interface AttentionActivityEvent {\n readonly action: AttentionActivityAction;\n readonly target: AttentionSelection;\n readonly timestamp: number;\n readonly summary?: string;\n readonly detail?: Readonly<Record<string, string>>;\n}\n\nexport interface AttentionContext {\n readonly application: string;\n readonly route: string;\n readonly workspace?: {\n readonly kind: string;\n readonly id: string;\n readonly label?: string;\n readonly revision?: number;\n };\n readonly selection?: AttentionSelection;\n readonly selections?: readonly AttentionSelection[];\n readonly hover?: AttentionSelection;\n readonly history?: readonly AttentionActivityEvent[];\n}\n\ntype MutableSelection = {\n kind: string;\n id: string;\n label?: string;\n detail?: Record<string, string>;\n};\n\ntype MutableActivity = {\n action: AttentionActivityAction;\n target: MutableSelection;\n timestamp: number;\n summary?: string;\n detail?: Record<string, string>;\n};\n\ntype MutableAttention = {\n application: string;\n route: string;\n workspace?: {\n kind: string;\n id: string;\n label?: string;\n revision?: number;\n };\n selection?: MutableSelection;\n selections?: MutableSelection[];\n hover?: MutableSelection;\n history?: MutableActivity[];\n};\n\nconst AttentionContextReact = createContext<AttentionContext | null>(null);\n\nexport function AttentionProvider({\n children,\n context,\n}: {\n readonly children: ReactNode;\n readonly context: AttentionContext;\n}) {\n return createElement(\n AttentionContextReact.Provider,\n { value: context },\n children,\n );\n}\n\nexport function useAttention(): AttentionContext | null {\n return useContext(AttentionContextReact);\n}\n\nexport function formatAttentionLabel(\n attention: AttentionContext | null,\n): string {\n const primary =\n attention?.selection?.label ??\n attention?.selection?.id ??\n attention?.workspace?.label ??\n \"this workspace\";\n const extraSelections = Math.max(0, (attention?.selections?.length ?? 0) - 1);\n return extraSelections > 0 ? `${primary} +${extraSelections}` : primary;\n}\n\nexport const AttentionContextSchema = standardSchema<AttentionContext>(\n (value) => {\n const issues = validateAttentionContext(value);\n return issues.length > 0 ? issues : (value as AttentionContext);\n },\n);\n\nexport function serializeAttention(\n context: AttentionContext,\n privacy: AttentionPrivacyLevel = \"focused\",\n): string {\n const normalized = normalizeAttention(context, privacy);\n assertClosedAttention(normalized);\n let serialized = JSON.stringify(normalized);\n if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;\n\n warnOversizedAttention();\n\n while (normalized.history?.some((event) => event.action === \"hover\")) {\n const hoverIndex = normalized.history.findIndex(\n (event) => event.action === \"hover\",\n );\n normalized.history.splice(hoverIndex, 1);\n if (normalized.history.length === 0) delete normalized.history;\n serialized = JSON.stringify(normalized);\n if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;\n }\n\n while ((normalized.history?.length ?? 0) > 0) {\n normalized.history?.shift();\n if (normalized.history?.length === 0) delete normalized.history;\n serialized = JSON.stringify(normalized);\n if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;\n }\n\n delete normalized.hover;\n serialized = JSON.stringify(normalized);\n if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;\n\n removeOptionalSelectionFields(normalized);\n serialized = JSON.stringify(normalized);\n if (byteLength(serialized) <= MAX_SERIALIZED_BYTES) return serialized;\n\n const required = truncateRequiredFields(normalized);\n serialized = JSON.stringify(required);\n while (\n byteLength(serialized) > MAX_SERIALIZED_BYTES &&\n (required.selections?.length ?? 0) > 0\n ) {\n required.selections?.pop();\n if (required.selections?.length === 0) delete required.selections;\n serialized = JSON.stringify(required);\n }\n return serialized;\n}\n\nexport function validateAttentionContext(\n value: unknown,\n path: readonly PropertyKey[] = [],\n): StandardSchemaV1.Issue[] {\n if (!isRecord(value)) return [issue(\"Expected attention context\", ...path)];\n const issues: StandardSchemaV1.Issue[] = [];\n if (\n !hasOnlyKeys(value, [\n \"application\",\n \"route\",\n \"workspace\",\n \"selection\",\n \"selections\",\n \"hover\",\n \"history\",\n ])\n )\n issues.push(issue(\"Unexpected attention field\", ...path));\n if (typeof value.application !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, \"application\"));\n if (typeof value.route !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, \"route\"));\n if (value.workspace !== undefined)\n issues.push(...validateWorkspace(value.workspace, [...path, \"workspace\"]));\n if (value.selection !== undefined)\n issues.push(...validateSelection(value.selection, [...path, \"selection\"]));\n if (value.hover !== undefined)\n issues.push(...validateSelection(value.hover, [...path, \"hover\"]));\n if (value.selections !== undefined) {\n if (!Array.isArray(value.selections))\n issues.push(issue(\"Expected selections\", ...path, \"selections\"));\n else\n value.selections.forEach((selection, index) =>\n issues.push(\n ...validateSelection(selection, [...path, \"selections\", index]),\n ),\n );\n }\n if (value.history !== undefined) {\n if (!Array.isArray(value.history))\n issues.push(issue(\"Expected activity history\", ...path, \"history\"));\n else\n value.history.forEach((event, index) =>\n issues.push(...validateActivity(event, [...path, \"history\", index])),\n );\n }\n return issues;\n}\n\nfunction normalizeAttention(\n context: AttentionContext,\n privacy: AttentionPrivacyLevel,\n): MutableAttention {\n const workspace = context.workspace\n ? {\n kind: context.workspace.kind,\n id: context.workspace.id,\n ...(context.workspace.revision === undefined\n ? {}\n : { revision: context.workspace.revision }),\n ...(privacy === \"minimal\" || context.workspace.label === undefined\n ? {}\n : { label: context.workspace.label }),\n }\n : undefined;\n const primary = context.selection\n ? normalizeSelection(context.selection, privacy !== \"minimal\")\n : undefined;\n\n if (privacy === \"minimal\") {\n return {\n application: context.application,\n route: context.route,\n ...(workspace ? { workspace } : {}),\n ...(primary ? { selection: primary } : {}),\n };\n }\n\n const selections = normalizeSelections(context.selections, primary);\n const history = normalizeHistory(\n context.history,\n privacy === \"focused\" ? MAX_FOCUSED_HISTORY : MAX_HISTORY,\n privacy === \"expanded\",\n );\n return {\n application: context.application,\n route: context.route,\n ...(workspace ? { workspace } : {}),\n ...(primary ? { selection: primary } : {}),\n ...(selections.length > 0 ? { selections } : {}),\n ...(privacy === \"expanded\" && context.hover\n ? { hover: normalizeSelection(context.hover, true) }\n : {}),\n ...(history.length > 0 ? { history } : {}),\n };\n}\n\nfunction normalizeSelections(\n selections: readonly AttentionSelection[] | undefined,\n primary: MutableSelection | undefined,\n): MutableSelection[] {\n const ordered = primary\n ? [\n primary,\n ...(selections ?? []).map((item) => normalizeSelection(item, true)),\n ]\n : (selections ?? []).map((item) => normalizeSelection(item, true));\n const seen = new Set<string>();\n return ordered\n .filter((item) => {\n const key = selectionKey(item);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .slice(0, MAX_SELECTIONS);\n}\n\nfunction normalizeHistory(\n history: readonly AttentionActivityEvent[] | undefined,\n limit: number,\n includeHover: boolean,\n): MutableActivity[] {\n const semantic: MutableActivity[] = [];\n const hovers: MutableActivity[] = [];\n for (const event of history ?? []) {\n const normalized = normalizeEvent(event);\n if (normalized.action !== \"hover\") semantic.push(normalized);\n else if (includeHover) {\n const previous = hovers.at(-1);\n if (\n previous &&\n selectionKey(previous.target) === selectionKey(normalized.target)\n )\n hovers[hovers.length - 1] = normalized;\n else hovers.push(normalized);\n }\n }\n const retainedSemantic = semantic.slice(-limit);\n const remaining = Math.max(0, limit - retainedSemantic.length);\n const hoverLimit = Math.min(MAX_HOVER_HISTORY, remaining);\n const retainedHover = hoverLimit > 0 ? hovers.slice(-hoverLimit) : [];\n return [...retainedSemantic, ...retainedHover].sort(\n (left, right) => left.timestamp - right.timestamp,\n );\n}\n\nfunction normalizeEvent(event: AttentionActivityEvent): MutableActivity {\n return {\n action: event.action,\n target: normalizeSelection(event.target, true),\n timestamp: event.timestamp,\n ...(event.summary === undefined ? {} : { summary: event.summary }),\n ...(event.detail === undefined ? {} : { detail: sortRecord(event.detail) }),\n };\n}\n\nfunction normalizeSelection(\n selection: AttentionSelection,\n includeOptional: boolean,\n): MutableSelection {\n return {\n kind: selection.kind,\n id: selection.id,\n ...(includeOptional && selection.label !== undefined\n ? { label: selection.label }\n : {}),\n ...(includeOptional && selection.detail !== undefined\n ? { detail: sortRecord(selection.detail) }\n : {}),\n };\n}\n\nfunction removeOptionalSelectionFields(context: MutableAttention): void {\n const selections = [\n context.selection,\n ...(context.selections ?? []),\n context.hover,\n ].filter((selection): selection is MutableSelection => Boolean(selection));\n for (const selection of selections.reverse()) {\n for (const key of Object.keys(selection.detail ?? {}).reverse()) {\n if (!selection.detail) break;\n delete selection.detail[key];\n if (Object.keys(selection.detail).length === 0) delete selection.detail;\n }\n delete selection.label;\n }\n if (context.workspace) delete context.workspace.label;\n}\n\nfunction truncateRequiredFields(context: MutableAttention): MutableAttention {\n return {\n application: truncateText(context.application),\n route: truncateText(context.route),\n ...(context.workspace\n ? {\n workspace: {\n kind: truncateText(context.workspace.kind),\n id: truncateText(context.workspace.id),\n ...(context.workspace.revision === undefined\n ? {}\n : { revision: context.workspace.revision }),\n },\n }\n : {}),\n ...(context.selection\n ? {\n selection: {\n kind: truncateText(context.selection.kind),\n id: truncateText(context.selection.id),\n },\n }\n : {}),\n ...(context.selections\n ? {\n selections: context.selections\n .slice(0, MAX_SELECTIONS)\n .map((item) => ({\n kind: truncateText(item.kind),\n id: truncateText(item.id),\n })),\n }\n : {}),\n };\n}\n\nfunction validateWorkspace(\n value: unknown,\n path: readonly PropertyKey[],\n): StandardSchemaV1.Issue[] {\n if (!isRecord(value)) return [issue(\"Expected a workspace\", ...path)];\n const issues: StandardSchemaV1.Issue[] = [];\n if (!hasOnlyKeys(value, [\"kind\", \"id\", \"label\", \"revision\"]))\n issues.push(issue(\"Unexpected workspace field\", ...path));\n for (const key of [\"kind\", \"id\"] as const)\n if (typeof value[key] !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, key));\n if (value.label !== undefined && typeof value.label !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, \"label\"));\n if (\n value.revision !== undefined &&\n (typeof value.revision !== \"number\" || !Number.isFinite(value.revision))\n )\n issues.push(issue(\"Expected a finite revision\", ...path, \"revision\"));\n return issues;\n}\n\nfunction validateSelection(\n value: unknown,\n path: readonly PropertyKey[],\n): StandardSchemaV1.Issue[] {\n if (!isRecord(value)) return [issue(\"Expected a selection\", ...path)];\n const issues: StandardSchemaV1.Issue[] = [];\n if (!hasOnlyKeys(value, [\"kind\", \"id\", \"label\", \"detail\"]))\n issues.push(issue(\"Unexpected selection field\", ...path));\n for (const key of [\"kind\", \"id\"] as const)\n if (typeof value[key] !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, key));\n if (value.label !== undefined && typeof value.label !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, \"label\"));\n issues.push(...validateStringRecord(value.detail, [...path, \"detail\"]));\n return issues;\n}\n\nfunction validateActivity(\n value: unknown,\n path: readonly PropertyKey[],\n): StandardSchemaV1.Issue[] {\n if (!isRecord(value)) return [issue(\"Expected activity\", ...path)];\n const issues: StandardSchemaV1.Issue[] = [];\n if (\n !hasOnlyKeys(value, [\"action\", \"target\", \"timestamp\", \"summary\", \"detail\"])\n )\n issues.push(issue(\"Unexpected activity field\", ...path));\n if (\n typeof value.action !== \"string\" ||\n !ATTENTION_ACTIVITY_ACTIONS.includes(\n value.action as AttentionActivityAction,\n )\n )\n issues.push(issue(\"Expected an action\", ...path, \"action\"));\n if (typeof value.timestamp !== \"number\" || !Number.isFinite(value.timestamp))\n issues.push(issue(\"Expected a finite timestamp\", ...path, \"timestamp\"));\n if (value.summary !== undefined && typeof value.summary !== \"string\")\n issues.push(issue(\"Expected a string\", ...path, \"summary\"));\n issues.push(...validateSelection(value.target, [...path, \"target\"]));\n issues.push(...validateStringRecord(value.detail, [...path, \"detail\"]));\n return issues;\n}\n\nfunction validateStringRecord(\n value: unknown,\n path: readonly PropertyKey[],\n): StandardSchemaV1.Issue[] {\n if (value === undefined) return [];\n if (\n !isRecord(value) ||\n !Object.values(value).every((item) => typeof item === \"string\")\n )\n return [issue(\"Expected string details\", ...path)];\n return [];\n}\n\nfunction assertClosedAttention(value: unknown): void {\n const issues = validateAttentionContext(value);\n if (issues.length > 0)\n throw new Error(`Invalid attention serialization: ${issues[0]?.message}`);\n}\n\nfunction standardSchema<T>(\n validate: (value: unknown) => T | readonly StandardSchemaV1.Issue[],\n): StandardSchemaV1<unknown, T> {\n return {\n \"~standard\": {\n version: 1,\n vendor: \"sigil-agent\",\n validate(value) {\n const result = validate(value);\n return Array.isArray(result)\n ? { issues: result }\n : { value: result as T };\n },\n },\n };\n}\n\nfunction issue(\n message: string,\n ...path: PropertyKey[]\n): StandardSchemaV1.Issue {\n return { message, path };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(\n value: Record<string, unknown>,\n allowed: readonly string[],\n): boolean {\n const keys = new Set(allowed);\n return Object.keys(value).every((key) => keys.has(key));\n}\n\nfunction sortRecord(\n record: Readonly<Record<string, string>>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(record).sort(([left], [right]) => left.localeCompare(right)),\n );\n}\n\nfunction selectionKey(\n selection: Pick<AttentionSelection, \"kind\" | \"id\">,\n): string {\n return `${selection.kind}\\u0000${selection.id}`;\n}\n\nfunction truncateText(value: string): string {\n return value.length <= MAX_REQUIRED_FIELD_LENGTH\n ? value\n : `${value.slice(0, MAX_REQUIRED_FIELD_LENGTH - 1)}…`;\n}\n\nfunction byteLength(value: string): number {\n return new TextEncoder().encode(value).byteLength;\n}\n\nfunction warnOversizedAttention(): void {\n const isDevelopment =\n (import.meta as ImportMeta & { env?: { DEV?: boolean } }).env?.DEV === true;\n if (isDevelopment)\n console.warn(\n \"Agent attention exceeded 4 KB; optional context was removed before sending.\",\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,68 @@
1
+ import { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import { AttentionActivityEvent, AttentionSelection, AttentionContext } from './attention.js';
3
+ import { AttentionPrivacyLevel } from './context-privacy.js';
4
+ import 'react';
5
+
6
+ type ContextRetention = "turn" | "session";
7
+ type ContextAttachmentSource = "application-selection" | "semantic-fork" | "agent-requested";
8
+ type ContextAttachmentInclusion = "user-added" | "automatic" | "agent-requested";
9
+ interface TurnContextAttachment {
10
+ readonly id: string;
11
+ readonly source: ContextAttachmentSource;
12
+ readonly inclusion: ContextAttachmentInclusion;
13
+ readonly resource: {
14
+ readonly kind: string;
15
+ readonly id: string;
16
+ };
17
+ readonly label: string;
18
+ readonly summary?: string;
19
+ readonly retention: ContextRetention;
20
+ }
21
+ interface AttentionContextPreview {
22
+ readonly attachmentCount: number;
23
+ readonly attachments: readonly TurnContextAttachment[];
24
+ readonly byteLength: number;
25
+ readonly estimatedTokens: number;
26
+ readonly formatted: string;
27
+ readonly history: readonly AttentionActivityEvent[];
28
+ readonly selectionCount: number;
29
+ readonly selections: readonly AttentionSelection[];
30
+ readonly serialized: string;
31
+ readonly summary: string;
32
+ readonly truncatedAttachmentCount: number;
33
+ }
34
+ interface ContextDraftPayload {
35
+ readonly application?: string;
36
+ readonly route?: string;
37
+ readonly workspace?: AttentionContext["workspace"];
38
+ readonly selection?: AttentionContext["selection"];
39
+ readonly selections?: AttentionContext["selections"];
40
+ readonly hover?: AttentionContext["hover"];
41
+ readonly history?: AttentionContext["history"];
42
+ readonly attachments?: readonly TurnContextAttachment[];
43
+ }
44
+ declare const ContextAttachmentSchema: StandardSchemaV1<unknown, TurnContextAttachment>;
45
+ declare const ContextDraftPayloadSchema: StandardSchemaV1<unknown, ContextDraftPayload>;
46
+ declare function attentionSelectionKey(selection: AttentionSelection): string;
47
+ declare function attentionHistoryKey(event: AttentionActivityEvent): string;
48
+ declare function getContextDraftScope(): string;
49
+ declare function getAttentionExclusions(): readonly string[];
50
+ declare function getTurnContextAttachments(): readonly TurnContextAttachment[];
51
+ declare function setContextDraftScope(scopeId: string): void;
52
+ declare function addContextAttachment(attachment: TurnContextAttachment): void;
53
+ declare function addTurnContextAttachment(selection: AttentionSelection, retention?: ContextRetention): void;
54
+ declare function removeTurnContextAttachment(id: string): void;
55
+ declare function moveTurnContextAttachment(id: string, direction: -1 | 1): void;
56
+ declare function setTurnContextAttachmentRetention(id: string, retention: ContextRetention): void;
57
+ declare function clearTurnContextAttachments(): void;
58
+ declare function clearContextDraft(): void;
59
+ declare function resetContextDraftForTests(): void;
60
+ declare function setAttentionItemExcluded(key: string, excluded: boolean): void;
61
+ declare function clearAttentionExclusions(): void;
62
+ declare function useAttentionExclusions(): readonly string[];
63
+ declare function useTurnContextAttachments(): readonly TurnContextAttachment[];
64
+ declare function serializeAttentionDraft(context: AttentionContext | null, privacy: AttentionPrivacyLevel, excludedKeys?: readonly string[], contextAttachments?: readonly TurnContextAttachment[]): string;
65
+ declare function createAttentionContextPreview(context: AttentionContext | null, privacy: AttentionPrivacyLevel, excludedKeys?: readonly string[], contextAttachments?: readonly TurnContextAttachment[]): AttentionContextPreview;
66
+ declare function applyAttentionExclusions(context: AttentionContext, excludedKeys: readonly string[]): AttentionContext;
67
+
68
+ export { type AttentionContextPreview, type ContextAttachmentInclusion, ContextAttachmentSchema, type ContextAttachmentSource, type ContextDraftPayload, ContextDraftPayloadSchema, type ContextRetention, type TurnContextAttachment, addContextAttachment, addTurnContextAttachment, applyAttentionExclusions, attentionHistoryKey, attentionSelectionKey, clearAttentionExclusions, clearContextDraft, clearTurnContextAttachments, createAttentionContextPreview, getAttentionExclusions, getContextDraftScope, getTurnContextAttachments, moveTurnContextAttachment, removeTurnContextAttachment, resetContextDraftForTests, serializeAttentionDraft, setAttentionItemExcluded, setContextDraftScope, setTurnContextAttachmentRetention, useAttentionExclusions, useTurnContextAttachments };