File size: 2,139 Bytes
8523e75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { useExternalStoreRuntime, type ThreadMessage, type AppendMessage } from "@assistant-ui/react";

export interface PaperclipIssueRuntimeReassignment {
  assigneeAgentId: string | null;
  assigneeUserId: string | null;
}

export interface PaperclipIssueRuntimeSendOptions {
  body: string;
  reopen?: boolean;
  reassignment?: PaperclipIssueRuntimeReassignment;
}

interface UsePaperclipIssueRuntimeOptions {
  messages: readonly ThreadMessage[];
  isRunning: boolean;
  onSend: (options: PaperclipIssueRuntimeSendOptions) => Promise<void>;
  onCancel?: (() => Promise<void>) | undefined;
}

function asRecord(value: unknown): Record<string, unknown> | null {
  if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
  return value as Record<string, unknown>;
}

function readTextContent(message: AppendMessage) {
  return message.content
    .filter((part): part is Extract<(typeof message.content)[number], { type: "text" }> => part.type === "text")
    .map((part) => part.text)
    .join("")
    .trim();
}

export function usePaperclipIssueRuntime({
  messages,
  isRunning,
  onSend,
  onCancel,
}: UsePaperclipIssueRuntimeOptions) {
  return useExternalStoreRuntime({
    messages,
    isRunning,
    onNew: async (message) => {
      const body = readTextContent(message);
      if (!body) return;

      const custom = asRecord(message.runConfig?.custom);
      const reassignmentRecord = asRecord(custom?.reassignment);
      const reassignment =
        reassignmentRecord &&
        ("assigneeAgentId" in reassignmentRecord || "assigneeUserId" in reassignmentRecord)
          ? {
              assigneeAgentId:
                typeof reassignmentRecord.assigneeAgentId === "string" ? reassignmentRecord.assigneeAgentId : null,
              assigneeUserId:
                typeof reassignmentRecord.assigneeUserId === "string" ? reassignmentRecord.assigneeUserId : null,
            }
          : undefined;

      await onSend({
        body,
        reopen: custom?.reopen === true ? true : undefined,
        reassignment,
      });
    },
    ...(onCancel ? { onCancel } : {}),
  });
}