@mlola/decision-jev 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Jev fast-path decision provider (PRD §15, §44).
3
+ *
4
+ * One request per normal decision cycle: operation head + speculative target
5
+ * heads built from the runtime's own action space.
6
+ */
7
+ import { RuntimeError, headForOperation, } from "@mlola/browser-protocol";
8
+ import { JevClient } from "./client.js";
9
+ import { buildQuestions } from "./questions.js";
10
+ import { renderDecisionState } from "./state.js";
11
+ export class JevDecisionProvider {
12
+ name;
13
+ client;
14
+ constructor(options = {}) {
15
+ this.name = options.name ?? "typesafe";
16
+ this.client = new JevClient(options);
17
+ }
18
+ get model() {
19
+ return this.client.model;
20
+ }
21
+ async warmup() {
22
+ await this.client.warmup();
23
+ }
24
+ async decide(input) {
25
+ const { text } = renderDecisionState(input);
26
+ const { questions, headForOperation: heads } = buildQuestions(input.actionSpace);
27
+ const { response, latencyMs } = await this.client.decide({ state: text, questions });
28
+ const operationAnswer = response.answers["operation"];
29
+ if (!operationAnswer) {
30
+ throw new RuntimeError("PROVIDER_FAILURE", "Jev did not answer the operation question", {
31
+ evidence: { answered: Object.keys(response.answers) },
32
+ });
33
+ }
34
+ const operation = operationAnswer.choice;
35
+ const operationProbabilities = operationAnswer.probabilities ?? {};
36
+ const output = {
37
+ operation,
38
+ operationProbabilities,
39
+ operationConfidence: operationAnswer.confidence ?? 0,
40
+ latencyMs,
41
+ provider: this.name,
42
+ model: response.model ?? this.client.model,
43
+ raw: response,
44
+ };
45
+ const head = heads[operation] ?? headForOperation(operation);
46
+ if (head !== undefined) {
47
+ const targetAnswer = response.answers[head];
48
+ if (targetAnswer) {
49
+ output.target = targetAnswer.choice;
50
+ output.targetProbabilities = targetAnswer.probabilities ?? {};
51
+ output.targetConfidence = targetAnswer.confidence ?? 0;
52
+ }
53
+ else {
54
+ // No compatible targets were offered, or the answer is missing: the
55
+ // validator turns this into a DECISION_INVALID for the recovery ladder.
56
+ output.targetProbabilities = {};
57
+ output.targetConfidence = 0;
58
+ }
59
+ }
60
+ const usage = usageFrom(response);
61
+ if (usage)
62
+ output.usage = usage;
63
+ return output;
64
+ }
65
+ }
66
+ const usageFrom = (response) => {
67
+ const usage = response?.usage;
68
+ if (!usage)
69
+ return undefined;
70
+ const inputTokens = usage["input_tokens"] ?? usage["prompt_tokens"] ?? usage["inputTokens"];
71
+ const outputTokens = usage["output_tokens"] ?? usage["completion_tokens"] ?? usage["outputTokens"];
72
+ return {
73
+ provider: "typesafe",
74
+ calls: 1,
75
+ ...(inputTokens !== undefined ? { inputTokens } : {}),
76
+ ...(outputTokens !== undefined ? { outputTokens } : {}),
77
+ };
78
+ };
79
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Dynamic question builder (PRD §14).
3
+ *
4
+ * One request carries the operation head plus speculative target heads; only
5
+ * compatible targets are exposed per operation. The runtime uses the head that
6
+ * matches the selected operation and ignores the rest.
7
+ */
8
+ import type { ActionSpace, OperationId, TargetHeadId } from "@mlola/browser-protocol";
9
+ import type { JevRequest } from "@mlola/browser-protocol";
10
+ export interface JevQuestion {
11
+ type: "choice";
12
+ instructions: string;
13
+ criteria: Record<string, string>;
14
+ }
15
+ export interface BuildQuestionsResult {
16
+ questions: Record<string, JevQuestion>;
17
+ /** Which question carries the target for each offered operation. */
18
+ headForOperation: Partial<Record<OperationId, TargetHeadId>>;
19
+ }
20
+ export declare const buildQuestions: (space: ActionSpace) => BuildQuestionsResult;
21
+ export declare const buildJevRequest: (input: {
22
+ model: string;
23
+ state: string;
24
+ questions: Record<string, JevQuestion>;
25
+ }) => JevRequest;
26
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../src/questions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAkCD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,oEAAoE;IACpE,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,WAAW,KAAG,oBAmCnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACxC,KAAG,UAIF,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Dynamic question builder (PRD §14).
3
+ *
4
+ * One request carries the operation head plus speculative target heads; only
5
+ * compatible targets are exposed per operation. The runtime uses the head that
6
+ * matches the selected operation and ignores the rest.
7
+ */
8
+ import { headForOperation } from "@mlola/browser-protocol";
9
+ const OPERATION_DESCRIPTIONS = {
10
+ CLICK: "Click one element from click_target.",
11
+ TYPE_TEXT: "Type text into one field from type_text_target. The runtime decides the exact text.",
12
+ SELECT: "Choose one option from select_target.",
13
+ SCROLL_UP: "Scroll up to see content above the current viewport.",
14
+ SCROLL_DOWN: "Scroll down to see more content.",
15
+ WAIT: "Wait briefly for the page to settle.",
16
+ BACK: "Go back in browser history.",
17
+ FORWARD: "Go forward in browser history.",
18
+ OPEN_TAB: "Open one link from open_tab_target in a new tab.",
19
+ SWITCH_TAB: "Switch to one tab from switch_tab_target.",
20
+ CLOSE_TAB: "Close the current tab.",
21
+ DOWNLOAD: "Download the file offered by one control from download_target.",
22
+ UPLOAD: "Upload an already-obtained file (chosen by the runtime) using one control from upload_target.",
23
+ PRESS: "Press a key.",
24
+ ACCEPT_DIALOG: "Accept the open browser dialog (e.g. leave the page).",
25
+ DISMISS_DIALOG: "Dismiss the open browser dialog (e.g. stay on the page).",
26
+ DONE: "The task (or the current subgoal) is complete.",
27
+ BLOCKED: "You cannot make progress without human help.",
28
+ ASK_USER: "You need the person to answer something or perform a step.",
29
+ };
30
+ const HEAD_INSTRUCTIONS = {
31
+ click_target: "Choose the element to click.",
32
+ type_text_target: "Choose the field to type into.",
33
+ select_target: "Choose the dropdown option to select.",
34
+ switch_tab_target: "Choose the tab to switch to.",
35
+ open_tab_target: "Choose the link to open in a new tab.",
36
+ download_target: "Choose the control that downloads the requested file.",
37
+ upload_target: "Choose the control that accepts the file upload.",
38
+ };
39
+ export const buildQuestions = (space) => {
40
+ const questions = {};
41
+ const operationCriteria = {};
42
+ for (const op of space.operations) {
43
+ operationCriteria[op] = OPERATION_DESCRIPTIONS[op] ?? op;
44
+ }
45
+ questions["operation"] = {
46
+ type: "choice",
47
+ instructions: "Choose the single best next operation to make progress on the goal. " +
48
+ "Prefer operations that are directly supported by the offered targets.",
49
+ criteria: operationCriteria,
50
+ };
51
+ const heads = {};
52
+ for (const op of space.operations) {
53
+ const head = headForOperation(op);
54
+ if (!head)
55
+ continue;
56
+ heads[op] = head;
57
+ const candidates = space.heads[head] ?? [];
58
+ if (candidates.length === 0)
59
+ continue;
60
+ if (questions[head])
61
+ continue;
62
+ const criteria = {};
63
+ for (const candidate of candidates) {
64
+ criteria[candidate.key] = candidate.label;
65
+ }
66
+ questions[head] = {
67
+ type: "choice",
68
+ instructions: HEAD_INSTRUCTIONS[head],
69
+ criteria,
70
+ };
71
+ }
72
+ return { questions, headForOperation: heads };
73
+ };
74
+ export const buildJevRequest = (input) => ({
75
+ model: input.model,
76
+ state: input.state,
77
+ questions: input.questions,
78
+ });
79
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.js","sourceRoot":"","sources":["../src/questions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAS3D,MAAM,sBAAsB,GAAgC;IAC1D,KAAK,EAAE,sCAAsC;IAC7C,SAAS,EAAE,qFAAqF;IAChG,MAAM,EAAE,uCAAuC;IAC/C,SAAS,EAAE,sDAAsD;IACjE,WAAW,EAAE,kCAAkC;IAC/C,IAAI,EAAE,sCAAsC;IAC5C,IAAI,EAAE,6BAA6B;IACnC,OAAO,EAAE,gCAAgC;IACzC,QAAQ,EAAE,kDAAkD;IAC5D,UAAU,EAAE,2CAA2C;IACvD,SAAS,EAAE,wBAAwB;IACnC,QAAQ,EAAE,gEAAgE;IAC1E,MAAM,EAAE,+FAA+F;IACvG,KAAK,EAAE,cAAc;IACrB,aAAa,EAAE,uDAAuD;IACtE,cAAc,EAAE,0DAA0D;IAC1E,IAAI,EAAE,gDAAgD;IACtD,OAAO,EAAE,8CAA8C;IACvD,QAAQ,EAAE,4DAA4D;CACvE,CAAC;AAEF,MAAM,iBAAiB,GAAiC;IACtD,YAAY,EAAE,8BAA8B;IAC5C,gBAAgB,EAAE,gCAAgC;IAClD,aAAa,EAAE,uCAAuC;IACtD,iBAAiB,EAAE,8BAA8B;IACjD,eAAe,EAAE,uCAAuC;IACxD,eAAe,EAAE,uDAAuD;IACxE,aAAa,EAAE,kDAAkD;CAClE,CAAC;AAQF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAkB,EAAwB,EAAE;IACzE,MAAM,SAAS,GAAgC,EAAE,CAAC;IAElD,MAAM,iBAAiB,GAA2B,EAAE,CAAC;IACrD,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAClC,iBAAiB,CAAC,EAAE,CAAC,GAAG,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IACD,SAAS,CAAC,WAAW,CAAC,GAAG;QACvB,IAAI,EAAE,QAAQ;QACd,YAAY,EACV,sEAAsE;YACtE,uEAAuE;QACzE,QAAQ,EAAE,iBAAiB;KAC5B,CAAC;IAEF,MAAM,KAAK,GAA+C,EAAE,CAAC;IAC7D,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACjB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACtC,IAAI,SAAS,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9B,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;QAC5C,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,GAAG;YAChB,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC;YACrC,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;AAChD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAI/B,EAAc,EAAE,CAAC,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC,KAAK;IAClB,KAAK,EAAE,KAAK,CAAC,KAAK;IAClB,SAAS,EAAE,KAAK,CAAC,SAAS;CAC3B,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Fast-path state rendering.
3
+ *
4
+ * This is everything Jev sees about the world for one decision. It is compact,
5
+ * structured and provenance-clean: no selectors, no coordinates, no secrets, no
6
+ * security verdicts (those are applied in code, not in the prompt).
7
+ */
8
+ import type { DecisionInput, ObservedNode } from "@mlola/browser-protocol";
9
+ export declare const renderElement: (node: ObservedNode) => string;
10
+ export interface RenderedState {
11
+ text: string;
12
+ }
13
+ export declare const renderDecisionState: (input: DecisionInput) => RenderedState;
14
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAM3E,eAAO,MAAM,aAAa,GAAI,MAAM,YAAY,KAAG,MAalD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,aAAa,KAAG,aAmF1D,CAAC"}
package/dist/state.js ADDED
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Fast-path state rendering.
3
+ *
4
+ * This is everything Jev sees about the world for one decision. It is compact,
5
+ * structured and provenance-clean: no selectors, no coordinates, no secrets, no
6
+ * security verdicts (those are applied in code, not in the prompt).
7
+ */
8
+ const collapse = (s) => s.replace(/\s+/g, " ").trim();
9
+ const truncate = (s, n) => (s.length <= n ? s : `${s.slice(0, n - 1)}…`);
10
+ export const renderElement = (node) => {
11
+ const parts = [`[${node.index}]`, node.role, JSON.stringify(truncate(collapse(node.label), 70))];
12
+ if (node.value !== undefined && node.value.length > 0)
13
+ parts.push(`value=${JSON.stringify(truncate(node.value, 40))}`);
14
+ if (node.placeholder)
15
+ parts.push(`placeholder=${JSON.stringify(truncate(node.placeholder, 30))}`);
16
+ if (node.flags.checked !== undefined)
17
+ parts.push(node.flags.checked ? "checked" : "unchecked");
18
+ if (node.flags.selected !== undefined)
19
+ parts.push(node.flags.selected ? "selected" : "unselected");
20
+ if (node.flags.expanded !== undefined)
21
+ parts.push(node.flags.expanded ? "expanded" : "collapsed");
22
+ if (node.flags.offscreen)
23
+ parts.push("offscreen");
24
+ if (!node.flags.enabled || node.flags.disabled)
25
+ parts.push("disabled");
26
+ if (node.flags.readonly)
27
+ parts.push("readonly");
28
+ if (node.flags.required)
29
+ parts.push("required");
30
+ if (node.accept)
31
+ parts.push(`accept=${node.accept}`);
32
+ return parts.join(" ");
33
+ };
34
+ export const renderDecisionState = (input) => {
35
+ const { snapshot, memory, history, artifacts } = input;
36
+ const lines = [];
37
+ lines.push("TASK");
38
+ lines.push(`goal: ${input.goal}`);
39
+ if (input.subgoal)
40
+ lines.push(`current_subgoal: ${input.subgoal}`);
41
+ lines.push(`step: ${input.step}`);
42
+ lines.push("");
43
+ lines.push("PAGE");
44
+ lines.push(`url: ${snapshot.url}`);
45
+ lines.push(`title: ${truncate(collapse(snapshot.title), 120)}`);
46
+ lines.push(`viewport: ${snapshot.viewport.width}x${snapshot.viewport.height} scroll_y=${Math.round(snapshot.viewport.scrollY)} document_height=${Math.round(snapshot.viewport.documentHeight)}`);
47
+ const tabs = snapshot.tabs
48
+ .map((t) => `${t.id}${t.active ? "*" : ""} ${JSON.stringify(truncate(collapse(t.title || t.url), 60))} (${t.ownership})`)
49
+ .join(" | ");
50
+ lines.push(`tabs: ${tabs.length > 0 ? tabs : "(one tab)"}`);
51
+ if (snapshot.blockingUi) {
52
+ const ui = snapshot.blockingUi;
53
+ lines.push(`blocking_ui: ${ui.kind}${ui.text ? ` ${JSON.stringify(truncate(collapse(ui.text), 140))}` : ""}`);
54
+ }
55
+ if (snapshot.visualOnly)
56
+ lines.push("note: the page is a visual surface with no semantic controls");
57
+ const offered = new Set();
58
+ for (const list of Object.values(input.actionSpace.heads)) {
59
+ for (const candidate of list ?? [])
60
+ if (candidate.nodeIndex !== undefined)
61
+ offered.add(candidate.nodeIndex);
62
+ }
63
+ lines.push("");
64
+ lines.push("ELEMENTS");
65
+ const visibleNodes = snapshot.nodes.filter((n) => n.flags.visible);
66
+ const shown = visibleNodes.length > 0 ? visibleNodes : snapshot.nodes;
67
+ for (const node of shown.slice(0, 80)) {
68
+ const mark = offered.has(node.index) ? " " : "~";
69
+ lines.push(`${mark}${renderElement(node)}`);
70
+ }
71
+ if (shown.length > 80)
72
+ lines.push(`… ${shown.length - 80} more elements`);
73
+ if (shown.length === 0)
74
+ lines.push("(no elements were detected)");
75
+ if (snapshot.textSummary.trim().length > 0) {
76
+ lines.push("");
77
+ lines.push("VISIBLE_TEXT");
78
+ const text = collapse(snapshot.textSummary);
79
+ lines.push(truncate(text, 1200));
80
+ }
81
+ if (artifacts.length > 0) {
82
+ lines.push("");
83
+ lines.push("FILES");
84
+ for (const a of artifacts) {
85
+ lines.push(`- ${a.id} ${a.name} (${a.documentType ?? a.mimeType}, ${a.verified ? "verified" : "unverified"})`);
86
+ }
87
+ }
88
+ if (history.length > 0) {
89
+ lines.push("");
90
+ lines.push("RECENT_STEPS");
91
+ for (const step of history.slice(-8)) {
92
+ lines.push(`${step.step}. ${step.action} -> ${step.outcome}${step.detail ? ` (${truncate(step.detail, 90)})` : ""}`);
93
+ }
94
+ }
95
+ const facts = memory.facts.slice(-8);
96
+ const failures = memory.failedAttempts.slice(-4);
97
+ if (facts.length > 0 || failures.length > 0) {
98
+ lines.push("");
99
+ lines.push("MEMORY");
100
+ for (const f of facts)
101
+ lines.push(`- ${truncate(f.text, 120)}`);
102
+ for (const f of failures)
103
+ lines.push(`- avoid repeating: ${truncate(f.text, 120)} (step ${f.step})`);
104
+ }
105
+ if (input.failure) {
106
+ lines.push("");
107
+ lines.push("PREVIOUS_ATTEMPT");
108
+ lines.push(`failed: ${truncate(input.failure, 200)}`);
109
+ }
110
+ return { text: lines.join("\n") };
111
+ };
112
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Offline decision providers for tests, evals and demos.
3
+ *
4
+ * Neither of these is a decision model. `ScriptedDecisionProvider` replays a
5
+ * fixed sequence through the full runtime (validation, policy, execution,
6
+ * verification); `KeywordDecisionProvider` is a deterministic keyword baseline
7
+ * used for offline demos and as the PRD §56 C baseline. The product fast path
8
+ * is the Jev provider.
9
+ */
10
+ import { actionSignature, type DecisionInput, type DecisionOutput, type DecisionProvider, type OperationId } from "@mlola/browser-protocol";
11
+ export interface ScriptStep {
12
+ operation: OperationId;
13
+ /** Exact target key inside the operation's head. */
14
+ target?: string;
15
+ /**
16
+ * Resolve the target by matching a candidate label (string substring or
17
+ * RegExp). Robust against index shifts across re-renders.
18
+ */
19
+ targetLabel?: string | RegExp;
20
+ note?: string;
21
+ }
22
+ export type ScriptEntry = ScriptStep | ((input: DecisionInput) => ScriptStep | Promise<ScriptStep>);
23
+ export declare class ScriptedDecisionProvider implements DecisionProvider {
24
+ #private;
25
+ readonly name: string;
26
+ readonly seen: DecisionInput[];
27
+ constructor(steps: ScriptEntry[], name?: string);
28
+ get remaining(): number;
29
+ decide(input: DecisionInput): Promise<DecisionOutput>;
30
+ }
31
+ export interface KeywordProviderOptions {
32
+ /** Provider name recorded in traces. */
33
+ name?: string;
34
+ /** Minimum score before a click/type target is chosen. */
35
+ minScore?: number;
36
+ }
37
+ export declare class KeywordDecisionProvider implements DecisionProvider {
38
+ #private;
39
+ readonly name: string;
40
+ constructor(options?: KeywordProviderOptions);
41
+ decide(input: DecisionInput): Promise<DecisionOutput>;
42
+ }
43
+ /** Signature helper re-exported for tests that assert loop behaviour. */
44
+ export { actionSignature };
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,eAAe,EAGf,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAEjB,MAAM,yBAAyB,CAAC;AAIjC,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,WAAW,CAAC;IACvB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AAEpG,qBAAa,wBAAyB,YAAW,gBAAgB;;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,aAAa,EAAE,CAAM;gBAIxB,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,SAAa;IAKnD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CAsD5D;AAmBD,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,qBAAa,uBAAwB,YAAW,gBAAgB;;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAIV,OAAO,GAAE,sBAA2B;IAK1C,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CAiK5D;AAID,yEAAyE;AACzE,OAAO,EAAE,eAAe,EAAE,CAAC"}