@rowan-agent/agent 0.9.15 → 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 +94 -4
- package/dist/index.js +265 -117
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -886,6 +886,10 @@ interface ExtensionAPI {
|
|
|
886
886
|
getNextPhase(): string | undefined;
|
|
887
887
|
/** Get the message set by setMessage */
|
|
888
888
|
getMessage(): string | undefined;
|
|
889
|
+
/** Phase Settings contributions registered by the Phase extension. */
|
|
890
|
+
settings: {
|
|
891
|
+
register(provider: PhaseSettingsProvider): void;
|
|
892
|
+
};
|
|
889
893
|
};
|
|
890
894
|
}
|
|
891
895
|
/**
|
|
@@ -976,6 +980,85 @@ interface PhaseContext {
|
|
|
976
980
|
/** Text to append after the system prompt */
|
|
977
981
|
appendSystemPrompt?: string;
|
|
978
982
|
}
|
|
983
|
+
/** JSON-safe structural defaults declared by a Phase's `input` mapping. */
|
|
984
|
+
type PhaseInput = Readonly<Record<string, JsonValue>>;
|
|
985
|
+
/** JSON-safe option metadata exposed by a Phase to a host Settings surface. */
|
|
986
|
+
interface PhaseSettingsOption {
|
|
987
|
+
value: string;
|
|
988
|
+
label: string;
|
|
989
|
+
description?: string;
|
|
990
|
+
disabled?: boolean;
|
|
991
|
+
}
|
|
992
|
+
interface PhaseSettingsBadge {
|
|
993
|
+
label: string;
|
|
994
|
+
tone?: "neutral" | "success" | "review" | "danger";
|
|
995
|
+
}
|
|
996
|
+
interface PhaseSettingsItem {
|
|
997
|
+
id: string;
|
|
998
|
+
title: string;
|
|
999
|
+
description?: string;
|
|
1000
|
+
badges?: readonly PhaseSettingsBadge[];
|
|
1001
|
+
}
|
|
1002
|
+
type PhaseSettingsControl = {
|
|
1003
|
+
type: "boolean";
|
|
1004
|
+
path: string;
|
|
1005
|
+
label: string;
|
|
1006
|
+
description?: string;
|
|
1007
|
+
} | {
|
|
1008
|
+
type: "number";
|
|
1009
|
+
path: string;
|
|
1010
|
+
label: string;
|
|
1011
|
+
description?: string;
|
|
1012
|
+
min?: number;
|
|
1013
|
+
max?: number;
|
|
1014
|
+
step?: number;
|
|
1015
|
+
unit?: string;
|
|
1016
|
+
scale?: number;
|
|
1017
|
+
} | {
|
|
1018
|
+
type: "select";
|
|
1019
|
+
path: string;
|
|
1020
|
+
label: string;
|
|
1021
|
+
description?: string;
|
|
1022
|
+
options: readonly PhaseSettingsOption[];
|
|
1023
|
+
} | {
|
|
1024
|
+
type: "text";
|
|
1025
|
+
path: string;
|
|
1026
|
+
label: string;
|
|
1027
|
+
description?: string;
|
|
1028
|
+
placeholder?: string;
|
|
1029
|
+
format?: "string" | "string-array" | "key-value";
|
|
1030
|
+
multiline?: boolean;
|
|
1031
|
+
} | {
|
|
1032
|
+
type: "collection";
|
|
1033
|
+
path: string;
|
|
1034
|
+
label: string;
|
|
1035
|
+
description?: string;
|
|
1036
|
+
items: readonly PhaseSettingsItem[];
|
|
1037
|
+
fields: readonly PhaseSettingsControl[];
|
|
1038
|
+
add?: {
|
|
1039
|
+
label: string;
|
|
1040
|
+
idLabel?: string;
|
|
1041
|
+
fields: readonly PhaseSettingsControl[];
|
|
1042
|
+
};
|
|
1043
|
+
removeLabel?: string;
|
|
1044
|
+
};
|
|
1045
|
+
interface PhaseSettingsSection {
|
|
1046
|
+
id: string;
|
|
1047
|
+
title: string;
|
|
1048
|
+
description?: string;
|
|
1049
|
+
controls: readonly PhaseSettingsControl[];
|
|
1050
|
+
}
|
|
1051
|
+
/** Declarative, host-neutral Settings surface contributed by a Phase. */
|
|
1052
|
+
interface PhaseSettingsDefinition {
|
|
1053
|
+
description?: string;
|
|
1054
|
+
sections: readonly PhaseSettingsSection[];
|
|
1055
|
+
}
|
|
1056
|
+
/** Host context is intentionally opaque beyond the effective configuration. */
|
|
1057
|
+
interface PhaseSettingsContext {
|
|
1058
|
+
configuration: Readonly<Record<string, unknown>>;
|
|
1059
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
1060
|
+
}
|
|
1061
|
+
type PhaseSettingsProvider = (context: PhaseSettingsContext) => PhaseSettingsDefinition | Promise<PhaseSettingsDefinition>;
|
|
979
1062
|
/**
|
|
980
1063
|
* Loaded Phase object
|
|
981
1064
|
*/
|
|
@@ -992,8 +1075,8 @@ interface Phase {
|
|
|
992
1075
|
skills?: Skill[];
|
|
993
1076
|
/** Forced next phase */
|
|
994
1077
|
target?: string;
|
|
995
|
-
/**
|
|
996
|
-
input?:
|
|
1078
|
+
/** Structural JSON-safe input defaults */
|
|
1079
|
+
input?: PhaseInput;
|
|
997
1080
|
/** If true, phase gets a fresh context when executed in parallel */
|
|
998
1081
|
isolated?: boolean;
|
|
999
1082
|
/** Path to PHASE.md file */
|
|
@@ -1008,7 +1091,7 @@ interface Phase {
|
|
|
1008
1091
|
disableAutoInvocation?: boolean;
|
|
1009
1092
|
/** Do not expose this Phase to direct user invocation. */
|
|
1010
1093
|
disableImplicitInvocation?: boolean;
|
|
1011
|
-
/** ExtensionAPI factory function
|
|
1094
|
+
/** ExtensionAPI factory function used for registration or programmatic execution. */
|
|
1012
1095
|
factory?: (api: ExtensionAPI) => Promise<void>;
|
|
1013
1096
|
/** Direct run function */
|
|
1014
1097
|
run?: (context: PhaseContext, execution: PhaseExecution) => Promise<PhaseOutput | void>;
|
|
@@ -1517,6 +1600,7 @@ type InvocationCatalogEntry = Readonly<{
|
|
|
1517
1600
|
kind: "phase" | "skill";
|
|
1518
1601
|
name: string;
|
|
1519
1602
|
description: string;
|
|
1603
|
+
input?: Phase["input"];
|
|
1520
1604
|
core?: boolean;
|
|
1521
1605
|
disableAutoInvocation: boolean;
|
|
1522
1606
|
disableImplicitInvocation: boolean;
|
|
@@ -2645,6 +2729,12 @@ declare function loadSkills(targetPath: string): Promise<Skill[]>;
|
|
|
2645
2729
|
* If a directory is provided, the loader reads its PHASE.md.
|
|
2646
2730
|
*/
|
|
2647
2731
|
declare function loadPhase(targetPath: string): Promise<Phase>;
|
|
2732
|
+
/**
|
|
2733
|
+
* Collect and evaluate the Settings provider registered through the Phase's
|
|
2734
|
+
* ExtensionAPI namespace. Settings discovery never reads a direct module
|
|
2735
|
+
* export; the Phase contributes through `api.phase.settings.register()`.
|
|
2736
|
+
*/
|
|
2737
|
+
declare function loadPhaseSettings(phase: Phase, context: PhaseSettingsContext): Promise<PhaseSettingsDefinition | undefined>;
|
|
2648
2738
|
/**
|
|
2649
2739
|
* Load all phases from the target directory.
|
|
2650
2740
|
*
|
|
@@ -2698,4 +2788,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
|
|
|
2698
2788
|
|
|
2699
2789
|
declare function createCoreTools(input?: CoreToolContext): Tool[];
|
|
2700
2790
|
|
|
2701
|
-
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 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, 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
|
}
|
|
@@ -1055,6 +1200,7 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1055
1200
|
let outputPayload = phaseIn?.state?.payload;
|
|
1056
1201
|
let nextPhase;
|
|
1057
1202
|
let outputMessage;
|
|
1203
|
+
let settingsProvider;
|
|
1058
1204
|
return {
|
|
1059
1205
|
on: (eventType, handler) => {
|
|
1060
1206
|
assertActive();
|
|
@@ -1115,65 +1261,22 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1115
1261
|
nextPhase = id;
|
|
1116
1262
|
},
|
|
1117
1263
|
getNextPhase: () => nextPhase,
|
|
1118
|
-
getMessage: () => outputMessage
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
return Boolean(descriptor && "value" in descriptor);
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
function visit(value, seen) {
|
|
1135
|
-
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
1136
|
-
if (typeof value === "number") return Number.isFinite(value);
|
|
1137
|
-
if (typeof value !== "object" || seen.has(value)) return false;
|
|
1138
|
-
seen.add(value);
|
|
1139
|
-
try {
|
|
1140
|
-
if (Array.isArray(value)) {
|
|
1141
|
-
if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDataProperties(value)) return false;
|
|
1142
|
-
if (Reflect.ownKeys(value).some((key) => key !== "length" && typeof key !== "string")) return false;
|
|
1143
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
1144
|
-
if (!Object.prototype.hasOwnProperty.call(value, index) || !visit(value[index], seen)) return false;
|
|
1264
|
+
getMessage: () => outputMessage,
|
|
1265
|
+
settings: {
|
|
1266
|
+
register: (provider) => {
|
|
1267
|
+
assertActive();
|
|
1268
|
+
if (typeof provider !== "function") {
|
|
1269
|
+
throw new Error("Phase Settings registration requires a provider function.");
|
|
1270
|
+
}
|
|
1271
|
+
if (settingsProvider) {
|
|
1272
|
+
throw new Error("A Phase may register only one Settings provider.");
|
|
1273
|
+
}
|
|
1274
|
+
settingsProvider = provider;
|
|
1275
|
+
options?.registerSettings?.(provider);
|
|
1276
|
+
}
|
|
1145
1277
|
}
|
|
1146
|
-
return true;
|
|
1147
1278
|
}
|
|
1148
|
-
if (!isPlainObject(value) || !hasOnlyDataProperties(value)) return false;
|
|
1149
|
-
if (Reflect.ownKeys(value).some((key) => typeof key !== "string")) return false;
|
|
1150
|
-
if (Object.prototype.hasOwnProperty.call(value, "toJSON")) return false;
|
|
1151
|
-
return Object.keys(value).every((key) => visit(value[key], seen));
|
|
1152
|
-
} finally {
|
|
1153
|
-
seen.delete(value);
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
function isJsonValue(value) {
|
|
1157
|
-
return visit(value, /* @__PURE__ */ new Set());
|
|
1158
|
-
}
|
|
1159
|
-
function assertJsonValue(value, argument = "value") {
|
|
1160
|
-
if (!isJsonValue(value)) throw new TypeError(`${argument} must be JSON-safe`);
|
|
1161
|
-
}
|
|
1162
|
-
function canonicalJson(value) {
|
|
1163
|
-
assertJsonValue(value);
|
|
1164
|
-
const encode = (candidate) => {
|
|
1165
|
-
if (candidate === null || typeof candidate !== "object") return JSON.stringify(candidate);
|
|
1166
|
-
if (Array.isArray(candidate)) return `[${candidate.map(encode).join(",")}]`;
|
|
1167
|
-
const object = candidate;
|
|
1168
|
-
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${encode(object[key])}`).join(",")}}`;
|
|
1169
1279
|
};
|
|
1170
|
-
return encode(value);
|
|
1171
|
-
}
|
|
1172
|
-
function utf8ByteLength(value) {
|
|
1173
|
-
return new TextEncoder().encode(value).byteLength;
|
|
1174
|
-
}
|
|
1175
|
-
function assertUtf8ByteLimit(value, limit, argument = "value") {
|
|
1176
|
-
if (utf8ByteLength(value) > limit) throw new RangeError(`${argument} exceeds ${limit} UTF-8 bytes`);
|
|
1177
1280
|
}
|
|
1178
1281
|
|
|
1179
1282
|
// src/harness/phases/interactions.ts
|
|
@@ -1607,13 +1710,21 @@ async function loadPhase(targetPath) {
|
|
|
1607
1710
|
warnResourceDiagnostics("phase", resolved, diagnostics);
|
|
1608
1711
|
const baseDir = dirname4(resolved);
|
|
1609
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
|
+
}
|
|
1610
1721
|
const phase = {
|
|
1611
1722
|
name,
|
|
1612
1723
|
description: description.description,
|
|
1613
1724
|
tools: definition.tools ? [...definition.tools] : void 0,
|
|
1614
1725
|
skills,
|
|
1615
1726
|
target: metadata.target,
|
|
1616
|
-
input:
|
|
1727
|
+
...input === void 0 ? {} : { input },
|
|
1617
1728
|
isolated: metadata.isolated,
|
|
1618
1729
|
filePath: resolved,
|
|
1619
1730
|
baseDir,
|
|
@@ -1627,12 +1738,24 @@ async function loadPhase(targetPath) {
|
|
|
1627
1738
|
const code = await loadPhaseCode(codePath);
|
|
1628
1739
|
if (code.factory) {
|
|
1629
1740
|
phase.factory = code.factory;
|
|
1630
|
-
}
|
|
1741
|
+
}
|
|
1742
|
+
if (code.run) {
|
|
1631
1743
|
phase.run = code.run;
|
|
1632
1744
|
}
|
|
1633
1745
|
}
|
|
1634
1746
|
return phase;
|
|
1635
1747
|
}
|
|
1748
|
+
async function loadPhaseSettings(phase, context) {
|
|
1749
|
+
if (!phase.factory) return void 0;
|
|
1750
|
+
let provider;
|
|
1751
|
+
const api = createExtensionAPI(void 0, {
|
|
1752
|
+
registerSettings: (candidate) => {
|
|
1753
|
+
provider = candidate;
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
await phase.factory(api);
|
|
1757
|
+
return provider ? provider(context) : void 0;
|
|
1758
|
+
}
|
|
1636
1759
|
async function loadPhaseSkills(baseDir) {
|
|
1637
1760
|
const entries = await readdir2(baseDir, { withFileTypes: true });
|
|
1638
1761
|
const skills = [];
|
|
@@ -1743,13 +1866,15 @@ async function loadPhaseCode(codePath) {
|
|
|
1743
1866
|
moduleCache: false,
|
|
1744
1867
|
tryNative: false
|
|
1745
1868
|
});
|
|
1746
|
-
const mod = await jiti.import(codePath
|
|
1747
|
-
const
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1869
|
+
const mod = await jiti.import(codePath);
|
|
1870
|
+
const namespace = mod && typeof mod === "object" ? mod : {};
|
|
1871
|
+
const fn = typeof mod === "function" ? mod : namespace.default;
|
|
1872
|
+
const run = namespace.run;
|
|
1873
|
+
if (typeof fn === "function" || typeof run === "function") {
|
|
1874
|
+
return {
|
|
1875
|
+
...typeof fn === "function" ? { factory: fn } : {},
|
|
1876
|
+
...typeof run === "function" ? { run } : {}
|
|
1877
|
+
};
|
|
1753
1878
|
}
|
|
1754
1879
|
throw new Error(`Phase code at "${codePath}" must export a default function or a run() function.`);
|
|
1755
1880
|
}
|
|
@@ -2163,9 +2288,21 @@ function resolveRouteDecision(route, registry) {
|
|
|
2163
2288
|
if (requestedCount !== 1) return void 0;
|
|
2164
2289
|
return { ...route, requestedCount };
|
|
2165
2290
|
}
|
|
2166
|
-
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
|
+
});
|
|
2167
2304
|
if (decision.length === 0) return void 0;
|
|
2168
|
-
return { ...route, decision, requestedCount };
|
|
2305
|
+
return { ...route, decision, requestedCount: decision.length };
|
|
2169
2306
|
}
|
|
2170
2307
|
function resolveModelRouteDecision(toolCalls, registry) {
|
|
2171
2308
|
return resolveRouteDecision(toolCalls ? extractRouteCall(toolCalls) : void 0, registry);
|
|
@@ -2400,7 +2537,8 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2400
2537
|
if (resumingSuspendedRun) {
|
|
2401
2538
|
state.status = "running";
|
|
2402
2539
|
}
|
|
2403
|
-
|
|
2540
|
+
const initialPayload = !resumingSuspendedRun ? config.execution.runMetadata?.phasePayload : void 0;
|
|
2541
|
+
let previousPayload = resumingSuspendedRun ? state.continuation?.previousPayload : initialPayload;
|
|
2404
2542
|
let previousPhaseMsgId = resumingSuspendedRun ? state.continuation?.previousPhaseMessageId : void 0;
|
|
2405
2543
|
let previousPhaseInputMsgId;
|
|
2406
2544
|
let previousResults = resumingSuspendedRun ? state.continuation?.previousResults?.map((result) => ({ ...result })) ?? [] : [];
|
|
@@ -2491,6 +2629,9 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2491
2629
|
if (!phase) {
|
|
2492
2630
|
throw new Error(`Phase "${currentPhaseId}" not found`);
|
|
2493
2631
|
}
|
|
2632
|
+
if (previousPayload !== void 0 || phase.input !== void 0) {
|
|
2633
|
+
previousPayload = preparePhasePayload(phase.input, previousPayload);
|
|
2634
|
+
}
|
|
2494
2635
|
state.currentPhase = currentPhaseId;
|
|
2495
2636
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
2496
2637
|
const messageManager = createMessageManager(config.context, config.onMessage, config.onMessageDelta);
|
|
@@ -2556,7 +2697,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2556
2697
|
const lastMessageBeforePhase = config.context.messages.at(-1);
|
|
2557
2698
|
previousPhaseMsgId = injectPhaseContent(
|
|
2558
2699
|
phase,
|
|
2559
|
-
{ results: previousResults, instruction: pendingInstruction },
|
|
2700
|
+
{ results: previousResults, instruction: pendingInstruction, payload: previousPayload },
|
|
2560
2701
|
config.context.messages,
|
|
2561
2702
|
phaseContext.messages
|
|
2562
2703
|
);
|
|
@@ -2602,6 +2743,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2602
2743
|
output = extAfter.output;
|
|
2603
2744
|
if (hookHasRoute) {
|
|
2604
2745
|
routeDecision = resolveHookRouteDecision(output, registry);
|
|
2746
|
+
if (routeDecision) applyFirstDecision(routeDecision, output);
|
|
2605
2747
|
} else if (phase.run || phase.factory) {
|
|
2606
2748
|
output = { ...output, route: "stop" };
|
|
2607
2749
|
routeDecision = void 0;
|
|
@@ -2708,7 +2850,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2708
2850
|
}
|
|
2709
2851
|
currentPhaseId = STOP_PHASE_ID;
|
|
2710
2852
|
previousPayload = output.payload;
|
|
2711
|
-
previousResults =
|
|
2853
|
+
previousResults = [];
|
|
2712
2854
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2713
2855
|
continue;
|
|
2714
2856
|
}
|
|
@@ -2725,8 +2867,10 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2725
2867
|
to: targetPhaseId,
|
|
2726
2868
|
ts: createTimestamp()
|
|
2727
2869
|
});
|
|
2728
|
-
|
|
2729
|
-
|
|
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 = [];
|
|
2730
2874
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2731
2875
|
currentPhaseId = targetPhaseId;
|
|
2732
2876
|
}
|
|
@@ -2784,6 +2928,14 @@ async function withRetry(fn, options = {}) {
|
|
|
2784
2928
|
}
|
|
2785
2929
|
async function executePhase(ctx) {
|
|
2786
2930
|
const { phase, config, execution, registry, context } = ctx;
|
|
2931
|
+
if (phase.run) {
|
|
2932
|
+
const output = resolvePhaseOutput(await phase.run(context, execution));
|
|
2933
|
+
output.phase = phase.name;
|
|
2934
|
+
if (output.message === "Phase completed.") {
|
|
2935
|
+
output.message = `${phase.name} phase completed.`;
|
|
2936
|
+
}
|
|
2937
|
+
return output;
|
|
2938
|
+
}
|
|
2787
2939
|
if (phase.factory) {
|
|
2788
2940
|
const api = createExtensionAPI(void 0, {
|
|
2789
2941
|
registerPhase: async () => {
|
|
@@ -2822,14 +2974,6 @@ async function executePhase(ctx) {
|
|
|
2822
2974
|
payload: api.phase.getPayload()
|
|
2823
2975
|
};
|
|
2824
2976
|
}
|
|
2825
|
-
if (phase.run) {
|
|
2826
|
-
const output = resolvePhaseOutput(await phase.run(context, execution));
|
|
2827
|
-
output.phase = phase.name;
|
|
2828
|
-
if (output.message === "Phase completed.") {
|
|
2829
|
-
output.message = `${phase.name} phase completed.`;
|
|
2830
|
-
}
|
|
2831
|
-
return output;
|
|
2832
|
-
}
|
|
2833
2977
|
return executePhaseWithModel(ctx);
|
|
2834
2978
|
}
|
|
2835
2979
|
async function executeToolCall(input) {
|
|
@@ -2995,6 +3139,7 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
2995
3139
|
}
|
|
2996
3140
|
async function executeParallelPhase(config, state, registry, phase, payload, instruction, context, availablePhases, instanceId, groupId, index, count, sourcePhaseId) {
|
|
2997
3141
|
const messages = [...context];
|
|
3142
|
+
const effectivePayload = preparePhasePayload(phase.input, payload);
|
|
2998
3143
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
2999
3144
|
const phaseTools = selectPhaseTools(allTools, phase.tools, false);
|
|
3000
3145
|
const phaseSkills = mergeSkills(config.context.skills, phase.skills);
|
|
@@ -3017,7 +3162,7 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3017
3162
|
current: phase.name,
|
|
3018
3163
|
available: Array.from(registry.phases.keys()),
|
|
3019
3164
|
iterations: 0,
|
|
3020
|
-
payload
|
|
3165
|
+
payload: effectivePayload
|
|
3021
3166
|
}
|
|
3022
3167
|
};
|
|
3023
3168
|
const messageManager = createMessageManager({ messages }, config.onMessage, config.onMessageDelta);
|
|
@@ -3025,7 +3170,8 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3025
3170
|
phase,
|
|
3026
3171
|
{
|
|
3027
3172
|
instruction,
|
|
3028
|
-
|
|
3173
|
+
payload: effectivePayload,
|
|
3174
|
+
results: []
|
|
3029
3175
|
},
|
|
3030
3176
|
messages
|
|
3031
3177
|
);
|
|
@@ -5863,6 +6009,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5863
6009
|
kind: "phase",
|
|
5864
6010
|
name: phase.name,
|
|
5865
6011
|
description: phase.description,
|
|
6012
|
+
...phase.input === void 0 ? {} : { input: phase.input },
|
|
5866
6013
|
...phase.core ? { core: true } : {},
|
|
5867
6014
|
disableAutoInvocation: phase.disableAutoInvocation ?? false,
|
|
5868
6015
|
disableImplicitInvocation: phase.disableImplicitInvocation ?? false,
|
|
@@ -8825,6 +8972,7 @@ export {
|
|
|
8825
8972
|
isRuntimeError,
|
|
8826
8973
|
loadExtensionsFromPath as loadExtensions,
|
|
8827
8974
|
loadPhase,
|
|
8975
|
+
loadPhaseSettings,
|
|
8828
8976
|
loadPhases,
|
|
8829
8977
|
loadSkill,
|
|
8830
8978
|
loadSkills,
|