@isomorph.ai/app-sdk 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/computer-use-handoff.d.ts +13 -1
- package/dist/computer-use-handoff.js +6 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.js +10 -0
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.js +1 -1
- package/package.json +1 -1
|
@@ -83,13 +83,25 @@ export type ComputerUseLoginInput = {
|
|
|
83
83
|
username?: never;
|
|
84
84
|
password?: never;
|
|
85
85
|
};
|
|
86
|
+
export interface ComputerUseLiveConnection {
|
|
87
|
+
endpoint: string;
|
|
88
|
+
headers: {
|
|
89
|
+
'X-aws-proxy-auth': string;
|
|
90
|
+
'X-aws-proxy-port': '8080';
|
|
91
|
+
};
|
|
92
|
+
viewerPath: string;
|
|
93
|
+
}
|
|
94
|
+
export type ComputerUseTakeover = ComputerUsePause & {
|
|
95
|
+
connection?: ComputerUseLiveConnection;
|
|
96
|
+
};
|
|
86
97
|
export interface ComputerUseHandoffOptions extends ComputerUseTransport {
|
|
87
98
|
runKey: string;
|
|
88
99
|
authorize(): Promise<boolean> | boolean;
|
|
89
100
|
}
|
|
90
101
|
export declare function createComputerUseHandoff(options: ComputerUseHandoffOptions): {
|
|
91
|
-
requestTakeover(reason: string, requiredInput?: "login" | "human"): Promise<
|
|
102
|
+
requestTakeover(reason: string, requiredInput?: "login" | "human", pauseId?: string): Promise<ComputerUseTakeover>;
|
|
92
103
|
view(pauseId: string): Promise<ComputerUsePage>;
|
|
104
|
+
live(_pauseId?: string): Promise<ComputerUseLiveConnection>;
|
|
93
105
|
input(pauseId: string, action: ComputerUseInputAction): Promise<ComputerUseInputResult>;
|
|
94
106
|
completeLogin(pauseId: string, input: ComputerUseLoginInput): Promise<{
|
|
95
107
|
status: "login_queued";
|
|
@@ -32,7 +32,7 @@ export function waitingInput(answer) {
|
|
|
32
32
|
}
|
|
33
33
|
export function createComputerUseHandoff(options) {
|
|
34
34
|
if (typeof options.runKey !== 'string' || !options.runKey || typeof options.authorize !== 'function')
|
|
35
|
-
throw new Error('Computer use handoff needs runKey and an authorize check for the current
|
|
35
|
+
throw new Error('Computer use handoff needs runKey and an authorize check for the current app task.');
|
|
36
36
|
const api = computerUseApi(options);
|
|
37
37
|
const post = async (path, body = {}, privateInput = false) => {
|
|
38
38
|
if (await options.authorize() !== true)
|
|
@@ -61,10 +61,10 @@ export function createComputerUseHandoff(options) {
|
|
|
61
61
|
return { pauseId };
|
|
62
62
|
};
|
|
63
63
|
return {
|
|
64
|
-
requestTakeover(reason, requiredInput = 'human') {
|
|
64
|
+
requestTakeover(reason, requiredInput = 'human', pauseId) {
|
|
65
65
|
if (!reason.trim() || !['login', 'human'].includes(requiredInput))
|
|
66
66
|
throw new Error('Takeover needs a reason and login or human input.');
|
|
67
|
-
return post('/tasks/takeover', { reason, requiredInput }).then(pauseOf);
|
|
67
|
+
return post('/tasks/takeover', { reason, requiredInput, ...(pauseId ? paused(pauseId) : {}) }).then(answer => ({ ...pauseOf(answer), ...(answer.connection ? { connection: answer.connection } : {}) }));
|
|
68
68
|
},
|
|
69
69
|
// The API answers 409 while the task is still pausing or after it resumed; `ready` is the only 200.
|
|
70
70
|
async view(pauseId) {
|
|
@@ -73,6 +73,9 @@ export function createComputerUseHandoff(options) {
|
|
|
73
73
|
throw new Error('The computer use API returned an incomplete screen.');
|
|
74
74
|
return { status: 'ready', screenshot: page.screenshot, url: page.url };
|
|
75
75
|
},
|
|
76
|
+
live(_pauseId) {
|
|
77
|
+
return post('/tasks/live');
|
|
78
|
+
},
|
|
76
79
|
input(pauseId, action) {
|
|
77
80
|
return post('/tasks/input', { ...paused(pauseId), action });
|
|
78
81
|
},
|
package/dist/index.d.ts
CHANGED
|
@@ -2017,6 +2017,11 @@ export declare function createClient(options?: ClientOptions): {
|
|
|
2017
2017
|
rpc: <T = unknown>(name: string, args?: Record<string, unknown>) => Promise<T>;
|
|
2018
2018
|
watch: <T = Record<string, unknown>>(build: () => QueryBuilder<T, any>, onResult: (result: WatchResult) => void, options?: WatchOptions) => (() => void);
|
|
2019
2019
|
};
|
|
2020
|
+
computerView: {
|
|
2021
|
+
url(action: string, taskId: string, options?: {
|
|
2022
|
+
mode?: "watch" | "control";
|
|
2023
|
+
}): string;
|
|
2024
|
+
};
|
|
2020
2025
|
files: {
|
|
2021
2026
|
createUpload: (input: {
|
|
2022
2027
|
path: string;
|
package/dist/index.js
CHANGED
|
@@ -773,6 +773,16 @@ export function createClient(options = {}) {
|
|
|
773
773
|
clearTimer(timer); };
|
|
774
774
|
},
|
|
775
775
|
},
|
|
776
|
+
computerView: {
|
|
777
|
+
url(action, taskId, options = {}) {
|
|
778
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]{0,127}$/.test(action) || !/^[A-Za-z0-9_-]{1,128}$/.test(taskId))
|
|
779
|
+
throw new IsomorphError('VALIDATION_FAILED', 'Computer view needs an action and task ID.');
|
|
780
|
+
const mode = options.mode ?? 'watch';
|
|
781
|
+
if (!['watch', 'control'].includes(mode))
|
|
782
|
+
throw new IsomorphError('VALIDATION_FAILED', 'Computer view needs watch or control mode.');
|
|
783
|
+
return `${transport.baseUrl}/_harbour/computer-view/${encodeURIComponent(action)}/${encodeURIComponent(taskId)}/${mode}/`;
|
|
784
|
+
},
|
|
785
|
+
},
|
|
776
786
|
files: {
|
|
777
787
|
createUpload: (input) => transport.json('/_harbour/files/uploads', { method: 'POST', body: JSON.stringify(input) }),
|
|
778
788
|
upload,
|
package/dist/runtime.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const GET_RUN_ACTION = "isomorph-jobs-get";
|
|
|
12
12
|
export declare const CANCEL_RUN_ACTION = "isomorph-jobs-cancel";
|
|
13
13
|
export declare const LIST_RUNS_ACTION = "isomorph-jobs-list";
|
|
14
14
|
export interface ActionContext {
|
|
15
|
+
readonly computerView?: boolean;
|
|
15
16
|
signal: AbortSignal;
|
|
16
17
|
user: IsomorphUser;
|
|
17
18
|
tenant: string;
|
package/dist/runtime.js
CHANGED
|
@@ -715,7 +715,7 @@ export class Runtime {
|
|
|
715
715
|
response.writeHead(200, { 'content-type': PROGRESS_MEDIA_TYPE, ...(requestId ? { 'x-request-id': requestId } : {}) });
|
|
716
716
|
response.write(line);
|
|
717
717
|
};
|
|
718
|
-
const context = { signal: controller.signal, user, tenant, app, requestId: requestId ?? '', progress, transaction: (fn) => this.transaction(name, fn) };
|
|
718
|
+
const context = { computerView: header(request, 'X-Harbour-Computer-View') === '1', signal: controller.signal, user, tenant, app, requestId: requestId ?? '', progress, transaction: (fn) => this.transaction(name, fn) };
|
|
719
719
|
const raw = await readBody(request);
|
|
720
720
|
if (raw === undefined)
|
|
721
721
|
return refuse(response, 413, 'VALIDATION_FAILED', 'the request body is larger than 1 MiB', requestId);
|