@tutti-os/agent-activity-core 0.0.222 → 0.0.224

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.js CHANGED
@@ -1,3 +1,151 @@
1
+ // src/liveProtocolRevision.gen.ts
2
+ var AGENT_ACTIVITY_LIVE_PROTOCOL_REVISION = "sha256:d6d418949c61ff09";
3
+
4
+ // src/activityValueParsing.ts
5
+ function cloneJSONValue(value) {
6
+ if (Array.isArray(value)) return value.map(cloneJSONValue);
7
+ if (value !== null && typeof value === "object") {
8
+ return Object.fromEntries(
9
+ Object.entries(value).map(([key, entry]) => [
10
+ key,
11
+ cloneJSONValue(entry)
12
+ ])
13
+ );
14
+ }
15
+ return value;
16
+ }
17
+ function recordValue(value) {
18
+ return typeof value === "object" && value !== null ? value : null;
19
+ }
20
+ function stringValue(value) {
21
+ return typeof value === "string" ? value.trim() : "";
22
+ }
23
+ function nullableStringValue(value) {
24
+ return typeof value === "string" ? value : value === null ? null : void 0;
25
+ }
26
+ function numberValue(value) {
27
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
28
+ }
29
+ function messageVersionValue(source) {
30
+ return numberValue(source.version) ?? numberValue(source.seq) ?? 0;
31
+ }
32
+
33
+ // src/liveEventParsing.ts
34
+ function parseAgentActivityMessageDeltaEvent(value) {
35
+ const event = recordValue2(value);
36
+ const data = recordValue2(event?.data);
37
+ if (event?.eventType !== "message_delta" || !data || !nonEmptyString(event.workspaceId) || !nonEmptyString(event.agentSessionId) || data.workspaceId !== event.workspaceId || data.agentSessionId !== event.agentSessionId || !nonEmptyString(data.messageId) || !nonEmptyString(data.turnId) || !nonEmptyString(data.role) || !nonEmptyString(data.kind) || !positiveSafeInteger(data.occurredAtUnixMs)) {
38
+ return null;
39
+ }
40
+ const content = parseContentOperation(data.content);
41
+ if (data.content !== void 0 && !content) {
42
+ return null;
43
+ }
44
+ const toolOutput = parseToolOutputOperation(data.toolOutput);
45
+ if (data.toolOutput !== void 0 && !toolOutput || toolOutput && data.kind !== "tool_call") {
46
+ return null;
47
+ }
48
+ const payloadSet = data.payloadSet === void 0 ? void 0 : recordValue2(data.payloadSet);
49
+ if (data.payloadSet !== void 0 && !payloadSet) {
50
+ return null;
51
+ }
52
+ const payloadUnset = stringArray(data.payloadUnset);
53
+ if (data.payloadUnset !== void 0 && !payloadUnset) {
54
+ return null;
55
+ }
56
+ const semantics = data.semantics === void 0 ? void 0 : recordValue2(data.semantics);
57
+ if (data.semantics !== void 0 && !semantics) {
58
+ return null;
59
+ }
60
+ if (data.status !== void 0 && typeof data.status !== "string" || !optionalNonNegativeSafeInteger(data.startedAtUnixMs) || !optionalNonNegativeSafeInteger(data.completedAtUnixMs)) {
61
+ return null;
62
+ }
63
+ if (!content && !toolOutput && !payloadSet && !payloadUnset && data.status === void 0 && !semantics && data.startedAtUnixMs === void 0 && data.completedAtUnixMs === void 0) {
64
+ return null;
65
+ }
66
+ return {
67
+ workspaceId: event.workspaceId,
68
+ agentSessionId: event.agentSessionId,
69
+ eventType: "message_delta",
70
+ data: {
71
+ workspaceId: data.workspaceId,
72
+ agentSessionId: data.agentSessionId,
73
+ messageId: data.messageId,
74
+ turnId: data.turnId,
75
+ role: data.role,
76
+ kind: data.kind,
77
+ occurredAtUnixMs: data.occurredAtUnixMs,
78
+ ...content ? { content } : {},
79
+ ...toolOutput ? { toolOutput } : {},
80
+ ...payloadSet ? {
81
+ payloadSet: cloneJSONValue(payloadSet)
82
+ } : {},
83
+ ...payloadUnset ? { payloadUnset } : {},
84
+ ...typeof data.status === "string" ? { status: data.status } : {},
85
+ ...semantics ? {
86
+ semantics: cloneJSONValue(
87
+ semantics
88
+ )
89
+ } : {},
90
+ ...typeof data.startedAtUnixMs === "number" ? { startedAtUnixMs: data.startedAtUnixMs } : {},
91
+ ...typeof data.completedAtUnixMs === "number" ? { completedAtUnixMs: data.completedAtUnixMs } : {}
92
+ }
93
+ };
94
+ }
95
+ function parseToolOutputOperation(value) {
96
+ if (value === void 0) return null;
97
+ const operation = recordValue2(value);
98
+ if (!operation || typeof operation.text !== "string") return null;
99
+ if (operation.operation === "set" && operation.offsetBytes === void 0) {
100
+ return { operation: "set", text: operation.text };
101
+ }
102
+ if (operation.operation === "append_text" && operation.text.length > 0 && nonNegativeSafeInteger(operation.offsetBytes)) {
103
+ return {
104
+ operation: "append_text",
105
+ text: operation.text,
106
+ offsetBytes: operation.offsetBytes
107
+ };
108
+ }
109
+ return null;
110
+ }
111
+ function parseContentOperation(value) {
112
+ if (value === void 0) return null;
113
+ const operation = recordValue2(value);
114
+ if (!operation) return null;
115
+ if (operation.operation === "append_text" && typeof operation.text === "string") {
116
+ return { operation: "append_text", text: operation.text };
117
+ }
118
+ if (operation.operation === "set" && Object.prototype.hasOwnProperty.call(operation, "value")) {
119
+ return {
120
+ operation: "set",
121
+ value: cloneJSONValue(operation.value)
122
+ };
123
+ }
124
+ return null;
125
+ }
126
+ function recordValue2(value) {
127
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
128
+ }
129
+ function nonEmptyString(value) {
130
+ return typeof value === "string" && value.trim().length > 0;
131
+ }
132
+ function positiveSafeInteger(value) {
133
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
134
+ }
135
+ function nonNegativeSafeInteger(value) {
136
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
137
+ }
138
+ function optionalNonNegativeSafeInteger(value) {
139
+ return value === void 0 || typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
140
+ }
141
+ function stringArray(value) {
142
+ if (value === void 0) return null;
143
+ if (!Array.isArray(value) || value.length === 0 || value.some((item) => !nonEmptyString(item))) {
144
+ return null;
145
+ }
146
+ return [...new Set(value)];
147
+ }
148
+
1
149
  // src/capabilityReferences.ts
2
150
  function normalizeAgentActivityCapabilityReferences(references) {
3
151
  if (!references?.length) return [];
@@ -716,8 +864,8 @@ function areJsonLikeValuesEqual(left, right) {
716
864
  }
717
865
  return true;
718
866
  }
719
- const leftRecord = recordValue(left);
720
- const rightRecord = recordValue(right);
867
+ const leftRecord = recordValue3(left);
868
+ const rightRecord = recordValue3(right);
721
869
  if (!leftRecord || !rightRecord) {
722
870
  return false;
723
871
  }
@@ -732,43 +880,14 @@ function areJsonLikeValuesEqual(left, right) {
732
880
  }
733
881
  return true;
734
882
  }
735
- function recordValue(value) {
736
- return typeof value === "object" && value !== null ? value : null;
737
- }
738
-
739
- // src/activityValueParsing.ts
740
- function cloneJSONValue(value) {
741
- if (Array.isArray(value)) return value.map(cloneJSONValue);
742
- if (value !== null && typeof value === "object") {
743
- return Object.fromEntries(
744
- Object.entries(value).map(([key, entry]) => [
745
- key,
746
- cloneJSONValue(entry)
747
- ])
748
- );
749
- }
750
- return value;
751
- }
752
- function recordValue2(value) {
883
+ function recordValue3(value) {
753
884
  return typeof value === "object" && value !== null ? value : null;
754
885
  }
755
- function stringValue(value) {
756
- return typeof value === "string" ? value.trim() : "";
757
- }
758
- function nullableStringValue(value) {
759
- return typeof value === "string" ? value : value === null ? null : void 0;
760
- }
761
- function numberValue(value) {
762
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
763
- }
764
- function messageVersionValue(source) {
765
- return numberValue(source.version) ?? numberValue(source.seq) ?? 0;
766
- }
767
886
 
768
887
  // src/inlineActivityMessages.ts
769
888
  function parseInlineActivityMessages(event) {
770
889
  if (event.eventType === "session_audit") {
771
- const audit = recordValue2(event.data.audit);
890
+ const audit = recordValue(event.data.audit);
772
891
  if (!audit) return [];
773
892
  return [
774
893
  agentActivityMessageFromInlineMessage({
@@ -787,13 +906,13 @@ function parseInlineActivityMessages(event) {
787
906
  ].filter((message) => message !== null);
788
907
  }
789
908
  if (event.eventType !== "message_update") return [];
790
- const source = recordValue2(event.data);
909
+ const source = recordValue(event.data);
791
910
  const rawMessages = Array.isArray(source?.messages) ? source.messages : [];
792
911
  const eventAgentSessionId = event.agentSessionId.trim();
793
912
  const workspaceId = event.workspaceId?.trim() ?? "";
794
913
  const messages = [];
795
914
  for (const raw of rawMessages) {
796
- const record = recordValue2(raw);
915
+ const record = recordValue(raw);
797
916
  if (!record) continue;
798
917
  const agentSessionId = stringValue(record.agentSessionId) || eventAgentSessionId;
799
918
  const message = agentActivityMessageFromInlineMessage({
@@ -825,10 +944,10 @@ function agentActivityMessageFromInlineMessage(input) {
825
944
  role,
826
945
  kind,
827
946
  status: nullableStringValue(input.message.status),
828
- semantics: recordValue2(input.message.semantics) ? cloneJSONValue(
947
+ semantics: recordValue(input.message.semantics) ? cloneJSONValue(
829
948
  input.message.semantics
830
949
  ) : void 0,
831
- payload: cloneJSONValue(recordValue2(input.message.payload) ?? {}),
950
+ payload: cloneJSONValue(recordValue(input.message.payload) ?? {}),
832
951
  sequence: numberValue(input.message.sequence),
833
952
  occurredAtUnixMs,
834
953
  createdAtUnixMs: numberValue(input.message.createdAtUnixMs),
@@ -837,6 +956,237 @@ function agentActivityMessageFromInlineMessage(input) {
837
956
  };
838
957
  }
839
958
 
959
+ // src/optimisticMessageOverlay.ts
960
+ function createAgentActivityOptimisticMessageOverlay() {
961
+ const optimistic = /* @__PURE__ */ new Map();
962
+ const canonical = /* @__PURE__ */ new Map();
963
+ return {
964
+ apply(event) {
965
+ if (event.eventType !== "message_delta") {
966
+ return { applied: false, needsReconcile: false };
967
+ }
968
+ return applyMessageDelta(event);
969
+ },
970
+ reconcile(scope, messages) {
971
+ const normalized = normalizeCanonicalMessages(scope, messages);
972
+ const prefix = scopePrefix(scope);
973
+ deleteScopeEntries(canonical, prefix);
974
+ for (const message of normalized) {
975
+ const key = messageKey(message);
976
+ canonical.set(key, cloneMessage(message));
977
+ }
978
+ for (const [key, entry] of optimistic) {
979
+ if (!key.startsWith(prefix)) {
980
+ continue;
981
+ }
982
+ const canonicalMessage = canonical.get(key);
983
+ if (!entry.explicitlyTerminal || canonicalMessage !== void 0 && isTerminalMessage(canonicalMessage)) {
984
+ optimistic.delete(key);
985
+ }
986
+ }
987
+ },
988
+ reset(scope) {
989
+ const prefix = scopePrefix(scope);
990
+ deleteScopeEntries(optimistic, prefix);
991
+ deleteScopeEntries(canonical, prefix);
992
+ },
993
+ project(scope, messages) {
994
+ const normalized = normalizeCanonicalMessages(scope, messages);
995
+ const byKey = /* @__PURE__ */ new Map();
996
+ for (const message of normalized) {
997
+ byKey.set(messageKey(message), cloneMessage(message));
998
+ }
999
+ const prefix = scopePrefix(scope);
1000
+ for (const [key, entry] of optimistic) {
1001
+ if (!key.startsWith(prefix)) {
1002
+ continue;
1003
+ }
1004
+ const base = byKey.get(key) ?? canonical.get(key);
1005
+ byKey.set(
1006
+ key,
1007
+ base ? materialize(base, entry.message, entry.payloadUnset) : cloneMessage(entry.message)
1008
+ );
1009
+ }
1010
+ return [...byKey.values()].sort(compareAgentActivityMessages);
1011
+ }
1012
+ };
1013
+ function applyMessageDelta(event) {
1014
+ const data = event.data;
1015
+ if (data.workspaceId !== event.workspaceId || data.agentSessionId !== event.agentSessionId) {
1016
+ return {
1017
+ applied: false,
1018
+ needsReconcile: true,
1019
+ reason: "identity_mismatch"
1020
+ };
1021
+ }
1022
+ const key = liveMessageKey(event);
1023
+ const existing = optimistic.get(key)?.message ?? canonical.get(key) ?? void 0;
1024
+ if (data.content?.operation === "append_text" && !existing) {
1025
+ return {
1026
+ applied: false,
1027
+ needsReconcile: true,
1028
+ reason: "append_without_anchor"
1029
+ };
1030
+ }
1031
+ if (data.toolOutput?.operation === "append_text" && !existing) {
1032
+ return {
1033
+ applied: false,
1034
+ needsReconcile: true,
1035
+ reason: "append_without_anchor"
1036
+ };
1037
+ }
1038
+ const next = existing ? cloneMessage(existing) : {
1039
+ workspaceId: event.workspaceId,
1040
+ agentSessionId: event.agentSessionId,
1041
+ messageId: data.messageId,
1042
+ version: 0,
1043
+ turnId: data.turnId ?? null,
1044
+ role: data.role,
1045
+ kind: data.kind,
1046
+ payload: {},
1047
+ occurredAtUnixMs: data.occurredAtUnixMs
1048
+ };
1049
+ next.workspaceId = event.workspaceId;
1050
+ next.agentSessionId = event.agentSessionId;
1051
+ next.turnId = data.turnId ?? next.turnId;
1052
+ next.role = data.role;
1053
+ next.kind = data.kind;
1054
+ next.occurredAtUnixMs = Math.max(
1055
+ next.occurredAtUnixMs,
1056
+ data.occurredAtUnixMs
1057
+ );
1058
+ if (data.content?.operation === "append_text") {
1059
+ const currentText = typeof next.payload.text === "string" ? next.payload.text : "";
1060
+ const text2 = currentText + data.content.text;
1061
+ next.payload.text = text2;
1062
+ next.payload.content = text2;
1063
+ } else if (data.content?.operation === "set") {
1064
+ const value = cloneJSONValue(data.content.value);
1065
+ next.payload.content = value;
1066
+ if (typeof value === "string") {
1067
+ next.payload.text = value;
1068
+ } else {
1069
+ delete next.payload.text;
1070
+ }
1071
+ }
1072
+ if (data.toolOutput) {
1073
+ const output = recordValue4(next.payload.output) ?? {};
1074
+ const currentText = typeof output.text === "string" ? output.text : "";
1075
+ if (data.toolOutput.operation === "append_text" && utf8ByteLength(currentText) !== data.toolOutput.offsetBytes) {
1076
+ return {
1077
+ applied: false,
1078
+ needsReconcile: true,
1079
+ reason: "tool_output_offset_mismatch"
1080
+ };
1081
+ }
1082
+ output.text = data.toolOutput.operation === "set" ? data.toolOutput.text : currentText + data.toolOutput.text;
1083
+ next.payload.output = output;
1084
+ }
1085
+ for (const [payloadKey, value] of Object.entries(data.payloadSet ?? {})) {
1086
+ next.payload[payloadKey] = cloneJSONValue(value);
1087
+ }
1088
+ for (const payloadKey of data.payloadUnset ?? []) {
1089
+ delete next.payload[payloadKey];
1090
+ }
1091
+ if (data.status !== void 0) next.status = data.status;
1092
+ if (data.semantics !== void 0) {
1093
+ next.semantics = cloneJSONValue(
1094
+ data.semantics
1095
+ );
1096
+ }
1097
+ if (data.startedAtUnixMs !== void 0) {
1098
+ next.startedAtUnixMs = data.startedAtUnixMs;
1099
+ }
1100
+ if (data.completedAtUnixMs !== void 0) {
1101
+ next.completedAtUnixMs = data.completedAtUnixMs;
1102
+ }
1103
+ const payloadUnset = new Set(optimistic.get(key)?.payloadUnset ?? []);
1104
+ for (const payloadKey of Object.keys(data.payloadSet ?? {})) {
1105
+ payloadUnset.delete(payloadKey);
1106
+ }
1107
+ for (const payloadKey of data.payloadUnset ?? []) {
1108
+ payloadUnset.add(payloadKey);
1109
+ }
1110
+ optimistic.set(key, {
1111
+ message: next,
1112
+ payloadUnset,
1113
+ explicitlyTerminal: (optimistic.get(key)?.explicitlyTerminal ?? false) || deltaIsExplicitlyTerminal(data)
1114
+ });
1115
+ return { applied: true, needsReconcile: false };
1116
+ }
1117
+ }
1118
+ function recordValue4(value) {
1119
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? cloneJSONValue(value) : null;
1120
+ }
1121
+ function utf8ByteLength(value) {
1122
+ return new TextEncoder().encode(value).byteLength;
1123
+ }
1124
+ function materialize(canonical, overlay, payloadUnset) {
1125
+ const materialized = {
1126
+ ...canonical,
1127
+ ...overlay,
1128
+ version: canonical.version,
1129
+ sequence: canonical.sequence ?? overlay.sequence,
1130
+ createdAtUnixMs: canonical.createdAtUnixMs ?? overlay.createdAtUnixMs,
1131
+ payload: {
1132
+ ...canonical.payload,
1133
+ ...overlay.payload
1134
+ },
1135
+ semantics: overlay.semantics ?? canonical.semantics
1136
+ };
1137
+ for (const key of payloadUnset) {
1138
+ delete materialized.payload[key];
1139
+ }
1140
+ return materialized;
1141
+ }
1142
+ function isTerminalMessage(message) {
1143
+ if (message.completedAtUnixMs !== void 0) return true;
1144
+ return isTerminalStatus(message.status);
1145
+ }
1146
+ function deltaIsExplicitlyTerminal(data) {
1147
+ return data.completedAtUnixMs !== void 0 || isTerminalStatus(data.status);
1148
+ }
1149
+ function isTerminalStatus(status) {
1150
+ return ["completed", "failed", "canceled", "interrupted"].includes(
1151
+ status ?? ""
1152
+ );
1153
+ }
1154
+ function liveMessageKey(event) {
1155
+ return `${identityPrefix(event.workspaceId, event.agentSessionId)}${event.data.messageId}`;
1156
+ }
1157
+ function messageKey(message) {
1158
+ return `${identityPrefix(message.workspaceId ?? "", message.agentSessionId)}${message.messageId}`;
1159
+ }
1160
+ function identityPrefix(workspaceId, agentSessionId) {
1161
+ return `${workspaceId}\0${agentSessionId}\0`;
1162
+ }
1163
+ function scopePrefix(scope) {
1164
+ return identityPrefix(scope.workspaceId, scope.agentSessionId);
1165
+ }
1166
+ function normalizeCanonicalMessages(scope, messages) {
1167
+ return messages.map((message) => {
1168
+ if (message.workspaceId !== void 0 && message.workspaceId !== scope.workspaceId || message.agentSessionId !== scope.agentSessionId) {
1169
+ throw new Error(
1170
+ "canonical Agent activity message is outside the optimistic overlay scope"
1171
+ );
1172
+ }
1173
+ return cloneMessage({
1174
+ ...message,
1175
+ workspaceId: scope.workspaceId
1176
+ });
1177
+ });
1178
+ }
1179
+ function deleteScopeEntries(entries, prefix) {
1180
+ for (const key of entries.keys()) {
1181
+ if (key.startsWith(prefix)) {
1182
+ entries.delete(key);
1183
+ }
1184
+ }
1185
+ }
1186
+ function cloneMessage(message) {
1187
+ return mergeAgentActivityMessages([], [message])[0];
1188
+ }
1189
+
840
1190
  // src/pagination.ts
841
1191
  var DEFAULT_MAX_MESSAGE_PAGES = 1e3;
842
1192
  function agentActivitySessionMessageWindowFromDescendingPage(page) {
@@ -1034,11 +1384,11 @@ function stringValue2(value) {
1034
1384
 
1035
1385
  // src/usage.ts
1036
1386
  function resolveAgentActivityUsage(input) {
1037
- const usage = recordValue3(input.sessionUsage);
1387
+ const usage = recordValue5(input.sessionUsage);
1038
1388
  if (!usage) {
1039
1389
  return null;
1040
1390
  }
1041
- const contextWindow = recordValue3(usage.contextWindow);
1391
+ const contextWindow = recordValue5(usage.contextWindow);
1042
1392
  const usedTokens = finiteNumber(contextWindow?.usedTokens);
1043
1393
  const totalTokens = finiteNumber(contextWindow?.totalTokens);
1044
1394
  const quotas = Array.isArray(usage.quotas) ? usage.quotas.map(normalizeQuota).filter((quota) => quota !== null) : [];
@@ -1054,7 +1404,7 @@ function resolveAgentActivityUsage(input) {
1054
1404
  };
1055
1405
  }
1056
1406
  function normalizeQuota(value) {
1057
- const record = recordValue3(value);
1407
+ const record = recordValue5(value);
1058
1408
  const quotaType = quotaTypeValue(record?.quotaType);
1059
1409
  if (!record || !quotaType) return null;
1060
1410
  const quota = { quotaType };
@@ -1083,7 +1433,7 @@ function quotaTypeValue(value) {
1083
1433
  return null;
1084
1434
  }
1085
1435
  }
1086
- function recordValue3(value) {
1436
+ function recordValue5(value) {
1087
1437
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
1088
1438
  }
1089
1439
  function finiteNumber(value) {
@@ -6572,6 +6922,7 @@ function workspaceAgentSessionStatus(session) {
6572
6922
  }
6573
6923
  }
6574
6924
  export {
6925
+ AGENT_ACTIVITY_LIVE_PROTOCOL_REVISION,
6575
6926
  AGENT_CAPABILITY_KEYS,
6576
6927
  AGENT_SESSION_ENGINE_LOCAL_ORIGIN,
6577
6928
  ENGINE_INTENT_BATCH_DELAY_MS,
@@ -6581,6 +6932,7 @@ export {
6581
6932
  canonicalTurnKey,
6582
6933
  cloneAgentActivityMessage,
6583
6934
  compareAgentActivityMessages,
6935
+ createAgentActivityOptimisticMessageOverlay,
6584
6936
  createAgentActivitySnapshotProjector,
6585
6937
  createAgentSessionEngine,
6586
6938
  createEmptyAgentActivitySnapshot,
@@ -6593,6 +6945,7 @@ export {
6593
6945
  normalizeAgentActivityCapabilityReferences,
6594
6946
  normalizeAgentActivityDisplayStatus,
6595
6947
  normalizeAgentActivitySession,
6948
+ parseAgentActivityMessageDeltaEvent,
6596
6949
  parseInlineActivityMessages,
6597
6950
  pendingSubmitRecordListsEqual,
6598
6951
  resolveAgentActivityCapability,