@opengeni/react 0.37.0 → 0.40.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 (71) hide show
  1. package/README.md +88 -2
  2. package/dist/{chunk-7CJOAW3V.js → chunk-EB67J347.js} +1 -135
  3. package/dist/chunk-EB67J347.js.map +1 -0
  4. package/dist/chunk-EKZH6IDG.js +141 -0
  5. package/dist/chunk-EKZH6IDG.js.map +1 -0
  6. package/dist/{chunk-FSPDND3P.js → chunk-JALF5FI3.js} +8 -6
  7. package/dist/{chunk-FSPDND3P.js.map → chunk-JALF5FI3.js.map} +1 -1
  8. package/dist/{chunk-UCZPNXV3.js → chunk-KR2SK5GJ.js} +1292 -711
  9. package/dist/chunk-KR2SK5GJ.js.map +1 -0
  10. package/dist/{chunk-IP22SLO6.js → chunk-OMCFRWHL.js} +28 -441
  11. package/dist/chunk-OMCFRWHL.js.map +1 -0
  12. package/dist/{chunk-HJ4OQVGW.js → chunk-Q2NCKWTK.js} +10 -5
  13. package/dist/chunk-Q2NCKWTK.js.map +1 -0
  14. package/dist/{chunk-ALA3UGWB.js → chunk-SXIQK54Z.js} +8 -6
  15. package/dist/{chunk-ALA3UGWB.js.map → chunk-SXIQK54Z.js.map} +1 -1
  16. package/dist/chunk-WZT5G5OR.js +433 -0
  17. package/dist/chunk-WZT5G5OR.js.map +1 -0
  18. package/dist/client.d.ts +2 -0
  19. package/dist/components/chat-composer.d.ts +5 -1
  20. package/dist/components/human-input-form.d.ts +16 -6
  21. package/dist/components/human-input-surface.d.ts +19 -0
  22. package/dist/components/machine-input-display.d.ts +12 -0
  23. package/dist/components/message-timeline.d.ts +6 -1
  24. package/dist/components/session-chrome.d.ts +1 -0
  25. package/dist/components/tip-follow.d.ts +30 -0
  26. package/dist/composer.js +14 -11
  27. package/dist/hooks/use-composer.d.ts +1 -1
  28. package/dist/index.d.ts +4 -0
  29. package/dist/index.js +2246 -2236
  30. package/dist/index.js.map +1 -1
  31. package/dist/machines.js +4 -3
  32. package/dist/realtime/dropdown-menu.d.ts +16 -0
  33. package/dist/realtime/realtime-control.d.ts +126 -0
  34. package/dist/realtime.d.ts +11 -0
  35. package/dist/realtime.js +1023 -0
  36. package/dist/realtime.js.map +1 -0
  37. package/dist/session-context.d.ts +7 -1
  38. package/dist/session-ui.d.ts +2 -0
  39. package/dist/session-ui.js +5 -3
  40. package/dist/session.js +4 -3
  41. package/dist/timeline/compute-label.d.ts +2 -0
  42. package/dist/timeline/index.d.ts +1 -0
  43. package/package.json +7 -2
  44. package/src/client.ts +13 -0
  45. package/src/components/chat-composer.tsx +11 -2
  46. package/src/components/composer-transcription-control.tsx +2 -2
  47. package/src/components/composer.tsx +14 -5
  48. package/src/components/human-input-form.tsx +506 -186
  49. package/src/components/human-input-surface.tsx +80 -0
  50. package/src/components/machine-input-display.ts +83 -0
  51. package/src/components/message-timeline.tsx +348 -308
  52. package/src/components/model-policy-picker.tsx +8 -3
  53. package/src/components/sandbox-files.tsx +1 -1
  54. package/src/components/session-chrome.tsx +3 -1
  55. package/src/components/tip-follow.ts +127 -6
  56. package/src/hooks/use-composer.ts +16 -13
  57. package/src/index.ts +4 -0
  58. package/src/realtime/dropdown-menu.tsx +123 -0
  59. package/src/realtime/realtime-control.tsx +1178 -0
  60. package/src/realtime.ts +27 -0
  61. package/src/session-context.ts +16 -0
  62. package/src/session-ui.ts +2 -0
  63. package/src/timeline/compute-label.tsx +18 -0
  64. package/src/timeline/index.ts +3 -0
  65. package/src/timeline/tool-renderers.tsx +232 -43
  66. package/styles/index.css +61 -0
  67. package/styles/tokens.css +2 -0
  68. package/dist/chunk-7CJOAW3V.js.map +0 -1
  69. package/dist/chunk-HJ4OQVGW.js.map +0 -1
  70. package/dist/chunk-IP22SLO6.js.map +0 -1
  71. package/dist/chunk-UCZPNXV3.js.map +0 -1
@@ -0,0 +1,80 @@
1
+ import type { SessionHumanInputRequest, SubmitHumanInputResponseRequest } from "@opengeni/sdk";
2
+ import { useEffect, useMemo, useRef } from "react";
3
+ import { cn } from "../lib/cn";
4
+ import {
5
+ HumanInputForm,
6
+ type HumanInputFormMessages,
7
+ type HumanInputFormProps,
8
+ } from "./human-input-form";
9
+
10
+ export type HumanInputSurfaceProps = {
11
+ requests: SessionHumanInputRequest[];
12
+ onSubmit: (requestId: string, response: SubmitHumanInputResponseRequest) => void | Promise<void>;
13
+ respondingRequestId?: string | null | undefined;
14
+ error?: string | null | undefined;
15
+ messages?: Partial<HumanInputFormMessages> | undefined;
16
+ className?: string | undefined;
17
+ /** Forwarded to the active form. Defaults true. */
18
+ autoFocus?: boolean | undefined;
19
+ };
20
+
21
+ /**
22
+ * One decision shell for pending structured human-input requests. Parallel
23
+ * freezes are shown one at a time (oldest first) as “N of M”; Continue/Skip
24
+ * settles the active request and the next remaining set advances automatically
25
+ * when the authoritative pending list updates.
26
+ */
27
+ export function HumanInputSurface({
28
+ requests,
29
+ onSubmit,
30
+ respondingRequestId = null,
31
+ error,
32
+ messages,
33
+ className,
34
+ autoFocus = true,
35
+ }: HumanInputSurfaceProps) {
36
+ const batchTotalRef = useRef(0);
37
+
38
+ const ordered = useMemo(() => {
39
+ return [...requests].sort((a, b) => {
40
+ const aAt = a.createdAt ? Date.parse(a.createdAt) : 0;
41
+ const bAt = b.createdAt ? Date.parse(b.createdAt) : 0;
42
+ if (aAt !== bAt) return aAt - bAt;
43
+ return a.id.localeCompare(b.id);
44
+ });
45
+ }, [requests]);
46
+
47
+ useEffect(() => {
48
+ if (ordered.length === 0) {
49
+ batchTotalRef.current = 0;
50
+ return;
51
+ }
52
+ batchTotalRef.current =
53
+ batchTotalRef.current === 0
54
+ ? ordered.length
55
+ : Math.max(batchTotalRef.current, ordered.length);
56
+ }, [ordered]);
57
+
58
+ if (ordered.length === 0) return null;
59
+
60
+ const active = ordered[0]!;
61
+ const batchTotal = Math.max(batchTotalRef.current, ordered.length);
62
+ const position = batchTotal - ordered.length + 1;
63
+ const progressLabel = batchTotal > 1 ? `${position} of ${batchTotal}` : null;
64
+
65
+ const formProps: HumanInputFormProps = {
66
+ request: active,
67
+ submitting: respondingRequestId !== null,
68
+ error: error ?? null,
69
+ progressLabel,
70
+ autoFocus,
71
+ ...(messages ? { messages } : {}),
72
+ onSubmit: (response) => onSubmit(active.id, response),
73
+ };
74
+
75
+ return (
76
+ <div className={cn("w-full", className)} data-human-input-surface="">
77
+ <HumanInputForm {...formProps} />
78
+ </div>
79
+ );
80
+ }
@@ -0,0 +1,83 @@
1
+ import type { MachineInputMember } from "../timeline/types";
2
+
3
+ export const MACHINE_INPUT_META: Record<MachineInputMember["kind"], string> = {
4
+ scheduled_occurrence: "Scheduled update",
5
+ goal_continuation: "Goal continued",
6
+ agent_message: "Agent update",
7
+ agent_steer_instruction: "Agent direction",
8
+ child_terminal_result: "Agent finished",
9
+ };
10
+
11
+ /**
12
+ * Collapsed landmark label for a coalesced machine-input batch.
13
+ * Same-kind batches get a natural plural; mixed kinds stay short.
14
+ */
15
+ export function machineInputBatchLabel(members: readonly MachineInputMember[]): string {
16
+ if (members.length === 0) return "Updates";
17
+ const counts = new Map<MachineInputMember["kind"], number>();
18
+ for (const member of members) {
19
+ counts.set(member.kind, (counts.get(member.kind) ?? 0) + 1);
20
+ }
21
+ if (counts.size === 1) {
22
+ const kind = members[0]!.kind;
23
+ const n = members.length;
24
+ switch (kind) {
25
+ case "child_terminal_result":
26
+ return n === 1 ? "Agent finished" : `${n} agents finished`;
27
+ case "goal_continuation":
28
+ return n === 1 ? "Goal continued" : `${n} goal continuations`;
29
+ case "scheduled_occurrence":
30
+ return n === 1 ? "Scheduled update" : `${n} scheduled updates`;
31
+ case "agent_message":
32
+ return n === 1 ? "Agent update" : `${n} agent updates`;
33
+ case "agent_steer_instruction":
34
+ return n === 1 ? "Agent direction" : `${n} agent directions`;
35
+ }
36
+ }
37
+ const parts = [...counts.entries()].map(([kind, count]) => {
38
+ const label = MACHINE_INPUT_META[kind];
39
+ return count === 1 ? label : `${count}× ${label}`;
40
+ });
41
+ const preview = parts.slice(0, 2).join(", ");
42
+ const suffix = parts.length > 2 ? ", …" : "";
43
+ return `${members.length} updates · ${preview}${suffix}`;
44
+ }
45
+
46
+ /** Strip protocol prefixes and worker/session UUIDs from display summaries. */
47
+ export function cleanMachineInputSummary(summary: string): string {
48
+ return summary
49
+ .replace(/^\[[A-Z][A-Z _-]*(?:\s+\d+\/\d+)?\]\s*/, "")
50
+ .replace(/\bWorker session id:\s*[0-9a-f]{8}-[0-9a-f-]{27,}\b/gi, "")
51
+ .replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, "")
52
+ .replace(/\(\s*\)/g, "")
53
+ .replace(/\s*[·|]\s*$/g, "")
54
+ .replace(/\s{2,}/g, " ")
55
+ .replace(/\s+([.,;:])/g, "$1")
56
+ .trim();
57
+ }
58
+
59
+ export function readableMachineInputSource(sourceId: string): string | null {
60
+ const value = sourceId.trim();
61
+ if (!value || /^[0-9a-f]{8}-[0-9a-f-]{27,}$/i.test(value)) return null;
62
+ if (/^(goal|schedule|system):/i.test(value)) return null;
63
+ return value.replaceAll("_", " ");
64
+ }
65
+
66
+ /** True when a cleaned single-member summary adds meaning beyond the pill label. */
67
+ export function machineInputSummaryIsUseful(
68
+ kind: MachineInputMember["kind"],
69
+ cleanedSummary: string,
70
+ ): boolean {
71
+ if (!cleanedSummary) return false;
72
+ const label = MACHINE_INPUT_META[kind].toLowerCase();
73
+ const text = cleanedSummary.toLowerCase();
74
+ if (text === label || text === `${label}.`) return false;
75
+ // Generic child-finished boilerplate after UUID scrub is still noise.
76
+ if (
77
+ kind === "child_terminal_result" &&
78
+ /^a worker session you spawned has finished/i.test(cleanedSummary)
79
+ ) {
80
+ return false;
81
+ }
82
+ return true;
83
+ }