@beeuni/sdk 0.1.0 → 0.3.0

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.
Files changed (291) hide show
  1. package/README.md +53 -92
  2. package/dist/beeuni.esm.min.js +36 -34
  3. package/dist/beeuni.global.js +36 -34
  4. package/dist/browser/cache/idb-sync-cache.js +15 -5
  5. package/dist/browser/session-sync/server-transcript-mirror.d.ts +7 -1
  6. package/dist/browser/session-sync/server-transcript-mirror.js +30 -24
  7. package/dist/browser/session-sync/session-sync-registry.d.ts +3 -1
  8. package/dist/browser/session-sync/session-sync-registry.js +48 -3
  9. package/dist/browser/stores/sync-store/keep-unchanged.d.ts +4 -0
  10. package/dist/browser/stores/sync-store/keep-unchanged.js +34 -0
  11. package/dist/browser/stores/sync-store.d.ts +7 -0
  12. package/dist/browser/stores/sync-store.js +122 -35
  13. package/dist/core/attachments/prompt-attachments.d.ts +4 -0
  14. package/dist/core/attachments/prompt-attachments.js +34 -0
  15. package/dist/core/capture/rules.d.ts +17 -0
  16. package/dist/core/capture/rules.js +27 -0
  17. package/dist/core/client/beeuni.d.ts +99 -34
  18. package/dist/core/client/beeuni.js +5 -11
  19. package/dist/core/client/capture.d.ts +105 -0
  20. package/dist/core/client/capture.js +48 -0
  21. package/dist/core/client/facade-catalog.d.ts +0 -4
  22. package/dist/core/client/facade-catalog.js +1 -5
  23. package/dist/core/client/facade-identity.d.ts +1 -0
  24. package/dist/core/client/facade-identity.js +1 -0
  25. package/dist/core/client/project-access-resources.d.ts +3 -1
  26. package/dist/core/client/project-access-resources.js +1 -1
  27. package/dist/core/client/project-connections.d.ts +2 -2
  28. package/dist/core/client/project-connections.js +2 -2
  29. package/dist/core/client/project-operations-admin.d.ts +4 -4
  30. package/dist/core/client/project-operations-review.d.ts +2 -3
  31. package/dist/core/client/project-operations-review.js +1 -0
  32. package/dist/core/client/project-operations-workspace.d.ts +4 -4
  33. package/dist/core/client/project-operations-workspace.js +1 -1
  34. package/dist/core/client/project-operations.d.ts +9 -19
  35. package/dist/core/client/project-operations.js +2 -6
  36. package/dist/core/client/project-platform-security.d.ts +1 -1
  37. package/dist/core/client/project-platform-settings.d.ts +1 -1
  38. package/dist/core/client/session-context.d.ts +2 -0
  39. package/dist/core/client/session-handle.d.ts +13 -0
  40. package/dist/core/client/session-lifecycle-resources.d.ts +11 -0
  41. package/dist/core/client/session-lifecycle-resources.js +4 -0
  42. package/dist/core/client/session-lifecycle-security.d.ts +2 -0
  43. package/dist/core/client/session-lifecycle-security.js +1 -0
  44. package/dist/core/client/session-readiness.d.ts +2 -0
  45. package/dist/core/client/session-readiness.js +20 -1
  46. package/dist/core/http/api-client.d.ts +1 -7
  47. package/dist/core/http/api-client.js +2 -37
  48. package/dist/core/http/auth.d.ts +2 -4
  49. package/dist/core/http/auth.js +2 -8
  50. package/dist/core/http/config.d.ts +2 -0
  51. package/dist/core/http/response-error.js +26 -11
  52. package/dist/core/http/transport.js +6 -1
  53. package/dist/core/models/composer-model.d.ts +14 -0
  54. package/dist/core/models/composer-model.js +21 -1
  55. package/dist/core/rest/platform-client/capture.d.ts +363 -0
  56. package/dist/core/rest/platform-client/capture.js +116 -0
  57. package/dist/core/rest/platform-client/client-policy.d.ts +8 -0
  58. package/dist/core/rest/platform-client/client-policy.js +30 -0
  59. package/dist/core/rest/platform-client/index.d.ts +4 -4
  60. package/dist/core/rest/platform-client/index.js +4 -4
  61. package/dist/core/rest/platform-client/lifecycle.js +18 -12
  62. package/dist/core/rest/platform-client/shared.d.ts +5 -0
  63. package/dist/core/rest/platform-client/shared.js +18 -0
  64. package/dist/core/rest/platform-client/types.d.ts +1 -1
  65. package/dist/core/rest/projects-client/account-secret-resources.d.ts +2 -1
  66. package/dist/core/rest/projects-client/accounts.d.ts +34 -0
  67. package/dist/core/rest/projects-client/accounts.js +10 -0
  68. package/dist/core/rest/projects-client/admin-providers.d.ts +0 -61
  69. package/dist/core/rest/projects-client/admin-providers.js +0 -6
  70. package/dist/core/rest/projects-client/agent-config.d.ts +3 -0
  71. package/dist/core/rest/projects-client/apps-fleet.d.ts +5 -1
  72. package/dist/core/rest/projects-client/apps-fleet.js +2 -2
  73. package/dist/core/rest/projects-client/apps.d.ts +11 -1
  74. package/dist/core/rest/projects-client/change-requests.d.ts +2 -0
  75. package/dist/core/rest/projects-client/change-requests.js +2 -0
  76. package/dist/core/rest/projects-client/connectors.d.ts +13 -55
  77. package/dist/core/rest/projects-client/connectors.js +5 -29
  78. package/dist/core/rest/projects-client/files.d.ts +3 -0
  79. package/dist/core/rest/projects-client/files.js +4 -0
  80. package/dist/core/rest/projects-client/gateway.d.ts +5 -0
  81. package/dist/core/rest/projects-client/git-backend.d.ts +1 -10
  82. package/dist/core/rest/projects-client/git-backend.js +0 -10
  83. package/dist/core/rest/projects-client/iam-actions.d.ts +76 -0
  84. package/dist/core/rest/projects-client/iam-actions.js +101 -0
  85. package/dist/core/rest/projects-client/iam-sso.d.ts +0 -10
  86. package/dist/core/rest/projects-client/iam-sso.js +0 -3
  87. package/dist/core/rest/projects-client/iam.d.ts +1 -0
  88. package/dist/core/rest/projects-client/iam.js +1 -0
  89. package/dist/core/rest/projects-client/index.d.ts +1 -4
  90. package/dist/core/rest/projects-client/index.js +1 -4
  91. package/dist/core/rest/projects-client/notifications.d.ts +1 -1
  92. package/dist/core/rest/projects-client/notifications.js +4 -0
  93. package/dist/core/rest/projects-client/projects.d.ts +4 -2
  94. package/dist/core/rest/projects-client/projects.js +4 -2
  95. package/dist/core/rest/projects-client/review-items.d.ts +2 -0
  96. package/dist/core/rest/projects-client/review-items.js +4 -0
  97. package/dist/core/rest/projects-client/review.d.ts +17 -3
  98. package/dist/core/rest/projects-client/review.js +11 -0
  99. package/dist/core/rest/projects-client/sandbox.d.ts +8 -9
  100. package/dist/core/rest/projects-client/secrets.d.ts +3 -0
  101. package/dist/core/rest/projects-client/session-attachments.js +14 -1
  102. package/dist/core/rest/projects-client/session-sandbox.d.ts +1 -1
  103. package/dist/core/rest/projects-client/sessions.d.ts +31 -4
  104. package/dist/core/rest/projects-client/sessions.js +34 -4
  105. package/dist/core/runtime/runtime-rest-client.js +1 -1
  106. package/dist/core/runtime/runtime-types.d.ts +1 -0
  107. package/dist/core/session/control-stream.d.ts +1 -0
  108. package/dist/core/session/control-stream.js +18 -1
  109. package/dist/core/session/open-bundle.d.ts +4 -4
  110. package/dist/core/session/open-bundle.js +29 -46
  111. package/dist/core/session/turn-end-watch.d.ts +47 -0
  112. package/dist/core/session/turn-end-watch.js +141 -0
  113. package/dist/core/session-log/guard.d.ts +6 -0
  114. package/dist/core/session-log/guard.js +109 -0
  115. package/dist/core/session-log/index.d.ts +7 -0
  116. package/dist/core/session-log/index.js +5 -0
  117. package/dist/core/session-log/saved-log.d.ts +10 -0
  118. package/dist/core/session-log/saved-log.js +25 -0
  119. package/dist/core/session-log/source.d.ts +25 -0
  120. package/dist/core/session-log/source.js +30 -0
  121. package/dist/core/session-log/store.d.ts +21 -0
  122. package/dist/core/session-log/store.js +126 -0
  123. package/dist/core/session-log/tool-call.d.ts +11 -0
  124. package/dist/core/session-log/tool-call.js +65 -0
  125. package/dist/core/session-log/turns/blocks.d.ts +60 -0
  126. package/dist/core/session-log/turns/blocks.js +124 -0
  127. package/dist/core/session-log/turns/history.d.ts +32 -0
  128. package/dist/core/session-log/turns/history.js +99 -0
  129. package/dist/core/session-log/turns/index.d.ts +4 -0
  130. package/dist/core/session-log/turns/index.js +4 -0
  131. package/dist/core/session-log/turns/metrics.d.ts +21 -0
  132. package/dist/core/session-log/turns/metrics.js +29 -0
  133. package/dist/core/session-log/turns/turn.d.ts +55 -0
  134. package/dist/core/session-log/turns/turn.js +279 -0
  135. package/dist/core/session-log/turns/v1-parts.d.ts +8 -0
  136. package/dist/core/session-log/turns/v1-parts.js +43 -0
  137. package/dist/core/session-log/types.d.ts +264 -0
  138. package/dist/core/session-log/types.js +6 -0
  139. package/dist/core/session-log/v1-view.d.ts +13 -0
  140. package/dist/core/session-log/v1-view.js +215 -0
  141. package/dist/core/session-log/v1.d.ts +31 -0
  142. package/dist/core/session-log/v1.js +473 -0
  143. package/dist/core/session-sync/copy-store-types.d.ts +19 -0
  144. package/dist/core/session-sync/copy-store-types.js +1 -0
  145. package/dist/core/session-sync/saved-copy-store.js +25 -4
  146. package/dist/core/session-sync/saved-transcript.d.ts +15 -1
  147. package/dist/core/session-sync/saved-transcript.js +55 -0
  148. package/dist/core/session-sync/session-sync-controller.js +3 -0
  149. package/dist/core/stream/event-stream.js +2 -2
  150. package/dist/core/turns/classify.d.ts +2 -1
  151. package/dist/core/turns/classify.js +7 -3
  152. package/dist/core/turns/edit-blocks.d.ts +1 -0
  153. package/dist/core/turns/edit-blocks.js +15 -0
  154. package/dist/core/turns/parts.d.ts +3 -2
  155. package/dist/core/turns/parts.js +4 -2
  156. package/dist/core/turns/segments/burst-summary.d.ts +1 -0
  157. package/dist/core/turns/segments/burst-summary.js +24 -0
  158. package/dist/core/turns/segments/group-steps.d.ts +4 -3
  159. package/dist/core/turns/segments/group-steps.js +9 -6
  160. package/dist/core/turns/segments/index.d.ts +1 -0
  161. package/dist/core/turns/segments/index.js +1 -0
  162. package/dist/core/turns/segments/narration.d.ts +5 -4
  163. package/dist/core/turns/segments/narration.js +12 -3
  164. package/dist/core/turns/segments/session-activity-groups.d.ts +2 -1
  165. package/dist/core/turns/segments/session-activity-groups.js +3 -1
  166. package/dist/core/turns/segments/step-label.d.ts +2 -1
  167. package/dist/core/turns/segments/step-label.js +3 -1
  168. package/dist/core/turns/segments/work-split.d.ts +10 -0
  169. package/dist/core/turns/segments/work-split.js +40 -0
  170. package/dist/core/turns/segments/working-turn.d.ts +4 -2
  171. package/dist/core/turns/segments/working-turn.js +9 -8
  172. package/dist/core/turns/state.d.ts +2 -7
  173. package/dist/core/turns/state.js +28 -134
  174. package/dist/core/turns/tool-kind.d.ts +1 -1
  175. package/dist/core/turns/tool-kind.js +3 -2
  176. package/dist/core/turns/tool-registry.js +1 -0
  177. package/dist/core/turns/tools/tool-meta.d.ts +3 -2
  178. package/dist/core/turns/tools/tool-meta.js +5 -2
  179. package/dist/core/turns/tools/tool-outcome.d.ts +2 -1
  180. package/dist/core/turns/tools/tool-outcome.js +3 -1
  181. package/dist/core/turns/types.d.ts +1 -1
  182. package/dist/core/turns/view-model.js +1 -13
  183. package/dist/core/warm-session-pool.d.ts +29 -0
  184. package/dist/core/warm-session-pool.js +127 -0
  185. package/dist/genui/catalog.d.ts +28 -0
  186. package/dist/genui/catalog.js +396 -0
  187. package/dist/genui/expansion.d.ts +3 -0
  188. package/dist/genui/expansion.js +295 -0
  189. package/dist/genui/fence-entry.d.ts +2 -0
  190. package/dist/genui/fence-entry.js +1 -0
  191. package/dist/genui/fence.d.ts +21 -0
  192. package/dist/genui/fence.js +138 -0
  193. package/dist/genui/index.d.ts +6 -0
  194. package/dist/genui/index.js +6 -0
  195. package/dist/genui/markdown.d.ts +12 -0
  196. package/dist/genui/markdown.js +104 -0
  197. package/dist/genui/parse.d.ts +6 -0
  198. package/dist/genui/parse.js +75 -0
  199. package/dist/genui/prompt.d.ts +2 -0
  200. package/dist/genui/prompt.js +206 -0
  201. package/dist/genui/react/default-components.d.ts +2 -0
  202. package/dist/genui/react/default-components.js +72 -0
  203. package/dist/genui/react/default-components.test.d.ts +1 -0
  204. package/dist/genui/react/default-components.test.js +94 -0
  205. package/dist/genui/react/genui-block-disabled.test.d.ts +1 -0
  206. package/dist/genui/react/genui-block-disabled.test.js +50 -0
  207. package/dist/genui/react/genui-block.d.ts +28 -0
  208. package/dist/genui/react/genui-block.js +91 -0
  209. package/dist/genui/react/genui-block.test.d.ts +1 -0
  210. package/dist/genui/react/genui-block.test.js +205 -0
  211. package/dist/genui/react/index.d.ts +2 -0
  212. package/dist/genui/react/index.js +2 -0
  213. package/dist/genui/share.d.ts +5 -0
  214. package/dist/genui/share.js +30 -0
  215. package/dist/genui/test-fixtures.d.ts +2 -0
  216. package/dist/genui/test-fixtures.js +16 -0
  217. package/dist/genui/types.d.ts +29 -0
  218. package/dist/genui/types.js +1 -0
  219. package/dist/genui/urls.d.ts +1 -0
  220. package/dist/genui/urls.js +18 -0
  221. package/dist/genui/validate.d.ts +9 -0
  222. package/dist/genui/validate.js +116 -0
  223. package/dist/index.d.ts +4 -4
  224. package/dist/index.js +4 -4
  225. package/dist/internal/connector-catalog.d.ts +48 -0
  226. package/dist/internal/connector-catalog.js +27 -0
  227. package/dist/internal/host-configuration.d.ts +22 -0
  228. package/dist/internal/host-configuration.js +28 -0
  229. package/dist/internal/platform-admin-react.d.ts +12 -0
  230. package/dist/internal/platform-admin-react.js +13 -0
  231. package/dist/internal/platform-admin.d.ts +9 -0
  232. package/dist/internal/platform-admin.js +9 -0
  233. package/dist/platform/ui.d.ts +8 -2
  234. package/dist/platform/ui.js +19 -4
  235. package/dist/react/chat/use-chat-turns.d.ts +1 -1
  236. package/dist/react/human-presence.d.ts +9 -0
  237. package/dist/react/human-presence.js +12 -0
  238. package/dist/react/index.d.ts +4 -13
  239. package/dist/react/index.js +4 -13
  240. package/dist/react/opencode.d.ts +1 -0
  241. package/dist/react/opencode.js +1 -0
  242. package/dist/react/query-contracts.d.ts +6 -0
  243. package/dist/react/query-contracts.js +6 -0
  244. package/dist/react/query-keys.d.ts +17 -2
  245. package/dist/react/query-keys.js +24 -2
  246. package/dist/react/reset-identity-state.js +2 -0
  247. package/dist/react/session-cache-write.d.ts +1 -0
  248. package/dist/react/session-cache-write.js +20 -0
  249. package/dist/react/session-transcript-subscription.js +3 -1
  250. package/dist/react/sign-in-with-beeuni.d.ts +6 -6
  251. package/dist/react/turn-end-handoff.d.ts +13 -0
  252. package/dist/react/turn-end-handoff.js +101 -0
  253. package/dist/react/use-admin-providers.d.ts +3 -6
  254. package/dist/react/use-admin-providers.js +1 -11
  255. package/dist/react/use-capture.d.ts +47 -0
  256. package/dist/react/use-capture.js +173 -0
  257. package/dist/react/use-feature-flag.js +1 -0
  258. package/dist/react/use-opencode-events/handle-event.d.ts +1 -0
  259. package/dist/react/use-opencode-events/handle-event.js +5 -0
  260. package/dist/react/use-opencode-events/handle-interaction-event.js +8 -3
  261. package/dist/react/use-opencode-events/handle-session-event.js +13 -8
  262. package/dist/react/use-opencode-events/handler-context.d.ts +1 -0
  263. package/dist/react/use-opencode-events/helpers.d.ts +1 -0
  264. package/dist/react/use-opencode-events/helpers.js +11 -1
  265. package/dist/react/use-opencode-events/index.js +1 -0
  266. package/dist/react/use-opencode-local.d.ts +5 -1
  267. package/dist/react/use-opencode-local.js +15 -2
  268. package/dist/react/use-opencode-sessions/commands.d.ts +11 -1
  269. package/dist/react/use-opencode-sessions/commands.js +21 -1
  270. package/dist/react/use-opencode-sessions/permissions.js +28 -1
  271. package/dist/react/use-project-sessions.d.ts +1 -1
  272. package/dist/react/use-project-sessions.js +6 -5
  273. package/dist/react/use-prompt-attachments.js +1 -0
  274. package/dist/react/use-review-summary.d.ts +13 -0
  275. package/dist/react/use-review-summary.js +32 -0
  276. package/dist/react/use-runtime-reconnect.js +1 -1
  277. package/dist/react/use-session-list-state.d.ts +6 -0
  278. package/dist/react/use-session-list-state.js +33 -0
  279. package/dist/react/use-session-log.d.ts +16 -0
  280. package/dist/react/use-session-log.js +143 -0
  281. package/dist/react/use-session-messages.d.ts +2 -1
  282. package/dist/react/use-session-messages.js +15 -14
  283. package/dist/react/use-session-stream.js +12 -1
  284. package/dist/react/use-session-sync.d.ts +2 -2
  285. package/dist/react/use-session-sync.js +10 -8
  286. package/dist/react/use-session-transcript-history.js +2 -12
  287. package/dist/react/use-session-working.d.ts +2 -0
  288. package/dist/react/use-session-working.js +10 -0
  289. package/dist/react/use-session.d.ts +6 -0
  290. package/dist/react/use-session.js +88 -6
  291. package/package.json +62 -8
@@ -1,6 +1,7 @@
1
1
  import type { MessageWithParts } from '../../transcript.js';
2
2
  import type { Part, ToolPart } from '../runtime/client.js';
3
3
  import { type GatewayAttemptFailure } from './errors.js';
4
+ import type { ToolCallBlock } from '../session-log/types.js';
4
5
  import { type ToolKind } from './tool-kind.js';
5
6
  import type { TokenUsageLike } from './types.js';
6
7
  export type ToolStatus = 'pending' | 'running' | 'done' | 'error';
@@ -30,7 +31,7 @@ export interface ToolView {
30
31
  answers?: string[][];
31
32
  childSessionId?: string;
32
33
  }
33
- export declare function toToolView(part: Pick<ToolPart, 'tool' | 'state'>): ToolView;
34
+ export declare function toToolView(call: Pick<ToolPart, 'tool' | 'state'> | ToolCallBlock): ToolView;
34
35
  export interface ClassifiedTextPart {
35
36
  kind: 'text';
36
37
  id: string;
@@ -1,5 +1,7 @@
1
1
  import { extractGatewayErrorDetails, unwrapError } from './errors.js';
2
2
  import { getChildSessionId } from './parts.js';
3
+ import { isToolCallBlock, toolPartOf } from '../session-log/tool-call.js';
4
+ import { editBlocks } from './edit-blocks.js';
3
5
  import { inputPath, toolKind } from './tool-kind.js';
4
6
  import { toolInfo } from './tool-registry.js';
5
7
  const MAX_PARSEABLE_OUTPUT_LENGTH = 256 * 1024;
@@ -91,11 +93,12 @@ function toolFiles(kind, input, metadata) {
91
93
  const filediff = record(metadata.filediff);
92
94
  const patch = filediff ? undefined : text(metadata.patch);
93
95
  const counts = patch ? patchLineCounts(patch) : undefined;
96
+ const blocks = filediff || patch ? [] : editBlocks(input);
94
97
  return [
95
98
  defined({
96
99
  path,
97
- before: text(filediff?.before) ?? text(input.oldString),
98
- after: text(filediff?.after) ?? text(input.newString),
100
+ before: text(filediff?.before) ?? (blocks.length ? blocks.map(([before]) => before).join('\n') : undefined),
101
+ after: text(filediff?.after) ?? (blocks.length ? blocks.map(([, after]) => after).join('\n') : text(input.new_source)),
99
102
  patch,
100
103
  additions: count(filediff?.additions) ?? counts?.additions,
101
104
  deletions: count(filediff?.deletions) ?? counts?.deletions,
@@ -153,7 +156,8 @@ function classifyToolState(tool, state) {
153
156
  childSessionId: getChildSessionId({ tool, state }),
154
157
  };
155
158
  }
156
- export function toToolView(part) {
159
+ export function toToolView(call) {
160
+ const part = isToolCallBlock(call) ? toolPartOf(call) : call;
157
161
  return classifyToolState(part.tool, part.state);
158
162
  }
159
163
  function classifyText(part) {
@@ -0,0 +1 @@
1
+ export declare function editBlocks(input: Record<string, unknown> | undefined): Array<[string, string]>;
@@ -0,0 +1,15 @@
1
+ export function editBlocks(input) {
2
+ const one = pair(input);
3
+ if (one)
4
+ return [one];
5
+ const edits = Array.isArray(input?.edits) ? input.edits : [];
6
+ return edits.flatMap((edit) => {
7
+ const block = edit && typeof edit === 'object' ? pair(edit) : undefined;
8
+ return block ? [block] : [];
9
+ });
10
+ }
11
+ function pair(input) {
12
+ const before = input?.oldString ?? input?.old_string ?? input?.oldText;
13
+ const after = input?.newString ?? input?.new_string ?? input?.newText;
14
+ return typeof before === 'string' && typeof after === 'string' ? [before, after] : undefined;
15
+ }
@@ -1,3 +1,4 @@
1
+ import type { ToolCallBlock } from '../session-log/types.js';
1
2
  import type { Diagnostic, MessageWithPartsLike, PartLike, RequestWithToolLike, ToolInfo, ToolPartLike } from './types.js';
2
3
  export declare function isTextPart<P extends PartLike>(part: P): part is P & {
3
4
  type: 'text';
@@ -42,8 +43,8 @@ export interface HiddenToolRef {
42
43
  }
43
44
  export declare function getHiddenToolParts(permission: RequestWithToolLike | undefined, question: RequestWithToolLike | undefined): HiddenToolRef[];
44
45
  export declare function isToolPartHidden(part: Pick<ToolPartLike, 'callID'>, messageId: string, hidden: HiddenToolRef[]): boolean;
45
- export declare function shouldShowToolPart(part: Pick<ToolPartLike, 'tool'>): boolean;
46
- export declare function getChildSessionId(part: Pick<ToolPartLike, 'tool' | 'state'>): string | undefined;
46
+ export declare function shouldShowToolPart(part: Pick<ToolPartLike, 'tool'> | ToolCallBlock): boolean;
47
+ export declare function getChildSessionId(call: Pick<ToolPartLike, 'tool' | 'state'> | ToolCallBlock): string | undefined;
47
48
  export declare function getChildSessionError(childMessages: readonly MessageWithPartsLike[] | undefined): string | undefined;
48
49
  export declare function getChildSessionToolParts<M extends MessageWithPartsLike>(childMessages: readonly M[]): Array<M['parts'][number] & {
49
50
  type: 'tool';
@@ -1,4 +1,5 @@
1
1
  import { unwrapError } from './errors.js';
2
+ import { isToolCallBlock, toolPartOf } from '../session-log/tool-call.js';
2
3
  import { inputPath, toolKind } from './tool-kind.js';
3
4
  import { normalizeName } from './tools/tool-meta.js';
4
5
  export function isTextPart(part) {
@@ -67,7 +68,7 @@ export function isToolPartHidden(part, messageId, hidden) {
67
68
  }
68
69
  const HIDDEN_TOOLS = new Set(['todoread', 'context_info']);
69
70
  export function shouldShowToolPart(part) {
70
- return !HIDDEN_TOOLS.has(part.tool);
71
+ return !HIDDEN_TOOLS.has(isToolCallBlock(part) ? part.name : part.tool);
71
72
  }
72
73
  const CHILD_SESSION_TOOLS = new Set([
73
74
  'task',
@@ -82,7 +83,8 @@ const CHILD_SESSION_TOOLS = new Set([
82
83
  'task_update',
83
84
  'task_message',
84
85
  ]);
85
- export function getChildSessionId(part) {
86
+ export function getChildSessionId(call) {
87
+ const part = isToolCallBlock(call) ? toolPartOf(call) : call;
86
88
  const tool = part.tool || '';
87
89
  if (tool.startsWith('oc-'))
88
90
  return undefined;
@@ -7,3 +7,4 @@ export interface BurstSummary {
7
7
  }
8
8
  export declare function burstSummary(parts: ReadonlyArray<Part>): BurstSummary;
9
9
  export declare function burstSummaryLabel(summary: BurstSummary, running: boolean): string;
10
+ export declare function burstWorkLabel(parts: ReadonlyArray<Part>): string;
@@ -1,5 +1,6 @@
1
1
  import { isReasoningPart, isToolPart } from '../parts.js';
2
2
  import { partOutcome } from '../tools/tool-outcome.js';
3
+ import { familyForTool, narrateStep } from './narration.js';
3
4
  import { stepLabel } from './step-label.js';
4
5
  export function burstSummary(parts) {
5
6
  let total = 0;
@@ -43,3 +44,26 @@ export function burstSummaryLabel(summary, running) {
43
44
  return `${steps(total)} failed`;
44
45
  return `Completed ${completed} of ${total} steps · ${failed} failed`;
45
46
  }
47
+ export function burstWorkLabel(parts) {
48
+ const families = new Map();
49
+ let failed = 0;
50
+ for (const part of parts) {
51
+ if (!isToolPart(part) || stepLabel(part).tier === 'plumbing')
52
+ continue;
53
+ const family = familyForTool(part.tool);
54
+ if (family === 'hidden')
55
+ continue;
56
+ families.set(family, [...(families.get(family) ?? []), part]);
57
+ if (partOutcome(part) !== 'ok')
58
+ failed += 1;
59
+ }
60
+ if (families.size === 0)
61
+ return burstSummaryLabel(burstSummary(parts), false);
62
+ const label = [...families]
63
+ .map(([family, calls], i) => {
64
+ const sentence = narrateStep(family, calls);
65
+ return i === 0 ? sentence : sentence.charAt(0).toLowerCase() + sentence.slice(1);
66
+ })
67
+ .join(', ');
68
+ return failed > 0 ? `${label} · ${failed} failed` : label;
69
+ }
@@ -1,11 +1,12 @@
1
1
  import type { ToolPart } from '../../runtime/client.js';
2
+ import type { ToolCallBlock } from '../../session-log/types.js';
2
3
  import { type StepFamily } from './narration.js';
3
- export interface Step {
4
+ export interface Step<P extends ToolPart | ToolCallBlock = ToolPart> {
4
5
  id: string;
5
6
  family: StepFamily;
6
7
  label: string;
7
- parts: ToolPart[];
8
+ parts: P[];
8
9
  status: 'running' | 'error' | 'done';
9
10
  durationMs?: number;
10
11
  }
11
- export declare function groupSteps(parts: ToolPart[]): Step[];
12
+ export declare function groupSteps<P extends ToolPart | ToolCallBlock = ToolPart>(given: P[]): Step<P>[];
@@ -1,3 +1,4 @@
1
+ import { asToolPart } from '../../session-log/tool-call.js';
1
2
  import { isEmptyShowPart, isNoGroupActivityTool } from './session-activity-groups.js';
2
3
  import { familyForTool, narrateFailedStep, narrateStep } from './narration.js';
3
4
  function statusOf(parts) {
@@ -22,18 +23,19 @@ function durationOf(parts) {
22
23
  return undefined;
23
24
  return end - start;
24
25
  }
25
- function finalize(family, parts) {
26
+ function finalize(family, given) {
27
+ const parts = given.map(asToolPart);
26
28
  const status = statusOf(parts);
27
29
  return {
28
30
  id: parts[0].callID,
29
31
  family,
30
32
  label: status === 'error' ? narrateFailedStep(family, parts) : narrateStep(family, parts),
31
- parts,
33
+ parts: given,
32
34
  status,
33
35
  durationMs: status === 'running' ? undefined : durationOf(parts),
34
36
  };
35
37
  }
36
- export function groupSteps(parts) {
38
+ export function groupSteps(given) {
37
39
  const steps = [];
38
40
  let family = null;
39
41
  let buffer = [];
@@ -43,7 +45,8 @@ export function groupSteps(parts) {
43
45
  family = null;
44
46
  buffer = [];
45
47
  };
46
- for (const part of parts) {
48
+ for (const item of given) {
49
+ const part = asToolPart(item);
47
50
  const f = familyForTool(part.tool);
48
51
  if (f === 'hidden')
49
52
  continue;
@@ -51,14 +54,14 @@ export function groupSteps(parts) {
51
54
  continue;
52
55
  if (isNoGroupActivityTool(part.tool)) {
53
56
  flush();
54
- steps.push(finalize(f, [part]));
57
+ steps.push(finalize(f, [item]));
55
58
  continue;
56
59
  }
57
60
  if (f !== family) {
58
61
  flush();
59
62
  family = f;
60
63
  }
61
- buffer.push(part);
64
+ buffer.push(item);
62
65
  }
63
66
  flush();
64
67
  return steps;
@@ -10,3 +10,4 @@ export * from './show-group.js';
10
10
  export * from './step-label.js';
11
11
  export * from './working-turn.js';
12
12
  export * from './turn-busy-visibility.js';
13
+ export * from './work-split.js';
@@ -10,3 +10,4 @@ export * from './show-group.js';
10
10
  export * from './step-label.js';
11
11
  export * from './working-turn.js';
12
12
  export * from './turn-busy-visibility.js';
13
+ export * from './work-split.js';
@@ -1,9 +1,10 @@
1
1
  import type { ToolPart } from '../../runtime/client.js';
2
- export type StepFamily = 'explore' | 'edit' | 'run' | 'web' | 'create' | 'plan' | 'delegate' | 'sessions' | 'memory' | 'connectors' | 'automations' | 'projects' | 'skills' | 'ask' | 'retired' | 'other';
2
+ import type { ToolCallBlock } from '../../session-log/types.js';
3
+ export type StepFamily = 'explore' | 'edit' | 'run' | 'script' | 'web' | 'create' | 'plan' | 'delegate' | 'sessions' | 'memory' | 'connectors' | 'automations' | 'projects' | 'skills' | 'ask' | 'retired' | 'other';
3
4
  export declare function familyForTool(toolName: string): StepFamily | 'hidden';
4
5
  export declare function narrationToolName(toolName: string): string;
5
6
  export declare function contextLabelForTool(toolName: string): string;
6
7
  export type CreateArtifactKind = 'image' | 'video' | 'presentation';
7
- export declare function createArtifactKind(part: ToolPart): CreateArtifactKind | null;
8
- export declare function narrateStep(family: StepFamily, parts: ToolPart[]): string;
9
- export declare function narrateFailedStep(family: StepFamily, parts: ToolPart[]): string;
8
+ export declare function createArtifactKind(call: ToolPart | ToolCallBlock): CreateArtifactKind | null;
9
+ export declare function narrateStep(family: StepFamily, calls: ReadonlyArray<ToolPart | ToolCallBlock>): string;
10
+ export declare function narrateFailedStep(family: StepFamily, calls: ReadonlyArray<ToolPart | ToolCallBlock>): string;
@@ -1,3 +1,4 @@
1
+ import { asToolPart } from '../../session-log/tool-call.js';
1
2
  import { inputPath, toolKind } from '../tool-kind.js';
2
3
  import { getToolPrimaryArg, normalizeName } from '../tools/tool-meta.js';
3
4
  import { parseWebSearchOutput, wsDomain } from '../tools/web-helpers.js';
@@ -23,6 +24,7 @@ const FAMILY_OF_KIND = {
23
24
  apply_patch: 'edit',
24
25
  bash: 'run',
25
26
  pty: 'run',
27
+ script: 'script',
26
28
  web_search: 'web',
27
29
  webfetch: 'web',
28
30
  media: 'create',
@@ -286,7 +288,8 @@ function createPartKey(part) {
286
288
  return 'shown:result';
287
289
  }
288
290
  const PRESENTATION_GEN_ARTIFACT_ACTIONS = new Set(['create_slide', 'export_pdf', 'export_pptx']);
289
- export function createArtifactKind(part) {
291
+ export function createArtifactKind(call) {
292
+ const part = asToolPart(call);
290
293
  const t = normalizeName(part.tool);
291
294
  if (t === 'image_gen')
292
295
  return 'image';
@@ -337,7 +340,8 @@ function mixedCreateSentence(keys) {
337
340
  });
338
341
  return `Worked on ${joinWithAnd(segments)}`;
339
342
  }
340
- export function narrateStep(family, parts) {
343
+ export function narrateStep(family, calls) {
344
+ const parts = calls.map(asToolPart);
341
345
  const n = parts.length;
342
346
  const arg = firstArg(parts);
343
347
  switch (family) {
@@ -358,6 +362,8 @@ export function narrateStep(family, parts) {
358
362
  }
359
363
  case 'run':
360
364
  return n === 1 ? 'Ran a command' : `Ran ${n} commands`;
365
+ case 'script':
366
+ return n === 1 ? 'Ran a script' : `Ran ${n} scripts`;
361
367
  case 'web': {
362
368
  const isSearch = (p) => {
363
369
  const t = normalizeName(p.tool);
@@ -525,7 +531,8 @@ export function narrateStep(family, parts) {
525
531
  }
526
532
  }
527
533
  }
528
- export function narrateFailedStep(family, parts) {
534
+ export function narrateFailedStep(family, calls) {
535
+ const parts = calls.map(asToolPart);
529
536
  const arg = firstArg(parts);
530
537
  switch (family) {
531
538
  case 'explore':
@@ -539,6 +546,8 @@ export function narrateFailedStep(family, parts) {
539
546
  }
540
547
  case 'run':
541
548
  return 'A command failed';
549
+ case 'script':
550
+ return 'A script failed';
542
551
  case 'web':
543
552
  return "Couldn't finish searching the web";
544
553
  case 'create':
@@ -1,3 +1,4 @@
1
+ import type { ToolCallBlock } from '../../session-log/types.js';
1
2
  export declare function normalizeActivityToolName(toolName: string | undefined): string;
2
3
  export declare function isShellActivityTool(toolName: string | undefined): boolean;
3
4
  export declare function isQuestionTool(toolName: string | undefined): boolean;
@@ -15,6 +16,6 @@ export interface ActivityPartLike {
15
16
  input?: Record<string, unknown> | null;
16
17
  } | null;
17
18
  }
18
- export declare function isEmptyShowPart(part: ActivityPartLike): boolean;
19
+ export declare function isEmptyShowPart(call: ActivityPartLike | ToolCallBlock): boolean;
19
20
  export declare const STANDALONE_TOOLS: ReadonlySet<string>;
20
21
  export declare function isStandaloneActivityTool(toolName: string | undefined): boolean;
@@ -1,4 +1,5 @@
1
1
  import { isShowPayloadEmpty } from '../tools/show-availability.js';
2
+ import { isToolCallBlock, toolPartOf } from '../../session-log/tool-call.js';
2
3
  export function normalizeActivityToolName(toolName) {
3
4
  return (toolName ?? '').replace(/^oc-/, '').replace(/-/g, '_');
4
5
  }
@@ -34,7 +35,8 @@ export function isInvisibleActivityPart(part) {
34
35
  return true;
35
36
  return false;
36
37
  }
37
- export function isEmptyShowPart(part) {
38
+ export function isEmptyShowPart(call) {
39
+ const part = isToolCallBlock(call) ? toolPartOf(call) : call;
38
40
  const name = normalizeActivityToolName(part.tool);
39
41
  if (name !== 'show' && name !== 'show_user')
40
42
  return false;
@@ -1,4 +1,5 @@
1
1
  import type { Part } from '../../runtime/client.js';
2
+ import type { SessionLogBlock, ToolCallBlock } from '../../session-log/types.js';
2
3
  export type StepTier = 'primary' | 'reasoning' | 'plumbing';
3
4
  export interface StepLabel {
4
5
  verb: string;
@@ -7,4 +8,4 @@ export interface StepLabel {
7
8
  tier: StepTier;
8
9
  }
9
10
  export declare const PLUMBING_TOOLS: ReadonlySet<string>;
10
- export declare function stepLabel(part: Part): StepLabel;
11
+ export declare function stepLabel(call: Part | ToolCallBlock | SessionLogBlock): StepLabel;
@@ -1,6 +1,7 @@
1
1
  import { isReasoningPart, isToolPart } from '../parts.js';
2
2
  import { humanizeSearchQuery } from '../tools/search-query.js';
3
3
  import { normalizeActivityToolName } from './session-activity-groups.js';
4
+ import { isToolCallBlock, toolPartOf } from '../../session-log/tool-call.js';
4
5
  export const PLUMBING_TOOLS = new Set([
5
6
  'get_mem',
6
7
  'memory_search',
@@ -63,7 +64,8 @@ function readObject(input, keys) {
63
64
  }
64
65
  return undefined;
65
66
  }
66
- export function stepLabel(part) {
67
+ export function stepLabel(call) {
68
+ const part = (isToolCallBlock(call) ? toolPartOf(call) : call);
67
69
  if (isReasoningPart(part)) {
68
70
  return { verb: 'Thought', running: 'Thinking', object: undefined, tier: 'reasoning' };
69
71
  }
@@ -0,0 +1,10 @@
1
+ import type { ShowGroupedSegment } from './show-group.js';
2
+ export interface TurnWorkSplit<S extends ShowGroupedSegment = ShowGroupedSegment> {
3
+ work: S[];
4
+ hoisted: S[];
5
+ final: S[];
6
+ }
7
+ export declare function splitTurnWork<S extends ShowGroupedSegment = ShowGroupedSegment>(segments: ReadonlyArray<S>, opts: {
8
+ working: boolean;
9
+ }): TurnWorkSplit<S> | null;
10
+ export declare function workedForLabel(durationMs: number | null): string;
@@ -0,0 +1,40 @@
1
+ import { formatDuration } from '../state.js';
2
+ import { normalizeActivityToolName } from './session-activity-groups.js';
3
+ function isDeliverableSegment(segment) {
4
+ if (segment.kind === 'show-group')
5
+ return true;
6
+ if (segment.kind !== 'standalone')
7
+ return false;
8
+ const name = normalizeActivityToolName(segment.part.tool);
9
+ return name === 'show' || name === 'show_user';
10
+ }
11
+ function isBlankText(segment) {
12
+ return segment.kind === 'text' && !segment.part.text?.trim();
13
+ }
14
+ export function splitTurnWork(segments, opts) {
15
+ if (opts.working)
16
+ return null;
17
+ let finalIndex = -1;
18
+ for (let i = segments.length - 1; i >= 0; i--) {
19
+ const segment = segments[i];
20
+ if (isDeliverableSegment(segment) || isBlankText(segment))
21
+ continue;
22
+ if (segment.kind === 'text')
23
+ finalIndex = i;
24
+ break;
25
+ }
26
+ const split = { work: [], hoisted: [], final: [] };
27
+ segments.forEach((segment, i) => {
28
+ if (i === finalIndex)
29
+ split.final.push(segment);
30
+ else if (isDeliverableSegment(segment))
31
+ split.hoisted.push(segment);
32
+ else
33
+ split.work.push(segment);
34
+ });
35
+ return split.work.length > 0 ? split : null;
36
+ }
37
+ export function workedForLabel(durationMs) {
38
+ const duration = durationMs == null ? '' : formatDuration(durationMs);
39
+ return duration ? `Worked for ${duration}` : 'Worked';
40
+ }
@@ -1,4 +1,5 @@
1
1
  import type { SessionPrompt } from '../../rest/projects-client/sessions.js';
2
+ import type { SessionLogTurn } from '../../session-log/turns/turn.js';
2
3
  interface TurnLike {
3
4
  userMessage: {
4
5
  info: {
@@ -14,6 +15,7 @@ interface TurnLike {
14
15
  };
15
16
  }>;
16
17
  }
18
+ type BlockTurnLike = Pick<SessionLogTurn, 'id' | 'assistant'>;
17
19
  export interface WorkingTurnResolution {
18
20
  workingTurnId: string | null;
19
21
  pendingTurnIds: string[];
@@ -38,7 +40,7 @@ interface DeliveringTurnInput {
38
40
  };
39
41
  }
40
42
  export declare function fallbackBusyRowAfterTurnId(input: QueuedTurnInput & DeliveringTurnInput & {
41
- turns: ReadonlyArray<TurnLike>;
43
+ turns: ReadonlyArray<TurnLike | BlockTurnLike>;
42
44
  }): string | null;
43
45
  export declare function turnIsConfirmedActive(input: {
44
46
  isTurnWorking: boolean;
@@ -61,7 +63,7 @@ export declare function workingTurnDrawsBusyRow(input: {
61
63
  isRetrying: boolean;
62
64
  awaitingUser?: boolean;
63
65
  }): boolean;
64
- export declare function freshSendHint(turns: ReadonlyArray<TurnLike>, isSentTurn: (userMessageId: string) => boolean): string | null;
66
+ export declare function freshSendHint(turns: ReadonlyArray<TurnLike | BlockTurnLike>, isSentTurn: (userMessageId: string) => boolean): string | null;
65
67
  export declare function resolveWorkingTurn(input: {
66
68
  turns: ReadonlyArray<TurnLike>;
67
69
  hintMessageId: string | null | undefined;
@@ -1,4 +1,6 @@
1
1
  import { showTurnBusyIndicator } from './turn-busy-visibility.js';
2
+ const turnIdOf = (turn) => ('id' in turn ? turn.id : turn.userMessage.info.id);
3
+ const replyCountOf = (turn) => ('assistant' in turn ? turn.assistant.length : turn.assistantMessages.length);
2
4
  const completedAt = (info) => info.time?.completed;
3
5
  export function shouldSuppressWorkingTurnBusy(input) {
4
6
  if (!input.hasPendingTurns || !input.newestAssistantCompleted)
@@ -8,18 +10,17 @@ export function shouldSuppressWorkingTurnBusy(input) {
8
10
  (input.activeTurnId !== null && input.activeTurnId !== input.workingTurnId));
9
11
  }
10
12
  function isQueuedTurn(turn, input) {
11
- const id = turn.userMessage.info.id;
12
- return (input.pendingTurnIds.has(id) ||
13
- (turn.assistantMessages.length === 0 && input.pendingPromptIds.has(id)));
13
+ const id = turnIdOf(turn);
14
+ return input.pendingTurnIds.has(id) || (replyCountOf(turn) === 0 && input.pendingPromptIds.has(id));
14
15
  }
15
16
  export function fallbackBusyRowAfterTurnId(input) {
16
- const delivering = input.turns.find((turn) => input.deliveringPromptIds.has(turn.userMessage.info.id));
17
+ const delivering = input.turns.find((turn) => input.deliveringPromptIds.has(turnIdOf(turn)));
17
18
  if (delivering)
18
- return delivering.userMessage.info.id;
19
+ return turnIdOf(delivering);
19
20
  const firstQueued = input.turns.findIndex((turn) => isQueuedTurn(turn, input));
20
21
  if (firstQueued <= 0)
21
22
  return null;
22
- return input.turns[firstQueued - 1].userMessage.info.id;
23
+ return turnIdOf(input.turns[firstQueued - 1]);
23
24
  }
24
25
  export function turnIsConfirmedActive(input) {
25
26
  return input.isTurnWorking && !input.pendingDelivery && input.activeTurnId === input.turnId;
@@ -47,10 +48,10 @@ export function workingTurnDrawsBusyRow(input) {
47
48
  }
48
49
  export function freshSendHint(turns, isSentTurn) {
49
50
  for (let i = turns.length - 1; i >= 0; i--) {
50
- const id = turns[i].userMessage.info.id;
51
+ const id = turnIdOf(turns[i]);
51
52
  if (!isSentTurn(id))
52
53
  continue;
53
- return turns[i].assistantMessages.length === 0 ? id : null;
54
+ return replyCountOf(turns[i]) === 0 ? id : null;
54
55
  }
55
56
  return null;
56
57
  }
@@ -1,5 +1,5 @@
1
1
  import { extractGatewayErrorDetails } from './errors.js';
2
- import type { MessageInfoLike, MessageWithPartsLike, ModelPricingLookup, PartLike, PartWithMessage, RetryInfo, SessionStatusLike, TurnCostInfo, TurnLike } from './types.js';
2
+ import type { MessageWithPartsLike, PartLike, PartWithMessage, RetryInfo, SessionStatusLike, TurnCostInfo, TurnLike } from './types.js';
3
3
  export declare function isLastUserMessage(messageId: string, allMessages: readonly MessageWithPartsLike[]): boolean;
4
4
  export declare function getWorkingState(sessionStatus: SessionStatusLike | undefined, isLast: boolean): boolean;
5
5
  export declare function shouldHideResponsePart(working: boolean, responsePartId: string | undefined): boolean;
@@ -11,12 +11,7 @@ export declare function getTurnStatus(parts: ReadonlyArray<{
11
11
  part: PartLike;
12
12
  }>, childMessages?: readonly MessageWithPartsLike[]): string;
13
13
  export declare function formatDuration(ms: number): string;
14
- export declare const COST_MARKUP = 1.2;
15
- export declare function getTurnCost(parts: ReadonlyArray<PartWithMessage>, lookup?: ModelPricingLookup): TurnCostInfo | undefined;
16
- export declare function getSessionCost(messages: ReadonlyArray<{
17
- info?: MessageInfoLike;
18
- parts: PartLike[];
19
- }>, lookup?: ModelPricingLookup): number;
14
+ export declare function getTurnTokens(parts: ReadonlyArray<PartWithMessage>): TurnCostInfo['tokens'] | undefined;
20
15
  export declare function formatCost(cost: number): string;
21
16
  export declare function formatTokens(tokens: number): string;
22
17
  export declare function getRetryInfo(status: SessionStatusLike | undefined): RetryInfo | undefined;