@rowan-agent/agent 0.9.11 → 0.9.12
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 +159 -153
- package/dist/index.js +79 -20
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -55,6 +55,159 @@ type ToolResult = {
|
|
|
55
55
|
error?: string;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
interface BeforePhaseEvent {
|
|
59
|
+
type: "before_phase";
|
|
60
|
+
phaseId: string;
|
|
61
|
+
input: PhaseContext;
|
|
62
|
+
}
|
|
63
|
+
interface AfterPhaseEvent {
|
|
64
|
+
type: "after_phase";
|
|
65
|
+
phaseId: string;
|
|
66
|
+
output: PhaseOutput;
|
|
67
|
+
}
|
|
68
|
+
interface BeforePromptEvent {
|
|
69
|
+
type: "before_prompt";
|
|
70
|
+
phaseId: string;
|
|
71
|
+
input: PhaseContext;
|
|
72
|
+
}
|
|
73
|
+
interface BeforeToolCallEvent {
|
|
74
|
+
type: "before_tool_call";
|
|
75
|
+
tool: Tool$1;
|
|
76
|
+
args: unknown;
|
|
77
|
+
}
|
|
78
|
+
interface AfterToolCallEvent {
|
|
79
|
+
type: "after_tool_call";
|
|
80
|
+
tool: Tool$1;
|
|
81
|
+
result: ToolResult;
|
|
82
|
+
}
|
|
83
|
+
type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
|
|
84
|
+
interface BeforePhaseResult {
|
|
85
|
+
abort?: Outcome$1;
|
|
86
|
+
skip?: {
|
|
87
|
+
route: string;
|
|
88
|
+
message: string;
|
|
89
|
+
};
|
|
90
|
+
input?: PhaseContext;
|
|
91
|
+
}
|
|
92
|
+
interface AfterPhaseResult {
|
|
93
|
+
abort?: Outcome$1;
|
|
94
|
+
retry?: PhaseContext;
|
|
95
|
+
output?: PhaseOutput;
|
|
96
|
+
}
|
|
97
|
+
interface BeforePromptResult {
|
|
98
|
+
input?: PhaseContext;
|
|
99
|
+
}
|
|
100
|
+
interface BeforeToolCallResult {
|
|
101
|
+
allow: boolean;
|
|
102
|
+
reason?: string;
|
|
103
|
+
}
|
|
104
|
+
interface AfterToolCallResult {
|
|
105
|
+
result?: ToolResult;
|
|
106
|
+
}
|
|
107
|
+
interface HookResultMap {
|
|
108
|
+
before_phase: BeforePhaseResult | undefined;
|
|
109
|
+
after_phase: AfterPhaseResult | undefined;
|
|
110
|
+
before_prompt: BeforePromptResult | undefined;
|
|
111
|
+
before_tool_call: BeforeToolCallResult | undefined;
|
|
112
|
+
after_tool_call: AfterToolCallResult | undefined;
|
|
113
|
+
}
|
|
114
|
+
type HookEventType = HookEvent["type"];
|
|
115
|
+
type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
|
|
116
|
+
type: K;
|
|
117
|
+
}>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
|
|
118
|
+
declare class HooksManager {
|
|
119
|
+
private handlers;
|
|
120
|
+
on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
121
|
+
off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
122
|
+
emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
123
|
+
type: K;
|
|
124
|
+
}>): Promise<void>;
|
|
125
|
+
emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
126
|
+
type: K;
|
|
127
|
+
}>): Promise<HookResultMap[K] | undefined>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type LoopMetrics = {
|
|
131
|
+
/** Number of phase iterations executed. */
|
|
132
|
+
iterations: number;
|
|
133
|
+
/** Phase transition history. */
|
|
134
|
+
phaseTransitions: Array<{
|
|
135
|
+
from: string;
|
|
136
|
+
to: string;
|
|
137
|
+
ts: string;
|
|
138
|
+
}>;
|
|
139
|
+
/** Number of times compaction was triggered. */
|
|
140
|
+
compactionCount: number;
|
|
141
|
+
/** Number of retry attempts due to transient errors. */
|
|
142
|
+
retryCount: number;
|
|
143
|
+
/** Loop start timestamp. */
|
|
144
|
+
startedAt: string;
|
|
145
|
+
/** Loop start time as epoch ms (for duration calculation). */
|
|
146
|
+
startedAtMs: number;
|
|
147
|
+
/** Loop end timestamp (set on completion). */
|
|
148
|
+
endedAt?: string;
|
|
149
|
+
/** Total wall-clock duration in ms. */
|
|
150
|
+
durationMs?: number;
|
|
151
|
+
};
|
|
152
|
+
type ExecutionState = {
|
|
153
|
+
currentPhase: string;
|
|
154
|
+
attempt: number;
|
|
155
|
+
metrics: LoopMetrics;
|
|
156
|
+
status: "idle" | "running" | "suspended" | "completed" | "aborted" | "failed";
|
|
157
|
+
continuation?: ExecutionContinuationState;
|
|
158
|
+
phaseInteractions?: PhaseInteractionState;
|
|
159
|
+
};
|
|
160
|
+
type ExecutionContinuationState = {
|
|
161
|
+
isContinuing: boolean;
|
|
162
|
+
previousPayload?: unknown;
|
|
163
|
+
previousResults: Array<{
|
|
164
|
+
name: string;
|
|
165
|
+
output?: unknown;
|
|
166
|
+
}>;
|
|
167
|
+
pendingInstruction?: string;
|
|
168
|
+
previousPhaseMessageId?: string;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
type PhaseInteractionKind = "user_input" | "permission" | "elicitation" | "confirmation";
|
|
172
|
+
type PhaseInteractionStatus = "pending" | "answered" | "denied" | "cancelled" | "expired";
|
|
173
|
+
type PhaseInteraction = Readonly<{
|
|
174
|
+
id: string;
|
|
175
|
+
phase: string;
|
|
176
|
+
kind: PhaseInteractionKind;
|
|
177
|
+
prompt: string;
|
|
178
|
+
payload?: JsonValue;
|
|
179
|
+
createdAt: string;
|
|
180
|
+
status: PhaseInteractionStatus;
|
|
181
|
+
}>;
|
|
182
|
+
type PhaseInteractionState = Readonly<{
|
|
183
|
+
requests: readonly PhaseInteraction[];
|
|
184
|
+
answers: Readonly<Record<string, JsonValue>>;
|
|
185
|
+
checkpoint?: JsonValue;
|
|
186
|
+
}>;
|
|
187
|
+
type PhaseInteractionDriver = Readonly<{
|
|
188
|
+
signal: AbortSignal;
|
|
189
|
+
request(input: Readonly<{
|
|
190
|
+
id?: string;
|
|
191
|
+
kind: PhaseInteractionKind;
|
|
192
|
+
prompt: string;
|
|
193
|
+
payload?: JsonValue;
|
|
194
|
+
}>): PhaseInteraction;
|
|
195
|
+
pending(): readonly PhaseInteraction[];
|
|
196
|
+
answers(): ReadonlyMap<string, JsonValue>;
|
|
197
|
+
suspend(input?: Readonly<{
|
|
198
|
+
checkpoint?: JsonValue;
|
|
199
|
+
}>): never;
|
|
200
|
+
}>;
|
|
201
|
+
declare class PhaseInteractionCancelledError extends Error {
|
|
202
|
+
readonly code: "phase_interaction_cancelled";
|
|
203
|
+
constructor();
|
|
204
|
+
}
|
|
205
|
+
declare class PhaseInteractionBoundary extends Error {
|
|
206
|
+
readonly state: ExecutionState;
|
|
207
|
+
readonly interactions: readonly PhaseInteraction[];
|
|
208
|
+
constructor(state: ExecutionState, interactions: readonly PhaseInteraction[]);
|
|
209
|
+
}
|
|
210
|
+
|
|
58
211
|
/** Durable and transient DTOs owned by the event-driven Agent Runtime. */
|
|
59
212
|
|
|
60
213
|
declare const opaqueIdBrand: unique symbol;
|
|
@@ -387,159 +540,6 @@ type PhaseStatusEvent = Readonly<{
|
|
|
387
540
|
}>;
|
|
388
541
|
type RunEvent = DurableRunEvent | MessageDelta | ThinkingDelta | ToolProgress | PhaseStatusEvent;
|
|
389
542
|
|
|
390
|
-
interface BeforePhaseEvent {
|
|
391
|
-
type: "before_phase";
|
|
392
|
-
phaseId: string;
|
|
393
|
-
input: PhaseContext;
|
|
394
|
-
}
|
|
395
|
-
interface AfterPhaseEvent {
|
|
396
|
-
type: "after_phase";
|
|
397
|
-
phaseId: string;
|
|
398
|
-
output: PhaseOutput;
|
|
399
|
-
}
|
|
400
|
-
interface BeforePromptEvent {
|
|
401
|
-
type: "before_prompt";
|
|
402
|
-
phaseId: string;
|
|
403
|
-
input: PhaseContext;
|
|
404
|
-
}
|
|
405
|
-
interface BeforeToolCallEvent {
|
|
406
|
-
type: "before_tool_call";
|
|
407
|
-
tool: Tool$1;
|
|
408
|
-
args: unknown;
|
|
409
|
-
}
|
|
410
|
-
interface AfterToolCallEvent {
|
|
411
|
-
type: "after_tool_call";
|
|
412
|
-
tool: Tool$1;
|
|
413
|
-
result: ToolResult;
|
|
414
|
-
}
|
|
415
|
-
type HookEvent = BeforePhaseEvent | AfterPhaseEvent | BeforePromptEvent | BeforeToolCallEvent | AfterToolCallEvent;
|
|
416
|
-
interface BeforePhaseResult {
|
|
417
|
-
abort?: Outcome$1;
|
|
418
|
-
skip?: {
|
|
419
|
-
route: string;
|
|
420
|
-
message: string;
|
|
421
|
-
};
|
|
422
|
-
input?: PhaseContext;
|
|
423
|
-
}
|
|
424
|
-
interface AfterPhaseResult {
|
|
425
|
-
abort?: Outcome$1;
|
|
426
|
-
retry?: PhaseContext;
|
|
427
|
-
output?: PhaseOutput;
|
|
428
|
-
}
|
|
429
|
-
interface BeforePromptResult {
|
|
430
|
-
input?: PhaseContext;
|
|
431
|
-
}
|
|
432
|
-
interface BeforeToolCallResult {
|
|
433
|
-
allow: boolean;
|
|
434
|
-
reason?: string;
|
|
435
|
-
}
|
|
436
|
-
interface AfterToolCallResult {
|
|
437
|
-
result?: ToolResult;
|
|
438
|
-
}
|
|
439
|
-
interface HookResultMap {
|
|
440
|
-
before_phase: BeforePhaseResult | undefined;
|
|
441
|
-
after_phase: AfterPhaseResult | undefined;
|
|
442
|
-
before_prompt: BeforePromptResult | undefined;
|
|
443
|
-
before_tool_call: BeforeToolCallResult | undefined;
|
|
444
|
-
after_tool_call: AfterToolCallResult | undefined;
|
|
445
|
-
}
|
|
446
|
-
type HookEventType = HookEvent["type"];
|
|
447
|
-
type HookHandler<K extends HookEventType> = (event: Extract<HookEvent, {
|
|
448
|
-
type: K;
|
|
449
|
-
}>) => HookResultMap[K] | Promise<HookResultMap[K]> | void | Promise<void>;
|
|
450
|
-
declare class HooksManager {
|
|
451
|
-
private handlers;
|
|
452
|
-
on<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
453
|
-
off<K extends HookEventType>(eventType: K, handler: HookHandler<K>): void;
|
|
454
|
-
emit<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
455
|
-
type: K;
|
|
456
|
-
}>): Promise<void>;
|
|
457
|
-
emitFirst<K extends HookEventType>(eventType: K, event: Extract<HookEvent, {
|
|
458
|
-
type: K;
|
|
459
|
-
}>): Promise<HookResultMap[K] | undefined>;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
type LoopMetrics = {
|
|
463
|
-
/** Number of phase iterations executed. */
|
|
464
|
-
iterations: number;
|
|
465
|
-
/** Phase transition history. */
|
|
466
|
-
phaseTransitions: Array<{
|
|
467
|
-
from: string;
|
|
468
|
-
to: string;
|
|
469
|
-
ts: string;
|
|
470
|
-
}>;
|
|
471
|
-
/** Number of times compaction was triggered. */
|
|
472
|
-
compactionCount: number;
|
|
473
|
-
/** Number of retry attempts due to transient errors. */
|
|
474
|
-
retryCount: number;
|
|
475
|
-
/** Loop start timestamp. */
|
|
476
|
-
startedAt: string;
|
|
477
|
-
/** Loop start time as epoch ms (for duration calculation). */
|
|
478
|
-
startedAtMs: number;
|
|
479
|
-
/** Loop end timestamp (set on completion). */
|
|
480
|
-
endedAt?: string;
|
|
481
|
-
/** Total wall-clock duration in ms. */
|
|
482
|
-
durationMs?: number;
|
|
483
|
-
};
|
|
484
|
-
type ExecutionState = {
|
|
485
|
-
currentPhase: string;
|
|
486
|
-
attempt: number;
|
|
487
|
-
metrics: LoopMetrics;
|
|
488
|
-
status: "idle" | "running" | "suspended" | "completed" | "aborted" | "failed";
|
|
489
|
-
continuation?: ExecutionContinuationState;
|
|
490
|
-
phaseInteractions?: PhaseInteractionState;
|
|
491
|
-
};
|
|
492
|
-
type ExecutionContinuationState = {
|
|
493
|
-
isContinuing: boolean;
|
|
494
|
-
previousPayload?: unknown;
|
|
495
|
-
previousResults: Array<{
|
|
496
|
-
name: string;
|
|
497
|
-
output?: unknown;
|
|
498
|
-
}>;
|
|
499
|
-
pendingInstruction?: string;
|
|
500
|
-
previousPhaseMessageId?: string;
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
type PhaseInteractionKind = "user_input" | "permission" | "elicitation" | "confirmation";
|
|
504
|
-
type PhaseInteractionStatus = "pending" | "answered" | "denied" | "cancelled" | "expired";
|
|
505
|
-
type PhaseInteraction = Readonly<{
|
|
506
|
-
id: string;
|
|
507
|
-
phase: string;
|
|
508
|
-
kind: PhaseInteractionKind;
|
|
509
|
-
prompt: string;
|
|
510
|
-
payload?: JsonValue;
|
|
511
|
-
createdAt: string;
|
|
512
|
-
status: PhaseInteractionStatus;
|
|
513
|
-
}>;
|
|
514
|
-
type PhaseInteractionState = Readonly<{
|
|
515
|
-
requests: readonly PhaseInteraction[];
|
|
516
|
-
answers: Readonly<Record<string, JsonValue>>;
|
|
517
|
-
checkpoint?: JsonValue;
|
|
518
|
-
}>;
|
|
519
|
-
type PhaseInteractionDriver = Readonly<{
|
|
520
|
-
signal: AbortSignal;
|
|
521
|
-
request(input: Readonly<{
|
|
522
|
-
id?: string;
|
|
523
|
-
kind: PhaseInteractionKind;
|
|
524
|
-
prompt: string;
|
|
525
|
-
payload?: JsonValue;
|
|
526
|
-
}>): PhaseInteraction;
|
|
527
|
-
pending(): readonly PhaseInteraction[];
|
|
528
|
-
answers(): ReadonlyMap<string, JsonValue>;
|
|
529
|
-
suspend(input?: Readonly<{
|
|
530
|
-
checkpoint?: JsonValue;
|
|
531
|
-
}>): never;
|
|
532
|
-
}>;
|
|
533
|
-
declare class PhaseInteractionCancelledError extends Error {
|
|
534
|
-
readonly code: "phase_interaction_cancelled";
|
|
535
|
-
constructor();
|
|
536
|
-
}
|
|
537
|
-
declare class PhaseInteractionBoundary extends Error {
|
|
538
|
-
readonly state: ExecutionState;
|
|
539
|
-
readonly interactions: readonly PhaseInteraction[];
|
|
540
|
-
constructor(state: ExecutionState, interactions: readonly PhaseInteraction[]);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
543
|
type ModelInvokeOutput = {
|
|
544
544
|
text: string;
|
|
545
545
|
contentBlocks: ContentBlock[];
|
|
@@ -932,6 +932,8 @@ type PhaseExecutionIdentity = Readonly<{
|
|
|
932
932
|
agentId: string;
|
|
933
933
|
runId: string;
|
|
934
934
|
executionId: string;
|
|
935
|
+
/** Original durable Run input, before any Phase-local interpretation. */
|
|
936
|
+
input?: UserContent;
|
|
935
937
|
/** Opaque metadata captured at the durable boundary; Rowan does not decode it. */
|
|
936
938
|
agentMetadata?: Readonly<Record<string, unknown>>;
|
|
937
939
|
runMetadata?: Readonly<Record<string, unknown>>;
|
|
@@ -1378,6 +1380,8 @@ type AgentConfiguration = Readonly<{
|
|
|
1378
1380
|
}>;
|
|
1379
1381
|
resourceView: ResourceView;
|
|
1380
1382
|
contexts?: readonly ContextCandidate[];
|
|
1383
|
+
/** Trusted Host-owned Contexts appended after Definition selection. */
|
|
1384
|
+
additionalContexts?: readonly ContextCandidate[];
|
|
1381
1385
|
cwd?: string;
|
|
1382
1386
|
maxAttempts?: number;
|
|
1383
1387
|
model: ModelConfig | ModelRef;
|
|
@@ -1938,6 +1942,7 @@ interface AgentRuntime$1 {
|
|
|
1938
1942
|
contextWindow?: number;
|
|
1939
1943
|
}): Promise<ContextStatus>;
|
|
1940
1944
|
compactContext(agentId: AgentId, options?: {
|
|
1945
|
+
input?: UserInput;
|
|
1941
1946
|
instructions?: string;
|
|
1942
1947
|
idempotencyKey?: string;
|
|
1943
1948
|
}): Promise<AgentRun>;
|
|
@@ -2029,6 +2034,7 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
2029
2034
|
contextWindow?: number;
|
|
2030
2035
|
}): Promise<ContextStatus>;
|
|
2031
2036
|
compactContext(agentId: AgentId, options?: {
|
|
2037
|
+
input?: UserInput;
|
|
2032
2038
|
instructions?: string;
|
|
2033
2039
|
idempotencyKey?: string;
|
|
2034
2040
|
}): Promise<AgentRun>;
|
package/dist/index.js
CHANGED
|
@@ -1751,7 +1751,7 @@ async function loadPhaseCode(codePath) {
|
|
|
1751
1751
|
throw new Error(`Phase code at "${codePath}" must export a default function or a run() function.`);
|
|
1752
1752
|
}
|
|
1753
1753
|
|
|
1754
|
-
// src/harness/phases/
|
|
1754
|
+
// src/harness/phases/core-phases.ts
|
|
1755
1755
|
var DEFAULT_PHASE_ID = "default";
|
|
1756
1756
|
var STOP_PHASE_ID = "stop";
|
|
1757
1757
|
var COMPACT_PHASE_ID = "compact";
|
|
@@ -1809,6 +1809,14 @@ function createCompactPhase() {
|
|
|
1809
1809
|
});
|
|
1810
1810
|
const tools = context.tools.filter((tool) => tool.core && (tool.name === "read" || tool.name === "bash"));
|
|
1811
1811
|
const working = { ...context, tools, skills: [...context.skills], messages: [...context.messages] };
|
|
1812
|
+
const instructions = compactInstructions(context);
|
|
1813
|
+
if (instructions) {
|
|
1814
|
+
working.messages.push(createMessage("user", `Additional compaction instructions:
|
|
1815
|
+
${instructions}`, {
|
|
1816
|
+
kind: "phase_input",
|
|
1817
|
+
phase: COMPACT_PHASE_ID
|
|
1818
|
+
}));
|
|
1819
|
+
}
|
|
1812
1820
|
let result = await execution.invokeModel(working, { output: "internal" });
|
|
1813
1821
|
for (let attempt = 0; attempt < 8 && result.toolCalls.length > 0; attempt += 1) {
|
|
1814
1822
|
const calls = result.toolCalls.filter((call) => tools.some((tool) => tool.name === call.name));
|
|
@@ -1860,7 +1868,11 @@ function createCompactPhase() {
|
|
|
1860
1868
|
return {
|
|
1861
1869
|
route: "stop",
|
|
1862
1870
|
phase: COMPACT_PHASE_ID,
|
|
1863
|
-
payload: {
|
|
1871
|
+
payload: {
|
|
1872
|
+
kind: "context_compaction",
|
|
1873
|
+
summary: result.text,
|
|
1874
|
+
...instructions ? { instructions } : {}
|
|
1875
|
+
},
|
|
1864
1876
|
status: {
|
|
1865
1877
|
state: "completed",
|
|
1866
1878
|
kind: "compacted",
|
|
@@ -1870,6 +1882,21 @@ function createCompactPhase() {
|
|
|
1870
1882
|
}
|
|
1871
1883
|
};
|
|
1872
1884
|
}
|
|
1885
|
+
function compactInstructions(context) {
|
|
1886
|
+
const rowan = context.execution.runMetadata?.rowan;
|
|
1887
|
+
if (typeof rowan === "object" && rowan !== null && !Array.isArray(rowan)) {
|
|
1888
|
+
const configured = rowan.instructions;
|
|
1889
|
+
if (typeof configured === "string" && configured.trim().length > 0) {
|
|
1890
|
+
return configured.trim();
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
const input = context.execution.input;
|
|
1894
|
+
if (input === void 0) return void 0;
|
|
1895
|
+
const text = typeof input === "string" ? input : input.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
1896
|
+
const match = text.match(/^\/compact(?:\s+([\s\S]*))?$/i);
|
|
1897
|
+
const instructions = match?.[1]?.trim();
|
|
1898
|
+
return instructions || void 0;
|
|
1899
|
+
}
|
|
1873
1900
|
function createCorePhases() {
|
|
1874
1901
|
return [createDefaultPhase(), createStopPhase(), createCompactPhase()];
|
|
1875
1902
|
}
|
|
@@ -3378,6 +3405,10 @@ function assertAgentConfigRequest(config) {
|
|
|
3378
3405
|
if (typeof context.name !== "string" || context.name.trim() === "") throw new TypeError("Context candidate name must be non-empty");
|
|
3379
3406
|
assertJsonValue(context.value, `Context candidate "${context.name}" value`);
|
|
3380
3407
|
}
|
|
3408
|
+
for (const context of config.additionalContexts ?? []) {
|
|
3409
|
+
if (typeof context.name !== "string" || context.name.trim() === "") throw new TypeError("Additional Context candidate name must be non-empty");
|
|
3410
|
+
assertJsonValue(context.value, `Additional Context candidate "${context.name}" value`);
|
|
3411
|
+
}
|
|
3381
3412
|
}
|
|
3382
3413
|
function assertToolExecutionResult(value) {
|
|
3383
3414
|
if (!isToolResult(value)) throw new TypeError("Tool result must be JSON-safe and contain no Runtime identity");
|
|
@@ -3563,6 +3594,12 @@ function snapshotConfiguration(config) {
|
|
|
3563
3594
|
name: context.name,
|
|
3564
3595
|
value: snapshotJsonValue(context.value)
|
|
3565
3596
|
})))
|
|
3597
|
+
} : {},
|
|
3598
|
+
...config.additionalContexts ? {
|
|
3599
|
+
additionalContexts: Object.freeze(config.additionalContexts.map((context) => Object.freeze({
|
|
3600
|
+
name: context.name,
|
|
3601
|
+
value: snapshotJsonValue(context.value)
|
|
3602
|
+
})))
|
|
3566
3603
|
} : {}
|
|
3567
3604
|
});
|
|
3568
3605
|
}
|
|
@@ -5474,14 +5511,18 @@ function resolveConfigurationSnapshot(registry, input) {
|
|
|
5474
5511
|
throw new Error(`Agent Definition "${input.definition.name}" is not available in the Resource View.`);
|
|
5475
5512
|
}
|
|
5476
5513
|
const layer = input.definition.layer;
|
|
5477
|
-
const
|
|
5514
|
+
const selectedContexts = selectNamedResources(input.contexts ?? [], base.contexts, "Context");
|
|
5515
|
+
const contexts = appendAdditionalContexts(selectedContexts, input.additionalContexts ?? []);
|
|
5516
|
+
const definition = addAdditionalContextNames(
|
|
5517
|
+
applyDefinitionLayer(base, layer),
|
|
5518
|
+
contexts.slice(selectedContexts.length).map(({ name }) => name)
|
|
5519
|
+
);
|
|
5478
5520
|
const tools = selectNamedResources(resolved.tools, definition.tools, "Tool");
|
|
5479
5521
|
const skills = mergeSkills(
|
|
5480
5522
|
selectNamedResources(resolved.skills, definition.skills, "Skill"),
|
|
5481
5523
|
definition.bundledSkills
|
|
5482
5524
|
);
|
|
5483
5525
|
const phases = resolvePhases(resolved.phases, definition.phases);
|
|
5484
|
-
const contexts = selectNamedResources(input.contexts ?? [], base.contexts, "Context");
|
|
5485
5526
|
return {
|
|
5486
5527
|
identity: input.identity,
|
|
5487
5528
|
definition,
|
|
@@ -5539,6 +5580,22 @@ function applyDefinitionLayer(base, layer) {
|
|
|
5539
5580
|
...layer.phases === void 0 ? {} : { phases: intersectPhaseSelection(base.phases, layer.phases) }
|
|
5540
5581
|
};
|
|
5541
5582
|
}
|
|
5583
|
+
function appendAdditionalContexts(selected, additional) {
|
|
5584
|
+
const contexts = [...selected];
|
|
5585
|
+
const seen = new Set(contexts.map(({ name }) => name));
|
|
5586
|
+
for (const context of additional) {
|
|
5587
|
+
if (seen.has(context.name)) continue;
|
|
5588
|
+
seen.add(context.name);
|
|
5589
|
+
contexts.push(context);
|
|
5590
|
+
}
|
|
5591
|
+
return contexts;
|
|
5592
|
+
}
|
|
5593
|
+
function addAdditionalContextNames(definition, names) {
|
|
5594
|
+
if (definition.contexts === void 0 || names.length === 0) return definition;
|
|
5595
|
+
const existing = new Set(definition.contexts);
|
|
5596
|
+
const additions = names.filter((name) => !existing.has(name));
|
|
5597
|
+
return additions.length === 0 ? definition : { ...definition, contexts: [...definition.contexts, ...additions] };
|
|
5598
|
+
}
|
|
5542
5599
|
function intersectNames(parent, layer, kind) {
|
|
5543
5600
|
if (parent === void 0) return [...layer];
|
|
5544
5601
|
const parentNames = new Set(parent);
|
|
@@ -5735,7 +5792,9 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5735
5792
|
};
|
|
5736
5793
|
const run = await this.owned.createRun({
|
|
5737
5794
|
agentId,
|
|
5738
|
-
input
|
|
5795
|
+
// An empty input is a system-triggered Control Run. A non-empty input
|
|
5796
|
+
// represents a user invocation and is committed by the Durable Store.
|
|
5797
|
+
input: options.input ?? "",
|
|
5739
5798
|
metadata,
|
|
5740
5799
|
idempotencyKey: options.idempotencyKey ?? createId("compact")
|
|
5741
5800
|
});
|
|
@@ -6002,17 +6061,6 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6002
6061
|
...executionContext2.phases,
|
|
6003
6062
|
entryPhaseId: COMPACT_PHASE_ID
|
|
6004
6063
|
};
|
|
6005
|
-
const instructions = controlKind === "compact" ? compactInstructions(run) : void 0;
|
|
6006
|
-
if (instructions) {
|
|
6007
|
-
executionContext2.messages.push({
|
|
6008
|
-
id: createId("msg"),
|
|
6009
|
-
role: "user",
|
|
6010
|
-
content: `Additional compaction instructions:
|
|
6011
|
-
${instructions}`,
|
|
6012
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6013
|
-
metadata: { kind: "phase_input", phase: COMPACT_PHASE_ID }
|
|
6014
|
-
});
|
|
6015
|
-
}
|
|
6016
6064
|
}
|
|
6017
6065
|
return executionContext2;
|
|
6018
6066
|
};
|
|
@@ -6029,6 +6077,7 @@ ${instructions}`,
|
|
|
6029
6077
|
agentId: run.agentId,
|
|
6030
6078
|
runId: run.id,
|
|
6031
6079
|
executionId: claim.execution.executionId,
|
|
6080
|
+
input: typeof run.input === "string" ? run.input : run.input.content,
|
|
6032
6081
|
...agent.metadata === void 0 ? {} : { agentMetadata: agent.metadata },
|
|
6033
6082
|
...run.metadata === void 0 ? {} : { runMetadata: run.metadata }
|
|
6034
6083
|
},
|
|
@@ -6175,6 +6224,7 @@ ${instructions}`,
|
|
|
6175
6224
|
const output = latestAssistant(run, result.messages.slice(modelMessages.length), modelMessages.length);
|
|
6176
6225
|
if (controlKind === "compact" || isCompactionOutcome(result.outcome.payload)) {
|
|
6177
6226
|
const summary = compactSummary(result.outcome.payload);
|
|
6227
|
+
const instructions = compactInstructions2(run) ?? compactOutputInstructions(result.outcome.payload);
|
|
6178
6228
|
if (summary) {
|
|
6179
6229
|
const covered = claim.history.at(-1);
|
|
6180
6230
|
const record = {
|
|
@@ -6182,7 +6232,7 @@ ${instructions}`,
|
|
|
6182
6232
|
agentId: run.agentId,
|
|
6183
6233
|
summary,
|
|
6184
6234
|
...covered ? { coveredThrough: { messageId: covered.id, sequence: covered.sequenceWithinRun } } : {},
|
|
6185
|
-
...
|
|
6235
|
+
...instructions ? { instructions } : {},
|
|
6186
6236
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6187
6237
|
};
|
|
6188
6238
|
await this.owned.commitContextCompaction(record);
|
|
@@ -6527,7 +6577,7 @@ function controlRunKind(run) {
|
|
|
6527
6577
|
const kind = rowan.kind;
|
|
6528
6578
|
return typeof kind === "string" ? kind : void 0;
|
|
6529
6579
|
}
|
|
6530
|
-
function
|
|
6580
|
+
function compactInstructions2(run) {
|
|
6531
6581
|
const rowan = run.metadata?.rowan;
|
|
6532
6582
|
if (typeof rowan !== "object" || rowan === null || !("instructions" in rowan)) return void 0;
|
|
6533
6583
|
const instructions = rowan.instructions;
|
|
@@ -6538,6 +6588,11 @@ function compactSummary(payload) {
|
|
|
6538
6588
|
const summary = payload.summary;
|
|
6539
6589
|
return typeof summary === "string" && summary.trim().length > 0 ? summary : void 0;
|
|
6540
6590
|
}
|
|
6591
|
+
function compactOutputInstructions(payload) {
|
|
6592
|
+
if (typeof payload !== "object" || payload === null || !("instructions" in payload)) return void 0;
|
|
6593
|
+
const instructions = payload.instructions;
|
|
6594
|
+
return typeof instructions === "string" && instructions.trim().length > 0 ? instructions.trim() : void 0;
|
|
6595
|
+
}
|
|
6541
6596
|
function isCompactionOutcome(payload) {
|
|
6542
6597
|
return typeof payload === "object" && payload !== null && "kind" in payload && payload.kind === "context_compaction";
|
|
6543
6598
|
}
|
|
@@ -7012,7 +7067,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7012
7067
|
}
|
|
7013
7068
|
if (!run.pinnedConfigToken && input.configToken) run.pinnedConfigToken = input.configToken;
|
|
7014
7069
|
let message;
|
|
7015
|
-
if (!run.checkpoint && !run.initialMessageId && !isControlRun(run)) {
|
|
7070
|
+
if (!run.checkpoint && !run.initialMessageId && (!isControlRun(run) || hasUserInput(run.input))) {
|
|
7016
7071
|
const userInput = normalizeUserInput(run.input);
|
|
7017
7072
|
message = {
|
|
7018
7073
|
id: input.messageId ?? createId("msg"),
|
|
@@ -7930,12 +7985,16 @@ function ownershipLost(expected, actual, reason) {
|
|
|
7930
7985
|
function userInputContent(input) {
|
|
7931
7986
|
return typeof input === "string" ? input : input.content;
|
|
7932
7987
|
}
|
|
7988
|
+
function hasUserInput(input) {
|
|
7989
|
+
const content = userInputContent(input);
|
|
7990
|
+
return content.length > 0;
|
|
7991
|
+
}
|
|
7933
7992
|
function userInputMetadata(input) {
|
|
7934
7993
|
return typeof input === "string" ? void 0 : input.metadata;
|
|
7935
7994
|
}
|
|
7936
7995
|
function isControlRun(run) {
|
|
7937
7996
|
const rowan = run.metadata?.rowan;
|
|
7938
|
-
return typeof rowan === "object" && rowan !== null &&
|
|
7997
|
+
return typeof rowan === "object" && rowan !== null && typeof rowan.kind === "string" && rowan.kind.length > 0;
|
|
7939
7998
|
}
|
|
7940
7999
|
function estimateMessageTokens(messages) {
|
|
7941
8000
|
let characters = 0;
|