@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 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 = phase.name === DEFAULT_PHASE_ID ? config.context.skills : phase.skills ?? [];
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 = phase.name === DEFAULT_PHASE_ID ? config.context.skills : phase.skills ?? [];
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 = selectNamedResources(
3495
- config.resources.skills,
3496
- config.definition.skills,
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 = selectNamedResources(resolved.skills, definition.skills, "Skill");
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 LIMIT -1 OFFSET ?"
6823
- ).all(after);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowan-agent/agent",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",