@rowan-agent/agent 0.9.16 → 0.9.17
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/index.d.ts +6 -3
- package/dist/index.js +220 -101
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -980,6 +980,8 @@ interface PhaseContext {
|
|
|
980
980
|
/** Text to append after the system prompt */
|
|
981
981
|
appendSystemPrompt?: string;
|
|
982
982
|
}
|
|
983
|
+
/** JSON-safe structural defaults declared by a Phase's `input` mapping. */
|
|
984
|
+
type PhaseInput = Readonly<Record<string, JsonValue>>;
|
|
983
985
|
/** JSON-safe option metadata exposed by a Phase to a host Settings surface. */
|
|
984
986
|
interface PhaseSettingsOption {
|
|
985
987
|
value: string;
|
|
@@ -1073,8 +1075,8 @@ interface Phase {
|
|
|
1073
1075
|
skills?: Skill[];
|
|
1074
1076
|
/** Forced next phase */
|
|
1075
1077
|
target?: string;
|
|
1076
|
-
/**
|
|
1077
|
-
input?:
|
|
1078
|
+
/** Structural JSON-safe input defaults */
|
|
1079
|
+
input?: PhaseInput;
|
|
1078
1080
|
/** If true, phase gets a fresh context when executed in parallel */
|
|
1079
1081
|
isolated?: boolean;
|
|
1080
1082
|
/** Path to PHASE.md file */
|
|
@@ -1598,6 +1600,7 @@ type InvocationCatalogEntry = Readonly<{
|
|
|
1598
1600
|
kind: "phase" | "skill";
|
|
1599
1601
|
name: string;
|
|
1600
1602
|
description: string;
|
|
1603
|
+
input?: Phase["input"];
|
|
1601
1604
|
core?: boolean;
|
|
1602
1605
|
disableAutoInvocation: boolean;
|
|
1603
1606
|
disableImplicitInvocation: boolean;
|
|
@@ -2785,4 +2788,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
|
|
|
2785
2788
|
|
|
2786
2789
|
declare function createCoreTools(input?: CoreToolContext): Tool[];
|
|
2787
2790
|
|
|
2788
|
-
export { type AfterToolCall, type AgentConfig, type AgentConfigRequest, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentResources, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInteraction, PhaseInteractionBoundary, PhaseInteractionCancelledError, type PhaseInteractionDriver, type PhaseInteractionKind, type PhaseInteractionState, type PhaseInteractionStatus, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, materializeConfigurationSnapshot, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
|
|
2791
|
+
export { type AfterToolCall, type AgentConfig, type AgentConfigRequest, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentResources, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, COMPACT_PHASE_ID, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type ContextCompactionRecord, type ContextStatus, type CoreToolContext, DEFAULT_PHASE_ID, type DefinitionLayer, type DurableConsumer, type DurableRunEvent, type DurableStore, type DurableToolResult, type EventCursor, type EventId, type ExecutionCheckpoint, type ExecutionId, type ExecutionToken, type ExtensionAPI, type ExtensionActivationError, type ExtensionActivationResult, type ExtensionContribution, type ExtensionDisposer, type ExtensionFactory, type ExtensionFactoryResult, ExtensionLifetimeError, type ExtensionLifetimeErrorCode, type ExtensionLoadInput, type FrontmatterResult, type HistorySeed, type HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, type InvocationCatalogEntry, type InvocationSource, type JsonObject, type JsonPrimitive, type JsonValue, type LoadExtensionsResult, type LoadInput, type LoadResult, type LoadedExtension, type Message, type MessageBase, type MessageCommitted, type MessageContent, type MessageDelta, type MessageId, type MessageRevised, type MessageRevisionResult, type Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecution, type PhaseExecutionIdentity, type PhaseInput, type PhaseInteraction, PhaseInteractionBoundary, PhaseInteractionCancelledError, type PhaseInteractionDriver, type PhaseInteractionKind, type PhaseInteractionState, type PhaseInteractionStatus, type PhaseInvocation, type PhaseMessageManager, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseSettingsBadge, type PhaseSettingsContext, type PhaseSettingsControl, type PhaseSettingsDefinition, type PhaseSettingsItem, type PhaseSettingsOption, type PhaseSettingsProvider, type PhaseSettingsSection, type PhaseState, type PhaseStatus, type PhaseStatusState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, type RetentionResult, type RunBoundary, type RunClaim, type RunEvent, type RunFailure, type RunId, type RunListCursor, type RunRecord, type RunSnapshot, type RunState, type RunStateChanged, type RunSummary, RuntimeBootstrapRegistry, RuntimeError, type RuntimeErrorCode, type RuntimeErrorDetails, RuntimeExtensionLifetime, STOP_PHASE_ID, type Skill, SqliteStore, type TextContent, type ThinkingContent, type ThinkingDelta, type Tool, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult$1 as ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCompactPhase, createCorePhases, createCoreTools, createDefaultPhase, createStopPhase, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, materializeConfigurationSnapshot, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { chmod, mkdir, readFile as readFile2, stat, writeFile } from "fs/promises";
|
|
3
3
|
import { basename as basename2, dirname as dirname2, relative as relative2, resolve as resolve2 } from "path";
|
|
4
4
|
import { tmpdir } from "os";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import Type3 from "typebox";
|
|
6
|
+
import Schema2 from "typebox/schema";
|
|
7
7
|
|
|
8
8
|
// src/harness/context/resource-formatter.ts
|
|
9
9
|
function escapeXml(value) {
|
|
@@ -95,6 +95,13 @@ function buildPhaseDirectiveMessage(phase, output) {
|
|
|
95
95
|
const parts = [];
|
|
96
96
|
parts.push(`<phase_content name="${escapeXml(phase.name)}">`);
|
|
97
97
|
parts.push(phase.content);
|
|
98
|
+
if (output.payload !== void 0) {
|
|
99
|
+
const payload = jsonToXml(output.payload, 2);
|
|
100
|
+
parts.push(" <phase_input>");
|
|
101
|
+
if (payload) parts.push(payload);
|
|
102
|
+
else if (output.payload === null) parts.push(" null");
|
|
103
|
+
parts.push(" </phase_input>");
|
|
104
|
+
}
|
|
98
105
|
if (output.results && output.results.length > 0 || output.instruction) {
|
|
99
106
|
parts.push(` <prev_phase_outputs>`);
|
|
100
107
|
if (output.instruction) {
|
|
@@ -161,15 +168,147 @@ function normalizeRelativePath(path) {
|
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// src/harness/tools/route-tool.ts
|
|
171
|
+
import Type2 from "typebox";
|
|
172
|
+
|
|
173
|
+
// src/runtime/json.ts
|
|
174
|
+
function isPlainObject(value) {
|
|
175
|
+
const prototype = Object.getPrototypeOf(value);
|
|
176
|
+
return prototype === Object.prototype || prototype === null;
|
|
177
|
+
}
|
|
178
|
+
function hasOnlyDataProperties(value) {
|
|
179
|
+
return Reflect.ownKeys(value).every((key) => {
|
|
180
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
181
|
+
return Boolean(descriptor && "value" in descriptor);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function visit(value, seen) {
|
|
185
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
186
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
187
|
+
if (typeof value !== "object" || seen.has(value)) return false;
|
|
188
|
+
seen.add(value);
|
|
189
|
+
try {
|
|
190
|
+
if (Array.isArray(value)) {
|
|
191
|
+
if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDataProperties(value)) return false;
|
|
192
|
+
if (Reflect.ownKeys(value).some((key) => key !== "length" && typeof key !== "string")) return false;
|
|
193
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
194
|
+
if (!Object.prototype.hasOwnProperty.call(value, index) || !visit(value[index], seen)) return false;
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
if (!isPlainObject(value) || !hasOnlyDataProperties(value)) return false;
|
|
199
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== "string")) return false;
|
|
200
|
+
if (Object.prototype.hasOwnProperty.call(value, "toJSON")) return false;
|
|
201
|
+
return Object.keys(value).every((key) => visit(value[key], seen));
|
|
202
|
+
} finally {
|
|
203
|
+
seen.delete(value);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function isJsonValue(value) {
|
|
207
|
+
return visit(value, /* @__PURE__ */ new Set());
|
|
208
|
+
}
|
|
209
|
+
function assertJsonValue(value, argument = "value") {
|
|
210
|
+
if (!isJsonValue(value)) throw new TypeError(`${argument} must be JSON-safe`);
|
|
211
|
+
}
|
|
212
|
+
function canonicalJson(value) {
|
|
213
|
+
assertJsonValue(value);
|
|
214
|
+
const encode = (candidate) => {
|
|
215
|
+
if (candidate === null || typeof candidate !== "object") return JSON.stringify(candidate);
|
|
216
|
+
if (Array.isArray(candidate)) return `[${candidate.map(encode).join(",")}]`;
|
|
217
|
+
const object = candidate;
|
|
218
|
+
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${encode(object[key])}`).join(",")}}`;
|
|
219
|
+
};
|
|
220
|
+
return encode(value);
|
|
221
|
+
}
|
|
222
|
+
function utf8ByteLength(value) {
|
|
223
|
+
return new TextEncoder().encode(value).byteLength;
|
|
224
|
+
}
|
|
225
|
+
function assertUtf8ByteLimit(value, limit, argument = "value") {
|
|
226
|
+
if (utf8ByteLength(value) > limit) throw new RangeError(`${argument} exceeds ${limit} UTF-8 bytes`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// src/harness/phases/input.ts
|
|
164
230
|
import Type from "typebox";
|
|
231
|
+
import Schema from "typebox/schema";
|
|
232
|
+
function parsePhaseInput(value) {
|
|
233
|
+
if (value === void 0) return void 0;
|
|
234
|
+
if (!isJsonValue(value) || value === null || Array.isArray(value)) {
|
|
235
|
+
throw new TypeError("input must be a JSON-safe object");
|
|
236
|
+
}
|
|
237
|
+
return value;
|
|
238
|
+
}
|
|
239
|
+
function phaseInputSchema(input) {
|
|
240
|
+
return schemaForObject(input);
|
|
241
|
+
}
|
|
242
|
+
function preparePhasePayload(input, payload) {
|
|
243
|
+
if (payload !== void 0 && !isJsonValue(payload)) {
|
|
244
|
+
throw new TypeError("Phase payload must be JSON-safe");
|
|
245
|
+
}
|
|
246
|
+
if (input === void 0 || payload === void 0) {
|
|
247
|
+
if (input === void 0) return payload;
|
|
248
|
+
return mergeDefaultObject(input, {});
|
|
249
|
+
}
|
|
250
|
+
const validator = Schema.Compile(phaseInputSchema(input));
|
|
251
|
+
if (!validator.Check(payload)) {
|
|
252
|
+
throw new TypeError("Phase payload does not match the Phase input definition");
|
|
253
|
+
}
|
|
254
|
+
return mergeDefaultObject(input, payload);
|
|
255
|
+
}
|
|
256
|
+
function schemaForValue(value) {
|
|
257
|
+
if (value === null) return Type.Unknown();
|
|
258
|
+
if (typeof value === "string") return Type.String();
|
|
259
|
+
if (typeof value === "boolean") return Type.Boolean();
|
|
260
|
+
if (typeof value === "number") return Type.Number();
|
|
261
|
+
if (Array.isArray(value)) {
|
|
262
|
+
if (value.length === 0) return Type.Array(Type.Unknown());
|
|
263
|
+
const schemas = value.map(schemaForValue);
|
|
264
|
+
const unique = new Map(schemas.map((schema) => [JSON.stringify(schema), schema]));
|
|
265
|
+
const item = unique.size === 1 ? [...unique.values()][0] : Type.Union([...unique.values()]);
|
|
266
|
+
return Type.Array(item);
|
|
267
|
+
}
|
|
268
|
+
if (!isJsonObject(value)) throw new TypeError("Phase input values must be JSON-safe");
|
|
269
|
+
return schemaForObject(value);
|
|
270
|
+
}
|
|
271
|
+
function schemaForObject(value) {
|
|
272
|
+
const keys = Object.keys(value);
|
|
273
|
+
if (keys.length === 0) return Type.Record(Type.String(), Type.Unknown());
|
|
274
|
+
const properties = Object.fromEntries(keys.map((key) => [key, schemaForValue(value[key])]));
|
|
275
|
+
return Type.Partial(Type.Object(properties), { additionalProperties: false });
|
|
276
|
+
}
|
|
277
|
+
function mergeDefaultObject(defaults, payload) {
|
|
278
|
+
const result = {};
|
|
279
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
280
|
+
const defaultValue = defaults[key];
|
|
281
|
+
result[key] = defaultValue !== void 0 && isJsonObject(defaultValue) && isJsonObject(value) ? mergeDefaultObject(defaultValue, value) : cloneJsonValue(value);
|
|
282
|
+
}
|
|
283
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
284
|
+
if (!Object.prototype.hasOwnProperty.call(payload, key)) {
|
|
285
|
+
result[key] = cloneJsonValue(value);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
function cloneJsonValue(value) {
|
|
291
|
+
if (Array.isArray(value)) return value.map(cloneJsonValue);
|
|
292
|
+
if (isJsonObject(value)) {
|
|
293
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, cloneJsonValue(item)]));
|
|
294
|
+
}
|
|
295
|
+
return value;
|
|
296
|
+
}
|
|
297
|
+
function isJsonObject(value) {
|
|
298
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/harness/tools/route-tool.ts
|
|
165
302
|
var PhaseRouteTool = "route";
|
|
166
303
|
function buildPhaseEntry(p) {
|
|
167
304
|
const entry = { name: p.name, description: p.description };
|
|
168
305
|
if (p.tools && p.tools.length > 0) {
|
|
169
306
|
entry.available_tools = p.tools.join(", ");
|
|
170
307
|
}
|
|
171
|
-
if (p.input
|
|
172
|
-
entry.
|
|
308
|
+
if (p.input !== void 0) {
|
|
309
|
+
entry.payload_schema = JSON.stringify(phaseInputSchema(p.input));
|
|
310
|
+
} else {
|
|
311
|
+
entry.payload_schema = "any JSON-safe value";
|
|
173
312
|
}
|
|
174
313
|
return entry;
|
|
175
314
|
}
|
|
@@ -203,14 +342,20 @@ function buildRouteDescription(availablePhases) {
|
|
|
203
342
|
}
|
|
204
343
|
function createRouteTool(availablePhases) {
|
|
205
344
|
const routablePhases = availablePhases.filter(({ name }) => name !== "stop");
|
|
206
|
-
const
|
|
207
|
-
phase
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
345
|
+
const decisionTargets = [
|
|
346
|
+
...routablePhases.map((phase) => Type2.Object({
|
|
347
|
+
phase: Type2.Literal(phase.name),
|
|
348
|
+
reason: Type2.Optional(Type2.String({ description: "Brief reason for this decision" })),
|
|
349
|
+
payload: Type2.Optional(
|
|
350
|
+
phase.input === void 0 ? Type2.Unknown({ description: "Any JSON-safe value for the target phase" }) : phaseInputSchema(phase.input)
|
|
351
|
+
)
|
|
352
|
+
})),
|
|
353
|
+
Type2.Object({
|
|
354
|
+
phase: Type2.Literal("stop"),
|
|
355
|
+
reason: Type2.Optional(Type2.String({ description: "Brief reason for this decision" })),
|
|
356
|
+
payload: Type2.Optional(Type2.Unknown({ description: "Optional stop payload" }))
|
|
357
|
+
})
|
|
358
|
+
];
|
|
214
359
|
return {
|
|
215
360
|
name: PhaseRouteTool,
|
|
216
361
|
description: buildRouteDescription(availablePhases),
|
|
@@ -219,9 +364,9 @@ function createRouteTool(availablePhases) {
|
|
|
219
364
|
"Do not call route together with ordinary tools.",
|
|
220
365
|
"Use route(stop) only when the current user request or task is complete; the Stop Phase will provide the final user-facing conclusion."
|
|
221
366
|
],
|
|
222
|
-
parameters:
|
|
223
|
-
decision:
|
|
224
|
-
instruction:
|
|
367
|
+
parameters: Type2.Object({
|
|
368
|
+
decision: Type2.Array(Type2.Union(decisionTargets), { description: "Phase executions to start", minItems: 1 }),
|
|
369
|
+
instruction: Type2.Optional(Type2.String({ description: "Overall instruction, passed as context" }))
|
|
225
370
|
}),
|
|
226
371
|
// No-op: this tool is intercepted by phases, never executed via tool execution
|
|
227
372
|
execute: async (_, context) => ({
|
|
@@ -274,37 +419,37 @@ var DEFAULT_MAX_READ_BYTES = 50 * 1024;
|
|
|
274
419
|
var DEFAULT_MAX_READ_LINES = 2e3;
|
|
275
420
|
var DEFAULT_BASH_TIMEOUT_MS = 3e4;
|
|
276
421
|
var DEFAULT_MAX_BASH_OUTPUT_BYTES = 64e3;
|
|
277
|
-
var ReadArgsSchema =
|
|
278
|
-
path:
|
|
279
|
-
offset:
|
|
280
|
-
limit:
|
|
422
|
+
var ReadArgsSchema = Type3.Object({
|
|
423
|
+
path: Type3.String({ description: "Path to the file to read." }),
|
|
424
|
+
offset: Type3.Optional(Type3.Number({ description: "1-based line to start from." })),
|
|
425
|
+
limit: Type3.Optional(Type3.Number({ description: "Maximum number of lines." }))
|
|
281
426
|
});
|
|
282
|
-
var ReadArgsValidator =
|
|
283
|
-
var WriteArgsSchema =
|
|
284
|
-
path:
|
|
285
|
-
content:
|
|
427
|
+
var ReadArgsValidator = Schema2.Compile(ReadArgsSchema);
|
|
428
|
+
var WriteArgsSchema = Type3.Object({
|
|
429
|
+
path: Type3.String({ description: "Path to the file to write." }),
|
|
430
|
+
content: Type3.String({ description: "Complete file contents." })
|
|
286
431
|
});
|
|
287
|
-
var WriteArgsValidator =
|
|
288
|
-
var EditArgsSchema =
|
|
289
|
-
path:
|
|
290
|
-
edits:
|
|
291
|
-
oldText:
|
|
292
|
-
newText:
|
|
432
|
+
var WriteArgsValidator = Schema2.Compile(WriteArgsSchema);
|
|
433
|
+
var EditArgsSchema = Type3.Object({
|
|
434
|
+
path: Type3.String({ description: "Path to the file to edit." }),
|
|
435
|
+
edits: Type3.Array(Type3.Object({
|
|
436
|
+
oldText: Type3.String({ description: "Exact unique text to replace." }),
|
|
437
|
+
newText: Type3.String({ description: "Replacement text." })
|
|
293
438
|
}), { description: "One or more non-overlapping replacements." })
|
|
294
439
|
});
|
|
295
|
-
var EditArgsValidator =
|
|
296
|
-
var BashArgsSchema =
|
|
297
|
-
command:
|
|
298
|
-
timeout:
|
|
440
|
+
var EditArgsValidator = Schema2.Compile(EditArgsSchema);
|
|
441
|
+
var BashArgsSchema = Type3.Object({
|
|
442
|
+
command: Type3.String({ description: "Bash command to execute." }),
|
|
443
|
+
timeout: Type3.Optional(Type3.Number({ description: "Timeout in seconds." }))
|
|
299
444
|
});
|
|
300
|
-
var BashArgsValidator =
|
|
445
|
+
var BashArgsValidator = Schema2.Compile(BashArgsSchema);
|
|
301
446
|
var validatorCache = /* @__PURE__ */ new WeakMap();
|
|
302
447
|
function validatorFor(schema) {
|
|
303
448
|
const cached = validatorCache.get(schema);
|
|
304
449
|
if (cached) {
|
|
305
450
|
return cached;
|
|
306
451
|
}
|
|
307
|
-
const validator =
|
|
452
|
+
const validator = Schema2.Compile(schema);
|
|
308
453
|
validatorCache.set(schema, validator);
|
|
309
454
|
return validator;
|
|
310
455
|
}
|
|
@@ -1134,62 +1279,6 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1134
1279
|
};
|
|
1135
1280
|
}
|
|
1136
1281
|
|
|
1137
|
-
// src/runtime/json.ts
|
|
1138
|
-
function isPlainObject(value) {
|
|
1139
|
-
const prototype = Object.getPrototypeOf(value);
|
|
1140
|
-
return prototype === Object.prototype || prototype === null;
|
|
1141
|
-
}
|
|
1142
|
-
function hasOnlyDataProperties(value) {
|
|
1143
|
-
return Reflect.ownKeys(value).every((key) => {
|
|
1144
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
1145
|
-
return Boolean(descriptor && "value" in descriptor);
|
|
1146
|
-
});
|
|
1147
|
-
}
|
|
1148
|
-
function visit(value, seen) {
|
|
1149
|
-
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
1150
|
-
if (typeof value === "number") return Number.isFinite(value);
|
|
1151
|
-
if (typeof value !== "object" || seen.has(value)) return false;
|
|
1152
|
-
seen.add(value);
|
|
1153
|
-
try {
|
|
1154
|
-
if (Array.isArray(value)) {
|
|
1155
|
-
if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDataProperties(value)) return false;
|
|
1156
|
-
if (Reflect.ownKeys(value).some((key) => key !== "length" && typeof key !== "string")) return false;
|
|
1157
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
1158
|
-
if (!Object.prototype.hasOwnProperty.call(value, index) || !visit(value[index], seen)) return false;
|
|
1159
|
-
}
|
|
1160
|
-
return true;
|
|
1161
|
-
}
|
|
1162
|
-
if (!isPlainObject(value) || !hasOnlyDataProperties(value)) return false;
|
|
1163
|
-
if (Reflect.ownKeys(value).some((key) => typeof key !== "string")) return false;
|
|
1164
|
-
if (Object.prototype.hasOwnProperty.call(value, "toJSON")) return false;
|
|
1165
|
-
return Object.keys(value).every((key) => visit(value[key], seen));
|
|
1166
|
-
} finally {
|
|
1167
|
-
seen.delete(value);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
function isJsonValue(value) {
|
|
1171
|
-
return visit(value, /* @__PURE__ */ new Set());
|
|
1172
|
-
}
|
|
1173
|
-
function assertJsonValue(value, argument = "value") {
|
|
1174
|
-
if (!isJsonValue(value)) throw new TypeError(`${argument} must be JSON-safe`);
|
|
1175
|
-
}
|
|
1176
|
-
function canonicalJson(value) {
|
|
1177
|
-
assertJsonValue(value);
|
|
1178
|
-
const encode = (candidate) => {
|
|
1179
|
-
if (candidate === null || typeof candidate !== "object") return JSON.stringify(candidate);
|
|
1180
|
-
if (Array.isArray(candidate)) return `[${candidate.map(encode).join(",")}]`;
|
|
1181
|
-
const object = candidate;
|
|
1182
|
-
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${encode(object[key])}`).join(",")}}`;
|
|
1183
|
-
};
|
|
1184
|
-
return encode(value);
|
|
1185
|
-
}
|
|
1186
|
-
function utf8ByteLength(value) {
|
|
1187
|
-
return new TextEncoder().encode(value).byteLength;
|
|
1188
|
-
}
|
|
1189
|
-
function assertUtf8ByteLimit(value, limit, argument = "value") {
|
|
1190
|
-
if (utf8ByteLength(value) > limit) throw new RangeError(`${argument} exceeds ${limit} UTF-8 bytes`);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
1282
|
// src/harness/phases/interactions.ts
|
|
1194
1283
|
var PhaseInteractionCancelledError = class extends Error {
|
|
1195
1284
|
code = "phase_interaction_cancelled";
|
|
@@ -1621,13 +1710,21 @@ async function loadPhase(targetPath) {
|
|
|
1621
1710
|
warnResourceDiagnostics("phase", resolved, diagnostics);
|
|
1622
1711
|
const baseDir = dirname4(resolved);
|
|
1623
1712
|
const skills = await loadPhaseSkills(baseDir);
|
|
1713
|
+
let input;
|
|
1714
|
+
try {
|
|
1715
|
+
input = parsePhaseInput(metadata.input);
|
|
1716
|
+
} catch (error) {
|
|
1717
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1718
|
+
warnResourceDiagnostics("phase", resolved, [message]);
|
|
1719
|
+
throw new ResourceMetadataError("invalid_metadata", message);
|
|
1720
|
+
}
|
|
1624
1721
|
const phase = {
|
|
1625
1722
|
name,
|
|
1626
1723
|
description: description.description,
|
|
1627
1724
|
tools: definition.tools ? [...definition.tools] : void 0,
|
|
1628
1725
|
skills,
|
|
1629
1726
|
target: metadata.target,
|
|
1630
|
-
input:
|
|
1727
|
+
...input === void 0 ? {} : { input },
|
|
1631
1728
|
isolated: metadata.isolated,
|
|
1632
1729
|
filePath: resolved,
|
|
1633
1730
|
baseDir,
|
|
@@ -2191,9 +2288,21 @@ function resolveRouteDecision(route, registry) {
|
|
|
2191
2288
|
if (requestedCount !== 1) return void 0;
|
|
2192
2289
|
return { ...route, requestedCount };
|
|
2193
2290
|
}
|
|
2194
|
-
const decision = route.decision.
|
|
2291
|
+
const decision = route.decision.flatMap((candidate) => {
|
|
2292
|
+
const target = registry.phases.get(candidate.phase);
|
|
2293
|
+
if (!target) return [];
|
|
2294
|
+
try {
|
|
2295
|
+
const payload = preparePhasePayload(target.input, normalizePayload(candidate.payload));
|
|
2296
|
+
return [{
|
|
2297
|
+
...candidate,
|
|
2298
|
+
...payload === void 0 ? {} : { payload }
|
|
2299
|
+
}];
|
|
2300
|
+
} catch {
|
|
2301
|
+
return [];
|
|
2302
|
+
}
|
|
2303
|
+
});
|
|
2195
2304
|
if (decision.length === 0) return void 0;
|
|
2196
|
-
return { ...route, decision, requestedCount };
|
|
2305
|
+
return { ...route, decision, requestedCount: decision.length };
|
|
2197
2306
|
}
|
|
2198
2307
|
function resolveModelRouteDecision(toolCalls, registry) {
|
|
2199
2308
|
return resolveRouteDecision(toolCalls ? extractRouteCall(toolCalls) : void 0, registry);
|
|
@@ -2428,7 +2537,8 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2428
2537
|
if (resumingSuspendedRun) {
|
|
2429
2538
|
state.status = "running";
|
|
2430
2539
|
}
|
|
2431
|
-
|
|
2540
|
+
const initialPayload = !resumingSuspendedRun ? config.execution.runMetadata?.phasePayload : void 0;
|
|
2541
|
+
let previousPayload = resumingSuspendedRun ? state.continuation?.previousPayload : initialPayload;
|
|
2432
2542
|
let previousPhaseMsgId = resumingSuspendedRun ? state.continuation?.previousPhaseMessageId : void 0;
|
|
2433
2543
|
let previousPhaseInputMsgId;
|
|
2434
2544
|
let previousResults = resumingSuspendedRun ? state.continuation?.previousResults?.map((result) => ({ ...result })) ?? [] : [];
|
|
@@ -2519,6 +2629,9 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2519
2629
|
if (!phase) {
|
|
2520
2630
|
throw new Error(`Phase "${currentPhaseId}" not found`);
|
|
2521
2631
|
}
|
|
2632
|
+
if (previousPayload !== void 0 || phase.input !== void 0) {
|
|
2633
|
+
previousPayload = preparePhasePayload(phase.input, previousPayload);
|
|
2634
|
+
}
|
|
2522
2635
|
state.currentPhase = currentPhaseId;
|
|
2523
2636
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
2524
2637
|
const messageManager = createMessageManager(config.context, config.onMessage, config.onMessageDelta);
|
|
@@ -2584,7 +2697,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2584
2697
|
const lastMessageBeforePhase = config.context.messages.at(-1);
|
|
2585
2698
|
previousPhaseMsgId = injectPhaseContent(
|
|
2586
2699
|
phase,
|
|
2587
|
-
{ results: previousResults, instruction: pendingInstruction },
|
|
2700
|
+
{ results: previousResults, instruction: pendingInstruction, payload: previousPayload },
|
|
2588
2701
|
config.context.messages,
|
|
2589
2702
|
phaseContext.messages
|
|
2590
2703
|
);
|
|
@@ -2630,6 +2743,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2630
2743
|
output = extAfter.output;
|
|
2631
2744
|
if (hookHasRoute) {
|
|
2632
2745
|
routeDecision = resolveHookRouteDecision(output, registry);
|
|
2746
|
+
if (routeDecision) applyFirstDecision(routeDecision, output);
|
|
2633
2747
|
} else if (phase.run || phase.factory) {
|
|
2634
2748
|
output = { ...output, route: "stop" };
|
|
2635
2749
|
routeDecision = void 0;
|
|
@@ -2736,7 +2850,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2736
2850
|
}
|
|
2737
2851
|
currentPhaseId = STOP_PHASE_ID;
|
|
2738
2852
|
previousPayload = output.payload;
|
|
2739
|
-
previousResults =
|
|
2853
|
+
previousResults = [];
|
|
2740
2854
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2741
2855
|
continue;
|
|
2742
2856
|
}
|
|
@@ -2753,8 +2867,10 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2753
2867
|
to: targetPhaseId,
|
|
2754
2868
|
ts: createTimestamp()
|
|
2755
2869
|
});
|
|
2756
|
-
|
|
2757
|
-
|
|
2870
|
+
const targetPhase = registry.phases.get(targetPhaseId);
|
|
2871
|
+
const targetPayload = !phase.target && routeDecision ? routeDecision.decision[0]?.payload : output.payload;
|
|
2872
|
+
previousPayload = preparePhasePayload(targetPhase?.input, targetPayload);
|
|
2873
|
+
previousResults = [];
|
|
2758
2874
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2759
2875
|
currentPhaseId = targetPhaseId;
|
|
2760
2876
|
}
|
|
@@ -3023,6 +3139,7 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3023
3139
|
}
|
|
3024
3140
|
async function executeParallelPhase(config, state, registry, phase, payload, instruction, context, availablePhases, instanceId, groupId, index, count, sourcePhaseId) {
|
|
3025
3141
|
const messages = [...context];
|
|
3142
|
+
const effectivePayload = preparePhasePayload(phase.input, payload);
|
|
3026
3143
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
3027
3144
|
const phaseTools = selectPhaseTools(allTools, phase.tools, false);
|
|
3028
3145
|
const phaseSkills = mergeSkills(config.context.skills, phase.skills);
|
|
@@ -3045,7 +3162,7 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3045
3162
|
current: phase.name,
|
|
3046
3163
|
available: Array.from(registry.phases.keys()),
|
|
3047
3164
|
iterations: 0,
|
|
3048
|
-
payload
|
|
3165
|
+
payload: effectivePayload
|
|
3049
3166
|
}
|
|
3050
3167
|
};
|
|
3051
3168
|
const messageManager = createMessageManager({ messages }, config.onMessage, config.onMessageDelta);
|
|
@@ -3053,7 +3170,8 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3053
3170
|
phase,
|
|
3054
3171
|
{
|
|
3055
3172
|
instruction,
|
|
3056
|
-
|
|
3173
|
+
payload: effectivePayload,
|
|
3174
|
+
results: []
|
|
3057
3175
|
},
|
|
3058
3176
|
messages
|
|
3059
3177
|
);
|
|
@@ -5891,6 +6009,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5891
6009
|
kind: "phase",
|
|
5892
6010
|
name: phase.name,
|
|
5893
6011
|
description: phase.description,
|
|
6012
|
+
...phase.input === void 0 ? {} : { input: phase.input },
|
|
5894
6013
|
...phase.core ? { core: true } : {},
|
|
5895
6014
|
disableAutoInvocation: phase.disableAutoInvocation ?? false,
|
|
5896
6015
|
disableImplicitInvocation: phase.disableImplicitInvocation ?? false,
|