@rowan-agent/agent 0.9.25 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -55
- package/dist/index.d.ts +14 -42
- package/dist/index.js +178 -290
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,6 @@ identity, not a process-local Session object.
|
|
|
9
9
|
```ts
|
|
10
10
|
import {
|
|
11
11
|
AgentRuntime,
|
|
12
|
-
createCoreTools,
|
|
13
12
|
InMemoryStore,
|
|
14
13
|
loadPhases,
|
|
15
14
|
loadSkills,
|
|
@@ -21,6 +20,21 @@ const runtime = await AgentRuntime.init({
|
|
|
21
20
|
store: new InMemoryStore(),
|
|
22
21
|
});
|
|
23
22
|
|
|
23
|
+
await runtime.loadAgents({
|
|
24
|
+
sourceId: "workspace",
|
|
25
|
+
values: [{
|
|
26
|
+
name: "workspace-assistant",
|
|
27
|
+
description: "Assist with the current workspace.",
|
|
28
|
+
prompt: "You are helpful.",
|
|
29
|
+
contexts: ["workspace"],
|
|
30
|
+
}],
|
|
31
|
+
});
|
|
32
|
+
await runtime.loadSkills({ sourceId: "workspace", values: skills });
|
|
33
|
+
await runtime.loadPhases({
|
|
34
|
+
sourceId: "workspace",
|
|
35
|
+
values: [...phases.phases.values()],
|
|
36
|
+
});
|
|
37
|
+
|
|
24
38
|
const agentId = await runtime.createAgent({
|
|
25
39
|
identity: "example:v1", // Stable config snapshot identity, not the Agent ID
|
|
26
40
|
model: {
|
|
@@ -30,21 +44,17 @@ const agentId = await runtime.createAgent({
|
|
|
30
44
|
baseUrl: "https://api.openai.com/v1",
|
|
31
45
|
apiKey: process.env.OPENAI_API_KEY!,
|
|
32
46
|
},
|
|
33
|
-
definition: {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
resources: {
|
|
40
|
-
tools: createCoreTools({ root: process.cwd() }),
|
|
41
|
-
skills,
|
|
42
|
-
contexts: [{
|
|
43
|
-
name: "workspace",
|
|
44
|
-
value: { root: process.cwd() },
|
|
45
|
-
}],
|
|
46
|
-
phases,
|
|
47
|
+
definition: { name: "workspace-assistant" },
|
|
48
|
+
resourceView: {
|
|
49
|
+
agents: ["workspace"],
|
|
50
|
+
tools: [],
|
|
51
|
+
skills: ["workspace"],
|
|
52
|
+
phases: ["workspace"],
|
|
47
53
|
},
|
|
54
|
+
contexts: [{
|
|
55
|
+
name: "workspace",
|
|
56
|
+
value: { root: process.cwd() },
|
|
57
|
+
}],
|
|
48
58
|
});
|
|
49
59
|
|
|
50
60
|
const run = await runtime.start(agentId, "Summarize the workspace.", {
|
|
@@ -93,8 +103,8 @@ lifecycles, and Owner fencing.
|
|
|
93
103
|
|
|
94
104
|
## Tool lifecycle
|
|
95
105
|
|
|
96
|
-
Tools are
|
|
97
|
-
|
|
106
|
+
Tools are registered under a source, selected by the Definition, and persist
|
|
107
|
+
through:
|
|
98
108
|
|
|
99
109
|
`pending → running → completed | failed | indeterminate`
|
|
100
110
|
|
|
@@ -150,17 +160,13 @@ await runtime.loadAgents({
|
|
|
150
160
|
prompt: "You are helpful.",
|
|
151
161
|
}],
|
|
152
162
|
});
|
|
153
|
-
await runtime.loadTools({
|
|
154
|
-
sourceId: "workspace",
|
|
155
|
-
values: createCoreTools({ root: process.cwd() }),
|
|
156
|
-
});
|
|
157
163
|
|
|
158
164
|
const agentId = await runtime.createAgent({
|
|
159
165
|
identity: "workspace:v1",
|
|
160
166
|
definition: { name: "workspace-assistant" },
|
|
161
167
|
resourceView: {
|
|
162
168
|
agents: ["workspace"],
|
|
163
|
-
tools: [
|
|
169
|
+
tools: [],
|
|
164
170
|
skills: [],
|
|
165
171
|
phases: [],
|
|
166
172
|
},
|
|
@@ -176,8 +182,11 @@ const agentId = await runtime.createAgent({
|
|
|
176
182
|
|
|
177
183
|
Each `load*()` call replaces one source atomically; use `directory` or inline
|
|
178
184
|
`values`. `resourceView` controls visibility, so same-name resources can live
|
|
179
|
-
in isolated sources but collide when selected together. The
|
|
180
|
-
|
|
185
|
+
in isolated sources but collide when selected together. The Runtime supplies the
|
|
186
|
+
core `read`/`bash`/`edit`/`write`/`route` Tools itself, and its `rowan.core`
|
|
187
|
+
source — like an Extension's `rowan.extensions` — is implicit in every view, so
|
|
188
|
+
a Definition can select a built-in Phase without naming that source. Core names
|
|
189
|
+
cannot be claimed by another source.
|
|
181
190
|
|
|
182
191
|
Extensions are Runtime-global. Load them only during `AgentRuntime.init()` via
|
|
183
192
|
`bootstrap`; after initialization they are frozen until the Runtime closes.
|
|
@@ -185,34 +194,22 @@ Definition name lists narrow the selected Tools, Skills, and Phases: omission
|
|
|
185
194
|
inherits all candidates, `[]` selects none, and missing names are skipped. The
|
|
186
195
|
same rule applies to `definition.contexts`.
|
|
187
196
|
|
|
188
|
-
###
|
|
197
|
+
### Registration, Definition, and View
|
|
189
198
|
|
|
190
|
-
|
|
199
|
+
Registration, selection, and visibility have different jobs:
|
|
191
200
|
|
|
192
|
-
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
-
|
|
201
|
+
- A **source** supplies resources. Tools carry their executable `execute()`,
|
|
202
|
+
Skills and Phases carry their loaded content, and a Definition carries its
|
|
203
|
+
prompt. Register them with `runtime.loadAgents/loadSkills/loadPhases/loadTools`.
|
|
204
|
+
- The **Definition** declares what one Agent uses. `tools`, `skills`,
|
|
196
205
|
`contexts`, and `phases` are name-based selectors; they cannot create a
|
|
197
|
-
resource that
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
the selectors when the Agent should use everything:
|
|
201
|
-
|
|
202
|
-
```ts
|
|
203
|
-
const agentId = await runtime.createAgent({
|
|
204
|
-
identity: "workspace:v1",
|
|
205
|
-
definition: {
|
|
206
|
-
name: "workspace-assistant",
|
|
207
|
-
description: "Assist with the current workspace.",
|
|
208
|
-
prompt: "You are helpful.",
|
|
209
|
-
},
|
|
210
|
-
resources: { tools, skills, contexts, phases },
|
|
211
|
-
model,
|
|
212
|
-
});
|
|
213
|
-
```
|
|
206
|
+
resource that no selected source holds.
|
|
207
|
+
- The **Resource View** decides which sources the Agent can see at all, by
|
|
208
|
+
stable source ID.
|
|
214
209
|
|
|
215
|
-
|
|
210
|
+
Contexts are the exception: `contexts` and `additionalContexts` ship with the
|
|
211
|
+
configuration request, because they carry host values rather than registered
|
|
212
|
+
resources. Use selectors when several Agents share a candidate pool:
|
|
216
213
|
|
|
217
214
|
```ts
|
|
218
215
|
definition: {
|
|
@@ -225,10 +222,6 @@ definition: {
|
|
|
225
222
|
}
|
|
226
223
|
```
|
|
227
224
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Configuration Snapshot. This lets a restarted Runtime resolve the same
|
|
232
|
-
resource revisions while keeping each Run pinned to the snapshot that created
|
|
233
|
-
it. Direct `resources` are simpler for embedding; `resourceView` is the
|
|
234
|
-
declarative form for shared, reloadable, and restart-resolvable resources.
|
|
225
|
+
Each Run resolves its view once into an immutable Configuration Snapshot and
|
|
226
|
+
stays pinned to it: replacing a source afterwards cannot change an active or
|
|
227
|
+
input-waiting Run, and a restarted Runtime re-resolves the same source IDs.
|
package/dist/index.d.ts
CHANGED
|
@@ -1521,10 +1521,9 @@ type ConfigurationSnapshot = Readonly<{
|
|
|
1521
1521
|
}>;
|
|
1522
1522
|
/** Resolve one Definition request into one immutable, source-qualified snapshot. */
|
|
1523
1523
|
declare function resolveConfigurationSnapshot(registry: ResourceRegistry, input: AgentConfiguration): ConfigurationSnapshot;
|
|
1524
|
-
/**
|
|
1525
|
-
*
|
|
1526
|
-
|
|
1527
|
-
declare function materializeConfigurationSnapshot(snapshot: ConfigurationSnapshot): AgentConfig;
|
|
1524
|
+
/** Whether one stored configuration is already a resolved snapshot. A snapshot
|
|
1525
|
+
* is used as it stands; a request is resolved against the current sources. */
|
|
1526
|
+
declare function isConfigurationSnapshot(config: AgentConfiguration | ConfigurationSnapshot): config is ConfigurationSnapshot;
|
|
1528
1527
|
|
|
1529
1528
|
type UserInput = string | Readonly<{
|
|
1530
1529
|
content: UserContent;
|
|
@@ -1597,16 +1596,6 @@ type AfterToolCall = (input: Readonly<{
|
|
|
1597
1596
|
context: ToolInvocationContext;
|
|
1598
1597
|
signal: AbortSignal;
|
|
1599
1598
|
}>) => ToolExecutionResult$1 | Promise<ToolExecutionResult$1>;
|
|
1600
|
-
type AgentResources = Readonly<{
|
|
1601
|
-
tools: readonly Tool[];
|
|
1602
|
-
skills: readonly Skill[];
|
|
1603
|
-
phases?: PhaseRegistry;
|
|
1604
|
-
contexts?: readonly ContextCandidate[];
|
|
1605
|
-
/** Source-qualified snapshot metadata retained for restart/recovery checks. */
|
|
1606
|
-
resourceView?: ResourceView;
|
|
1607
|
-
resourceRefs?: readonly ResourceRef[];
|
|
1608
|
-
resourceRevisions?: Readonly<Record<ResourceKind, readonly string[]>>;
|
|
1609
|
-
}>;
|
|
1610
1599
|
type InvocationSource = "auto" | "implicit" | "external";
|
|
1611
1600
|
type InvocationCatalogEntry = Readonly<{
|
|
1612
1601
|
kind: "phase" | "skill";
|
|
@@ -1618,25 +1607,6 @@ type InvocationCatalogEntry = Readonly<{
|
|
|
1618
1607
|
disableImplicitInvocation: boolean;
|
|
1619
1608
|
filePath: string;
|
|
1620
1609
|
}>;
|
|
1621
|
-
type AgentConfig = Readonly<{
|
|
1622
|
-
identity: string;
|
|
1623
|
-
definition: AgentDefinition;
|
|
1624
|
-
resources: AgentResources;
|
|
1625
|
-
/** Host-owned Contexts rendered in the System Prompt with the selected Contexts. */
|
|
1626
|
-
additionalContexts?: readonly ContextCandidate[];
|
|
1627
|
-
cwd?: string;
|
|
1628
|
-
maxAttempts?: number;
|
|
1629
|
-
beforeToolCall?: BeforeToolCall;
|
|
1630
|
-
afterToolCall?: AfterToolCall;
|
|
1631
|
-
} & ({
|
|
1632
|
-
model: ModelConfig;
|
|
1633
|
-
stream?: never;
|
|
1634
|
-
} | {
|
|
1635
|
-
model: ModelRef;
|
|
1636
|
-
stream: StreamFn;
|
|
1637
|
-
})>;
|
|
1638
|
-
/** Definition-reference request accepted at the public Runtime seam. */
|
|
1639
|
-
type AgentConfigRequest = AgentConfig | AgentConfiguration;
|
|
1640
1610
|
type AgentRecord = Readonly<{
|
|
1641
1611
|
id: AgentId;
|
|
1642
1612
|
metadata?: Metadata;
|
|
@@ -1816,7 +1786,7 @@ type RunBoundary = Readonly<{
|
|
|
1816
1786
|
}>;
|
|
1817
1787
|
type ConfigResolution = Readonly<{
|
|
1818
1788
|
kind: "available";
|
|
1819
|
-
config:
|
|
1789
|
+
config: AgentConfiguration | ConfigurationSnapshot;
|
|
1820
1790
|
} | {
|
|
1821
1791
|
kind: "deferred";
|
|
1822
1792
|
retryAfterMs?: number;
|
|
@@ -1834,7 +1804,7 @@ interface ConfigProvider {
|
|
|
1834
1804
|
put(input: {
|
|
1835
1805
|
agentId: AgentId;
|
|
1836
1806
|
agentMetadata?: Metadata;
|
|
1837
|
-
config:
|
|
1807
|
+
config: AgentConfiguration | ConfigurationSnapshot;
|
|
1838
1808
|
operationId: string;
|
|
1839
1809
|
signal: AbortSignal;
|
|
1840
1810
|
}): Promise<ConfigPutResult>;
|
|
@@ -2031,12 +2001,12 @@ interface AgentRuntime$1 {
|
|
|
2031
2001
|
kind: ResourceKind;
|
|
2032
2002
|
sourceId: string;
|
|
2033
2003
|
}>): Promise<LoadResult>;
|
|
2034
|
-
createAgent(config:
|
|
2004
|
+
createAgent(config: AgentConfiguration, options?: {
|
|
2035
2005
|
idempotencyKey?: string;
|
|
2036
2006
|
metadata?: Metadata;
|
|
2037
2007
|
historySeed?: HistorySeed;
|
|
2038
2008
|
}): Promise<AgentId>;
|
|
2039
|
-
updateAgentConfig(agentId: AgentId, config:
|
|
2009
|
+
updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
|
|
2040
2010
|
idempotencyKey: string;
|
|
2041
2011
|
}): Promise<void>;
|
|
2042
2012
|
deleteAgent(input: AgentDeletionRequest): Promise<void>;
|
|
@@ -2122,12 +2092,12 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
2122
2092
|
kind: ResourceKind;
|
|
2123
2093
|
sourceId: string;
|
|
2124
2094
|
}>): Promise<LoadResult>;
|
|
2125
|
-
createAgent(config:
|
|
2095
|
+
createAgent(config: AgentConfiguration, options?: {
|
|
2126
2096
|
idempotencyKey?: string;
|
|
2127
2097
|
metadata?: Metadata;
|
|
2128
2098
|
historySeed?: HistorySeed;
|
|
2129
2099
|
}): Promise<AgentId>;
|
|
2130
|
-
updateAgentConfig(agentId: AgentId, config:
|
|
2100
|
+
updateAgentConfig(agentId: AgentId, config: AgentConfiguration, options: {
|
|
2131
2101
|
idempotencyKey: string;
|
|
2132
2102
|
}): Promise<void>;
|
|
2133
2103
|
deleteAgent(input: AgentDeletionRequest): Promise<void>;
|
|
@@ -2211,7 +2181,9 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
2211
2181
|
signal?: AbortSignal;
|
|
2212
2182
|
}): Promise<RunBoundary>;
|
|
2213
2183
|
private assertOpen;
|
|
2214
|
-
|
|
2184
|
+
/** Resolve one stored configuration to the snapshot this execution uses. A
|
|
2185
|
+
* stored snapshot is already source-qualified and is used as it stands. */
|
|
2186
|
+
private resolveConfig;
|
|
2215
2187
|
private startHeartbeat;
|
|
2216
2188
|
}
|
|
2217
2189
|
|
|
@@ -2627,7 +2599,7 @@ declare class InMemoryConfigProvider implements ConfigProvider {
|
|
|
2627
2599
|
put(input: {
|
|
2628
2600
|
agentId: AgentId;
|
|
2629
2601
|
agentMetadata?: Metadata;
|
|
2630
|
-
config:
|
|
2602
|
+
config: AgentConfiguration | ConfigurationSnapshot;
|
|
2631
2603
|
operationId: string;
|
|
2632
2604
|
signal: AbortSignal;
|
|
2633
2605
|
}): Promise<ConfigPutResult>;
|
|
@@ -2810,4 +2782,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
|
|
|
2810
2782
|
|
|
2811
2783
|
declare function createCoreTools(input?: CoreToolContext): Tool[];
|
|
2812
2784
|
|
|
2813
|
-
export { type AfterToolCall, type
|
|
2785
|
+
export { type AfterToolCall, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, 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, isConfigurationSnapshot, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhaseSettings, loadPhases, loadSkill, loadSkills, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
|
package/dist/index.js
CHANGED
|
@@ -3447,9 +3447,9 @@ var THINKING_LEVELS = [
|
|
|
3447
3447
|
];
|
|
3448
3448
|
function thinkingLevelFromMetadata(metadata) {
|
|
3449
3449
|
const record = isRecord3(metadata) ? metadata : void 0;
|
|
3450
|
-
const
|
|
3451
|
-
if (!isRecord3(
|
|
3452
|
-
const level =
|
|
3450
|
+
const mori = record?.mori;
|
|
3451
|
+
if (!isRecord3(mori)) return void 0;
|
|
3452
|
+
const level = mori.thinkingLevel;
|
|
3453
3453
|
return typeof level === "string" && THINKING_LEVELS.includes(level) ? level : void 0;
|
|
3454
3454
|
}
|
|
3455
3455
|
function thinkingLevelFromMessages(messages) {
|
|
@@ -3463,9 +3463,6 @@ function thinkingLevelFromMessages(messages) {
|
|
|
3463
3463
|
}
|
|
3464
3464
|
return void 0;
|
|
3465
3465
|
}
|
|
3466
|
-
function isAgentConfiguration(config) {
|
|
3467
|
-
return !("resources" in config);
|
|
3468
|
-
}
|
|
3469
3466
|
var METADATA_LIMIT = 64 * 1024;
|
|
3470
3467
|
var IDENTITY_LIMIT = 256;
|
|
3471
3468
|
function isRecord3(value) {
|
|
@@ -3521,35 +3518,7 @@ function isToolResult(value) {
|
|
|
3521
3518
|
if (JSON.stringify(Object.keys(value).sort()) !== JSON.stringify(expected)) return false;
|
|
3522
3519
|
return value.ok || typeof value.error === "string";
|
|
3523
3520
|
}
|
|
3524
|
-
function
|
|
3525
|
-
if (typeof config.identity !== "string" || config.identity.length === 0) throw new TypeError("config.identity must be non-empty");
|
|
3526
|
-
assertUtf8ByteLimit(config.identity, IDENTITY_LIMIT, "config.identity");
|
|
3527
|
-
assertAgentDefinition(config.definition);
|
|
3528
|
-
if (!config.resources || !Array.isArray(config.resources.tools) || !Array.isArray(config.resources.skills)) {
|
|
3529
|
-
throw new TypeError("config.resources is invalid");
|
|
3530
|
-
}
|
|
3531
|
-
for (const tool of config.resources.tools) projectToolDefinition(tool);
|
|
3532
|
-
const names = /* @__PURE__ */ new Set();
|
|
3533
|
-
for (const context of config.resources.contexts ?? []) {
|
|
3534
|
-
if (typeof context.name !== "string" || context.name.trim() === "") {
|
|
3535
|
-
throw new TypeError("Context candidate name must be non-empty");
|
|
3536
|
-
}
|
|
3537
|
-
if (names.has(context.name)) throw new TypeError(`Duplicate Context candidate "${context.name}".`);
|
|
3538
|
-
names.add(context.name);
|
|
3539
|
-
assertJsonValue(context.value, `Context candidate "${context.name}" value`);
|
|
3540
|
-
}
|
|
3541
|
-
for (const context of config.additionalContexts ?? []) {
|
|
3542
|
-
if (typeof context.name !== "string" || context.name.trim() === "") {
|
|
3543
|
-
throw new TypeError("Additional Context candidate name must be non-empty");
|
|
3544
|
-
}
|
|
3545
|
-
assertJsonValue(context.value, `Additional Context candidate "${context.name}" value`);
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
|
-
function assertAgentConfigRequest(config) {
|
|
3549
|
-
if (!isAgentConfiguration(config)) {
|
|
3550
|
-
assertAgentConfig(config);
|
|
3551
|
-
return;
|
|
3552
|
-
}
|
|
3521
|
+
function assertAgentConfiguration(config) {
|
|
3553
3522
|
if (typeof config.identity !== "string" || config.identity.length === 0) throw new TypeError("config.identity must be non-empty");
|
|
3554
3523
|
assertUtf8ByteLimit(config.identity, IDENTITY_LIMIT, "config.identity");
|
|
3555
3524
|
if (!config.definition || typeof config.definition.name !== "string" || config.definition.name.trim() === "") {
|
|
@@ -3579,11 +3548,110 @@ function assertAgentConfigRequest(config) {
|
|
|
3579
3548
|
function assertToolExecutionResult(value) {
|
|
3580
3549
|
if (!isToolResult(value)) throw new TypeError("Tool result must be JSON-safe and contain no Runtime identity");
|
|
3581
3550
|
}
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3551
|
+
|
|
3552
|
+
// src/runtime/configuration-snapshot.ts
|
|
3553
|
+
function resolveConfigurationSnapshot(registry, input) {
|
|
3554
|
+
validateMaxAttempts(input.maxAttempts);
|
|
3555
|
+
const resolved = registry.resolveView(input.resourceView);
|
|
3556
|
+
const base = resolved.agents.find(({ name }) => name === input.definition.name);
|
|
3557
|
+
if (!base) {
|
|
3558
|
+
throw new Error(`Agent Definition "${input.definition.name}" is not available in the Resource View.`);
|
|
3559
|
+
}
|
|
3560
|
+
const layer = input.definition.layer;
|
|
3561
|
+
const selectedContexts = selectNamedResources(input.contexts ?? [], base.contexts, "Context");
|
|
3562
|
+
const additionalContexts = deduplicateContexts(input.additionalContexts ?? [], selectedContexts);
|
|
3563
|
+
const definition = applyDefinitionLayer(base, layer);
|
|
3564
|
+
const tools = selectNamedResources(resolved.tools, definition.tools, "Tool");
|
|
3565
|
+
const skills = mergeSkills(
|
|
3566
|
+
selectNamedResources(resolved.skills, definition.skills, "Skill"),
|
|
3567
|
+
definition.bundledSkills
|
|
3568
|
+
);
|
|
3569
|
+
const phases = resolvePhases(resolved.phases, definition.phases);
|
|
3570
|
+
return {
|
|
3571
|
+
identity: input.identity,
|
|
3572
|
+
definition,
|
|
3573
|
+
resources: {
|
|
3574
|
+
tools,
|
|
3575
|
+
skills,
|
|
3576
|
+
...phases ? { phases } : {},
|
|
3577
|
+
revisions: resolved.revisions,
|
|
3578
|
+
refs: {
|
|
3579
|
+
agent: selectedRefs(resolved.refs.agent, [base.name]),
|
|
3580
|
+
tool: selectedRefs(resolved.refs.tool, tools.map(({ name }) => name)),
|
|
3581
|
+
skill: selectedRefs(resolved.refs.skill, skills.map(({ name }) => name)),
|
|
3582
|
+
phase: selectedRefs(resolved.refs.phase, [...phases?.phases.keys() ?? []])
|
|
3583
|
+
}
|
|
3584
|
+
},
|
|
3585
|
+
contexts: selectedContexts,
|
|
3586
|
+
additionalContexts,
|
|
3587
|
+
resourceView: input.resourceView,
|
|
3588
|
+
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
3589
|
+
...input.maxAttempts === void 0 ? {} : { maxAttempts: input.maxAttempts },
|
|
3590
|
+
..."stream" in input && input.stream ? { model: layer?.model ?? input.model, stream: input.stream } : { model: layer?.model ?? input.model }
|
|
3591
|
+
};
|
|
3592
|
+
}
|
|
3593
|
+
function isConfigurationSnapshot(config) {
|
|
3594
|
+
return "resources" in config;
|
|
3595
|
+
}
|
|
3596
|
+
function applyDefinitionLayer(base, layer) {
|
|
3597
|
+
if (!layer) return { ...base };
|
|
3598
|
+
return {
|
|
3599
|
+
...base,
|
|
3600
|
+
...layer.description === void 0 ? {} : { description: layer.description },
|
|
3601
|
+
...layer.prompt === void 0 ? {} : { prompt: layer.prompt },
|
|
3602
|
+
...layer.model === void 0 ? {} : { model: layer.model },
|
|
3603
|
+
...layer.tools === void 0 ? {} : { tools: intersectNames(base.tools, layer.tools, "Tool") },
|
|
3604
|
+
...layer.skills === void 0 ? {} : { skills: intersectNames(base.skills, layer.skills, "Skill") },
|
|
3605
|
+
...layer.phases === void 0 ? {} : { phases: intersectPhaseSelection(base.phases, layer.phases) }
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
function deduplicateContexts(additional, existing = []) {
|
|
3609
|
+
const contexts = [];
|
|
3610
|
+
const seen = new Set(existing.map(({ name }) => name));
|
|
3611
|
+
for (const context of additional) {
|
|
3612
|
+
if (seen.has(context.name)) continue;
|
|
3613
|
+
seen.add(context.name);
|
|
3614
|
+
contexts.push(context);
|
|
3615
|
+
}
|
|
3616
|
+
return contexts;
|
|
3617
|
+
}
|
|
3618
|
+
function intersectNames(parent, layer, kind) {
|
|
3619
|
+
if (parent === void 0) return [...layer];
|
|
3620
|
+
const parentNames = new Set(parent);
|
|
3621
|
+
for (const name of layer) {
|
|
3622
|
+
if (!parentNames.has(name)) console.warn(`${kind} "${name}" is not available and will be skipped.`);
|
|
3623
|
+
}
|
|
3624
|
+
return layer.filter((name) => parentNames.has(name));
|
|
3625
|
+
}
|
|
3626
|
+
function intersectPhaseSelection(parent, layer) {
|
|
3627
|
+
if (!parent) return layer;
|
|
3628
|
+
const parentNames = new Set(parent.phaseIds);
|
|
3629
|
+
for (const name of layer.phaseIds) {
|
|
3630
|
+
if (!parentNames.has(name)) console.warn(`Phase "${name}" is not available and will be skipped.`);
|
|
3631
|
+
}
|
|
3632
|
+
return {
|
|
3633
|
+
entryPhaseId: layer.entryPhaseId,
|
|
3634
|
+
phaseIds: layer.phaseIds.filter((name) => parentNames.has(name))
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
function resolvePhases(candidates, selection) {
|
|
3638
|
+
const coreNames = /* @__PURE__ */ new Set([DEFAULT_PHASE_ID, STOP_PHASE_ID, COMPACT_PHASE_ID]);
|
|
3639
|
+
const core = candidates.filter((phase) => phase.core || coreNames.has(phase.name));
|
|
3640
|
+
const authored = candidates.filter((phase) => !coreNames.has(phase.name) && !phase.core);
|
|
3641
|
+
const selected = [...core, ...selectNamedResources(authored, selection?.phaseIds, "Phase")];
|
|
3642
|
+
const entryPhaseId = selection?.entryPhaseId ?? null;
|
|
3643
|
+
if (entryPhaseId !== null && entryPhaseId !== DEFAULT_PHASE_ID && !selected.some(({ name }) => name === entryPhaseId)) {
|
|
3644
|
+
console.warn(`Phase entry "${entryPhaseId}" is not available and will be skipped.`);
|
|
3645
|
+
return { phases: new Map(selected.map((phase) => [phase.name, phase])), entryPhaseId: null };
|
|
3646
|
+
}
|
|
3647
|
+
return {
|
|
3648
|
+
phases: new Map(selected.map((phase) => [phase.name, phase])),
|
|
3649
|
+
entryPhaseId
|
|
3650
|
+
};
|
|
3651
|
+
}
|
|
3652
|
+
function selectedRefs(refs, names) {
|
|
3653
|
+
const selected = new Set(names);
|
|
3654
|
+
return refs.filter(({ name }) => selected.has(name));
|
|
3587
3655
|
}
|
|
3588
3656
|
|
|
3589
3657
|
// src/runtime/idempotency.ts
|
|
@@ -3669,58 +3737,54 @@ function validateConfigResolution(agentId, value) {
|
|
|
3669
3737
|
}
|
|
3670
3738
|
function snapshotConfig(config) {
|
|
3671
3739
|
validateMaxAttempts(config.maxAttempts);
|
|
3672
|
-
|
|
3740
|
+
return isConfigurationSnapshot(config) ? snapshotConfigurationSnapshot(config) : snapshotConfiguration(config);
|
|
3741
|
+
}
|
|
3742
|
+
function snapshotConfigurationSnapshot(snapshot) {
|
|
3673
3743
|
const definition = Object.freeze({
|
|
3674
|
-
...
|
|
3675
|
-
...
|
|
3676
|
-
...
|
|
3677
|
-
...
|
|
3678
|
-
bundledSkills: Object.freeze(
|
|
3744
|
+
...snapshot.definition,
|
|
3745
|
+
...snapshot.definition.tools ? { tools: Object.freeze([...snapshot.definition.tools]) } : {},
|
|
3746
|
+
...snapshot.definition.skills ? { skills: Object.freeze([...snapshot.definition.skills]) } : {},
|
|
3747
|
+
...snapshot.definition.bundledSkills ? {
|
|
3748
|
+
bundledSkills: Object.freeze(snapshot.definition.bundledSkills.map((skill) => Object.freeze({ ...skill })))
|
|
3679
3749
|
} : {},
|
|
3680
|
-
...
|
|
3750
|
+
...snapshot.definition.phases ? {
|
|
3681
3751
|
phases: Object.freeze({
|
|
3682
|
-
entryPhaseId:
|
|
3683
|
-
phaseIds: Object.freeze([...
|
|
3752
|
+
entryPhaseId: snapshot.definition.phases.entryPhaseId,
|
|
3753
|
+
phaseIds: Object.freeze([...snapshot.definition.phases.phaseIds])
|
|
3684
3754
|
})
|
|
3685
3755
|
} : {},
|
|
3686
|
-
...
|
|
3756
|
+
...snapshot.definition.contexts ? { contexts: Object.freeze([...snapshot.definition.contexts]) } : {}
|
|
3687
3757
|
});
|
|
3688
3758
|
const resources = Object.freeze({
|
|
3689
|
-
...
|
|
3690
|
-
tools: Object.freeze([...
|
|
3691
|
-
skills: Object.freeze([...
|
|
3692
|
-
...
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
})
|
|
3700
|
-
} : {},
|
|
3701
|
-
...config.resources.resourceRefs ? { resourceRefs: Object.freeze(config.resources.resourceRefs.map((ref) => Object.freeze({ ...ref }))) } : {},
|
|
3702
|
-
...config.resources.resourceRevisions ? {
|
|
3703
|
-
resourceRevisions: Object.freeze(Object.fromEntries(
|
|
3704
|
-
Object.entries(config.resources.resourceRevisions).map(([kind, revisions]) => [kind, Object.freeze([...revisions])])
|
|
3705
|
-
))
|
|
3706
|
-
} : {},
|
|
3707
|
-
...config.resources.contexts ? {
|
|
3708
|
-
contexts: Object.freeze(config.resources.contexts.map((context) => Object.freeze({
|
|
3709
|
-
name: context.name,
|
|
3710
|
-
value: snapshotJsonValue(context.value)
|
|
3711
|
-
})))
|
|
3712
|
-
} : {}
|
|
3759
|
+
...snapshot.resources,
|
|
3760
|
+
tools: Object.freeze([...snapshot.resources.tools]),
|
|
3761
|
+
skills: Object.freeze([...snapshot.resources.skills]),
|
|
3762
|
+
...snapshot.resources.phases ? { phases: snapshotPhaseRegistry(snapshot.resources.phases) } : {},
|
|
3763
|
+
revisions: Object.freeze(Object.fromEntries(
|
|
3764
|
+
Object.entries(snapshot.resources.revisions).map(([kind, revisions]) => [kind, Object.freeze([...revisions])])
|
|
3765
|
+
)),
|
|
3766
|
+
refs: Object.freeze(Object.fromEntries(
|
|
3767
|
+
Object.entries(snapshot.resources.refs).map(([kind, refs]) => [kind, Object.freeze(refs.map((ref) => Object.freeze({ ...ref })))])
|
|
3768
|
+
))
|
|
3713
3769
|
});
|
|
3714
3770
|
return Object.freeze({
|
|
3715
|
-
...
|
|
3771
|
+
...snapshot,
|
|
3716
3772
|
definition,
|
|
3717
3773
|
resources,
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3774
|
+
contexts: Object.freeze(snapshot.contexts.map((context) => Object.freeze({
|
|
3775
|
+
name: context.name,
|
|
3776
|
+
value: snapshotJsonValue(context.value)
|
|
3777
|
+
}))),
|
|
3778
|
+
additionalContexts: Object.freeze(snapshot.additionalContexts.map((context) => Object.freeze({
|
|
3779
|
+
name: context.name,
|
|
3780
|
+
value: snapshotJsonValue(context.value)
|
|
3781
|
+
}))),
|
|
3782
|
+
resourceView: Object.freeze({
|
|
3783
|
+
agents: Object.freeze([...snapshot.resourceView.agents]),
|
|
3784
|
+
tools: Object.freeze([...snapshot.resourceView.tools]),
|
|
3785
|
+
skills: Object.freeze([...snapshot.resourceView.skills]),
|
|
3786
|
+
phases: Object.freeze([...snapshot.resourceView.phases])
|
|
3787
|
+
})
|
|
3724
3788
|
});
|
|
3725
3789
|
}
|
|
3726
3790
|
function snapshotPhaseRegistry(registry) {
|
|
@@ -3833,7 +3897,7 @@ var ConfigCommandService = class {
|
|
|
3833
3897
|
configs;
|
|
3834
3898
|
storeIncarnation;
|
|
3835
3899
|
async createAgent(input) {
|
|
3836
|
-
|
|
3900
|
+
assertAgentConfiguration(input.config);
|
|
3837
3901
|
assertIdentity(input.config.identity);
|
|
3838
3902
|
const reserved = await this.store.reserveAgent({
|
|
3839
3903
|
idempotencyKey: input.idempotencyKey,
|
|
@@ -3856,7 +3920,7 @@ var ConfigCommandService = class {
|
|
|
3856
3920
|
return reserved.id;
|
|
3857
3921
|
}
|
|
3858
3922
|
async updateAgentConfig(input) {
|
|
3859
|
-
|
|
3923
|
+
assertAgentConfiguration(input.config);
|
|
3860
3924
|
assertIdentity(input.config.identity);
|
|
3861
3925
|
const agent = await this.findAgent(input.agentId);
|
|
3862
3926
|
const operationId = this.operationId("update_agent_config", input.agentId, input.idempotencyKey);
|
|
@@ -3887,7 +3951,7 @@ var ConfigCommandService = class {
|
|
|
3887
3951
|
* The durable Run pins this token at claim time, so later Source replacement
|
|
3888
3952
|
* cannot mutate an active or input-waiting Run. */
|
|
3889
3953
|
async storeSnapshot(input) {
|
|
3890
|
-
|
|
3954
|
+
assertAgentConfiguration(input.config);
|
|
3891
3955
|
const result = await this.put({
|
|
3892
3956
|
agentId: input.agent.id,
|
|
3893
3957
|
agentMetadata: input.agent.metadata,
|
|
@@ -4140,26 +4204,17 @@ function jsonText(value) {
|
|
|
4140
4204
|
}
|
|
4141
4205
|
|
|
4142
4206
|
// src/runtime/extensions.ts
|
|
4143
|
-
function assembleRegisteredExtensions(
|
|
4144
|
-
const extensionTools = runner.getAllRegisteredTools().map(adaptExtensionTool);
|
|
4207
|
+
function assembleRegisteredExtensions(snapshot, runner, options = {}) {
|
|
4145
4208
|
const coreTools = createRuntimeCoreTools({
|
|
4146
|
-
root:
|
|
4209
|
+
root: snapshot.cwd,
|
|
4147
4210
|
...options.toolArchiveDir ? { archiveDir: options.toolArchiveDir } : {}
|
|
4148
4211
|
});
|
|
4149
4212
|
const coreNames = new Set(coreTools.map((tool) => tool.name));
|
|
4150
4213
|
const tools = [
|
|
4151
|
-
...
|
|
4214
|
+
...snapshot.resources.tools.filter((tool) => !coreNames.has(tool.name)),
|
|
4152
4215
|
...coreTools
|
|
4153
4216
|
];
|
|
4154
|
-
const
|
|
4155
|
-
for (const tool of extensionTools) {
|
|
4156
|
-
if (names.has(tool.name)) throw new TypeError(`Extension Tool collides with Context Tool "${tool.name}"`);
|
|
4157
|
-
names.add(tool.name);
|
|
4158
|
-
tools.push(tool);
|
|
4159
|
-
}
|
|
4160
|
-
const extensionPhases = runner.createPhaseRegistry({ entryPhaseId: null });
|
|
4161
|
-
const phases = mergePhases(config.resources.phases, extensionPhases);
|
|
4162
|
-
const context = resolveDefinitionContext(config, { tools, phases });
|
|
4217
|
+
const context = resolveDefinitionContext(snapshot, tools);
|
|
4163
4218
|
return {
|
|
4164
4219
|
context,
|
|
4165
4220
|
beforePhase: (phaseId, input) => runner.emitBeforePhase(phaseId, input),
|
|
@@ -4180,83 +4235,41 @@ function assembleRegisteredExtensions(config, runner, options = {}) {
|
|
|
4180
4235
|
}
|
|
4181
4236
|
};
|
|
4182
4237
|
}
|
|
4183
|
-
function resolveDefinitionContext(
|
|
4184
|
-
const
|
|
4185
|
-
const
|
|
4186
|
-
const authoredTools = candidateTools.filter((tool) => !tool.core);
|
|
4238
|
+
function resolveDefinitionContext(snapshot, assembled) {
|
|
4239
|
+
const coreTools = assembled.filter((tool) => tool.core);
|
|
4240
|
+
const authoredTools = assembled.filter((tool) => !tool.core);
|
|
4187
4241
|
const tools = [
|
|
4188
|
-
...selectNamedResources(authoredTools,
|
|
4242
|
+
...selectNamedResources(authoredTools, snapshot.definition.tools, "Tool"),
|
|
4189
4243
|
...coreTools
|
|
4190
4244
|
];
|
|
4191
4245
|
const skills = mergeSkills(
|
|
4192
|
-
selectNamedResources(
|
|
4193
|
-
|
|
4246
|
+
selectNamedResources(snapshot.resources.skills, snapshot.definition.skills, "Skill"),
|
|
4247
|
+
snapshot.definition.bundledSkills
|
|
4194
4248
|
);
|
|
4195
4249
|
const contexts = [
|
|
4196
|
-
...selectNamedResources(
|
|
4197
|
-
|
|
4198
|
-
config.definition.contexts,
|
|
4199
|
-
"Context"
|
|
4200
|
-
),
|
|
4201
|
-
...config.additionalContexts ?? []
|
|
4250
|
+
...selectNamedResources(snapshot.contexts, snapshot.definition.contexts, "Context"),
|
|
4251
|
+
...snapshot.additionalContexts
|
|
4202
4252
|
];
|
|
4203
|
-
const
|
|
4204
|
-
const phaseCandidates = [...candidateRegistry?.phases.values() ?? []];
|
|
4253
|
+
const phaseCandidates = [...snapshot.resources.phases?.phases.values() ?? []];
|
|
4205
4254
|
const coreNames = /* @__PURE__ */ new Set([DEFAULT_PHASE_ID, STOP_PHASE_ID, COMPACT_PHASE_ID]);
|
|
4206
4255
|
const selectedPhases = [
|
|
4207
4256
|
...phaseCandidates.filter((phase) => phase.core || coreNames.has(phase.name)),
|
|
4208
4257
|
...selectNamedResources(
|
|
4209
4258
|
phaseCandidates.filter((phase) => !phase.core && !coreNames.has(phase.name)),
|
|
4210
|
-
|
|
4259
|
+
snapshot.definition.phases?.phaseIds,
|
|
4211
4260
|
"Phase"
|
|
4212
4261
|
)
|
|
4213
4262
|
];
|
|
4214
4263
|
const phases = new Map(selectedPhases.map((phase) => [phase.name, phase]));
|
|
4215
|
-
const requestedEntry =
|
|
4264
|
+
const requestedEntry = snapshot.definition.phases ? snapshot.definition.phases.entryPhaseId : snapshot.resources.phases?.entryPhaseId ?? null;
|
|
4216
4265
|
const entryPhaseId = requestedEntry === DEFAULT_PHASE_ID ? DEFAULT_PHASE_ID : requestedEntry && phases.has(requestedEntry) ? requestedEntry : null;
|
|
4217
|
-
if (requestedEntry && requestedEntry !== DEFAULT_PHASE_ID && !phases.has(requestedEntry)) {
|
|
4218
|
-
console.warn(`Phase entry "${requestedEntry}" is not available; Rowan will use "default".`);
|
|
4219
|
-
}
|
|
4220
4266
|
return {
|
|
4221
|
-
systemPrompt: [
|
|
4267
|
+
systemPrompt: [snapshot.definition.prompt, buildContextDescription(contexts)].filter((section) => section.length > 0).join("\n\n"),
|
|
4222
4268
|
tools,
|
|
4223
4269
|
skills,
|
|
4224
4270
|
phases: { phases, entryPhaseId }
|
|
4225
4271
|
};
|
|
4226
4272
|
}
|
|
4227
|
-
function mergePhases(base, extension) {
|
|
4228
|
-
const core = createCorePhases();
|
|
4229
|
-
const coreNames = new Set(core.map(({ name }) => name));
|
|
4230
|
-
const phases = new Map(core.map((phase) => [phase.name, phase]));
|
|
4231
|
-
for (const [name, phase] of base?.phases ?? []) {
|
|
4232
|
-
if (coreNames.has(name)) {
|
|
4233
|
-
if (!phase.core) throw new TypeError(`Configured Phase collides with Rowan built-in Phase "${name}".`);
|
|
4234
|
-
continue;
|
|
4235
|
-
}
|
|
4236
|
-
phases.set(name, phase);
|
|
4237
|
-
}
|
|
4238
|
-
for (const [name, phase] of extension.phases) {
|
|
4239
|
-
if (phases.has(name)) throw new TypeError(`Extension Phase collides with Context Phase "${name}"`);
|
|
4240
|
-
phases.set(name, phase);
|
|
4241
|
-
}
|
|
4242
|
-
return {
|
|
4243
|
-
phases,
|
|
4244
|
-
entryPhaseId: base?.entryPhaseId ?? extension.entryPhaseId ?? DEFAULT_PHASE_ID
|
|
4245
|
-
};
|
|
4246
|
-
}
|
|
4247
|
-
function adaptExtensionTool(input) {
|
|
4248
|
-
const definition = input.definition;
|
|
4249
|
-
return {
|
|
4250
|
-
name: definition.name,
|
|
4251
|
-
description: definition.description,
|
|
4252
|
-
parameters: definition.parameters,
|
|
4253
|
-
execute: async (args, _context, signal) => {
|
|
4254
|
-
const result = await definition.execute(args, signal);
|
|
4255
|
-
const content = JSON.parse(JSON.stringify(result.content));
|
|
4256
|
-
return result.isError ? { ok: false, content, error: "Extension Tool failed." } : { ok: true, content };
|
|
4257
|
-
}
|
|
4258
|
-
};
|
|
4259
|
-
}
|
|
4260
4273
|
function toLoopResult(result, toolCallId, toolName) {
|
|
4261
4274
|
return {
|
|
4262
4275
|
toolCallId,
|
|
@@ -5677,7 +5690,7 @@ var RuntimeBootstrapRegistry = class extends ResourceRegistry {
|
|
|
5677
5690
|
})();
|
|
5678
5691
|
const normalized = await loaded;
|
|
5679
5692
|
const result = await this.extensions.activate(normalized.extensions);
|
|
5680
|
-
await this.replaceImplicit("tool", this.extensionSourceId, this.extensions.tools().map(
|
|
5693
|
+
await this.replaceImplicit("tool", this.extensionSourceId, this.extensions.tools().map(adaptExtensionTool));
|
|
5681
5694
|
await this.replaceImplicit("phase", this.extensionSourceId, [...this.extensions.phases()]);
|
|
5682
5695
|
return {
|
|
5683
5696
|
...result,
|
|
@@ -5704,7 +5717,7 @@ var RuntimeBootstrapRegistry = class extends ResourceRegistry {
|
|
|
5704
5717
|
await this.extensions.close();
|
|
5705
5718
|
}
|
|
5706
5719
|
};
|
|
5707
|
-
function
|
|
5720
|
+
function adaptExtensionTool(input) {
|
|
5708
5721
|
const definition = input.definition;
|
|
5709
5722
|
return {
|
|
5710
5723
|
name: definition.name,
|
|
@@ -5718,132 +5731,6 @@ function adaptExtensionTool2(input) {
|
|
|
5718
5731
|
};
|
|
5719
5732
|
}
|
|
5720
5733
|
|
|
5721
|
-
// src/runtime/configuration-snapshot.ts
|
|
5722
|
-
function resolveConfigurationSnapshot(registry, input) {
|
|
5723
|
-
validateMaxAttempts(input.maxAttempts);
|
|
5724
|
-
const resolved = registry.resolveView(input.resourceView);
|
|
5725
|
-
const base = resolved.agents.find(({ name }) => name === input.definition.name);
|
|
5726
|
-
if (!base) {
|
|
5727
|
-
throw new Error(`Agent Definition "${input.definition.name}" is not available in the Resource View.`);
|
|
5728
|
-
}
|
|
5729
|
-
const layer = input.definition.layer;
|
|
5730
|
-
const selectedContexts = selectNamedResources(input.contexts ?? [], base.contexts, "Context");
|
|
5731
|
-
const additionalContexts = deduplicateContexts(input.additionalContexts ?? [], selectedContexts);
|
|
5732
|
-
const definition = applyDefinitionLayer(base, layer);
|
|
5733
|
-
const tools = selectNamedResources(resolved.tools, definition.tools, "Tool");
|
|
5734
|
-
const skills = mergeSkills(
|
|
5735
|
-
selectNamedResources(resolved.skills, definition.skills, "Skill"),
|
|
5736
|
-
definition.bundledSkills
|
|
5737
|
-
);
|
|
5738
|
-
const phases = resolvePhases(resolved.phases, definition.phases);
|
|
5739
|
-
return {
|
|
5740
|
-
identity: input.identity,
|
|
5741
|
-
definition,
|
|
5742
|
-
resources: {
|
|
5743
|
-
tools,
|
|
5744
|
-
skills,
|
|
5745
|
-
...phases ? { phases } : {},
|
|
5746
|
-
revisions: resolved.revisions,
|
|
5747
|
-
refs: {
|
|
5748
|
-
agent: selectedRefs(resolved.refs.agent, [base.name]),
|
|
5749
|
-
tool: selectedRefs(resolved.refs.tool, tools.map(({ name }) => name)),
|
|
5750
|
-
skill: selectedRefs(resolved.refs.skill, skills.map(({ name }) => name)),
|
|
5751
|
-
phase: selectedRefs(resolved.refs.phase, [...phases?.phases.keys() ?? []])
|
|
5752
|
-
}
|
|
5753
|
-
},
|
|
5754
|
-
contexts: selectedContexts,
|
|
5755
|
-
additionalContexts,
|
|
5756
|
-
resourceView: input.resourceView,
|
|
5757
|
-
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
5758
|
-
...input.maxAttempts === void 0 ? {} : { maxAttempts: input.maxAttempts },
|
|
5759
|
-
..."stream" in input && input.stream ? { model: layer?.model ?? input.model, stream: input.stream } : { model: layer?.model ?? input.model }
|
|
5760
|
-
};
|
|
5761
|
-
}
|
|
5762
|
-
function materializeConfigurationSnapshot(snapshot) {
|
|
5763
|
-
return {
|
|
5764
|
-
identity: snapshot.identity,
|
|
5765
|
-
definition: snapshot.definition,
|
|
5766
|
-
resources: {
|
|
5767
|
-
tools: snapshot.resources.tools,
|
|
5768
|
-
skills: snapshot.resources.skills,
|
|
5769
|
-
...snapshot.resources.phases ? { phases: snapshot.resources.phases } : {},
|
|
5770
|
-
...snapshot.contexts.length > 0 ? { contexts: snapshot.contexts } : {},
|
|
5771
|
-
resourceView: snapshot.resourceView,
|
|
5772
|
-
resourceRefs: [
|
|
5773
|
-
...snapshot.resources.refs.agent,
|
|
5774
|
-
...snapshot.resources.refs.tool,
|
|
5775
|
-
...snapshot.resources.refs.skill,
|
|
5776
|
-
...snapshot.resources.refs.phase
|
|
5777
|
-
],
|
|
5778
|
-
resourceRevisions: snapshot.resources.revisions
|
|
5779
|
-
},
|
|
5780
|
-
...snapshot.additionalContexts.length > 0 ? { additionalContexts: snapshot.additionalContexts } : {},
|
|
5781
|
-
...snapshot.cwd === void 0 ? {} : { cwd: snapshot.cwd },
|
|
5782
|
-
...snapshot.maxAttempts === void 0 ? {} : { maxAttempts: snapshot.maxAttempts },
|
|
5783
|
-
..."stream" in snapshot && snapshot.stream ? { model: snapshot.model, stream: snapshot.stream } : { model: snapshot.model }
|
|
5784
|
-
};
|
|
5785
|
-
}
|
|
5786
|
-
function applyDefinitionLayer(base, layer) {
|
|
5787
|
-
if (!layer) return { ...base };
|
|
5788
|
-
return {
|
|
5789
|
-
...base,
|
|
5790
|
-
...layer.description === void 0 ? {} : { description: layer.description },
|
|
5791
|
-
...layer.prompt === void 0 ? {} : { prompt: layer.prompt },
|
|
5792
|
-
...layer.model === void 0 ? {} : { model: layer.model },
|
|
5793
|
-
...layer.tools === void 0 ? {} : { tools: intersectNames(base.tools, layer.tools, "Tool") },
|
|
5794
|
-
...layer.skills === void 0 ? {} : { skills: intersectNames(base.skills, layer.skills, "Skill") },
|
|
5795
|
-
...layer.phases === void 0 ? {} : { phases: intersectPhaseSelection(base.phases, layer.phases) }
|
|
5796
|
-
};
|
|
5797
|
-
}
|
|
5798
|
-
function deduplicateContexts(additional, existing = []) {
|
|
5799
|
-
const contexts = [];
|
|
5800
|
-
const seen = new Set(existing.map(({ name }) => name));
|
|
5801
|
-
for (const context of additional) {
|
|
5802
|
-
if (seen.has(context.name)) continue;
|
|
5803
|
-
seen.add(context.name);
|
|
5804
|
-
contexts.push(context);
|
|
5805
|
-
}
|
|
5806
|
-
return contexts;
|
|
5807
|
-
}
|
|
5808
|
-
function intersectNames(parent, layer, kind) {
|
|
5809
|
-
if (parent === void 0) return [...layer];
|
|
5810
|
-
const parentNames = new Set(parent);
|
|
5811
|
-
for (const name of layer) {
|
|
5812
|
-
if (!parentNames.has(name)) console.warn(`${kind} "${name}" is not available and will be skipped.`);
|
|
5813
|
-
}
|
|
5814
|
-
return layer.filter((name) => parentNames.has(name));
|
|
5815
|
-
}
|
|
5816
|
-
function intersectPhaseSelection(parent, layer) {
|
|
5817
|
-
if (!parent) return layer;
|
|
5818
|
-
const parentNames = new Set(parent.phaseIds);
|
|
5819
|
-
for (const name of layer.phaseIds) {
|
|
5820
|
-
if (!parentNames.has(name)) console.warn(`Phase "${name}" is not available and will be skipped.`);
|
|
5821
|
-
}
|
|
5822
|
-
return {
|
|
5823
|
-
entryPhaseId: layer.entryPhaseId,
|
|
5824
|
-
phaseIds: layer.phaseIds.filter((name) => parentNames.has(name))
|
|
5825
|
-
};
|
|
5826
|
-
}
|
|
5827
|
-
function resolvePhases(candidates, selection) {
|
|
5828
|
-
const coreNames = /* @__PURE__ */ new Set([DEFAULT_PHASE_ID, STOP_PHASE_ID, COMPACT_PHASE_ID]);
|
|
5829
|
-
const core = candidates.filter((phase) => phase.core || coreNames.has(phase.name));
|
|
5830
|
-
const authored = candidates.filter((phase) => !coreNames.has(phase.name) && !phase.core);
|
|
5831
|
-
const selected = [...core, ...selectNamedResources(authored, selection?.phaseIds, "Phase")];
|
|
5832
|
-
const entryPhaseId = selection?.entryPhaseId ?? null;
|
|
5833
|
-
if (entryPhaseId !== null && entryPhaseId !== DEFAULT_PHASE_ID && !selected.some(({ name }) => name === entryPhaseId)) {
|
|
5834
|
-
console.warn(`Phase entry "${entryPhaseId}" is not available and will be skipped.`);
|
|
5835
|
-
return { phases: new Map(selected.map((phase) => [phase.name, phase])), entryPhaseId: null };
|
|
5836
|
-
}
|
|
5837
|
-
return {
|
|
5838
|
-
phases: new Map(selected.map((phase) => [phase.name, phase])),
|
|
5839
|
-
entryPhaseId
|
|
5840
|
-
};
|
|
5841
|
-
}
|
|
5842
|
-
function selectedRefs(refs, names) {
|
|
5843
|
-
const selected = new Set(names);
|
|
5844
|
-
return refs.filter(({ name }) => selected.has(name));
|
|
5845
|
-
}
|
|
5846
|
-
|
|
5847
5734
|
// src/runtime/durable-runtime.ts
|
|
5848
5735
|
var DEFAULT_CONCURRENCY = 10;
|
|
5849
5736
|
var DEFAULT_POLL_MS = 25;
|
|
@@ -6045,7 +5932,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6045
5932
|
reason: resolution.kind === "deferred" ? "Configuration is deferred." : resolution.reason
|
|
6046
5933
|
});
|
|
6047
5934
|
}
|
|
6048
|
-
const config =
|
|
5935
|
+
const config = this.resolveConfig(resolution.config);
|
|
6049
5936
|
const assembly = assembleRegisteredExtensions(config, this.resources.extensionRunner, {
|
|
6050
5937
|
toolArchiveDir: this.archiveDirFor(agentId)
|
|
6051
5938
|
});
|
|
@@ -6206,9 +6093,9 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6206
6093
|
return;
|
|
6207
6094
|
}
|
|
6208
6095
|
let resolvedConfig = resolution.config;
|
|
6209
|
-
if (
|
|
6096
|
+
if (!isConfigurationSnapshot(resolvedConfig)) {
|
|
6210
6097
|
try {
|
|
6211
|
-
const snapshot = this.
|
|
6098
|
+
const snapshot = this.resolveConfig(resolvedConfig);
|
|
6212
6099
|
token = await this.commands.storeSnapshot({
|
|
6213
6100
|
agent,
|
|
6214
6101
|
config: snapshot,
|
|
@@ -6220,7 +6107,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6220
6107
|
return;
|
|
6221
6108
|
}
|
|
6222
6109
|
}
|
|
6223
|
-
const config = resolvedConfig;
|
|
6110
|
+
const config = this.resolveConfig(resolvedConfig);
|
|
6224
6111
|
const controlKind = controlRunKind(run);
|
|
6225
6112
|
if (!controlKind && !this.autoCompactionRuns.has(run.id)) {
|
|
6226
6113
|
const contextWindow = await resolveContextWindowForConfig(config);
|
|
@@ -6283,8 +6170,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6283
6170
|
let executionContext = buildExecutionContext(modelMessages);
|
|
6284
6171
|
const executionTools = {
|
|
6285
6172
|
tools: assembly.context.tools,
|
|
6286
|
-
beforeToolCall: assembly.beforeToolCall
|
|
6287
|
-
afterToolCall: assembly.afterToolCall
|
|
6173
|
+
beforeToolCall: assembly.beforeToolCall,
|
|
6174
|
+
afterToolCall: assembly.afterToolCall
|
|
6288
6175
|
};
|
|
6289
6176
|
const executeModel = (context) => executeOnce({
|
|
6290
6177
|
canonicalMessages: context.messages,
|
|
@@ -6492,7 +6379,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6492
6379
|
if (!agent.currentConfigToken) return 128e3;
|
|
6493
6380
|
const resolution = await this.commands.resolve({ agent, token: agent.currentConfigToken });
|
|
6494
6381
|
if (resolution.kind !== "available") return 128e3;
|
|
6495
|
-
const config =
|
|
6382
|
+
const config = this.resolveConfig(resolution.config);
|
|
6496
6383
|
return resolveContextWindowForConfig(config);
|
|
6497
6384
|
}
|
|
6498
6385
|
async executeTool(input) {
|
|
@@ -6715,9 +6602,10 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6715
6602
|
assertOpen() {
|
|
6716
6603
|
if (this.closed) throw new RuntimeError("runtime_closed", null);
|
|
6717
6604
|
}
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6605
|
+
/** Resolve one stored configuration to the snapshot this execution uses. A
|
|
6606
|
+
* stored snapshot is already source-qualified and is used as it stands. */
|
|
6607
|
+
resolveConfig(config) {
|
|
6608
|
+
return isConfigurationSnapshot(config) ? config : resolveConfigurationSnapshot(this.resources, config);
|
|
6721
6609
|
}
|
|
6722
6610
|
startHeartbeat() {
|
|
6723
6611
|
this.heartbeat = setInterval(() => {
|
|
@@ -9036,6 +8924,7 @@ export {
|
|
|
9036
8924
|
createCoreTools2 as createCoreTools,
|
|
9037
8925
|
createDefaultPhase,
|
|
9038
8926
|
createStopPhase,
|
|
8927
|
+
isConfigurationSnapshot,
|
|
9039
8928
|
isRuntimeError,
|
|
9040
8929
|
loadExtensionsFromPath as loadExtensions,
|
|
9041
8930
|
loadPhase,
|
|
@@ -9043,7 +8932,6 @@ export {
|
|
|
9043
8932
|
loadPhases,
|
|
9044
8933
|
loadSkill,
|
|
9045
8934
|
loadSkills,
|
|
9046
|
-
materializeConfigurationSnapshot,
|
|
9047
8935
|
parseAgentDefinition,
|
|
9048
8936
|
parseFrontmatter,
|
|
9049
8937
|
resolveConfigurationSnapshot
|