@ouispec/agent-worker 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.
Files changed (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/dist/approvals/client.d.ts +29 -0
  4. package/dist/approvals/client.d.ts.map +1 -0
  5. package/dist/approvals/client.js +50 -0
  6. package/dist/approvals/client.js.map +1 -0
  7. package/dist/approvals/continuation.d.ts +28 -0
  8. package/dist/approvals/continuation.d.ts.map +1 -0
  9. package/dist/approvals/continuation.js +43 -0
  10. package/dist/approvals/continuation.js.map +1 -0
  11. package/dist/approvals/preview.d.ts +15 -0
  12. package/dist/approvals/preview.d.ts.map +1 -0
  13. package/dist/approvals/preview.js +33 -0
  14. package/dist/approvals/preview.js.map +1 -0
  15. package/dist/approvals/requirement.d.ts +15 -0
  16. package/dist/approvals/requirement.d.ts.map +1 -0
  17. package/dist/approvals/requirement.js +26 -0
  18. package/dist/approvals/requirement.js.map +1 -0
  19. package/dist/authz/tool-policy.d.ts +63 -0
  20. package/dist/authz/tool-policy.d.ts.map +1 -0
  21. package/dist/authz/tool-policy.js +23 -0
  22. package/dist/authz/tool-policy.js.map +1 -0
  23. package/dist/container/server.d.ts +24 -0
  24. package/dist/container/server.d.ts.map +1 -0
  25. package/dist/container/server.js +119 -0
  26. package/dist/container/server.js.map +1 -0
  27. package/dist/emit/http-adapter.d.ts +15 -0
  28. package/dist/emit/http-adapter.d.ts.map +1 -0
  29. package/dist/emit/http-adapter.js +35 -0
  30. package/dist/emit/http-adapter.js.map +1 -0
  31. package/dist/emit/types.d.ts +9 -0
  32. package/dist/emit/types.d.ts.map +1 -0
  33. package/dist/emit/types.js +7 -0
  34. package/dist/emit/types.js.map +1 -0
  35. package/dist/events/http-waiter.d.ts +19 -0
  36. package/dist/events/http-waiter.d.ts.map +1 -0
  37. package/dist/events/http-waiter.js +20 -0
  38. package/dist/events/http-waiter.js.map +1 -0
  39. package/dist/index.d.ts +60 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +45 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/lambda/handler.d.ts +38 -0
  44. package/dist/lambda/handler.d.ts.map +1 -0
  45. package/dist/lambda/handler.js +26 -0
  46. package/dist/lambda/handler.js.map +1 -0
  47. package/dist/model.d.ts +33 -0
  48. package/dist/model.d.ts.map +1 -0
  49. package/dist/model.js +15 -0
  50. package/dist/model.js.map +1 -0
  51. package/dist/openapi/document.d.ts +87 -0
  52. package/dist/openapi/document.d.ts.map +1 -0
  53. package/dist/openapi/document.js +117 -0
  54. package/dist/openapi/document.js.map +1 -0
  55. package/dist/openapi/executor.d.ts +51 -0
  56. package/dist/openapi/executor.d.ts.map +1 -0
  57. package/dist/openapi/executor.js +140 -0
  58. package/dist/openapi/executor.js.map +1 -0
  59. package/dist/openapi/index.d.ts +14 -0
  60. package/dist/openapi/index.d.ts.map +1 -0
  61. package/dist/openapi/index.js +9 -0
  62. package/dist/openapi/index.js.map +1 -0
  63. package/dist/openapi/loader.d.ts +81 -0
  64. package/dist/openapi/loader.d.ts.map +1 -0
  65. package/dist/openapi/loader.js +361 -0
  66. package/dist/openapi/loader.js.map +1 -0
  67. package/dist/openapi/x-agent.d.ts +34 -0
  68. package/dist/openapi/x-agent.d.ts.map +1 -0
  69. package/dist/openapi/x-agent.js +102 -0
  70. package/dist/openapi/x-agent.js.map +1 -0
  71. package/dist/orchestrator.d.ts +12 -0
  72. package/dist/orchestrator.d.ts.map +1 -0
  73. package/dist/orchestrator.js +1019 -0
  74. package/dist/orchestrator.js.map +1 -0
  75. package/dist/prompt/builder.d.ts +29 -0
  76. package/dist/prompt/builder.d.ts.map +1 -0
  77. package/dist/prompt/builder.js +129 -0
  78. package/dist/prompt/builder.js.map +1 -0
  79. package/dist/prompt/index.d.ts +15 -0
  80. package/dist/prompt/index.d.ts.map +1 -0
  81. package/dist/prompt/index.js +13 -0
  82. package/dist/prompt/index.js.map +1 -0
  83. package/dist/prompt/rules/base.d.ts +6 -0
  84. package/dist/prompt/rules/base.d.ts.map +1 -0
  85. package/dist/prompt/rules/base.js +38 -0
  86. package/dist/prompt/rules/base.js.map +1 -0
  87. package/dist/prompt/rules/communication.d.ts +7 -0
  88. package/dist/prompt/rules/communication.d.ts.map +1 -0
  89. package/dist/prompt/rules/communication.js +53 -0
  90. package/dist/prompt/rules/communication.js.map +1 -0
  91. package/dist/prompt/rules/tool-strategy.d.ts +6 -0
  92. package/dist/prompt/rules/tool-strategy.d.ts.map +1 -0
  93. package/dist/prompt/rules/tool-strategy.js +42 -0
  94. package/dist/prompt/rules/tool-strategy.js.map +1 -0
  95. package/dist/prompt/rules/ui-control.d.ts +10 -0
  96. package/dist/prompt/rules/ui-control.d.ts.map +1 -0
  97. package/dist/prompt/rules/ui-control.js +44 -0
  98. package/dist/prompt/rules/ui-control.js.map +1 -0
  99. package/dist/prompt/types.d.ts +85 -0
  100. package/dist/prompt/types.d.ts.map +1 -0
  101. package/dist/prompt/types.js +10 -0
  102. package/dist/prompt/types.js.map +1 -0
  103. package/dist/realtime/long-poll.d.ts +21 -0
  104. package/dist/realtime/long-poll.d.ts.map +1 -0
  105. package/dist/realtime/long-poll.js +36 -0
  106. package/dist/realtime/long-poll.js.map +1 -0
  107. package/dist/runtime/config.d.ts +4 -0
  108. package/dist/runtime/config.d.ts.map +1 -0
  109. package/dist/runtime/config.js +29 -0
  110. package/dist/runtime/config.js.map +1 -0
  111. package/dist/runtime/turn-runner.d.ts +32 -0
  112. package/dist/runtime/turn-runner.d.ts.map +1 -0
  113. package/dist/runtime/turn-runner.js +216 -0
  114. package/dist/runtime/turn-runner.js.map +1 -0
  115. package/dist/runtime/types.d.ts +244 -0
  116. package/dist/runtime/types.d.ts.map +1 -0
  117. package/dist/runtime/types.js +2 -0
  118. package/dist/runtime/types.js.map +1 -0
  119. package/dist/testing/desk-events.d.ts +12 -0
  120. package/dist/testing/desk-events.d.ts.map +1 -0
  121. package/dist/testing/desk-events.js +62 -0
  122. package/dist/testing/desk-events.js.map +1 -0
  123. package/dist/testing/index.d.ts +8 -0
  124. package/dist/testing/index.d.ts.map +1 -0
  125. package/dist/testing/index.js +7 -0
  126. package/dist/testing/index.js.map +1 -0
  127. package/dist/testing/openapi-fixture.d.ts +47 -0
  128. package/dist/testing/openapi-fixture.d.ts.map +1 -0
  129. package/dist/testing/openapi-fixture.js +370 -0
  130. package/dist/testing/openapi-fixture.js.map +1 -0
  131. package/dist/tools/async-binding.d.ts +71 -0
  132. package/dist/tools/async-binding.d.ts.map +1 -0
  133. package/dist/tools/async-binding.js +104 -0
  134. package/dist/tools/async-binding.js.map +1 -0
  135. package/dist/tools/builtin-tools.d.ts +20 -0
  136. package/dist/tools/builtin-tools.d.ts.map +1 -0
  137. package/dist/tools/builtin-tools.js +108 -0
  138. package/dist/tools/builtin-tools.js.map +1 -0
  139. package/dist/tools/entity-tools.d.ts +6 -0
  140. package/dist/tools/entity-tools.d.ts.map +1 -0
  141. package/dist/tools/entity-tools.js +227 -0
  142. package/dist/tools/entity-tools.js.map +1 -0
  143. package/dist/tools/input-validation.d.ts +16 -0
  144. package/dist/tools/input-validation.d.ts.map +1 -0
  145. package/dist/tools/input-validation.js +75 -0
  146. package/dist/tools/input-validation.js.map +1 -0
  147. package/dist/tools/load-all-tools.d.ts +12 -0
  148. package/dist/tools/load-all-tools.d.ts.map +1 -0
  149. package/dist/tools/load-all-tools.js +42 -0
  150. package/dist/tools/load-all-tools.js.map +1 -0
  151. package/dist/tools/schema-loader.d.ts +24 -0
  152. package/dist/tools/schema-loader.d.ts.map +1 -0
  153. package/dist/tools/schema-loader.js +267 -0
  154. package/dist/tools/schema-loader.js.map +1 -0
  155. package/dist/tools/types.d.ts +85 -0
  156. package/dist/tools/types.d.ts.map +1 -0
  157. package/dist/tools/types.js +22 -0
  158. package/dist/tools/types.js.map +1 -0
  159. package/dist/turn-policy.d.ts +68 -0
  160. package/dist/turn-policy.d.ts.map +1 -0
  161. package/dist/turn-policy.js +21 -0
  162. package/dist/turn-policy.js.map +1 -0
  163. package/dist/types.d.ts +151 -0
  164. package/dist/types.d.ts.map +1 -0
  165. package/dist/types.js +2 -0
  166. package/dist/types.js.map +1 -0
  167. package/dist/ui/channel.d.ts +64 -0
  168. package/dist/ui/channel.d.ts.map +1 -0
  169. package/dist/ui/channel.js +81 -0
  170. package/dist/ui/channel.js.map +1 -0
  171. package/dist/ui/knowledge.d.ts +30 -0
  172. package/dist/ui/knowledge.d.ts.map +1 -0
  173. package/dist/ui/knowledge.js +66 -0
  174. package/dist/ui/knowledge.js.map +1 -0
  175. package/dist/ui/observations.d.ts +41 -0
  176. package/dist/ui/observations.d.ts.map +1 -0
  177. package/dist/ui/observations.js +236 -0
  178. package/dist/ui/observations.js.map +1 -0
  179. package/dist/ui/snapshot.d.ts +33 -0
  180. package/dist/ui/snapshot.d.ts.map +1 -0
  181. package/dist/ui/snapshot.js +75 -0
  182. package/dist/ui/snapshot.js.map +1 -0
  183. package/dist/ui/ui-sequence.d.ts +75 -0
  184. package/dist/ui/ui-sequence.d.ts.map +1 -0
  185. package/dist/ui/ui-sequence.js +73 -0
  186. package/dist/ui/ui-sequence.js.map +1 -0
  187. package/dist/ui/ui-tools.d.ts +59 -0
  188. package/dist/ui/ui-tools.d.ts.map +1 -0
  189. package/dist/ui/ui-tools.js +244 -0
  190. package/dist/ui/ui-tools.js.map +1 -0
  191. package/package.json +78 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Page state within the model's budget, problems first (ADR-0167).
3
+ *
4
+ * A surface may publish a `problems` observation: what its page cannot draw,
5
+ * load or read — a face it does not have and the text it therefore hides, an
6
+ * asset that failed, what an import could not reproduce. Those are exactly
7
+ * what the model must not miss before it tells the user a result, so when the
8
+ * page state is over budget they are kept whole and only the rest is cut. So
9
+ * are the statuses of the jobs the page follows: whether what an action
10
+ * started has finished is how the model knows it may say so.
11
+ */
12
+ /** The observation id a surface reports its page's problems under. */
13
+ export const PROBLEMS_OBSERVATION_ID = 'problems';
14
+ /** Every surface's non-empty `problems`, by surface id; null when none reports any. */
15
+ export function surfaceProblems(observations) {
16
+ const found = {};
17
+ for (const [surface, values] of Object.entries(observations)) {
18
+ const problems = values?.[PROBLEMS_OBSERVATION_ID];
19
+ if (Array.isArray(problems) ? problems.length > 0 : problems !== undefined && problems !== null) {
20
+ found[surface] = problems;
21
+ }
22
+ }
23
+ return Object.keys(found).length > 0 ? found : null;
24
+ }
25
+ /**
26
+ * Every job an action started that the page is following: each surface's
27
+ * `<surface>:<action>:status` observations (started, running, complete with
28
+ * what it made, failed with why), by surface id; null when there are none.
29
+ * The model is told an action like Generate is done only through these, so
30
+ * they must reach it whatever else the page reports.
31
+ */
32
+ export function jobStatuses(observations) {
33
+ const found = {};
34
+ for (const [surface, values] of Object.entries(observations)) {
35
+ for (const [id, value] of Object.entries(values ?? {})) {
36
+ if (!isJobStatus(id))
37
+ continue;
38
+ (found[surface] ??= {})[id] = value;
39
+ }
40
+ }
41
+ return Object.keys(found).length > 0 ? found : null;
42
+ }
43
+ const isJobStatus = (observationId) => observationId.endsWith(':status');
44
+ /** The observations without what is reported whole beside them: problems and job statuses. */
45
+ function withoutKeptWhole(observations) {
46
+ return Object.fromEntries(Object.entries(observations).map(([surface, values]) => [
47
+ surface,
48
+ Object.fromEntries(Object.entries(values ?? {}).filter(([id]) => id !== PROBLEMS_OBSERVATION_ID && !isJobStatus(id))),
49
+ ]));
50
+ }
51
+ /** Rows past this in any list are summed up as "… and N more" at the first step of fitting an over-budget page state. */
52
+ export const MAX_LIST_ROWS = 20;
53
+ /**
54
+ * A list this short is never shortened: it is a field's choices (the engines a
55
+ * voice can speak with, a document's types), not a collection to browse.
56
+ */
57
+ export const WHOLE_LIST_ROWS = 5;
58
+ /** How far long lists are shortened, step by step; 0 gives only how many rows there are. */
59
+ const LIST_STEPS = [MAX_LIST_ROWS, 10, WHOLE_LIST_ROWS, 0];
60
+ /**
61
+ * What a page state reports that is never shortened: its fields, what is
62
+ * unavailable or busy, and a row's own schema (its options or range).
63
+ */
64
+ const FIELD_KEYS = new Set(['values', 'unavailable', 'busy', 'schema']);
65
+ /**
66
+ * Where a surface comes in the page state over budget: the surface the action
67
+ * acted on, then the pages and rooms, then shared parts of them, then anything
68
+ * else, and the shells (the chrome around every page: accounts, projects,
69
+ * navigation) last. A long project list in the shell must never crowd out the
70
+ * page the model is working on.
71
+ */
72
+ function surfaceRank(surfaceId, acting) {
73
+ if (acting !== undefined && surfaceId === acting)
74
+ return 0;
75
+ if (surfaceId.startsWith('page:') || surfaceId.startsWith('room:'))
76
+ return 1;
77
+ if (surfaceId.startsWith('shared:'))
78
+ return 2;
79
+ if (surfaceId.startsWith('shell:') || surfaceId === 'app-shell')
80
+ return 4;
81
+ return 3;
82
+ }
83
+ /** A row the person has chosen (a selected card, the variant in use): kept however short its list gets. */
84
+ const isChosen = (row) => row !== null && typeof row === 'object' && row.value === true;
85
+ /** A list shortened to `limit` rows plus the chosen ones and how many more; only a count at 0. */
86
+ function shortenRows(rows, limit) {
87
+ if (rows.length <= Math.max(limit, WHOLE_LIST_ROWS))
88
+ return rows;
89
+ if (limit === 0) {
90
+ const chosen = rows.filter(isChosen);
91
+ const count = `${rows.length - chosen.length}${chosen.length ? ' more' : ''} rows`;
92
+ return [...chosen, `${count}, not listed to fit the page state; name a row by its title`];
93
+ }
94
+ const kept = rows.slice(0, limit);
95
+ const chosen = rows.slice(limit).filter(isChosen);
96
+ return [...kept, ...chosen, `… and ${rows.length - kept.length - chosen.length} more`];
97
+ }
98
+ /**
99
+ * What the page shows (`shown`): facts that describe one row of a list (one per
100
+ * card) are shortened like the list; the page's own facts, such as those of the
101
+ * item open in a detail panel, are kept whole.
102
+ */
103
+ function shortenShown(shown, limit) {
104
+ const perList = new Map();
105
+ const own = [];
106
+ for (const entry of shown) {
107
+ const item = entry?.item;
108
+ if (item === undefined)
109
+ own.push(entry);
110
+ else {
111
+ const id = String(entry.id);
112
+ perList.set(id, [...(perList.get(id) ?? []), entry]);
113
+ }
114
+ }
115
+ return [...own, ...[...perList.values()].flatMap((rows) => shortenRows(rows, limit))];
116
+ }
117
+ /**
118
+ * The value with every long list shortened to `limit` (see shortenRows); fields,
119
+ * what is unavailable or busy, and the page's own facts are left whole.
120
+ */
121
+ function compactValue(value, limit) {
122
+ if (Array.isArray(value)) {
123
+ const rows = value.map((v) => compactValue(v, limit));
124
+ return shortenRows(rows, limit);
125
+ }
126
+ if (value !== null && typeof value === 'object') {
127
+ return Object.fromEntries(Object.entries(value).map(([key, v]) => {
128
+ if (FIELD_KEYS.has(key))
129
+ return [key, v];
130
+ if (key === 'shown' && Array.isArray(v))
131
+ return [key, shortenShown(v, limit)];
132
+ return [key, compactValue(v, limit)];
133
+ }));
134
+ }
135
+ return value;
136
+ }
137
+ const size = (value) => JSON.stringify(value).length;
138
+ /**
139
+ * The page state over budget, fitted step by step, cutting the least important
140
+ * first. The surfaces are ordered by rank. Then long lists are shortened (20
141
+ * rows, 10, 5, then only a count), on every other surface a step before the
142
+ * surface the action acted on. Lists of five rows or fewer, every field, what is
143
+ * unavailable or busy, the page's own facts and chosen rows are never shortened,
144
+ * so the item open in a detail panel stays whole beside a long list. Then whole
145
+ * surfaces are left out, the shells first, never the acting one. Only if that
146
+ * still does not fit is the rest cut.
147
+ */
148
+ function fitted(observations, maxChars, acting) {
149
+ const base = Object.fromEntries(Object.entries(withoutKeptWhole(observations)).sort(([a], [b]) => surfaceRank(a, acting) - surfaceRank(b, acting)));
150
+ const actingPresent = acting !== undefined && acting in base;
151
+ // Each step is (others' limit, the acting surface's limit): the acting one lags a step behind.
152
+ const steps = [];
153
+ LIST_STEPS.forEach((limit, i) => {
154
+ if (actingPresent && i > 0)
155
+ steps.push([limit, LIST_STEPS[i - 1]]);
156
+ steps.push([limit, limit]);
157
+ });
158
+ let values = base;
159
+ let listStep;
160
+ for (const [others, own] of steps) {
161
+ values = Object.fromEntries(Object.entries(base).map(([id, v]) => [id, compactValue(v, id === acting ? own : others)]));
162
+ listStep = others;
163
+ if (size(values) <= maxChars)
164
+ return { values, listStep, omitted: [], fits: true };
165
+ }
166
+ const omitted = [];
167
+ const droppable = Object.keys(values)
168
+ .filter((id) => id !== acting)
169
+ .sort((a, b) => surfaceRank(b, acting) - surfaceRank(a, acting) || size(values[b]) - size(values[a]));
170
+ for (const id of droppable) {
171
+ if (Object.keys(values).length <= 1)
172
+ break;
173
+ values = Object.fromEntries(Object.entries(values).filter(([key]) => key !== id));
174
+ omitted.push(id);
175
+ if (size(values) <= maxChars)
176
+ return { values, listStep, omitted, fits: true };
177
+ }
178
+ return { values, listStep, omitted, fits: false };
179
+ }
180
+ /** What fitting did, in words. */
181
+ function fitSummary(fit, maxChars, whole, acted) {
182
+ const lists = fit.listStep === undefined
183
+ ? ''
184
+ : fit.listStep === 0
185
+ ? `lists longer than ${WHOLE_LIST_ROWS} rows are given as a count`
186
+ : `long lists are shortened, to as few as ${Math.max(fit.listStep, WHOLE_LIST_ROWS)} rows, with how many more`;
187
+ const parts = [
188
+ lists,
189
+ 'fields, the page’s own facts and chosen rows are kept whole',
190
+ acted ? 'the page you acted on comes first' : 'the pages come first and the shells last',
191
+ fit.omitted.length ? `left out to fit: ${fit.omitted.join(', ')}` : '',
192
+ fit.fits ? '' : `showing the first ${maxChars} characters`,
193
+ whole.length ? `with ${whole.join(' and ')} in full` : '',
194
+ ].filter(Boolean);
195
+ const text = parts.join('; ');
196
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}.`;
197
+ }
198
+ /**
199
+ * The observations as the model receives them: whole when they fit. Over
200
+ * budget, every surface's problems and job statuses are kept whole; the rest is
201
+ * fitted (see fitted): long lists shortened first, the page it acted on first
202
+ * and kept whole, and only if that still does not fit is the rest cut, saying so.
203
+ */
204
+ export function boundObservations(observations, maxChars, actingSurfaceId) {
205
+ const json = JSON.stringify(observations);
206
+ if (json.length <= maxChars)
207
+ return observations;
208
+ const problems = surfaceProblems(observations);
209
+ const jobs = jobStatuses(observations);
210
+ const fit = fitted(observations, maxChars, actingSurfaceId);
211
+ const whole = [problems ? 'every surface’s problems' : '', jobs ? 'every job’s status' : ''].filter(Boolean);
212
+ return {
213
+ truncated: true,
214
+ note: `Page state is ${json.length} characters. ${fitSummary(fit, maxChars, whole, actingSurfaceId !== undefined)}`,
215
+ ...(problems ? { problems } : {}),
216
+ ...(jobs ? { jobs } : {}),
217
+ ...(fit.fits ? { values: fit.values } : { preview: JSON.stringify(fit.values).slice(0, maxChars) }),
218
+ };
219
+ }
220
+ /** The same, as the text of a `<page_state>` block. */
221
+ export function observationsText(observations, maxChars) {
222
+ const json = JSON.stringify(observations);
223
+ if (json.length <= maxChars)
224
+ return json;
225
+ const problems = surfaceProblems(observations);
226
+ const jobs = jobStatuses(observations);
227
+ const fit = fitted(observations, maxChars, undefined);
228
+ const rest = JSON.stringify(fit.values);
229
+ const head = (problems ? `Problems (in full): ${JSON.stringify(problems)}\n` : '') +
230
+ (jobs ? `Jobs (in full): ${JSON.stringify(jobs)}\n` : '');
231
+ const tail = fit.fits
232
+ ? ` (fitted from ${json.length} characters. ${fitSummary(fit, maxChars, [], false)})`
233
+ : `… (truncated from ${json.length} characters)`;
234
+ return `${head}${head ? 'Values: ' : ''}${rest.slice(0, maxChars)}${tail}`;
235
+ }
236
+ //# sourceMappingURL=observations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observations.js","sourceRoot":"","sources":["../../src/ui/observations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The client's surface snapshot, carried on the turn.
3
+ *
4
+ * A UI client puts what it can do right now — its mounted OUI surfaces and
5
+ * their latest observations — on the turn's context under `oui` (ADR-0209).
6
+ * The worker builds the turn's UI tools from it and from nothing else, so the
7
+ * tools always describe the client that sent the turn.
8
+ */
9
+ import type { OUISurface, OUISurfaceSnapshot } from 'oui-spec/spec';
10
+ /** The context key a UI client uses for its snapshot. */
11
+ export declare const CLIENT_SNAPSHOT_KEY = "oui";
12
+ /**
13
+ * Read and validate the snapshot from a turn's context. Returns null when the
14
+ * turn carries none (a client with no UI), and throws when it carries one that
15
+ * is malformed: a broken snapshot is a client bug that must not quietly turn
16
+ * into "this client has no UI".
17
+ */
18
+ export declare function readClientSnapshot(context: Record<string, unknown> | null | undefined): OUISurfaceSnapshot | null;
19
+ /** The turn's context without the snapshot. */
20
+ export declare function withoutClientSnapshot(context: Record<string, unknown> | null | undefined): Record<string, unknown> | null | undefined;
21
+ /**
22
+ * The turn's context without what the client's UI sent for the worker itself:
23
+ * its snapshot (the turn's UI tools) and its knowledge (rendered after the
24
+ * host's prompt). This is the context the host's prompt renders as prose.
25
+ */
26
+ export declare function withoutClientUI(context: Record<string, unknown> | null | undefined): Record<string, unknown> | null | undefined;
27
+ /**
28
+ * A stable fingerprint of what the client can do: its surface ids and each
29
+ * surface's action ids. Two snapshots with the same fingerprint give the
30
+ * model the same tools.
31
+ */
32
+ export declare function capabilityFingerprint(surfaces: readonly OUISurface[]): string;
33
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/ui/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGpE,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,GAAG,IAAI,CA0BjH;AAED,+CAA+C;AAC/C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAClD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAClD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAE5C;AAUD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAI7E"}
@@ -0,0 +1,75 @@
1
+ import { CLIENT_KNOWLEDGE_KEY } from './knowledge.js';
2
+ /** The context key a UI client uses for its snapshot. */
3
+ export const CLIENT_SNAPSHOT_KEY = 'oui';
4
+ /**
5
+ * Read and validate the snapshot from a turn's context. Returns null when the
6
+ * turn carries none (a client with no UI), and throws when it carries one that
7
+ * is malformed: a broken snapshot is a client bug that must not quietly turn
8
+ * into "this client has no UI".
9
+ */
10
+ export function readClientSnapshot(context) {
11
+ const raw = context?.[CLIENT_SNAPSHOT_KEY];
12
+ if (raw === undefined || raw === null)
13
+ return null;
14
+ if (typeof raw !== 'object') {
15
+ throw new Error(`[agent-sdk] context.${CLIENT_SNAPSHOT_KEY} must be an object`);
16
+ }
17
+ const { surfaces, observations, surfacesHash } = raw;
18
+ if (!Array.isArray(surfaces)) {
19
+ throw new Error(`[agent-sdk] context.${CLIENT_SNAPSHOT_KEY}.surfaces must be an array`);
20
+ }
21
+ for (const [i, s] of surfaces.entries()) {
22
+ if (!isSurface(s)) {
23
+ throw new Error(`[agent-sdk] context.${CLIENT_SNAPSHOT_KEY}.surfaces[${i}] is not an OUI surface manifest (id, name, description, actions[])`);
24
+ }
25
+ }
26
+ return {
27
+ surfaces: surfaces,
28
+ observations: observations && typeof observations === 'object'
29
+ ? observations
30
+ : {},
31
+ // The hash the worker sends back as `knownSurfaces` (oui-spec 0.6), when the client sent one.
32
+ ...(typeof surfacesHash === 'string' && surfacesHash ? { surfacesHash } : {}),
33
+ };
34
+ }
35
+ /** The turn's context without the snapshot. */
36
+ export function withoutClientSnapshot(context) {
37
+ return omitKeys(context, [CLIENT_SNAPSHOT_KEY]);
38
+ }
39
+ /**
40
+ * The turn's context without what the client's UI sent for the worker itself:
41
+ * its snapshot (the turn's UI tools) and its knowledge (rendered after the
42
+ * host's prompt). This is the context the host's prompt renders as prose.
43
+ */
44
+ export function withoutClientUI(context) {
45
+ return omitKeys(context, [CLIENT_SNAPSHOT_KEY, CLIENT_KNOWLEDGE_KEY]);
46
+ }
47
+ function omitKeys(context, keys) {
48
+ if (!context || !keys.some((k) => k in context))
49
+ return context;
50
+ return Object.fromEntries(Object.entries(context).filter(([k]) => !keys.includes(k)));
51
+ }
52
+ /**
53
+ * A stable fingerprint of what the client can do: its surface ids and each
54
+ * surface's action ids. Two snapshots with the same fingerprint give the
55
+ * model the same tools.
56
+ */
57
+ export function capabilityFingerprint(surfaces) {
58
+ return surfaces
59
+ .map((s) => `${s.id}(${s.actions.map((a) => a.id).join(',')})`)
60
+ .join('|');
61
+ }
62
+ function isSurface(value) {
63
+ if (!value || typeof value !== 'object')
64
+ return false;
65
+ const s = value;
66
+ return (typeof s.id === 'string' &&
67
+ typeof s.name === 'string' &&
68
+ typeof s.description === 'string' &&
69
+ Array.isArray(s.actions) &&
70
+ s.actions.every((a) => !!a &&
71
+ typeof a === 'object' &&
72
+ typeof a.id === 'string' &&
73
+ typeof a.description === 'string'));
74
+ }
75
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/ui/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A turn's UI actions run one at a time, in the order the model called them.
3
+ *
4
+ * The model often asks for several UI actions in one response: fill a field,
5
+ * fill another, press the form's button. Each is a tool call, and tool calls
6
+ * from one response run concurrently, so a button press could reach the page
7
+ * before the fields were filled and find the button still disabled. UI actions
8
+ * act on one page, so they queue: each is dispatched only once the one before
9
+ * has answered, whether it succeeded or failed, and each result shows the page
10
+ * as the actions before it left it.
11
+ *
12
+ * The order is taken when the model's call arrives, not when the action is
13
+ * ready to dispatch. Whatever runs first (the orchestrator's input check, the
14
+ * host's tool policy, the "tool call started" emit) may finish in any order, so
15
+ * the caller reserves its place synchronously, before any `await`, and runs
16
+ * the action on that place later (`reserve`). On dev a name and a prompt called
17
+ * in that order ran prompt-first because the queue was joined only after those
18
+ * awaits.
19
+ *
20
+ * One sequence per turn, shared by every set of UI tools built during it (the
21
+ * tools are rebuilt when the page changes). Host tools are not queued.
22
+ *
23
+ * The sequence also holds the page's surfaces, by their hash (oui-spec 0.6):
24
+ * a request says which surfaces the worker holds (`knownSurfaces`), and the
25
+ * tab's answer then carries surfaces only when they changed. An answer
26
+ * without them is resolved here, from the hash it reports.
27
+ */
28
+ import type { OUISurface } from 'oui-spec/spec';
29
+ /** One place in a turn's UI order, taken when the call arrived. */
30
+ export interface UISlot {
31
+ /**
32
+ * Run the action in this place: once every place taken before it has
33
+ * finished. The place is finished when the action settles, succeeded or not.
34
+ * Call it at most once.
35
+ */
36
+ run<T>(step: () => Promise<T>): Promise<T>;
37
+ /**
38
+ * Give the place up without running anything (the call was refused before it
39
+ * reached the page). Does nothing once `run` has been called: then the place
40
+ * is finished only when the action settles, so a caller that stops waiting
41
+ * (a timeout) cannot let the next action reach the page early.
42
+ */
43
+ release(): void;
44
+ }
45
+ export interface UISequence {
46
+ /** Take the next place in the order now, synchronously. Every place must be run or released. */
47
+ reserve(): UISlot;
48
+ /** Take the next place and run a UI action in it: `reserve().run(step)`. */
49
+ run<T>(step: () => Promise<T>): Promise<T>;
50
+ /** The surfaces on screen after the last answered action, or null before any has answered. */
51
+ latestSurfaces(): readonly OUISurface[] | null;
52
+ /**
53
+ * The hash of the surfaces the worker holds for the page — the snapshot's,
54
+ * or the last answer's — sent as a request's `knownSurfaces`; null when the
55
+ * page's surfaces are not known for certain, so the tab sends them all.
56
+ */
57
+ knownHash(): string | null;
58
+ /**
59
+ * The surfaces an answer stands for: those it carries, else those held under
60
+ * the hash it reports, else undefined (an answer from a tab that sends
61
+ * neither, or a hash the worker never held).
62
+ */
63
+ resolve(answer: {
64
+ surfaces?: OUISurface[];
65
+ surfacesHash?: string;
66
+ }): OUISurface[] | undefined;
67
+ /**
68
+ * Record the surfaces an answer (or the turn's snapshot) reported, with
69
+ * their hash. An answer whose surfaces cannot be resolved makes the page's
70
+ * surfaces unknown: the next request names none, and the tab sends them.
71
+ */
72
+ record(surfaces: readonly OUISurface[] | undefined, hash?: string): void;
73
+ }
74
+ export declare function createUISequence(): UISequence;
75
+ //# sourceMappingURL=ui-sequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-sequence.d.ts","sourceRoot":"","sources":["../../src/ui/ui-sequence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C;;;;;OAKG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,gGAAgG;IAChG,OAAO,IAAI,MAAM,CAAC;IAClB,4EAA4E;IAC5E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C,8FAA8F;IAC9F,cAAc,IAAI,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE,GAAG,SAAS,CAAC;IAC9F;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1E;AAKD,wBAAgB,gBAAgB,IAAI,UAAU,CAgE7C"}
@@ -0,0 +1,73 @@
1
+ /** How many surface sets the sequence keeps by hash: the page, and the few it was just on. */
2
+ const HELD_SURFACE_SETS = 8;
3
+ export function createUISequence() {
4
+ let tail = Promise.resolve();
5
+ let latest = null;
6
+ let latestHash = null;
7
+ // Surface sets by hash, oldest first, at most HELD_SURFACE_SETS.
8
+ const held = new Map();
9
+ const hold = (hash, surfaces) => {
10
+ held.delete(hash);
11
+ held.set(hash, surfaces);
12
+ while (held.size > HELD_SURFACE_SETS)
13
+ held.delete(held.keys().next().value);
14
+ };
15
+ function reserve() {
16
+ const before = tail;
17
+ let finish;
18
+ const finished = new Promise((resolve) => {
19
+ finish = resolve;
20
+ });
21
+ // The next place waits for this one, and so for every place before it,
22
+ // even when this one is released without running.
23
+ tail = before.then(() => finished);
24
+ let used = false;
25
+ return {
26
+ run(step) {
27
+ if (used)
28
+ throw new Error('[agent-sdk] a UI slot runs one action');
29
+ used = true;
30
+ const next = before.then(step);
31
+ // A failed action does not hold up the ones after it.
32
+ next.then(finish, finish);
33
+ return next;
34
+ },
35
+ release() {
36
+ if (used)
37
+ return;
38
+ used = true;
39
+ finish();
40
+ },
41
+ };
42
+ }
43
+ return {
44
+ reserve,
45
+ run: (step) => reserve().run(step),
46
+ latestSurfaces: () => latest,
47
+ knownHash: () => latestHash,
48
+ resolve(answer) {
49
+ if (answer.surfaces)
50
+ return answer.surfaces;
51
+ return answer.surfacesHash ? held.get(answer.surfacesHash) : undefined;
52
+ },
53
+ record(surfaces, hash) {
54
+ if (surfaces) {
55
+ latest = surfaces;
56
+ latestHash = hash ?? null;
57
+ if (hash)
58
+ hold(hash, [...surfaces]);
59
+ }
60
+ else if (hash !== undefined && held.has(hash)) {
61
+ // Unchanged, or back to a set held before: that set is the page now.
62
+ latest = held.get(hash);
63
+ latestHash = hash;
64
+ hold(hash, held.get(hash));
65
+ }
66
+ else {
67
+ // What the page offers now is not known for certain: ask for it whole.
68
+ latestHash = null;
69
+ }
70
+ },
71
+ };
72
+ }
73
+ //# sourceMappingURL=ui-sequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-sequence.js","sourceRoot":"","sources":["../../src/ui/ui-sequence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * UI tools: one tool per action of every surface the client has mounted.
3
+ *
4
+ * Calling one sends an OUI action request to the client that sent the turn
5
+ * and waits for its answer (ADR-0209 D2). The model gets what really happened
6
+ * — the action's result or error — and what the page offers afterwards.
7
+ */
8
+ import type { OUIActionResult, OUISurface } from 'oui-spec/spec';
9
+ import type { RegisteredTool } from '../tools/types.js';
10
+ import type { UIActionChannel } from './channel.js';
11
+ import { type UISequence } from './ui-sequence.js';
12
+ export interface UIToolDependencies {
13
+ channel: UIActionChannel;
14
+ /** How long to wait for the client's answer. */
15
+ resultTimeoutMs: number;
16
+ /** The surfaces the model's current tools were built from. */
17
+ currentSurfaces(): readonly OUISurface[];
18
+ /** Called with every answer, before the model sees it. */
19
+ onResult(result: OUIActionResult): void;
20
+ /** Largest observation payload returned to the model, in characters. */
21
+ maxObservationChars?: number;
22
+ /**
23
+ * When the turn must stop waiting for work an action started, so the model
24
+ * still has time to answer: epoch ms. An action that is still running then is
25
+ * reported as running, never as done. Unbounded when not given.
26
+ */
27
+ waitDeadline?: () => number;
28
+ /**
29
+ * The turn's UI action queue, shared by every set of UI tools built during the
30
+ * turn, so the actions run one at a time in the order they were called. A new
31
+ * one is made for these tools when none is given.
32
+ */
33
+ sequence?: UISequence;
34
+ }
35
+ export interface UIToolCollision {
36
+ actionId: string;
37
+ keptSurface: string;
38
+ droppedSurface: string;
39
+ }
40
+ /**
41
+ * When to send a request again while no tab has received it (dispatchUntilAnswered):
42
+ * after 1 s, then 2, 4, and every 8 s.
43
+ */
44
+ export declare const FIRST_RESEND_AFTER_MS = 1000;
45
+ export declare const MAX_RESEND_AFTER_MS = 8000;
46
+ /**
47
+ * When to send a request a tab received again, if its answer has not come: by
48
+ * then longer than the tab waits before answering a repeat (oui-spec's
49
+ * `reanswerAfterMs`, 8 s), so the repeat recovers an answer that was lost.
50
+ */
51
+ export declare const RECEIVED_RESEND_AFTER_MS = 10000;
52
+ /** How long to wait for an async action's outcome when it declares no limit of its own. */
53
+ export declare const DEFAULT_JOB_WAIT_MS: number;
54
+ /** Build the UI tools for a set of surfaces. The first surface to declare an action id keeps it. */
55
+ export declare function buildUITools(surfaces: readonly OUISurface[], deps: UIToolDependencies): {
56
+ tools: RegisteredTool[];
57
+ collisions: UIToolCollision[];
58
+ };
59
+ //# sourceMappingURL=ui-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-tools.d.ts","sourceRoot":"","sources":["../../src/ui/ui-tools.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAA+B,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,mBAAmB,CAAC;AACnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,eAAe,CAAC;IACzB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,eAAe,IAAI,SAAS,UAAU,EAAE,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAGD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAC3C,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,2FAA2F;AAC3F,eAAO,MAAM,mBAAmB,QAAa,CAAC;AAE9C,oGAAoG;AACpG,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,IAAI,EAAE,kBAAkB,GACvB;IAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IAAC,UAAU,EAAE,eAAe,EAAE,CAAA;CAAE,CAkB5D"}