@rowan-agent/agent 0.9.2 → 0.9.4

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
@@ -778,6 +778,8 @@ type MessageBase = Readonly<{
778
778
  id: MessageId;
779
779
  agentId: AgentId;
780
780
  runId: RunId;
781
+ /** Monotonic active revision. Omitted on legacy/initial messages and read as 0. */
782
+ messageRevision?: number;
781
783
  metadata?: Metadata;
782
784
  sequenceWithinRun: number;
783
785
  createdAt: string;
@@ -789,6 +791,7 @@ type UserMessage = MessageBase & Readonly<{
789
791
  type AssistantMessage = MessageBase & Readonly<{
790
792
  role: "assistant";
791
793
  content: AssistantContent;
794
+ interrupted?: boolean;
792
795
  }>;
793
796
  type ToolMessage = MessageBase & Readonly<{
794
797
  role: "tool";
@@ -887,6 +890,14 @@ type MessageCommitted = DurableEventBase & Readonly<{
887
890
  kind: "message_committed";
888
891
  message: Message;
889
892
  }>;
893
+ type MessageRevised = DurableEventBase & Readonly<{
894
+ kind: "message_revised";
895
+ message: UserMessage;
896
+ previousRevision: number;
897
+ invalidatedRunIds: readonly RunId[];
898
+ targetRunId: RunId;
899
+ cutoffSequenceWithinRun: number;
900
+ }>;
890
901
  type RunStateChanged = DurableEventBase & (Readonly<{
891
902
  kind: "run_state_changed";
892
903
  from: null;
@@ -985,7 +996,7 @@ type ToolStateChanged = DurableEventBase & (Readonly<{
985
996
  state: "indeterminate";
986
997
  }>;
987
998
  }>);
988
- type DurableRunEvent = MessageCommitted | RunStateChanged | ToolStateChanged;
999
+ type DurableRunEvent = MessageCommitted | MessageRevised | RunStateChanged | ToolStateChanged;
989
1000
  type MessageDelta = Readonly<{
990
1001
  kind: "message_delta";
991
1002
  durability: "transient";
@@ -1264,6 +1275,7 @@ type UserInput = string | Readonly<{
1264
1275
  content: UserContent;
1265
1276
  metadata?: Metadata;
1266
1277
  }>;
1278
+ type HistorySeed = readonly Message[];
1267
1279
  type ToolInvocationContext = Readonly<{
1268
1280
  agentId: AgentId;
1269
1281
  runId: RunId;
@@ -1342,6 +1354,11 @@ type AgentRecord = Readonly<{
1342
1354
  activatedAt?: string;
1343
1355
  updatedAt: string;
1344
1356
  }>;
1357
+ type AgentDeletionRequest = Readonly<{
1358
+ agentId: AgentId;
1359
+ expectedRunIds: readonly RunId[];
1360
+ confirmation: "conversation-delete-v1";
1361
+ }>;
1345
1362
  type ExecutionToken = Readonly<{
1346
1363
  runId: RunId;
1347
1364
  ownerEpoch: number;
@@ -1396,6 +1413,11 @@ type RunRecord = Readonly<{
1396
1413
  revision: number;
1397
1414
  state: RunState;
1398
1415
  input: UserInput;
1416
+ initialMessageId?: MessageId;
1417
+ invalidatedBy?: Readonly<{
1418
+ messageId: MessageId;
1419
+ messageRevision: number;
1420
+ }>;
1399
1421
  metadata?: Metadata;
1400
1422
  pinnedConfigToken?: ConfigToken;
1401
1423
  checkpoint?: ExecutionCheckpoint;
@@ -1407,6 +1429,22 @@ type RunRecord = Readonly<{
1407
1429
  createdAt: string;
1408
1430
  updatedAt: string;
1409
1431
  }>;
1432
+ type MessageRevisionResult = Readonly<{
1433
+ message: UserMessage & Readonly<{
1434
+ messageRevision: number;
1435
+ }>;
1436
+ replacementRun: RunRecord;
1437
+ invalidatedRunIds: readonly RunId[];
1438
+ affectedToolCallIds: readonly ToolCallId[];
1439
+ effectDigest?: string;
1440
+ }>;
1441
+ type RetentionResult = Readonly<{
1442
+ deletedRunIds: readonly RunId[];
1443
+ deletedToolCallIds: readonly ToolCallId[];
1444
+ deletedEventCount: number;
1445
+ retentionFloor: EventCursor;
1446
+ skipped?: "active_consumers" | "no_eligible_events";
1447
+ }>;
1410
1448
  type AgentSummary = Readonly<{
1411
1449
  id: AgentId;
1412
1450
  metadata?: Metadata;
@@ -1514,6 +1552,7 @@ interface OwnedStore {
1514
1552
  idempotencyKey: string;
1515
1553
  metadata?: Metadata;
1516
1554
  configIdentity?: string;
1555
+ historySeed?: HistorySeed;
1517
1556
  }): Promise<AgentRecord>;
1518
1557
  activateAgent(agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1519
1558
  updateAgentConfigToken(input: {
@@ -1522,6 +1561,19 @@ interface OwnedStore {
1522
1561
  configIdentity?: string;
1523
1562
  idempotencyKey: string;
1524
1563
  }): Promise<AgentRecord>;
1564
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1565
+ reviseMessage(input: {
1566
+ agentId: AgentId;
1567
+ messageId: MessageId;
1568
+ expectedMessageRevision: number;
1569
+ content: UserContent;
1570
+ operationId: string;
1571
+ effectDigestConfirmation?: string;
1572
+ }): Promise<MessageRevisionResult>;
1573
+ compact(input?: {
1574
+ now?: string;
1575
+ retentionMs?: number;
1576
+ }): Promise<RetentionResult>;
1525
1577
  createRun(input: {
1526
1578
  agentId: AgentId;
1527
1579
  input: UserInput;
@@ -1600,8 +1652,10 @@ interface OwnedStore {
1600
1652
  runId: RunId;
1601
1653
  expectedRevision?: number;
1602
1654
  reason?: string;
1655
+ output?: AssistantMessage;
1603
1656
  }): Promise<RunRecord>;
1604
1657
  snapshotRun(runId: RunId): Promise<RunSnapshot>;
1658
+ history(agentId: AgentId): Promise<readonly Message[]>;
1605
1659
  listAgents(): Promise<readonly AgentRecord[]>;
1606
1660
  listRuns(input?: {
1607
1661
  agentId?: AgentId;
@@ -1666,15 +1720,29 @@ interface AgentRuntime$1 {
1666
1720
  createAgent(config: AgentConfigRequest, options?: {
1667
1721
  idempotencyKey?: string;
1668
1722
  metadata?: Metadata;
1723
+ historySeed?: HistorySeed;
1669
1724
  }): Promise<AgentId>;
1670
1725
  updateAgentConfig(agentId: AgentId, config: AgentConfigRequest, options: {
1671
1726
  idempotencyKey: string;
1672
1727
  }): Promise<void>;
1728
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1729
+ revise(agentId: AgentId, input: {
1730
+ messageId: MessageId;
1731
+ expectedMessageRevision: number;
1732
+ content: UserContent;
1733
+ operationId: string;
1734
+ effectDigestConfirmation?: string;
1735
+ }): Promise<MessageRevisionResult>;
1736
+ compact(input?: {
1737
+ now?: string;
1738
+ retentionMs?: number;
1739
+ }): Promise<RetentionResult>;
1673
1740
  start(agentId: AgentId, input: UserInput, options: {
1674
1741
  idempotencyKey: string;
1675
1742
  metadata?: Metadata;
1676
1743
  }): Promise<AgentRun>;
1677
1744
  run(runId: RunId): AgentRun;
1745
+ history(agentId: AgentId): Promise<readonly Message[]>;
1678
1746
  listAgents(input?: {
1679
1747
  after?: AgentListCursor;
1680
1748
  limit?: number;
@@ -1706,6 +1774,9 @@ declare class AgentRuntime implements AgentRuntime$1 {
1706
1774
  private readonly storeIncarnation;
1707
1775
  private readonly activeAgents;
1708
1776
  private readonly executions;
1777
+ private readonly executionDone;
1778
+ private readonly cancellationRequested;
1779
+ private readonly cancellationReasons;
1709
1780
  private readonly consumers;
1710
1781
  private readonly transientEvents;
1711
1782
  private readonly resources;
@@ -1728,10 +1799,29 @@ declare class AgentRuntime implements AgentRuntime$1 {
1728
1799
  createAgent(config: AgentConfigRequest, options?: {
1729
1800
  idempotencyKey?: string;
1730
1801
  metadata?: Metadata;
1802
+ historySeed?: HistorySeed;
1731
1803
  }): Promise<AgentId>;
1732
1804
  updateAgentConfig(agentId: AgentId, config: AgentConfigRequest, options: {
1733
1805
  idempotencyKey: string;
1734
1806
  }): Promise<void>;
1807
+ deleteAgent(input: AgentDeletionRequest): Promise<void>;
1808
+ revise(agentId: AgentId, input: {
1809
+ messageId: MessageId;
1810
+ expectedMessageRevision: number;
1811
+ content: UserContent;
1812
+ operationId: string;
1813
+ effectDigestConfirmation?: string;
1814
+ }): Promise<MessageRevisionResult>;
1815
+ compact(input?: {
1816
+ now?: string;
1817
+ retentionMs?: number;
1818
+ }): Promise<Readonly<{
1819
+ deletedRunIds: readonly RunId[];
1820
+ deletedToolCallIds: readonly ToolCallId[];
1821
+ deletedEventCount: number;
1822
+ retentionFloor: EventCursor;
1823
+ skipped?: "active_consumers" | "no_eligible_events";
1824
+ }>>;
1735
1825
  start(agentId: AgentId, input: UserInput, options: {
1736
1826
  idempotencyKey: string;
1737
1827
  metadata?: Metadata;
@@ -1756,6 +1846,7 @@ declare class AgentRuntime implements AgentRuntime$1 {
1756
1846
  }): Promise<DurableConsumer>;
1757
1847
  close(): Promise<void>;
1758
1848
  snapshot(runId: RunId): Promise<RunSnapshot>;
1849
+ history(agentId: AgentId): Promise<readonly Message[]>;
1759
1850
  respond(runId: RunId, input: {
1760
1851
  requestId: InputRequestId;
1761
1852
  input: UserInput;
@@ -1794,7 +1885,9 @@ type InMemoryStoreState = Readonly<{
1794
1885
  events: readonly DurableRunEvent[];
1795
1886
  idempotency: readonly (readonly [string, IdempotencyReceipt])[];
1796
1887
  operationReceipts: readonly (readonly [string, IdempotencyReceipt])[];
1888
+ historySeeds?: readonly (readonly [AgentId, readonly Message[]])[];
1797
1889
  consumerCheckpoints: readonly (readonly [string, EventCursor])[];
1890
+ retentionFloor?: number;
1798
1891
  nextAgentSequence: readonly (readonly [AgentId, number])[];
1799
1892
  nextReadySequence: readonly (readonly [AgentId, number])[];
1800
1893
  eventSequence: number;
@@ -1808,12 +1901,14 @@ declare class InMemoryStore implements DurableStore {
1808
1901
  private readonly events;
1809
1902
  private readonly idempotency;
1810
1903
  private readonly operationReceipts;
1904
+ private readonly historySeeds;
1811
1905
  private readonly consumerCheckpoints;
1812
1906
  private readonly nextAgentSequence;
1813
1907
  private readonly nextReadySequence;
1814
1908
  private owner?;
1815
1909
  private ownerEpoch;
1816
1910
  private eventSequence;
1911
+ private retentionFloor;
1817
1912
  constructor(options?: {
1818
1913
  incarnation?: string;
1819
1914
  });
@@ -1832,6 +1927,7 @@ declare class InMemoryStore implements DurableStore {
1832
1927
  idempotencyKey: string;
1833
1928
  metadata?: Metadata;
1834
1929
  configIdentity?: string;
1930
+ historySeed?: HistorySeed;
1835
1931
  }): AgentRecord;
1836
1932
  activateAgent(lease: OwnerLease, agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): AgentRecord;
1837
1933
  updateAgentConfigToken(lease: OwnerLease, input: {
@@ -1840,6 +1936,15 @@ declare class InMemoryStore implements DurableStore {
1840
1936
  configIdentity?: string;
1841
1937
  idempotencyKey: string;
1842
1938
  }): AgentRecord;
1939
+ deleteAgent(lease: OwnerLease, input: AgentDeletionRequest): void;
1940
+ reviseMessage(lease: OwnerLease, input: {
1941
+ agentId: AgentId;
1942
+ messageId: MessageId;
1943
+ expectedMessageRevision: number;
1944
+ content: UserContent;
1945
+ operationId: string;
1946
+ effectDigestConfirmation?: string;
1947
+ }): MessageRevisionResult;
1843
1948
  createRun(lease: OwnerLease, input: {
1844
1949
  agentId: AgentId;
1845
1950
  input: UserInput;
@@ -1925,6 +2030,7 @@ declare class InMemoryStore implements DurableStore {
1925
2030
  runId: RunId;
1926
2031
  expectedRevision?: number;
1927
2032
  reason?: string;
2033
+ output?: AssistantMessage;
1928
2034
  }): RunRecord;
1929
2035
  snapshotRun(lease: OwnerLease, runId: RunId): RunSnapshot;
1930
2036
  listAgents(lease: OwnerLease): readonly AgentRecord[];
@@ -1940,6 +2046,10 @@ declare class InMemoryStore implements DurableStore {
1940
2046
  consumerId: string;
1941
2047
  cursor: EventCursor;
1942
2048
  }): void;
2049
+ compact(lease: OwnerLease, input?: {
2050
+ now?: string;
2051
+ retentionMs?: number;
2052
+ }): RetentionResult;
1943
2053
  private replay;
1944
2054
  private writeReceipt;
1945
2055
  private replayOperation;
@@ -1956,7 +2066,8 @@ declare class InMemoryStore implements DurableStore {
1956
2066
  private nextReady;
1957
2067
  private nextMessageSequence;
1958
2068
  private messagesForRun;
1959
- private history;
2069
+ history(lease: OwnerLease, agentId: AgentId): readonly Message[];
2070
+ private activeHistory;
1960
2071
  private appendMessage;
1961
2072
  private appendTransition;
1962
2073
  private appendToolTransition;
@@ -1979,6 +2090,7 @@ declare class SqliteStore implements DurableStore {
1979
2090
  idempotencyKey: string;
1980
2091
  metadata?: Metadata;
1981
2092
  configIdentity?: string;
2093
+ historySeed?: HistorySeed;
1982
2094
  }): Promise<AgentRecord>;
1983
2095
  activateAgent(lease: OwnerLease, agentId: AgentId, configToken?: ConfigToken, configIdentity?: string): Promise<AgentRecord>;
1984
2096
  updateAgentConfigToken(lease: OwnerLease, input: {
@@ -1987,6 +2099,15 @@ declare class SqliteStore implements DurableStore {
1987
2099
  configIdentity?: string;
1988
2100
  idempotencyKey: string;
1989
2101
  }): Promise<AgentRecord>;
2102
+ deleteAgent(lease: OwnerLease, input: AgentDeletionRequest): Promise<void>;
2103
+ reviseMessage(lease: OwnerLease, input: {
2104
+ agentId: AgentId;
2105
+ messageId: MessageId;
2106
+ expectedMessageRevision: number;
2107
+ content: UserContent;
2108
+ operationId: string;
2109
+ effectDigestConfirmation?: string;
2110
+ }): Promise<MessageRevisionResult>;
1990
2111
  createRun(lease: OwnerLease, input: {
1991
2112
  agentId: AgentId;
1992
2113
  input: UserInput;
@@ -2072,8 +2193,10 @@ declare class SqliteStore implements DurableStore {
2072
2193
  runId: RunId;
2073
2194
  expectedRevision?: number;
2074
2195
  reason?: string;
2196
+ output?: AssistantMessage;
2075
2197
  }): Promise<RunRecord>;
2076
2198
  snapshotRun(lease: OwnerLease, runId: RunId): Promise<RunSnapshot>;
2199
+ history(lease: OwnerLease, agentId: AgentId): Promise<readonly Message[]>;
2077
2200
  listAgents(lease: OwnerLease): Promise<readonly AgentRecord[]>;
2078
2201
  listRuns(lease: OwnerLease, input?: {
2079
2202
  agentId?: AgentId;
@@ -2087,6 +2210,10 @@ declare class SqliteStore implements DurableStore {
2087
2210
  consumerId: string;
2088
2211
  cursor: EventCursor;
2089
2212
  }): Promise<void>;
2213
+ compact(lease: OwnerLease, input?: {
2214
+ now?: string;
2215
+ retentionMs?: number;
2216
+ }): Promise<RetentionResult>;
2090
2217
  renewOwner(lease: OwnerLease, leaseMs: number): Promise<OwnerLease>;
2091
2218
  sealAndReleaseOwner(lease: OwnerLease): Promise<void>;
2092
2219
  private invoke;
@@ -2125,7 +2252,7 @@ declare class InMemoryConfigProvider implements ConfigProvider {
2125
2252
  }
2126
2253
  declare function brandConfigToken(raw: unknown): ConfigToken;
2127
2254
 
2128
- type RuntimeErrorCode = "invalid_argument" | "runtime_closed" | "runtime_already_owned" | "runtime_ownership_lost" | "agent_not_found" | "run_not_found" | "run_state_conflict" | "input_request_conflict" | "idempotency_conflict" | "configuration_unavailable" | "checkpoint_incompatible" | "consumer_already_active" | "invalid_cursor" | "store_unavailable" | "unsupported_store_version";
2255
+ type RuntimeErrorCode = "invalid_argument" | "runtime_closed" | "runtime_already_owned" | "runtime_ownership_lost" | "agent_not_found" | "run_not_found" | "run_state_conflict" | "message_revision_conflict" | "tool_effect_confirmation_required" | "input_request_conflict" | "idempotency_conflict" | "configuration_unavailable" | "checkpoint_incompatible" | "consumer_already_active" | "invalid_cursor" | "store_unavailable" | "unsupported_store_version";
2129
2256
  type RuntimeErrorDetails = {
2130
2257
  invalid_argument: Readonly<{
2131
2258
  argument: string;
@@ -2153,6 +2280,18 @@ type RuntimeErrorDetails = {
2153
2280
  expected: readonly RunState[];
2154
2281
  actual: RunState;
2155
2282
  }>;
2283
+ message_revision_conflict: Readonly<{
2284
+ agentId: AgentId;
2285
+ messageId: MessageId;
2286
+ expected: number;
2287
+ actual: number;
2288
+ }>;
2289
+ tool_effect_confirmation_required: Readonly<{
2290
+ agentId: AgentId;
2291
+ messageId: MessageId;
2292
+ effectDigest: string;
2293
+ toolCallIds: readonly ToolCallId[];
2294
+ }>;
2156
2295
  input_request_conflict: Readonly<{
2157
2296
  runId: RunId;
2158
2297
  requestId: InputRequestId;
@@ -2184,7 +2323,7 @@ type RuntimeErrorDetails = {
2184
2323
  }>;
2185
2324
  invalid_cursor: Readonly<{
2186
2325
  cursorType: "agent_list" | "run_list" | "event";
2187
- reason: "malformed" | "wrong_store" | "wrong_collection" | "filter_mismatch" | "beyond_waterline";
2326
+ reason: "malformed" | "wrong_store" | "wrong_collection" | "filter_mismatch" | "beyond_waterline" | "expired";
2188
2327
  }>;
2189
2328
  store_unavailable: Readonly<{
2190
2329
  operation: string;
@@ -2260,4 +2399,4 @@ declare function parseFrontmatter<T = Record<string, unknown>>(raw: string): Fro
2260
2399
 
2261
2400
  declare function createCoreTools(input?: CoreToolContext): Tool[];
2262
2401
 
2263
- export { type AfterToolCall, type AgentConfig, type AgentConfigRequest, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentResources, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type CoreToolContext, 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 HookEvent, type HookEventType, type HookHandler, InMemoryConfigProvider, InMemoryStore, type InputRequest, type InputRequestId, type InputRequiredCommit, 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 Metadata, type OpaqueId, type Outcome, type OwnerLease, type OwnerToken, type Page, type Phase, type PhaseContext, type PhaseContribution, type PhaseExecutionIdentity, type PhaseInvocation, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseState, type ResolvedResourceView, type ResourceDiagnostic, type ResourceKind, type ResourceRef, ResourceRegistry, ResourceRegistryError, type ResourceRegistryErrorCode, type ResourceSourceId, type ResourceView, 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, type Skill, SqliteStore, type TextContent, type ThinkingContent, type Tool, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCoreTools, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhases, loadSkill, loadSkills, materializeConfigurationSnapshot, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
2402
+ export { type AfterToolCall, type AgentConfig, type AgentConfigRequest, type AgentConfiguration, type AgentDefinition, type AgentId, type AgentListCursor, type AgentRecord, type AgentResources, type AgentRun, AgentRuntime, type AgentRuntimeOptions, type AgentSummary, type AnyRuntimeError, type AssistantContent, type AssistantMessage, type BeforeToolCall, type ConfigProvider, type ConfigPutResult, type ConfigResolution, type ConfigToken, type ConfigurationSnapshot, type ContextCandidate, type CoreToolContext, 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 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 PhaseExecutionIdentity, type PhaseInvocation, type PhaseOutput, type PhaseRegistry, type PhaseRegistrySelection, type PhaseState, 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, type Skill, SqliteStore, type TextContent, type ThinkingContent, type Tool, type ToolCallId, type ToolCallSnapshot, type ToolCallState, type ToolContribution, type ToolDefinition, type ToolExecutionResult, type ToolInvocationContext, type ToolMessage, type ToolMessageContent, type ToolProgress, type ToolResultContent, type ToolStateChanged, type ToolUseContent, type UserContent, type UserInput, type UserMessage, brandConfigToken, createCoreTools, isRuntimeError, loadExtensionsFromPath as loadExtensions, loadPhase, loadPhases, loadSkill, loadSkills, materializeConfigurationSnapshot, parseAgentDefinition, parseFrontmatter, resolveConfigurationSnapshot };
package/dist/index.js CHANGED
@@ -2879,6 +2879,14 @@ function isImage(value) {
2879
2879
  function isUserContent(value) {
2880
2880
  return typeof value === "string" || Array.isArray(value) && value.every((part) => isText(part) || isImage(part));
2881
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
+ }
2882
2890
  function normalizeUserInput(input) {
2883
2891
  const normalized = typeof input === "string" ? { content: input } : input;
2884
2892
  if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata"]) || !isUserContent(normalized.content)) throw new TypeError("input must contain only valid UserContent");
@@ -2886,6 +2894,9 @@ function normalizeUserInput(input) {
2886
2894
  assertJsonValue(normalized, "input");
2887
2895
  return normalized;
2888
2896
  }
2897
+ function isAssistantMessage(value) {
2898
+ return isRecord3(value) && hasOnlyKeys(value, ["id", "agentId", "runId", "messageRevision", "role", "content", "metadata", "sequenceWithinRun", "createdAt", "interrupted"]) && typeof value.id === "string" && typeof value.agentId === "string" && typeof value.runId === "string" && value.role === "assistant" && (value.messageRevision === void 0 || Number.isInteger(value.messageRevision) && value.messageRevision >= 0) && Number.isInteger(value.sequenceWithinRun) && value.sequenceWithinRun >= 0 && typeof value.createdAt === "string" && isAssistantContent(value.content) && (value.metadata === void 0 || isMetadata(value.metadata)) && (value.interrupted === void 0 || typeof value.interrupted === "boolean");
2899
+ }
2889
2900
  function isToolResult(value) {
2890
2901
  if (!isRecord3(value) || !isJsonValue(value.content) || typeof value.ok !== "boolean") return false;
2891
2902
  const expected = value.ok ? ["content", "ok"] : ["content", "error", "ok"];
@@ -3182,6 +3193,7 @@ var ConfigCommandService = class {
3182
3193
  const reserved = await this.store.reserveAgent({
3183
3194
  idempotencyKey: input.idempotencyKey,
3184
3195
  ...input.metadata === void 0 ? {} : { metadata: input.metadata },
3196
+ ...input.historySeed === void 0 ? {} : { historySeed: input.historySeed },
3185
3197
  configIdentity: input.config.identity
3186
3198
  });
3187
3199
  if (reserved.activatedAt && reserved.currentConfigToken) return reserved.id;
@@ -3402,18 +3414,23 @@ function projectModelContext(input) {
3402
3414
  ...input.context.phases ? { phases: input.context.phases } : {}
3403
3415
  };
3404
3416
  }
3405
- function projectAssistantMessage(message, agentId, runId, sequenceWithinRun) {
3417
+ function projectAssistantMessage(message, agentId, runId, sequenceWithinRun, options = {}) {
3406
3418
  return {
3407
3419
  id: message.id,
3408
3420
  agentId,
3409
3421
  runId,
3410
3422
  role: "assistant",
3411
- content: durableAssistantContent(message.content),
3423
+ content: options.interrupted ? durableInterruptedAssistantContent(message.content) : durableAssistantContent(message.content),
3412
3424
  sequenceWithinRun,
3413
3425
  createdAt: message.createdAt,
3414
- ...message.metadata ? { metadata: message.metadata } : {}
3426
+ ...message.metadata ? { metadata: message.metadata } : {},
3427
+ ...options.interrupted ? { interrupted: true } : {}
3415
3428
  };
3416
3429
  }
3430
+ function durableInterruptedAssistantContent(content) {
3431
+ if (typeof content === "string") return content;
3432
+ return content.filter((part) => part.type === "text").map((part) => ({ type: "text", text: part.text }));
3433
+ }
3417
3434
  function projectMessage(message) {
3418
3435
  switch (message.role) {
3419
3436
  case "user":
@@ -5103,6 +5120,9 @@ var AgentRuntime = class _AgentRuntime {
5103
5120
  storeIncarnation;
5104
5121
  activeAgents = /* @__PURE__ */ new Set();
5105
5122
  executions = /* @__PURE__ */ new Map();
5123
+ executionDone = /* @__PURE__ */ new Map();
5124
+ cancellationRequested = /* @__PURE__ */ new Set();
5125
+ cancellationReasons = /* @__PURE__ */ new Map();
5106
5126
  consumers = /* @__PURE__ */ new Map();
5107
5127
  transientEvents = new TransientRunEventHub();
5108
5128
  resources;
@@ -5160,6 +5180,7 @@ var AgentRuntime = class _AgentRuntime {
5160
5180
  return this.commands.createAgent({
5161
5181
  config,
5162
5182
  ...options.metadata === void 0 ? {} : { metadata: options.metadata },
5183
+ ...options.historySeed === void 0 ? {} : { historySeed: options.historySeed },
5163
5184
  idempotencyKey: options.idempotencyKey ?? crypto.randomUUID()
5164
5185
  });
5165
5186
  }
@@ -5167,6 +5188,33 @@ var AgentRuntime = class _AgentRuntime {
5167
5188
  this.assertOpen();
5168
5189
  await this.commands.updateAgentConfig({ agentId, config, idempotencyKey: options.idempotencyKey });
5169
5190
  }
5191
+ async deleteAgent(input) {
5192
+ this.assertOpen();
5193
+ const runs = await this.owned.listRuns({ agentId: input.agentId });
5194
+ for (const run of runs) {
5195
+ if (["queued", "running", "input_required"].includes(run.state)) {
5196
+ await this.cancel(run.id, "Conversation deleted.");
5197
+ }
5198
+ }
5199
+ await this.owned.deleteAgent(input);
5200
+ }
5201
+ async revise(agentId, input) {
5202
+ this.assertOpen();
5203
+ const result = await this.owned.reviseMessage({ agentId, ...input });
5204
+ for (const runId of result.invalidatedRunIds) {
5205
+ const execution = this.executions.get(runId);
5206
+ if (execution) {
5207
+ execution.controller.abort();
5208
+ this.transientEvents.clear(runId, execution.executionId);
5209
+ }
5210
+ }
5211
+ void this.pump();
5212
+ return result;
5213
+ }
5214
+ async compact(input = {}) {
5215
+ this.assertOpen();
5216
+ return this.owned.compact(input);
5217
+ }
5170
5218
  async start(agentId, input, options) {
5171
5219
  this.assertOpen();
5172
5220
  const agent = await this.requireAgent(agentId);
@@ -5220,6 +5268,10 @@ var AgentRuntime = class _AgentRuntime {
5220
5268
  this.assertOpen();
5221
5269
  return this.owned.snapshotRun(runId);
5222
5270
  }
5271
+ async history(agentId) {
5272
+ this.assertOpen();
5273
+ return this.owned.history(agentId);
5274
+ }
5223
5275
  async respond(runId, input) {
5224
5276
  this.assertOpen();
5225
5277
  const snapshot = await this.owned.snapshotRun(runId);
@@ -5231,6 +5283,14 @@ var AgentRuntime = class _AgentRuntime {
5231
5283
  }
5232
5284
  async cancel(runId, reason) {
5233
5285
  this.assertOpen();
5286
+ const done = this.executionDone.get(runId);
5287
+ if (done) {
5288
+ this.cancellationRequested.add(runId);
5289
+ this.cancellationReasons.set(runId, reason ?? "Agent run stopped.");
5290
+ this.executions.get(runId)?.controller.abort();
5291
+ await done;
5292
+ return boundaryFromSnapshot(await this.owned.snapshotRun(runId));
5293
+ }
5234
5294
  const snapshot = await this.owned.snapshotRun(runId);
5235
5295
  await this.owned.cancelRun({ runId, expectedRevision: snapshot.revision, ...reason === void 0 ? {} : { reason } });
5236
5296
  const active = this.executions.get(runId);
@@ -5252,8 +5312,12 @@ var AgentRuntime = class _AgentRuntime {
5252
5312
  if (execution) this.transientEvents.clear(next.id, execution.executionId);
5253
5313
  this.activeAgents.delete(next.agentId);
5254
5314
  this.executions.delete(next.id);
5315
+ this.cancellationRequested.delete(next.id);
5316
+ this.cancellationReasons.delete(next.id);
5317
+ this.executionDone.delete(next.id);
5255
5318
  void this.pump();
5256
5319
  });
5320
+ this.executionDone.set(next.id, task);
5257
5321
  void task;
5258
5322
  }
5259
5323
  } catch (error) {
@@ -5311,6 +5375,7 @@ var AgentRuntime = class _AgentRuntime {
5311
5375
  executionRevision = claim.run.revision;
5312
5376
  const controller = new AbortController();
5313
5377
  this.executions.set(run.id, { controller, executionId });
5378
+ if (this.cancellationRequested.has(run.id)) controller.abort();
5314
5379
  const config = resolvedConfig;
5315
5380
  const assembly = assembleRegisteredExtensions(config, this.resources.extensionRunner);
5316
5381
  let toolQueue = Promise.resolve();
@@ -5399,6 +5464,18 @@ var AgentRuntime = class _AgentRuntime {
5399
5464
  }
5400
5465
  }
5401
5466
  });
5467
+ if (this.cancellationRequested.has(run.id) || controller.signal.aborted) {
5468
+ const output = latestAssistant(run, result.messages, claim.history.length, true);
5469
+ const reason = this.cancellationReasons.get(run.id) ?? "Agent run stopped.";
5470
+ await this.owned.cancelRun({
5471
+ runId: run.id,
5472
+ expectedRevision: executionRevision,
5473
+ reason,
5474
+ ...output && hasVisibleAssistantText(output) ? { output } : {}
5475
+ });
5476
+ this.transientEvents.clear(run.id, claim.execution.executionId);
5477
+ return;
5478
+ }
5402
5479
  if (result.type === "input_required") {
5403
5480
  const prompt = promptMessage(run, result.request.prompt, result.messages.length);
5404
5481
  await this.owned.commitInputRequired({ runId: run.id, execution: claim.execution, expectedRevision: executionRevision, requestId: createId("input"), phase: result.request.phase, prompt, checkpoint: result.checkpoint });
@@ -5417,6 +5494,14 @@ var AgentRuntime = class _AgentRuntime {
5417
5494
  } catch (error) {
5418
5495
  if (!claim && error instanceof RuntimeError && ["run_state_conflict", "runtime_ownership_lost", "run_not_found"].includes(error.code)) return;
5419
5496
  if (claim) {
5497
+ if (this.cancellationRequested.has(run.id)) {
5498
+ await this.owned.cancelRun({
5499
+ runId: run.id,
5500
+ expectedRevision: executionRevision,
5501
+ reason: this.cancellationReasons.get(run.id) ?? "Agent run stopped."
5502
+ }).catch(() => void 0);
5503
+ return;
5504
+ }
5420
5505
  await this.owned.commitOutcome({
5421
5506
  runId: run.id,
5422
5507
  execution: claim.execution,
@@ -5663,10 +5748,13 @@ var DurableRun = class {
5663
5748
  function promptMessage(run, prompt, sequence) {
5664
5749
  return { id: createId("msg"), agentId: run.agentId, runId: run.id, role: "assistant", content: prompt, sequenceWithinRun: sequence, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
5665
5750
  }
5666
- function latestAssistant(run, messages, sequence) {
5751
+ function latestAssistant(run, messages, sequence, interrupted = false) {
5667
5752
  const message = [...messages].reverse().find((candidate) => candidate.role === "assistant");
5668
5753
  if (!message) return void 0;
5669
- return projectAssistantMessage(message, run.agentId, run.id, sequence);
5754
+ return projectAssistantMessage(message, run.agentId, run.id, sequence, { interrupted });
5755
+ }
5756
+ function hasVisibleAssistantText(message) {
5757
+ return typeof message.content === "string" ? message.content.length > 0 : message.content.some((part) => part.type === "text" && part.text.length > 0);
5670
5758
  }
5671
5759
  function durableOutcome(outcome) {
5672
5760
  return {
@@ -5728,6 +5816,7 @@ function deferred2() {
5728
5816
  }
5729
5817
 
5730
5818
  // src/runtime/durable-store.ts
5819
+ import { createHash } from "crypto";
5731
5820
  var InMemoryStore = class _InMemoryStore {
5732
5821
  incarnation;
5733
5822
  agents = /* @__PURE__ */ new Map();
@@ -5737,12 +5826,14 @@ var InMemoryStore = class _InMemoryStore {
5737
5826
  events = [];
5738
5827
  idempotency = /* @__PURE__ */ new Map();
5739
5828
  operationReceipts = /* @__PURE__ */ new Map();
5829
+ historySeeds = /* @__PURE__ */ new Map();
5740
5830
  consumerCheckpoints = /* @__PURE__ */ new Map();
5741
5831
  nextAgentSequence = /* @__PURE__ */ new Map();
5742
5832
  nextReadySequence = /* @__PURE__ */ new Map();
5743
5833
  owner;
5744
5834
  ownerEpoch = 0;
5745
5835
  eventSequence = 0;
5836
+ retentionFloor = 1;
5746
5837
  constructor(options = {}) {
5747
5838
  this.incarnation = options.incarnation ?? createId("store");
5748
5839
  }
@@ -5755,10 +5846,12 @@ var InMemoryStore = class _InMemoryStore {
5755
5846
  store.events.push(...clone(state.events));
5756
5847
  for (const [key, receipt] of state.idempotency) store.idempotency.set(key, clone(receipt));
5757
5848
  for (const [key, receipt] of state.operationReceipts) store.operationReceipts.set(key, clone(receipt));
5849
+ for (const [agentId, messages] of state.historySeeds ?? []) store.historySeeds.set(agentId, clone(messages));
5758
5850
  for (const [consumerId, cursor] of state.consumerCheckpoints ?? []) store.consumerCheckpoints.set(consumerId, cursor);
5759
5851
  for (const [agentId, sequence] of state.nextAgentSequence) store.nextAgentSequence.set(agentId, sequence);
5760
5852
  for (const [agentId, sequence] of state.nextReadySequence) store.nextReadySequence.set(agentId, sequence);
5761
5853
  store.eventSequence = state.eventSequence;
5854
+ store.retentionFloor = Math.max(1, state.retentionFloor ?? 1);
5762
5855
  store.ownerEpoch = Math.max(
5763
5856
  0,
5764
5857
  ...state.runs.map((run) => run.execution?.ownerEpoch ?? 0)
@@ -5775,7 +5868,9 @@ var InMemoryStore = class _InMemoryStore {
5775
5868
  events: this.events,
5776
5869
  idempotency: [...this.idempotency.entries()],
5777
5870
  operationReceipts: [...this.operationReceipts.entries()],
5871
+ historySeeds: [...this.historySeeds.entries()],
5778
5872
  consumerCheckpoints: [...this.consumerCheckpoints.entries()],
5873
+ retentionFloor: this.retentionFloor,
5779
5874
  nextAgentSequence: [...this.nextAgentSequence.entries()],
5780
5875
  nextReadySequence: [...this.nextReadySequence.entries()],
5781
5876
  eventSequence: this.eventSequence
@@ -5851,7 +5946,8 @@ var InMemoryStore = class _InMemoryStore {
5851
5946
  const scope = createIdempotencyScope("create_agent", input.idempotencyKey);
5852
5947
  const payload = canonicalJson({
5853
5948
  ...input.metadata === void 0 ? {} : { metadata: input.metadata },
5854
- ...input.configIdentity === void 0 ? {} : { configIdentity: input.configIdentity }
5949
+ ...input.configIdentity === void 0 ? {} : { configIdentity: input.configIdentity },
5950
+ ...input.historySeed === void 0 ? {} : { historySeed: input.historySeed }
5855
5951
  });
5856
5952
  const replay = this.replay(scope, payload);
5857
5953
  if (replay) return clone(replay);
@@ -5863,6 +5959,7 @@ var InMemoryStore = class _InMemoryStore {
5863
5959
  updatedAt: timestamp
5864
5960
  };
5865
5961
  this.agents.set(agent.id, agent);
5962
+ if (input.historySeed && input.historySeed.length > 0) this.historySeeds.set(agent.id, materializeHistorySeed(agent.id, input.historySeed));
5866
5963
  this.nextAgentSequence.set(agent.id, 0);
5867
5964
  this.nextReadySequence.set(agent.id, 0);
5868
5965
  this.writeReceipt(scope, payload, agent);
@@ -5890,6 +5987,178 @@ var InMemoryStore = class _InMemoryStore {
5890
5987
  this.writeReceipt(scope, payload, agent);
5891
5988
  return clone(agent);
5892
5989
  }
5990
+ deleteAgent(lease, input) {
5991
+ this.assertOwner(lease);
5992
+ if (input.confirmation !== "conversation-delete-v1") {
5993
+ throw new TypeError("Agent deletion requires the conversation deletion confirmation token");
5994
+ }
5995
+ const agent = this.requireAgent(input.agentId);
5996
+ const runs = [...this.runs.values()].filter((run) => run.agentId === agent.id);
5997
+ const expected = new Set(input.expectedRunIds.map(String));
5998
+ const actual = new Set(runs.map((run) => String(run.id)));
5999
+ if (expected.size !== actual.size || [...actual].some((runId) => !expected.has(runId))) {
6000
+ throw new RuntimeError("run_state_conflict", {
6001
+ runId: runs[0]?.id ?? input.expectedRunIds[0] ?? "unknown",
6002
+ expected: [],
6003
+ actual: "cancelled"
6004
+ });
6005
+ }
6006
+ const runIds = new Set(runs.map((run) => run.id));
6007
+ this.agents.delete(agent.id);
6008
+ this.nextAgentSequence.delete(agent.id);
6009
+ this.nextReadySequence.delete(agent.id);
6010
+ this.historySeeds.delete(agent.id);
6011
+ for (const run of runs) this.runs.delete(run.id);
6012
+ for (const [messageId, message] of this.messages) {
6013
+ if (runIds.has(message.runId)) this.messages.delete(messageId);
6014
+ }
6015
+ for (const [toolCallId, toolCall] of this.toolCalls) {
6016
+ if (runIds.has(toolCall.runId)) this.toolCalls.delete(toolCallId);
6017
+ }
6018
+ for (let index = this.events.length - 1; index >= 0; index -= 1) {
6019
+ if (this.events[index].agentId === agent.id) this.events.splice(index, 1);
6020
+ }
6021
+ for (const [key] of this.idempotency) {
6022
+ if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) this.idempotency.delete(key);
6023
+ }
6024
+ for (const [key] of this.operationReceipts) {
6025
+ if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) this.operationReceipts.delete(key);
6026
+ }
6027
+ }
6028
+ reviseMessage(lease, input) {
6029
+ this.assertOwner(lease);
6030
+ if (!Number.isInteger(input.expectedMessageRevision) || input.expectedMessageRevision < 0) {
6031
+ throw new TypeError("expectedMessageRevision must be a non-negative integer");
6032
+ }
6033
+ if (typeof input.operationId !== "string" || input.operationId.length === 0) throw new TypeError("operationId must be non-empty");
6034
+ const normalized = normalizeUserInput({ content: input.content });
6035
+ const operationKey = `revise_message:${input.agentId}:${input.operationId}`;
6036
+ const operationPayload = canonicalJson([
6037
+ input.messageId,
6038
+ input.expectedMessageRevision,
6039
+ normalized,
6040
+ input.effectDigestConfirmation ?? null
6041
+ ]);
6042
+ const replay = this.replayOperation(operationKey, operationPayload);
6043
+ if (replay) return clone(replay);
6044
+ const agent = this.requireAgent(input.agentId);
6045
+ const seed = this.historySeeds.get(agent.id) ?? [];
6046
+ const original = this.messages.get(input.messageId) ?? seed.find(({ id }) => id === input.messageId);
6047
+ if (!original || original.agentId !== agent.id || original.role !== "user") {
6048
+ throw new RuntimeError("message_revision_conflict", {
6049
+ agentId: agent.id,
6050
+ messageId: input.messageId,
6051
+ expected: input.expectedMessageRevision,
6052
+ actual: -1
6053
+ });
6054
+ }
6055
+ const actualRevision = original.messageRevision ?? 0;
6056
+ if (actualRevision !== input.expectedMessageRevision) {
6057
+ throw new RuntimeError("message_revision_conflict", {
6058
+ agentId: agent.id,
6059
+ messageId: input.messageId,
6060
+ expected: input.expectedMessageRevision,
6061
+ actual: actualRevision
6062
+ });
6063
+ }
6064
+ const targetRun = this.runs.get(original.runId);
6065
+ const isSeedMessage = !targetRun && seed.some(({ id }) => id === original.id);
6066
+ if (!targetRun && !isSeedMessage) {
6067
+ throw new RuntimeError("message_revision_conflict", {
6068
+ agentId: agent.id,
6069
+ messageId: input.messageId,
6070
+ expected: input.expectedMessageRevision,
6071
+ actual: actualRevision
6072
+ });
6073
+ }
6074
+ const targetAgentSequence = targetRun?.agentSequence ?? -1;
6075
+ const affectedRuns = [...this.runs.values()].filter((run) => run.agentId === agent.id && run.agentSequence >= targetAgentSequence).sort((left, right) => left.agentSequence - right.agentSequence);
6076
+ const affectedRunIds = affectedRuns.map((run) => run.id);
6077
+ const affectedRunSet = new Set(affectedRunIds);
6078
+ const affectedTools = [...this.toolCalls.values()].filter((toolCall) => affectedRunSet.has(toolCall.runId)).sort((left, right) => String(left.id).localeCompare(String(right.id)));
6079
+ const effectDigest = affectedTools.length > 0 ? digestToolEffects(affectedTools) : void 0;
6080
+ if (effectDigest && input.effectDigestConfirmation !== effectDigest) {
6081
+ throw new RuntimeError("tool_effect_confirmation_required", {
6082
+ agentId: agent.id,
6083
+ messageId: input.messageId,
6084
+ effectDigest,
6085
+ toolCallIds: affectedTools.map((toolCall) => toolCall.id)
6086
+ });
6087
+ }
6088
+ const timestamp = createTimestamp();
6089
+ const replacementRun = {
6090
+ id: createId("run"),
6091
+ agentId: agent.id,
6092
+ agentSequence: this.nextSequence(agent.id),
6093
+ readySequence: this.nextReady(agent.id),
6094
+ revision: 0,
6095
+ state: "queued",
6096
+ input: targetInput(normalized, original.metadata),
6097
+ initialMessageId: original.id,
6098
+ ...(targetRun?.pinnedConfigToken ?? this.agents.get(agent.id)?.currentConfigToken) === void 0 ? {} : { pinnedConfigToken: targetRun?.pinnedConfigToken ?? this.agents.get(agent.id)?.currentConfigToken },
6099
+ createdAt: timestamp,
6100
+ updatedAt: timestamp
6101
+ };
6102
+ for (const run of affectedRuns) {
6103
+ const previousState = run.state;
6104
+ run.invalidatedBy = { messageId: original.id, messageRevision: actualRevision + 1 };
6105
+ if (run.state === "running" || run.state === "queued" || run.state === "input_required") {
6106
+ if (run.state === "running") {
6107
+ const openToolCalls = [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "running"));
6108
+ for (const toolCall of openToolCalls) this.interruptToolCall(run, toolCall, "Run superseded by Message revision.");
6109
+ } else {
6110
+ delete run.openInputRequest;
6111
+ delete run.checkpoint;
6112
+ }
6113
+ delete run.execution;
6114
+ run.state = "cancelled";
6115
+ run.cancellationReason = "Run superseded by Message revision.";
6116
+ run.revision += 1;
6117
+ run.updatedAt = timestamp;
6118
+ this.appendTransition(run, previousState, "cancelled", void 0, void 0, void 0, void 0, run.cancellationReason);
6119
+ } else {
6120
+ run.revision += 1;
6121
+ run.updatedAt = timestamp;
6122
+ }
6123
+ }
6124
+ for (const [messageId, message] of this.messages) {
6125
+ if (!affectedRunSet.has(message.runId)) continue;
6126
+ if (message.runId !== original.runId || message.sequenceWithinRun > original.sequenceWithinRun) this.messages.delete(messageId);
6127
+ }
6128
+ if (isSeedMessage) {
6129
+ const targetIndex = seed.findIndex(({ id }) => id === original.id);
6130
+ if (targetIndex >= 0) this.historySeeds.set(agent.id, seed.slice(0, targetIndex));
6131
+ }
6132
+ const revisedMessage = {
6133
+ ...clone(original),
6134
+ runId: replacementRun.id,
6135
+ content: userInputContent(normalized),
6136
+ messageRevision: actualRevision + 1,
6137
+ sequenceWithinRun: 0,
6138
+ createdAt: timestamp
6139
+ };
6140
+ this.messages.set(revisedMessage.id, revisedMessage);
6141
+ this.runs.set(replacementRun.id, replacementRun);
6142
+ this.appendTransition(replacementRun, null, "queued");
6143
+ this.events.push({
6144
+ ...this.baseEvent(replacementRun),
6145
+ kind: "message_revised",
6146
+ message: revisedMessage,
6147
+ previousRevision: actualRevision,
6148
+ invalidatedRunIds: affectedRunIds,
6149
+ targetRunId: original.runId,
6150
+ cutoffSequenceWithinRun: original.sequenceWithinRun
6151
+ });
6152
+ const result = {
6153
+ message: clone(revisedMessage),
6154
+ replacementRun: clone(replacementRun),
6155
+ invalidatedRunIds: affectedRunIds,
6156
+ affectedToolCallIds: affectedTools.map((toolCall) => toolCall.id),
6157
+ ...effectDigest === void 0 ? {} : { effectDigest }
6158
+ };
6159
+ this.writeOperationReceipt(operationKey, operationPayload, result);
6160
+ return clone(result);
6161
+ }
5893
6162
  createRun(lease, input) {
5894
6163
  this.assertOwner(lease);
5895
6164
  this.requireAgent(input.agentId);
@@ -5937,7 +6206,7 @@ var InMemoryStore = class _InMemoryStore {
5937
6206
  }
5938
6207
  if (!run.pinnedConfigToken && input.configToken) run.pinnedConfigToken = input.configToken;
5939
6208
  let message;
5940
- if (!run.checkpoint) {
6209
+ if (!run.checkpoint && !run.initialMessageId) {
5941
6210
  const userInput = normalizeUserInput(run.input);
5942
6211
  message = {
5943
6212
  id: input.messageId ?? createId("msg"),
@@ -5962,7 +6231,7 @@ var InMemoryStore = class _InMemoryStore {
5962
6231
  run.updatedAt = createTimestamp();
5963
6232
  if (message) this.appendMessage(run, message);
5964
6233
  this.appendTransition(run, "queued", "running");
5965
- const result = { run: clone(run), execution: clone(execution), history: this.history(run.agentId, run.agentSequence) };
6234
+ const result = { run: clone(run), execution: clone(execution), history: this.activeHistory(run.agentId, run.agentSequence) };
5966
6235
  this.writeOperationReceipt(operationKey, operationPayload, result);
5967
6236
  return result;
5968
6237
  }
@@ -6258,11 +6527,16 @@ var InMemoryStore = class _InMemoryStore {
6258
6527
  cancelRun(lease, input) {
6259
6528
  this.assertOwner(lease);
6260
6529
  const operationKey = `cancel:${input.runId}:${input.expectedRevision ?? "current"}`;
6261
- const operationPayload = canonicalJson(input.reason ?? null);
6530
+ const operationPayload = canonicalJson([input.reason ?? null, input.output ?? null]);
6262
6531
  const replay = this.replayOperation(operationKey, operationPayload);
6263
6532
  if (replay) return clone(replay);
6264
6533
  const run = this.requireRun(input.runId);
6265
6534
  if (input.expectedRevision !== void 0) this.assertRevision(run, input.expectedRevision);
6535
+ if (input.output !== void 0) {
6536
+ if (!isAssistantMessage(input.output) || input.output.agentId !== run.agentId || input.output.runId !== run.id || input.output.interrupted !== true) {
6537
+ throw new TypeError("cancelled output must be an interrupted AssistantMessage from this Run");
6538
+ }
6539
+ }
6266
6540
  if (["completed", "failed", "cancelled"].includes(run.state)) {
6267
6541
  const result2 = clone(run);
6268
6542
  if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
@@ -6272,6 +6546,11 @@ var InMemoryStore = class _InMemoryStore {
6272
6546
  const activeToolCalls = run.execution ? [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "running")) : [];
6273
6547
  const indeterminateToolCallIds = activeToolCalls.filter((toolCall) => toolCall.state === "running").map((toolCall) => toolCall.id);
6274
6548
  for (const toolCall of activeToolCalls) this.interruptToolCall(run, toolCall, input.reason ?? "The Run was cancelled.");
6549
+ if (input.output && (typeof input.output.content === "string" ? input.output.content.length > 0 : input.output.content.length > 0)) {
6550
+ const output = { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) };
6551
+ this.messages.set(output.id, output);
6552
+ this.appendMessage(run, output);
6553
+ }
6275
6554
  if (indeterminateToolCallIds.length > 0) {
6276
6555
  const failure = {
6277
6556
  code: "tool_indeterminate",
@@ -6347,7 +6626,10 @@ var InMemoryStore = class _InMemoryStore {
6347
6626
  }
6348
6627
  listEvents(lease, input = {}) {
6349
6628
  this.assertOwner(lease);
6350
- const after = input.after ? this.parseCursor(input.after) : 0;
6629
+ const after = input.after ? this.parseCursor(input.after) : this.retentionFloor - 1;
6630
+ if (input.after && after < this.retentionFloor - 1) {
6631
+ throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "expired" });
6632
+ }
6351
6633
  if (after > this.eventSequence) {
6352
6634
  throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "beyond_waterline" });
6353
6635
  }
@@ -6364,11 +6646,72 @@ var InMemoryStore = class _InMemoryStore {
6364
6646
  advanceConsumerCheckpoint(lease, input) {
6365
6647
  this.assertOwner(lease);
6366
6648
  const next = this.parseCursor(input.cursor);
6649
+ if (next < this.retentionFloor - 1) {
6650
+ throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "expired" });
6651
+ }
6367
6652
  if (next > this.eventSequence) throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "beyond_waterline" });
6368
6653
  const previous = this.consumerCheckpoints.get(input.consumerId);
6369
6654
  if (previous !== void 0 && next <= this.parseCursor(previous)) return;
6370
6655
  this.consumerCheckpoints.set(input.consumerId, input.cursor);
6371
6656
  }
6657
+ compact(lease, input = {}) {
6658
+ this.assertOwner(lease);
6659
+ const retentionMs = input.retentionMs ?? 7 * 24 * 60 * 60 * 1e3;
6660
+ if (!Number.isFinite(retentionMs) || retentionMs < 0) {
6661
+ throw new TypeError("retentionMs must be a non-negative finite number");
6662
+ }
6663
+ const now = input.now === void 0 ? Date.now() : Date.parse(input.now);
6664
+ if (!Number.isFinite(now)) throw new TypeError("now must be an ISO timestamp");
6665
+ const cutoff = now - retentionMs;
6666
+ const checkpointSequences = [...this.consumerCheckpoints.values()].map((cursor) => this.parseCursor(cursor));
6667
+ const consumerFloor = checkpointSequences.length > 0 ? Math.min(...checkpointSequences) : this.eventSequence;
6668
+ const blockedRunIds = /* @__PURE__ */ new Set();
6669
+ for (const run of this.runs.values()) {
6670
+ if (run.state === "running") blockedRunIds.add(run.id);
6671
+ }
6672
+ for (const tool of this.toolCalls.values()) {
6673
+ if (tool.state === "pending" || tool.state === "running" || tool.state === "indeterminate") {
6674
+ blockedRunIds.add(tool.runId);
6675
+ }
6676
+ }
6677
+ let deleteThrough = this.retentionFloor - 1;
6678
+ for (const event of this.events) {
6679
+ const sequence = this.parseCursor(event.cursor);
6680
+ if (sequence < this.retentionFloor) continue;
6681
+ if (sequence > consumerFloor) break;
6682
+ if (Date.parse(event.createdAt) > cutoff || blockedRunIds.has(event.runId)) break;
6683
+ const eventRun = this.runs.get(event.runId);
6684
+ if (!eventRun || eventRun.invalidatedBy === void 0 || !["completed", "failed", "cancelled"].includes(eventRun.state) || Date.parse(eventRun.updatedAt) > cutoff) break;
6685
+ deleteThrough = sequence;
6686
+ }
6687
+ const deletedEvents = deleteThrough >= this.retentionFloor ? this.events.filter((event) => this.parseCursor(event.cursor) <= deleteThrough) : [];
6688
+ if (deleteThrough >= this.retentionFloor) {
6689
+ this.events.splice(0, this.events.length, ...this.events.filter((event) => this.parseCursor(event.cursor) > deleteThrough));
6690
+ this.retentionFloor = deleteThrough + 1;
6691
+ for (const [consumerId, cursor] of this.consumerCheckpoints) {
6692
+ if (this.parseCursor(cursor) < this.retentionFloor - 1) {
6693
+ this.consumerCheckpoints.delete(consumerId);
6694
+ }
6695
+ }
6696
+ }
6697
+ const activeMessageRunIds = new Set([...this.messages.values()].map((message) => message.runId));
6698
+ const deletableRuns = [...this.runs.values()].filter((run) => run.invalidatedBy !== void 0 && ["completed", "failed", "cancelled"].includes(run.state) && Date.parse(run.updatedAt) <= cutoff && !activeMessageRunIds.has(run.id) && !blockedRunIds.has(run.id) && this.events.filter((event) => event.runId === run.id).every((event) => this.parseCursor(event.cursor) <= consumerFloor && Date.parse(event.createdAt) <= cutoff));
6699
+ const deletedRunIds = deletableRuns.map((run) => run.id);
6700
+ const deletedRunSet = new Set(deletedRunIds);
6701
+ const deletedTools = [...this.toolCalls.values()].filter((tool) => deletedRunSet.has(tool.runId));
6702
+ for (const runId of deletedRunIds) this.runs.delete(runId);
6703
+ for (const [messageId, message] of this.messages) {
6704
+ if (deletedRunSet.has(message.runId)) this.messages.delete(messageId);
6705
+ }
6706
+ for (const tool of deletedTools) this.toolCalls.delete(tool.id);
6707
+ return {
6708
+ deletedRunIds,
6709
+ deletedToolCallIds: deletedTools.map((tool) => tool.id),
6710
+ deletedEventCount: deletedEvents.length,
6711
+ retentionFloor: `${this.incarnation}:${this.retentionFloor}`,
6712
+ ...deletedRunIds.length === 0 && deletedEvents.length === 0 ? { skipped: "no_eligible_events" } : {}
6713
+ };
6714
+ }
6372
6715
  replay(scope, payload) {
6373
6716
  const key = encodeIdempotencyScope(this.incarnation, scope);
6374
6717
  const receipt = this.idempotency.get(key);
@@ -6466,8 +6809,16 @@ var InMemoryStore = class _InMemoryStore {
6466
6809
  messagesForRun(runId) {
6467
6810
  return [...this.messages.values()].filter((message) => message.runId === runId).sort((a, b) => a.sequenceWithinRun - b.sequenceWithinRun);
6468
6811
  }
6469
- history(agentId, beforeSequence) {
6470
- return clone([...this.runs.values()].filter((run) => run.agentId === agentId && run.agentSequence <= beforeSequence).sort((a, b) => a.agentSequence - b.agentSequence).flatMap((run) => this.messagesForRun(run.id)));
6812
+ history(lease, agentId) {
6813
+ this.assertOwner(lease);
6814
+ this.requireAgent(agentId);
6815
+ return this.activeHistory(agentId, Number.MAX_SAFE_INTEGER);
6816
+ }
6817
+ activeHistory(agentId, beforeSequence) {
6818
+ return clone([
6819
+ ...this.historySeeds.get(agentId) ?? [],
6820
+ ...[...this.runs.values()].filter((run) => run.agentId === agentId && run.agentSequence <= beforeSequence).sort((a, b) => a.agentSequence - b.agentSequence).flatMap((run) => this.messagesForRun(run.id))
6821
+ ].map((message) => ({ ...message, messageRevision: message.messageRevision ?? 0 })));
6471
6822
  }
6472
6823
  appendMessage(run, message) {
6473
6824
  this.events.push(this.baseEvent(run, {
@@ -6535,6 +6886,15 @@ var MemoryOwnedStore = class {
6535
6886
  async updateAgentConfigToken(input) {
6536
6887
  return this.store.updateAgentConfigToken(this.lease, input);
6537
6888
  }
6889
+ async deleteAgent(input) {
6890
+ this.store.deleteAgent(this.lease, input);
6891
+ }
6892
+ async reviseMessage(input) {
6893
+ return this.store.reviseMessage(this.lease, input);
6894
+ }
6895
+ async compact(input) {
6896
+ return this.store.compact(this.lease, input);
6897
+ }
6538
6898
  async createRun(input) {
6539
6899
  return this.store.createRun(this.lease, input);
6540
6900
  }
@@ -6571,6 +6931,9 @@ var MemoryOwnedStore = class {
6571
6931
  async snapshotRun(runId) {
6572
6932
  return this.store.snapshotRun(this.lease, runId);
6573
6933
  }
6934
+ async history(agentId) {
6935
+ return this.store.history(this.lease, agentId);
6936
+ }
6574
6937
  async listAgents() {
6575
6938
  return this.store.listAgents(this.lease);
6576
6939
  }
@@ -6618,6 +6981,41 @@ function userInputContent(input) {
6618
6981
  function userInputMetadata(input) {
6619
6982
  return typeof input === "string" ? void 0 : input.metadata;
6620
6983
  }
6984
+ function targetInput(input, metadata) {
6985
+ const content = typeof input === "string" ? input : input.content;
6986
+ return metadata === void 0 ? { content } : { content, metadata: clone(metadata) };
6987
+ }
6988
+ function materializeHistorySeed(agentId, source) {
6989
+ const seedRunId = createId("seed");
6990
+ const toolIds = /* @__PURE__ */ new Map();
6991
+ return source.map((message, sequenceWithinRun) => {
6992
+ const content = remapSeedContent(message.content, toolIds);
6993
+ return {
6994
+ ...clone(message),
6995
+ id: createId("msg"),
6996
+ agentId,
6997
+ runId: seedRunId,
6998
+ content,
6999
+ messageRevision: message.messageRevision ?? 0,
7000
+ sequenceWithinRun,
7001
+ createdAt: createTimestamp()
7002
+ };
7003
+ });
7004
+ }
7005
+ function remapSeedContent(content, toolIds) {
7006
+ if (typeof content === "string") return content;
7007
+ return content.map((part) => {
7008
+ if (part.type === "tool_use" || part.type === "tool_result") {
7009
+ const toolCallId = toolIds.get(part.toolCallId) ?? createId("tool");
7010
+ toolIds.set(part.toolCallId, toolCallId);
7011
+ return part.type === "tool_result" ? { ...part, toolCallId, result: clone(part.result) } : { ...part, toolCallId };
7012
+ }
7013
+ return clone(part);
7014
+ });
7015
+ }
7016
+ function digestToolEffects(toolCalls) {
7017
+ return createHash("sha256").update(canonicalJson(toolCalls)).digest("hex");
7018
+ }
6621
7019
  function assertToolValue(value, argument) {
6622
7020
  assertUtf8ByteLimit(canonicalJson(value), TOOL_VALUE_JSON_BYTES, argument);
6623
7021
  }
@@ -6625,8 +7023,9 @@ function assertToolValue(value, argument) {
6625
7023
  // src/runtime/sqlite-durable-store.ts
6626
7024
  import { Database } from "bun:sqlite";
6627
7025
  var SCHEMA_ID = "rowan.agent.runtime";
6628
- var SCHEMA_VERSION = "1";
7026
+ var SCHEMA_VERSION = "2";
6629
7027
  var SCHEMA_VALUE = `${SCHEMA_ID}:${SCHEMA_VERSION}`;
7028
+ var RETENTION_FLOOR_KEY = "retention_floor";
6630
7029
  var STATE_ROW = 1;
6631
7030
  var CURRENT_TABLES = /* @__PURE__ */ new Set([
6632
7031
  "runtime_meta",
@@ -6791,6 +7190,12 @@ var SqliteStore = class {
6791
7190
  async updateAgentConfigToken(lease, input) {
6792
7191
  return this.invoke(lease, (store, current) => store.updateAgentConfigToken(current, input));
6793
7192
  }
7193
+ async deleteAgent(lease, input) {
7194
+ return this.invoke(lease, (store, current) => store.deleteAgent(current, input));
7195
+ }
7196
+ async reviseMessage(lease, input) {
7197
+ return this.invoke(lease, (store, current) => store.reviseMessage(current, input));
7198
+ }
6794
7199
  async createRun(lease, input) {
6795
7200
  return this.invoke(lease, (store, current) => store.createRun(current, input));
6796
7201
  }
@@ -6827,6 +7232,9 @@ var SqliteStore = class {
6827
7232
  async snapshotRun(lease, runId) {
6828
7233
  return this.invoke(lease, (store, current) => store.snapshotRun(current, runId), false);
6829
7234
  }
7235
+ async history(lease, agentId) {
7236
+ return this.invoke(lease, (store, current) => store.history(current, agentId), false);
7237
+ }
6830
7238
  async listAgents(lease) {
6831
7239
  return this.invoke(lease, (store, current) => store.listAgents(current), false);
6832
7240
  }
@@ -6837,24 +7245,28 @@ var SqliteStore = class {
6837
7245
  this.assertOpen();
6838
7246
  return this.readTransaction(() => {
6839
7247
  this.requireMatchingOwner(lease, true);
6840
- const after = input.after ? parseEventCursor(lease, input.after) : 0;
7248
+ const retentionRow = this.database.query(
7249
+ "SELECT value FROM runtime_meta WHERE key = ?"
7250
+ ).get(RETENTION_FLOOR_KEY);
7251
+ const retentionFloor = Math.max(1, Number(retentionRow?.value ?? "1"));
7252
+ const after = input.after ? parseEventCursor(lease, input.after) : retentionFloor - 1;
7253
+ if (input.after && after < retentionFloor - 1) {
7254
+ throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "expired" });
7255
+ }
6841
7256
  if (input.after) {
6842
7257
  const latest = this.database.query(
6843
- "SELECT payload_json FROM run_events ORDER BY sequence DESC LIMIT 1"
7258
+ "SELECT max(sequence) AS sequence FROM run_events"
6844
7259
  ).get();
6845
- const waterline = latest ? parseEventCursor(
6846
- lease,
6847
- JSON.parse(latest.payload_json).cursor
6848
- ) : 0;
7260
+ const waterline = latest.sequence ?? 0;
6849
7261
  if (after > waterline) {
6850
7262
  throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "beyond_waterline" });
6851
7263
  }
6852
7264
  if (after === waterline) return [];
6853
7265
  }
6854
7266
  const rows = this.database.query(
6855
- "SELECT payload_json FROM run_events ORDER BY sequence LIMIT -1 OFFSET ?"
6856
- ).all(after);
6857
- return rows.map((row) => JSON.parse(row.payload_json));
7267
+ "SELECT payload_json FROM run_events ORDER BY sequence"
7268
+ ).all();
7269
+ return rows.map((row) => JSON.parse(row.payload_json)).filter((event) => parseEventCursor(lease, event.cursor) > after);
6858
7270
  });
6859
7271
  }
6860
7272
  async openConsumer(lease, consumerId) {
@@ -6863,6 +7275,15 @@ var SqliteStore = class {
6863
7275
  async advanceConsumerCheckpoint(lease, input) {
6864
7276
  return this.invoke(lease, (store, current) => store.advanceConsumerCheckpoint(current, input));
6865
7277
  }
7278
+ async compact(lease, input = {}) {
7279
+ this.assertOpen();
7280
+ const result = this.invoke(lease, (store, current) => store.compact(current, input));
7281
+ if (result.deletedEventCount > 0 || result.deletedRunIds.length > 0) {
7282
+ this.database.run("PRAGMA wal_checkpoint(PASSIVE)");
7283
+ this.database.run("PRAGMA incremental_vacuum");
7284
+ }
7285
+ return result;
7286
+ }
6866
7287
  async renewOwner(lease, leaseMs) {
6867
7288
  this.assertOpen();
6868
7289
  assertOwnerInput(lease.ownerId, leaseMs);
@@ -6915,6 +7336,7 @@ var SqliteStore = class {
6915
7336
  if (sql) this.database.run(sql);
6916
7337
  }
6917
7338
  this.database.run("INSERT INTO runtime_meta (key, value) VALUES (?, ?)", ["schema_version", SCHEMA_VALUE]);
7339
+ this.database.run("INSERT INTO runtime_meta (key, value) VALUES (?, ?)", [RETENTION_FLOOR_KEY, "1"]);
6918
7340
  const state = new InMemoryStore();
6919
7341
  this.database.run("INSERT INTO runtime_owner (singleton, epoch) VALUES (?, ?)", [STATE_ROW, 0]);
6920
7342
  this.database.run("INSERT INTO runtime_state (singleton, state_json) VALUES (?, ?)", [STATE_ROW, JSON.stringify(state.exportState())]);
@@ -6963,6 +7385,10 @@ var SqliteStore = class {
6963
7385
  }
6964
7386
  persistState(state) {
6965
7387
  this.writeState(state);
7388
+ this.database.run(
7389
+ "INSERT INTO runtime_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",
7390
+ [RETENTION_FLOOR_KEY, String(Math.max(1, state.retentionFloor ?? 1))]
7391
+ );
6966
7392
  for (const table of ["consumer_checkpoints", "idempotency", "run_events", "messages", "input_requests", "tool_calls", "runs", "agents"]) {
6967
7393
  this.database.run(`DELETE FROM ${table}`);
6968
7394
  }
@@ -7078,6 +7504,15 @@ var SqliteOwnedStore = class {
7078
7504
  updateAgentConfigToken(input) {
7079
7505
  return this.store.updateAgentConfigToken(this.lease, input);
7080
7506
  }
7507
+ deleteAgent(input) {
7508
+ return this.store.deleteAgent(this.lease, input);
7509
+ }
7510
+ reviseMessage(input) {
7511
+ return this.store.reviseMessage(this.lease, input);
7512
+ }
7513
+ compact(input) {
7514
+ return this.store.compact(this.lease, input);
7515
+ }
7081
7516
  createRun(input) {
7082
7517
  return this.store.createRun(this.lease, input);
7083
7518
  }
@@ -7114,6 +7549,9 @@ var SqliteOwnedStore = class {
7114
7549
  snapshotRun(runId) {
7115
7550
  return this.store.snapshotRun(this.lease, runId);
7116
7551
  }
7552
+ history(agentId) {
7553
+ return this.store.history(this.lease, agentId);
7554
+ }
7117
7555
  listAgents() {
7118
7556
  return this.store.listAgents(this.lease);
7119
7557
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowan-agent/agent",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",