@sudobility/sider_types 0.0.12 → 0.0.13
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/actions.d.ts +60 -0
- package/dist/actions.js +30 -0
- package/dist/actions.test.d.ts +1 -0
- package/dist/actions.test.js +57 -0
- package/package.json +1 -1
- package/src/actions.test.ts +61 -0
- package/src/actions.ts +88 -0
package/dist/actions.d.ts
CHANGED
|
@@ -27,6 +27,66 @@ export interface ReadPageResult {
|
|
|
27
27
|
items: ExtractedItem[];
|
|
28
28
|
count: number;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Every tool the agent can call, named once.
|
|
32
|
+
*
|
|
33
|
+
* sider_api's decision endpoint produces one of these strings and the extension
|
|
34
|
+
* routes on it. Before this existed the name was retyped in four places — the
|
|
35
|
+
* panel's dispatch, two presentation tables, and the live harness — and nothing
|
|
36
|
+
* made them agree: `presentList` was emitted with no executor and answered
|
|
37
|
+
* "unknown tool" on every turn, so the agent kept retrying a run it had already
|
|
38
|
+
* done the work for.
|
|
39
|
+
*/
|
|
40
|
+
export declare const TOOL_NAMES: readonly ["readPage", "navigateTo", "siderDomAction", "callSiderTool", "attachFile", "downloadFile", "planChecklist", "presentList"];
|
|
41
|
+
export type ToolName = (typeof TOOL_NAMES)[number];
|
|
42
|
+
/** Everything `siderDomAction` can do to a page. */
|
|
43
|
+
export declare const DOM_ACTION_TYPES: readonly ["hover", "click", "type", "select", "press", "scroll", "hold"];
|
|
44
|
+
export type DomActionType = (typeof DOM_ACTION_TYPES)[number];
|
|
45
|
+
/**
|
|
46
|
+
* One act on a page.
|
|
47
|
+
*
|
|
48
|
+
* `controlName` is the currency: the site graph plans in visible labels, because
|
|
49
|
+
* a selector is regenerated per render and means nothing to another user of the
|
|
50
|
+
* site. `selector` remains for exploration, when no label identifies the target,
|
|
51
|
+
* and may carry a frame prefix (see the extension's `frame-ref.ts`).
|
|
52
|
+
*/
|
|
53
|
+
export interface DomAction {
|
|
54
|
+
type: DomActionType;
|
|
55
|
+
controlName?: string;
|
|
56
|
+
within?: string;
|
|
57
|
+
selector?: string;
|
|
58
|
+
text?: string;
|
|
59
|
+
/** For `press` — a key name, not a character. */
|
|
60
|
+
key?: string;
|
|
61
|
+
/** For `hold` — how long to hold, in milliseconds. */
|
|
62
|
+
ms?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface ReadPageArgs {
|
|
65
|
+
/** Free-text steer for extraction ("job listings", "prices"). */
|
|
66
|
+
hint?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface NavigateToArgs {
|
|
69
|
+
url: string;
|
|
70
|
+
}
|
|
71
|
+
export interface DownloadFileArgs {
|
|
72
|
+
/** May be relative — the caller resolves it against the driven tab's origin. */
|
|
73
|
+
url: string;
|
|
74
|
+
filename?: string;
|
|
75
|
+
}
|
|
76
|
+
export interface AttachFileArgs {
|
|
77
|
+
/** Which of the user's attached files to use; absent means all of them. */
|
|
78
|
+
fileNames?: string[];
|
|
79
|
+
/** Which upload field, when a form has more than one. */
|
|
80
|
+
controlName?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface CallSiderToolArgs {
|
|
83
|
+
toolId: string;
|
|
84
|
+
args?: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
export interface PlanChecklistArgs {
|
|
87
|
+
items?: unknown[];
|
|
88
|
+
budget?: string;
|
|
89
|
+
}
|
|
30
90
|
/**
|
|
31
91
|
* Icons a presented list may use.
|
|
32
92
|
*
|
package/dist/actions.js
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
// Structured results for the three model-facing browser actions (callSiderTool,
|
|
2
2
|
// readPage, siderDomAction). One shape so the agent can aggregate outcomes and
|
|
3
3
|
// report a status summary (e.g. "added 3/5; 2 pre-order only").
|
|
4
|
+
/**
|
|
5
|
+
* Every tool the agent can call, named once.
|
|
6
|
+
*
|
|
7
|
+
* sider_api's decision endpoint produces one of these strings and the extension
|
|
8
|
+
* routes on it. Before this existed the name was retyped in four places — the
|
|
9
|
+
* panel's dispatch, two presentation tables, and the live harness — and nothing
|
|
10
|
+
* made them agree: `presentList` was emitted with no executor and answered
|
|
11
|
+
* "unknown tool" on every turn, so the agent kept retrying a run it had already
|
|
12
|
+
* done the work for.
|
|
13
|
+
*/
|
|
14
|
+
export const TOOL_NAMES = [
|
|
15
|
+
"readPage",
|
|
16
|
+
"navigateTo",
|
|
17
|
+
"siderDomAction",
|
|
18
|
+
"callSiderTool",
|
|
19
|
+
"attachFile",
|
|
20
|
+
"downloadFile",
|
|
21
|
+
"planChecklist",
|
|
22
|
+
"presentList",
|
|
23
|
+
];
|
|
24
|
+
/** Everything `siderDomAction` can do to a page. */
|
|
25
|
+
export const DOM_ACTION_TYPES = [
|
|
26
|
+
"hover",
|
|
27
|
+
"click",
|
|
28
|
+
"type",
|
|
29
|
+
"select",
|
|
30
|
+
"press",
|
|
31
|
+
"scroll",
|
|
32
|
+
"hold",
|
|
33
|
+
];
|
|
4
34
|
/**
|
|
5
35
|
* Icons a presented list may use.
|
|
6
36
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
import { TOOL_NAMES, DOM_ACTION_TYPES } from "./actions";
|
|
3
|
+
// These two arrays are a WIRE CONTRACT. sider_api emits one of these names from
|
|
4
|
+
// a ShapeShyft decision endpoint and the extension routes on it; a rename on one
|
|
5
|
+
// side with no matching rename on the other is exactly how `presentList` came
|
|
6
|
+
// back "unknown tool" turn after turn, with the agent unable to end a run whose
|
|
7
|
+
// work was already done. Pinned by value so a rename cannot pass silently.
|
|
8
|
+
test("the tool name contract is exactly these eight", () => {
|
|
9
|
+
expect([...TOOL_NAMES].sort()).toEqual([
|
|
10
|
+
"attachFile",
|
|
11
|
+
"callSiderTool",
|
|
12
|
+
"downloadFile",
|
|
13
|
+
"navigateTo",
|
|
14
|
+
"planChecklist",
|
|
15
|
+
"presentList",
|
|
16
|
+
"readPage",
|
|
17
|
+
"siderDomAction",
|
|
18
|
+
]);
|
|
19
|
+
});
|
|
20
|
+
test("the dom action contract is exactly these seven", () => {
|
|
21
|
+
expect([...DOM_ACTION_TYPES].sort()).toEqual([
|
|
22
|
+
"click",
|
|
23
|
+
"hold",
|
|
24
|
+
"hover",
|
|
25
|
+
"press",
|
|
26
|
+
"scroll",
|
|
27
|
+
"select",
|
|
28
|
+
"type",
|
|
29
|
+
]);
|
|
30
|
+
});
|
|
31
|
+
// Exhaustiveness: a name added to the union but not the array (or the reverse)
|
|
32
|
+
// fails to compile here rather than at runtime in a browser.
|
|
33
|
+
test("every ToolName is present in TOOL_NAMES", () => {
|
|
34
|
+
const seen = {
|
|
35
|
+
readPage: true,
|
|
36
|
+
navigateTo: true,
|
|
37
|
+
siderDomAction: true,
|
|
38
|
+
callSiderTool: true,
|
|
39
|
+
attachFile: true,
|
|
40
|
+
downloadFile: true,
|
|
41
|
+
planChecklist: true,
|
|
42
|
+
presentList: true,
|
|
43
|
+
};
|
|
44
|
+
expect(Object.keys(seen).sort()).toEqual([...TOOL_NAMES].sort());
|
|
45
|
+
});
|
|
46
|
+
test("every DomActionType is present in DOM_ACTION_TYPES", () => {
|
|
47
|
+
const seen = {
|
|
48
|
+
hover: true,
|
|
49
|
+
click: true,
|
|
50
|
+
type: true,
|
|
51
|
+
select: true,
|
|
52
|
+
press: true,
|
|
53
|
+
scroll: true,
|
|
54
|
+
hold: true,
|
|
55
|
+
};
|
|
56
|
+
expect(Object.keys(seen).sort()).toEqual([...DOM_ACTION_TYPES].sort());
|
|
57
|
+
});
|
package/package.json
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
import { TOOL_NAMES, DOM_ACTION_TYPES, type ToolName, type DomActionType } from "./actions";
|
|
3
|
+
|
|
4
|
+
// These two arrays are a WIRE CONTRACT. sider_api emits one of these names from
|
|
5
|
+
// a ShapeShyft decision endpoint and the extension routes on it; a rename on one
|
|
6
|
+
// side with no matching rename on the other is exactly how `presentList` came
|
|
7
|
+
// back "unknown tool" turn after turn, with the agent unable to end a run whose
|
|
8
|
+
// work was already done. Pinned by value so a rename cannot pass silently.
|
|
9
|
+
test("the tool name contract is exactly these eight", () => {
|
|
10
|
+
expect([...TOOL_NAMES].sort()).toEqual([
|
|
11
|
+
"attachFile",
|
|
12
|
+
"callSiderTool",
|
|
13
|
+
"downloadFile",
|
|
14
|
+
"navigateTo",
|
|
15
|
+
"planChecklist",
|
|
16
|
+
"presentList",
|
|
17
|
+
"readPage",
|
|
18
|
+
"siderDomAction",
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("the dom action contract is exactly these seven", () => {
|
|
23
|
+
expect([...DOM_ACTION_TYPES].sort()).toEqual([
|
|
24
|
+
"click",
|
|
25
|
+
"hold",
|
|
26
|
+
"hover",
|
|
27
|
+
"press",
|
|
28
|
+
"scroll",
|
|
29
|
+
"select",
|
|
30
|
+
"type",
|
|
31
|
+
]);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Exhaustiveness: a name added to the union but not the array (or the reverse)
|
|
35
|
+
// fails to compile here rather than at runtime in a browser.
|
|
36
|
+
test("every ToolName is present in TOOL_NAMES", () => {
|
|
37
|
+
const seen: Record<ToolName, true> = {
|
|
38
|
+
readPage: true,
|
|
39
|
+
navigateTo: true,
|
|
40
|
+
siderDomAction: true,
|
|
41
|
+
callSiderTool: true,
|
|
42
|
+
attachFile: true,
|
|
43
|
+
downloadFile: true,
|
|
44
|
+
planChecklist: true,
|
|
45
|
+
presentList: true,
|
|
46
|
+
};
|
|
47
|
+
expect(Object.keys(seen).sort()).toEqual([...TOOL_NAMES].sort());
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("every DomActionType is present in DOM_ACTION_TYPES", () => {
|
|
51
|
+
const seen: Record<DomActionType, true> = {
|
|
52
|
+
hover: true,
|
|
53
|
+
click: true,
|
|
54
|
+
type: true,
|
|
55
|
+
select: true,
|
|
56
|
+
press: true,
|
|
57
|
+
scroll: true,
|
|
58
|
+
hold: true,
|
|
59
|
+
};
|
|
60
|
+
expect(Object.keys(seen).sort()).toEqual([...DOM_ACTION_TYPES].sort());
|
|
61
|
+
});
|
package/src/actions.ts
CHANGED
|
@@ -42,6 +42,94 @@ export interface ReadPageResult {
|
|
|
42
42
|
count: number;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Every tool the agent can call, named once.
|
|
47
|
+
*
|
|
48
|
+
* sider_api's decision endpoint produces one of these strings and the extension
|
|
49
|
+
* routes on it. Before this existed the name was retyped in four places — the
|
|
50
|
+
* panel's dispatch, two presentation tables, and the live harness — and nothing
|
|
51
|
+
* made them agree: `presentList` was emitted with no executor and answered
|
|
52
|
+
* "unknown tool" on every turn, so the agent kept retrying a run it had already
|
|
53
|
+
* done the work for.
|
|
54
|
+
*/
|
|
55
|
+
export const TOOL_NAMES = [
|
|
56
|
+
"readPage",
|
|
57
|
+
"navigateTo",
|
|
58
|
+
"siderDomAction",
|
|
59
|
+
"callSiderTool",
|
|
60
|
+
"attachFile",
|
|
61
|
+
"downloadFile",
|
|
62
|
+
"planChecklist",
|
|
63
|
+
"presentList",
|
|
64
|
+
] as const;
|
|
65
|
+
|
|
66
|
+
export type ToolName = (typeof TOOL_NAMES)[number];
|
|
67
|
+
|
|
68
|
+
/** Everything `siderDomAction` can do to a page. */
|
|
69
|
+
export const DOM_ACTION_TYPES = [
|
|
70
|
+
"hover",
|
|
71
|
+
"click",
|
|
72
|
+
"type",
|
|
73
|
+
"select",
|
|
74
|
+
"press",
|
|
75
|
+
"scroll",
|
|
76
|
+
"hold",
|
|
77
|
+
] as const;
|
|
78
|
+
|
|
79
|
+
export type DomActionType = (typeof DOM_ACTION_TYPES)[number];
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* One act on a page.
|
|
83
|
+
*
|
|
84
|
+
* `controlName` is the currency: the site graph plans in visible labels, because
|
|
85
|
+
* a selector is regenerated per render and means nothing to another user of the
|
|
86
|
+
* site. `selector` remains for exploration, when no label identifies the target,
|
|
87
|
+
* and may carry a frame prefix (see the extension's `frame-ref.ts`).
|
|
88
|
+
*/
|
|
89
|
+
export interface DomAction {
|
|
90
|
+
type: DomActionType;
|
|
91
|
+
controlName?: string;
|
|
92
|
+
within?: string;
|
|
93
|
+
selector?: string;
|
|
94
|
+
text?: string;
|
|
95
|
+
/** For `press` — a key name, not a character. */
|
|
96
|
+
key?: string;
|
|
97
|
+
/** For `hold` — how long to hold, in milliseconds. */
|
|
98
|
+
ms?: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ReadPageArgs {
|
|
102
|
+
/** Free-text steer for extraction ("job listings", "prices"). */
|
|
103
|
+
hint?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface NavigateToArgs {
|
|
107
|
+
url: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface DownloadFileArgs {
|
|
111
|
+
/** May be relative — the caller resolves it against the driven tab's origin. */
|
|
112
|
+
url: string;
|
|
113
|
+
filename?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface AttachFileArgs {
|
|
117
|
+
/** Which of the user's attached files to use; absent means all of them. */
|
|
118
|
+
fileNames?: string[];
|
|
119
|
+
/** Which upload field, when a form has more than one. */
|
|
120
|
+
controlName?: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface CallSiderToolArgs {
|
|
124
|
+
toolId: string;
|
|
125
|
+
args?: Record<string, unknown>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface PlanChecklistArgs {
|
|
129
|
+
items?: unknown[];
|
|
130
|
+
budget?: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
45
133
|
/**
|
|
46
134
|
* Icons a presented list may use.
|
|
47
135
|
*
|