@rowan-agent/agent 0.29.0 → 0.31.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/README.md +1 -1
- package/dist/chunk-HL6TMTA5.js +265 -0
- package/dist/index-jC_-oKbx.d.ts +2257 -0
- package/dist/index.d.ts +4 -3398
- package/dist/index.js +5 -13298
- package/dist/runtime.d.ts +947 -0
- package/dist/runtime.js +12991 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// src/utils.ts
|
|
2
|
+
function createId(prefix) {
|
|
3
|
+
return `${prefix}_${crypto.randomUUID().slice(0, 8)}`;
|
|
4
|
+
}
|
|
5
|
+
function createTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
6
|
+
const offset = date.getTimezoneOffset();
|
|
7
|
+
const local = new Date(date.getTime() - offset * 6e4);
|
|
8
|
+
const iso = local.toISOString().slice(0, -1);
|
|
9
|
+
const sign = offset <= 0 ? "+" : "-";
|
|
10
|
+
const abs = Math.abs(offset);
|
|
11
|
+
const hh = String(Math.floor(abs / 60)).padStart(2, "0");
|
|
12
|
+
const mm = String(abs % 60).padStart(2, "0");
|
|
13
|
+
return `${iso}${sign}${hh}:${mm}`;
|
|
14
|
+
}
|
|
15
|
+
function combineSignals(signalA, signalB) {
|
|
16
|
+
if (!signalA && !signalB) return new AbortController().signal;
|
|
17
|
+
if (!signalA) return signalB;
|
|
18
|
+
if (!signalB) return signalA;
|
|
19
|
+
if (typeof AbortSignal.any === "function") {
|
|
20
|
+
return AbortSignal.any([signalA, signalB]);
|
|
21
|
+
}
|
|
22
|
+
if (signalA.aborted) return signalA;
|
|
23
|
+
if (signalB.aborted) return signalB;
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const onAbort = (ev) => {
|
|
26
|
+
const target = ev.target;
|
|
27
|
+
controller.abort(target.reason);
|
|
28
|
+
};
|
|
29
|
+
signalA.addEventListener("abort", onAbort, { once: true });
|
|
30
|
+
signalB.addEventListener("abort", onAbort, { once: true });
|
|
31
|
+
return controller.signal;
|
|
32
|
+
}
|
|
33
|
+
function withAbort(promise, signal) {
|
|
34
|
+
if (!signal) return promise;
|
|
35
|
+
if (signal.aborted) {
|
|
36
|
+
const error = signal.reason instanceof Error ? signal.reason : new DOMException(typeof signal.reason === "string" ? signal.reason : "Tool execution aborted.", "AbortError");
|
|
37
|
+
return Promise.reject(error);
|
|
38
|
+
}
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const onAbort = () => {
|
|
41
|
+
signal.removeEventListener("abort", onAbort);
|
|
42
|
+
const error = signal.reason instanceof Error ? signal.reason : new DOMException(typeof signal.reason === "string" ? signal.reason : "Tool execution aborted.", "AbortError");
|
|
43
|
+
reject(error);
|
|
44
|
+
};
|
|
45
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
46
|
+
promise.then(
|
|
47
|
+
(val) => {
|
|
48
|
+
signal.removeEventListener("abort", onAbort);
|
|
49
|
+
resolve(val);
|
|
50
|
+
},
|
|
51
|
+
(err) => {
|
|
52
|
+
signal.removeEventListener("abort", onAbort);
|
|
53
|
+
reject(err);
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/runtime/json.ts
|
|
60
|
+
function isPlainObject(value) {
|
|
61
|
+
const prototype = Object.getPrototypeOf(value);
|
|
62
|
+
return prototype === Object.prototype || prototype === null;
|
|
63
|
+
}
|
|
64
|
+
function hasOnlyDataProperties(value) {
|
|
65
|
+
return Reflect.ownKeys(value).every((key) => {
|
|
66
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
67
|
+
return Boolean(descriptor && "value" in descriptor);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function visit(value, seen) {
|
|
71
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
72
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
73
|
+
if (typeof value !== "object" || seen.has(value)) return false;
|
|
74
|
+
seen.add(value);
|
|
75
|
+
try {
|
|
76
|
+
if (Array.isArray(value)) {
|
|
77
|
+
if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDataProperties(value)) return false;
|
|
78
|
+
if (Reflect.ownKeys(value).some((key) => key !== "length" && typeof key !== "string")) return false;
|
|
79
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
80
|
+
if (!Object.prototype.hasOwnProperty.call(value, index) || !visit(value[index], seen)) return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
if (!isPlainObject(value) || !hasOnlyDataProperties(value)) return false;
|
|
85
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== "string")) return false;
|
|
86
|
+
if (Object.prototype.hasOwnProperty.call(value, "toJSON")) return false;
|
|
87
|
+
return Object.keys(value).every((key) => visit(value[key], seen));
|
|
88
|
+
} finally {
|
|
89
|
+
seen.delete(value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function isJsonValue(value) {
|
|
93
|
+
return visit(value, /* @__PURE__ */ new Set());
|
|
94
|
+
}
|
|
95
|
+
function assertJsonValue(value, argument = "value") {
|
|
96
|
+
if (!isJsonValue(value)) throw new TypeError(`${argument} must be JSON-safe`);
|
|
97
|
+
}
|
|
98
|
+
function canonicalJson(value) {
|
|
99
|
+
assertJsonValue(value);
|
|
100
|
+
const encode = (candidate) => {
|
|
101
|
+
if (candidate === null || typeof candidate !== "object") return JSON.stringify(candidate);
|
|
102
|
+
if (Array.isArray(candidate)) return `[${candidate.map(encode).join(",")}]`;
|
|
103
|
+
const object = candidate;
|
|
104
|
+
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${encode(object[key])}`).join(",")}}`;
|
|
105
|
+
};
|
|
106
|
+
return encode(value);
|
|
107
|
+
}
|
|
108
|
+
function utf8ByteLength(value) {
|
|
109
|
+
return new TextEncoder().encode(value).byteLength;
|
|
110
|
+
}
|
|
111
|
+
function assertUtf8ByteLimit(value, limit, argument = "value") {
|
|
112
|
+
if (utf8ByteLength(value) > limit) throw new RangeError(`${argument} exceeds ${limit} UTF-8 bytes`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/harness/phases/interactions.ts
|
|
116
|
+
var RunInteractionCancelledError = class extends Error {
|
|
117
|
+
code = "run_interaction_cancelled";
|
|
118
|
+
constructor(message = "Run interaction work was cancelled.") {
|
|
119
|
+
super(message);
|
|
120
|
+
this.name = "RunInteractionCancelledError";
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var RunInteractionBoundary = class extends Error {
|
|
124
|
+
constructor(state, interactions) {
|
|
125
|
+
super("Run interactions require host input.");
|
|
126
|
+
this.state = state;
|
|
127
|
+
this.interactions = interactions;
|
|
128
|
+
this.name = "RunInteractionBoundary";
|
|
129
|
+
}
|
|
130
|
+
state;
|
|
131
|
+
interactions;
|
|
132
|
+
};
|
|
133
|
+
function createRunInteractionDriver(state, phase, signal) {
|
|
134
|
+
const stored = state.runInteractions ?? state.phaseInteractions;
|
|
135
|
+
const requests = new Map(
|
|
136
|
+
stored?.requests.map((request) => [request.id, { ...request }]) ?? []
|
|
137
|
+
);
|
|
138
|
+
const answers = new Map(Object.entries(stored?.answers ?? {}));
|
|
139
|
+
const usedRequestIds = /* @__PURE__ */ new Set();
|
|
140
|
+
let checkpoint = stored?.checkpoint;
|
|
141
|
+
const snapshot = () => ({
|
|
142
|
+
requests: [...requests.values()].map((request) => ({
|
|
143
|
+
...request,
|
|
144
|
+
status: answers.has(request.id) ? "answered" : request.status
|
|
145
|
+
})),
|
|
146
|
+
answers: Object.fromEntries(answers),
|
|
147
|
+
...checkpoint === void 0 ? {} : { checkpoint }
|
|
148
|
+
});
|
|
149
|
+
const sync = () => {
|
|
150
|
+
state.runInteractions = snapshot();
|
|
151
|
+
};
|
|
152
|
+
const assertActive = () => {
|
|
153
|
+
if (signal?.aborted) throw new RunInteractionCancelledError();
|
|
154
|
+
};
|
|
155
|
+
const matchingStoredRequest = (input) => {
|
|
156
|
+
const fingerprint = interactionFingerprint(input);
|
|
157
|
+
return [...requests.values()].find((request) => !usedRequestIds.has(request.id) && (answers.has(request.id) || request.status === "pending") && request.toolCallId === input.toolCallId && interactionFingerprint(request) === fingerprint);
|
|
158
|
+
};
|
|
159
|
+
return {
|
|
160
|
+
signal: signal ?? new AbortController().signal,
|
|
161
|
+
request(input) {
|
|
162
|
+
assertActive();
|
|
163
|
+
if (input.id !== void 0 && input.id.trim().length === 0) {
|
|
164
|
+
throw new TypeError("Run interaction id must be non-empty.");
|
|
165
|
+
}
|
|
166
|
+
if (input.prompt.trim().length === 0) {
|
|
167
|
+
throw new TypeError("Run interaction prompt must be non-empty.");
|
|
168
|
+
}
|
|
169
|
+
if (!RUN_INTERACTION_KINDS.includes(input.kind)) {
|
|
170
|
+
throw new TypeError(`Unsupported Run interaction kind: ${String(input.kind)}.`);
|
|
171
|
+
}
|
|
172
|
+
if (input.payload !== void 0) assertJsonValue(input.payload, "Run interaction payload");
|
|
173
|
+
const matched = input.id === void 0 ? matchingStoredRequest(input) : void 0;
|
|
174
|
+
const id = input.id ?? matched?.id ?? createId("interaction");
|
|
175
|
+
const existing = requests.get(id);
|
|
176
|
+
if (existing) {
|
|
177
|
+
if (interactionFingerprint(existing) !== interactionFingerprint(input)) {
|
|
178
|
+
throw new Error(`Run interaction ${id} was requested with different metadata.`);
|
|
179
|
+
}
|
|
180
|
+
usedRequestIds.add(id);
|
|
181
|
+
return {
|
|
182
|
+
...existing,
|
|
183
|
+
status: answers.has(id) ? "answered" : existing.status
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const request = {
|
|
187
|
+
id,
|
|
188
|
+
phase,
|
|
189
|
+
kind: input.kind,
|
|
190
|
+
prompt: input.prompt,
|
|
191
|
+
...input.payload === void 0 ? {} : { payload: input.payload },
|
|
192
|
+
...input.toolCallId === void 0 ? {} : { toolCallId: input.toolCallId },
|
|
193
|
+
...input.result === void 0 ? {} : { result: input.result },
|
|
194
|
+
createdAt: createTimestamp(),
|
|
195
|
+
status: "pending"
|
|
196
|
+
};
|
|
197
|
+
requests.set(id, request);
|
|
198
|
+
usedRequestIds.add(id);
|
|
199
|
+
sync();
|
|
200
|
+
return request;
|
|
201
|
+
},
|
|
202
|
+
pending() {
|
|
203
|
+
return [...requests.values()].filter((request) => request.status === "pending" && !answers.has(request.id)).map((request) => ({ ...request, status: "pending" }));
|
|
204
|
+
},
|
|
205
|
+
answers() {
|
|
206
|
+
return new Map(answers);
|
|
207
|
+
},
|
|
208
|
+
checkpoint() {
|
|
209
|
+
return checkpoint;
|
|
210
|
+
},
|
|
211
|
+
clearCheckpoint() {
|
|
212
|
+
checkpoint = void 0;
|
|
213
|
+
sync();
|
|
214
|
+
},
|
|
215
|
+
answer(id, value) {
|
|
216
|
+
answers.set(id, value);
|
|
217
|
+
const req = requests.get(id);
|
|
218
|
+
if (req) {
|
|
219
|
+
requests.set(id, { ...req, status: "answered", answer: value });
|
|
220
|
+
}
|
|
221
|
+
sync();
|
|
222
|
+
},
|
|
223
|
+
clearAnswer(id) {
|
|
224
|
+
answers.delete(id);
|
|
225
|
+
requests.delete(id);
|
|
226
|
+
sync();
|
|
227
|
+
},
|
|
228
|
+
suspend(input = {}) {
|
|
229
|
+
assertActive();
|
|
230
|
+
const pending = this.pending();
|
|
231
|
+
if (pending.length === 0) throw new Error("Cannot suspend without pending Run interactions.");
|
|
232
|
+
if (input.checkpoint !== void 0) checkpoint = input.checkpoint;
|
|
233
|
+
state.status = "suspended";
|
|
234
|
+
sync();
|
|
235
|
+
throw new RunInteractionBoundary(state, pending);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
var RUN_INTERACTION_KINDS = [
|
|
240
|
+
"user_input",
|
|
241
|
+
"permission",
|
|
242
|
+
"elicitation",
|
|
243
|
+
"confirmation"
|
|
244
|
+
];
|
|
245
|
+
function interactionFingerprint(value) {
|
|
246
|
+
return canonicalJson({
|
|
247
|
+
kind: value.kind,
|
|
248
|
+
prompt: value.prompt,
|
|
249
|
+
payload: value.payload ?? null
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export {
|
|
254
|
+
createId,
|
|
255
|
+
createTimestamp,
|
|
256
|
+
combineSignals,
|
|
257
|
+
withAbort,
|
|
258
|
+
isJsonValue,
|
|
259
|
+
assertJsonValue,
|
|
260
|
+
canonicalJson,
|
|
261
|
+
assertUtf8ByteLimit,
|
|
262
|
+
RunInteractionCancelledError,
|
|
263
|
+
RunInteractionBoundary,
|
|
264
|
+
createRunInteractionDriver
|
|
265
|
+
};
|