@rowan-agent/agent 0.9.16 → 0.9.18
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 -6
- package/dist/index.js +231 -140
- 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;
|
|
@@ -1873,7 +1876,6 @@ interface OwnedStore {
|
|
|
1873
1876
|
executionId?: ExecutionId;
|
|
1874
1877
|
messageId?: MessageId;
|
|
1875
1878
|
configToken?: ConfigToken;
|
|
1876
|
-
inputContext?: UserInput;
|
|
1877
1879
|
}): Promise<RunClaim>;
|
|
1878
1880
|
failQueuedRun(input: {
|
|
1879
1881
|
runId: RunId;
|
|
@@ -2288,7 +2290,6 @@ declare class InMemoryStore implements DurableStore {
|
|
|
2288
2290
|
executionId?: ExecutionId;
|
|
2289
2291
|
messageId?: MessageId;
|
|
2290
2292
|
configToken?: ConfigToken;
|
|
2291
|
-
inputContext?: UserInput;
|
|
2292
2293
|
}): RunClaim;
|
|
2293
2294
|
failQueuedRun(lease: OwnerLease, input: {
|
|
2294
2295
|
runId: RunId;
|
|
@@ -2472,7 +2473,6 @@ declare class SqliteStore implements DurableStore {
|
|
|
2472
2473
|
executionId?: ExecutionId;
|
|
2473
2474
|
messageId?: MessageId;
|
|
2474
2475
|
configToken?: ConfigToken;
|
|
2475
|
-
inputContext?: UserInput;
|
|
2476
2476
|
}): Promise<RunClaim>;
|
|
2477
2477
|
failQueuedRun(lease: OwnerLease, input: {
|
|
2478
2478
|
runId: RunId;
|
|
@@ -2785,4 +2785,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
|
|
|
2785
2785
|
|
|
2786
2786
|
declare function createCoreTools(input?: CoreToolContext): Tool[];
|
|
2787
2787
|
|
|
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 };
|
|
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 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) {
|
|
@@ -46,9 +46,6 @@ function buildContextDescription(contexts) {
|
|
|
46
46
|
lines.push("</agent_context>");
|
|
47
47
|
return lines.join("\n");
|
|
48
48
|
}
|
|
49
|
-
function buildAdditionalContextMessage(contexts) {
|
|
50
|
-
return buildContextDescription(contexts);
|
|
51
|
-
}
|
|
52
49
|
function formatResourceOutput(resource) {
|
|
53
50
|
const parts = [`<${resource.type} name="${escapeXml(resource.name)}" location="${escapeXml(resource.location)}">`];
|
|
54
51
|
if (resource.baseDir) {
|
|
@@ -95,6 +92,13 @@ function buildPhaseDirectiveMessage(phase, output) {
|
|
|
95
92
|
const parts = [];
|
|
96
93
|
parts.push(`<phase_content name="${escapeXml(phase.name)}">`);
|
|
97
94
|
parts.push(phase.content);
|
|
95
|
+
if (output.payload !== void 0) {
|
|
96
|
+
const payload = jsonToXml(output.payload, 2);
|
|
97
|
+
parts.push(" <phase_input>");
|
|
98
|
+
if (payload) parts.push(payload);
|
|
99
|
+
else if (output.payload === null) parts.push(" null");
|
|
100
|
+
parts.push(" </phase_input>");
|
|
101
|
+
}
|
|
98
102
|
if (output.results && output.results.length > 0 || output.instruction) {
|
|
99
103
|
parts.push(` <prev_phase_outputs>`);
|
|
100
104
|
if (output.instruction) {
|
|
@@ -161,15 +165,147 @@ function normalizeRelativePath(path) {
|
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
// src/harness/tools/route-tool.ts
|
|
168
|
+
import Type2 from "typebox";
|
|
169
|
+
|
|
170
|
+
// src/runtime/json.ts
|
|
171
|
+
function isPlainObject(value) {
|
|
172
|
+
const prototype = Object.getPrototypeOf(value);
|
|
173
|
+
return prototype === Object.prototype || prototype === null;
|
|
174
|
+
}
|
|
175
|
+
function hasOnlyDataProperties(value) {
|
|
176
|
+
return Reflect.ownKeys(value).every((key) => {
|
|
177
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
178
|
+
return Boolean(descriptor && "value" in descriptor);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function visit(value, seen) {
|
|
182
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") return true;
|
|
183
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
184
|
+
if (typeof value !== "object" || seen.has(value)) return false;
|
|
185
|
+
seen.add(value);
|
|
186
|
+
try {
|
|
187
|
+
if (Array.isArray(value)) {
|
|
188
|
+
if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDataProperties(value)) return false;
|
|
189
|
+
if (Reflect.ownKeys(value).some((key) => key !== "length" && typeof key !== "string")) return false;
|
|
190
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
191
|
+
if (!Object.prototype.hasOwnProperty.call(value, index) || !visit(value[index], seen)) return false;
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if (!isPlainObject(value) || !hasOnlyDataProperties(value)) return false;
|
|
196
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== "string")) return false;
|
|
197
|
+
if (Object.prototype.hasOwnProperty.call(value, "toJSON")) return false;
|
|
198
|
+
return Object.keys(value).every((key) => visit(value[key], seen));
|
|
199
|
+
} finally {
|
|
200
|
+
seen.delete(value);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function isJsonValue(value) {
|
|
204
|
+
return visit(value, /* @__PURE__ */ new Set());
|
|
205
|
+
}
|
|
206
|
+
function assertJsonValue(value, argument = "value") {
|
|
207
|
+
if (!isJsonValue(value)) throw new TypeError(`${argument} must be JSON-safe`);
|
|
208
|
+
}
|
|
209
|
+
function canonicalJson(value) {
|
|
210
|
+
assertJsonValue(value);
|
|
211
|
+
const encode = (candidate) => {
|
|
212
|
+
if (candidate === null || typeof candidate !== "object") return JSON.stringify(candidate);
|
|
213
|
+
if (Array.isArray(candidate)) return `[${candidate.map(encode).join(",")}]`;
|
|
214
|
+
const object = candidate;
|
|
215
|
+
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${encode(object[key])}`).join(",")}}`;
|
|
216
|
+
};
|
|
217
|
+
return encode(value);
|
|
218
|
+
}
|
|
219
|
+
function utf8ByteLength(value) {
|
|
220
|
+
return new TextEncoder().encode(value).byteLength;
|
|
221
|
+
}
|
|
222
|
+
function assertUtf8ByteLimit(value, limit, argument = "value") {
|
|
223
|
+
if (utf8ByteLength(value) > limit) throw new RangeError(`${argument} exceeds ${limit} UTF-8 bytes`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/harness/phases/input.ts
|
|
164
227
|
import Type from "typebox";
|
|
228
|
+
import Schema from "typebox/schema";
|
|
229
|
+
function parsePhaseInput(value) {
|
|
230
|
+
if (value === void 0) return void 0;
|
|
231
|
+
if (!isJsonValue(value) || value === null || Array.isArray(value)) {
|
|
232
|
+
throw new TypeError("input must be a JSON-safe object");
|
|
233
|
+
}
|
|
234
|
+
return value;
|
|
235
|
+
}
|
|
236
|
+
function phaseInputSchema(input) {
|
|
237
|
+
return schemaForObject(input);
|
|
238
|
+
}
|
|
239
|
+
function preparePhasePayload(input, payload) {
|
|
240
|
+
if (payload !== void 0 && !isJsonValue(payload)) {
|
|
241
|
+
throw new TypeError("Phase payload must be JSON-safe");
|
|
242
|
+
}
|
|
243
|
+
if (input === void 0 || payload === void 0) {
|
|
244
|
+
if (input === void 0) return payload;
|
|
245
|
+
return mergeDefaultObject(input, {});
|
|
246
|
+
}
|
|
247
|
+
const validator = Schema.Compile(phaseInputSchema(input));
|
|
248
|
+
if (!validator.Check(payload)) {
|
|
249
|
+
throw new TypeError("Phase payload does not match the Phase input definition");
|
|
250
|
+
}
|
|
251
|
+
return mergeDefaultObject(input, payload);
|
|
252
|
+
}
|
|
253
|
+
function schemaForValue(value) {
|
|
254
|
+
if (value === null) return Type.Unknown();
|
|
255
|
+
if (typeof value === "string") return Type.String();
|
|
256
|
+
if (typeof value === "boolean") return Type.Boolean();
|
|
257
|
+
if (typeof value === "number") return Type.Number();
|
|
258
|
+
if (Array.isArray(value)) {
|
|
259
|
+
if (value.length === 0) return Type.Array(Type.Unknown());
|
|
260
|
+
const schemas = value.map(schemaForValue);
|
|
261
|
+
const unique = new Map(schemas.map((schema) => [JSON.stringify(schema), schema]));
|
|
262
|
+
const item = unique.size === 1 ? [...unique.values()][0] : Type.Union([...unique.values()]);
|
|
263
|
+
return Type.Array(item);
|
|
264
|
+
}
|
|
265
|
+
if (!isJsonObject(value)) throw new TypeError("Phase input values must be JSON-safe");
|
|
266
|
+
return schemaForObject(value);
|
|
267
|
+
}
|
|
268
|
+
function schemaForObject(value) {
|
|
269
|
+
const keys = Object.keys(value);
|
|
270
|
+
if (keys.length === 0) return Type.Record(Type.String(), Type.Unknown());
|
|
271
|
+
const properties = Object.fromEntries(keys.map((key) => [key, schemaForValue(value[key])]));
|
|
272
|
+
return Type.Partial(Type.Object(properties), { additionalProperties: false });
|
|
273
|
+
}
|
|
274
|
+
function mergeDefaultObject(defaults, payload) {
|
|
275
|
+
const result = {};
|
|
276
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
277
|
+
const defaultValue = defaults[key];
|
|
278
|
+
result[key] = defaultValue !== void 0 && isJsonObject(defaultValue) && isJsonObject(value) ? mergeDefaultObject(defaultValue, value) : cloneJsonValue(value);
|
|
279
|
+
}
|
|
280
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
281
|
+
if (!Object.prototype.hasOwnProperty.call(payload, key)) {
|
|
282
|
+
result[key] = cloneJsonValue(value);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
function cloneJsonValue(value) {
|
|
288
|
+
if (Array.isArray(value)) return value.map(cloneJsonValue);
|
|
289
|
+
if (isJsonObject(value)) {
|
|
290
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, cloneJsonValue(item)]));
|
|
291
|
+
}
|
|
292
|
+
return value;
|
|
293
|
+
}
|
|
294
|
+
function isJsonObject(value) {
|
|
295
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/harness/tools/route-tool.ts
|
|
165
299
|
var PhaseRouteTool = "route";
|
|
166
300
|
function buildPhaseEntry(p) {
|
|
167
301
|
const entry = { name: p.name, description: p.description };
|
|
168
302
|
if (p.tools && p.tools.length > 0) {
|
|
169
303
|
entry.available_tools = p.tools.join(", ");
|
|
170
304
|
}
|
|
171
|
-
if (p.input
|
|
172
|
-
entry.
|
|
305
|
+
if (p.input !== void 0) {
|
|
306
|
+
entry.payload_schema = JSON.stringify(phaseInputSchema(p.input));
|
|
307
|
+
} else {
|
|
308
|
+
entry.payload_schema = "any JSON-safe value";
|
|
173
309
|
}
|
|
174
310
|
return entry;
|
|
175
311
|
}
|
|
@@ -203,14 +339,20 @@ function buildRouteDescription(availablePhases) {
|
|
|
203
339
|
}
|
|
204
340
|
function createRouteTool(availablePhases) {
|
|
205
341
|
const routablePhases = availablePhases.filter(({ name }) => name !== "stop");
|
|
206
|
-
const
|
|
207
|
-
phase
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
342
|
+
const decisionTargets = [
|
|
343
|
+
...routablePhases.map((phase) => Type2.Object({
|
|
344
|
+
phase: Type2.Literal(phase.name),
|
|
345
|
+
reason: Type2.Optional(Type2.String({ description: "Brief reason for this decision" })),
|
|
346
|
+
payload: Type2.Optional(
|
|
347
|
+
phase.input === void 0 ? Type2.Unknown({ description: "Any JSON-safe value for the target phase" }) : phaseInputSchema(phase.input)
|
|
348
|
+
)
|
|
349
|
+
})),
|
|
350
|
+
Type2.Object({
|
|
351
|
+
phase: Type2.Literal("stop"),
|
|
352
|
+
reason: Type2.Optional(Type2.String({ description: "Brief reason for this decision" })),
|
|
353
|
+
payload: Type2.Optional(Type2.Unknown({ description: "Optional stop payload" }))
|
|
354
|
+
})
|
|
355
|
+
];
|
|
214
356
|
return {
|
|
215
357
|
name: PhaseRouteTool,
|
|
216
358
|
description: buildRouteDescription(availablePhases),
|
|
@@ -219,9 +361,9 @@ function createRouteTool(availablePhases) {
|
|
|
219
361
|
"Do not call route together with ordinary tools.",
|
|
220
362
|
"Use route(stop) only when the current user request or task is complete; the Stop Phase will provide the final user-facing conclusion."
|
|
221
363
|
],
|
|
222
|
-
parameters:
|
|
223
|
-
decision:
|
|
224
|
-
instruction:
|
|
364
|
+
parameters: Type2.Object({
|
|
365
|
+
decision: Type2.Array(Type2.Union(decisionTargets), { description: "Phase executions to start", minItems: 1 }),
|
|
366
|
+
instruction: Type2.Optional(Type2.String({ description: "Overall instruction, passed as context" }))
|
|
225
367
|
}),
|
|
226
368
|
// No-op: this tool is intercepted by phases, never executed via tool execution
|
|
227
369
|
execute: async (_, context) => ({
|
|
@@ -274,37 +416,37 @@ var DEFAULT_MAX_READ_BYTES = 50 * 1024;
|
|
|
274
416
|
var DEFAULT_MAX_READ_LINES = 2e3;
|
|
275
417
|
var DEFAULT_BASH_TIMEOUT_MS = 3e4;
|
|
276
418
|
var DEFAULT_MAX_BASH_OUTPUT_BYTES = 64e3;
|
|
277
|
-
var ReadArgsSchema =
|
|
278
|
-
path:
|
|
279
|
-
offset:
|
|
280
|
-
limit:
|
|
419
|
+
var ReadArgsSchema = Type3.Object({
|
|
420
|
+
path: Type3.String({ description: "Path to the file to read." }),
|
|
421
|
+
offset: Type3.Optional(Type3.Number({ description: "1-based line to start from." })),
|
|
422
|
+
limit: Type3.Optional(Type3.Number({ description: "Maximum number of lines." }))
|
|
281
423
|
});
|
|
282
|
-
var ReadArgsValidator =
|
|
283
|
-
var WriteArgsSchema =
|
|
284
|
-
path:
|
|
285
|
-
content:
|
|
424
|
+
var ReadArgsValidator = Schema2.Compile(ReadArgsSchema);
|
|
425
|
+
var WriteArgsSchema = Type3.Object({
|
|
426
|
+
path: Type3.String({ description: "Path to the file to write." }),
|
|
427
|
+
content: Type3.String({ description: "Complete file contents." })
|
|
286
428
|
});
|
|
287
|
-
var WriteArgsValidator =
|
|
288
|
-
var EditArgsSchema =
|
|
289
|
-
path:
|
|
290
|
-
edits:
|
|
291
|
-
oldText:
|
|
292
|
-
newText:
|
|
429
|
+
var WriteArgsValidator = Schema2.Compile(WriteArgsSchema);
|
|
430
|
+
var EditArgsSchema = Type3.Object({
|
|
431
|
+
path: Type3.String({ description: "Path to the file to edit." }),
|
|
432
|
+
edits: Type3.Array(Type3.Object({
|
|
433
|
+
oldText: Type3.String({ description: "Exact unique text to replace." }),
|
|
434
|
+
newText: Type3.String({ description: "Replacement text." })
|
|
293
435
|
}), { description: "One or more non-overlapping replacements." })
|
|
294
436
|
});
|
|
295
|
-
var EditArgsValidator =
|
|
296
|
-
var BashArgsSchema =
|
|
297
|
-
command:
|
|
298
|
-
timeout:
|
|
437
|
+
var EditArgsValidator = Schema2.Compile(EditArgsSchema);
|
|
438
|
+
var BashArgsSchema = Type3.Object({
|
|
439
|
+
command: Type3.String({ description: "Bash command to execute." }),
|
|
440
|
+
timeout: Type3.Optional(Type3.Number({ description: "Timeout in seconds." }))
|
|
299
441
|
});
|
|
300
|
-
var BashArgsValidator =
|
|
442
|
+
var BashArgsValidator = Schema2.Compile(BashArgsSchema);
|
|
301
443
|
var validatorCache = /* @__PURE__ */ new WeakMap();
|
|
302
444
|
function validatorFor(schema) {
|
|
303
445
|
const cached = validatorCache.get(schema);
|
|
304
446
|
if (cached) {
|
|
305
447
|
return cached;
|
|
306
448
|
}
|
|
307
|
-
const validator =
|
|
449
|
+
const validator = Schema2.Compile(schema);
|
|
308
450
|
validatorCache.set(schema, validator);
|
|
309
451
|
return validator;
|
|
310
452
|
}
|
|
@@ -1134,62 +1276,6 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1134
1276
|
};
|
|
1135
1277
|
}
|
|
1136
1278
|
|
|
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
1279
|
// src/harness/phases/interactions.ts
|
|
1194
1280
|
var PhaseInteractionCancelledError = class extends Error {
|
|
1195
1281
|
code = "phase_interaction_cancelled";
|
|
@@ -1621,13 +1707,21 @@ async function loadPhase(targetPath) {
|
|
|
1621
1707
|
warnResourceDiagnostics("phase", resolved, diagnostics);
|
|
1622
1708
|
const baseDir = dirname4(resolved);
|
|
1623
1709
|
const skills = await loadPhaseSkills(baseDir);
|
|
1710
|
+
let input;
|
|
1711
|
+
try {
|
|
1712
|
+
input = parsePhaseInput(metadata.input);
|
|
1713
|
+
} catch (error) {
|
|
1714
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1715
|
+
warnResourceDiagnostics("phase", resolved, [message]);
|
|
1716
|
+
throw new ResourceMetadataError("invalid_metadata", message);
|
|
1717
|
+
}
|
|
1624
1718
|
const phase = {
|
|
1625
1719
|
name,
|
|
1626
1720
|
description: description.description,
|
|
1627
1721
|
tools: definition.tools ? [...definition.tools] : void 0,
|
|
1628
1722
|
skills,
|
|
1629
1723
|
target: metadata.target,
|
|
1630
|
-
input:
|
|
1724
|
+
...input === void 0 ? {} : { input },
|
|
1631
1725
|
isolated: metadata.isolated,
|
|
1632
1726
|
filePath: resolved,
|
|
1633
1727
|
baseDir,
|
|
@@ -2191,9 +2285,21 @@ function resolveRouteDecision(route, registry) {
|
|
|
2191
2285
|
if (requestedCount !== 1) return void 0;
|
|
2192
2286
|
return { ...route, requestedCount };
|
|
2193
2287
|
}
|
|
2194
|
-
const decision = route.decision.
|
|
2288
|
+
const decision = route.decision.flatMap((candidate) => {
|
|
2289
|
+
const target = registry.phases.get(candidate.phase);
|
|
2290
|
+
if (!target) return [];
|
|
2291
|
+
try {
|
|
2292
|
+
const payload = preparePhasePayload(target.input, normalizePayload(candidate.payload));
|
|
2293
|
+
return [{
|
|
2294
|
+
...candidate,
|
|
2295
|
+
...payload === void 0 ? {} : { payload }
|
|
2296
|
+
}];
|
|
2297
|
+
} catch {
|
|
2298
|
+
return [];
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2195
2301
|
if (decision.length === 0) return void 0;
|
|
2196
|
-
return { ...route, decision, requestedCount };
|
|
2302
|
+
return { ...route, decision, requestedCount: decision.length };
|
|
2197
2303
|
}
|
|
2198
2304
|
function resolveModelRouteDecision(toolCalls, registry) {
|
|
2199
2305
|
return resolveRouteDecision(toolCalls ? extractRouteCall(toolCalls) : void 0, registry);
|
|
@@ -2428,7 +2534,8 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2428
2534
|
if (resumingSuspendedRun) {
|
|
2429
2535
|
state.status = "running";
|
|
2430
2536
|
}
|
|
2431
|
-
|
|
2537
|
+
const initialPayload = !resumingSuspendedRun ? config.execution.runMetadata?.phasePayload : void 0;
|
|
2538
|
+
let previousPayload = resumingSuspendedRun ? state.continuation?.previousPayload : initialPayload;
|
|
2432
2539
|
let previousPhaseMsgId = resumingSuspendedRun ? state.continuation?.previousPhaseMessageId : void 0;
|
|
2433
2540
|
let previousPhaseInputMsgId;
|
|
2434
2541
|
let previousResults = resumingSuspendedRun ? state.continuation?.previousResults?.map((result) => ({ ...result })) ?? [] : [];
|
|
@@ -2519,6 +2626,9 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2519
2626
|
if (!phase) {
|
|
2520
2627
|
throw new Error(`Phase "${currentPhaseId}" not found`);
|
|
2521
2628
|
}
|
|
2629
|
+
if (previousPayload !== void 0 || phase.input !== void 0) {
|
|
2630
|
+
previousPayload = preparePhasePayload(phase.input, previousPayload);
|
|
2631
|
+
}
|
|
2522
2632
|
state.currentPhase = currentPhaseId;
|
|
2523
2633
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
2524
2634
|
const messageManager = createMessageManager(config.context, config.onMessage, config.onMessageDelta);
|
|
@@ -2584,7 +2694,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2584
2694
|
const lastMessageBeforePhase = config.context.messages.at(-1);
|
|
2585
2695
|
previousPhaseMsgId = injectPhaseContent(
|
|
2586
2696
|
phase,
|
|
2587
|
-
{ results: previousResults, instruction: pendingInstruction },
|
|
2697
|
+
{ results: previousResults, instruction: pendingInstruction, payload: previousPayload },
|
|
2588
2698
|
config.context.messages,
|
|
2589
2699
|
phaseContext.messages
|
|
2590
2700
|
);
|
|
@@ -2630,6 +2740,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2630
2740
|
output = extAfter.output;
|
|
2631
2741
|
if (hookHasRoute) {
|
|
2632
2742
|
routeDecision = resolveHookRouteDecision(output, registry);
|
|
2743
|
+
if (routeDecision) applyFirstDecision(routeDecision, output);
|
|
2633
2744
|
} else if (phase.run || phase.factory) {
|
|
2634
2745
|
output = { ...output, route: "stop" };
|
|
2635
2746
|
routeDecision = void 0;
|
|
@@ -2736,7 +2847,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2736
2847
|
}
|
|
2737
2848
|
currentPhaseId = STOP_PHASE_ID;
|
|
2738
2849
|
previousPayload = output.payload;
|
|
2739
|
-
previousResults =
|
|
2850
|
+
previousResults = [];
|
|
2740
2851
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2741
2852
|
continue;
|
|
2742
2853
|
}
|
|
@@ -2753,8 +2864,10 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2753
2864
|
to: targetPhaseId,
|
|
2754
2865
|
ts: createTimestamp()
|
|
2755
2866
|
});
|
|
2756
|
-
|
|
2757
|
-
|
|
2867
|
+
const targetPhase = registry.phases.get(targetPhaseId);
|
|
2868
|
+
const targetPayload = !phase.target && routeDecision ? routeDecision.decision[0]?.payload : output.payload;
|
|
2869
|
+
previousPayload = preparePhasePayload(targetPhase?.input, targetPayload);
|
|
2870
|
+
previousResults = [];
|
|
2758
2871
|
pendingInstruction = phase.target ? void 0 : routeDecision?.instruction;
|
|
2759
2872
|
currentPhaseId = targetPhaseId;
|
|
2760
2873
|
}
|
|
@@ -3023,6 +3136,7 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3023
3136
|
}
|
|
3024
3137
|
async function executeParallelPhase(config, state, registry, phase, payload, instruction, context, availablePhases, instanceId, groupId, index, count, sourcePhaseId) {
|
|
3025
3138
|
const messages = [...context];
|
|
3139
|
+
const effectivePayload = preparePhasePayload(phase.input, payload);
|
|
3026
3140
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
3027
3141
|
const phaseTools = selectPhaseTools(allTools, phase.tools, false);
|
|
3028
3142
|
const phaseSkills = mergeSkills(config.context.skills, phase.skills);
|
|
@@ -3045,7 +3159,7 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3045
3159
|
current: phase.name,
|
|
3046
3160
|
available: Array.from(registry.phases.keys()),
|
|
3047
3161
|
iterations: 0,
|
|
3048
|
-
payload
|
|
3162
|
+
payload: effectivePayload
|
|
3049
3163
|
}
|
|
3050
3164
|
};
|
|
3051
3165
|
const messageManager = createMessageManager({ messages }, config.onMessage, config.onMessageDelta);
|
|
@@ -3053,7 +3167,8 @@ async function executeParallelPhase(config, state, registry, phase, payload, ins
|
|
|
3053
3167
|
phase,
|
|
3054
3168
|
{
|
|
3055
3169
|
instruction,
|
|
3056
|
-
|
|
3170
|
+
payload: effectivePayload,
|
|
3171
|
+
results: []
|
|
3057
3172
|
},
|
|
3058
3173
|
messages
|
|
3059
3174
|
);
|
|
@@ -3308,7 +3423,6 @@ function isContinuation(value) {
|
|
|
3308
3423
|
}
|
|
3309
3424
|
|
|
3310
3425
|
// src/runtime/contracts.ts
|
|
3311
|
-
var HOST_CONTEXT_MESSAGE_KIND = "host_context";
|
|
3312
3426
|
var THINKING_LEVELS = [
|
|
3313
3427
|
"off",
|
|
3314
3428
|
"minimal",
|
|
@@ -3331,7 +3445,7 @@ function thinkingLevelFromMessages(messages) {
|
|
|
3331
3445
|
if (message?.role !== "user") continue;
|
|
3332
3446
|
const metadata = message.metadata;
|
|
3333
3447
|
const kind = isRecord3(metadata) && typeof metadata.kind === "string" ? metadata.kind : void 0;
|
|
3334
|
-
if (kind === "phase_prompt" || kind === "phase_input"
|
|
3448
|
+
if (kind === "phase_prompt" || kind === "phase_input") continue;
|
|
3335
3449
|
return thinkingLevelFromMetadata(metadata);
|
|
3336
3450
|
}
|
|
3337
3451
|
return void 0;
|
|
@@ -3385,9 +3499,6 @@ function normalizeUserInput(input) {
|
|
|
3385
3499
|
assertJsonValue(normalized, "input");
|
|
3386
3500
|
return normalized;
|
|
3387
3501
|
}
|
|
3388
|
-
function canonicalUserInput(input) {
|
|
3389
|
-
return canonicalJson(normalizeUserInput(input));
|
|
3390
|
-
}
|
|
3391
3502
|
function isAssistantMessage(value) {
|
|
3392
3503
|
return isRecord3(value) && hasOnlyKeys(value, ["id", "agentId", "runId", "messageRevision", "role", "content", "metadata", "sequenceWithinRun", "createdAt", "interrupted"]) && typeof value.id === "string" && typeof value.agentId === "string" && typeof value.runId === "string" && value.role === "assistant" && (value.messageRevision === void 0 || Number.isInteger(value.messageRevision) && value.messageRevision >= 0) && Number.isInteger(value.sequenceWithinRun) && value.sequenceWithinRun >= 0 && typeof value.createdAt === "string" && isAssistantContent(value.content) && (value.metadata === void 0 || isMetadata(value.metadata)) && (value.interrupted === void 0 || typeof value.interrupted === "boolean");
|
|
3393
3504
|
}
|
|
@@ -4068,11 +4179,14 @@ function resolveDefinitionContext(config, assembled = {}) {
|
|
|
4068
4179
|
selectNamedResources(config.resources.skills, config.definition.skills, "Skill"),
|
|
4069
4180
|
config.definition.bundledSkills
|
|
4070
4181
|
);
|
|
4071
|
-
const contexts =
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4182
|
+
const contexts = [
|
|
4183
|
+
...selectNamedResources(
|
|
4184
|
+
config.resources.contexts ?? [],
|
|
4185
|
+
config.definition.contexts,
|
|
4186
|
+
"Context"
|
|
4187
|
+
),
|
|
4188
|
+
...config.additionalContexts ?? []
|
|
4189
|
+
];
|
|
4076
4190
|
const candidateRegistry = assembled.phases ?? config.resources.phases;
|
|
4077
4191
|
const phaseCandidates = [...candidateRegistry?.phases.values() ?? []];
|
|
4078
4192
|
const coreNames = /* @__PURE__ */ new Set([DEFAULT_PHASE_ID, STOP_PHASE_ID, COMPACT_PHASE_ID]);
|
|
@@ -5891,6 +6005,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5891
6005
|
kind: "phase",
|
|
5892
6006
|
name: phase.name,
|
|
5893
6007
|
description: phase.description,
|
|
6008
|
+
...phase.input === void 0 ? {} : { input: phase.input },
|
|
5894
6009
|
...phase.core ? { core: true } : {},
|
|
5895
6010
|
disableAutoInvocation: phase.disableAutoInvocation ?? false,
|
|
5896
6011
|
disableImplicitInvocation: phase.disableImplicitInvocation ?? false,
|
|
@@ -6082,8 +6197,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6082
6197
|
runId: run.id,
|
|
6083
6198
|
expectedRevision: run.revision,
|
|
6084
6199
|
executionId,
|
|
6085
|
-
configToken: token
|
|
6086
|
-
...controlKind ? {} : { inputContext: additionalContextInput(config) }
|
|
6200
|
+
configToken: token
|
|
6087
6201
|
});
|
|
6088
6202
|
executionRevision = claim.run.revision;
|
|
6089
6203
|
const controller = new AbortController();
|
|
@@ -6553,12 +6667,6 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6553
6667
|
this.heartbeat.unref?.();
|
|
6554
6668
|
}
|
|
6555
6669
|
};
|
|
6556
|
-
function additionalContextInput(config) {
|
|
6557
|
-
const contexts = config.additionalContexts ?? [];
|
|
6558
|
-
if (contexts.length === 0) return void 0;
|
|
6559
|
-
const content = buildAdditionalContextMessage(contexts);
|
|
6560
|
-
return content.length === 0 ? void 0 : { content, metadata: { kind: HOST_CONTEXT_MESSAGE_KIND } };
|
|
6561
|
-
}
|
|
6562
6670
|
var DurableRun = class {
|
|
6563
6671
|
constructor(runtime, id) {
|
|
6564
6672
|
this.runtime = runtime;
|
|
@@ -7107,13 +7215,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7107
7215
|
this.assertOwner(lease);
|
|
7108
7216
|
const executionId = input.executionId ?? createId("exec");
|
|
7109
7217
|
const operationKey = `claim:${executionId}`;
|
|
7110
|
-
const inputContext = input.inputContext === void 0 ? void 0 : normalizeUserInput(input.inputContext);
|
|
7111
7218
|
const operationPayload = canonicalJson([
|
|
7112
7219
|
input.runId,
|
|
7113
7220
|
input.expectedRevision,
|
|
7114
7221
|
input.messageId ?? null,
|
|
7115
|
-
input.configToken ?? null
|
|
7116
|
-
inputContext ?? null
|
|
7222
|
+
input.configToken ?? null
|
|
7117
7223
|
]);
|
|
7118
7224
|
const replay = this.replayOperation(operationKey, operationPayload);
|
|
7119
7225
|
if (replay) return clone(replay);
|
|
@@ -7131,21 +7237,6 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7131
7237
|
}
|
|
7132
7238
|
if (!run.pinnedConfigToken && input.configToken) run.pinnedConfigToken = input.configToken;
|
|
7133
7239
|
const committedMessages = [];
|
|
7134
|
-
const existingMessages = this.messagesForRun(run.id);
|
|
7135
|
-
if (inputContext && hasUserInput(inputContext) && !isControlRun(run) && !existingMessages.some((message) => message.role === "user" && message.metadata?.kind === HOST_CONTEXT_MESSAGE_KIND && canonicalUserInput({ content: message.content, metadata: message.metadata }) === canonicalUserInput(inputContext))) {
|
|
7136
|
-
const contextMessage = {
|
|
7137
|
-
id: createId("msg"),
|
|
7138
|
-
agentId: run.agentId,
|
|
7139
|
-
runId: run.id,
|
|
7140
|
-
role: "user",
|
|
7141
|
-
content: userInputContent(inputContext),
|
|
7142
|
-
...userInputMetadata(inputContext) ? { metadata: clone(userInputMetadata(inputContext)) } : {},
|
|
7143
|
-
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
7144
|
-
createdAt: createTimestamp()
|
|
7145
|
-
};
|
|
7146
|
-
this.messages.set(contextMessage.id, contextMessage);
|
|
7147
|
-
committedMessages.push(contextMessage);
|
|
7148
|
-
}
|
|
7149
7240
|
if (!run.checkpoint && !run.initialMessageId && (!isControlRun(run) || hasUserInput(run.input))) {
|
|
7150
7241
|
const userInput = normalizeUserInput(run.input);
|
|
7151
7242
|
const message = {
|