@tutti-os/agent-gui 0.0.187 → 0.0.189

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.
@@ -68,7 +68,7 @@ import {
68
68
  toLocalShortDateTime,
69
69
  updateAgentComposerDraft,
70
70
  useProjectedAgentConversation
71
- } from "./chunk-62JB3KCN.js";
71
+ } from "./chunk-BVA5SVOD.js";
72
72
  import {
73
73
  agentRichTextContentToPromptText,
74
74
  createAgentRichTextInputExtensions,
@@ -2174,17 +2174,37 @@ function mergeProfilesIntoSnapshot(snapshot, users) {
2174
2174
 
2175
2175
  // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
2176
2176
  function projectWorkspaceAgentMessagesToTimelineItems(messages) {
2177
- const sortedMessages = latestMessageSnapshots(messages).filter((message) => !isGoalControlAudit(message)).sort(compareMessagesByDisplayOrder);
2177
+ const sortedMessages = latestMessageSnapshots(messages).sort(
2178
+ compareMessagesByDisplayOrder
2179
+ );
2178
2180
  const mergedToolPayloadByKey = /* @__PURE__ */ new Map();
2179
2181
  return sortedMessages.map((message, index) => {
2180
2182
  const kind = normalizeToken(message.kind);
2181
2183
  const role = normalizeToken(message.role);
2182
2184
  const payload = normalizedPayload(message.payload);
2185
+ const goalControlAudit = isGoalControlAudit(message);
2183
2186
  const id = normalizedMessageId(message.version, index);
2184
2187
  const seq = index + 1;
2185
- const eventId = message.messageId.trim() || `message:${id}`;
2188
+ const eventId = goalControlAudit ? firstNonEmptyString(
2189
+ stringValue(payload.messageId),
2190
+ message.messageId,
2191
+ `message:${id}`
2192
+ ) : message.messageId.trim() || `message:${id}`;
2186
2193
  const turnId = message.turnId?.trim() || void 0;
2187
2194
  const occurredAtUnixMs = messageDisplayOrderTime(message);
2195
+ if (goalControlAudit) {
2196
+ return messageTimelineItem({
2197
+ message,
2198
+ id,
2199
+ seq,
2200
+ eventId,
2201
+ actorType: "user",
2202
+ itemType: "goal.control",
2203
+ role: "user",
2204
+ content: messageText(message),
2205
+ occurredAtUnixMs
2206
+ });
2207
+ }
2188
2208
  if (kind === "tool_call") {
2189
2209
  const callId = firstNonEmptyString(
2190
2210
  messagePayloadString(message, "callId"),
@@ -3654,6 +3674,20 @@ function createOptimisticPromptMessage(input) {
3654
3674
  startedAtUnixMs: input.occurredAtUnixMs
3655
3675
  };
3656
3676
  }
3677
+ function createOptimisticGoalControlMessage(input) {
3678
+ const message = createOptimisticPromptMessage(input);
3679
+ return {
3680
+ ...message,
3681
+ kind: "session_audit",
3682
+ payload: {
3683
+ ...message.payload,
3684
+ action: input.goalControl.action,
3685
+ goalControl: true,
3686
+ ...input.goalControl.objective !== void 0 ? { objective: input.goalControl.objective } : {},
3687
+ messageId: message.messageId
3688
+ }
3689
+ };
3690
+ }
3657
3691
  function projectAgentGUIMessagesToTimelineItems(messages) {
3658
3692
  return mergeAgentGUITimelineItems(
3659
3693
  [],
@@ -5182,7 +5216,7 @@ function stabilizeConversationDetail(previous, next) {
5182
5216
  previous.activity,
5183
5217
  next.activity
5184
5218
  );
5185
- if (previous.cwd === next.cwd && previous.workspaceRoot === next.workspaceRoot && previous.showProcessingIndicator === next.showProcessingIndicator && previous.turns === next.turns && previous.sessionTurns === next.sessionTurns && previous.session === session && previous.activity === activity) {
5219
+ if (previous.cwd === next.cwd && previous.workspaceRoot === next.workspaceRoot && previous.showProcessingIndicator === next.showProcessingIndicator && previous.goalControls === next.goalControls && previous.turns === next.turns && previous.sessionTurns === next.sessionTurns && previous.session === session && previous.activity === activity) {
5186
5220
  return previous;
5187
5221
  }
5188
5222
  return {
@@ -5952,7 +5986,19 @@ function useAgentGUIActiveMessages(input) {
5952
5986
  workspaceId
5953
5987
  })
5954
5988
  );
5955
- const pendingActivationMessage = activePendingActivation?.mode === "new" && isPendingActivationViable(activePendingActivation) && activePendingActivation.clientSubmitId && activePendingActivation.content.length > 0 ? createOptimisticPromptMessage({
5989
+ const pendingActivationMessage = activePendingActivation?.mode === "new" && isPendingActivationViable(activePendingActivation) && activePendingActivation.clientSubmitId && activePendingActivation.content.length > 0 ? activePendingActivation.initialGoalControl ? createOptimisticGoalControlMessage({
5990
+ agentSessionId: activePendingActivation.agentSessionId,
5991
+ clientSubmitId: activePendingActivation.clientSubmitId,
5992
+ content: [...activePendingActivation.content],
5993
+ displayPrompt: activePendingActivation.displayPrompt,
5994
+ goalControl: activePendingActivation.initialGoalControl,
5995
+ occurredAtUnixMs: activePendingActivation.requestedAtUnixMs,
5996
+ turnId: createPendingOptimisticTurnId(
5997
+ activePendingActivation.clientSubmitId
5998
+ ),
5999
+ userId: currentUserId?.trim() || "user",
6000
+ workspaceId
6001
+ }) : createOptimisticPromptMessage({
5956
6002
  agentSessionId: activePendingActivation.agentSessionId,
5957
6003
  clientSubmitId: activePendingActivation.clientSubmitId,
5958
6004
  content: [...activePendingActivation.content],
@@ -9094,11 +9140,102 @@ import {
9094
9140
  import {
9095
9141
  selectEngineQueuedPrompt
9096
9142
  } from "@tutti-os/agent-activity-core";
9143
+
9144
+ // agent-gui/agentGuiNode/queuedPromptImageLoadOwner.ts
9145
+ function queuedPromptImageLoadRequestIdentity(request) {
9146
+ return [
9147
+ request.imageKey,
9148
+ request.workspaceId,
9149
+ request.agentSessionId,
9150
+ request.attachmentId,
9151
+ request.path,
9152
+ request.mimeType,
9153
+ request.name,
9154
+ request.remoteUrl
9155
+ ].join("\0");
9156
+ }
9157
+ function queuedPromptImageHasSafeRemoteUrl(value) {
9158
+ try {
9159
+ const url = new URL(value);
9160
+ return url.protocol === "https:" && Boolean(url.hostname) && !url.username && !url.password;
9161
+ } catch {
9162
+ return false;
9163
+ }
9164
+ }
9165
+ var QueuedPromptImageLoadOwner = class {
9166
+ constructor(request, onSource) {
9167
+ this.request = request;
9168
+ this.onSource = onSource;
9169
+ }
9170
+ request;
9171
+ onSource;
9172
+ canceled = false;
9173
+ start() {
9174
+ const {
9175
+ agentSessionId,
9176
+ attachmentId,
9177
+ mimeType,
9178
+ name,
9179
+ path,
9180
+ runtime,
9181
+ workspaceId
9182
+ } = this.request;
9183
+ const readAsset = async () => {
9184
+ if (attachmentId) {
9185
+ return await runtime.readSessionAttachment?.({
9186
+ workspaceId,
9187
+ agentSessionId,
9188
+ attachmentId
9189
+ });
9190
+ }
9191
+ return await runtime.readPromptAsset?.({
9192
+ workspaceId,
9193
+ agentSessionId,
9194
+ mimeType,
9195
+ name,
9196
+ path
9197
+ });
9198
+ };
9199
+ void readAsset().then((asset) => {
9200
+ if (this.canceled || !asset) {
9201
+ return;
9202
+ }
9203
+ this.onSource(`data:${asset.mimeType};base64,${asset.data}`);
9204
+ }).catch((error) => {
9205
+ if (this.canceled) {
9206
+ return;
9207
+ }
9208
+ this.onSource(null);
9209
+ console.warn(
9210
+ "[agent-gui]",
9211
+ JSON.stringify({
9212
+ event: "agent.gui.queued_prompt_image_load_failed",
9213
+ level: "warn",
9214
+ source: "agent-gui",
9215
+ workspaceId,
9216
+ details: {
9217
+ agentSessionId: agentSessionId || null,
9218
+ attachmentId: attachmentId || null,
9219
+ path: path || null,
9220
+ error: error instanceof Error ? error.message : String(error)
9221
+ }
9222
+ })
9223
+ );
9224
+ });
9225
+ }
9226
+ dispose() {
9227
+ this.canceled = true;
9228
+ }
9229
+ };
9230
+
9231
+ // agent-gui/agentGuiNode/controller/useAgentGUIQueueActions.ts
9097
9232
  function useAgentGUIQueueActions({
9098
9233
  activeConversationIdRef,
9234
+ agentActivityRuntime,
9099
9235
  previewMode,
9100
9236
  sessionEngine,
9101
- setDraftByScopeKey
9237
+ setDraftByScopeKey,
9238
+ workspaceId
9102
9239
  }) {
9103
9240
  const removeQueuedPrompt = useCallback17(
9104
9241
  (queuedPromptId) => {
@@ -9144,6 +9281,13 @@ function useAgentGUIQueueActions({
9144
9281
  if (!queuedPrompt) {
9145
9282
  return;
9146
9283
  }
9284
+ const draftScopeKey = resolveAgentComposerDraftScopeKey({
9285
+ agentSessionId
9286
+ });
9287
+ const restoredDraft = agentPromptContentToComposerDraft(
9288
+ queuedPrompt.content,
9289
+ `restore-${queuedPrompt.id}`
9290
+ );
9147
9291
  sessionEngine.dispatch(
9148
9292
  queuedPrompt.clientSubmitId ? {
9149
9293
  agentSessionId,
@@ -9157,13 +9301,65 @@ function useAgentGUIQueueActions({
9157
9301
  );
9158
9302
  setDraftByScopeKey((current) => ({
9159
9303
  ...current,
9160
- [resolveAgentComposerDraftScopeKey({ agentSessionId })]: agentPromptContentToComposerDraft(
9161
- queuedPrompt.content,
9162
- `restore-${queuedPrompt.id}`
9163
- )
9304
+ [draftScopeKey]: restoredDraft
9164
9305
  }));
9306
+ for (const restoredImage of agentComposerDraftImages(restoredDraft)) {
9307
+ const attachmentId = restoredImage.attachmentId?.trim() ?? "";
9308
+ const path = restoredImage.path?.trim() ?? "";
9309
+ if (restoredImage.previewUrl || !attachmentId && !path) {
9310
+ continue;
9311
+ }
9312
+ const owner = new QueuedPromptImageLoadOwner(
9313
+ {
9314
+ agentSessionId,
9315
+ attachmentId,
9316
+ imageKey: restoredImage.id,
9317
+ mimeType: restoredImage.mimeType,
9318
+ name: restoredImage.name,
9319
+ path,
9320
+ remoteUrl: restoredImage.url?.trim() ?? "",
9321
+ runtime: agentActivityRuntime,
9322
+ workspaceId
9323
+ },
9324
+ (source) => {
9325
+ if (!source) {
9326
+ return;
9327
+ }
9328
+ setDraftByScopeKey((current) => {
9329
+ const currentDraft = current[draftScopeKey];
9330
+ if (!currentDraft) {
9331
+ return current;
9332
+ }
9333
+ let updated = false;
9334
+ const images = agentComposerDraftImages(currentDraft).map(
9335
+ (currentImage) => {
9336
+ if (currentImage.id !== restoredImage.id || currentImage.previewUrl || currentImage.attachmentId !== restoredImage.attachmentId || currentImage.path !== restoredImage.path || currentImage.url !== restoredImage.url) {
9337
+ return currentImage;
9338
+ }
9339
+ updated = true;
9340
+ return { ...currentImage, previewUrl: source };
9341
+ }
9342
+ );
9343
+ return updated ? {
9344
+ ...current,
9345
+ [draftScopeKey]: updateAgentComposerDraft(currentDraft, {
9346
+ images
9347
+ })
9348
+ } : current;
9349
+ });
9350
+ }
9351
+ );
9352
+ owner.start();
9353
+ }
9165
9354
  },
9166
- [activeConversationIdRef, previewMode, sessionEngine, setDraftByScopeKey]
9355
+ [
9356
+ activeConversationIdRef,
9357
+ agentActivityRuntime,
9358
+ previewMode,
9359
+ sessionEngine,
9360
+ setDraftByScopeKey,
9361
+ workspaceId
9362
+ ]
9167
9363
  );
9168
9364
  const sendQueuedPromptNext = useCallback17(
9169
9365
  (queuedPromptId) => {
@@ -20143,7 +20339,7 @@ import { Spinner as Spinner2 } from "@tutti-os/ui-system";
20143
20339
  // agent-gui/agentGuiNode/composer/AgentComposerDraftPreview.tsx
20144
20340
  import { useState as useState13 } from "react";
20145
20341
  import { Spinner } from "@tutti-os/ui-system";
20146
- import { X as X2 } from "lucide-react";
20342
+ import { ImageIcon, X as X2 } from "lucide-react";
20147
20343
  import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
20148
20344
  function AgentComposerDraftImagePreview({
20149
20345
  image,
@@ -20178,7 +20374,7 @@ function AgentComposerDraftImagePreview({
20178
20374
  "data-upload-error": image.uploadError ? "true" : void 0,
20179
20375
  style: previewStyle,
20180
20376
  children: [
20181
- /* @__PURE__ */ jsx22(
20377
+ image.previewUrl ? /* @__PURE__ */ jsx22(
20182
20378
  ZoomableImage,
20183
20379
  {
20184
20380
  src: image.previewUrl,
@@ -20200,6 +20396,13 @@ function AgentComposerDraftImagePreview({
20200
20396
  setAspectRatio(nextRatio);
20201
20397
  }
20202
20398
  }
20399
+ ) : /* @__PURE__ */ jsx22(
20400
+ "div",
20401
+ {
20402
+ className: "grid size-full place-items-center text-[var(--text-tertiary)]",
20403
+ "data-testid": "agent-gui-composer-image-preview-pending",
20404
+ children: /* @__PURE__ */ jsx22(ImageIcon, { "aria-hidden": true, size: 22, strokeWidth: 1.8 })
20405
+ }
20203
20406
  ),
20204
20407
  image.uploading ? /* @__PURE__ */ jsx22(
20205
20408
  "div",
@@ -20547,95 +20750,6 @@ import {
20547
20750
  useTextOverflow
20548
20751
  } from "@tutti-os/ui-system";
20549
20752
  import { extractPlainTextFromContent } from "@tutti-os/ui-rich-text";
20550
-
20551
- // agent-gui/agentGuiNode/queuedPromptImageLoadOwner.ts
20552
- function queuedPromptImageLoadRequestIdentity(request) {
20553
- return [
20554
- request.imageKey,
20555
- request.workspaceId,
20556
- request.agentSessionId,
20557
- request.attachmentId,
20558
- request.path,
20559
- request.mimeType,
20560
- request.name,
20561
- request.remoteUrl
20562
- ].join("\0");
20563
- }
20564
- function queuedPromptImageHasSafeRemoteUrl(value) {
20565
- try {
20566
- const url = new URL(value);
20567
- return url.protocol === "https:" && Boolean(url.hostname) && !url.username && !url.password;
20568
- } catch {
20569
- return false;
20570
- }
20571
- }
20572
- var QueuedPromptImageLoadOwner = class {
20573
- constructor(request, onSource) {
20574
- this.request = request;
20575
- this.onSource = onSource;
20576
- }
20577
- request;
20578
- onSource;
20579
- canceled = false;
20580
- start() {
20581
- const {
20582
- agentSessionId,
20583
- attachmentId,
20584
- mimeType,
20585
- name,
20586
- path,
20587
- runtime,
20588
- workspaceId
20589
- } = this.request;
20590
- const readAsset = async () => {
20591
- if (attachmentId) {
20592
- return await runtime.readSessionAttachment?.({
20593
- workspaceId,
20594
- agentSessionId,
20595
- attachmentId
20596
- });
20597
- }
20598
- return await runtime.readPromptAsset?.({
20599
- workspaceId,
20600
- agentSessionId,
20601
- mimeType,
20602
- name,
20603
- path
20604
- });
20605
- };
20606
- void readAsset().then((asset) => {
20607
- if (this.canceled || !asset) {
20608
- return;
20609
- }
20610
- this.onSource(`data:${asset.mimeType};base64,${asset.data}`);
20611
- }).catch((error) => {
20612
- if (this.canceled) {
20613
- return;
20614
- }
20615
- this.onSource(null);
20616
- console.warn(
20617
- "[agent-gui]",
20618
- JSON.stringify({
20619
- event: "agent.gui.queued_prompt_image_load_failed",
20620
- level: "warn",
20621
- source: "agent-gui",
20622
- workspaceId,
20623
- details: {
20624
- agentSessionId: agentSessionId || null,
20625
- attachmentId: attachmentId || null,
20626
- path: path || null,
20627
- error: error instanceof Error ? error.message : String(error)
20628
- }
20629
- })
20630
- );
20631
- });
20632
- }
20633
- dispose() {
20634
- this.canceled = true;
20635
- }
20636
- };
20637
-
20638
- // agent-gui/agentGuiNode/AgentQueuedPromptPanel.tsx
20639
20753
  import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
20640
20754
  var EMPTY_WORKSPACE_APP_ICONS2 = [];
20641
20755
  var QUEUED_PROMPT_OVERFLOW_DESCENDANTS = '[data-workspace-agent-markdown="true"], .tsh-agent-object-token__main';
@@ -40693,4 +40807,4 @@ export {
40693
40807
  AgentHandoffMenu,
40694
40808
  AgentGUI
40695
40809
  };
40696
- //# sourceMappingURL=chunk-43M2GHDA.js.map
40810
+ //# sourceMappingURL=chunk-F5YFT4VB.js.map