@ruakit/agent 0.0.0-stage → 0.1.0-alpha.1
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/LICENSE +21 -0
- package/NOTICE +4 -0
- package/dist/approval.d.ts +17 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +3 -0
- package/dist/approval.js.map +7 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +7 -0
- package/dist/decision-runtime.d.ts +5 -0
- package/dist/decision-runtime.d.ts.map +1 -0
- package/dist/decision-runtime.js +3 -0
- package/dist/decision-runtime.js.map +7 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +3 -0
- package/dist/errors.js.map +7 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +7 -0
- package/dist/operations.d.ts +10 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +3 -0
- package/dist/operations.js.map +7 -0
- package/dist/plan-transport.d.ts +11 -0
- package/dist/plan-transport.d.ts.map +1 -0
- package/dist/plan-transport.js +3 -0
- package/dist/plan-transport.js.map +7 -0
- package/dist/plan.d.ts +47 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +3 -0
- package/dist/plan.js.map +7 -0
- package/dist/request-outcome.d.ts +43 -0
- package/dist/request-outcome.d.ts.map +1 -0
- package/dist/request-outcome.js +3 -0
- package/dist/request-outcome.js.map +7 -0
- package/dist/request-state.d.ts +84 -0
- package/dist/request-state.d.ts.map +1 -0
- package/dist/request-state.js +3 -0
- package/dist/request-state.js.map +7 -0
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +3 -0
- package/dist/runtime.js.map +7 -0
- package/dist/session.d.ts +49 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +3 -0
- package/dist/session.js.map +7 -0
- package/dist/transport.d.ts +11 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +3 -0
- package/dist/transport.js.map +7 -0
- package/dist/user-interruption.d.ts +6 -0
- package/dist/user-interruption.d.ts.map +1 -0
- package/dist/user-interruption.js +25 -0
- package/dist/user-interruption.js.map +1 -0
- package/package.json +32 -3
- package/src/approval.ts +47 -0
- package/src/constants.ts +13 -0
- package/src/decision-runtime.ts +26 -0
- package/src/errors.ts +56 -0
- package/src/index.ts +50 -0
- package/src/operations.ts +71 -0
- package/src/plan-transport.ts +82 -0
- package/src/plan.ts +468 -0
- package/src/request-outcome.ts +58 -0
- package/src/request-state.ts +189 -0
- package/src/runtime.ts +88 -0
- package/src/session.ts +408 -0
- package/src/transport.ts +52 -0
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-state.d.ts","sourceRoot":"","sources":["../src/request-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var c=Object.defineProperty;var a=(r,s)=>c(r,"name",{value:s,configurable:!0});import{REQUEST_MESSAGES as e}from"./constants.js";const n=Object.freeze({status:"idle",message:e.ready});function u(r){return r.status==="running"||r.status==="cancelling"||r.status==="approval"}a(u,"requestIsBusy");function o(r,s){if(s.type==="reset")return u(r)?r:n;if(s.type==="started")return u(r)?r:{status:"running",requestId:s.requestId,...s.identity?{identity:s.identity}:{},phase:"observing",message:e.thinking};if(r.status==="clarification"&&s.type==="cancelled"&&r.requestId===s.requestId)return{status:"cancelled",requestId:r.requestId,...r.identity?{identity:r.identity}:{},message:e.cancelled};if(!u(r)||r.requestId!==s.requestId)return r;const i=r.identity?{identity:r.identity}:{};switch(s.type){case"progress":return r.status==="running"?{...r,message:s.message}:r;case"phase":return r.status==="running"?{...r,phase:s.phase}:r;case"approval":return r.status==="cancelling"?r:{status:"approval",...i,requestId:s.requestId,approvalId:s.approvalId,approval:s.approval,originalPrompt:s.originalPrompt,message:s.approval.message};case"approval-resolved":return r.status!=="approval"?r:{status:"running",...i,requestId:s.requestId,phase:"executing",message:e.checkingApproval};case"cancelling":return{...r,status:"cancelling",phase:r.status==="approval"?"executing":r.phase,message:e.cancelling};case"cancelled":return{status:"cancelled",...i,requestId:s.requestId,message:e.cancelled};case"triggered":return r.status==="cancelling"?r:{status:"triggered",...i,requestId:s.requestId,result:s.result,message:s.result.message??e.triggered};case"clarification":return r.status==="cancelling"?r:{status:"clarification",...i,requestId:s.requestId,clarification:s.clarification,originalPrompt:s.originalPrompt,message:s.message??s.clarification.question};case"failed":return r.status==="cancelling"?r:{status:"failed",...i,...s.error?{error:s.error}:{},requestId:s.requestId,message:s.message}}}a(o,"requestReducer");export{n as INITIAL_REQUEST_STATE,u as requestIsBusy,o as requestReducer};
|
|
3
|
+
//# sourceMappingURL=request-state.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/request-state.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { REQUEST_MESSAGES } from './constants.js';\nimport type { Clarification, ExecutionResult } from \"@ruakit/schema\";\nimport type { RequestError, RequestIdentity } from \"./request-outcome.js\";\nimport type { ApprovalRequest } from \"./approval.js\";\n\n/** Machine-readable execution stages; progress messages remain separate UI text. */\nexport type RequestPhase = \"observing\" | \"planning\" | \"executing\";\n\ninterface ActiveRequest {\n requestId: number;\n message: string;\n identity?: RequestIdentity;\n}\n\nexport type RequestState =\n | { status: \"idle\"; message: string }\n | (ActiveRequest & { status: \"running\" | \"cancelling\"; phase: RequestPhase })\n | (ActiveRequest & {\n status: \"approval\";\n approvalId: string;\n approval: ApprovalRequest;\n originalPrompt: string;\n })\n | (ActiveRequest & { status: \"triggered\"; result: ExecutionResult })\n | (ActiveRequest & {\n status: \"clarification\";\n clarification: Clarification;\n originalPrompt: string;\n })\n | (ActiveRequest & { status: \"cancelled\" })\n | (ActiveRequest & { status: \"failed\"; error?: RequestError });\n\nexport type RequestEvent =\n | { type: \"started\"; requestId: number; identity?: RequestIdentity }\n | { type: \"progress\"; requestId: number; message: string }\n | { type: \"phase\"; requestId: number; phase: RequestPhase }\n | {\n type: \"approval\";\n requestId: number;\n approvalId: string;\n approval: ApprovalRequest;\n originalPrompt: string;\n }\n | { type: \"approval-resolved\"; requestId: number }\n | {\n type: \"cancelling\" | \"cancelled\";\n requestId: number;\n }\n | { type: \"triggered\"; requestId: number; result: ExecutionResult }\n | { type: \"failed\"; requestId: number; message: string; error?: RequestError }\n | {\n type: \"clarification\";\n requestId: number;\n clarification: Clarification;\n originalPrompt: string;\n message?: string;\n }\n | { type: \"reset\" };\n\nexport const INITIAL_REQUEST_STATE: RequestState = Object.freeze({\n status: \"idle\",\n message: REQUEST_MESSAGES.ready,\n});\n\nexport function requestIsBusy(\n state: RequestState,\n): state is Extract<\n RequestState,\n { status: \"running\" | \"cancelling\" | \"approval\" }\n> {\n return (\n state.status === \"running\" ||\n state.status === \"cancelling\" ||\n state.status === \"approval\"\n );\n}\n\n/** Ignore obsolete completions and progress after cancellation or settlement. */\nexport function requestReducer(\n state: RequestState,\n event: RequestEvent,\n): RequestState {\n if (event.type === \"reset\") {\n return requestIsBusy(state) ? state : INITIAL_REQUEST_STATE;\n }\n if (event.type === \"started\") {\n return requestIsBusy(state)\n ? state\n : {\n status: \"running\",\n requestId: event.requestId,\n ...(event.identity ? { identity: event.identity } : {}),\n phase: \"observing\",\n message: REQUEST_MESSAGES.thinking,\n };\n }\n const cancellingQuestion =\n state.status === \"clarification\" && event.type === \"cancelled\";\n if (cancellingQuestion && state.requestId === event.requestId) {\n return {\n status: \"cancelled\",\n requestId: state.requestId,\n ...(state.identity ? { identity: state.identity } : {}),\n message: REQUEST_MESSAGES.cancelled,\n };\n }\n if (!requestIsBusy(state) || state.requestId !== event.requestId) {\n return state;\n }\n const identity = state.identity ? { identity: state.identity } : {};\n switch (event.type) {\n case \"progress\":\n return state.status === \"running\"\n ? { ...state, message: event.message }\n : state;\n case \"phase\":\n return state.status === \"running\"\n ? { ...state, phase: event.phase }\n : state;\n case \"approval\":\n return state.status === \"cancelling\"\n ? state\n : {\n status: \"approval\",\n ...identity,\n requestId: event.requestId,\n approvalId: event.approvalId,\n approval: event.approval,\n originalPrompt: event.originalPrompt,\n message: event.approval.message,\n };\n case \"approval-resolved\":\n return state.status !== \"approval\"\n ? state\n : {\n status: \"running\",\n ...identity,\n requestId: event.requestId,\n phase: \"executing\",\n message: REQUEST_MESSAGES.checkingApproval,\n };\n case \"cancelling\":\n return {\n ...state,\n status: \"cancelling\",\n phase: state.status === \"approval\" ? \"executing\" : state.phase,\n message: REQUEST_MESSAGES.cancelling,\n };\n case \"cancelled\":\n return {\n status: \"cancelled\",\n ...identity,\n requestId: event.requestId,\n message: REQUEST_MESSAGES.cancelled,\n };\n case \"triggered\":\n return state.status === \"cancelling\"\n ? state\n : {\n status: \"triggered\",\n ...identity,\n requestId: event.requestId,\n result: event.result,\n message: event.result.message ?? REQUEST_MESSAGES.triggered,\n };\n case \"clarification\":\n return state.status === \"cancelling\"\n ? state\n : {\n status: \"clarification\",\n ...identity,\n requestId: event.requestId,\n clarification: event.clarification,\n originalPrompt: event.originalPrompt,\n message: event.message ?? event.clarification.question,\n };\n case \"failed\":\n return state.status === \"cancelling\"\n ? state\n : {\n status: \"failed\",\n ...identity,\n ...(event.error ? { error: event.error } : {}),\n requestId: event.requestId,\n message: event.message,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": ";+EACA,OAAS,oBAAAA,MAAwB,iBA2D1B,MAAMC,EAAsC,OAAO,OAAO,CAC/D,OAAQ,OACR,QAASD,EAAiB,MAC3B,EAEK,SAAUE,EACdC,EAAmB,CAKnB,OACEA,EAAM,SAAW,WACjBA,EAAM,SAAW,cACjBA,EAAM,SAAW,UAErB,CAXgBC,EAAAF,EAAA,iBAcV,SAAUG,EACdF,EACAG,EAAmB,CAEnB,GAAIA,EAAM,OAAS,QACjB,OAAOJ,EAAcC,CAAK,EAAIA,EAAQF,EAExC,GAAIK,EAAM,OAAS,UACjB,OAAOJ,EAAcC,CAAK,EACtBA,EACA,CACE,OAAQ,UACR,UAAWG,EAAM,UACjB,GAAIA,EAAM,SAAW,CAAE,SAAUA,EAAM,QAAQ,EAAK,CAAA,EACpD,MAAO,YACP,QAASN,EAAiB,UAKlC,GADEG,EAAM,SAAW,iBAAmBG,EAAM,OAAS,aAC3BH,EAAM,YAAcG,EAAM,UAClD,MAAO,CACL,OAAQ,YACR,UAAWH,EAAM,UACjB,GAAIA,EAAM,SAAW,CAAE,SAAUA,EAAM,QAAQ,EAAK,CAAA,EACpD,QAASH,EAAiB,WAG9B,GAAI,CAACE,EAAcC,CAAK,GAAKA,EAAM,YAAcG,EAAM,UACrD,OAAOH,EAET,MAAMI,EAAWJ,EAAM,SAAW,CAAE,SAAUA,EAAM,QAAQ,EAAK,CAAA,EACjE,OAAQG,EAAM,KAAM,CAClB,IAAK,WACH,OAAOH,EAAM,SAAW,UACpB,CAAE,GAAGA,EAAO,QAASG,EAAM,OAAO,EAClCH,EACN,IAAK,QACH,OAAOA,EAAM,SAAW,UACpB,CAAE,GAAGA,EAAO,MAAOG,EAAM,KAAK,EAC9BH,EACN,IAAK,WACH,OAAOA,EAAM,SAAW,aACpBA,EACA,CACE,OAAQ,WACR,GAAGI,EACH,UAAWD,EAAM,UACjB,WAAYA,EAAM,WAClB,SAAUA,EAAM,SAChB,eAAgBA,EAAM,eACtB,QAASA,EAAM,SAAS,SAEhC,IAAK,oBACH,OAAOH,EAAM,SAAW,WACpBA,EACA,CACE,OAAQ,UACR,GAAGI,EACH,UAAWD,EAAM,UACjB,MAAO,YACP,QAASN,EAAiB,kBAElC,IAAK,aACH,MAAO,CACL,GAAGG,EACH,OAAQ,aACR,MAAOA,EAAM,SAAW,WAAa,YAAcA,EAAM,MACzD,QAASH,EAAiB,YAE9B,IAAK,YACH,MAAO,CACL,OAAQ,YACR,GAAGO,EACH,UAAWD,EAAM,UACjB,QAASN,EAAiB,WAE9B,IAAK,YACH,OAAOG,EAAM,SAAW,aACpBA,EACA,CACE,OAAQ,YACR,GAAGI,EACH,UAAWD,EAAM,UACjB,OAAQA,EAAM,OACd,QAASA,EAAM,OAAO,SAAWN,EAAiB,WAE1D,IAAK,gBACH,OAAOG,EAAM,SAAW,aACpBA,EACA,CACE,OAAQ,gBACR,GAAGI,EACH,UAAWD,EAAM,UACjB,cAAeA,EAAM,cACrB,eAAgBA,EAAM,eACtB,QAASA,EAAM,SAAWA,EAAM,cAAc,UAEtD,IAAK,SACH,OAAOH,EAAM,SAAW,aACpBA,EACA,CACE,OAAQ,SACR,GAAGI,EACH,GAAID,EAAM,MAAQ,CAAE,MAAOA,EAAM,KAAK,EAAK,CAAA,EAC3C,UAAWA,EAAM,UACjB,QAASA,EAAM,QAEzB,CACF,CA7GgBF,EAAAC,EAAA",
|
|
6
|
+
"names": ["REQUEST_MESSAGES", "INITIAL_REQUEST_STATE", "requestIsBusy", "state", "__name", "requestReducer", "event", "identity"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ClarificationTurn, ExecutionResult } from '@ruakit/schema';
|
|
2
|
+
import type { ExecutionOptions, RuaSession } from './session.js';
|
|
3
|
+
import type { PlanTransport } from './plan-transport.js';
|
|
4
|
+
import type { PlanPlanner, PlanTask, PlanTaskOptions } from './plan.js';
|
|
5
|
+
import type { HttpTransportOptions, RuaKitTransport } from './transport.js';
|
|
6
|
+
export interface RuntimeOptions extends HttpTransportOptions, Omit<ExecutionOptions, 'signal'> {
|
|
7
|
+
protocol?: 'decision';
|
|
8
|
+
document?: Document;
|
|
9
|
+
/** Reuse the target registry used by snapshot/run primitives. */
|
|
10
|
+
session?: RuaSession;
|
|
11
|
+
transport?: RuaKitTransport;
|
|
12
|
+
}
|
|
13
|
+
export interface PlanRuntimeOptions extends Omit<RuntimeOptions, 'transport' | 'protocol'>, Pick<PlanTaskOptions, 'context' | 'maxReplans' | 'onPlan'> {
|
|
14
|
+
protocol: 'plan';
|
|
15
|
+
transport?: PlanTransport;
|
|
16
|
+
planner?: PlanPlanner;
|
|
17
|
+
task?: PlanTask;
|
|
18
|
+
}
|
|
19
|
+
export interface RequestOptions {
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
clarifications?: ClarificationTurn[];
|
|
22
|
+
}
|
|
23
|
+
export interface RuaKitRuntime {
|
|
24
|
+
request(prompt: string, options?: RequestOptions): Promise<ExecutionResult>;
|
|
25
|
+
}
|
|
26
|
+
/** Plan from the rendered page and execute only locally observed DOM targets. */
|
|
27
|
+
export declare function createRuntime(options?: RuntimeOptions): RuaKitRuntime;
|
|
28
|
+
export declare function createRuntime(options: PlanRuntimeOptions): RuaKitRuntime;
|
|
29
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAExE,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE5E,MAAM,WAAW,cAAe,SAAQ,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC;IAC5F,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AACD,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,UAAU,CAAC,EACxF,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7E;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;AACvE,wBAAgB,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAAC"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var f=Object.defineProperty;var o=(e,r)=>f(e,"name",{value:r,configurable:!0});import{RUNTIME_META_NAME as l}from"@ruakit/schema";import{RuaKitError as s}from"./errors.js";import{createDecisionRuntime as w}from"./decision-runtime.js";import{createHttpTransport as E}from"./transport.js";import{createPlanTransport as U}from"./plan-transport.js";import{createSession as h}from"./session.js";function N(e={}){const r=e.document??e.session?.document??globalThis.document;if(!r?.defaultView)throw new s("UNAVAILABLE","RuaKit requires a browser document.");const c=r.querySelector(`meta[name="${l}"]`)?.content;let a;if(c!==void 0)try{const t=JSON.parse(c);if(!t||typeof t!="object"||Array.isArray(t))throw new Error;const n=t;if(n.serverUrl!==void 0&&(typeof n.serverUrl!="string"||!n.serverUrl.trim()))throw new Error;a=n.serverUrl}catch{throw new s("INVALID_REQUEST","The page has invalid RuaKit configuration.")}if(e.protocol==="plan"){const t=e.session??h({document:r});if(t.document!==r)throw new s("INVALID_REQUEST","The Rua session belongs to a different document.");const n=e.planner?void 0:e.transport??U({...e,...e.serverUrl===void 0&&a?{serverUrl:a}:{},document:r});return{request:o((u,i={})=>(e.task??t.createPlanTask()).request(u,e.planner??((m,d)=>n.plan(m,d)),{...e,...i}),"request")}}return w(e,e.transport??E({...e,...e.serverUrl===void 0&&a?{serverUrl:a}:{}}))}o(N,"createRuntime");export{N as createRuntime};
|
|
3
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/runtime.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { RUNTIME_META_NAME } from '@ruakit/schema';\nimport type { ClarificationTurn, ExecutionResult } from '@ruakit/schema';\nimport { RuaKitError } from './errors.js';\nimport { createDecisionRuntime } from './decision-runtime.js';\nimport type { ExecutionOptions, RuaSession } from './session.js';\nimport { createHttpTransport } from './transport.js';\nimport { createPlanTransport } from './plan-transport.js';\nimport type { PlanTransport } from './plan-transport.js';\nimport type { PlanPlanner, PlanTask, PlanTaskOptions } from './plan.js';\nimport { createSession } from './session.js';\nimport type { HttpTransportOptions, RuaKitTransport } from './transport.js';\n\nexport interface RuntimeOptions extends HttpTransportOptions, Omit<ExecutionOptions, 'signal'> {\n protocol?: 'decision';\n document?: Document;\n /** Reuse the target registry used by snapshot/run primitives. */\n session?: RuaSession;\n transport?: RuaKitTransport;\n}\nexport interface PlanRuntimeOptions extends Omit<RuntimeOptions, 'transport' | 'protocol'>,\n Pick<PlanTaskOptions, 'context' | 'maxReplans' | 'onPlan'> {\n protocol: 'plan';\n transport?: PlanTransport;\n planner?: PlanPlanner;\n task?: PlanTask;\n}\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n clarifications?: ClarificationTurn[];\n}\n\nexport interface RuaKitRuntime {\n request(prompt: string, options?: RequestOptions): Promise<ExecutionResult>;\n}\n\n/** Plan from the rendered page and execute only locally observed DOM targets. */\nexport function createRuntime(options?: RuntimeOptions): RuaKitRuntime;\nexport function createRuntime(options: PlanRuntimeOptions): RuaKitRuntime;\nexport function createRuntime(options: RuntimeOptions | PlanRuntimeOptions = {}): RuaKitRuntime {\n const document = options.document ?? options.session?.document ?? globalThis.document;\n if (!document?.defaultView) {\n throw new RuaKitError('UNAVAILABLE', 'RuaKit requires a browser document.');\n }\n const embedded = document.querySelector<HTMLMetaElement>(\n `meta[name=\"${RUNTIME_META_NAME}\"]`,\n )?.content;\n let serverUrl: string | undefined;\n if (embedded !== undefined) {\n try {\n const value: unknown = JSON.parse(embedded);\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error();\n }\n const record = value as Record<string, unknown>;\n if (\n record.serverUrl !== undefined &&\n (typeof record.serverUrl !== 'string' || !record.serverUrl.trim())\n ) {\n throw new Error();\n }\n serverUrl = record.serverUrl as string | undefined;\n } catch {\n throw new RuaKitError('INVALID_REQUEST', 'The page has invalid RuaKit configuration.');\n }\n }\n if (options.protocol === 'plan') {\n const session = options.session ?? createSession({ document });\n if (session.document !== document)\n throw new RuaKitError('INVALID_REQUEST', 'The Rua session belongs to a different document.');\n const transport = options.planner ? undefined : options.transport ?? createPlanTransport({\n ...options, ...(options.serverUrl === undefined && serverUrl ? { serverUrl } : {}), document,\n });\n return {\n request: (prompt, settings = {}) => (options.task ?? session.createPlanTask()).request(prompt,\n options.planner ?? ((input, signal) => transport!.plan(input, signal)), { ...options, ...settings }),\n };\n }\n return createDecisionRuntime(\n options,\n options.transport ??\n createHttpTransport({\n ...options,\n ...(options.serverUrl === undefined && serverUrl ? { serverUrl } : {}),\n }),\n );\n}\n"],
|
|
5
|
+
"mappings": ";+EACA,OAAS,qBAAAA,MAAyB,iBAElC,OAAS,eAAAC,MAAmB,cAC5B,OAAS,yBAAAC,MAA6B,wBAEtC,OAAS,uBAAAC,MAA2B,iBACpC,OAAS,uBAAAC,MAA2B,sBAGpC,OAAS,iBAAAC,MAAqB,eA8BxB,SAAUC,EAAcC,EAA+C,CAAA,EAAE,CAC7E,MAAMC,EAAWD,EAAQ,UAAYA,EAAQ,SAAS,UAAY,WAAW,SAC7E,GAAI,CAACC,GAAU,YACb,MAAM,IAAIP,EAAY,cAAe,qCAAqC,EAE5E,MAAMQ,EAAWD,EAAS,cACxB,cAAcR,CAAiB,IAAI,GAClC,QACH,IAAIU,EACJ,GAAID,IAAa,OACf,GAAI,CACF,MAAME,EAAiB,KAAK,MAAMF,CAAQ,EAC1C,GAAI,CAACE,GAAS,OAAOA,GAAU,UAAY,MAAM,QAAQA,CAAK,EAC5D,MAAM,IAAI,MAEZ,MAAMC,EAASD,EACf,GACEC,EAAO,YAAc,SACpB,OAAOA,EAAO,WAAc,UAAY,CAACA,EAAO,UAAU,KAAI,GAE/D,MAAM,IAAI,MAEZF,EAAYE,EAAO,SACrB,MAAQ,CACN,MAAM,IAAIX,EAAY,kBAAmB,4CAA4C,CACvF,CAEF,GAAIM,EAAQ,WAAa,OAAQ,CAC/B,MAAMM,EAAUN,EAAQ,SAAWF,EAAc,CAAE,SAAAG,CAAQ,CAAE,EAC7D,GAAIK,EAAQ,WAAaL,EACvB,MAAM,IAAIP,EAAY,kBAAmB,kDAAkD,EAC7F,MAAMa,EAAYP,EAAQ,QAAU,OAAYA,EAAQ,WAAaH,EAAoB,CACvF,GAAGG,EAAS,GAAIA,EAAQ,YAAc,QAAaG,EAAY,CAAE,UAAAA,CAAS,EAAK,CAAA,EAAK,SAAAF,EACrF,EACD,MAAO,CACL,QAASO,EAAA,CAACC,EAAQC,EAAW,CAAA,KAAQV,EAAQ,MAAQM,EAAQ,eAAc,GAAI,QAAQG,EACrFT,EAAQ,UAAY,CAACW,EAAOC,IAAWL,EAAW,KAAKI,EAAOC,CAAM,GAAI,CAAE,GAAGZ,EAAS,GAAGU,CAAQ,CAAE,EAD5F,WAGb,CACA,OAAOf,EACLK,EACAA,EAAQ,WACNJ,EAAoB,CAClB,GAAGI,EACH,GAAIA,EAAQ,YAAc,QAAaG,EAAY,CAAE,UAAAA,CAAS,EAAK,CAAA,EACpE,CAAC,CAER,CA/CgBK,EAAAT,EAAA",
|
|
6
|
+
"names": ["RUNTIME_META_NAME", "RuaKitError", "createDecisionRuntime", "createHttpTransport", "createPlanTransport", "createSession", "createRuntime", "options", "document", "embedded", "serverUrl", "value", "record", "session", "transport", "__name", "prompt", "settings", "input", "signal"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ActionFeedbackOptions, PageState } from '@ruakit/runtime';
|
|
2
|
+
import type { ClarificationTurn, CompletionCheck, ExecutionResult } from '@ruakit/schema';
|
|
3
|
+
import type { RequestPhase } from './request-state.js';
|
|
4
|
+
import type { RuaKitTransport } from './transport.js';
|
|
5
|
+
import type { ApprovalOptions } from './approval.js';
|
|
6
|
+
import type { PlanExecutionOptions, PlanExecutionResult, PlanTask } from './plan.js';
|
|
7
|
+
export interface ExecutionOptions extends ActionFeedbackOptions, ApprovalOptions {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
requestTimeoutMs?: number;
|
|
11
|
+
/** Optional stronger application check, called only after all DOM outcomes pass. */
|
|
12
|
+
verifyCompletion?: (context: CompletionContext) => boolean | Promise<boolean>;
|
|
13
|
+
/** Observational feedback; exceptions cannot change execution. */
|
|
14
|
+
onProgress?: (message: string) => void;
|
|
15
|
+
onPhaseChange?: (phase: RequestPhase) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface CompletionContext {
|
|
18
|
+
prompt: string | undefined;
|
|
19
|
+
checks: readonly CompletionCheck[];
|
|
20
|
+
baseline: PageState;
|
|
21
|
+
snapshot: PageState;
|
|
22
|
+
signal: AbortSignal;
|
|
23
|
+
}
|
|
24
|
+
export interface RunOptions extends ExecutionOptions {
|
|
25
|
+
/** The original observation used to obtain this decision, from this session. */
|
|
26
|
+
snapshot: PageState;
|
|
27
|
+
/** Optional host-established outcomes for a manually owned loop. */
|
|
28
|
+
checks?: CompletionCheck[];
|
|
29
|
+
/** Original session observation for checks requiring a newly appeared result. */
|
|
30
|
+
baseline?: PageState;
|
|
31
|
+
}
|
|
32
|
+
export interface PlanOptions extends ExecutionOptions {
|
|
33
|
+
clarifications?: ClarificationTurn[];
|
|
34
|
+
}
|
|
35
|
+
export interface RuaSession {
|
|
36
|
+
readonly document: Document;
|
|
37
|
+
snapshot(): PageState;
|
|
38
|
+
/** Validate and apply one decision. A triggered action does not establish task completion. */
|
|
39
|
+
run(decision: unknown, options: RunOptions): Promise<ExecutionResult>;
|
|
40
|
+
executePlan(plan: unknown, options?: PlanExecutionOptions): Promise<PlanExecutionResult>;
|
|
41
|
+
createPlanTask(): PlanTask;
|
|
42
|
+
/** Observe, request a decision, and apply it until the planner finishes or asks a question. */
|
|
43
|
+
plan(prompt: string, request: RuaKitTransport['dom'], options?: PlanOptions): Promise<ExecutionResult>;
|
|
44
|
+
}
|
|
45
|
+
/** One browser target registry shared by observation, execution, and planning. */
|
|
46
|
+
export declare function createSession(options?: {
|
|
47
|
+
document?: Document;
|
|
48
|
+
}): RuaSession;
|
|
49
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAC;AAOpF,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,QAAQ,EAAc,MAAM,WAAW,CAAC;AAEjG,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB,EAAE,eAAe;IAC9E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,kEAAkE;IAClE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAClD,gFAAgF;IAChF,QAAQ,EAAE,SAAS,CAAC;IACpB,oEAAoE;IACpE,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,IAAI,SAAS,CAAC;IACtB,8FAA8F;IAC9F,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACtE,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzF,cAAc,IAAI,QAAQ,CAAC;IAC3B,+FAA+F;IAC/F,IAAI,CACF,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAC/B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAO,GAAG,UAAU,CA8U/E"}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var _=Object.defineProperty;var c=(A,m)=>_(A,"name",{value:m,configurable:!0});import{REQUEST_MESSAGES as K}from"./constants.js";import{createRuntime as R}from"@ruakit/runtime";import{completionChecksSchema as x,evaluateCompletionChecks as L,decisionSchema as U,decisionRequestSchema as O}from"@ruakit/schema";import{ClarificationNeededError as B,RuaKitError as i,parsePayload as D}from"./errors.js";import{createRequestOperation as W,runWithSignal as q,validateRequestTimeout as F}from"./operations.js";import{executePlan as J,createPlanTask as Q}from"./plan.js";import{requestApproval as $}from"./approval.js";function te(A={}){const m=A.document??globalThis.document;if(!m?.defaultView)throw new i("UNAVAILABLE","RuaKit requires a browser document.");let w,k=!1,I,C,E=0;const b=new WeakMap,P=new WeakMap,s=R({root:m,timeoutMs:8e3,onAction:c(t=>w?.onAction?.(t),"onAction"),get actionDelayMs(){return w?.actionDelayMs??0},get scrollToTarget(){return w?.scrollToTarget??!1}});function v(){const t=s.getState(),e=structuredClone(t);return b.set(t,e),P.set(t,e),t}c(v,"snapshot");function S(t,e){try{t.onProgress?.(e)}catch{}}c(S,"notify");function N(t,e){try{t.onPhaseChange?.(e)}catch{}}c(N,"phase");async function y(t,e){if(k){if(I?.aborted)return await C,y(t,e);throw new i("BUSY","A RuaKit request is already running.")}k=!0;let r;C=new Promise(a=>{r=a});try{F(t.timeoutMs??8e3);const a=W(t.requestTimeoutMs??6e4,t.signal);I=a.signal,w=t;try{return a.signal.throwIfAborted(),await e(a.signal)}finally{a.dispose()}}finally{w=void 0,I=void 0,k=!1,r()}}c(y,"own");function T(t,e,r="observed"){return{planId:`dom-${Date.now()}-${++E}`,status:"triggered",events:t,...e.type==="complete"?{goalCompleted:!0,message:e.message,verification:{level:r,checks:e.checks}}:{}}}c(T,"receipt");async function g(t,e,r,a,h){r.throwIfAborted();const l=b.get(e);if(!l)throw new i("INVALID_PLAN","Use an unused snapshot from this Rua session.");const o=D(U,t,"INVALID_PLAN","The planner returned an invalid decision.");if(b.delete(e),S(a,o.message),r.throwIfAborted(),o.type==="clarify")throw new B({type:"clarification",question:o.message,options:[]});if(o.type==="unsupported")throw new i("UNAVAILABLE",o.message);if(o.type==="complete"){const d=h?.checks??o.checks;if(JSON.stringify(d)!==JSON.stringify(o.checks))throw new i("INVALID_PLAN","Completion checks cannot change after execution begins.");const p=h?.baseline??l;if(!L(d,l,p).passed||!L(d,s.getState(),p).passed)throw new i("INVALID_PLAN","The requested outcomes are not all present on the live page.");if(a.verifyCompletion){const M=await q(r,()=>a.verifyCompletion({prompt:h?.prompt,checks:structuredClone(d),baseline:structuredClone(p),snapshot:s.getState(),signal:r}));if(r.throwIfAborted(),M!==!0)throw new i("VERIFICATION_FAILED","The application could not confirm the requested outcome.");if(!L(d,s.getState(),p).passed)throw new i("INVALID_PLAN","The page changed while the application verified completion.")}return o}if(o.type==="prepare"||o.type==="screenshot")return o;if(h?.requirePreparation&&!h.checks)throw new i("INVALID_PLAN","Establish completion checks with prepare before taking actions.");const n=o.step,f=l.controls.find(d=>d.target.id===n.target.id&&d.target.version===n.target.version);if(!f||!f.enabled)throw new i("INVALID_PLAN","The planner selected an unavailable live DOM target.");o.type==="approval"&&await $(o,l,r,a,h?.prompt),N(a,"executing");const u={signal:r,timeoutMs:a.timeoutMs??8e3};switch(n.type){case"focus":await s.focus(n.target,u);break;case"key":await s.pressKey(n.target,n.key,{...u,altKey:n.altKey,ctrlKey:n.ctrlKey,metaKey:n.metaKey,shiftKey:n.shiftKey});break;case"insertText":await s.insertText(n.target,n.text,u);break;case"click":await s.click(n.target,u);break;case"fill":await s.setValue(n.target,n.value,u);break;case"select":await s.selectOption(n.target,n.values,u);break;case"check":await s.setChecked(n.target,n.checked,u);break}return r.throwIfAborted(),o}c(g,"apply");const V={platform:m.defaultView?.navigator.platform??"",snapshot:v,apply:g,screenshot:c((t,e)=>s.screenshot({signal:t,timeoutMs:e}),"screenshot")};return{document:m,snapshot:v,executePlan:c((t,e={})=>y(e,r=>J(V,t,r,e)),"executePlan"),createPlanTask:c(()=>Q(V,y),"createPlanTask"),run:c((t,e)=>y(e,async r=>{const a=e.baseline?P.get(e.baseline):void 0;if(e.baseline&&!a)throw new i("INVALID_PLAN","Use an original session observation as the verification baseline.");const h=e.checks?x.parse(e.checks):void 0,l=await g(t,e.snapshot,r,e,{baseline:a??b.get(e.snapshot)??e.snapshot,checks:h,prompt:void 0}),o=T([l.message.slice(0,500)],l,e.verifyCompletion?"confirmed":"observed");return l.type==="screenshot"&&(o.screenshot=await s.screenshot({signal:r,timeoutMs:e.timeoutMs??8e3})),o}),"run"),plan:c((t,e,r={})=>y(r,async a=>{const h=[],l=[];let o,n,f;for(S(r,K.observing);;){a.throwIfAborted(),N(r,"observing");const u=v();n??=structuredClone(u),f&&f.url!==u.url&&(f=void 0);const d=D(O,{platform:m.defaultView?.navigator.platform??"",prompt:t,clarifications:r.clarifications??[],snapshot:u,history:h.slice(-20),checks:o?structuredClone(o):null,canScreenshot:!0,...f?{screenshot:f}:{}},"INVALID_REQUEST","Enter a valid request for the current application page.");N(r,"planning");const p=await g(await q(a,()=>e(d,a)),u,a,r,{baseline:n,checks:o,prompt:t,requirePreparation:!0});if(l.push(p.message.slice(0,500)),p.type==="complete")return T(l,p,r.verifyCompletion?"confirmed":"observed");if(p.type==="prepare"){if(o)throw new i("INVALID_PLAN","Completion checks cannot change after preparation.");o=structuredClone(p.checks)}if(p.type==="screenshot"){if(f)throw new i("INVALID_PLAN","Use the supplied screenshot before requesting another image.");f=await s.screenshot({signal:a,timeoutMs:r.timeoutMs??8e3})}else f=void 0;h.push(p)}}),"plan")}}c(te,"createSession");export{te as createSession};
|
|
3
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/session.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { REQUEST_MESSAGES } from './constants.js';\nimport { createRuntime as createDomRuntime } from '@ruakit/runtime';\nimport type { ActionFeedbackOptions, PageState, Screenshot } from '@ruakit/runtime';\nimport {\n completionChecksSchema,\n evaluateCompletionChecks,\n decisionSchema,\n decisionRequestSchema,\n} from '@ruakit/schema';\nimport type {\n ClarificationTurn,\n CompletionCheck,\n ExecutionResult,\n Decision,\n} from '@ruakit/schema';\nimport { ClarificationNeededError, RuaKitError, parsePayload } from './errors.js';\nimport { createRequestOperation, runWithSignal, validateRequestTimeout } from './operations.js';\nimport type { RequestPhase } from './request-state.js';\nimport type { RuaKitTransport } from './transport.js';\nimport { executePlan, createPlanTask } from './plan.js';\nimport { requestApproval } from './approval.js';\nimport type { ApprovalOptions } from './approval.js';\nimport type { PlanExecutionOptions, PlanExecutionResult, PlanTask, PlanEngine } from './plan.js';\n\nexport interface ExecutionOptions extends ActionFeedbackOptions, ApprovalOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n requestTimeoutMs?: number;\n /** Optional stronger application check, called only after all DOM outcomes pass. */\n verifyCompletion?: (context: CompletionContext) => boolean | Promise<boolean>;\n /** Observational feedback; exceptions cannot change execution. */\n onProgress?: (message: string) => void;\n onPhaseChange?: (phase: RequestPhase) => void;\n}\n\nexport interface CompletionContext {\n prompt: string | undefined;\n checks: readonly CompletionCheck[];\n baseline: PageState;\n snapshot: PageState;\n signal: AbortSignal;\n}\n\nexport interface RunOptions extends ExecutionOptions {\n /** The original observation used to obtain this decision, from this session. */\n snapshot: PageState;\n /** Optional host-established outcomes for a manually owned loop. */\n checks?: CompletionCheck[];\n /** Original session observation for checks requiring a newly appeared result. */\n baseline?: PageState;\n}\n\nexport interface PlanOptions extends ExecutionOptions {\n clarifications?: ClarificationTurn[];\n}\n\nexport interface RuaSession {\n readonly document: Document;\n snapshot(): PageState;\n /** Validate and apply one decision. A triggered action does not establish task completion. */\n run(decision: unknown, options: RunOptions): Promise<ExecutionResult>;\n executePlan(plan: unknown, options?: PlanExecutionOptions): Promise<PlanExecutionResult>;\n createPlanTask(): PlanTask;\n /** Observe, request a decision, and apply it until the planner finishes or asks a question. */\n plan(\n prompt: string,\n request: RuaKitTransport['dom'],\n options?: PlanOptions,\n ): Promise<ExecutionResult>;\n}\n\n/** One browser target registry shared by observation, execution, and planning. */\nexport function createSession(options: { document?: Document } = {}): RuaSession {\n const document = options.document ?? globalThis.document;\n if (!document?.defaultView) {\n throw new RuaKitError('UNAVAILABLE', 'RuaKit requires a browser document.');\n }\n let active: ExecutionOptions | undefined;\n let busy = false;\n let currentSignal: AbortSignal | undefined;\n let settled: Promise<void> | undefined;\n let sequence = 0;\n const observations = new WeakMap<PageState, PageState>();\n const baselines = new WeakMap<PageState, PageState>();\n const dom = createDomRuntime({\n root: document,\n timeoutMs: 8000,\n onAction: (event) => active?.onAction?.(event),\n get actionDelayMs() {\n return active?.actionDelayMs ?? 0;\n },\n get scrollToTarget() {\n return active?.scrollToTarget ?? false;\n },\n });\n\n function snapshot(): PageState {\n const state = dom.getState();\n // Keep our own copy so callers cannot authorize targets by editing a snapshot.\n const original = structuredClone(state);\n observations.set(state, original);\n baselines.set(state, original);\n return state;\n }\n\n function notify(settings: ExecutionOptions, message: string): void {\n try {\n settings.onProgress?.(message);\n } catch {\n /* Feedback is observational. */\n }\n }\n\n function phase(settings: ExecutionOptions, value: RequestPhase): void {\n try {\n settings.onPhaseChange?.(value);\n } catch {\n /* Feedback is observational. */\n }\n }\n\n async function own<T>(\n settings: ExecutionOptions,\n perform: (signal: AbortSignal) => Promise<T>,\n ): Promise<T> {\n if (busy) {\n // React Strict Mode can start a replacement before the cancelled call's\n // finally block runs. Wait for that owner rather than overlapping actions.\n if (currentSignal?.aborted) {\n await settled;\n return own(settings, perform);\n }\n throw new RuaKitError('BUSY', 'A RuaKit request is already running.');\n }\n busy = true;\n let release!: () => void;\n settled = new Promise<void>((resolve) => {\n release = resolve;\n });\n try {\n validateRequestTimeout(settings.timeoutMs ?? 8000);\n const operation = createRequestOperation(settings.requestTimeoutMs ?? 60000, settings.signal);\n currentSignal = operation.signal;\n active = settings;\n try {\n operation.signal.throwIfAborted();\n return await perform(operation.signal);\n } finally {\n operation.dispose();\n }\n } finally {\n active = undefined;\n currentSignal = undefined;\n busy = false;\n release();\n }\n }\n\n function receipt(\n events: string[],\n decision: Decision,\n level: 'observed' | 'confirmed' = 'observed',\n ): ExecutionResult {\n return {\n planId: `dom-${Date.now()}-${++sequence}`,\n status: 'triggered',\n events,\n ...(decision.type === 'complete'\n ? {\n goalCompleted: true as const,\n message: decision.message,\n verification: { level, checks: decision.checks },\n }\n : {}),\n };\n }\n\n async function apply(\n value: unknown,\n source: PageState,\n signal: AbortSignal,\n settings: ExecutionOptions,\n verification?: {\n baseline: PageState;\n checks: CompletionCheck[] | undefined;\n prompt: string | undefined;\n requirePreparation?: boolean;\n },\n ): Promise<Decision> {\n signal.throwIfAborted();\n const observed = observations.get(source);\n if (!observed) {\n throw new RuaKitError('INVALID_PLAN', 'Use an unused snapshot from this Rua session.');\n }\n const decision = parsePayload(\n decisionSchema,\n value,\n 'INVALID_PLAN',\n 'The planner returned an invalid decision.',\n );\n observations.delete(source);\n notify(settings, decision.message);\n signal.throwIfAborted();\n if (decision.type === 'clarify') {\n throw new ClarificationNeededError({\n type: 'clarification',\n question: decision.message,\n options: [],\n });\n }\n if (decision.type === 'unsupported') {\n throw new RuaKitError('UNAVAILABLE', decision.message);\n }\n if (decision.type === 'complete') {\n const checks = verification?.checks ?? decision.checks;\n if (JSON.stringify(checks) !== JSON.stringify(decision.checks)) {\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Completion checks cannot change after execution begins.',\n );\n }\n const baseline = verification?.baseline ?? observed;\n if (\n !evaluateCompletionChecks(checks, observed, baseline).passed ||\n !evaluateCompletionChecks(checks, dom.getState(), baseline).passed\n ) {\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'The requested outcomes are not all present on the live page.',\n );\n }\n if (settings.verifyCompletion) {\n const confirmed = await runWithSignal(signal, () =>\n settings.verifyCompletion!({\n prompt: verification?.prompt,\n checks: structuredClone(checks),\n baseline: structuredClone(baseline),\n snapshot: dom.getState(),\n signal,\n }),\n );\n signal.throwIfAborted();\n if (confirmed !== true)\n throw new RuaKitError(\n 'VERIFICATION_FAILED',\n 'The application could not confirm the requested outcome.',\n );\n if (!evaluateCompletionChecks(checks, dom.getState(), baseline).passed) {\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'The page changed while the application verified completion.',\n );\n }\n }\n return decision;\n }\n if (decision.type === 'prepare' || decision.type === 'screenshot') return decision;\n if (verification?.requirePreparation && !verification.checks) {\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Establish completion checks with prepare before taking actions.',\n );\n }\n const step = decision.step;\n const control = observed.controls.find(\n (item) => item.target.id === step.target.id && item.target.version === step.target.version,\n );\n if (!control || !control.enabled) {\n throw new RuaKitError('INVALID_PLAN', 'The planner selected an unavailable live DOM target.');\n }\n if (decision.type === 'approval') {\n await requestApproval(decision, observed, signal, settings, verification?.prompt);\n }\n phase(settings, 'executing');\n const action = { signal, timeoutMs: settings.timeoutMs ?? 8000 };\n switch (step.type) {\n case 'focus':\n await dom.focus(step.target, action);\n break;\n case 'key':\n await dom.pressKey(step.target, step.key, {\n ...action,\n altKey: step.altKey,\n ctrlKey: step.ctrlKey,\n metaKey: step.metaKey,\n shiftKey: step.shiftKey,\n });\n break;\n case 'insertText':\n await dom.insertText(step.target, step.text, action);\n break;\n case 'click':\n await dom.click(step.target, action);\n break;\n case 'fill':\n await dom.setValue(step.target, step.value, action);\n break;\n case 'select':\n await dom.selectOption(step.target, step.values, action);\n break;\n case 'check':\n await dom.setChecked(step.target, step.checked, action);\n break;\n }\n signal.throwIfAborted();\n return decision;\n }\n\n const planEngine: PlanEngine = {\n platform: document.defaultView?.navigator.platform ?? '',\n snapshot, apply,\n screenshot: (signal, timeoutMs) => dom.screenshot({ signal, timeoutMs }),\n };\n\n return {\n document,\n snapshot,\n executePlan: (plan, options = {}) => own(options, (signal) => executePlan(planEngine, plan, signal, options)),\n createPlanTask: () => createPlanTask(planEngine, own),\n run: (decision, settings) =>\n own(settings, async (signal) => {\n const baseline = settings.baseline ? baselines.get(settings.baseline) : undefined;\n if (settings.baseline && !baseline)\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Use an original session observation as the verification baseline.',\n );\n const checks = settings.checks ? completionChecksSchema.parse(settings.checks) : undefined;\n const applied = await apply(decision, settings.snapshot, signal, settings, {\n baseline: baseline ?? observations.get(settings.snapshot) ?? settings.snapshot,\n checks,\n prompt: undefined,\n });\n const result = receipt(\n [applied.message.slice(0, 500)],\n applied,\n settings.verifyCompletion ? 'confirmed' : 'observed',\n );\n if (applied.type === 'screenshot')\n result.screenshot = await dom.screenshot({\n signal,\n timeoutMs: settings.timeoutMs ?? 8000,\n });\n return result;\n }),\n plan: (prompt, request, settings = {}) =>\n own(settings, async (signal) => {\n const history: Decision[] = [];\n const events: string[] = [];\n let checks: CompletionCheck[] | undefined;\n let baseline: PageState | undefined;\n let image: Screenshot | undefined;\n notify(settings, REQUEST_MESSAGES.observing);\n while (true) {\n signal.throwIfAborted();\n phase(settings, 'observing');\n const source = snapshot();\n baseline ??= structuredClone(source);\n if (image && image.url !== source.url) image = undefined;\n const input = parsePayload(\n decisionRequestSchema,\n {\n platform: document.defaultView?.navigator.platform ?? '',\n prompt,\n clarifications: settings.clarifications ?? [],\n snapshot: source,\n history: history.slice(-20),\n checks: checks ? structuredClone(checks) : null,\n canScreenshot: true,\n ...(image ? { screenshot: image } : {}),\n },\n 'INVALID_REQUEST',\n 'Enter a valid request for the current application page.',\n );\n phase(settings, 'planning');\n const decision = await apply(\n await runWithSignal(signal, () => request(input, signal)),\n source,\n signal,\n settings,\n { baseline, checks, prompt, requirePreparation: true },\n );\n events.push(decision.message.slice(0, 500));\n if (decision.type === 'complete') {\n return receipt(events, decision, settings.verifyCompletion ? 'confirmed' : 'observed');\n }\n if (decision.type === 'prepare') {\n if (checks)\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Completion checks cannot change after preparation.',\n );\n checks = structuredClone(decision.checks);\n }\n if (decision.type === 'screenshot') {\n if (image)\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Use the supplied screenshot before requesting another image.',\n );\n image = await dom.screenshot({ signal, timeoutMs: settings.timeoutMs ?? 8000 });\n } else image = undefined;\n history.push(decision);\n }\n }),\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["REQUEST_MESSAGES", "createDomRuntime", "completionChecksSchema", "evaluateCompletionChecks", "decisionSchema", "decisionRequestSchema", "ClarificationNeededError", "RuaKitError", "parsePayload", "createRequestOperation", "runWithSignal", "validateRequestTimeout", "executePlan", "createPlanTask", "requestApproval", "createSession", "options", "document", "active", "busy", "currentSignal", "settled", "sequence", "observations", "baselines", "dom", "__name", "event", "snapshot", "state", "original", "notify", "settings", "message", "phase", "value", "own", "perform", "release", "resolve", "operation", "receipt", "events", "decision", "level", "apply", "source", "signal", "verification", "observed", "checks", "baseline", "confirmed", "step", "control", "item", "action", "planEngine", "timeoutMs", "plan", "applied", "result", "prompt", "request", "history", "image", "input"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DecisionRequest, Decision } from '@ruakit/schema';
|
|
2
|
+
/** Replace HTTP with another planner without changing browser execution. */
|
|
3
|
+
export interface RuaKitTransport {
|
|
4
|
+
dom(request: DecisionRequest, signal: AbortSignal): Promise<Decision>;
|
|
5
|
+
}
|
|
6
|
+
export interface HttpTransportOptions {
|
|
7
|
+
serverUrl?: string;
|
|
8
|
+
fetch?: typeof globalThis.fetch;
|
|
9
|
+
}
|
|
10
|
+
export declare function createHttpTransport(options?: HttpTransportOptions): RuaKitTransport;
|
|
11
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAGhE,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,CAoCvF"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var d=Object.defineProperty;var n=(r,t)=>d(r,"name",{value:t,configurable:!0});import{decisionSchema as h}from"@ruakit/schema";import{RuaKitError as s,parsePayload as p}from"./errors.js";function m(r={}){const t=r.fetch??globalThis.fetch.bind(globalThis),i=(r.serverUrl??"").replace(/\/$/,"");return{async dom(c,l){const o=await t(`${i}/v1/plan`,{method:"POST",signal:l,cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});let e;try{e=await o.json()}catch(a){throw new s("HTTP_ERROR","The server returned invalid JSON.",{cause:a})}if(!o.ok){const a=typeof e=="object"&&e!==null&&"error"in e&&typeof e.error=="string"?e.error:`RuaKit request failed (${o.status}).`;throw new s("HTTP_ERROR",a)}return p(h,e,"INVALID_PLAN","The server returned an invalid decision.")}}}n(m,"createHttpTransport");export{m as createHttpTransport};
|
|
3
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/transport.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { decisionSchema } from '@ruakit/schema';\nimport type { DecisionRequest, Decision } from '@ruakit/schema';\nimport { RuaKitError, parsePayload } from './errors.js';\n\n/** Replace HTTP with another planner without changing browser execution. */\nexport interface RuaKitTransport {\n dom(request: DecisionRequest, signal: AbortSignal): Promise<Decision>;\n}\n\nexport interface HttpTransportOptions {\n serverUrl?: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport function createHttpTransport(options: HttpTransportOptions = {}): RuaKitTransport {\n const fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);\n const base = (options.serverUrl ?? '').replace(/\\/$/, '');\n return {\n async dom(request, signal) {\n const response = await fetcher(`${base}/v1/plan`, {\n method: 'POST',\n signal,\n cache: 'no-store',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n let data: unknown;\n try {\n data = await response.json();\n } catch (cause) {\n throw new RuaKitError('HTTP_ERROR', 'The server returned invalid JSON.', { cause });\n }\n if (!response.ok) {\n const message =\n typeof data === 'object' &&\n data !== null &&\n 'error' in data &&\n typeof data.error === 'string'\n ? data.error\n : `RuaKit request failed (${response.status}).`;\n throw new RuaKitError('HTTP_ERROR', message);\n }\n return parsePayload(\n decisionSchema,\n data,\n 'INVALID_PLAN',\n 'The server returned an invalid decision.',\n );\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";+EACA,OAAS,kBAAAA,MAAsB,iBAE/B,OAAS,eAAAC,EAAa,gBAAAC,MAAoB,cAYpC,SAAUC,EAAoBC,EAAgC,CAAA,EAAE,CACpE,MAAMC,EAAUD,EAAQ,OAAS,WAAW,MAAM,KAAK,UAAU,EAC3DE,GAAQF,EAAQ,WAAa,IAAI,QAAQ,MAAO,EAAE,EACxD,MAAO,CACL,MAAM,IAAIG,EAASC,EAAM,CACvB,MAAMC,EAAW,MAAMJ,EAAQ,GAAGC,CAAI,WAAY,CAChD,OAAQ,OACR,OAAAE,EACA,MAAO,WACP,QAAS,CAAE,eAAgB,kBAAkB,EAC7C,KAAM,KAAK,UAAUD,CAAO,EAC7B,EACD,IAAIG,EACJ,GAAI,CACFA,EAAO,MAAMD,EAAS,KAAI,CAC5B,OAASE,EAAO,CACd,MAAM,IAAIV,EAAY,aAAc,oCAAqC,CAAE,MAAAU,CAAK,CAAE,CACpF,CACA,GAAI,CAACF,EAAS,GAAI,CAChB,MAAMG,EACJ,OAAOF,GAAS,UAChBA,IAAS,MACT,UAAWA,GACX,OAAOA,EAAK,OAAU,SAClBA,EAAK,MACL,0BAA0BD,EAAS,MAAM,KAC/C,MAAM,IAAIR,EAAY,aAAcW,CAAO,CAC7C,CACA,OAAOV,EACLF,EACAU,EACA,eACA,0CAA0C,CAE9C,EAEJ,CApCgBG,EAAAV,EAAA",
|
|
6
|
+
"names": ["decisionSchema", "RuaKitError", "parsePayload", "createHttpTransport", "options", "fetcher", "base", "request", "signal", "response", "data", "cause", "message", "__name"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare class UserInterruptedError extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
/** Real keyboard/pointer input interrupts; synthetic agent events do not. */
|
|
5
|
+
export declare function watchUserInterruption(document: Document, controller: AbortController): () => void;
|
|
6
|
+
//# sourceMappingURL=user-interruption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-interruption.d.ts","sourceRoot":"","sources":["../src/user-interruption.ts"],"names":[],"mappings":"AACA,qBAAa,oBAAqB,SAAQ,KAAK;;CAK9C;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,GAAG,MAAM,IAAI,CAejG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
export class UserInterruptedError extends Error {
|
|
3
|
+
constructor() {
|
|
4
|
+
super('Stopped because you interacted with the page.');
|
|
5
|
+
this.name = 'UserInterruptedError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/** Real keyboard/pointer input interrupts; synthetic agent events do not. */
|
|
9
|
+
export function watchUserInterruption(document, controller) {
|
|
10
|
+
const types = ['keydown', 'pointerdown', 'wheel'];
|
|
11
|
+
const interrupt = (event) => {
|
|
12
|
+
if (event.isTrusted && !controller.signal.aborted) {
|
|
13
|
+
controller.abort(new UserInterruptedError());
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
for (const type of types) {
|
|
17
|
+
document.addEventListener(type, interrupt, { capture: true, passive: true });
|
|
18
|
+
}
|
|
19
|
+
return () => {
|
|
20
|
+
for (const type of types) {
|
|
21
|
+
document.removeEventListener(type, interrupt, true);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=user-interruption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-interruption.js","sourceRoot":"","sources":["../src/user-interruption.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C;QACE,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CAAC,QAAkB,EAAE,UAA2B;IACnF,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,CAAU,CAAC;IAC3D,MAAM,SAAS,GAAG,CAAC,KAAY,EAAE,EAAE;QACjC,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClD,UAAU,CAAC,KAAK,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,EAAE;QACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,QAAQ,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruakit/agent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Framework-agnostic agent orchestration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"src",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE",
|
|
12
|
+
"NOTICE"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@ruakit/runtime": "^0.1.0-alpha.1",
|
|
23
|
+
"@ruakit/schema": "^0.1.0-alpha.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/react": "19.3.0",
|
|
27
|
+
"@types/react-dom": "19.3.0",
|
|
28
|
+
"react": "18.3.1",
|
|
29
|
+
"react-dom": "18.3.1"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -p tsconfig.json && node ../shared/scripts/minify.mjs",
|
|
33
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
34
|
+
}
|
|
6
35
|
}
|
package/src/approval.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
import type { ApprovalDecision, PlanApproval } from '@ruakit/schema';
|
|
3
|
+
import type { PageState } from '@ruakit/runtime';
|
|
4
|
+
import { ApprovalNeededError, RuaKitError } from './errors.js';
|
|
5
|
+
import { runWithSignal } from './operations.js';
|
|
6
|
+
|
|
7
|
+
export type ApprovalRequest = ApprovalDecision | PlanApproval;
|
|
8
|
+
|
|
9
|
+
export interface ApprovalContext {
|
|
10
|
+
/** A detached copy. Editing it cannot change the action awaiting approval. */
|
|
11
|
+
approval: ApprovalRequest;
|
|
12
|
+
snapshot: PageState;
|
|
13
|
+
prompt: string | undefined;
|
|
14
|
+
signal: AbortSignal;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ApprovalOptions {
|
|
18
|
+
/** Ask the user through trusted host UI. Only exactly true grants approval. */
|
|
19
|
+
onApproval?: (context: ApprovalContext) => boolean | Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The model chooses the gate; the host owns the user's answer. Never infer consent. */
|
|
23
|
+
export async function requestApproval(
|
|
24
|
+
approval: ApprovalRequest,
|
|
25
|
+
snapshot: PageState,
|
|
26
|
+
signal: AbortSignal,
|
|
27
|
+
options: ApprovalOptions,
|
|
28
|
+
prompt?: string,
|
|
29
|
+
): Promise<void> {
|
|
30
|
+
signal.throwIfAborted();
|
|
31
|
+
if (!options.onApproval)
|
|
32
|
+
throw new ApprovalNeededError(structuredClone(approval));
|
|
33
|
+
const accepted = await runWithSignal(signal, () =>
|
|
34
|
+
options.onApproval!({
|
|
35
|
+
approval: structuredClone(approval),
|
|
36
|
+
snapshot: structuredClone(snapshot),
|
|
37
|
+
prompt,
|
|
38
|
+
signal,
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
signal.throwIfAborted();
|
|
42
|
+
if (accepted !== true)
|
|
43
|
+
throw new RuaKitError(
|
|
44
|
+
'APPROVAL_DENIED',
|
|
45
|
+
'The proposed action was not approved.',
|
|
46
|
+
);
|
|
47
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
/** Default messages shown during a request. */
|
|
4
|
+
export const REQUEST_MESSAGES = {
|
|
5
|
+
ready: "Ready",
|
|
6
|
+
thinking: "Thinking…",
|
|
7
|
+
observing: "Observing the current page…",
|
|
8
|
+
replanning: "The page changed. Planning the remaining steps…",
|
|
9
|
+
checkingApproval: "Checking the approval response…",
|
|
10
|
+
cancelling: "Cancelling request…",
|
|
11
|
+
cancelled: "Request cancelled",
|
|
12
|
+
triggered: "Actions triggered",
|
|
13
|
+
} as const;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
import { RuaKitError } from './errors.js';
|
|
3
|
+
import { validateRequestTimeout } from './operations.js';
|
|
4
|
+
import type { RuntimeOptions, RuaKitRuntime } from './runtime.js';
|
|
5
|
+
import { createSession } from './session.js';
|
|
6
|
+
import type { RuaKitTransport } from './transport.js';
|
|
7
|
+
|
|
8
|
+
/** The default integration uses the same primitives as custom planning loops. */
|
|
9
|
+
export function createDecisionRuntime(
|
|
10
|
+
options: RuntimeOptions,
|
|
11
|
+
transport: RuaKitTransport,
|
|
12
|
+
): RuaKitRuntime {
|
|
13
|
+
const session = options.session ?? createSession(options);
|
|
14
|
+
if (options.document && options.document !== session.document) {
|
|
15
|
+
throw new RuaKitError('INVALID_REQUEST', 'The Rua session belongs to a different document.');
|
|
16
|
+
}
|
|
17
|
+
validateRequestTimeout(options.requestTimeoutMs ?? 60000);
|
|
18
|
+
validateRequestTimeout(options.timeoutMs ?? 8000);
|
|
19
|
+
return {
|
|
20
|
+
request: (prompt, settings = {}) =>
|
|
21
|
+
session.plan(prompt, (input, signal) => transport.dom(input, signal), {
|
|
22
|
+
...options,
|
|
23
|
+
...settings,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
import type { Clarification } from '@ruakit/schema';
|
|
3
|
+
import type { ApprovalRequest } from './approval.js';
|
|
4
|
+
export type RuntimeErrorCode =
|
|
5
|
+
| 'INVALID_REQUEST'
|
|
6
|
+
| 'INVALID_PLAN'
|
|
7
|
+
| 'UNAVAILABLE'
|
|
8
|
+
| 'STALE_TARGET'
|
|
9
|
+
| 'BUSY'
|
|
10
|
+
| 'HTTP_ERROR'
|
|
11
|
+
| 'CLARIFICATION_REQUIRED'
|
|
12
|
+
| 'APPROVAL_REQUIRED'
|
|
13
|
+
| 'APPROVAL_DENIED'
|
|
14
|
+
| 'VERIFICATION_FAILED'
|
|
15
|
+
| 'REPLAN_LIMIT';
|
|
16
|
+
|
|
17
|
+
/** Errors expose a stable code for embedding applications and a readable message for the toolbar. */
|
|
18
|
+
export class RuaKitError extends Error {
|
|
19
|
+
constructor(
|
|
20
|
+
readonly code: RuntimeErrorCode,
|
|
21
|
+
message: string,
|
|
22
|
+
options?: ErrorOptions,
|
|
23
|
+
) {
|
|
24
|
+
super(message, options);
|
|
25
|
+
this.name = 'RuaKitError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A validated conversational response. Headless consumers can present it and resend with answers. */
|
|
30
|
+
export class ClarificationNeededError extends RuaKitError {
|
|
31
|
+
constructor(readonly clarification: Clarification) {
|
|
32
|
+
super('CLARIFICATION_REQUIRED', clarification.question);
|
|
33
|
+
this.name = 'ClarificationNeededError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** No approval handler was supplied. The proposed action or plan has not executed. */
|
|
38
|
+
export class ApprovalNeededError extends RuaKitError {
|
|
39
|
+
constructor(readonly approval: ApprovalRequest) {
|
|
40
|
+
super('APPROVAL_REQUIRED', approval.message);
|
|
41
|
+
this.name = 'ApprovalNeededError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function parsePayload<T>(
|
|
46
|
+
schema: { parse(value: unknown): T },
|
|
47
|
+
value: unknown,
|
|
48
|
+
code: RuntimeErrorCode,
|
|
49
|
+
message: string,
|
|
50
|
+
): T {
|
|
51
|
+
try {
|
|
52
|
+
return schema.parse(value);
|
|
53
|
+
} catch (cause) {
|
|
54
|
+
throw new RuaKitError(code, message, { cause });
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
export { createRuntime } from './runtime.js';
|
|
3
|
+
export type { RuntimeOptions, PlanRuntimeOptions, RequestOptions, RuaKitRuntime } from './runtime.js';
|
|
4
|
+
export { createSession } from './session.js';
|
|
5
|
+
export type {
|
|
6
|
+
RuaSession,
|
|
7
|
+
ExecutionOptions,
|
|
8
|
+
RunOptions,
|
|
9
|
+
PlanOptions,
|
|
10
|
+
CompletionContext,
|
|
11
|
+
} from './session.js';
|
|
12
|
+
export type { PageState } from '@ruakit/runtime';
|
|
13
|
+
export { createHttpTransport } from './transport.js';
|
|
14
|
+
export type { HttpTransportOptions, RuaKitTransport } from './transport.js';
|
|
15
|
+
export { createPlanTransport } from './plan-transport.js';
|
|
16
|
+
export type { PlanTransport, PlanHttpTransportOptions } from './plan-transport.js';
|
|
17
|
+
export type { PlanExecutionOptions, PlanExecutionResult, PlanPlanner, PlanTaskOptions, PlanTask } from './plan.js';
|
|
18
|
+
export { RuaKitError, ClarificationNeededError, ApprovalNeededError } from './errors.js';
|
|
19
|
+
export type { ApprovalContext, ApprovalRequest, ApprovalOptions } from './approval.js';
|
|
20
|
+
export type { RuntimeErrorCode } from './errors.js';
|
|
21
|
+
export type { RequestPhase, RequestState } from './request-state.js';
|
|
22
|
+
export type {
|
|
23
|
+
ActionFeedbackOptions,
|
|
24
|
+
ActionRect,
|
|
25
|
+
RuntimeAction,
|
|
26
|
+
RuntimeActionEvent,
|
|
27
|
+
} from '@ruakit/runtime';
|
|
28
|
+
export type {
|
|
29
|
+
Clarification,
|
|
30
|
+
ClarificationTurn,
|
|
31
|
+
ExecutionResult,
|
|
32
|
+
CompletionCheck,
|
|
33
|
+
DecisionRequest,
|
|
34
|
+
Decision,
|
|
35
|
+
ApprovalDecision,
|
|
36
|
+
PlanApproval,
|
|
37
|
+
Plan, PlannedStep, CompletedPlanStep, Replan, PlanRequest, PlanResponse, JsonValue,
|
|
38
|
+
} from '@ruakit/schema';
|
|
39
|
+
|
|
40
|
+
export { INITIAL_REQUEST_STATE, requestIsBusy, requestReducer } from './request-state.js';
|
|
41
|
+
export type { RequestEvent } from './request-state.js';
|
|
42
|
+
export { toRequestError } from './request-outcome.js';
|
|
43
|
+
export type {
|
|
44
|
+
RequestCorrelation,
|
|
45
|
+
RequestIdentity,
|
|
46
|
+
RequestError,
|
|
47
|
+
RequestOutcome,
|
|
48
|
+
} from './request-outcome.js';
|
|
49
|
+
|
|
50
|
+
export type { Screenshot, ScreenshotImage } from '@ruakit/runtime';
|