@ouispec/agent-worker 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approvals/continuation.d.ts +14 -1
- package/dist/approvals/continuation.d.ts.map +1 -1
- package/dist/approvals/continuation.js +12 -2
- package/dist/approvals/continuation.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +383 -128
- package/dist/orchestrator.js.map +1 -1
- package/dist/prompt/clock.d.ts +34 -0
- package/dist/prompt/clock.d.ts.map +1 -0
- package/dist/prompt/clock.js +63 -0
- package/dist/prompt/clock.js.map +1 -0
- package/dist/prompt/rules/ui-control.d.ts +3 -3
- package/dist/prompt/rules/ui-control.d.ts.map +1 -1
- package/dist/prompt/rules/ui-control.js +45 -22
- package/dist/prompt/rules/ui-control.js.map +1 -1
- package/dist/runtime/turn-runner.d.ts.map +1 -1
- package/dist/runtime/turn-runner.js +3 -1
- package/dist/runtime/turn-runner.js.map +1 -1
- package/dist/runtime/types.d.ts +5 -3
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/tools/builtin-tools.js +11 -4
- package/dist/tools/builtin-tools.js.map +1 -1
- package/dist/tools/types.d.ts +17 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/turn-ledger.d.ts +30 -0
- package/dist/turn-ledger.d.ts.map +1 -0
- package/dist/turn-ledger.js +45 -0
- package/dist/turn-ledger.js.map +1 -0
- package/dist/types.d.ts +9 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/answer-image.d.ts +32 -0
- package/dist/ui/answer-image.d.ts.map +1 -0
- package/dist/ui/answer-image.js +50 -0
- package/dist/ui/answer-image.js.map +1 -0
- package/dist/ui/observations.d.ts +29 -5
- package/dist/ui/observations.d.ts.map +1 -1
- package/dist/ui/observations.js +122 -46
- package/dist/ui/observations.js.map +1 -1
- package/dist/ui/outline.d.ts +49 -0
- package/dist/ui/outline.d.ts.map +1 -0
- package/dist/ui/outline.js +229 -0
- package/dist/ui/outline.js.map +1 -0
- package/dist/ui/page-index.d.ts +74 -0
- package/dist/ui/page-index.d.ts.map +1 -0
- package/dist/ui/page-index.js +137 -0
- package/dist/ui/page-index.js.map +1 -0
- package/dist/ui/snapshot.d.ts +24 -12
- package/dist/ui/snapshot.d.ts.map +1 -1
- package/dist/ui/snapshot.js +34 -39
- package/dist/ui/snapshot.js.map +1 -1
- package/dist/ui/ui-sequence.d.ts +9 -9
- package/dist/ui/ui-sequence.d.ts.map +1 -1
- package/dist/ui/ui-sequence.js +2 -2
- package/dist/ui/ui-sequence.js.map +1 -1
- package/dist/ui/ui-tools.d.ts +64 -14
- package/dist/ui/ui-tools.d.ts.map +1 -1
- package/dist/ui/ui-tools.js +466 -92
- package/dist/ui/ui-tools.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-tools.js","sourceRoot":"","sources":["../../src/tools/builtin-tools.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,oBAAoB,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO;QACL;YACE,IAAI,EAAE,iBAAiB;YACvB,WAAW,EACT,uLAAuL;YACzL,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"builtin-tools.js","sourceRoot":"","sources":["../../src/tools/builtin-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -27,6 +27,14 @@ export interface RegisteredTool {
|
|
|
27
27
|
destructive?: boolean;
|
|
28
28
|
description: string;
|
|
29
29
|
inputSchema: Record<string, unknown>;
|
|
30
|
+
/**
|
|
31
|
+
* The schema a call's input is checked against, when it is not known until
|
|
32
|
+
* the tool is used: a UI action's definition is fetched from the page then
|
|
33
|
+
* (ADR-0245 §2.1). Called once per call, before validation; `inputSchema`
|
|
34
|
+
* only stands in for it. A rejection is told to the model as the reason the
|
|
35
|
+
* call did not run.
|
|
36
|
+
*/
|
|
37
|
+
resolveInputSchema?: (ctx: ToolExecutionContext) => Promise<Record<string, unknown>>;
|
|
30
38
|
execute: (input: Record<string, unknown>, ctx: ToolExecutionContext) => Promise<ToolExecutionResult>;
|
|
31
39
|
/** Its name as a person reads it, for the approval card. Default: `name`. */
|
|
32
40
|
title?: string;
|
|
@@ -73,6 +81,15 @@ export interface ToolExecutionResult {
|
|
|
73
81
|
success: boolean;
|
|
74
82
|
data?: unknown;
|
|
75
83
|
error?: string;
|
|
84
|
+
/**
|
|
85
|
+
* A picture the model is given beside the result's text, as an image part
|
|
86
|
+
* of the tool result. It is given once and stored nowhere: `data` says what
|
|
87
|
+
* the picture is.
|
|
88
|
+
*/
|
|
89
|
+
image?: {
|
|
90
|
+
mediaType: string;
|
|
91
|
+
base64: string;
|
|
92
|
+
};
|
|
76
93
|
}
|
|
77
94
|
export interface ToolRegistry {
|
|
78
95
|
tools: RegisteredTool[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;;GAGG;AAEH;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC;AAEtC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrG,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,0FAA0F;IAC1F,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;;GAGG;AAEH;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC;AAEtC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrG,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,0FAA0F;IAC1F,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAChH;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,YAAY,CAiBxE"}
|
package/dist/tools/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAqGA;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAuB;IACxD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,OAAO;QACL,KAAK;QACL,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,KAA8B,EAAE,GAAyB;YACnF,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YACrF,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn's own record of what its calls did (ADR-0244 §2.5).
|
|
3
|
+
*
|
|
4
|
+
* A model writes its closing message from memory of a long turn, and a
|
|
5
|
+
* failure a dozen steps back is easy to pass over: on 2026-10-02 the
|
|
6
|
+
* assistant asked for a 2-second duration, got 5, and told the person 5 was
|
|
7
|
+
* better; it reported five layers centred when two had not moved. The worker
|
|
8
|
+
* knows what each call returned, so before every step after one did not
|
|
9
|
+
* succeed it says so again, in one place, and the reply is held to it.
|
|
10
|
+
*
|
|
11
|
+
* Nothing is added while every call has succeeded: the record costs nothing
|
|
12
|
+
* on a turn that went well.
|
|
13
|
+
*/
|
|
14
|
+
/** One call of the turn. */
|
|
15
|
+
export interface LedgerEntry {
|
|
16
|
+
tool: string;
|
|
17
|
+
ok: boolean;
|
|
18
|
+
/** Why it did not succeed, or did not run, in the words the model was given. */
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TurnLedger {
|
|
22
|
+
record(entry: LedgerEntry): void;
|
|
23
|
+
entries(): readonly LedgerEntry[];
|
|
24
|
+
/** The note for the next step, or null while every call has succeeded. */
|
|
25
|
+
note(): string | null;
|
|
26
|
+
}
|
|
27
|
+
export declare function createTurnLedger(): TurnLedger;
|
|
28
|
+
/** What the model is told about the turn so far, when any call did not succeed. */
|
|
29
|
+
export declare function ledgerNote(calls: readonly LedgerEntry[]): string | null;
|
|
30
|
+
//# sourceMappingURL=turn-ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-ledger.d.ts","sourceRoot":"","sources":["../src/turn-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,4BAA4B;AAC5B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,OAAO,IAAI,SAAS,WAAW,EAAE,CAAC;IAClC,0EAA0E;IAC1E,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;CACvB;AASD,wBAAgB,gBAAgB,IAAI,UAAU,CAO7C;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAiBvE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn's own record of what its calls did (ADR-0244 §2.5).
|
|
3
|
+
*
|
|
4
|
+
* A model writes its closing message from memory of a long turn, and a
|
|
5
|
+
* failure a dozen steps back is easy to pass over: on 2026-10-02 the
|
|
6
|
+
* assistant asked for a 2-second duration, got 5, and told the person 5 was
|
|
7
|
+
* better; it reported five layers centred when two had not moved. The worker
|
|
8
|
+
* knows what each call returned, so before every step after one did not
|
|
9
|
+
* succeed it says so again, in one place, and the reply is held to it.
|
|
10
|
+
*
|
|
11
|
+
* Nothing is added while every call has succeeded: the record costs nothing
|
|
12
|
+
* on a turn that went well.
|
|
13
|
+
*/
|
|
14
|
+
/** How much of each failure's reason the note repeats. */
|
|
15
|
+
const MAX_REASON_CHARS = 240;
|
|
16
|
+
/** How many failures the note lists one by one; the rest are counted. */
|
|
17
|
+
const MAX_LISTED = 12;
|
|
18
|
+
const clip = (text) => (text.length > MAX_REASON_CHARS ? `${text.slice(0, MAX_REASON_CHARS)}…` : text);
|
|
19
|
+
export function createTurnLedger() {
|
|
20
|
+
const calls = [];
|
|
21
|
+
return {
|
|
22
|
+
record: (entry) => void calls.push(entry),
|
|
23
|
+
entries: () => calls,
|
|
24
|
+
note: () => ledgerNote(calls),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** What the model is told about the turn so far, when any call did not succeed. */
|
|
28
|
+
export function ledgerNote(calls) {
|
|
29
|
+
const failed = calls.filter((c) => !c.ok);
|
|
30
|
+
if (failed.length === 0)
|
|
31
|
+
return null;
|
|
32
|
+
const listed = failed
|
|
33
|
+
.slice(0, MAX_LISTED)
|
|
34
|
+
.map((c) => `- ${c.tool}: ${clip(c.error ?? 'did not succeed')}`)
|
|
35
|
+
.join('\n');
|
|
36
|
+
const more = failed.length > MAX_LISTED ? `\n- … and ${failed.length - MAX_LISTED} more` : '';
|
|
37
|
+
return (`<turn_record>\n` +
|
|
38
|
+
`This turn has made ${calls.length} call${calls.length === 1 ? '' : 's'}; ${failed.length} did not succeed:\n` +
|
|
39
|
+
`${listed}${more}\n` +
|
|
40
|
+
`What you tell the person must match this record. For each of these, either it has since been done by a later call ` +
|
|
41
|
+
`that succeeded, or your reply says it was not done and why. Never describe a call that did not succeed as done, ` +
|
|
42
|
+
`and never present what you got in place of what was asked as if it were what was asked.\n` +
|
|
43
|
+
`</turn_record>`);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=turn-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-ledger.js","sourceRoot":"","sources":["../src/turn-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH,0DAA0D;AAC1D,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,yEAAyE;AACzE,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE/G,MAAM,UAAU,gBAAgB;IAC9B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QACzC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;QACpB,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,KAA6B;IACtD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM;SAClB,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;SACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,iBAAiB,CAAC,EAAE,CAAC;SAChE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,MAAM,GAAG,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,OAAO,CACL,iBAAiB;QACjB,sBAAsB,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,MAAM,qBAAqB;QAC9G,GAAG,MAAM,GAAG,IAAI,IAAI;QACpB,oHAAoH;QACpH,kHAAkH;QAClH,2FAA2F;QAC3F,gBAAgB,CACjB,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -29,7 +29,12 @@ export interface AgentWorkerConfig {
|
|
|
29
29
|
promptCacheBreakpoint?: ProviderOptions;
|
|
30
30
|
maxToolRounds?: number;
|
|
31
31
|
maxTokens?: number;
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* The sampling temperature. Default 0.3. `null` sends none: for a model that
|
|
34
|
+
* does not take one (Claude Sonnet 5.5 on Bedrock refuses a request that
|
|
35
|
+
* names it), the model's own sampling is used.
|
|
36
|
+
*/
|
|
37
|
+
temperature?: number | null;
|
|
33
38
|
toolTimeoutMs?: number;
|
|
34
39
|
turnDeadlineMs?: number;
|
|
35
40
|
retries?: number;
|
|
@@ -56,8 +61,10 @@ export interface AgentWorkerConfig {
|
|
|
56
61
|
channel: UIActionChannel;
|
|
57
62
|
/** How long a UI tool waits for the client's answer. Default 20 s. */
|
|
58
63
|
resultTimeoutMs?: number;
|
|
59
|
-
/** Largest page-state payload given to the model, in characters. Default
|
|
64
|
+
/** Largest page-state payload given to the model, in characters. Default 12000 (`DEFAULT_PAGE_STATE_CHARS`). */
|
|
60
65
|
maxObservationChars?: number;
|
|
66
|
+
/** Largest index of the page's actions given to the model, in characters. Default 60000 (`DEFAULT_INDEX_CHARS`). */
|
|
67
|
+
maxIndexChars?: number;
|
|
61
68
|
};
|
|
62
69
|
}
|
|
63
70
|
export interface SystemPromptContext {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -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,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A picture in an action's answer (ADR-0244 §2.2, ADR-0245 §2.4).
|
|
3
|
+
*
|
|
4
|
+
* A room can answer a read with what it draws: `data.image`, an encoded
|
|
5
|
+
* picture. As JSON text its base64 would cost the model hundreds of thousands
|
|
6
|
+
* of characters and show it nothing, so the worker lifts it out: the model is
|
|
7
|
+
* given the picture itself as an image part of the tool result, and the text
|
|
8
|
+
* keeps only what the picture is (its type and size). The base64 is given to
|
|
9
|
+
* the model once and kept nowhere: the socket event, the turn's record and the
|
|
10
|
+
* stored tool result carry the text.
|
|
11
|
+
*/
|
|
12
|
+
/** The picture types a model is given. */
|
|
13
|
+
export declare const ANSWER_IMAGE_MEDIA_TYPES: readonly ["image/png", "image/jpeg", "image/webp"];
|
|
14
|
+
/** The longest base64 a picture may be, in characters (256 KB): past it the picture is left out, and said so. */
|
|
15
|
+
export declare const MAX_ANSWER_IMAGE_BASE64_CHARS: number;
|
|
16
|
+
/** A picture for the model: its type and its bytes in base64. */
|
|
17
|
+
export interface AnswerImage {
|
|
18
|
+
mediaType: (typeof ANSWER_IMAGE_MEDIA_TYPES)[number];
|
|
19
|
+
base64: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* `data` with its picture lifted out: `data.image` keeps its type and size,
|
|
23
|
+
* and the picture is returned beside it. Only `data.image` in the shape
|
|
24
|
+
* `{ mediaType, base64, width, height }` is a picture; anything else is left
|
|
25
|
+
* as it is. A picture of a type the model is not given, or past the size, is
|
|
26
|
+
* left out of both, and `data.image.leftOut` says why.
|
|
27
|
+
*/
|
|
28
|
+
export declare function liftAnswerImage(data: unknown): {
|
|
29
|
+
data: unknown;
|
|
30
|
+
image?: AnswerImage;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=answer-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answer-image.d.ts","sourceRoot":"","sources":["../../src/ui/answer-image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0CAA0C;AAC1C,eAAO,MAAM,wBAAwB,oDAAqD,CAAC;AAC3F,iHAAiH;AACjH,eAAO,MAAM,6BAA6B,QAAa,CAAC;AAExD,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,CAuBrF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A picture in an action's answer (ADR-0244 §2.2, ADR-0245 §2.4).
|
|
3
|
+
*
|
|
4
|
+
* A room can answer a read with what it draws: `data.image`, an encoded
|
|
5
|
+
* picture. As JSON text its base64 would cost the model hundreds of thousands
|
|
6
|
+
* of characters and show it nothing, so the worker lifts it out: the model is
|
|
7
|
+
* given the picture itself as an image part of the tool result, and the text
|
|
8
|
+
* keeps only what the picture is (its type and size). The base64 is given to
|
|
9
|
+
* the model once and kept nowhere: the socket event, the turn's record and the
|
|
10
|
+
* stored tool result carry the text.
|
|
11
|
+
*/
|
|
12
|
+
/** The picture types a model is given. */
|
|
13
|
+
export const ANSWER_IMAGE_MEDIA_TYPES = ['image/png', 'image/jpeg', 'image/webp'];
|
|
14
|
+
/** The longest base64 a picture may be, in characters (256 KB): past it the picture is left out, and said so. */
|
|
15
|
+
export const MAX_ANSWER_IMAGE_BASE64_CHARS = 256 * 1024;
|
|
16
|
+
const isRecord = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
17
|
+
const BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
18
|
+
/**
|
|
19
|
+
* `data` with its picture lifted out: `data.image` keeps its type and size,
|
|
20
|
+
* and the picture is returned beside it. Only `data.image` in the shape
|
|
21
|
+
* `{ mediaType, base64, width, height }` is a picture; anything else is left
|
|
22
|
+
* as it is. A picture of a type the model is not given, or past the size, is
|
|
23
|
+
* left out of both, and `data.image.leftOut` says why.
|
|
24
|
+
*/
|
|
25
|
+
export function liftAnswerImage(data) {
|
|
26
|
+
if (!isRecord(data) || !isRecord(data.image))
|
|
27
|
+
return { data };
|
|
28
|
+
const { mediaType, base64, ...rest } = data.image;
|
|
29
|
+
if (typeof mediaType !== 'string' || typeof base64 !== 'string')
|
|
30
|
+
return { data };
|
|
31
|
+
const described = (extra = {}) => ({ ...data, image: { ...rest, mediaType, ...extra } });
|
|
32
|
+
if (!ANSWER_IMAGE_MEDIA_TYPES.includes(mediaType)) {
|
|
33
|
+
return { data: described({ leftOut: `a picture of type ${mediaType} cannot be shown to you; ${ANSWER_IMAGE_MEDIA_TYPES.join(', ')} can` }) };
|
|
34
|
+
}
|
|
35
|
+
if (base64.length > MAX_ANSWER_IMAGE_BASE64_CHARS) {
|
|
36
|
+
return {
|
|
37
|
+
data: described({
|
|
38
|
+
leftOut: `the picture is ${base64.length} characters of base64; one of at most ${MAX_ANSWER_IMAGE_BASE64_CHARS} can be shown to you. Ask for it smaller if the action takes a size.`,
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (base64.length === 0 || !BASE64.test(base64)) {
|
|
43
|
+
return { data: described({ leftOut: 'the picture was not valid base64' }) };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
data: described({ shown: 'The picture is attached to this result: look at it.' }),
|
|
47
|
+
image: { mediaType: mediaType, base64 },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=answer-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answer-image.js","sourceRoot":"","sources":["../../src/ui/answer-image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,YAAY,CAAU,CAAC;AAC3F,iHAAiH;AACjH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,GAAG,IAAI,CAAC;AAQxD,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrI,MAAM,MAAM,GAAG,wBAAwB,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9D,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;IAClD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAEjF,MAAM,SAAS,GAAG,CAAC,QAAiC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC;IAClH,IAAI,CAAE,wBAA8C,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACzE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,qBAAqB,SAAS,4BAA4B,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IAC/I,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAClD,OAAO;YACL,IAAI,EAAE,SAAS,CAAC;gBACd,OAAO,EAAE,kBAAkB,MAAM,CAAC,MAAM,yCAAyC,6BAA6B,sEAAsE;aACrL,CAAC;SACH,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,qDAAqD,EAAE,CAAC;QACjF,KAAK,EAAE,EAAE,SAAS,EAAE,SAAqC,EAAE,MAAM,EAAE;KACpE,CAAC;AACJ,CAAC"}
|
|
@@ -22,20 +22,44 @@ export declare function surfaceProblems(observations: OUIObservationSnapshot): R
|
|
|
22
22
|
* they must reach it whatever else the page reports.
|
|
23
23
|
*/
|
|
24
24
|
export declare function jobStatuses(observations: OUIObservationSnapshot): Record<string, Record<string, unknown>> | null;
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* The largest page state the model is given when the host sets none
|
|
27
|
+
* (`ui.maxObservationChars`): the user's message's, and each UI action's
|
|
28
|
+
* answer's. About 3,000 tokens: room for a document of a hundred rows as index
|
|
29
|
+
* rows with the few being worked on whole (ADR-0244 §2.1). It was 6,000, which
|
|
30
|
+
* a board of six artboards filled.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_PAGE_STATE_CHARS = 12000;
|
|
33
|
+
/** Rows past this in any list are given as index rows at the first step of fitting an over-budget page state. */
|
|
26
34
|
export declare const MAX_LIST_ROWS = 20;
|
|
27
35
|
/**
|
|
28
36
|
* A list this short is never shortened: it is a field's choices (the engines a
|
|
29
37
|
* voice can speak with, a document's types), not a collection to browse.
|
|
30
38
|
*/
|
|
31
39
|
export declare const WHOLE_LIST_ROWS = 5;
|
|
40
|
+
/** Each surface's observation schemas, by surface id then observation id: where the row lists are declared. */
|
|
41
|
+
export type ObservationSchemas = Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
42
|
+
/** The observation schemas of a turn's surfaces, for fitting their page state. */
|
|
43
|
+
export declare function observationSchemas(surfaces: readonly {
|
|
44
|
+
id: string;
|
|
45
|
+
observations?: readonly {
|
|
46
|
+
id: string;
|
|
47
|
+
schema?: unknown;
|
|
48
|
+
}[];
|
|
49
|
+
}[]): ObservationSchemas;
|
|
50
|
+
/** What fitting reads beside the observations: where the row lists are declared, and the rows an action just changed. */
|
|
51
|
+
export interface FitOptions {
|
|
52
|
+
schemas?: ObservationSchemas;
|
|
53
|
+
/** Refs of the rows the answered action changed: kept whole, like the selection. */
|
|
54
|
+
changed?: readonly string[];
|
|
55
|
+
}
|
|
32
56
|
/**
|
|
33
57
|
* The observations as the model receives them: whole when they fit. Over
|
|
34
58
|
* budget, every surface's problems and job statuses are kept whole; the rest is
|
|
35
|
-
* fitted (see fitted): long lists
|
|
36
|
-
* and kept whole, and only if that still does not fit is the rest cut, saying so.
|
|
59
|
+
* fitted (see fitted): long lists cut to index rows first, the page it acted on
|
|
60
|
+
* first and kept whole, and only if that still does not fit is the rest cut, saying so.
|
|
37
61
|
*/
|
|
38
|
-
export declare function boundObservations(observations: OUIObservationSnapshot, maxChars: number, actingSurfaceId?: string): unknown;
|
|
62
|
+
export declare function boundObservations(observations: OUIObservationSnapshot, maxChars: number, actingSurfaceId?: string, options?: FitOptions): unknown;
|
|
39
63
|
/** The same, as the text of a `<page_state>` block. */
|
|
40
|
-
export declare function observationsText(observations: OUIObservationSnapshot, maxChars: number): string;
|
|
64
|
+
export declare function observationsText(observations: OUIObservationSnapshot, maxChars: number, options?: FitOptions): string;
|
|
41
65
|
//# sourceMappingURL=observations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/ui/observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAShH;AAgBD,
|
|
1
|
+
{"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/ui/observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAElD,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CASpG;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAShH;AAgBD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,iHAAiH;AACjH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AA6DjC,+GAA+G;AAC/G,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7F,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAAE,EAAE,GAC9F,kBAAkB,CAIpB;AAsID,yHAAyH;AACzH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,oFAAoF;IACpF,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAuFD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EACpC,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,GAAE,UAAe,GACvB,OAAO,CAcT;AAED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CAczH"}
|
package/dist/ui/observations.js
CHANGED
|
@@ -48,15 +48,31 @@ function withoutKeptWhole(observations) {
|
|
|
48
48
|
Object.fromEntries(Object.entries(values ?? {}).filter(([id]) => id !== PROBLEMS_OBSERVATION_ID && !isJobStatus(id))),
|
|
49
49
|
]));
|
|
50
50
|
}
|
|
51
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* The largest page state the model is given when the host sets none
|
|
53
|
+
* (`ui.maxObservationChars`): the user's message's, and each UI action's
|
|
54
|
+
* answer's. About 3,000 tokens: room for a document of a hundred rows as index
|
|
55
|
+
* rows with the few being worked on whole (ADR-0244 §2.1). It was 6,000, which
|
|
56
|
+
* a board of six artboards filled.
|
|
57
|
+
*/
|
|
58
|
+
export const DEFAULT_PAGE_STATE_CHARS = 12_000;
|
|
59
|
+
/** Rows past this in any list are given as index rows at the first step of fitting an over-budget page state. */
|
|
52
60
|
export const MAX_LIST_ROWS = 20;
|
|
53
61
|
/**
|
|
54
62
|
* A list this short is never shortened: it is a field's choices (the engines a
|
|
55
63
|
* voice can speak with, a document's types), not a collection to browse.
|
|
56
64
|
*/
|
|
57
65
|
export const WHOLE_LIST_ROWS = 5;
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const LIST_STEPS = [
|
|
67
|
+
{ whole: MAX_LIST_ROWS, index: Infinity },
|
|
68
|
+
{ whole: 10, index: Infinity },
|
|
69
|
+
{ whole: WHOLE_LIST_ROWS, index: Infinity },
|
|
70
|
+
{ whole: 0, index: Infinity },
|
|
71
|
+
{ whole: 0, index: 100 },
|
|
72
|
+
{ whole: 0, index: 40 },
|
|
73
|
+
{ whole: 0, index: 12 },
|
|
74
|
+
{ whole: 0, index: 0 },
|
|
75
|
+
];
|
|
60
76
|
/**
|
|
61
77
|
* What a page state reports that is never shortened: its fields, what is
|
|
62
78
|
* unavailable or busy, and a row's own schema (its options or range).
|
|
@@ -80,27 +96,64 @@ function surfaceRank(surfaceId, acting) {
|
|
|
80
96
|
return 4;
|
|
81
97
|
return 3;
|
|
82
98
|
}
|
|
99
|
+
/** The observation schemas of a turn's surfaces, for fitting their page state. */
|
|
100
|
+
export function observationSchemas(surfaces) {
|
|
101
|
+
return Object.fromEntries(surfaces.map((s) => [s.id, Object.fromEntries((s.observations ?? []).map((o) => [o.id, o.schema]))]));
|
|
102
|
+
}
|
|
103
|
+
/** A page list's row (oui-bindings `PageStateRow`): addressed by its key, called by its title, chosen when its value is true. */
|
|
104
|
+
const PAGE_ROW = {
|
|
105
|
+
index: (row) => ({ key: row.key, title: row.title }),
|
|
106
|
+
chosen: (row) => row !== null && typeof row === 'object' && row.value === true,
|
|
107
|
+
rest: 'name a row by its title',
|
|
108
|
+
};
|
|
109
|
+
const isPageRow = (row) => row !== null &&
|
|
110
|
+
typeof row === 'object' &&
|
|
111
|
+
typeof row.key === 'string' &&
|
|
112
|
+
typeof row.title === 'string';
|
|
113
|
+
/** A declared list's rows: addressed and called by the properties it names, chosen when selected or just changed. */
|
|
114
|
+
function declaredShape(declaration, chosenRefs) {
|
|
115
|
+
const kept = [declaration.ref, declaration.title, ...(declaration.index ?? [])];
|
|
116
|
+
return {
|
|
117
|
+
index: (row) => Object.fromEntries(kept.filter((key) => row[key] !== undefined).map((key) => [key, row[key]])),
|
|
118
|
+
chosen: (row) => row !== null && typeof row === 'object' && chosenRefs.has(String(row[declaration.ref])),
|
|
119
|
+
rest: 'read them with this surface’s query tool, or one with its inspect tool',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
83
122
|
/** A row the person has chosen (a selected card, the variant in use): kept however short its list gets. */
|
|
84
|
-
const
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
|
|
123
|
+
const isChosenValue = PAGE_ROW.chosen;
|
|
124
|
+
/**
|
|
125
|
+
* A list fitted to a step: the first `whole` rows and the chosen ones whole,
|
|
126
|
+
* up to `index` of the rest as index rows, and how many are left out with how
|
|
127
|
+
* to read them. A list whose rows cannot be indexed keeps only how many more
|
|
128
|
+
* there are.
|
|
129
|
+
*/
|
|
130
|
+
function shortenRows(rows, step, shape) {
|
|
131
|
+
if (rows.length <= Math.max(step.whole, WHOLE_LIST_ROWS))
|
|
88
132
|
return rows;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
133
|
+
const chosen = shape?.chosen ?? isChosenValue;
|
|
134
|
+
const whole = [];
|
|
135
|
+
const rest = [];
|
|
136
|
+
rows.forEach((row, i) => (i < step.whole || chosen(row) ? whole : rest).push(row));
|
|
137
|
+
if (!shape) {
|
|
138
|
+
if (step.whole === 0) {
|
|
139
|
+
const count = `${rest.length}${whole.length ? ' more' : ''} rows`;
|
|
140
|
+
return [...whole, `${count}, not listed to fit the page state; name a row by its title`];
|
|
141
|
+
}
|
|
142
|
+
return [...whole, `… and ${rest.length} more`];
|
|
93
143
|
}
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
144
|
+
const indexed = rest.slice(0, step.index).map((row) => shape.index(row));
|
|
145
|
+
const left = rest.length - indexed.length;
|
|
146
|
+
if (left === 0)
|
|
147
|
+
return [...whole, ...indexed];
|
|
148
|
+
const count = whole.length + indexed.length > 0 ? `… and ${left} more rows` : `${left} rows`;
|
|
149
|
+
return [...whole, ...indexed, `${count}, not listed to fit the page state; ${shape.rest}`];
|
|
97
150
|
}
|
|
98
151
|
/**
|
|
99
152
|
* What the page shows (`shown`): facts that describe one row of a list (one per
|
|
100
153
|
* card) are shortened like the list; the page's own facts, such as those of the
|
|
101
154
|
* item open in a detail panel, are kept whole.
|
|
102
155
|
*/
|
|
103
|
-
function shortenShown(shown,
|
|
156
|
+
function shortenShown(shown, step) {
|
|
104
157
|
const perList = new Map();
|
|
105
158
|
const own = [];
|
|
106
159
|
for (const entry of shown) {
|
|
@@ -112,24 +165,37 @@ function shortenShown(shown, limit) {
|
|
|
112
165
|
perList.set(id, [...(perList.get(id) ?? []), entry]);
|
|
113
166
|
}
|
|
114
167
|
}
|
|
115
|
-
return [...own, ...[...perList.values()].flatMap((rows) => shortenRows(rows,
|
|
168
|
+
return [...own, ...[...perList.values()].flatMap((rows) => shortenRows(rows, { whole: step.whole, index: 0 }, null))];
|
|
169
|
+
}
|
|
170
|
+
/** How a list's rows are indexed: as its schema declares, as a page list's rows are, or not at all. */
|
|
171
|
+
function shapeOf(rows, schema, selected, ctx) {
|
|
172
|
+
const declaration = schema?.['x-rows'];
|
|
173
|
+
if (declaration)
|
|
174
|
+
return declaredShape(declaration, new Set([...selected, ...ctx.changed]));
|
|
175
|
+
return rows.length > 0 && rows.every(isPageRow) ? PAGE_ROW : null;
|
|
116
176
|
}
|
|
117
177
|
/**
|
|
118
|
-
* The value with every long list
|
|
178
|
+
* The value with every long list fitted to the step (see shortenRows); fields,
|
|
119
179
|
* what is unavailable or busy, and the page's own facts are left whole.
|
|
120
180
|
*/
|
|
121
|
-
function compactValue(value,
|
|
181
|
+
function compactValue(value, schema, ctx, selected = []) {
|
|
122
182
|
if (Array.isArray(value)) {
|
|
123
|
-
const
|
|
124
|
-
|
|
183
|
+
const shape = shapeOf(value, schema, selected, ctx);
|
|
184
|
+
// A row kept whole has its own lists fitted; a row cut to its index does not need them.
|
|
185
|
+
const given = new Set(value);
|
|
186
|
+
return shortenRows(value, ctx.step, shape).map((row) => (given.has(row) ? compactValue(row, schema?.items, ctx) : row));
|
|
125
187
|
}
|
|
126
188
|
if (value !== null && typeof value === 'object') {
|
|
127
|
-
|
|
189
|
+
const object = value;
|
|
190
|
+
return Object.fromEntries(Object.entries(object).map(([key, v]) => {
|
|
128
191
|
if (FIELD_KEYS.has(key))
|
|
129
192
|
return [key, v];
|
|
130
193
|
if (key === 'shown' && Array.isArray(v))
|
|
131
|
-
return [key, shortenShown(v,
|
|
132
|
-
|
|
194
|
+
return [key, shortenShown(v, ctx.step)];
|
|
195
|
+
const child = schema?.properties?.[key];
|
|
196
|
+
const selection = child?.['x-rows']?.selection;
|
|
197
|
+
const chosen = selection && Array.isArray(object[selection]) ? object[selection].map(String) : [];
|
|
198
|
+
return [key, compactValue(v, child, ctx, chosen)];
|
|
133
199
|
}));
|
|
134
200
|
}
|
|
135
201
|
return value;
|
|
@@ -137,28 +203,35 @@ function compactValue(value, limit) {
|
|
|
137
203
|
const size = (value) => JSON.stringify(value).length;
|
|
138
204
|
/**
|
|
139
205
|
* 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
|
|
141
|
-
* rows, 10, 5, then
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
206
|
+
* first. The surfaces are ordered by rank. Then long lists are shortened: 20
|
|
207
|
+
* rows kept whole, then 10, 5, then none, the rest cut to index rows (what
|
|
208
|
+
* each is addressed and called by); then the index itself, to 100 rows, 40, 12
|
|
209
|
+
* and none, saying how the rest are read. Every other surface is a step ahead of
|
|
210
|
+
* the surface the action acted on. Lists of five rows or fewer, every field,
|
|
211
|
+
* what is unavailable or busy, the page's own facts and chosen rows are never
|
|
212
|
+
* shortened, so the item open in a detail panel and the layer just changed
|
|
213
|
+
* stay whole beside a long list. Then whole surfaces are left out, the shells
|
|
214
|
+
* first, never the acting one. Only if that still does not fit is the rest cut.
|
|
147
215
|
*/
|
|
148
|
-
function fitted(observations, maxChars, acting) {
|
|
216
|
+
function fitted(observations, maxChars, acting, options) {
|
|
149
217
|
const base = Object.fromEntries(Object.entries(withoutKeptWhole(observations)).sort(([a], [b]) => surfaceRank(a, acting) - surfaceRank(b, acting)));
|
|
150
218
|
const actingPresent = acting !== undefined && acting in base;
|
|
151
|
-
|
|
219
|
+
const changed = new Set(options.changed ?? []);
|
|
220
|
+
// Each step is (others' step, the acting surface's step): the acting one lags a step behind.
|
|
152
221
|
const steps = [];
|
|
153
|
-
LIST_STEPS.forEach((
|
|
222
|
+
LIST_STEPS.forEach((step, i) => {
|
|
154
223
|
if (actingPresent && i > 0)
|
|
155
|
-
steps.push([
|
|
156
|
-
steps.push([
|
|
224
|
+
steps.push([step, LIST_STEPS[i - 1]]);
|
|
225
|
+
steps.push([step, step]);
|
|
157
226
|
});
|
|
227
|
+
const fit = (surfaceId, value, step) => Object.fromEntries(Object.entries((value ?? {})).map(([observationId, v]) => [
|
|
228
|
+
observationId,
|
|
229
|
+
compactValue(v, options.schemas?.[surfaceId]?.[observationId], { step, changed }),
|
|
230
|
+
]));
|
|
158
231
|
let values = base;
|
|
159
232
|
let listStep;
|
|
160
233
|
for (const [others, own] of steps) {
|
|
161
|
-
values = Object.fromEntries(Object.entries(base).map(([id, v]) => [id,
|
|
234
|
+
values = Object.fromEntries(Object.entries(base).map(([id, v]) => [id, fit(id, v, id === acting ? own : others)]));
|
|
162
235
|
listStep = others;
|
|
163
236
|
if (size(values) <= maxChars)
|
|
164
237
|
return { values, listStep, omitted: [], fits: true };
|
|
@@ -179,11 +252,14 @@ function fitted(observations, maxChars, acting) {
|
|
|
179
252
|
}
|
|
180
253
|
/** What fitting did, in words. */
|
|
181
254
|
function fitSummary(fit, maxChars, whole, acted) {
|
|
182
|
-
const
|
|
255
|
+
const step = fit.listStep;
|
|
256
|
+
const lists = step === undefined
|
|
183
257
|
? ''
|
|
184
|
-
:
|
|
185
|
-
? `lists
|
|
186
|
-
:
|
|
258
|
+
: step.whole > 0
|
|
259
|
+
? `long lists keep their first ${Math.max(step.whole, WHOLE_LIST_ROWS)} rows whole and the rest as index rows (what each is addressed and called by)`
|
|
260
|
+
: step.index > 0
|
|
261
|
+
? `rows of lists longer than ${WHOLE_LIST_ROWS} are given as index rows (what each is addressed and called by)${Number.isFinite(step.index) ? `, the first ${step.index} of them` : ''}`
|
|
262
|
+
: `lists longer than ${WHOLE_LIST_ROWS} rows are given as a count, with how to read them`;
|
|
187
263
|
const parts = [
|
|
188
264
|
lists,
|
|
189
265
|
'fields, the page’s own facts and chosen rows are kept whole',
|
|
@@ -198,16 +274,16 @@ function fitSummary(fit, maxChars, whole, acted) {
|
|
|
198
274
|
/**
|
|
199
275
|
* The observations as the model receives them: whole when they fit. Over
|
|
200
276
|
* budget, every surface's problems and job statuses are kept whole; the rest is
|
|
201
|
-
* fitted (see fitted): long lists
|
|
202
|
-
* and kept whole, and only if that still does not fit is the rest cut, saying so.
|
|
277
|
+
* fitted (see fitted): long lists cut to index rows first, the page it acted on
|
|
278
|
+
* first and kept whole, and only if that still does not fit is the rest cut, saying so.
|
|
203
279
|
*/
|
|
204
|
-
export function boundObservations(observations, maxChars, actingSurfaceId) {
|
|
280
|
+
export function boundObservations(observations, maxChars, actingSurfaceId, options = {}) {
|
|
205
281
|
const json = JSON.stringify(observations);
|
|
206
282
|
if (json.length <= maxChars)
|
|
207
283
|
return observations;
|
|
208
284
|
const problems = surfaceProblems(observations);
|
|
209
285
|
const jobs = jobStatuses(observations);
|
|
210
|
-
const fit = fitted(observations, maxChars, actingSurfaceId);
|
|
286
|
+
const fit = fitted(observations, maxChars, actingSurfaceId, options);
|
|
211
287
|
const whole = [problems ? 'every surface’s problems' : '', jobs ? 'every job’s status' : ''].filter(Boolean);
|
|
212
288
|
return {
|
|
213
289
|
truncated: true,
|
|
@@ -218,13 +294,13 @@ export function boundObservations(observations, maxChars, actingSurfaceId) {
|
|
|
218
294
|
};
|
|
219
295
|
}
|
|
220
296
|
/** The same, as the text of a `<page_state>` block. */
|
|
221
|
-
export function observationsText(observations, maxChars) {
|
|
297
|
+
export function observationsText(observations, maxChars, options = {}) {
|
|
222
298
|
const json = JSON.stringify(observations);
|
|
223
299
|
if (json.length <= maxChars)
|
|
224
300
|
return json;
|
|
225
301
|
const problems = surfaceProblems(observations);
|
|
226
302
|
const jobs = jobStatuses(observations);
|
|
227
|
-
const fit = fitted(observations, maxChars, undefined);
|
|
303
|
+
const fit = fitted(observations, maxChars, undefined, options);
|
|
228
304
|
const rest = JSON.stringify(fit.values);
|
|
229
305
|
const head = (problems ? `Problems (in full): ${JSON.stringify(problems)}\n` : '') +
|
|
230
306
|
(jobs ? `Jobs (in full): ${JSON.stringify(jobs)}\n` : '');
|