@ouispec/agent-worker 0.4.0 → 0.8.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 (97) hide show
  1. package/README.md +57 -2
  2. package/dist/approvals/client.d.ts +8 -1
  3. package/dist/approvals/client.d.ts.map +1 -1
  4. package/dist/approvals/client.js +10 -0
  5. package/dist/approvals/client.js.map +1 -1
  6. package/dist/approvals/continuation.d.ts +13 -1
  7. package/dist/approvals/continuation.d.ts.map +1 -1
  8. package/dist/approvals/continuation.js +35 -0
  9. package/dist/approvals/continuation.js.map +1 -1
  10. package/dist/approvals/preview.d.ts +2 -2
  11. package/dist/approvals/preview.d.ts.map +1 -1
  12. package/dist/approvals/preview.js +20 -3
  13. package/dist/approvals/preview.js.map +1 -1
  14. package/dist/attachments/content.d.ts +68 -0
  15. package/dist/attachments/content.d.ts.map +1 -0
  16. package/dist/attachments/content.js +318 -0
  17. package/dist/attachments/content.js.map +1 -0
  18. package/dist/attachments/guard.d.ts +69 -0
  19. package/dist/attachments/guard.d.ts.map +1 -0
  20. package/dist/attachments/guard.js +86 -0
  21. package/dist/attachments/guard.js.map +1 -0
  22. package/dist/attachments/limits.d.ts +46 -0
  23. package/dist/attachments/limits.d.ts.map +1 -0
  24. package/dist/attachments/limits.js +64 -0
  25. package/dist/attachments/limits.js.map +1 -0
  26. package/dist/attachments/store.d.ts +85 -0
  27. package/dist/attachments/store.d.ts.map +1 -0
  28. package/dist/attachments/store.js +2 -0
  29. package/dist/attachments/store.js.map +1 -0
  30. package/dist/attachments/tools.d.ts +12 -0
  31. package/dist/attachments/tools.d.ts.map +1 -0
  32. package/dist/attachments/tools.js +216 -0
  33. package/dist/attachments/tools.js.map +1 -0
  34. package/dist/authz/tool-policy.d.ts +6 -0
  35. package/dist/authz/tool-policy.d.ts.map +1 -1
  36. package/dist/authz/tool-policy.js.map +1 -1
  37. package/dist/index.d.ts +12 -3
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +10 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/lambda/handler.d.ts +2 -2
  42. package/dist/lambda/handler.d.ts.map +1 -1
  43. package/dist/lambda/handler.js +3 -2
  44. package/dist/lambda/handler.js.map +1 -1
  45. package/dist/orchestrator.d.ts.map +1 -1
  46. package/dist/orchestrator.js +613 -101
  47. package/dist/orchestrator.js.map +1 -1
  48. package/dist/prompt/clock.d.ts +0 -17
  49. package/dist/prompt/clock.d.ts.map +1 -1
  50. package/dist/prompt/clock.js +19 -2
  51. package/dist/prompt/clock.js.map +1 -1
  52. package/dist/prompt/user-text.d.ts +19 -0
  53. package/dist/prompt/user-text.d.ts.map +1 -0
  54. package/dist/prompt/user-text.js +20 -0
  55. package/dist/prompt/user-text.js.map +1 -0
  56. package/dist/runtime/turn-runner.d.ts +29 -2
  57. package/dist/runtime/turn-runner.d.ts.map +1 -1
  58. package/dist/runtime/turn-runner.js +118 -9
  59. package/dist/runtime/turn-runner.js.map +1 -1
  60. package/dist/runtime/types.d.ts +84 -6
  61. package/dist/runtime/types.d.ts.map +1 -1
  62. package/dist/stop/partial.d.ts +49 -0
  63. package/dist/stop/partial.d.ts.map +1 -0
  64. package/dist/stop/partial.js +73 -0
  65. package/dist/stop/partial.js.map +1 -0
  66. package/dist/stop/results.d.ts +20 -0
  67. package/dist/stop/results.d.ts.map +1 -0
  68. package/dist/stop/results.js +46 -0
  69. package/dist/stop/results.js.map +1 -0
  70. package/dist/stop/turn-stop.d.ts +114 -0
  71. package/dist/stop/turn-stop.d.ts.map +1 -0
  72. package/dist/stop/turn-stop.js +159 -0
  73. package/dist/stop/turn-stop.js.map +1 -0
  74. package/dist/tools/input-validation.d.ts.map +1 -1
  75. package/dist/tools/input-validation.js +3 -0
  76. package/dist/tools/input-validation.js.map +1 -1
  77. package/dist/tools/types.d.ts +19 -0
  78. package/dist/tools/types.d.ts.map +1 -1
  79. package/dist/tools/types.js.map +1 -1
  80. package/dist/turn-policy.d.ts +14 -0
  81. package/dist/turn-policy.d.ts.map +1 -1
  82. package/dist/turn-policy.js.map +1 -1
  83. package/dist/types.d.ts +84 -3
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/ui/knowledge.d.ts +28 -2
  86. package/dist/ui/knowledge.d.ts.map +1 -1
  87. package/dist/ui/knowledge.js +117 -13
  88. package/dist/ui/knowledge.js.map +1 -1
  89. package/dist/ui/newest-page-state.d.ts +25 -0
  90. package/dist/ui/newest-page-state.d.ts.map +1 -0
  91. package/dist/ui/newest-page-state.js +91 -0
  92. package/dist/ui/newest-page-state.js.map +1 -0
  93. package/dist/ui/ui-tools.d.ts +20 -2
  94. package/dist/ui/ui-tools.d.ts.map +1 -1
  95. package/dist/ui/ui-tools.js +65 -6
  96. package/dist/ui/ui-tools.js.map +1 -1
  97. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,mBAAmB,CAAC;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,qBAAqB,EAAE,eAAe,CAAC;IAC3D,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAC,CAAC;IAClE,2EAA2E;IAC3E,KAAK,EAAE,aAAa,CAAC;IACrB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,eAAe,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;;;OAIG;IACH,EAAE,CAAC,EAAE;QACH,OAAO,EAAE,eAAe,CAAC;QACzB,sEAAsE;QACtE,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gHAAgH;QAChH,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,oHAAoH;QACpH,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,OAAO,GAAG,aAAa,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,WAAW,EAAE,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,6EAA6E;QAC7E,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB;;;;;WAKG;QACH,gBAAgB,EAAE,MAAM,CAAC;QACzB,uGAAuG;QACvG,eAAe,EAAE,MAAM,CAAC;QACxB,8EAA8E;QAC9E,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,UAAU,EAAE,iBAAiB,GAAG,mBAAmB,GAAG,YAAY,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;CACzH;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -10,10 +10,24 @@
10
10
  * The worker renders it into the system prompt after the host's own prompt, for
11
11
  * every host: a persona or a `systemPrompt` callback never sees it as context
12
12
  * and never has to render it.
13
+ *
14
+ * It is bounded, as the page's index is (ADR-0245): in session 24611234 the
15
+ * video editor's knowledge was 117,000 characters, most of it a page detail
16
+ * that repeats what the index already lists, in every model call of every
17
+ * turn. What fits in `KNOWLEDGE_PROMPT_CHARS` is sent; the rest of an entry,
18
+ * and a workflow's steps, are read with `ui_guide` when they are needed, and
19
+ * the prompt says what is not shown and how to read it.
13
20
  */
14
21
  import type { ResolvedKnowledge } from '@ouispec/bindings';
22
+ import type { RegisteredTool } from '../tools/types.js';
15
23
  /** The context key a UI client uses for its knowledge. */
16
24
  export declare const CLIENT_KNOWLEDGE_KEY = "uiKnowledge";
25
+ /** The tool that reads the rest of the knowledge. */
26
+ export declare const KNOWLEDGE_TOOL = "ui_guide";
27
+ /** The knowledge the system prompt carries at most, in characters. One constant. */
28
+ export declare const KNOWLEDGE_PROMPT_CHARS = 12000;
29
+ /** What one `ui_guide` answer gives at most. */
30
+ export declare const KNOWLEDGE_PAGE_CHARS = 12000;
17
31
  /** What a UI client sends: the knowledge for the page the user is on. */
18
32
  export type ClientKnowledge = ResolvedKnowledge;
19
33
  /**
@@ -23,8 +37,20 @@ export type ClientKnowledge = ResolvedKnowledge;
23
37
  * become "this client knows nothing".
24
38
  */
25
39
  export declare function readClientKnowledge(context: Record<string, unknown> | null | undefined): ClientKnowledge | null;
26
- /** The knowledge as a prompt section: every entry, then every workflow with its numbered steps. */
27
- export declare function renderClientKnowledge(knowledge: ClientKnowledge): string;
40
+ /**
41
+ * The knowledge as a prompt section, within `maxChars`: every entry whole when
42
+ * all of it fits, and every workflow with its steps. Over that, small entries
43
+ * stay whole, a large one is cut at a line with a note saying how much is left
44
+ * and how to read it, and the workflows are listed by name to be read one at a
45
+ * time.
46
+ */
47
+ export declare function renderClientKnowledge(knowledge: ClientKnowledge, maxChars?: number): string;
48
+ /**
49
+ * Reads what the prompt leaves out of the client's knowledge: the rest of an
50
+ * entry, a page at a time, or a workflow in full. It reads only what the turn's
51
+ * client sent, so it changes nothing and needs no approval.
52
+ */
53
+ export declare function knowledgeTool(knowledge: ClientKnowledge): RegisteredTool;
28
54
  /** The host's system prompt, followed by the knowledge the turn's client sent, if any. */
29
55
  export declare function withClientKnowledge(systemPrompt: string, context: Record<string, unknown> | null | undefined): string;
30
56
  //# sourceMappingURL=knowledge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/ui/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAElD,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEhD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAe/G;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAgBxE;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAIrH"}
1
+ {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/ui/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,qDAAqD;AACrD,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAG7C,gDAAgD;AAChD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEhD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAe/G;AAcD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,EAAE,QAAQ,SAAyB,GAAG,MAAM,CAqC3G;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,cAAc,CAmDxE;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAIrH"}
@@ -1,5 +1,13 @@
1
1
  /** The context key a UI client uses for its knowledge. */
2
2
  export const CLIENT_KNOWLEDGE_KEY = 'uiKnowledge';
3
+ /** The tool that reads the rest of the knowledge. */
4
+ export const KNOWLEDGE_TOOL = 'ui_guide';
5
+ /** The knowledge the system prompt carries at most, in characters. One constant. */
6
+ export const KNOWLEDGE_PROMPT_CHARS = 12_000;
7
+ /** An entry this size or smaller is never cut: a map, a frame, a neighbouring page's summary. */
8
+ const WHOLE_ENTRY_CHARS = 1_500;
9
+ /** What one `ui_guide` answer gives at most. */
10
+ export const KNOWLEDGE_PAGE_CHARS = 12_000;
3
11
  /**
4
12
  * Read and validate the knowledge from a turn's context. Returns null when the
5
13
  * turn carries none (a client with no UI), and throws when it carries knowledge
@@ -28,19 +36,115 @@ export function readClientKnowledge(context) {
28
36
  });
29
37
  return { entries, workflows };
30
38
  }
31
- /** The knowledge as a prompt section: every entry, then every workflow with its numbered steps. */
32
- export function renderClientKnowledge(knowledge) {
33
- const sections = [];
34
- if (knowledge.entries.length > 0) {
35
- sections.push('## Platform Knowledge (Context-Aware)\n\n' + knowledge.entries.map((e) => `### ${e.title}\n${e.content}`).join('\n\n'));
36
- }
37
- if (knowledge.workflows.length > 0) {
38
- sections.push('## Active Workflows\n\n' +
39
- knowledge.workflows
40
- .map((w) => `### ${w.name}\nTrigger: ${w.trigger}\nSteps:\n${w.steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}`)
41
- .join('\n\n'));
42
- }
43
- return sections.join('\n\n');
39
+ /** A workflow in full: its trigger and numbered steps. */
40
+ function workflowText(w) {
41
+ return `Trigger: ${w.trigger}\nSteps:\n${w.steps.map((step, i) => `${i + 1}. ${step}`).join('\n')}`;
42
+ }
43
+ /** `text` cut at a line end at most `max` characters in, never mid-line when a line end is near. */
44
+ function cutAt(text, max) {
45
+ if (text.length <= max)
46
+ return text;
47
+ const end = text.lastIndexOf('\n', max);
48
+ return text.slice(0, end > max / 2 ? end : max);
49
+ }
50
+ /**
51
+ * The knowledge as a prompt section, within `maxChars`: every entry whole when
52
+ * all of it fits, and every workflow with its steps. Over that, small entries
53
+ * stay whole, a large one is cut at a line with a note saying how much is left
54
+ * and how to read it, and the workflows are listed by name to be read one at a
55
+ * time.
56
+ */
57
+ export function renderClientKnowledge(knowledge, maxChars = KNOWLEDGE_PROMPT_CHARS) {
58
+ const entryHead = '## Platform Knowledge (Context-Aware)\n\n';
59
+ const workflowHead = '## Active Workflows\n\n';
60
+ const whole = (e) => `### ${e.title}\n${e.content}`;
61
+ const wholeWorkflows = knowledge.workflows.map((w) => `### ${w.name}\n${workflowText(w)}`).join('\n\n');
62
+ const sections = (entries, workflows) => [entries.length ? entryHead + entries.join('\n\n') : '', workflows ? workflowHead + workflows : '']
63
+ .filter(Boolean)
64
+ .join('\n\n');
65
+ const all = sections(knowledge.entries.map(whole), wholeWorkflows);
66
+ if (all.length <= maxChars)
67
+ return all;
68
+ // The workflows by name: each read whole with the tool.
69
+ const named = knowledge.workflows.length
70
+ ? `Each is read in full, with its steps, by \`${KNOWLEDGE_TOOL}\` with \`workflow\` set to its name.\n` +
71
+ knowledge.workflows.map((w) => `- ${w.name}`).join('\n')
72
+ : '';
73
+ const workflowsSize = named ? workflowHead.length + named.length + 2 : 0;
74
+ // The small entries whole; the large ones share what is left, each cut at a line.
75
+ const small = knowledge.entries.filter((e) => whole(e).length <= WHOLE_ENTRY_CHARS);
76
+ const large = knowledge.entries.filter((e) => whole(e).length > WHOLE_ENTRY_CHARS);
77
+ const fixed = entryHead.length + small.reduce((n, e) => n + whole(e).length + 2, 0);
78
+ const share = Math.max(0, Math.floor((maxChars - workflowsSize - fixed) / Math.max(large.length, 1)) - 200);
79
+ const rendered = knowledge.entries.map((e) => {
80
+ if (!large.includes(e))
81
+ return whole(e);
82
+ const shown = cutAt(e.content, share);
83
+ const rest = e.content.length - shown.length;
84
+ return (`### ${e.title}\n${shown}` +
85
+ (rest > 0
86
+ ? `\n(${rest} more characters of "${e.title}" are not shown: \`${KNOWLEDGE_TOOL}\` with \`entry\` set to this title and \`from: ${shown.length}\` reads them.)`
87
+ : ''));
88
+ });
89
+ return sections(rendered, named);
90
+ }
91
+ /**
92
+ * Reads what the prompt leaves out of the client's knowledge: the rest of an
93
+ * entry, a page at a time, or a workflow in full. It reads only what the turn's
94
+ * client sent, so it changes nothing and needs no approval.
95
+ */
96
+ export function knowledgeTool(knowledge) {
97
+ const titles = knowledge.entries.map((e) => e.title);
98
+ const names = knowledge.workflows.map((w) => w.name);
99
+ const listed = (items) => items.slice(0, 40).map((t) => `"${t}"`).join(', ') + (items.length > 40 ? ', …' : '');
100
+ return {
101
+ name: KNOWLEDGE_TOOL,
102
+ kind: 'ui',
103
+ effect: 'view',
104
+ description: 'Reads the part of what the app knows about this page that your instructions do not show: the rest of a ' +
105
+ 'knowledge entry (`entry`, its title, and `from`, where to continue), or one workflow with its steps (`workflow`, its name). ' +
106
+ 'Your instructions say what is not shown and give the title or name.',
107
+ inputSchema: {
108
+ type: 'object',
109
+ additionalProperties: false,
110
+ properties: {
111
+ entry: { type: 'string', description: 'A knowledge entry’s title, as your instructions give it.' },
112
+ workflow: { type: 'string', description: 'A workflow’s name, as your instructions list it.' },
113
+ from: { type: 'integer', minimum: 0, description: 'Where in the entry to begin. Default 0.' },
114
+ },
115
+ },
116
+ async execute(input) {
117
+ const workflow = typeof input.workflow === 'string' ? input.workflow.trim() : '';
118
+ const entry = typeof input.entry === 'string' ? input.entry.trim() : '';
119
+ if (workflow) {
120
+ const found = knowledge.workflows.find((w) => w.name === workflow) ??
121
+ knowledge.workflows.find((w) => w.name.toLowerCase() === workflow.toLowerCase());
122
+ if (!found)
123
+ return { success: false, error: `No workflow is named "${workflow}". Workflows: ${listed(names)}.` };
124
+ return { success: true, data: { workflow: found.name, text: workflowText(found) } };
125
+ }
126
+ if (entry) {
127
+ const found = knowledge.entries.find((e) => e.title === entry) ??
128
+ knowledge.entries.find((e) => e.title.toLowerCase() === entry.toLowerCase());
129
+ if (!found)
130
+ return { success: false, error: `No knowledge entry has the title "${entry}". Entries: ${listed(titles)}.` };
131
+ const from = typeof input.from === 'number' && input.from > 0 ? Math.min(input.from, found.content.length) : 0;
132
+ const text = cutAt(found.content.slice(from), KNOWLEDGE_PAGE_CHARS);
133
+ const next = from + text.length;
134
+ return {
135
+ success: true,
136
+ data: {
137
+ entry: found.title,
138
+ from,
139
+ total: found.content.length,
140
+ text,
141
+ ...(next < found.content.length ? { next } : {}),
142
+ },
143
+ };
144
+ }
145
+ return { success: false, error: 'Give an `entry` title or a `workflow` name.' };
146
+ },
147
+ };
44
148
  }
45
149
  /** The host's system prompt, followed by the knowledge the turn's client sent, if any. */
46
150
  export function withClientKnowledge(systemPrompt, context) {
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/ui/knowledge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/ui/knowledge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Only the newest UI answer carries the page's state to the model.
3
+ *
4
+ * Every UI answer comes with the page's state (`state`, up to the page-state
5
+ * budget), so the model sees what its action did. Kept on every answer, a turn
6
+ * of many actions resends every earlier page with every step: in session
7
+ * 24611234 a turn of 24 editor actions peaked at 205,000 prompt tokens, about
8
+ * 5,000 for each answer kept. An earlier page is not what the page is now, and
9
+ * the newest answer holds that.
10
+ *
11
+ * So before each step, every earlier answer keeps what it did (its result, the
12
+ * rows it changed, what the page offers since, any error) and its `state` is
13
+ * replaced with one line that says where the page's state is.
14
+ */
15
+ import type { ModelMessage } from 'ai';
16
+ export declare const SUPERSEDED_STATE = "Not repeated: a later answer in this conversation carries the page\u2019s state, which is what the page is now.";
17
+ /**
18
+ * `messages` with the page's state kept on the newest answer that carries one
19
+ * and replaced on every earlier one, or null when there is nothing to replace.
20
+ */
21
+ export declare function withNewestPageStateOnly(messages: readonly ModelMessage[]): {
22
+ messages: ModelMessage[];
23
+ replaced: number;
24
+ } | null;
25
+ //# sourceMappingURL=newest-page-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newest-page-state.d.ts","sourceRoot":"","sources":["../../src/ui/newest-page-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC,eAAO,MAAM,gBAAgB,oHACiF,CAAC;AAgD/G;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkChI"}
@@ -0,0 +1,91 @@
1
+ export const SUPERSEDED_STATE = 'Not repeated: a later answer in this conversation carries the page’s state, which is what the page is now.';
2
+ /** The JSON text of an answer, when it is a UI answer that carries the page's state. */
3
+ function stateful(text) {
4
+ if (!text.includes('"state"'))
5
+ return null;
6
+ try {
7
+ const value = JSON.parse(text);
8
+ return value && typeof value === 'object' && !Array.isArray(value) && 'state' in value
9
+ ? value
10
+ : null;
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ /** The answer's text, wherever its output keeps it. */
17
+ function textOf(output) {
18
+ if (output.type === 'text')
19
+ return output.value;
20
+ if (output.type === 'json')
21
+ return JSON.stringify(output.value);
22
+ if (output.type === 'content') {
23
+ const part = output.value.find((p) => p.type === 'text');
24
+ return part?.text ?? null;
25
+ }
26
+ return null;
27
+ }
28
+ function withText(output, text) {
29
+ if (output.type === 'text')
30
+ return { ...output, value: text };
31
+ if (output.type === 'json')
32
+ return { ...output, value: JSON.parse(text) };
33
+ if (output.type === 'content') {
34
+ let done = false;
35
+ return {
36
+ ...output,
37
+ value: output.value.map((p) => {
38
+ if (done || p.type !== 'text')
39
+ return p;
40
+ done = true;
41
+ return { ...p, text };
42
+ }),
43
+ };
44
+ }
45
+ return output;
46
+ }
47
+ /**
48
+ * `messages` with the page's state kept on the newest answer that carries one
49
+ * and replaced on every earlier one, or null when there is nothing to replace.
50
+ */
51
+ export function withNewestPageStateOnly(messages) {
52
+ // The newest answer with a state, found from the end.
53
+ let newest = null;
54
+ for (let i = messages.length - 1; i >= 0 && newest === null; i--) {
55
+ const m = messages[i];
56
+ if (m.role !== 'tool')
57
+ continue;
58
+ for (let j = m.content.length - 1; j >= 0; j--) {
59
+ const part = m.content[j];
60
+ if (part.type !== 'tool-result')
61
+ continue;
62
+ const text = textOf(part.output);
63
+ if (text !== null && stateful(text)) {
64
+ newest = part.toolCallId;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ if (newest === null)
70
+ return null;
71
+ let replaced = 0;
72
+ const out = messages.map((m) => {
73
+ if (m.role !== 'tool')
74
+ return m;
75
+ let changed = false;
76
+ const content = m.content.map((part) => {
77
+ if (part.type !== 'tool-result' || part.toolCallId === newest)
78
+ return part;
79
+ const text = textOf(part.output);
80
+ const answer = text === null ? null : stateful(text);
81
+ if (!answer || answer.state === SUPERSEDED_STATE)
82
+ return part;
83
+ changed = true;
84
+ replaced++;
85
+ return { ...part, output: withText(part.output, JSON.stringify({ ...answer, state: SUPERSEDED_STATE })) };
86
+ });
87
+ return changed ? { ...m, content } : m;
88
+ });
89
+ return replaced ? { messages: out, replaced } : null;
90
+ }
91
+ //# sourceMappingURL=newest-page-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newest-page-state.js","sourceRoot":"","sources":["../../src/ui/newest-page-state.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,12 @@ export interface UIToolDependencies {
55
55
  * reported as running, never as done. Unbounded when not given.
56
56
  */
57
57
  waitDeadline?: () => number;
58
+ /**
59
+ * The longest a call waits for the outcome of work its action started, in ms;
60
+ * `DEFAULT_JOB_WAIT_MS` when not given. Never longer than the action's own
61
+ * limit or `waitDeadline`.
62
+ */
63
+ jobWaitMs?: number;
58
64
  /**
59
65
  * The turn's UI action queue, shared by every set of UI tools built during the
60
66
  * turn, so the actions run one at a time in the order they were called. A new
@@ -85,8 +91,18 @@ export declare const MAX_RESEND_AFTER_MS = 8000;
85
91
  * `reanswerAfterMs`, 8 s), so the repeat recovers an answer that was lost.
86
92
  */
87
93
  export declare const RECEIVED_RESEND_AFTER_MS = 10000;
88
- /** How long to wait for an async action's outcome when it declares no limit of its own. */
89
- export declare const DEFAULT_JOB_WAIT_MS: number;
94
+ /**
95
+ * The longest a UI tool waits, in the call, for the outcome of work an action
96
+ * started (a GPU job, an export): `UIToolDependencies.jobWaitMs` by default.
97
+ *
98
+ * Work that ends within it is reported done in the call. Work that does not is
99
+ * reported still running, and the turn goes on and ends: its outcome reaches
100
+ * the conversation through the page state, where the app's job tracker lists
101
+ * it, in the next turn. The call never waits on the action's own limit (its
102
+ * `maxDurationMs`), which can be many minutes for a job queued behind a live
103
+ * conversation: a turn held open that long could not be stopped or answered.
104
+ */
105
+ export declare const DEFAULT_JOB_WAIT_MS = 20000;
90
106
  /** The most actions one `ui_describe` call describes. */
91
107
  export declare const MAX_DESCRIBED_ACTIONS = 8;
92
108
  /**
@@ -103,6 +119,8 @@ export declare function buildUITools(page: readonly PageSurface[], deps: UIToolD
103
119
  /** Thrown when an action's definition cannot be had: the model is told why. */
104
120
  export declare class DefinitionUnavailable extends Error {
105
121
  }
122
+ /** The call's wait for a started action's outcome. */
123
+ export declare function jobWaitOf(deps: Pick<UIToolDependencies, 'jobWaitMs'>): number;
106
124
  /** What of the page's state the client left out to fit its answer, and how to read each part (oui-spec §7.3.9). */
107
125
  export declare function fitNotes(cuts: NonNullable<OUIFit['observations']>): string[];
108
126
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ui-tools.d.ts","sourceRoot":"","sources":["../../src/ui/ui-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui-tools.d.ts","sourceRoot":"","sources":["../../src/ui/ui-tools.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@
14
14
  * tools built here are what `ui_act` runs, so every check a tool call goes
15
15
  * through — input, quota, policy, approval — sees the action itself.
16
16
  */
17
+ import { stoppedBeforeAnswer, stoppedNotRun, stoppedNotTaken, stoppedOutcomeUnknown } from '../stop/results.js';
17
18
  import { randomUUID } from 'node:crypto';
18
19
  import { AGENT_UI_TOOLS } from '@ouispec/agent-core';
19
20
  import { jsonBytes, OUI_DESCRIBE_ACTION, OUI_READ_ACTION, OUI_RUNTIME_SURFACE, } from 'oui-spec/spec';
@@ -79,8 +80,18 @@ export const MAX_RESEND_AFTER_MS = 8_000;
79
80
  * `reanswerAfterMs`, 8 s), so the repeat recovers an answer that was lost.
80
81
  */
81
82
  export const RECEIVED_RESEND_AFTER_MS = 10_000;
82
- /** How long to wait for an async action's outcome when it declares no limit of its own. */
83
- export const DEFAULT_JOB_WAIT_MS = 5 * 60_000;
83
+ /**
84
+ * The longest a UI tool waits, in the call, for the outcome of work an action
85
+ * started (a GPU job, an export): `UIToolDependencies.jobWaitMs` by default.
86
+ *
87
+ * Work that ends within it is reported done in the call. Work that does not is
88
+ * reported still running, and the turn goes on and ends: its outcome reaches
89
+ * the conversation through the page state, where the app's job tracker lists
90
+ * it, in the next turn. The call never waits on the action's own limit (its
91
+ * `maxDurationMs`), which can be many minutes for a job queued behind a live
92
+ * conversation: a turn held open that long could not be stopped or answered.
93
+ */
94
+ export const DEFAULT_JOB_WAIT_MS = 20_000;
84
95
  /** The most actions one `ui_describe` call describes. */
85
96
  export const MAX_DESCRIBED_ACTIONS = 8;
86
97
  /**
@@ -137,6 +148,9 @@ function actionTool(action, shared) {
137
148
  // Checked here, in the action's place in the turn's order, and not when
138
149
  // the model's call arrived: of two changes called in one response, the
139
150
  // first's answer decides whether the second may run (ADR-0245 §2.5).
151
+ // A stopped turn sends nothing more: said first, since why it did not run is the stop.
152
+ if (ctx.stop?.reason())
153
+ return stoppedNotRun(entry.id);
140
154
  const refusal = entry.effect === 'view' ? null : shared.sight.refuseChange();
141
155
  if (refusal) {
142
156
  shared.deps.log?.('warn', 'UI action refused: the page cannot be seen', { action: entry.id, stopped: refusal.stopped });
@@ -174,14 +188,21 @@ async function definitionsOf(wanted, shared, ctx) {
174
188
  const room = ctx.socketRoom;
175
189
  if (!room)
176
190
  throw new Error('[agent-sdk] Describing a UI action needs the turn’s room');
191
+ // A stopped turn asks the page nothing more.
192
+ if (ctx.stop?.reason())
193
+ throw new DefinitionUnavailable(stoppedBeforeAnswer('what the action takes').error);
177
194
  const request = {
178
195
  requestId: `describe-${randomUUID()}`,
179
196
  surfaceId: OUI_RUNTIME_SURFACE,
180
197
  actionId: OUI_DESCRIBE_ACTION,
181
198
  params: { actions: missing.map((a) => ({ surface: a.surface.id, action: a.entry.id })) },
182
199
  timestamp: Date.now(),
200
+ turnId: ctx.turnId,
183
201
  };
184
202
  const answered = await dispatchUntilAnswered(shared.deps, room, request, ctx);
203
+ if (!answered.result && ctx.stop?.reason()) {
204
+ throw new DefinitionUnavailable(stoppedBeforeAnswer('what the action takes').error);
205
+ }
185
206
  if (!answered.result) {
186
207
  // A page that does not answer cannot be seen either: nothing is changed in it until it is read.
187
208
  shared.sight.lost('the page is not answering');
@@ -332,14 +353,20 @@ function readTool(shared) {
332
353
  const room = ctx.socketRoom;
333
354
  if (!room)
334
355
  throw new Error('[agent-sdk] Reading the page needs the turn’s room');
356
+ // A stopped turn asks the page nothing more.
357
+ if (ctx.stop?.reason())
358
+ return stoppedBeforeAnswer('the read');
335
359
  const request = {
336
360
  requestId: ctx.toolCallId ?? `read-${randomUUID()}`,
337
361
  surfaceId: OUI_RUNTIME_SURFACE,
338
362
  actionId: OUI_READ_ACTION,
339
363
  params: input,
340
364
  timestamp: Date.now(),
365
+ turnId: ctx.turnId,
341
366
  };
342
367
  const answered = await dispatchUntilAnswered(shared.deps, room, request, ctx);
368
+ if (!answered.result && ctx.stop?.reason())
369
+ return stoppedBeforeAnswer('the read');
343
370
  if (!answered.result) {
344
371
  shared.sight.lost('the page did not answer a read');
345
372
  return {
@@ -366,6 +393,10 @@ async function runAction(action, shared, input, ctx) {
366
393
  if (!requestId || !room) {
367
394
  throw new Error(`[agent-sdk] UI tool ${entry.id} needs the tool call id and the turn's room`);
368
395
  }
396
+ // A stopped turn sends nothing more: an action that was waiting its place in
397
+ // the turn's UI order has not reached the page, and now never does.
398
+ if (ctx.stop?.reason())
399
+ return stoppedNotRun(entry.id);
369
400
  // The page as the actions before this one left it.
370
401
  const before = sequence.latestSurfaces() ?? deps.currentPage();
371
402
  // What the worker holds of the page, so the answer repeats it only if it changed (oui-spec §7.3.4).
@@ -378,8 +409,29 @@ async function runAction(action, shared, input, ctx) {
378
409
  timestamp: Date.now(),
379
410
  ...(ctx.approval ? { approval: ctx.approval } : {}),
380
411
  ...(knownSurfaces ? { knownSurfaces } : {}),
412
+ // The tab runs a request only for its current turn (oui-spec §7.3.1).
413
+ turnId: ctx.turnId,
381
414
  };
382
- const answered = await dispatchUntilAnswered(deps, room, request, ctx);
415
+ let answered = await dispatchUntilAnswered(deps, room, request, ctx);
416
+ // The turn was stopped while the request was out (ADR-0252 §2.2).
417
+ if (!answered.result && ctx.stop?.reason()) {
418
+ // Tabs answered that they got it, and none took it: it did not run.
419
+ if (answered.receipts && !answered.received)
420
+ return stoppedNotTaken(entry.id);
421
+ // The page may be running it. One last look, on the stop's own signal (the
422
+ // turn's is aborted), so an action that did run has its answer stored and
423
+ // the next turn does not do it again.
424
+ const late = await deps.channel.awaitResult(requestId, {
425
+ userId: ctx.userId,
426
+ timeoutMs: ctx.stop.graceMs,
427
+ signal: ctx.stop.graceSignal(),
428
+ });
429
+ if (!late) {
430
+ sight.lost(`the turn was stopped before the page answered "${entry.id}"`);
431
+ return stoppedOutcomeUnknown(entry.id);
432
+ }
433
+ answered = { ...answered, result: late };
434
+ }
383
435
  if (!answered.result) {
384
436
  const within = `within ${Math.round(deps.resultTimeoutMs / 1000)}s`;
385
437
  const sent = `${answered.sends} time${answered.sends === 1 ? '' : 's'}`;
@@ -489,11 +541,13 @@ function withPage(result, shared) {
489
541
  }
490
542
  /**
491
543
  * The final answer to a started action: its outcome once the work is done or
492
- * has failed, or `'running'` when it has not finished by its own limit (its
493
- * polling's `maxDurationMs`) or by when the turn must stop waiting.
544
+ * has failed, or `'running'` when it has not finished within the call's wait
545
+ * (`jobWaitMs`), its own limit (its polling's `maxDurationMs`), or by when the
546
+ * turn must stop waiting, whichever comes first.
494
547
  */
495
548
  async function awaitOutcome(entry, deps, requestId, ctx) {
496
- const until = Math.min(Date.now() + (entry.maxDurationMs ?? DEFAULT_JOB_WAIT_MS), deps.waitDeadline?.() ?? Infinity);
549
+ const waitMs = Math.min(entry.maxDurationMs ?? Infinity, jobWaitOf(deps));
550
+ const until = Math.min(Date.now() + waitMs, deps.waitDeadline?.() ?? Infinity);
497
551
  const timeoutMs = until - Date.now();
498
552
  if (timeoutMs <= 0)
499
553
  return 'running';
@@ -508,6 +562,11 @@ async function awaitOutcome(entry, deps, requestId, ctx) {
508
562
  return 'running';
509
563
  return final;
510
564
  }
565
+ /** The call's wait for a started action's outcome. */
566
+ export function jobWaitOf(deps) {
567
+ const ms = deps.jobWaitMs;
568
+ return typeof ms === 'number' && Number.isFinite(ms) && ms >= 0 ? ms : DEFAULT_JOB_WAIT_MS;
569
+ }
511
570
  function stillRunningNote(entry) {
512
571
  return (`"${entry.id}" started and has not finished yet, so it is not done: tell the person it is still running, ` +
513
572
  'never that it is done. Its status and result appear in the page state when it finishes.');