@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 +144 -5
- package/dist/index.js +460 -22
- package/package.json +1 -1
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
|
-
|
|
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.
|
|
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) :
|
|
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(
|
|
6470
|
-
|
|
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 = "
|
|
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
|
|
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
|
|
7258
|
+
"SELECT max(sequence) AS sequence FROM run_events"
|
|
6844
7259
|
).get();
|
|
6845
|
-
const waterline = latest
|
|
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
|
|
6856
|
-
).all(
|
|
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
|
}
|