@rowan-agent/agent 0.9.1 → 0.9.3
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 +19 -0
- package/dist/index.js +170 -16
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -611,6 +611,8 @@ type AgentDefinition = Readonly<{
|
|
|
611
611
|
prompt: string;
|
|
612
612
|
tools?: readonly string[];
|
|
613
613
|
skills?: readonly string[];
|
|
614
|
+
/** Host-supplied Skills private to this Agent Definition/Bundle. */
|
|
615
|
+
bundledSkills?: readonly Skill[];
|
|
614
616
|
phases?: PhaseRegistrySelection;
|
|
615
617
|
contexts?: readonly string[];
|
|
616
618
|
model?: ModelRef;
|
|
@@ -787,6 +789,7 @@ type UserMessage = MessageBase & Readonly<{
|
|
|
787
789
|
type AssistantMessage = MessageBase & Readonly<{
|
|
788
790
|
role: "assistant";
|
|
789
791
|
content: AssistantContent;
|
|
792
|
+
interrupted?: boolean;
|
|
790
793
|
}>;
|
|
791
794
|
type ToolMessage = MessageBase & Readonly<{
|
|
792
795
|
role: "tool";
|
|
@@ -1340,6 +1343,11 @@ type AgentRecord = Readonly<{
|
|
|
1340
1343
|
activatedAt?: string;
|
|
1341
1344
|
updatedAt: string;
|
|
1342
1345
|
}>;
|
|
1346
|
+
type AgentDeletionRequest = Readonly<{
|
|
1347
|
+
agentId: AgentId;
|
|
1348
|
+
expectedRunIds: readonly RunId[];
|
|
1349
|
+
confirmation: "conversation-delete-v1";
|
|
1350
|
+
}>;
|
|
1343
1351
|
type ExecutionToken = Readonly<{
|
|
1344
1352
|
runId: RunId;
|
|
1345
1353
|
ownerEpoch: number;
|
|
@@ -1520,6 +1528,7 @@ interface OwnedStore {
|
|
|
1520
1528
|
configIdentity?: string;
|
|
1521
1529
|
idempotencyKey: string;
|
|
1522
1530
|
}): Promise<AgentRecord>;
|
|
1531
|
+
deleteAgent(input: AgentDeletionRequest): Promise<void>;
|
|
1523
1532
|
createRun(input: {
|
|
1524
1533
|
agentId: AgentId;
|
|
1525
1534
|
input: UserInput;
|
|
@@ -1598,6 +1607,7 @@ interface OwnedStore {
|
|
|
1598
1607
|
runId: RunId;
|
|
1599
1608
|
expectedRevision?: number;
|
|
1600
1609
|
reason?: string;
|
|
1610
|
+
output?: AssistantMessage;
|
|
1601
1611
|
}): Promise<RunRecord>;
|
|
1602
1612
|
snapshotRun(runId: RunId): Promise<RunSnapshot>;
|
|
1603
1613
|
listAgents(): Promise<readonly AgentRecord[]>;
|
|
@@ -1668,6 +1678,7 @@ interface AgentRuntime$1 {
|
|
|
1668
1678
|
updateAgentConfig(agentId: AgentId, config: AgentConfigRequest, options: {
|
|
1669
1679
|
idempotencyKey: string;
|
|
1670
1680
|
}): Promise<void>;
|
|
1681
|
+
deleteAgent(input: AgentDeletionRequest): Promise<void>;
|
|
1671
1682
|
start(agentId: AgentId, input: UserInput, options: {
|
|
1672
1683
|
idempotencyKey: string;
|
|
1673
1684
|
metadata?: Metadata;
|
|
@@ -1704,6 +1715,9 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
1704
1715
|
private readonly storeIncarnation;
|
|
1705
1716
|
private readonly activeAgents;
|
|
1706
1717
|
private readonly executions;
|
|
1718
|
+
private readonly executionDone;
|
|
1719
|
+
private readonly cancellationRequested;
|
|
1720
|
+
private readonly cancellationReasons;
|
|
1707
1721
|
private readonly consumers;
|
|
1708
1722
|
private readonly transientEvents;
|
|
1709
1723
|
private readonly resources;
|
|
@@ -1730,6 +1744,7 @@ declare class AgentRuntime implements AgentRuntime$1 {
|
|
|
1730
1744
|
updateAgentConfig(agentId: AgentId, config: AgentConfigRequest, options: {
|
|
1731
1745
|
idempotencyKey: string;
|
|
1732
1746
|
}): Promise<void>;
|
|
1747
|
+
deleteAgent(input: AgentDeletionRequest): Promise<void>;
|
|
1733
1748
|
start(agentId: AgentId, input: UserInput, options: {
|
|
1734
1749
|
idempotencyKey: string;
|
|
1735
1750
|
metadata?: Metadata;
|
|
@@ -1838,6 +1853,7 @@ declare class InMemoryStore implements DurableStore {
|
|
|
1838
1853
|
configIdentity?: string;
|
|
1839
1854
|
idempotencyKey: string;
|
|
1840
1855
|
}): AgentRecord;
|
|
1856
|
+
deleteAgent(lease: OwnerLease, input: AgentDeletionRequest): void;
|
|
1841
1857
|
createRun(lease: OwnerLease, input: {
|
|
1842
1858
|
agentId: AgentId;
|
|
1843
1859
|
input: UserInput;
|
|
@@ -1923,6 +1939,7 @@ declare class InMemoryStore implements DurableStore {
|
|
|
1923
1939
|
runId: RunId;
|
|
1924
1940
|
expectedRevision?: number;
|
|
1925
1941
|
reason?: string;
|
|
1942
|
+
output?: AssistantMessage;
|
|
1926
1943
|
}): RunRecord;
|
|
1927
1944
|
snapshotRun(lease: OwnerLease, runId: RunId): RunSnapshot;
|
|
1928
1945
|
listAgents(lease: OwnerLease): readonly AgentRecord[];
|
|
@@ -1985,6 +2002,7 @@ declare class SqliteStore implements DurableStore {
|
|
|
1985
2002
|
configIdentity?: string;
|
|
1986
2003
|
idempotencyKey: string;
|
|
1987
2004
|
}): Promise<AgentRecord>;
|
|
2005
|
+
deleteAgent(lease: OwnerLease, input: AgentDeletionRequest): Promise<void>;
|
|
1988
2006
|
createRun(lease: OwnerLease, input: {
|
|
1989
2007
|
agentId: AgentId;
|
|
1990
2008
|
input: UserInput;
|
|
@@ -2070,6 +2088,7 @@ declare class SqliteStore implements DurableStore {
|
|
|
2070
2088
|
runId: RunId;
|
|
2071
2089
|
expectedRevision?: number;
|
|
2072
2090
|
reason?: string;
|
|
2091
|
+
output?: AssistantMessage;
|
|
2073
2092
|
}): Promise<RunRecord>;
|
|
2074
2093
|
snapshotRun(lease: OwnerLease, runId: RunId): Promise<RunSnapshot>;
|
|
2075
2094
|
listAgents(lease: OwnerLease): Promise<readonly AgentRecord[]>;
|
package/dist/index.js
CHANGED
|
@@ -1046,6 +1046,7 @@ function assertAgentDefinition(value) {
|
|
|
1046
1046
|
requiredString(value.prompt, "definition.prompt");
|
|
1047
1047
|
optionalStringList(value.tools, "definition.tools");
|
|
1048
1048
|
optionalStringList(value.skills, "definition.skills");
|
|
1049
|
+
optionalBundledSkills(value.bundledSkills, "definition.bundledSkills");
|
|
1049
1050
|
optionalPhaseRegistrySelection(value.phases, "definition.phases");
|
|
1050
1051
|
optionalStringList(value.contexts, "definition.contexts");
|
|
1051
1052
|
if ("extensions" in value) throw new TypeError("definition.extensions is not supported; Extensions are Runtime-global");
|
|
@@ -1117,6 +1118,19 @@ function optionalStringList(value, field) {
|
|
|
1117
1118
|
}
|
|
1118
1119
|
return names;
|
|
1119
1120
|
}
|
|
1121
|
+
function optionalBundledSkills(value, field) {
|
|
1122
|
+
if (value === void 0) return;
|
|
1123
|
+
if (!Array.isArray(value)) throw new TypeError(`${field} must be an array of Skills`);
|
|
1124
|
+
const names = /* @__PURE__ */ new Set();
|
|
1125
|
+
for (const [index, item] of value.entries()) {
|
|
1126
|
+
if (!isRecord(item) || typeof item.name !== "string" || item.name.trim() === "" || typeof item.description !== "string" || typeof item.filePath !== "string" || typeof item.baseDir !== "string" || typeof item.content !== "string" || typeof item.disableModelInvocation !== "boolean") {
|
|
1127
|
+
throw new TypeError(`${field}[${index}] is invalid`);
|
|
1128
|
+
}
|
|
1129
|
+
if (names.has(item.name)) throw new TypeError(`Duplicate bundled Skill "${item.name}".`);
|
|
1130
|
+
names.add(item.name);
|
|
1131
|
+
}
|
|
1132
|
+
return value;
|
|
1133
|
+
}
|
|
1120
1134
|
function optionalPhaseRegistrySelection(value, field) {
|
|
1121
1135
|
if (value === void 0) return void 0;
|
|
1122
1136
|
if (!isRecord(value)) throw new TypeError(`${field} must be an object`);
|
|
@@ -1511,6 +1525,13 @@ function selectNamedResources(candidates, names, kind) {
|
|
|
1511
1525
|
}
|
|
1512
1526
|
return selected;
|
|
1513
1527
|
}
|
|
1528
|
+
function mergeSkills(...layers) {
|
|
1529
|
+
const byName = /* @__PURE__ */ new Map();
|
|
1530
|
+
for (const layer of layers) {
|
|
1531
|
+
for (const skill of layer ?? []) byName.set(skill.name, skill);
|
|
1532
|
+
}
|
|
1533
|
+
return [...byName.values()];
|
|
1534
|
+
}
|
|
1514
1535
|
|
|
1515
1536
|
// src/harness/context/system-prompt.ts
|
|
1516
1537
|
function buildSystemPrompt(options) {
|
|
@@ -2040,7 +2061,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2040
2061
|
const toolExecutionManager = createToolExecutionManager();
|
|
2041
2062
|
const execution = createPhaseExecution(config, state, phase, messageManager, toolExecutionManager, registry);
|
|
2042
2063
|
const phaseTools = selectPhaseTools(allTools, phase.tools);
|
|
2043
|
-
const phaseSkills =
|
|
2064
|
+
const phaseSkills = mergeSkills(config.context.skills, phase.skills);
|
|
2044
2065
|
let phaseContext = {
|
|
2045
2066
|
systemPrompt: config.context.systemPrompt,
|
|
2046
2067
|
messages: messageManager.visible(),
|
|
@@ -2531,7 +2552,7 @@ async function executeParallelPhase(config, state, registry, phase, payload, con
|
|
|
2531
2552
|
const messages = [...context];
|
|
2532
2553
|
const allTools = buildToolsWithRouting(config, availablePhases);
|
|
2533
2554
|
const phaseTools = selectPhaseTools(allTools, phase.tools);
|
|
2534
|
-
const phaseSkills =
|
|
2555
|
+
const phaseSkills = mergeSkills(config.context.skills, phase.skills);
|
|
2535
2556
|
const systemPrompt = config.context.systemPrompt;
|
|
2536
2557
|
const phaseContext = {
|
|
2537
2558
|
systemPrompt,
|
|
@@ -2858,6 +2879,14 @@ function isImage(value) {
|
|
|
2858
2879
|
function isUserContent(value) {
|
|
2859
2880
|
return typeof value === "string" || Array.isArray(value) && value.every((part) => isText(part) || isImage(part));
|
|
2860
2881
|
}
|
|
2882
|
+
function isAssistantContent(value) {
|
|
2883
|
+
return typeof value === "string" || Array.isArray(value) && value.every((part) => {
|
|
2884
|
+
if (isText(part)) return true;
|
|
2885
|
+
if (!isRecord3(part)) return false;
|
|
2886
|
+
if (part.type === "thinking") return typeof part.thinking === "string" && (part.signature === void 0 || typeof part.signature === "string");
|
|
2887
|
+
return part.type === "tool_use" && typeof part.toolCallId === "string" && typeof part.name === "string" && isJsonValue(part.input);
|
|
2888
|
+
});
|
|
2889
|
+
}
|
|
2861
2890
|
function normalizeUserInput(input) {
|
|
2862
2891
|
const normalized = typeof input === "string" ? { content: input } : input;
|
|
2863
2892
|
if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata"]) || !isUserContent(normalized.content)) throw new TypeError("input must contain only valid UserContent");
|
|
@@ -2865,6 +2894,9 @@ function normalizeUserInput(input) {
|
|
|
2865
2894
|
assertJsonValue(normalized, "input");
|
|
2866
2895
|
return normalized;
|
|
2867
2896
|
}
|
|
2897
|
+
function isAssistantMessage(value) {
|
|
2898
|
+
return isRecord3(value) && hasOnlyKeys(value, ["id", "agentId", "runId", "role", "content", "metadata", "sequenceWithinRun", "createdAt", "interrupted"]) && typeof value.id === "string" && typeof value.agentId === "string" && typeof value.runId === "string" && value.role === "assistant" && 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");
|
|
2899
|
+
}
|
|
2868
2900
|
function isToolResult(value) {
|
|
2869
2901
|
if (!isRecord3(value) || !isJsonValue(value.content) || typeof value.ok !== "boolean") return false;
|
|
2870
2902
|
const expected = value.ok ? ["content", "ok"] : ["content", "error", "ok"];
|
|
@@ -3013,6 +3045,9 @@ function snapshotConfig(config) {
|
|
|
3013
3045
|
...config.definition,
|
|
3014
3046
|
...config.definition.tools ? { tools: Object.freeze([...config.definition.tools]) } : {},
|
|
3015
3047
|
...config.definition.skills ? { skills: Object.freeze([...config.definition.skills]) } : {},
|
|
3048
|
+
...config.definition.bundledSkills ? {
|
|
3049
|
+
bundledSkills: Object.freeze(config.definition.bundledSkills.map((skill) => Object.freeze({ ...skill })))
|
|
3050
|
+
} : {},
|
|
3016
3051
|
...config.definition.phases ? {
|
|
3017
3052
|
phases: Object.freeze({
|
|
3018
3053
|
entryPhaseId: config.definition.phases.entryPhaseId,
|
|
@@ -3378,18 +3413,23 @@ function projectModelContext(input) {
|
|
|
3378
3413
|
...input.context.phases ? { phases: input.context.phases } : {}
|
|
3379
3414
|
};
|
|
3380
3415
|
}
|
|
3381
|
-
function projectAssistantMessage(message, agentId, runId, sequenceWithinRun) {
|
|
3416
|
+
function projectAssistantMessage(message, agentId, runId, sequenceWithinRun, options = {}) {
|
|
3382
3417
|
return {
|
|
3383
3418
|
id: message.id,
|
|
3384
3419
|
agentId,
|
|
3385
3420
|
runId,
|
|
3386
3421
|
role: "assistant",
|
|
3387
|
-
content: durableAssistantContent(message.content),
|
|
3422
|
+
content: options.interrupted ? durableInterruptedAssistantContent(message.content) : durableAssistantContent(message.content),
|
|
3388
3423
|
sequenceWithinRun,
|
|
3389
3424
|
createdAt: message.createdAt,
|
|
3390
|
-
...message.metadata ? { metadata: message.metadata } : {}
|
|
3425
|
+
...message.metadata ? { metadata: message.metadata } : {},
|
|
3426
|
+
...options.interrupted ? { interrupted: true } : {}
|
|
3391
3427
|
};
|
|
3392
3428
|
}
|
|
3429
|
+
function durableInterruptedAssistantContent(content) {
|
|
3430
|
+
if (typeof content === "string") return content;
|
|
3431
|
+
return content.filter((part) => part.type === "text").map((part) => ({ type: "text", text: part.text }));
|
|
3432
|
+
}
|
|
3393
3433
|
function projectMessage(message) {
|
|
3394
3434
|
switch (message.role) {
|
|
3395
3435
|
case "user":
|
|
@@ -3491,10 +3531,9 @@ function resolveDefinitionContext(config, assembled = {}) {
|
|
|
3491
3531
|
config.definition.tools,
|
|
3492
3532
|
"Tool"
|
|
3493
3533
|
);
|
|
3494
|
-
const skills =
|
|
3495
|
-
config.resources.skills,
|
|
3496
|
-
config.definition.
|
|
3497
|
-
"Skill"
|
|
3534
|
+
const skills = mergeSkills(
|
|
3535
|
+
selectNamedResources(config.resources.skills, config.definition.skills, "Skill"),
|
|
3536
|
+
config.definition.bundledSkills
|
|
3498
3537
|
);
|
|
3499
3538
|
const contexts = selectNamedResources(
|
|
3500
3539
|
config.resources.contexts ?? [],
|
|
@@ -4688,6 +4727,13 @@ var ResourceRegistry = class {
|
|
|
4688
4727
|
}
|
|
4689
4728
|
};
|
|
4690
4729
|
function snapshotResourceValue(kind, value) {
|
|
4730
|
+
if (kind === "agent") {
|
|
4731
|
+
const agent = value;
|
|
4732
|
+
return Object.freeze({
|
|
4733
|
+
...agent,
|
|
4734
|
+
...agent.bundledSkills ? { bundledSkills: Object.freeze(agent.bundledSkills.map((skill) => Object.freeze({ ...skill }))) } : {}
|
|
4735
|
+
});
|
|
4736
|
+
}
|
|
4691
4737
|
if (kind !== "phase") return value;
|
|
4692
4738
|
const phase = value;
|
|
4693
4739
|
const snapshot = {
|
|
@@ -4961,7 +5007,10 @@ function resolveConfigurationSnapshot(registry, input) {
|
|
|
4961
5007
|
const layer = input.definition.layer;
|
|
4962
5008
|
const definition = applyDefinitionLayer(base, layer);
|
|
4963
5009
|
const tools = selectNamedResources(resolved.tools, definition.tools, "Tool");
|
|
4964
|
-
const skills =
|
|
5010
|
+
const skills = mergeSkills(
|
|
5011
|
+
selectNamedResources(resolved.skills, definition.skills, "Skill"),
|
|
5012
|
+
definition.bundledSkills
|
|
5013
|
+
);
|
|
4965
5014
|
const phases = resolvePhases(resolved.phases, definition.phases);
|
|
4966
5015
|
const contexts = selectNamedResources(input.contexts ?? [], base.contexts, "Context");
|
|
4967
5016
|
return {
|
|
@@ -5070,6 +5119,9 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5070
5119
|
storeIncarnation;
|
|
5071
5120
|
activeAgents = /* @__PURE__ */ new Set();
|
|
5072
5121
|
executions = /* @__PURE__ */ new Map();
|
|
5122
|
+
executionDone = /* @__PURE__ */ new Map();
|
|
5123
|
+
cancellationRequested = /* @__PURE__ */ new Set();
|
|
5124
|
+
cancellationReasons = /* @__PURE__ */ new Map();
|
|
5073
5125
|
consumers = /* @__PURE__ */ new Map();
|
|
5074
5126
|
transientEvents = new TransientRunEventHub();
|
|
5075
5127
|
resources;
|
|
@@ -5134,6 +5186,16 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5134
5186
|
this.assertOpen();
|
|
5135
5187
|
await this.commands.updateAgentConfig({ agentId, config, idempotencyKey: options.idempotencyKey });
|
|
5136
5188
|
}
|
|
5189
|
+
async deleteAgent(input) {
|
|
5190
|
+
this.assertOpen();
|
|
5191
|
+
const runs = await this.owned.listRuns({ agentId: input.agentId });
|
|
5192
|
+
for (const run of runs) {
|
|
5193
|
+
if (["queued", "running", "input_required"].includes(run.state)) {
|
|
5194
|
+
await this.cancel(run.id, "Conversation deleted.");
|
|
5195
|
+
}
|
|
5196
|
+
}
|
|
5197
|
+
await this.owned.deleteAgent(input);
|
|
5198
|
+
}
|
|
5137
5199
|
async start(agentId, input, options) {
|
|
5138
5200
|
this.assertOpen();
|
|
5139
5201
|
const agent = await this.requireAgent(agentId);
|
|
@@ -5198,6 +5260,14 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5198
5260
|
}
|
|
5199
5261
|
async cancel(runId, reason) {
|
|
5200
5262
|
this.assertOpen();
|
|
5263
|
+
const done = this.executionDone.get(runId);
|
|
5264
|
+
if (done) {
|
|
5265
|
+
this.cancellationRequested.add(runId);
|
|
5266
|
+
this.cancellationReasons.set(runId, reason ?? "Agent run stopped.");
|
|
5267
|
+
this.executions.get(runId)?.controller.abort();
|
|
5268
|
+
await done;
|
|
5269
|
+
return boundaryFromSnapshot(await this.owned.snapshotRun(runId));
|
|
5270
|
+
}
|
|
5201
5271
|
const snapshot = await this.owned.snapshotRun(runId);
|
|
5202
5272
|
await this.owned.cancelRun({ runId, expectedRevision: snapshot.revision, ...reason === void 0 ? {} : { reason } });
|
|
5203
5273
|
const active = this.executions.get(runId);
|
|
@@ -5219,8 +5289,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5219
5289
|
if (execution) this.transientEvents.clear(next.id, execution.executionId);
|
|
5220
5290
|
this.activeAgents.delete(next.agentId);
|
|
5221
5291
|
this.executions.delete(next.id);
|
|
5292
|
+
this.cancellationRequested.delete(next.id);
|
|
5293
|
+
this.cancellationReasons.delete(next.id);
|
|
5294
|
+
this.executionDone.delete(next.id);
|
|
5222
5295
|
void this.pump();
|
|
5223
5296
|
});
|
|
5297
|
+
this.executionDone.set(next.id, task);
|
|
5224
5298
|
void task;
|
|
5225
5299
|
}
|
|
5226
5300
|
} catch (error) {
|
|
@@ -5278,6 +5352,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5278
5352
|
executionRevision = claim.run.revision;
|
|
5279
5353
|
const controller = new AbortController();
|
|
5280
5354
|
this.executions.set(run.id, { controller, executionId });
|
|
5355
|
+
if (this.cancellationRequested.has(run.id)) controller.abort();
|
|
5281
5356
|
const config = resolvedConfig;
|
|
5282
5357
|
const assembly = assembleRegisteredExtensions(config, this.resources.extensionRunner);
|
|
5283
5358
|
let toolQueue = Promise.resolve();
|
|
@@ -5366,6 +5441,18 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5366
5441
|
}
|
|
5367
5442
|
}
|
|
5368
5443
|
});
|
|
5444
|
+
if (this.cancellationRequested.has(run.id) || controller.signal.aborted) {
|
|
5445
|
+
const output = latestAssistant(run, result.messages, claim.history.length, true);
|
|
5446
|
+
const reason = this.cancellationReasons.get(run.id) ?? "Agent run stopped.";
|
|
5447
|
+
await this.owned.cancelRun({
|
|
5448
|
+
runId: run.id,
|
|
5449
|
+
expectedRevision: executionRevision,
|
|
5450
|
+
reason,
|
|
5451
|
+
...output && hasVisibleAssistantText(output) ? { output } : {}
|
|
5452
|
+
});
|
|
5453
|
+
this.transientEvents.clear(run.id, claim.execution.executionId);
|
|
5454
|
+
return;
|
|
5455
|
+
}
|
|
5369
5456
|
if (result.type === "input_required") {
|
|
5370
5457
|
const prompt = promptMessage(run, result.request.prompt, result.messages.length);
|
|
5371
5458
|
await this.owned.commitInputRequired({ runId: run.id, execution: claim.execution, expectedRevision: executionRevision, requestId: createId("input"), phase: result.request.phase, prompt, checkpoint: result.checkpoint });
|
|
@@ -5384,6 +5471,14 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
5384
5471
|
} catch (error) {
|
|
5385
5472
|
if (!claim && error instanceof RuntimeError && ["run_state_conflict", "runtime_ownership_lost", "run_not_found"].includes(error.code)) return;
|
|
5386
5473
|
if (claim) {
|
|
5474
|
+
if (this.cancellationRequested.has(run.id)) {
|
|
5475
|
+
await this.owned.cancelRun({
|
|
5476
|
+
runId: run.id,
|
|
5477
|
+
expectedRevision: executionRevision,
|
|
5478
|
+
reason: this.cancellationReasons.get(run.id) ?? "Agent run stopped."
|
|
5479
|
+
}).catch(() => void 0);
|
|
5480
|
+
return;
|
|
5481
|
+
}
|
|
5387
5482
|
await this.owned.commitOutcome({
|
|
5388
5483
|
runId: run.id,
|
|
5389
5484
|
execution: claim.execution,
|
|
@@ -5630,10 +5725,13 @@ var DurableRun = class {
|
|
|
5630
5725
|
function promptMessage(run, prompt, sequence) {
|
|
5631
5726
|
return { id: createId("msg"), agentId: run.agentId, runId: run.id, role: "assistant", content: prompt, sequenceWithinRun: sequence, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
5632
5727
|
}
|
|
5633
|
-
function latestAssistant(run, messages, sequence) {
|
|
5728
|
+
function latestAssistant(run, messages, sequence, interrupted = false) {
|
|
5634
5729
|
const message = [...messages].reverse().find((candidate) => candidate.role === "assistant");
|
|
5635
5730
|
if (!message) return void 0;
|
|
5636
|
-
return projectAssistantMessage(message, run.agentId, run.id, sequence);
|
|
5731
|
+
return projectAssistantMessage(message, run.agentId, run.id, sequence, { interrupted });
|
|
5732
|
+
}
|
|
5733
|
+
function hasVisibleAssistantText(message) {
|
|
5734
|
+
return typeof message.content === "string" ? message.content.length > 0 : message.content.some((part) => part.type === "text" && part.text.length > 0);
|
|
5637
5735
|
}
|
|
5638
5736
|
function durableOutcome(outcome) {
|
|
5639
5737
|
return {
|
|
@@ -5857,6 +5955,43 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
5857
5955
|
this.writeReceipt(scope, payload, agent);
|
|
5858
5956
|
return clone(agent);
|
|
5859
5957
|
}
|
|
5958
|
+
deleteAgent(lease, input) {
|
|
5959
|
+
this.assertOwner(lease);
|
|
5960
|
+
if (input.confirmation !== "conversation-delete-v1") {
|
|
5961
|
+
throw new TypeError("Agent deletion requires the conversation deletion confirmation token");
|
|
5962
|
+
}
|
|
5963
|
+
const agent = this.requireAgent(input.agentId);
|
|
5964
|
+
const runs = [...this.runs.values()].filter((run) => run.agentId === agent.id);
|
|
5965
|
+
const expected = new Set(input.expectedRunIds.map(String));
|
|
5966
|
+
const actual = new Set(runs.map((run) => String(run.id)));
|
|
5967
|
+
if (expected.size !== actual.size || [...actual].some((runId) => !expected.has(runId))) {
|
|
5968
|
+
throw new RuntimeError("run_state_conflict", {
|
|
5969
|
+
runId: runs[0]?.id ?? input.expectedRunIds[0] ?? "unknown",
|
|
5970
|
+
expected: [],
|
|
5971
|
+
actual: "cancelled"
|
|
5972
|
+
});
|
|
5973
|
+
}
|
|
5974
|
+
const runIds = new Set(runs.map((run) => run.id));
|
|
5975
|
+
this.agents.delete(agent.id);
|
|
5976
|
+
this.nextAgentSequence.delete(agent.id);
|
|
5977
|
+
this.nextReadySequence.delete(agent.id);
|
|
5978
|
+
for (const run of runs) this.runs.delete(run.id);
|
|
5979
|
+
for (const [messageId, message] of this.messages) {
|
|
5980
|
+
if (runIds.has(message.runId)) this.messages.delete(messageId);
|
|
5981
|
+
}
|
|
5982
|
+
for (const [toolCallId, toolCall] of this.toolCalls) {
|
|
5983
|
+
if (runIds.has(toolCall.runId)) this.toolCalls.delete(toolCallId);
|
|
5984
|
+
}
|
|
5985
|
+
for (let index = this.events.length - 1; index >= 0; index -= 1) {
|
|
5986
|
+
if (this.events[index].agentId === agent.id) this.events.splice(index, 1);
|
|
5987
|
+
}
|
|
5988
|
+
for (const [key] of this.idempotency) {
|
|
5989
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) this.idempotency.delete(key);
|
|
5990
|
+
}
|
|
5991
|
+
for (const [key] of this.operationReceipts) {
|
|
5992
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) this.operationReceipts.delete(key);
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5860
5995
|
createRun(lease, input) {
|
|
5861
5996
|
this.assertOwner(lease);
|
|
5862
5997
|
this.requireAgent(input.agentId);
|
|
@@ -6225,11 +6360,16 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
6225
6360
|
cancelRun(lease, input) {
|
|
6226
6361
|
this.assertOwner(lease);
|
|
6227
6362
|
const operationKey = `cancel:${input.runId}:${input.expectedRevision ?? "current"}`;
|
|
6228
|
-
const operationPayload = canonicalJson(input.reason ?? null);
|
|
6363
|
+
const operationPayload = canonicalJson([input.reason ?? null, input.output ?? null]);
|
|
6229
6364
|
const replay = this.replayOperation(operationKey, operationPayload);
|
|
6230
6365
|
if (replay) return clone(replay);
|
|
6231
6366
|
const run = this.requireRun(input.runId);
|
|
6232
6367
|
if (input.expectedRevision !== void 0) this.assertRevision(run, input.expectedRevision);
|
|
6368
|
+
if (input.output !== void 0) {
|
|
6369
|
+
if (!isAssistantMessage(input.output) || input.output.agentId !== run.agentId || input.output.runId !== run.id || input.output.interrupted !== true) {
|
|
6370
|
+
throw new TypeError("cancelled output must be an interrupted AssistantMessage from this Run");
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6233
6373
|
if (["completed", "failed", "cancelled"].includes(run.state)) {
|
|
6234
6374
|
const result2 = clone(run);
|
|
6235
6375
|
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
|
|
@@ -6239,6 +6379,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
6239
6379
|
const activeToolCalls = run.execution ? [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "running")) : [];
|
|
6240
6380
|
const indeterminateToolCallIds = activeToolCalls.filter((toolCall) => toolCall.state === "running").map((toolCall) => toolCall.id);
|
|
6241
6381
|
for (const toolCall of activeToolCalls) this.interruptToolCall(run, toolCall, input.reason ?? "The Run was cancelled.");
|
|
6382
|
+
if (input.output && (typeof input.output.content === "string" ? input.output.content.length > 0 : input.output.content.length > 0)) {
|
|
6383
|
+
const output = { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) };
|
|
6384
|
+
this.messages.set(output.id, output);
|
|
6385
|
+
this.appendMessage(run, output);
|
|
6386
|
+
}
|
|
6242
6387
|
if (indeterminateToolCallIds.length > 0) {
|
|
6243
6388
|
const failure = {
|
|
6244
6389
|
code: "tool_indeterminate",
|
|
@@ -6502,6 +6647,9 @@ var MemoryOwnedStore = class {
|
|
|
6502
6647
|
async updateAgentConfigToken(input) {
|
|
6503
6648
|
return this.store.updateAgentConfigToken(this.lease, input);
|
|
6504
6649
|
}
|
|
6650
|
+
async deleteAgent(input) {
|
|
6651
|
+
this.store.deleteAgent(this.lease, input);
|
|
6652
|
+
}
|
|
6505
6653
|
async createRun(input) {
|
|
6506
6654
|
return this.store.createRun(this.lease, input);
|
|
6507
6655
|
}
|
|
@@ -6758,6 +6906,9 @@ var SqliteStore = class {
|
|
|
6758
6906
|
async updateAgentConfigToken(lease, input) {
|
|
6759
6907
|
return this.invoke(lease, (store, current) => store.updateAgentConfigToken(current, input));
|
|
6760
6908
|
}
|
|
6909
|
+
async deleteAgent(lease, input) {
|
|
6910
|
+
return this.invoke(lease, (store, current) => store.deleteAgent(current, input));
|
|
6911
|
+
}
|
|
6761
6912
|
async createRun(lease, input) {
|
|
6762
6913
|
return this.invoke(lease, (store, current) => store.createRun(current, input));
|
|
6763
6914
|
}
|
|
@@ -6819,9 +6970,9 @@ var SqliteStore = class {
|
|
|
6819
6970
|
if (after === waterline) return [];
|
|
6820
6971
|
}
|
|
6821
6972
|
const rows = this.database.query(
|
|
6822
|
-
"SELECT payload_json FROM run_events ORDER BY sequence
|
|
6823
|
-
).all(
|
|
6824
|
-
return rows.map((row) => JSON.parse(row.payload_json));
|
|
6973
|
+
"SELECT payload_json FROM run_events ORDER BY sequence"
|
|
6974
|
+
).all();
|
|
6975
|
+
return rows.map((row) => JSON.parse(row.payload_json)).filter((event) => parseEventCursor(lease, event.cursor) > after);
|
|
6825
6976
|
});
|
|
6826
6977
|
}
|
|
6827
6978
|
async openConsumer(lease, consumerId) {
|
|
@@ -7045,6 +7196,9 @@ var SqliteOwnedStore = class {
|
|
|
7045
7196
|
updateAgentConfigToken(input) {
|
|
7046
7197
|
return this.store.updateAgentConfigToken(this.lease, input);
|
|
7047
7198
|
}
|
|
7199
|
+
deleteAgent(input) {
|
|
7200
|
+
return this.store.deleteAgent(this.lease, input);
|
|
7201
|
+
}
|
|
7048
7202
|
createRun(input) {
|
|
7049
7203
|
return this.store.createRun(this.lease, input);
|
|
7050
7204
|
}
|