@parhelia/core 0.1.12782 → 0.1.12784

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.
@@ -1,4 +1,4 @@
1
1
  export function selectComponents(componentIds) {
2
- window.top?.window.postMessage({ componentIds, type: "componentsSelected" }, "*");
2
+ window.top?.window.postMessage({ componentIds, type: "componentsSelected" }, window.location.origin);
3
3
  }
4
4
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client-components/api.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,YAAsB;IACrD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAC5B,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAC5C,GAAG,CACJ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/client-components/api.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,YAAsB;IACrD,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAC5B,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,CACvB,CAAC;AACJ,CAAC"}
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import React, { useEffect, useState, useRef, useCallback, useLayoutEffect, useMemo, } from "react";
3
3
  import { flushSync } from "react-dom";
4
4
  import { Send, AlertCircle, Loader2, Wand2, Square, Mic, MicOff, ChevronDown, ChevronUp, ArrowLeft, DollarSign, ExternalLink, Settings2, Target, X, Plus, Lock, } from "lucide-react";
5
- import { getAgent, startAgent, claimAgentBrowser, cancelAgentDialog, assignAgentSkill, persistDraftAgent, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkillCatalog, getAgentAvailableTools, getAgentOperationAllowances, getAgentTriggerSubscriptions, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, getAgentDiagnostics, releaseAgentBrowser, rejectToolCall, revokeAgentSkill, isAgentReadOnly, } from "../services/agentService";
5
+ import { getAgent, startAgent, claimAgentBrowser, cancelAgentDialog, acceptAgentDialog, replayAgentDialog, assignAgentSkill, persistDraftAgent, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkillCatalog, getAgentAvailableTools, getAgentOperationAllowances, getAgentTriggerSubscriptions, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, getAgentDiagnostics, releaseAgentBrowser, rejectToolCall, revokeAgentSkill, isAgentReadOnly, } from "../services/agentService";
6
6
  import { parseAgentRunStatusData, parseAgentStatus, } from "../services/agentStatus";
7
7
  import { useEditContext, useFieldsEditContext } from "../client/editContext";
8
8
  import { localStorageService } from "../services/localStorageService";
@@ -47,7 +47,7 @@ import { forceEditorSocketReconnect } from "../client/hooks/useEditorWebSocket";
47
47
  import { SimpleTabs } from "../ui/SimpleTabs";
48
48
  import { Splitter } from "../ui/Splitter";
49
49
  import { ScrollingContentTree } from "../ScrollingContentTree";
50
- import { requestAgentSubscriptionReplay, subscribeAgent, } from "../services/agentSubscriptionRegistry";
50
+ import { subscribeAgent } from "../services/agentSubscriptionRegistry";
51
51
  import { registerMountedInstance, unregisterMountedInstance, setVisibleDialogEntry, clearVisibleDialogEntriesForInstance, updateInstanceFocus, isElectedDialogReceiver, } from "./agentDialogRegistry";
52
52
  const RECENT_RUN_EVENTS_LIMIT = 50;
53
53
  const STOP_STALE_RUNNING_LOAD_SUPPRESSION_MS = 5000;
@@ -79,6 +79,10 @@ function hasStaleRunningLoadSuppression(agentId) {
79
79
  }
80
80
  return true;
81
81
  }
82
+ function normalizeInitialPrompt(value) {
83
+ const trimmed = value?.trim();
84
+ return trimmed ? trimmed : null;
85
+ }
82
86
  // interface AgentTerminalProps {
83
87
  // agentStub: Agent;
84
88
  // }
@@ -90,6 +94,10 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, onReloadPr
90
94
  const effectiveIsVisible = isVisible ?? isActive ?? true;
91
95
  const effectiveIsFocused = isFocused ?? isActive ?? true;
92
96
  const editContext = useEditContext();
97
+ const editContextRef = useRef(editContext);
98
+ useEffect(() => {
99
+ editContextRef.current = editContext;
100
+ }, [editContext]);
93
101
  const fieldsContext = useFieldsEditContext();
94
102
  const [agent, setAgent] = useState(() => buildPlaceholderAgentDetails(agentStub));
95
103
  const [messages, setMessages] = useState([]);
@@ -373,19 +381,79 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, onReloadPr
373
381
  if (activeCallbackId === normalizedCallbackId) {
374
382
  return;
375
383
  }
376
- const replayRequested = requestAgentSubscriptionReplay(agentId);
377
- appendToolUiEvent(replayRequested
378
- ? "ui:pending-dialog-replay-requested"
379
- : "ui:pending-dialog-replay-skipped", `${dialogType || "dialog"} callbackId=${normalizedCallbackId} agentId=${agentId}`);
384
+ if (!editContext?.sessionId) {
385
+ appendToolUiEvent("ui:pending-dialog-replay-skipped", `${dialogType || "dialog"} callbackId=${normalizedCallbackId} agentId=${agentId} reason=no-session`);
386
+ return;
387
+ }
388
+ void replayAgentDialog({
389
+ callbackId: normalizedCallbackId,
390
+ agentId,
391
+ reason: "frontend-recover",
392
+ terminalInstanceId: dialogTerminalInstanceIdRef.current,
393
+ sessionId: editContext.sessionId,
394
+ })
395
+ .then((result) => {
396
+ appendToolUiEvent("ui:pending-dialog-replay-requested", `${dialogType || "dialog"} callbackId=${normalizedCallbackId} agentId=${agentId} replayed=${result.replayed ?? 0}`);
397
+ })
398
+ .catch((error) => {
399
+ appendToolUiEvent("ui:pending-dialog-replay-failed", `${dialogType || "dialog"} callbackId=${normalizedCallbackId} agentId=${agentId} error=${error instanceof Error ? error.message : String(error)}`);
400
+ });
380
401
  }, 750);
381
402
  pendingDialogReplayTimeoutsRef.current.add(timeout);
382
- }, [appendToolUiEvent]);
403
+ }, [appendToolUiEvent, editContext?.sessionId]);
383
404
  useEffect(() => {
384
405
  return () => {
385
406
  pendingDialogReplayTimeoutsRef.current.forEach((timeout) => clearTimeout(timeout));
386
407
  pendingDialogReplayTimeoutsRef.current.clear();
387
408
  };
388
409
  }, []);
410
+ useEffect(() => {
411
+ const currentStatus = parseAgentStatus(agent?.status);
412
+ if (currentStatus !== "waitingForInput" ||
413
+ activeInlineDialog ||
414
+ !editContext?.sessionId) {
415
+ return;
416
+ }
417
+ let cancelled = false;
418
+ appendToolUiEvent("ui:pending-dialog-recovery-check-started", `agentId=${agentStub.id} status=${currentStatus} activeDialog=false`);
419
+ void getAgentDiagnostics(agentStub.id, editContext.sessionId)
420
+ .then((diagnostics) => {
421
+ if (cancelled || activeInlineDialogRef.current)
422
+ return;
423
+ const pendingDialogs = diagnostics.pendingDialogs ?? [];
424
+ const pendingDialog = pendingDialogs.find((dialog) => dialog.replayableToCurrentSession &&
425
+ dialog.callbackId &&
426
+ dialog.dialogType !== DIALOG_TYPES.CAPTURE_PAGE_DOM &&
427
+ dialog.dialogType !== DIALOG_TYPES.CAPTURE_PAGE_SCREENSHOT);
428
+ if (!pendingDialog) {
429
+ appendToolUiEvent("ui:pending-dialog-recovery-check-not-required", `agentId=${agentStub.id} pendingDialogCount=${diagnostics.pendingDialogCount ?? pendingDialogs.length} replayableDialogs=${pendingDialogs.length}`);
430
+ return;
431
+ }
432
+ appendToolUiEvent("ui:pending-dialog-recovery-check-required", `${pendingDialog.dialogType} callbackId=${pendingDialog.callbackId} agentId=${agentStub.id}`);
433
+ window.dispatchEvent(new CustomEvent("agent:dialog:recover", {
434
+ detail: {
435
+ agentId: agentStub.id,
436
+ callbackId: pendingDialog.callbackId,
437
+ dialogType: pendingDialog.dialogType,
438
+ terminalInstanceId: dialogTerminalInstanceIdRef.current,
439
+ },
440
+ }));
441
+ schedulePendingDialogReplay(agentStub.id, pendingDialog.callbackId, pendingDialog.dialogType);
442
+ })
443
+ .catch((error) => {
444
+ appendToolUiEvent("ui:pending-dialog-recovery-lookup-failed", error instanceof Error ? error.message : String(error));
445
+ });
446
+ return () => {
447
+ cancelled = true;
448
+ };
449
+ }, [
450
+ agent?.status,
451
+ agentStub.id,
452
+ activeInlineDialog,
453
+ appendToolUiEvent,
454
+ editContext?.sessionId,
455
+ schedulePendingDialogReplay,
456
+ ]);
389
457
  // Collect all pending tool calls for batch approval functionality.
390
458
  // Returns a stable reference when the content is equivalent so consumers
391
459
  // (memoized children) don't re-render on every streaming token.
@@ -1301,6 +1369,19 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, onReloadPr
1301
1369
  const pendingSettingsRef = useRef(null);
1302
1370
  // Track whether textarea should maintain focus during re-renders
1303
1371
  const shouldMaintainFocusRef = useRef(false);
1372
+ // The splash screen clears initialPrompt after first render; keep a local
1373
+ // copy until the terminal is ready to submit it.
1374
+ const pendingInitialPromptRef = useRef(normalizeInitialPrompt(initialPrompt));
1375
+ const submittedInitialPromptKeyRef = useRef(null);
1376
+ useEffect(() => {
1377
+ const normalizedPrompt = normalizeInitialPrompt(initialPrompt);
1378
+ if (!normalizedPrompt)
1379
+ return;
1380
+ const promptKey = `${agentStub.id}:${normalizedPrompt}`;
1381
+ if (submittedInitialPromptKeyRef.current === promptKey)
1382
+ return;
1383
+ pendingInitialPromptRef.current = normalizedPrompt;
1384
+ }, [agentStub.id, initialPrompt]);
1304
1385
  // Auto-scroll to bottom when new messages arrive
1305
1386
  const scrollToBottom = useCallback(() => {
1306
1387
  const container = messagesContainerRef.current;
@@ -3858,6 +3939,18 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, onReloadPr
3858
3939
  window.dispatchEvent(new CustomEvent("agent:dialog:accepted", {
3859
3940
  detail: { callbackId: request.callbackId },
3860
3941
  }));
3942
+ const currentEditContext = editContextRef.current;
3943
+ if (currentEditContext?.sessionId) {
3944
+ void acceptAgentDialog({
3945
+ callbackId: request.callbackId,
3946
+ agentId: request.agentId,
3947
+ dialogType: request.dialogType,
3948
+ terminalInstanceId,
3949
+ sessionId: currentEditContext.sessionId,
3950
+ }).catch((error) => {
3951
+ console.warn("[AgentTerminal] Failed to acknowledge dialog:", error);
3952
+ });
3953
+ }
3861
3954
  }
3862
3955
  setTimeout(() => {
3863
3956
  if (request.dialogType === "questionnaire") {
@@ -4410,6 +4503,45 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, onReloadPr
4410
4503
  setIsSubmitting(false);
4411
4504
  }
4412
4505
  };
4506
+ useEffect(() => {
4507
+ const promptToSubmit = pendingInitialPromptRef.current;
4508
+ if (!promptToSubmit)
4509
+ return;
4510
+ const promptKey = `${agentStub.id}:${promptToSubmit}`;
4511
+ if (submittedInitialPromptKeyRef.current === promptKey) {
4512
+ pendingInitialPromptRef.current = null;
4513
+ return;
4514
+ }
4515
+ if (!effectiveIsFocused ||
4516
+ isLoading ||
4517
+ isSubmitting ||
4518
+ readOnly ||
4519
+ !editContext ||
4520
+ !agent?.id ||
4521
+ !activeProfile) {
4522
+ return;
4523
+ }
4524
+ if ((activeProfile.models?.length ?? 0) > 0 && !selectedModelId)
4525
+ return;
4526
+ if (initialMetadata && !agentMetadata)
4527
+ return;
4528
+ submittedInitialPromptKeyRef.current = promptKey;
4529
+ pendingInitialPromptRef.current = null;
4530
+ void handleSubmit(promptToSubmit);
4531
+ }, [
4532
+ activeProfile,
4533
+ agent?.id,
4534
+ agentMetadata,
4535
+ agentStub.id,
4536
+ editContext,
4537
+ effectiveIsFocused,
4538
+ handleSubmit,
4539
+ initialMetadata,
4540
+ isLoading,
4541
+ isSubmitting,
4542
+ readOnly,
4543
+ selectedModelId,
4544
+ ]);
4413
4545
  const handlePaste = (e) => {
4414
4546
  if (!activeProfile?.enableDocumentUpload || !documentListRef.current)
4415
4547
  return;