roe-typescript 0.1.1 → 0.1.3
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/README.md +280 -10
- package/dist/api/agents.d.ts +7 -2
- package/dist/api/agents.js +19 -8
- package/dist/api/policies.d.ts +39 -0
- package/dist/api/policies.js +90 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +5 -0
- package/dist/exceptions.js +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/models/job.d.ts +2 -2
- package/dist/models/job.js +106 -31
- package/dist/models/policy.d.ts +19 -0
- package/dist/models/policy.js +1 -0
- package/dist/models/responses.d.ts +11 -1
- package/dist/models/responses.js +12 -0
- package/dist/utils/httpClient.d.ts +1 -1
- package/dist/utils/httpClient.js +4 -1
- package/package.json +1 -1
- package/dist/integration_test.js +0 -686
- package/dist/src/api/agents.js +0 -269
- package/dist/src/auth.js +0 -15
- package/dist/src/client.js +0 -22
- package/dist/src/config.js +0 -47
- package/dist/src/exceptions.js +0 -86
- package/dist/src/models/agent.js +0 -45
- package/dist/src/models/file.js +0 -92
- package/dist/src/models/job.js +0 -138
- package/dist/src/models/responses.js +0 -42
- package/dist/src/models/user.js +0 -2
- package/dist/src/utils/fileDetection.js +0 -46
- package/dist/src/utils/httpClient.js +0 -236
- package/dist/src/utils/pagination.js +0 -18
package/dist/models/job.js
CHANGED
|
@@ -20,11 +20,30 @@ export class Job {
|
|
|
20
20
|
while (true) {
|
|
21
21
|
const status = await this.retrieveStatus();
|
|
22
22
|
const code = status.status;
|
|
23
|
-
if (code === JobStatus.SUCCESS ||
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if (code === JobStatus.SUCCESS ||
|
|
24
|
+
code === JobStatus.CACHED ||
|
|
25
|
+
code === JobStatus.FAILURE ||
|
|
26
|
+
code === JobStatus.CANCELLED) {
|
|
27
|
+
const isFailed = code === JobStatus.FAILURE || code === JobStatus.CANCELLED;
|
|
28
|
+
let result;
|
|
29
|
+
try {
|
|
30
|
+
result = await this.retrieveResult();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (!isFailed)
|
|
34
|
+
throw err;
|
|
35
|
+
result = {
|
|
36
|
+
agent_id: "",
|
|
37
|
+
agent_version_id: "",
|
|
38
|
+
inputs: [],
|
|
39
|
+
outputs: [],
|
|
40
|
+
input_tokens: null,
|
|
41
|
+
output_tokens: null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
result.status = code;
|
|
45
|
+
result.error_message = status.error_message ?? null;
|
|
46
|
+
return result;
|
|
28
47
|
}
|
|
29
48
|
if (Date.now() - start > timeoutSeconds * 1000) {
|
|
30
49
|
throw new Error(`Job ${this.jobId} did not complete within ${timeoutSeconds} seconds`);
|
|
@@ -42,7 +61,7 @@ export class Job {
|
|
|
42
61
|
export class JobBatch {
|
|
43
62
|
constructor(opts) {
|
|
44
63
|
this.completed = {};
|
|
45
|
-
this.
|
|
64
|
+
this.statuses = {};
|
|
46
65
|
this.agentsApi = opts.agentsApi;
|
|
47
66
|
this.jobIds = opts.jobIds;
|
|
48
67
|
this.timeoutSeconds = opts.timeoutSeconds ?? 7200;
|
|
@@ -64,45 +83,86 @@ export class JobBatch {
|
|
|
64
83
|
if (!pending.length)
|
|
65
84
|
break;
|
|
66
85
|
const statusBatch = await this.agentsApi.jobs.retrieveStatusMany(pending);
|
|
67
|
-
const failures = statusBatch.filter((s) => s.status === JobStatus.FAILURE || s.status === JobStatus.CANCELLED);
|
|
68
|
-
if (failures.length) {
|
|
69
|
-
const detail = failures.map((f) => `${f.id}:${f.status ?? "unknown"}`).join(', ');
|
|
70
|
-
throw new Error(`Jobs failed or cancelled: ${detail}`);
|
|
71
|
-
}
|
|
72
86
|
const completedIds = [];
|
|
73
87
|
for (const status of statusBatch) {
|
|
74
88
|
const code = status.status;
|
|
75
|
-
if (code === JobStatus.SUCCESS ||
|
|
89
|
+
if (code === JobStatus.SUCCESS ||
|
|
90
|
+
code === JobStatus.CACHED ||
|
|
91
|
+
code === JobStatus.FAILURE ||
|
|
92
|
+
code === JobStatus.CANCELLED) {
|
|
76
93
|
completedIds.push(status.id);
|
|
77
94
|
}
|
|
78
95
|
if (code !== undefined && code !== null) {
|
|
79
|
-
this.
|
|
96
|
+
this.statuses[status.id] = {
|
|
97
|
+
status: code,
|
|
98
|
+
timestamp: status.timestamp ?? null,
|
|
99
|
+
error_message: status.error_message ?? null,
|
|
100
|
+
};
|
|
80
101
|
}
|
|
81
102
|
}
|
|
82
103
|
if (completedIds.length) {
|
|
83
|
-
|
|
104
|
+
let resultBatch;
|
|
105
|
+
try {
|
|
106
|
+
resultBatch = await this.agentsApi.jobs.retrieveResultMany(completedIds);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
// Only synthesize for failed/cancelled — can't fake results for success/cached
|
|
110
|
+
const failedIds = completedIds.filter((id) => {
|
|
111
|
+
const s = this.statuses[id]?.status;
|
|
112
|
+
return s === JobStatus.FAILURE || s === JobStatus.CANCELLED;
|
|
113
|
+
});
|
|
114
|
+
if (failedIds.length < completedIds.length) {
|
|
115
|
+
// Some successful jobs had their results lost — must propagate
|
|
116
|
+
throw err;
|
|
117
|
+
}
|
|
118
|
+
resultBatch = failedIds.map((id) => ({
|
|
119
|
+
id,
|
|
120
|
+
status: this.statuses[id]?.status ?? null,
|
|
121
|
+
agent_id: null,
|
|
122
|
+
agent_version_id: null,
|
|
123
|
+
inputs: null,
|
|
124
|
+
result: null,
|
|
125
|
+
corrected_outputs: null,
|
|
126
|
+
input_tokens: null,
|
|
127
|
+
output_tokens: null,
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
84
130
|
for (const res of resultBatch) {
|
|
131
|
+
const jobStatus = res.status ?? this.statuses[res.id]?.status ?? null;
|
|
132
|
+
const isFailed = jobStatus === JobStatus.FAILURE || jobStatus === JobStatus.CANCELLED;
|
|
85
133
|
if (!res.agent_id || !res.agent_version_id) {
|
|
86
|
-
|
|
87
|
-
|
|
134
|
+
if (!isFailed) {
|
|
135
|
+
const id = res.id ?? 'unknown';
|
|
136
|
+
throw new Error(`Job ${id} missing agent identifiers`);
|
|
137
|
+
}
|
|
88
138
|
}
|
|
89
139
|
// Use corrected_outputs as fallback if result is null/undefined
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
140
|
+
const rawOutputs = res.result ?? res.corrected_outputs;
|
|
141
|
+
let outputs;
|
|
142
|
+
if (rawOutputs == null) {
|
|
143
|
+
if (!isFailed) {
|
|
144
|
+
throw new Error(`Job ${res.id} returned null or undefined result`);
|
|
145
|
+
}
|
|
146
|
+
outputs = [];
|
|
94
147
|
}
|
|
95
|
-
if (!Array.isArray(
|
|
96
|
-
|
|
97
|
-
|
|
148
|
+
else if (!Array.isArray(rawOutputs)) {
|
|
149
|
+
if (!isFailed) {
|
|
150
|
+
throw new Error(`Job ${res.id} returned unexpected result format: ${typeof rawOutputs}`);
|
|
151
|
+
}
|
|
152
|
+
outputs = [];
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
outputs = rawOutputs;
|
|
98
156
|
}
|
|
99
157
|
this.completed[res.id] = {
|
|
100
|
-
agent_id: res.agent_id,
|
|
101
|
-
agent_version_id: res.agent_version_id,
|
|
158
|
+
agent_id: res.agent_id ?? "",
|
|
159
|
+
agent_version_id: res.agent_version_id ?? "",
|
|
102
160
|
inputs: res.inputs ?? [],
|
|
103
161
|
input_tokens: res.input_tokens,
|
|
104
162
|
output_tokens: res.output_tokens,
|
|
105
163
|
outputs,
|
|
164
|
+
status: jobStatus,
|
|
165
|
+
error_message: this.statuses[res.id]?.error_message ?? null,
|
|
106
166
|
};
|
|
107
167
|
}
|
|
108
168
|
}
|
|
@@ -117,14 +177,29 @@ export class JobBatch {
|
|
|
117
177
|
return this.jobIds.map((id) => this.completed[id]);
|
|
118
178
|
}
|
|
119
179
|
async retrieveStatus() {
|
|
120
|
-
const statusMap = {
|
|
121
|
-
const toQuery =
|
|
180
|
+
const statusMap = {};
|
|
181
|
+
const toQuery = [];
|
|
182
|
+
const TERMINAL = new Set([JobStatus.SUCCESS, JobStatus.CACHED, JobStatus.FAILURE, JobStatus.CANCELLED]);
|
|
183
|
+
for (const id of this.jobIds) {
|
|
184
|
+
const cached = this.statuses[id];
|
|
185
|
+
if (cached !== undefined && TERMINAL.has(cached.status)) {
|
|
186
|
+
statusMap[id] = cached;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
toQuery.push(id);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
122
192
|
if (toQuery.length) {
|
|
123
|
-
const
|
|
124
|
-
for (const s of
|
|
193
|
+
const batchStatuses = await this.agentsApi.jobs.retrieveStatusMany(toQuery);
|
|
194
|
+
for (const s of batchStatuses) {
|
|
125
195
|
if (s.status !== undefined && s.status !== null) {
|
|
126
|
-
|
|
127
|
-
|
|
196
|
+
const js = {
|
|
197
|
+
status: s.status,
|
|
198
|
+
timestamp: s.timestamp ?? null,
|
|
199
|
+
error_message: s.error_message ?? null,
|
|
200
|
+
};
|
|
201
|
+
this.statuses[s.id] = js;
|
|
202
|
+
statusMap[s.id] = js;
|
|
128
203
|
}
|
|
129
204
|
}
|
|
130
205
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type Policy = {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
organization_id: string;
|
|
6
|
+
current_version_id: string | null;
|
|
7
|
+
created_at: string;
|
|
8
|
+
updated_at: string;
|
|
9
|
+
};
|
|
10
|
+
export type PolicyVersion = {
|
|
11
|
+
id: string;
|
|
12
|
+
version_name: string;
|
|
13
|
+
content: Record<string, unknown>;
|
|
14
|
+
created_at: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
policy: Policy | null;
|
|
17
|
+
created_by: Record<string, unknown> | null;
|
|
18
|
+
base_version_id: string | null;
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -26,7 +26,7 @@ export type PaginatedResponse<T> = {
|
|
|
26
26
|
};
|
|
27
27
|
export type AgentJobStatus = {
|
|
28
28
|
status: number;
|
|
29
|
-
timestamp: number;
|
|
29
|
+
timestamp: number | null;
|
|
30
30
|
error_message?: string | null;
|
|
31
31
|
};
|
|
32
32
|
export type Reference = {
|
|
@@ -43,12 +43,22 @@ export type AgentJobResult = {
|
|
|
43
43
|
input_tokens?: number | null;
|
|
44
44
|
output_tokens?: number | null;
|
|
45
45
|
outputs: AgentDatum[];
|
|
46
|
+
status?: number | null;
|
|
47
|
+
error_message?: string | null;
|
|
46
48
|
};
|
|
49
|
+
/** Returns true if the job status is SUCCESS or CACHED. */
|
|
50
|
+
export declare function isJobSuccess(result: AgentJobResult): boolean;
|
|
51
|
+
/** Returns true if the job status is FAILURE or CANCELLED (any non-success terminal state). */
|
|
52
|
+
export declare function isJobFailure(result: AgentJobResult): boolean;
|
|
53
|
+
/** Returns true if the job status is specifically CANCELLED. */
|
|
54
|
+
export declare function isJobCancelled(result: AgentJobResult): boolean;
|
|
47
55
|
export type AgentJobStatusBatch = {
|
|
48
56
|
id: string;
|
|
49
57
|
status?: number | null;
|
|
50
58
|
created_at?: unknown;
|
|
51
59
|
last_updated_at?: unknown;
|
|
60
|
+
timestamp?: number | null;
|
|
61
|
+
error_message?: string | null;
|
|
52
62
|
};
|
|
53
63
|
export type AgentJobResultBatch = {
|
|
54
64
|
id: string;
|
package/dist/models/responses.js
CHANGED
|
@@ -34,3 +34,15 @@ export function extractReferencesFromOutputs(outputs) {
|
|
|
34
34
|
export function getJobReferences(result) {
|
|
35
35
|
return extractReferencesFromOutputs(result.outputs ?? []);
|
|
36
36
|
}
|
|
37
|
+
/** Returns true if the job status is SUCCESS or CACHED. */
|
|
38
|
+
export function isJobSuccess(result) {
|
|
39
|
+
return result.status === JobStatus.SUCCESS || result.status === JobStatus.CACHED;
|
|
40
|
+
}
|
|
41
|
+
/** Returns true if the job status is FAILURE or CANCELLED (any non-success terminal state). */
|
|
42
|
+
export function isJobFailure(result) {
|
|
43
|
+
return result.status === JobStatus.FAILURE || result.status === JobStatus.CANCELLED;
|
|
44
|
+
}
|
|
45
|
+
/** Returns true if the job status is specifically CANCELLED. */
|
|
46
|
+
export function isJobCancelled(result) {
|
|
47
|
+
return result.status === JobStatus.CANCELLED;
|
|
48
|
+
}
|
|
@@ -26,5 +26,5 @@ export declare class RoeHTTPClient {
|
|
|
26
26
|
private executeWithFormData;
|
|
27
27
|
put<T>(url: string, json?: Record<string, unknown>, params?: Record<string, unknown>): Promise<T>;
|
|
28
28
|
delete(url: string, params?: Record<string, unknown>): Promise<void>;
|
|
29
|
-
postWithDynamicInputs<T>(url: string, inputs: Record<string, unknown>, params?: Record<string, unknown>): Promise<T>;
|
|
29
|
+
postWithDynamicInputs<T>(url: string, inputs: Record<string, unknown>, params?: Record<string, unknown>, metadata?: Record<string, unknown>): Promise<T>;
|
|
30
30
|
}
|
package/dist/utils/httpClient.js
CHANGED
|
@@ -196,7 +196,7 @@ export class RoeHTTPClient {
|
|
|
196
196
|
delete(url, params) {
|
|
197
197
|
return this.execute(() => this.client.delete(url, { params }));
|
|
198
198
|
}
|
|
199
|
-
async postWithDynamicInputs(url, inputs, params) {
|
|
199
|
+
async postWithDynamicInputs(url, inputs, params, metadata) {
|
|
200
200
|
const formData = {};
|
|
201
201
|
const files = {};
|
|
202
202
|
// Process inputs and detect file paths asynchronously
|
|
@@ -224,6 +224,9 @@ export class RoeHTTPClient {
|
|
|
224
224
|
formData[key] = value;
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
+
if (metadata !== undefined) {
|
|
228
|
+
formData.metadata = JSON.stringify(metadata);
|
|
229
|
+
}
|
|
227
230
|
return this.post({ url, formData, files, params });
|
|
228
231
|
}
|
|
229
232
|
}
|