@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RuaKit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ApprovalDecision, PlanApproval } from '@ruakit/schema';
|
|
2
|
+
import type { PageState } from '@ruakit/runtime';
|
|
3
|
+
export type ApprovalRequest = ApprovalDecision | PlanApproval;
|
|
4
|
+
export interface ApprovalContext {
|
|
5
|
+
/** A detached copy. Editing it cannot change the action awaiting approval. */
|
|
6
|
+
approval: ApprovalRequest;
|
|
7
|
+
snapshot: PageState;
|
|
8
|
+
prompt: string | undefined;
|
|
9
|
+
signal: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
export interface ApprovalOptions {
|
|
12
|
+
/** Ask the user through trusted host UI. Only exactly true grants approval. */
|
|
13
|
+
onApproval?: (context: ApprovalContext) => boolean | Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
/** The model chooses the gate; the host owns the user's answer. Never infer consent. */
|
|
16
|
+
export declare function requestApproval(approval: ApprovalRequest, snapshot: PageState, signal: AbortSignal, options: ApprovalOptions, prompt?: string): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../src/approval.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,YAAY,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvE;AAED,wFAAwF;AACxF,wBAAsB,eAAe,CACnC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,SAAS,EACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,eAAe,EACxB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
package/dist/approval.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var u=Object.defineProperty;var p=(r,t)=>u(r,"name",{value:t,configurable:!0});import{ApprovalNeededError as d,RuaKitError as c}from"./errors.js";import{runWithSignal as w}from"./operations.js";async function i(r,t,o,e,n){if(o.throwIfAborted(),!e.onApproval)throw new d(structuredClone(r));const a=await w(o,()=>e.onApproval({approval:structuredClone(r),snapshot:structuredClone(t),prompt:n,signal:o}));if(o.throwIfAborted(),a!==!0)throw new c("APPROVAL_DENIED","The proposed action was not approved.")}p(i,"requestApproval");export{i as requestApproval};
|
|
3
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/approval.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport type { ApprovalDecision, PlanApproval } from '@ruakit/schema';\nimport type { PageState } from '@ruakit/runtime';\nimport { ApprovalNeededError, RuaKitError } from './errors.js';\nimport { runWithSignal } from './operations.js';\n\nexport type ApprovalRequest = ApprovalDecision | PlanApproval;\n\nexport interface ApprovalContext {\n /** A detached copy. Editing it cannot change the action awaiting approval. */\n approval: ApprovalRequest;\n snapshot: PageState;\n prompt: string | undefined;\n signal: AbortSignal;\n}\n\nexport interface ApprovalOptions {\n /** Ask the user through trusted host UI. Only exactly true grants approval. */\n onApproval?: (context: ApprovalContext) => boolean | Promise<boolean>;\n}\n\n/** The model chooses the gate; the host owns the user's answer. Never infer consent. */\nexport async function requestApproval(\n approval: ApprovalRequest,\n snapshot: PageState,\n signal: AbortSignal,\n options: ApprovalOptions,\n prompt?: string,\n): Promise<void> {\n signal.throwIfAborted();\n if (!options.onApproval)\n throw new ApprovalNeededError(structuredClone(approval));\n const accepted = await runWithSignal(signal, () =>\n options.onApproval!({\n approval: structuredClone(approval),\n snapshot: structuredClone(snapshot),\n prompt,\n signal,\n }),\n );\n signal.throwIfAborted();\n if (accepted !== true)\n throw new RuaKitError(\n 'APPROVAL_DENIED',\n 'The proposed action was not approved.',\n );\n}\n"],
|
|
5
|
+
"mappings": ";+EAGA,OAAS,uBAAAA,EAAqB,eAAAC,MAAmB,cACjD,OAAS,iBAAAC,MAAqB,kBAkB9B,eAAsBC,EACpBC,EACAC,EACAC,EACAC,EACAC,EAAe,CAGf,GADAF,EAAO,eAAc,EACjB,CAACC,EAAQ,WACX,MAAM,IAAIP,EAAoB,gBAAgBI,CAAQ,CAAC,EACzD,MAAMK,EAAW,MAAMP,EAAcI,EAAQ,IAC3CC,EAAQ,WAAY,CAClB,SAAU,gBAAgBH,CAAQ,EAClC,SAAU,gBAAgBC,CAAQ,EAClC,OAAAG,EACA,OAAAF,EACD,CAAC,EAGJ,GADAA,EAAO,eAAc,EACjBG,IAAa,GACf,MAAM,IAAIR,EACR,kBACA,uCAAuC,CAE7C,CAxBsBS,EAAAP,EAAA",
|
|
6
|
+
"names": ["ApprovalNeededError", "RuaKitError", "runWithSignal", "requestApproval", "approval", "snapshot", "signal", "options", "prompt", "accepted", "__name"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Default messages shown during a request. */
|
|
2
|
+
export declare const REQUEST_MESSAGES: {
|
|
3
|
+
readonly ready: "Ready";
|
|
4
|
+
readonly thinking: "Thinking…";
|
|
5
|
+
readonly observing: "Observing the current page…";
|
|
6
|
+
readonly replanning: "The page changed. Planning the remaining steps…";
|
|
7
|
+
readonly checkingApproval: "Checking the approval response…";
|
|
8
|
+
readonly cancelling: "Cancelling request…";
|
|
9
|
+
readonly cancelled: "Request cancelled";
|
|
10
|
+
readonly triggered: "Actions triggered";
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB;;;;;;;;;CASnB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
const e={ready:"Ready",thinking:"Thinking\u2026",observing:"Observing the current page\u2026",replanning:"The page changed. Planning the remaining steps\u2026",checkingApproval:"Checking the approval response\u2026",cancelling:"Cancelling request\u2026",cancelled:"Request cancelled",triggered:"Actions triggered"};export{e as REQUEST_MESSAGES};
|
|
3
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/constants.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\n\n/** Default messages shown during a request. */\nexport const REQUEST_MESSAGES = {\n ready: \"Ready\",\n thinking: \"Thinking\u2026\",\n observing: \"Observing the current page\u2026\",\n replanning: \"The page changed. Planning the remaining steps\u2026\",\n checkingApproval: \"Checking the approval response\u2026\",\n cancelling: \"Cancelling request\u2026\",\n cancelled: \"Request cancelled\",\n triggered: \"Actions triggered\",\n} as const;\n"],
|
|
5
|
+
"mappings": ";AAGO,MAAMA,EAAmB,CAC9B,MAAO,QACP,SAAU,iBACV,UAAW,mCACX,WAAY,uDACZ,iBAAkB,uCAClB,WAAY,2BACZ,UAAW,oBACX,UAAW",
|
|
6
|
+
"names": ["REQUEST_MESSAGES"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RuntimeOptions, RuaKitRuntime } from './runtime.js';
|
|
2
|
+
import type { RuaKitTransport } from './transport.js';
|
|
3
|
+
/** The default integration uses the same primitives as custom planning loops. */
|
|
4
|
+
export declare function createDecisionRuntime(options: RuntimeOptions, transport: RuaKitTransport): RuaKitRuntime;
|
|
5
|
+
//# sourceMappingURL=decision-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-runtime.d.ts","sourceRoot":"","sources":["../src/decision-runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,eAAe,GACzB,aAAa,CAcf"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var c=Object.defineProperty;var r=(e,t)=>c(e,"name",{value:t,configurable:!0});import{RuaKitError as a}from"./errors.js";import{validateRequestTimeout as u}from"./operations.js";import{createSession as d}from"./session.js";function q(e,t){const m=e.session??d(e);if(e.document&&e.document!==m.document)throw new a("INVALID_REQUEST","The Rua session belongs to a different document.");return u(e.requestTimeoutMs??6e4),u(e.timeoutMs??8e3),{request:r((o,s={})=>m.plan(o,(i,n)=>t.dom(i,n),{...e,...s}),"request")}}r(q,"createDecisionRuntime");export{q as createDecisionRuntime};
|
|
3
|
+
//# sourceMappingURL=decision-runtime.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/decision-runtime.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { RuaKitError } from './errors.js';\nimport { validateRequestTimeout } from './operations.js';\nimport type { RuntimeOptions, RuaKitRuntime } from './runtime.js';\nimport { createSession } from './session.js';\nimport type { RuaKitTransport } from './transport.js';\n\n/** The default integration uses the same primitives as custom planning loops. */\nexport function createDecisionRuntime(\n options: RuntimeOptions,\n transport: RuaKitTransport,\n): RuaKitRuntime {\n const session = options.session ?? createSession(options);\n if (options.document && options.document !== session.document) {\n throw new RuaKitError('INVALID_REQUEST', 'The Rua session belongs to a different document.');\n }\n validateRequestTimeout(options.requestTimeoutMs ?? 60000);\n validateRequestTimeout(options.timeoutMs ?? 8000);\n return {\n request: (prompt, settings = {}) =>\n session.plan(prompt, (input, signal) => transport.dom(input, signal), {\n ...options,\n ...settings,\n }),\n };\n}\n"],
|
|
5
|
+
"mappings": ";+EACA,OAAS,eAAAA,MAAmB,cAC5B,OAAS,0BAAAC,MAA8B,kBAEvC,OAAS,iBAAAC,MAAqB,eAIxB,SAAUC,EACdC,EACAC,EAA0B,CAE1B,MAAMC,EAAUF,EAAQ,SAAWF,EAAcE,CAAO,EACxD,GAAIA,EAAQ,UAAYA,EAAQ,WAAaE,EAAQ,SACnD,MAAM,IAAIN,EAAY,kBAAmB,kDAAkD,EAE7F,OAAAC,EAAuBG,EAAQ,kBAAoB,GAAK,EACxDH,EAAuBG,EAAQ,WAAa,GAAI,EACzC,CACL,QAASG,EAAA,CAACC,EAAQC,EAAW,CAAA,IAC3BH,EAAQ,KAAKE,EAAQ,CAACE,EAAOC,IAAWN,EAAU,IAAIK,EAAOC,CAAM,EAAG,CACpE,GAAGP,EACH,GAAGK,EACJ,EAJM,WAMb,CAjBgBF,EAAAJ,EAAA",
|
|
6
|
+
"names": ["RuaKitError", "validateRequestTimeout", "createSession", "createDecisionRuntime", "options", "transport", "session", "__name", "prompt", "settings", "input", "signal"]
|
|
7
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Clarification } from '@ruakit/schema';
|
|
2
|
+
import type { ApprovalRequest } from './approval.js';
|
|
3
|
+
export type RuntimeErrorCode = 'INVALID_REQUEST' | 'INVALID_PLAN' | 'UNAVAILABLE' | 'STALE_TARGET' | 'BUSY' | 'HTTP_ERROR' | 'CLARIFICATION_REQUIRED' | 'APPROVAL_REQUIRED' | 'APPROVAL_DENIED' | 'VERIFICATION_FAILED' | 'REPLAN_LIMIT';
|
|
4
|
+
/** Errors expose a stable code for embedding applications and a readable message for the toolbar. */
|
|
5
|
+
export declare class RuaKitError extends Error {
|
|
6
|
+
readonly code: RuntimeErrorCode;
|
|
7
|
+
constructor(code: RuntimeErrorCode, message: string, options?: ErrorOptions);
|
|
8
|
+
}
|
|
9
|
+
/** A validated conversational response. Headless consumers can present it and resend with answers. */
|
|
10
|
+
export declare class ClarificationNeededError extends RuaKitError {
|
|
11
|
+
readonly clarification: Clarification;
|
|
12
|
+
constructor(clarification: Clarification);
|
|
13
|
+
}
|
|
14
|
+
/** No approval handler was supplied. The proposed action or plan has not executed. */
|
|
15
|
+
export declare class ApprovalNeededError extends RuaKitError {
|
|
16
|
+
readonly approval: ApprovalRequest;
|
|
17
|
+
constructor(approval: ApprovalRequest);
|
|
18
|
+
}
|
|
19
|
+
export declare function parsePayload<T>(schema: {
|
|
20
|
+
parse(value: unknown): T;
|
|
21
|
+
}, value: unknown, code: RuntimeErrorCode, message: string): T;
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,MAAM,MAAM,gBAAgB,GACxB,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,cAAc,GACd,MAAM,GACN,YAAY,GACZ,wBAAwB,GACxB,mBAAmB,GACnB,iBAAiB,GACjB,qBAAqB,GACrB,cAAc,CAAC;AAEnB,qGAAqG;AACrG,qBAAa,WAAY,SAAQ,KAAK;IAElC,QAAQ,CAAC,IAAI,EAAE,gBAAgB;gBAAtB,IAAI,EAAE,gBAAgB,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY;CAKzB;AAED,sGAAsG;AACtG,qBAAa,wBAAyB,SAAQ,WAAW;IAC3C,QAAQ,CAAC,aAAa,EAAE,aAAa;gBAA5B,aAAa,EAAE,aAAa;CAIlD;AAED,sFAAsF;AACtF,qBAAa,mBAAoB,SAAQ,WAAW;IACtC,QAAQ,CAAC,QAAQ,EAAE,eAAe;gBAAzB,QAAQ,EAAE,eAAe;CAI/C;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,MAAM,EAAE;IAAE,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,CAAA;CAAE,EACpC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,GACd,CAAC,CAMH"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});class a extends Error{static{t(this,"RuaKitError")}code;constructor(r,o,s){super(o,s),this.code=r,this.name="RuaKitError"}}class p extends a{static{t(this,"ClarificationNeededError")}clarification;constructor(r){super("CLARIFICATION_REQUIRED",r.question),this.clarification=r,this.name="ClarificationNeededError"}}class d extends a{static{t(this,"ApprovalNeededError")}approval;constructor(r){super("APPROVAL_REQUIRED",r.message),this.approval=r,this.name="ApprovalNeededError"}}function u(e,r,o,s){try{return e.parse(r)}catch(c){throw new a(o,s,{cause:c})}}t(u,"parsePayload");export{d as ApprovalNeededError,p as ClarificationNeededError,a as RuaKitError,u as parsePayload};
|
|
3
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/errors.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport type { Clarification } from '@ruakit/schema';\nimport type { ApprovalRequest } from './approval.js';\nexport type RuntimeErrorCode =\n | 'INVALID_REQUEST'\n | 'INVALID_PLAN'\n | 'UNAVAILABLE'\n | 'STALE_TARGET'\n | 'BUSY'\n | 'HTTP_ERROR'\n | 'CLARIFICATION_REQUIRED'\n | 'APPROVAL_REQUIRED'\n | 'APPROVAL_DENIED'\n | 'VERIFICATION_FAILED'\n | 'REPLAN_LIMIT';\n\n/** Errors expose a stable code for embedding applications and a readable message for the toolbar. */\nexport class RuaKitError extends Error {\n constructor(\n readonly code: RuntimeErrorCode,\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = 'RuaKitError';\n }\n}\n\n/** A validated conversational response. Headless consumers can present it and resend with answers. */\nexport class ClarificationNeededError extends RuaKitError {\n constructor(readonly clarification: Clarification) {\n super('CLARIFICATION_REQUIRED', clarification.question);\n this.name = 'ClarificationNeededError';\n }\n}\n\n/** No approval handler was supplied. The proposed action or plan has not executed. */\nexport class ApprovalNeededError extends RuaKitError {\n constructor(readonly approval: ApprovalRequest) {\n super('APPROVAL_REQUIRED', approval.message);\n this.name = 'ApprovalNeededError';\n }\n}\n\nexport function parsePayload<T>(\n schema: { parse(value: unknown): T },\n value: unknown,\n code: RuntimeErrorCode,\n message: string,\n): T {\n try {\n return schema.parse(value);\n } catch (cause) {\n throw new RuaKitError(code, message, { cause });\n }\n}\n"],
|
|
5
|
+
"mappings": ";+EAiBM,MAAOA,UAAoB,KAAK,CADtC,MACsC,CAAAC,EAAA,oBAEzB,KADX,YACWC,EACTC,EACAC,EAAsB,CAEtB,MAAMD,EAASC,CAAO,EAJb,KAAA,KAAAF,EAKT,KAAK,KAAO,aACd,EAII,MAAOG,UAAiCL,CAAW,CAbzD,MAayD,CAAAC,EAAA,iCAClC,cAArB,YAAqBK,EAA4B,CAC/C,MAAM,yBAA0BA,EAAc,QAAQ,EADnC,KAAA,cAAAA,EAEnB,KAAK,KAAO,0BACd,EAII,MAAOC,UAA4BP,CAAW,CArBpD,MAqBoD,CAAAC,EAAA,4BAC7B,SAArB,YAAqBO,EAAyB,CAC5C,MAAM,oBAAqBA,EAAS,OAAO,EADxB,KAAA,SAAAA,EAEnB,KAAK,KAAO,qBACd,EAGI,SAAUC,EACdC,EACAC,EACAT,EACAC,EAAe,CAEf,GAAI,CACF,OAAOO,EAAO,MAAMC,CAAK,CAC3B,OAASC,EAAO,CACd,MAAM,IAAIZ,EAAYE,EAAMC,EAAS,CAAE,MAAAS,CAAK,CAAE,CAChD,CACF,CAXgBX,EAAAQ,EAAA",
|
|
6
|
+
"names": ["RuaKitError", "__name", "code", "message", "options", "ClarificationNeededError", "clarification", "ApprovalNeededError", "approval", "parsePayload", "schema", "value", "cause"]
|
|
7
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { createRuntime } from './runtime.js';
|
|
2
|
+
export type { RuntimeOptions, PlanRuntimeOptions, RequestOptions, RuaKitRuntime } from './runtime.js';
|
|
3
|
+
export { createSession } from './session.js';
|
|
4
|
+
export type { RuaSession, ExecutionOptions, RunOptions, PlanOptions, CompletionContext, } from './session.js';
|
|
5
|
+
export type { PageState } from '@ruakit/runtime';
|
|
6
|
+
export { createHttpTransport } from './transport.js';
|
|
7
|
+
export type { HttpTransportOptions, RuaKitTransport } from './transport.js';
|
|
8
|
+
export { createPlanTransport } from './plan-transport.js';
|
|
9
|
+
export type { PlanTransport, PlanHttpTransportOptions } from './plan-transport.js';
|
|
10
|
+
export type { PlanExecutionOptions, PlanExecutionResult, PlanPlanner, PlanTaskOptions, PlanTask } from './plan.js';
|
|
11
|
+
export { RuaKitError, ClarificationNeededError, ApprovalNeededError } from './errors.js';
|
|
12
|
+
export type { ApprovalContext, ApprovalRequest, ApprovalOptions } from './approval.js';
|
|
13
|
+
export type { RuntimeErrorCode } from './errors.js';
|
|
14
|
+
export type { RequestPhase, RequestState } from './request-state.js';
|
|
15
|
+
export type { ActionFeedbackOptions, ActionRect, RuntimeAction, RuntimeActionEvent, } from '@ruakit/runtime';
|
|
16
|
+
export type { Clarification, ClarificationTurn, ExecutionResult, CompletionCheck, DecisionRequest, Decision, ApprovalDecision, PlanApproval, Plan, PlannedStep, CompletedPlanStep, Replan, PlanRequest, PlanResponse, JsonValue, } from '@ruakit/schema';
|
|
17
|
+
export { INITIAL_REQUEST_STATE, requestIsBusy, requestReducer } from './request-state.js';
|
|
18
|
+
export type { RequestEvent } from './request-state.js';
|
|
19
|
+
export { toRequestError } from './request-outcome.js';
|
|
20
|
+
export type { RequestCorrelation, RequestIdentity, RequestError, RequestOutcome, } from './request-outcome.js';
|
|
21
|
+
export type { Screenshot, ScreenshotImage } from '@ruakit/runtime';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACnH,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACvF,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrE,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,GACnF,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,cAAc,GACf,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
import{createRuntime as o}from"./runtime.js";import{createSession as p}from"./session.js";import{createHttpTransport as s}from"./transport.js";import{createPlanTransport as m}from"./plan-transport.js";import{RuaKitError as x,ClarificationNeededError as E,ApprovalNeededError as c}from"./errors.js";import{INITIAL_REQUEST_STATE as n,requestIsBusy as T,requestReducer as d}from"./request-state.js";import{toRequestError as I}from"./request-outcome.js";export{c as ApprovalNeededError,E as ClarificationNeededError,n as INITIAL_REQUEST_STATE,x as RuaKitError,s as createHttpTransport,m as createPlanTransport,o as createRuntime,p as createSession,T as requestIsBusy,d as requestReducer,I as toRequestError};
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nexport { createRuntime } from './runtime.js';\nexport type { RuntimeOptions, PlanRuntimeOptions, RequestOptions, RuaKitRuntime } from './runtime.js';\nexport { createSession } from './session.js';\nexport type {\n RuaSession,\n ExecutionOptions,\n RunOptions,\n PlanOptions,\n CompletionContext,\n} from './session.js';\nexport type { PageState } from '@ruakit/runtime';\nexport { createHttpTransport } from './transport.js';\nexport type { HttpTransportOptions, RuaKitTransport } from './transport.js';\nexport { createPlanTransport } from './plan-transport.js';\nexport type { PlanTransport, PlanHttpTransportOptions } from './plan-transport.js';\nexport type { PlanExecutionOptions, PlanExecutionResult, PlanPlanner, PlanTaskOptions, PlanTask } from './plan.js';\nexport { RuaKitError, ClarificationNeededError, ApprovalNeededError } from './errors.js';\nexport type { ApprovalContext, ApprovalRequest, ApprovalOptions } from './approval.js';\nexport type { RuntimeErrorCode } from './errors.js';\nexport type { RequestPhase, RequestState } from './request-state.js';\nexport type {\n ActionFeedbackOptions,\n ActionRect,\n RuntimeAction,\n RuntimeActionEvent,\n} from '@ruakit/runtime';\nexport type {\n Clarification,\n ClarificationTurn,\n ExecutionResult,\n CompletionCheck,\n DecisionRequest,\n Decision,\n ApprovalDecision,\n PlanApproval,\n Plan, PlannedStep, CompletedPlanStep, Replan, PlanRequest, PlanResponse, JsonValue,\n} from '@ruakit/schema';\n\nexport { INITIAL_REQUEST_STATE, requestIsBusy, requestReducer } from './request-state.js';\nexport type { RequestEvent } from './request-state.js';\nexport { toRequestError } from './request-outcome.js';\nexport type {\n RequestCorrelation,\n RequestIdentity,\n RequestError,\n RequestOutcome,\n} from './request-outcome.js';\n\nexport type { Screenshot, ScreenshotImage } from '@ruakit/runtime';\n"],
|
|
5
|
+
"mappings": ";AACA,OAAS,iBAAAA,MAAqB,eAE9B,OAAS,iBAAAC,MAAqB,eAS9B,OAAS,uBAAAC,MAA2B,iBAEpC,OAAS,uBAAAC,MAA2B,sBAGpC,OAAS,eAAAC,EAAa,4BAAAC,EAA0B,uBAAAC,MAA2B,cAsB3E,OAAS,yBAAAC,EAAuB,iBAAAC,EAAe,kBAAAC,MAAsB,qBAErE,OAAS,kBAAAC,MAAsB",
|
|
6
|
+
"names": ["createRuntime", "createSession", "createHttpTransport", "createPlanTransport", "RuaKitError", "ClarificationNeededError", "ApprovalNeededError", "INITIAL_REQUEST_STATE", "requestIsBusy", "requestReducer", "toRequestError"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RequestOperation {
|
|
2
|
+
signal: AbortSignal;
|
|
3
|
+
dispose(): void;
|
|
4
|
+
}
|
|
5
|
+
export declare function validateRequestTimeout(timeoutMs: number): void;
|
|
6
|
+
/** Own the deadline and caller subscription until this request settles. */
|
|
7
|
+
export declare function createRequestOperation(timeoutMs: number, callerSignal?: AbortSignal): RequestOperation;
|
|
8
|
+
/** Stop awaiting an adapter that ignores cancellation; its late result is discarded. */
|
|
9
|
+
export declare function runWithSignal<Value>(signal: AbortSignal, operation: () => Value | Promise<Value>): Promise<Value>;
|
|
10
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,WAAW,GACzB,gBAAgB,CAkBlB;AAED,wFAAwF;AACxF,wBAAsB,aAAa,CAAC,KAAK,EACvC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GACtC,OAAO,CAAC,KAAK,CAAC,CA2BhB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var a=Object.defineProperty;var r=(e,t)=>a(e,"name",{value:t,configurable:!0});function c(e){if(!Number.isInteger(e)||e<=0||e>2147483647)throw new RangeError("RuaKit request timeout must be an integer from 1 to 2147483647 milliseconds.")}r(c,"validateRequestTimeout");function d(e,t){c(e);const n=new AbortController,o=r(()=>n.abort(t?.reason),"cancel");t?.addEventListener("abort",o,{once:!0}),t?.aborted&&o();const i=setTimeout(()=>{n.abort(new DOMException("The operation was aborted due to timeout","TimeoutError"))},e);return{signal:n.signal,dispose(){clearTimeout(i),t?.removeEventListener("abort",o)}}}r(d,"createRequestOperation");async function m(e,t){return e.throwIfAborted(),new Promise((n,o)=>{const i=r(()=>e.removeEventListener("abort",u),"cleanup"),u=r(()=>{i(),o(e.reason)},"cancel");e.addEventListener("abort",u,{once:!0}),Promise.resolve().then(()=>(e.throwIfAborted(),t())).then(s=>{i(),n(s)},s=>{i(),o(s)})})}r(m,"runWithSignal");export{d as createRequestOperation,m as runWithSignal,c as validateRequestTimeout};
|
|
3
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/operations.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\n\nexport interface RequestOperation {\n signal: AbortSignal;\n dispose(): void;\n}\n\nexport function validateRequestTimeout(timeoutMs: number): void {\n if (!Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {\n throw new RangeError(\n 'RuaKit request timeout must be an integer from 1 to 2147483647 milliseconds.',\n );\n }\n}\n\n/** Own the deadline and caller subscription until this request settles. */\nexport function createRequestOperation(\n timeoutMs: number,\n callerSignal?: AbortSignal,\n): RequestOperation {\n validateRequestTimeout(timeoutMs);\n const controller = new AbortController();\n const cancel = (): void => controller.abort(callerSignal?.reason);\n callerSignal?.addEventListener('abort', cancel, { once: true });\n if (callerSignal?.aborted) {\n cancel();\n }\n const timer = setTimeout(() => {\n controller.abort(new DOMException('The operation was aborted due to timeout', 'TimeoutError'));\n }, timeoutMs);\n return {\n signal: controller.signal,\n dispose() {\n clearTimeout(timer);\n callerSignal?.removeEventListener('abort', cancel);\n },\n };\n}\n\n/** Stop awaiting an adapter that ignores cancellation; its late result is discarded. */\nexport async function runWithSignal<Value>(\n signal: AbortSignal,\n operation: () => Value | Promise<Value>,\n): Promise<Value> {\n signal.throwIfAborted();\n return new Promise<Value>((resolve, reject) => {\n const cleanup = (): void => signal.removeEventListener('abort', cancel);\n const cancel = (): void => {\n cleanup();\n reject(signal.reason);\n };\n signal.addEventListener('abort', cancel, { once: true });\n // Attach both settlement handlers even after cancellation so a late rejection\n // from a custom adapter cannot become an unhandled rejection.\n Promise.resolve()\n .then(() => {\n signal.throwIfAborted();\n return operation();\n })\n .then(\n (value) => {\n cleanup();\n resolve(value);\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n },\n );\n });\n}\n"],
|
|
5
|
+
"mappings": ";+EAOM,SAAUA,EAAuBC,EAAiB,CACtD,GAAI,CAAC,OAAO,UAAUA,CAAS,GAAKA,GAAa,GAAKA,EAAY,WAChE,MAAM,IAAI,WACR,8EAA8E,CAGpF,CANgBC,EAAAF,EAAA,0BASV,SAAUG,EACdF,EACAG,EAA0B,CAE1BJ,EAAuBC,CAAS,EAChC,MAAMI,EAAa,IAAI,gBACjBC,EAASJ,EAAA,IAAYG,EAAW,MAAMD,GAAc,MAAM,EAAjD,UACfA,GAAc,iBAAiB,QAASE,EAAQ,CAAE,KAAM,EAAI,CAAE,EAC1DF,GAAc,SAChBE,EAAM,EAER,MAAMC,EAAQ,WAAW,IAAK,CAC5BF,EAAW,MAAM,IAAI,aAAa,2CAA4C,cAAc,CAAC,CAC/F,EAAGJ,CAAS,EACZ,MAAO,CACL,OAAQI,EAAW,OACnB,SAAO,CACL,aAAaE,CAAK,EAClBH,GAAc,oBAAoB,QAASE,CAAM,CACnD,EAEJ,CArBgBJ,EAAAC,EAAA,0BAwBhB,eAAsBK,EACpBC,EACAC,EAAuC,CAEvC,OAAAD,EAAO,eAAc,EACd,IAAI,QAAe,CAACE,EAASC,IAAU,CAC5C,MAAMC,EAAUX,EAAA,IAAYO,EAAO,oBAAoB,QAASH,CAAM,EAAtD,WACVA,EAASJ,EAAA,IAAW,CACxBW,EAAO,EACPD,EAAOH,EAAO,MAAM,CACtB,EAHe,UAIfA,EAAO,iBAAiB,QAASH,EAAQ,CAAE,KAAM,EAAI,CAAE,EAGvD,QAAQ,QAAO,EACZ,KAAK,KACJG,EAAO,eAAc,EACdC,EAAS,EACjB,EACA,KACEI,GAAS,CACRD,EAAO,EACPF,EAAQG,CAAK,CACf,EACCC,GAAkB,CACjBF,EAAO,EACPD,EAAOG,CAAK,CACd,CAAC,CAEP,CAAC,CACH,CA9BsBb,EAAAM,EAAA",
|
|
6
|
+
"names": ["validateRequestTimeout", "timeoutMs", "__name", "createRequestOperation", "callerSignal", "controller", "cancel", "timer", "runWithSignal", "signal", "operation", "resolve", "reject", "cleanup", "value", "error"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PlanRequest, PlanResponse } from '@ruakit/schema';
|
|
2
|
+
import type { HttpTransportOptions } from './transport.js';
|
|
3
|
+
export interface PlanTransport {
|
|
4
|
+
plan(input: PlanRequest, signal: AbortSignal): Promise<PlanResponse>;
|
|
5
|
+
}
|
|
6
|
+
export interface PlanHttpTransportOptions extends HttpTransportOptions {
|
|
7
|
+
document?: Document;
|
|
8
|
+
}
|
|
9
|
+
/** The plan protocol shares the existing route, including the server-only proxy. */
|
|
10
|
+
export declare function createPlanTransport(options?: PlanHttpTransportOptions): PlanTransport;
|
|
11
|
+
//# sourceMappingURL=plan-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-transport.d.ts","sourceRoot":"","sources":["../src/plan-transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACtE;AACD,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,wBAA6B,GACrC,aAAa,CAiEf"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var d=Object.defineProperty;var c=(t,n)=>d(t,"name",{value:n,configurable:!0});import{planResponseSchema as p,RUNTIME_META_NAME as h}from"@ruakit/schema";import{RuaKitError as i,parsePayload as u}from"./errors.js";function R(t={}){let n=t.serverUrl;if(n===void 0){const a=t.document?.querySelector(`meta[name="${h}"]`)?.content;if(a!==void 0)try{const e=JSON.parse(a);if(typeof e!="object"||e===null||Array.isArray(e)||"serverUrl"in e&&typeof e.serverUrl!="string")throw new Error;"serverUrl"in e&&(n=e.serverUrl)}catch(e){throw new i("INVALID_REQUEST","The page has invalid RuaKit configuration.",{cause:e})}}const l=(n??"").replace(/\/$/,""),f=t.fetch??globalThis.fetch.bind(globalThis);return{async plan(a,e){const o=await f(`${l}/v1/plan`,{method:"POST",signal:e,cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});let r;try{r=await o.json()}catch(s){throw new i("HTTP_ERROR","The server returned invalid JSON.",{cause:s})}if(!o.ok){const s=typeof r=="object"&&r!==null&&"error"in r&&typeof r.error=="string"?r.error:`RuaKit request failed (${o.status}).`;throw new i("HTTP_ERROR",s)}return u(p,r,"INVALID_PLAN","The server returned an invalid plan response.")}}}c(R,"createPlanTransport");export{R as createPlanTransport};
|
|
3
|
+
//# sourceMappingURL=plan-transport.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plan-transport.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { planResponseSchema, RUNTIME_META_NAME } from '@ruakit/schema';\nimport type { PlanRequest, PlanResponse } from '@ruakit/schema';\nimport { RuaKitError, parsePayload } from './errors.js';\nimport type { HttpTransportOptions } from './transport.js';\n\nexport interface PlanTransport {\n plan(input: PlanRequest, signal: AbortSignal): Promise<PlanResponse>;\n}\nexport interface PlanHttpTransportOptions extends HttpTransportOptions {\n document?: Document;\n}\n\n/** The plan protocol shares the existing route, including the server-only proxy. */\nexport function createPlanTransport(\n options: PlanHttpTransportOptions = {},\n): PlanTransport {\n let serverUrl = options.serverUrl;\n if (serverUrl === undefined) {\n const embedded = options.document?.querySelector<HTMLMetaElement>(\n `meta[name=\"${RUNTIME_META_NAME}\"]`,\n )?.content;\n if (embedded !== undefined) {\n try {\n const config: unknown = JSON.parse(embedded);\n if (\n typeof config !== 'object' ||\n config === null ||\n Array.isArray(config) ||\n ('serverUrl' in config && typeof config.serverUrl !== 'string')\n )\n throw new Error();\n if ('serverUrl' in config) serverUrl = config.serverUrl as string;\n } catch (cause) {\n throw new RuaKitError(\n 'INVALID_REQUEST',\n 'The page has invalid RuaKit configuration.',\n { cause },\n );\n }\n }\n }\n const base = (serverUrl ?? '').replace(/\\/$/, '');\n const fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);\n return {\n async plan(input, 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(input),\n });\n let data: unknown;\n try {\n data = await response.json();\n } catch (cause) {\n throw new RuaKitError(\n 'HTTP_ERROR',\n 'The server returned invalid JSON.',\n { cause },\n );\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 planResponseSchema,\n data,\n 'INVALID_PLAN',\n 'The server returned an invalid plan response.',\n );\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";+EACA,OAAS,sBAAAA,EAAoB,qBAAAC,MAAyB,iBAEtD,OAAS,eAAAC,EAAa,gBAAAC,MAAoB,cAWpC,SAAUC,EACdC,EAAoC,CAAA,EAAE,CAEtC,IAAIC,EAAYD,EAAQ,UACxB,GAAIC,IAAc,OAAW,CAC3B,MAAMC,EAAWF,EAAQ,UAAU,cACjC,cAAcJ,CAAiB,IAAI,GAClC,QACH,GAAIM,IAAa,OACf,GAAI,CACF,MAAMC,EAAkB,KAAK,MAAMD,CAAQ,EAC3C,GACE,OAAOC,GAAW,UAClBA,IAAW,MACX,MAAM,QAAQA,CAAM,GACnB,cAAeA,GAAU,OAAOA,EAAO,WAAc,SAEtD,MAAM,IAAI,MACR,cAAeA,IAAQF,EAAYE,EAAO,UAChD,OAASC,EAAO,CACd,MAAM,IAAIP,EACR,kBACA,6CACA,CAAE,MAAAO,CAAK,CAAE,CAEb,CAEJ,CACA,MAAMC,GAAQJ,GAAa,IAAI,QAAQ,MAAO,EAAE,EAC1CK,EAAUN,EAAQ,OAAS,WAAW,MAAM,KAAK,UAAU,EACjE,MAAO,CACL,MAAM,KAAKO,EAAOC,EAAM,CACtB,MAAMC,EAAW,MAAMH,EAAQ,GAAGD,CAAI,WAAY,CAChD,OAAQ,OACR,OAAAG,EACA,MAAO,WACP,QAAS,CAAE,eAAgB,kBAAkB,EAC7C,KAAM,KAAK,UAAUD,CAAK,EAC3B,EACD,IAAIG,EACJ,GAAI,CACFA,EAAO,MAAMD,EAAS,KAAI,CAC5B,OAASL,EAAO,CACd,MAAM,IAAIP,EACR,aACA,oCACA,CAAE,MAAAO,CAAK,CAAE,CAEb,CACA,GAAI,CAACK,EAAS,GAAI,CAChB,MAAME,EACJ,OAAOD,GAAS,UAChBA,IAAS,MACT,UAAWA,GACX,OAAOA,EAAK,OAAU,SAClBA,EAAK,MACL,0BAA0BD,EAAS,MAAM,KAC/C,MAAM,IAAIZ,EAAY,aAAcc,CAAO,CAC7C,CACA,OAAOb,EACLH,EACAe,EACA,eACA,+CAA+C,CAEnD,EAEJ,CAnEgBE,EAAAb,EAAA",
|
|
6
|
+
"names": ["planResponseSchema", "RUNTIME_META_NAME", "RuaKitError", "parsePayload", "createPlanTransport", "options", "serverUrl", "embedded", "config", "cause", "base", "fetcher", "input", "signal", "response", "data", "message", "__name"]
|
|
7
|
+
}
|
package/dist/plan.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Plan, CompletedPlanStep, Replan, PlanRequest, CompletionCheck, ExecutionResult, Decision, ClarificationTurn } from '@ruakit/schema';
|
|
2
|
+
import type { PageState, Screenshot } from '@ruakit/runtime';
|
|
3
|
+
import type { ExecutionOptions } from './session.js';
|
|
4
|
+
export type PlanPlanner = (input: PlanRequest, signal: AbortSignal) => Promise<unknown>;
|
|
5
|
+
export interface PlanExecutionOptions extends ExecutionOptions {
|
|
6
|
+
prompt?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PlanTaskOptions extends ExecutionOptions {
|
|
9
|
+
context?: unknown;
|
|
10
|
+
clarifications?: ClarificationTurn[];
|
|
11
|
+
/** Maximum replacement plans after the initial plan. Defaults to 3. */
|
|
12
|
+
maxReplans?: number;
|
|
13
|
+
onPlan?: (plan: Plan) => void;
|
|
14
|
+
}
|
|
15
|
+
export type PlanExecutionResult = {
|
|
16
|
+
status: 'completed';
|
|
17
|
+
planId: string;
|
|
18
|
+
completedSteps: CompletedPlanStep[];
|
|
19
|
+
result: ExecutionResult;
|
|
20
|
+
} | {
|
|
21
|
+
status: 'needs-replan';
|
|
22
|
+
planId: string;
|
|
23
|
+
completedSteps: CompletedPlanStep[];
|
|
24
|
+
replan: Replan;
|
|
25
|
+
snapshot: PageState;
|
|
26
|
+
};
|
|
27
|
+
/** A task retains checks and completed actions while waiting for clarification. */
|
|
28
|
+
export interface PlanTask {
|
|
29
|
+
readonly canResume: boolean;
|
|
30
|
+
request(prompt: string, planner: PlanPlanner, options?: PlanTaskOptions): Promise<ExecutionResult>;
|
|
31
|
+
}
|
|
32
|
+
export interface PlanEngine {
|
|
33
|
+
readonly platform: string;
|
|
34
|
+
snapshot(): PageState;
|
|
35
|
+
apply(value: unknown, source: PageState, signal: AbortSignal, options: ExecutionOptions, verification: {
|
|
36
|
+
baseline: PageState;
|
|
37
|
+
checks: CompletionCheck[];
|
|
38
|
+
prompt: string | undefined;
|
|
39
|
+
}): Promise<Decision>;
|
|
40
|
+
screenshot(signal: AbortSignal, timeoutMs: number): Promise<Screenshot>;
|
|
41
|
+
}
|
|
42
|
+
type Owner = <T>(options: ExecutionOptions, perform: (signal: AbortSignal) => Promise<T>) => Promise<T>;
|
|
43
|
+
/** Execute one supplied plan. This function never contacts a planner. */
|
|
44
|
+
export declare function executePlan(engine: PlanEngine, value: unknown, signal: AbortSignal, options: PlanExecutionOptions): Promise<PlanExecutionResult>;
|
|
45
|
+
export declare function createPlanTask(engine: PlanEngine, own: Owner): PlanTask;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,IAAI,EAEJ,iBAAiB,EACjB,MAAM,EACN,WAAW,EAEX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,iBAAiB,EAElB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;AACtB,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACrC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/B;AACD,MAAM,MAAM,mBAAmB,GAC3B;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,MAAM,EAAE,eAAe,CAAC;CACzB,GACD;IACE,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEN,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,OAAO,CACL,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,IAAI,SAAS,CAAC;IACtB,KAAK,CACH,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE;QACZ,QAAQ,EAAE,SAAS,CAAC;QACpB,MAAM,EAAE,eAAe,EAAE,CAAC;QAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KAC5B,GACA,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACzE;AACD,KAAK,KAAK,GAAG,CAAC,CAAC,EACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,KACzC,OAAO,CAAC,CAAC,CAAC,CAAC;AAkOhB,yEAAyE;AACzE,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAc9B;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,GAAG,QAAQ,CAgIvE"}
|
package/dist/plan.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var _=Object.defineProperty;var h=(t,n)=>_(t,"name",{value:n,configurable:!0});import{REQUEST_MESSAGES as R}from"./constants.js";import{evaluateCompletionChecks as b,planSchema as x,planRequestSchema as C,planResponseSchema as D,planApprovalSchema as V}from"@ruakit/schema";import{RuntimeError as q}from"@ruakit/runtime";import{ClarificationNeededError as U,RuaKitError as d,parsePayload as L}from"./errors.js";import{runWithSignal as J}from"./operations.js";import{requestApproval as M}from"./approval.js";function E(t){return{baseline:structuredClone(t.snapshot()),checks:void 0,completedSteps:[],events:[],effects:[]}}h(E,"progress");function A(t){try{t?.()}catch{}}h(A,"notify");function v(t){const{id:n,message:e,...r}=t;return JSON.stringify({...r,target:{...r.target,id:null}})}h(v,"signature");function k(t,n){const e=t.target;return n.controls.filter(r=>(e.id===null||r.target.id===e.id)&&r.role===e.role&&r.label===e.label&&(e.context===null||r.context===e.context)&&(e.group===null||r.groups?.some(s=>s.name===e.group)))}h(k,"matches");async function T(t,n,e,r,s,u){if(e.checks&&JSON.stringify(e.checks)!==JSON.stringify(n.checks))throw new d("INVALID_PLAN","Replacement plans must preserve every completion check.");e.checks??=structuredClone(n.checks);const w={baseline:e.baseline,checks:e.checks,prompt:s.prompt},f=h((c,a,l,o)=>({status:"needs-replan",planId:n.id,completedSteps:structuredClone(e.completedSteps),snapshot:c,replan:{planId:n.id,completedSteps:structuredClone(e.completedSteps),failedStepId:o,reason:a,message:l}}),"incomplete"),I=[...e.completedSteps];if(u){const c=t.snapshot();await M(u,c,r,s,s.prompt);const a=t.snapshot();if(a.url!==c.url||n.steps.some(l=>{const o=k(l,c);if(!o.length&&l.target.id===null)return!1;const g=k(l,a);return o.length!==1||g.length!==1||o[0].target.id!==g[0].target.id||o[0].target.version!==g[0].target.version}))throw new d("STALE_TARGET","The page changed while awaiting approval. Request approval again from a fresh observation.")}if(!b(e.checks,t.snapshot(),e.baseline).passed)for(const c of n.steps){r.throwIfAborted();const a=I.find(i=>i.step.id===c.id);if(a){if(v(a.step)!==v(c))throw new d("INVALID_PLAN","A completed step ID cannot describe a different action.");continue}if(!["fill","select","check","focus"].includes(c.type)&&I.some(i=>v(i.step)===v(c)))throw new d("INVALID_PLAN","A replacement plan cannot replay an already completed action.");if(e.completedSteps.length>=200)throw new d("REPLAN_LIMIT","The task reached its execution limit.");A(()=>s.onPhaseChange?.("observing"));const l=t.snapshot(),o=k(c,l);if(o.length!==1||!o[0].enabled)return f(l,"target-unavailable","The next step has no unique enabled target on the current page.",c.id);const{id:g,message:S,...p}=c,y=JSON.stringify({...p,target:o[0].target.id});if(!["fill","select","check","focus"].includes(c.type)&&e.effects.some(i=>i.planId!==n.id&&i.signature===y))throw new d("INVALID_PLAN","A replacement plan cannot replay an already completed action.");try{await t.apply({type:"act",message:S,step:{...p,target:o[0].target}},l,r,s,w)}catch(i){if(i instanceof q&&i.code==="STALE_TARGET")return f(t.snapshot(),"target-stale",i.message,c.id);throw i}e.completedSteps.push({planId:n.id,step:structuredClone(c)}),e.effects.push({planId:n.id,signature:y}),e.events.push(S.slice(0,500))}r.throwIfAborted();const m=t.snapshot();return b(e.checks,m,e.baseline).passed?(await t.apply({type:"complete",message:n.message,checks:e.checks},m,r,s,w),{status:"completed",planId:n.id,completedSteps:structuredClone(e.completedSteps),result:{planId:n.id,status:"triggered",goalCompleted:!0,message:n.message,events:[...e.events],verification:{level:s.verifyCompletion?"confirmed":"observed",checks:structuredClone(e.checks)}}}):f(m,"outcome-mismatch","The plan finished, but the expected outcomes are not all present.",null)}h(T,"execute");async function z(t,n,e,r){const s=V.safeParse(n),u=s.success?s.data.plan:L(x,n,"INVALID_PLAN","Expected a valid plan or approval with an ID, steps and completion checks.");return T(t,u,E(t),e,r,s.success?s.data:void 0)}h(z,"executePlan");function F(t,n){let e,r,s=null,u,w=0,f=!1;const I=new Set;return{get canResume(){return!f},request:h((m,c,a={})=>n(a,async l=>{if(f)throw new d("INVALID_REQUEST","This plan task has already settled.");const o=a.maxReplans??3;if(!Number.isInteger(o)||o<0||o>10)throw new d("INVALID_REQUEST","maxReplans must be an integer between 0 and 10.");if(r!==void 0&&r!==m)throw new d("INVALID_REQUEST","Resume a plan task with its original prompt.");for(r=m,e??=E(t);;){l.throwIfAborted(),A(()=>a.onPhaseChange?.("observing"));const g=t.snapshot();u&&u.url!==g.url&&(u=void 0);const S=L(C,{protocol:"plan",prompt:m,snapshot:g,platform:t.platform,clarifications:a.clarifications??[],checks:e.checks??null,replan:s,...a.context===void 0?{}:{context:a.context},canScreenshot:!0,...u?{screenshot:u}:{}},"INVALID_REQUEST","Expected a valid planning request and bounded JSON context.");A(()=>a.onPhaseChange?.("planning"));const p=L(D,await J(l,()=>c(S,l)),"INVALID_PLAN","The backend returned an invalid plan response."),y="type"in p&&p.type==="approval"?p:void 0;if(!("id"in p)&&p.type!=="approval"){if(p.type==="clarify")throw new U({type:"clarification",question:p.message,options:[]});if(p.type==="unsupported")throw new d("UNAVAILABLE",p.message);if(u)throw new d("INVALID_PLAN","Use the supplied screenshot before requesting another image.");u=await t.screenshot(l,a.timeoutMs??8e3);continue}const i="id"in p?p:p.plan;if(I.has(i.id)||i.replacesPlanId!==s?.planId)throw new d("INVALID_PLAN","Each plan needs a new ID and the correct replacement plan ID.");if(s&&++w>o)throw new d("REPLAN_LIMIT","The task reached its replanning limit.");I.add(i.id),A(()=>a.onPlan?.(structuredClone(i)));let N;try{N=await T(t,i,e,l,{...a,prompt:m},y)}catch(P){throw f=!0,P}if(u=void 0,N.status==="completed")return f=!0,N.result;if(s=N.replan,w>=o)throw f=!0,new d("REPLAN_LIMIT","The task reached its replanning limit.");A(()=>a.onProgress?.(R.replanning))}}),"request")}}h(F,"createPlanTask");export{F as createPlanTask,z as executePlan};
|
|
3
|
+
//# sourceMappingURL=plan.js.map
|
package/dist/plan.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plan.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport { REQUEST_MESSAGES } from './constants.js';\nimport {\n evaluateCompletionChecks,\n planSchema,\n planRequestSchema,\n planResponseSchema,\n planApprovalSchema,\n} from '@ruakit/schema';\nimport type {\n Plan,\n PlannedStep,\n CompletedPlanStep,\n Replan,\n PlanRequest,\n PlanResponse,\n CompletionCheck,\n ExecutionResult,\n Decision,\n ClarificationTurn,\n PlanApproval,\n} from '@ruakit/schema';\nimport { RuntimeError } from '@ruakit/runtime';\nimport type { PageState, Screenshot } from '@ruakit/runtime';\nimport {\n ClarificationNeededError,\n RuaKitError,\n parsePayload,\n} from './errors.js';\nimport { runWithSignal } from './operations.js';\nimport type { ExecutionOptions } from './session.js';\nimport { requestApproval } from './approval.js';\n\nexport type PlanPlanner = (\n input: PlanRequest,\n signal: AbortSignal,\n) => Promise<unknown>;\nexport interface PlanExecutionOptions extends ExecutionOptions {\n prompt?: string;\n}\nexport interface PlanTaskOptions extends ExecutionOptions {\n context?: unknown;\n clarifications?: ClarificationTurn[];\n /** Maximum replacement plans after the initial plan. Defaults to 3. */\n maxReplans?: number;\n onPlan?: (plan: Plan) => void;\n}\nexport type PlanExecutionResult =\n | {\n status: 'completed';\n planId: string;\n completedSteps: CompletedPlanStep[];\n result: ExecutionResult;\n }\n | {\n status: 'needs-replan';\n planId: string;\n completedSteps: CompletedPlanStep[];\n replan: Replan;\n snapshot: PageState;\n };\n\n/** A task retains checks and completed actions while waiting for clarification. */\nexport interface PlanTask {\n readonly canResume: boolean;\n request(\n prompt: string,\n planner: PlanPlanner,\n options?: PlanTaskOptions,\n ): Promise<ExecutionResult>;\n}\n\nexport interface PlanEngine {\n readonly platform: string;\n snapshot(): PageState;\n apply(\n value: unknown,\n source: PageState,\n signal: AbortSignal,\n options: ExecutionOptions,\n verification: {\n baseline: PageState;\n checks: CompletionCheck[];\n prompt: string | undefined;\n },\n ): Promise<Decision>;\n screenshot(signal: AbortSignal, timeoutMs: number): Promise<Screenshot>;\n}\ntype Owner = <T>(\n options: ExecutionOptions,\n perform: (signal: AbortSignal) => Promise<T>,\n) => Promise<T>;\ninterface Progress {\n baseline: PageState;\n checks: CompletionCheck[] | undefined;\n completedSteps: CompletedPlanStep[];\n events: string[];\n effects: { planId: string; signature: string }[];\n}\n\nfunction progress(engine: PlanEngine): Progress {\n return {\n baseline: structuredClone(engine.snapshot()),\n checks: undefined,\n completedSteps: [],\n events: [],\n effects: [],\n };\n}\nfunction notify(callback: (() => void) | undefined): void {\n try {\n callback?.();\n } catch {\n /* Feedback cannot change execution. */\n }\n}\nfunction signature(step: PlannedStep): string {\n const { id: _id, message: _message, ...action } = step;\n return JSON.stringify({ ...action, target: { ...action.target, id: null } });\n}\nfunction matches(step: PlannedStep, state: PageState): PageState['controls'] {\n const locator = step.target;\n return state.controls.filter(\n (control) =>\n (locator.id === null || control.target.id === locator.id) &&\n control.role === locator.role &&\n control.label === locator.label &&\n (locator.context === null || control.context === locator.context) &&\n (locator.group === null ||\n control.groups?.some((group) => group.name === locator.group)),\n );\n}\n\nasync function execute(\n engine: PlanEngine,\n plan: Plan,\n state: Progress,\n signal: AbortSignal,\n options: PlanExecutionOptions,\n approval?: PlanApproval,\n): Promise<PlanExecutionResult> {\n if (\n state.checks &&\n JSON.stringify(state.checks) !== JSON.stringify(plan.checks)\n )\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Replacement plans must preserve every completion check.',\n );\n state.checks ??= structuredClone(plan.checks);\n const verification = {\n baseline: state.baseline,\n checks: state.checks,\n prompt: options.prompt,\n };\n const incomplete = (\n snapshot: PageState,\n reason: Replan['reason'],\n message: string,\n failedStepId: string | null,\n ): PlanExecutionResult => ({\n status: 'needs-replan',\n planId: plan.id,\n completedSteps: structuredClone(state.completedSteps),\n snapshot,\n replan: {\n planId: plan.id,\n completedSteps: structuredClone(state.completedSteps),\n failedStepId,\n reason,\n message,\n },\n });\n const prior = [...state.completedSteps];\n if (approval) {\n const observed = engine.snapshot();\n await requestApproval(approval, observed, signal, options, options.prompt);\n const current = engine.snapshot();\n // Approval cannot silently move to a changed control while the user is reading.\n if (\n current.url !== observed.url ||\n plan.steps.some((step) => {\n const before = matches(step, observed);\n // A later step can reveal a control described by a semantic locator.\n if (!before.length && step.target.id === null) return false;\n const after = matches(step, current);\n return (\n before.length !== 1 || after.length !== 1 ||\n before[0]!.target.id !== after[0]!.target.id ||\n before[0]!.target.version !== after[0]!.target.version\n );\n })\n ) throw new RuaKitError(\n 'STALE_TARGET',\n 'The page changed while awaiting approval. Request approval again from a fresh observation.',\n );\n }\n // Existing outcomes may already satisfy a request without dispatching an action.\n if (\n !evaluateCompletionChecks(state.checks, engine.snapshot(), state.baseline)\n .passed\n ) {\n for (const step of plan.steps) {\n signal.throwIfAborted();\n const previous = prior.find((entry) => entry.step.id === step.id);\n if (previous) {\n if (signature(previous.step) !== signature(step))\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'A completed step ID cannot describe a different action.',\n );\n continue;\n }\n if (\n !['fill', 'select', 'check', 'focus'].includes(step.type) &&\n prior.some((entry) => signature(entry.step) === signature(step))\n )\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'A replacement plan cannot replay an already completed action.',\n );\n if (state.completedSteps.length >= 200)\n throw new RuaKitError(\n 'REPLAN_LIMIT',\n 'The task reached its execution limit.',\n );\n notify(() => options.onPhaseChange?.('observing'));\n const source = engine.snapshot();\n const controls = matches(step, source);\n if (controls.length !== 1 || !controls[0]!.enabled)\n return incomplete(\n source,\n 'target-unavailable',\n 'The next step has no unique enabled target on the current page.',\n step.id,\n );\n const { id: _id, message, ...action } = step;\n const effect = JSON.stringify({\n ...action,\n target: controls[0]!.target.id,\n });\n if (\n !['fill', 'select', 'check', 'focus'].includes(step.type) &&\n state.effects.some(\n (entry) => entry.planId !== plan.id && entry.signature === effect,\n )\n )\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'A replacement plan cannot replay an already completed action.',\n );\n try {\n await engine.apply(\n {\n type: 'act',\n message,\n step: { ...action, target: controls[0]!.target },\n },\n source,\n signal,\n options,\n verification,\n );\n } catch (error) {\n // STALE_TARGET is raised before dispatch. Other failures can have effects;\n // stop rather than automatically retrying an uncertain action.\n if (error instanceof RuntimeError && error.code === 'STALE_TARGET')\n return incomplete(\n engine.snapshot(),\n 'target-stale',\n error.message,\n step.id,\n );\n throw error;\n }\n state.completedSteps.push({\n planId: plan.id,\n step: structuredClone(step),\n });\n state.effects.push({ planId: plan.id, signature: effect });\n state.events.push(message.slice(0, 500));\n }\n }\n signal.throwIfAborted();\n const final = engine.snapshot();\n if (!evaluateCompletionChecks(state.checks, final, state.baseline).passed)\n return incomplete(\n final,\n 'outcome-mismatch',\n 'The plan finished, but the expected outcomes are not all present.',\n null,\n );\n await engine.apply(\n { type: 'complete', message: plan.message, checks: state.checks },\n final,\n signal,\n options,\n verification,\n );\n return {\n status: 'completed',\n planId: plan.id,\n completedSteps: structuredClone(state.completedSteps),\n result: {\n planId: plan.id,\n status: 'triggered',\n goalCompleted: true,\n message: plan.message,\n events: [...state.events],\n verification: {\n level: options.verifyCompletion ? 'confirmed' : 'observed',\n checks: structuredClone(state.checks),\n },\n },\n };\n}\n\n/** Execute one supplied plan. This function never contacts a planner. */\nexport async function executePlan(\n engine: PlanEngine,\n value: unknown,\n signal: AbortSignal,\n options: PlanExecutionOptions,\n): Promise<PlanExecutionResult> {\n const approval = planApprovalSchema.safeParse(value);\n const plan = approval.success\n ? approval.data.plan\n : parsePayload(\n planSchema,\n value,\n 'INVALID_PLAN',\n 'Expected a valid plan or approval with an ID, steps and completion checks.',\n );\n return execute(\n engine, plan, progress(engine), signal, options,\n approval.success ? approval.data : undefined,\n );\n}\n\nexport function createPlanTask(engine: PlanEngine, own: Owner): PlanTask {\n let state: Progress | undefined;\n let originalPrompt: string | undefined;\n let replan: Replan | null = null;\n let image: Screenshot | undefined;\n let replacements = 0;\n let finished = false;\n const ids = new Set<string>();\n return {\n get canResume() {\n return !finished;\n },\n request: (prompt, planner, options = {}) =>\n own(options, async (signal) => {\n if (finished)\n throw new RuaKitError(\n 'INVALID_REQUEST',\n 'This plan task has already settled.',\n );\n const limit = options.maxReplans ?? 3;\n if (!Number.isInteger(limit) || limit < 0 || limit > 10)\n throw new RuaKitError(\n 'INVALID_REQUEST',\n 'maxReplans must be an integer between 0 and 10.',\n );\n if (originalPrompt !== undefined && originalPrompt !== prompt)\n throw new RuaKitError(\n 'INVALID_REQUEST',\n 'Resume a plan task with its original prompt.',\n );\n originalPrompt = prompt;\n state ??= progress(engine);\n while (true) {\n signal.throwIfAborted();\n notify(() => options.onPhaseChange?.('observing'));\n const source = engine.snapshot();\n if (image && image.url !== source.url) image = undefined;\n const input = parsePayload(\n planRequestSchema,\n {\n protocol: 'plan',\n prompt,\n snapshot: source,\n platform: engine.platform,\n clarifications: options.clarifications ?? [],\n checks: state.checks ?? null,\n replan,\n ...(options.context === undefined\n ? {}\n : { context: options.context }),\n canScreenshot: true,\n ...(image ? { screenshot: image } : {}),\n },\n 'INVALID_REQUEST',\n 'Expected a valid planning request and bounded JSON context.',\n );\n notify(() => options.onPhaseChange?.('planning'));\n const response: PlanResponse = parsePayload(\n planResponseSchema,\n await runWithSignal(signal, () => planner(input, signal)),\n 'INVALID_PLAN',\n 'The backend returned an invalid plan response.',\n );\n const approval = 'type' in response && response.type === 'approval'\n ? response : undefined;\n if (!('id' in response) && response.type !== 'approval') {\n if (response.type === 'clarify')\n throw new ClarificationNeededError({\n type: 'clarification',\n question: response.message,\n options: [],\n });\n if (response.type === 'unsupported')\n throw new RuaKitError('UNAVAILABLE', response.message);\n if (image)\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Use the supplied screenshot before requesting another image.',\n );\n image = await engine.screenshot(signal, options.timeoutMs ?? 8000);\n continue;\n }\n const plan = 'id' in response ? response : response.plan;\n if (\n ids.has(plan.id) ||\n plan.replacesPlanId !== replan?.planId\n )\n throw new RuaKitError(\n 'INVALID_PLAN',\n 'Each plan needs a new ID and the correct replacement plan ID.',\n );\n if (replan && ++replacements > limit)\n throw new RuaKitError(\n 'REPLAN_LIMIT',\n 'The task reached its replanning limit.',\n );\n ids.add(plan.id);\n notify(() => options.onPlan?.(structuredClone(plan)));\n let result: PlanExecutionResult;\n try {\n result = await execute(\n engine, plan, state, signal, { ...options, prompt }, approval,\n );\n } catch (error) {\n finished = true;\n throw error;\n }\n image = undefined;\n if (result.status === 'completed') {\n finished = true;\n return result.result;\n }\n replan = result.replan;\n if (replacements >= limit) {\n finished = true;\n throw new RuaKitError(\n 'REPLAN_LIMIT',\n 'The task reached its replanning limit.',\n );\n }\n notify(() =>\n options.onProgress?.(\n REQUEST_MESSAGES.replanning,\n ),\n );\n }\n }),\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["REQUEST_MESSAGES", "evaluateCompletionChecks", "planSchema", "planRequestSchema", "planResponseSchema", "planApprovalSchema", "RuntimeError", "ClarificationNeededError", "RuaKitError", "parsePayload", "runWithSignal", "requestApproval", "progress", "engine", "__name", "notify", "callback", "signature", "step", "_id", "_message", "action", "matches", "state", "locator", "control", "group", "execute", "plan", "signal", "options", "approval", "verification", "incomplete", "snapshot", "reason", "message", "failedStepId", "prior", "observed", "current", "before", "after", "previous", "entry", "source", "controls", "effect", "error", "final", "executePlan", "value", "createPlanTask", "own", "originalPrompt", "replan", "image", "replacements", "finished", "ids", "prompt", "planner", "limit", "input", "response", "result"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Clarification, ExecutionResult } from '@ruakit/schema';
|
|
2
|
+
import type { RuntimeErrorCode as BrowserErrorCode } from '@ruakit/runtime';
|
|
3
|
+
import type { RuntimeErrorCode } from './errors.js';
|
|
4
|
+
/** Host labels for associating local work with a conversation. Never authorize actions. */
|
|
5
|
+
export interface RequestCorrelation {
|
|
6
|
+
readonly threadId?: string;
|
|
7
|
+
readonly messageId?: string;
|
|
8
|
+
readonly toolCallId?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RequestIdentity {
|
|
11
|
+
/** Stable across clarification attempts; distinct from the UI's numeric attempt ID. */
|
|
12
|
+
readonly operationId: string;
|
|
13
|
+
readonly correlation?: RequestCorrelation;
|
|
14
|
+
}
|
|
15
|
+
export interface RequestError {
|
|
16
|
+
readonly code: RuntimeErrorCode | BrowserErrorCode | 'STALE_REQUEST' | 'REQUEST_FAILED';
|
|
17
|
+
readonly message: string;
|
|
18
|
+
}
|
|
19
|
+
/** Local integration outcomes, not additions to the planner wire protocol. */
|
|
20
|
+
export type RequestOutcome = RequestIdentity & ({
|
|
21
|
+
status: 'completed';
|
|
22
|
+
result: ExecutionResult;
|
|
23
|
+
} | {
|
|
24
|
+
status: 'triggered';
|
|
25
|
+
result: ExecutionResult;
|
|
26
|
+
} | {
|
|
27
|
+
status: 'needs-input';
|
|
28
|
+
clarification: Clarification;
|
|
29
|
+
} | {
|
|
30
|
+
status: 'cancelled';
|
|
31
|
+
reason: 'caller' | 'explicit' | 'unmounted' | 'aborted';
|
|
32
|
+
} | {
|
|
33
|
+
status: 'rejected';
|
|
34
|
+
error: RequestError;
|
|
35
|
+
} | {
|
|
36
|
+
status: 'failed';
|
|
37
|
+
error: RequestError;
|
|
38
|
+
/** A failed answer can be retried against the same pending question. */
|
|
39
|
+
canRespond: boolean;
|
|
40
|
+
});
|
|
41
|
+
/** Preserve known execution codes without trusting arbitrary thrown objects. */
|
|
42
|
+
export declare function toRequestError(error: unknown): RequestError;
|
|
43
|
+
//# sourceMappingURL=request-outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-outcome.d.ts","sourceRoot":"","sources":["../src/request-outcome.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,IAAI,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,2FAA2F;AAC3F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EACX,gBAAgB,GAAG,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,CAAC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,eAAe,GAC1C,CACI;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,aAAa,EAAE,aAAa,CAAA;CAAE,GACvD;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;CACzD,GACD;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAC3C;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,wEAAwE;IACxE,UAAU,EAAE,OAAO,CAAC;CACrB,CACJ,CAAC;AAEJ,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAW3D"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT
|
|
2
|
+
var o=Object.defineProperty;var n=(t,e)=>o(t,"name",{value:e,configurable:!0});import{RuntimeError as i}from"@ruakit/runtime";import{RuaKitError as s}from"./errors.js";function m(t){const e=t instanceof Error||t instanceof DOMException;return{code:t instanceof s||t instanceof i?t.code:e&&t.name==="TimeoutError"?"TIMEOUT":"REQUEST_FAILED",message:e?t.message:"Request failed."}}n(m,"toRequestError");export{m as toRequestError};
|
|
3
|
+
//# sourceMappingURL=request-outcome.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/request-outcome.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 RuaKit contributors. SPDX-License-Identifier: MIT\nimport type { Clarification, ExecutionResult } from '@ruakit/schema';\nimport { RuntimeError } from '@ruakit/runtime';\nimport type { RuntimeErrorCode as BrowserErrorCode } from '@ruakit/runtime';\nimport { RuaKitError } from './errors.js';\nimport type { RuntimeErrorCode } from './errors.js';\n\n/** Host labels for associating local work with a conversation. Never authorize actions. */\nexport interface RequestCorrelation {\n readonly threadId?: string;\n readonly messageId?: string;\n readonly toolCallId?: string;\n}\n\nexport interface RequestIdentity {\n /** Stable across clarification attempts; distinct from the UI's numeric attempt ID. */\n readonly operationId: string;\n readonly correlation?: RequestCorrelation;\n}\n\nexport interface RequestError {\n readonly code:\n RuntimeErrorCode | BrowserErrorCode | 'STALE_REQUEST' | 'REQUEST_FAILED';\n readonly message: string;\n}\n\n/** Local integration outcomes, not additions to the planner wire protocol. */\nexport type RequestOutcome = RequestIdentity &\n (\n | { status: 'completed'; result: ExecutionResult }\n | { status: 'triggered'; result: ExecutionResult }\n | { status: 'needs-input'; clarification: Clarification }\n | {\n status: 'cancelled';\n reason: 'caller' | 'explicit' | 'unmounted' | 'aborted';\n }\n | { status: 'rejected'; error: RequestError }\n | {\n status: 'failed';\n error: RequestError;\n /** A failed answer can be retried against the same pending question. */\n canRespond: boolean;\n }\n );\n\n/** Preserve known execution codes without trusting arbitrary thrown objects. */\nexport function toRequestError(error: unknown): RequestError {\n const exception = error instanceof Error || error instanceof DOMException;\n return {\n code:\n error instanceof RuaKitError || error instanceof RuntimeError\n ? error.code\n : exception && error.name === 'TimeoutError'\n ? 'TIMEOUT'\n : 'REQUEST_FAILED',\n message: exception ? error.message : 'Request failed.',\n };\n}\n"],
|
|
5
|
+
"mappings": ";+EAEA,OAAS,gBAAAA,MAAoB,kBAE7B,OAAS,eAAAC,MAAmB,cA0CtB,SAAUC,EAAeC,EAAc,CAC3C,MAAMC,EAAYD,aAAiB,OAASA,aAAiB,aAC7D,MAAO,CACL,KACEA,aAAiBF,GAAeE,aAAiBH,EAC7CG,EAAM,KACNC,GAAaD,EAAM,OAAS,eAC1B,UACA,iBACR,QAASC,EAAYD,EAAM,QAAU,kBAEzC,CAXgBE,EAAAH,EAAA",
|
|
6
|
+
"names": ["RuntimeError", "RuaKitError", "toRequestError", "error", "exception", "__name"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Clarification, ExecutionResult } from "@ruakit/schema";
|
|
2
|
+
import type { RequestError, RequestIdentity } from "./request-outcome.js";
|
|
3
|
+
import type { ApprovalRequest } from "./approval.js";
|
|
4
|
+
/** Machine-readable execution stages; progress messages remain separate UI text. */
|
|
5
|
+
export type RequestPhase = "observing" | "planning" | "executing";
|
|
6
|
+
interface ActiveRequest {
|
|
7
|
+
requestId: number;
|
|
8
|
+
message: string;
|
|
9
|
+
identity?: RequestIdentity;
|
|
10
|
+
}
|
|
11
|
+
export type RequestState = {
|
|
12
|
+
status: "idle";
|
|
13
|
+
message: string;
|
|
14
|
+
} | (ActiveRequest & {
|
|
15
|
+
status: "running" | "cancelling";
|
|
16
|
+
phase: RequestPhase;
|
|
17
|
+
}) | (ActiveRequest & {
|
|
18
|
+
status: "approval";
|
|
19
|
+
approvalId: string;
|
|
20
|
+
approval: ApprovalRequest;
|
|
21
|
+
originalPrompt: string;
|
|
22
|
+
}) | (ActiveRequest & {
|
|
23
|
+
status: "triggered";
|
|
24
|
+
result: ExecutionResult;
|
|
25
|
+
}) | (ActiveRequest & {
|
|
26
|
+
status: "clarification";
|
|
27
|
+
clarification: Clarification;
|
|
28
|
+
originalPrompt: string;
|
|
29
|
+
}) | (ActiveRequest & {
|
|
30
|
+
status: "cancelled";
|
|
31
|
+
}) | (ActiveRequest & {
|
|
32
|
+
status: "failed";
|
|
33
|
+
error?: RequestError;
|
|
34
|
+
});
|
|
35
|
+
export type RequestEvent = {
|
|
36
|
+
type: "started";
|
|
37
|
+
requestId: number;
|
|
38
|
+
identity?: RequestIdentity;
|
|
39
|
+
} | {
|
|
40
|
+
type: "progress";
|
|
41
|
+
requestId: number;
|
|
42
|
+
message: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: "phase";
|
|
45
|
+
requestId: number;
|
|
46
|
+
phase: RequestPhase;
|
|
47
|
+
} | {
|
|
48
|
+
type: "approval";
|
|
49
|
+
requestId: number;
|
|
50
|
+
approvalId: string;
|
|
51
|
+
approval: ApprovalRequest;
|
|
52
|
+
originalPrompt: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: "approval-resolved";
|
|
55
|
+
requestId: number;
|
|
56
|
+
} | {
|
|
57
|
+
type: "cancelling" | "cancelled";
|
|
58
|
+
requestId: number;
|
|
59
|
+
} | {
|
|
60
|
+
type: "triggered";
|
|
61
|
+
requestId: number;
|
|
62
|
+
result: ExecutionResult;
|
|
63
|
+
} | {
|
|
64
|
+
type: "failed";
|
|
65
|
+
requestId: number;
|
|
66
|
+
message: string;
|
|
67
|
+
error?: RequestError;
|
|
68
|
+
} | {
|
|
69
|
+
type: "clarification";
|
|
70
|
+
requestId: number;
|
|
71
|
+
clarification: Clarification;
|
|
72
|
+
originalPrompt: string;
|
|
73
|
+
message?: string;
|
|
74
|
+
} | {
|
|
75
|
+
type: "reset";
|
|
76
|
+
};
|
|
77
|
+
export declare const INITIAL_REQUEST_STATE: RequestState;
|
|
78
|
+
export declare function requestIsBusy(state: RequestState): state is Extract<RequestState, {
|
|
79
|
+
status: "running" | "cancelling" | "approval";
|
|
80
|
+
}>;
|
|
81
|
+
/** Ignore obsolete completions and progress after cancellation or settlement. */
|
|
82
|
+
export declare function requestReducer(state: RequestState, event: RequestEvent): RequestState;
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=request-state.d.ts.map
|