@parallelworks/ui 0.18.0 → 0.19.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.
- package/README.md +86 -6
- package/dist/ai/adapter/memoryStore.d.ts +8 -0
- package/dist/ai/adapter/mock/index.d.ts +2 -0
- package/dist/ai/adapter/mock/index.js +81 -0
- package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
- package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
- package/dist/ai/adapter/openai/errors.d.ts +3 -0
- package/dist/ai/adapter/openai/index.d.ts +6 -0
- package/dist/ai/adapter/openai/index.js +334 -0
- package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
- package/dist/ai/adapter/openai/responses.d.ts +4 -0
- package/dist/ai/adapter/openai/sse.d.ts +24 -0
- package/dist/ai/adapter/openai/wire.d.ts +40 -0
- package/dist/ai/adapter/types.d.ts +131 -0
- package/dist/ai/agent/classifier.d.ts +2 -0
- package/dist/ai/agent/diff.d.ts +35 -0
- package/dist/ai/agent/diffHighlight.d.ts +6 -0
- package/dist/ai/agent/index.d.ts +6 -0
- package/dist/ai/agent/permissions.d.ts +11 -0
- package/dist/ai/agent/toolfmt.d.ts +18 -0
- package/dist/ai/agent/transcript.d.ts +38 -0
- package/dist/ai/ai.css +325 -0
- package/dist/ai/components/AllocationSelector.d.ts +4 -0
- package/dist/ai/components/AttachmentManager.d.ts +1 -0
- package/dist/ai/components/AttachmentUpload.d.ts +24 -0
- package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
- package/dist/ai/components/BranchNavigator.d.ts +8 -0
- package/dist/ai/components/ChatEmptyState.d.ts +3 -0
- package/dist/ai/components/ChatInput.d.ts +45 -0
- package/dist/ai/components/ChatLayout.d.ts +5 -0
- package/dist/ai/components/ChatMessage.d.ts +24 -0
- package/dist/ai/components/ChatMessageList.d.ts +35 -0
- package/dist/ai/components/ChatSidebar.d.ts +5 -0
- package/dist/ai/components/ChatThread.d.ts +3 -0
- package/dist/ai/components/ComposerChrome.d.ts +18 -0
- package/dist/ai/components/ComposerFrame.d.ts +16 -0
- package/dist/ai/components/DragOverlay.d.ts +5 -0
- package/dist/ai/components/ModelSelector.d.ts +6 -0
- package/dist/ai/components/ShareDialog.d.ts +11 -0
- package/dist/ai/components/SlashMenu.d.ts +28 -0
- package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
- package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
- package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
- package/dist/ai/components/attachmentKeys.d.ts +4 -0
- package/dist/ai/core/ChatProvider.d.ts +66 -0
- package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
- package/dist/ai/core/chatReducer.d.ts +114 -0
- package/dist/ai/core/config.d.ts +47 -0
- package/dist/ai/core/events.d.ts +1 -0
- package/dist/ai/core/exportConversation.d.ts +4 -0
- package/dist/ai/core/greeting.d.ts +3 -0
- package/dist/ai/core/parts.d.ts +11 -0
- package/dist/ai/core/useDragDrop.d.ts +14 -0
- package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
- package/dist/ai/core/useSSEStream.d.ts +34 -0
- package/dist/ai/index.d.ts +40 -0
- package/dist/ai/index.js +6645 -0
- package/dist/ai/strings.d.ts +167 -0
- package/dist/ai/types.d.ts +236 -0
- package/dist/ai/ui/Avatar.d.ts +8 -0
- package/dist/ai/ui/Dropdown.d.ts +31 -0
- package/dist/ai/ui/Markdown.d.ts +8 -0
- package/dist/ai/ui/Notice.d.ts +21 -0
- package/dist/ai/ui/buttons.d.ts +1 -0
- package/dist/ai/ui/codeBreaks.d.ts +16 -0
- package/dist/ai/ui/prose.d.ts +1 -0
- package/dist/ai/ui/sidebar.d.ts +81 -0
- package/dist/ai/utils.d.ts +4 -0
- package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
- package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
- package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
- package/dist/chunks/{CodePreviewEditor-4lx3kE-w.js → CodePreviewEditor-YqQBz1YL.js} +1 -1
- package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
- package/dist/chunks/{FieldWrapper-Bef01EWO.js → FieldWrapper-Cszwg-4B.js} +3 -7
- package/dist/chunks/{CreateModal-BY6DLmur.js → Markdown-CM-FenNE.js} +19 -91
- package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
- package/dist/chunks/{PageHeader-l49p1nM9.js → PageHeader-0kG_iypP.js} +67 -65
- package/dist/chunks/{Provider-Ghua9PkN.js → Provider-CDYurraE.js} +54 -20
- package/dist/chunks/{SwitchToggle-CHPP8uZQ.js → SwitchToggle-DShNdcao.js} +135 -132
- package/dist/chunks/{Table-4OHjdKdO.js → Table-DU2MW8xz.js} +5 -3
- package/dist/chunks/{Tooltip-Crxo_eU_.js → Tooltip-K5HJr4_p.js} +31 -4
- package/dist/chunks/duration-BOv8Phl8.js +17 -0
- package/dist/chunks/{editor-9_uVtUyy.js → editor-Dk1rbV75.js} +32 -18
- package/dist/chunks/focus-D_iZJTW1.js +7 -0
- package/dist/chunks/{list-qrojZZNv.js → list-CJm875m7.js} +377 -370
- package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
- package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
- package/dist/chunks/types-Yy0NrerF.js +11 -0
- package/dist/components/Avatar.d.ts +1 -1
- package/dist/components/Breadcrumbs.d.ts +1 -1
- package/dist/components/Dropdown.d.ts +1 -1
- package/dist/components/EmptyState.d.ts +1 -1
- package/dist/components/Indicator.d.ts +2 -2
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/LetterBadge.d.ts +1 -1
- package/dist/components/MarkdownImpl.d.ts +1 -1
- package/dist/components/Provider.d.ts +16 -65
- package/dist/components/SettingRow.d.ts +1 -1
- package/dist/components/SettingsGroup.d.ts +1 -1
- package/dist/components/focus.d.ts +2 -0
- package/dist/components/keys.d.ts +12 -0
- package/dist/duration.d.ts +3 -0
- package/dist/editor/Monaco.d.ts +1 -20
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/index.js +2 -2
- package/dist/editor/yaml.d.ts +5 -0
- package/dist/engine.d.ts +98 -0
- package/dist/file-explorer/FileExplorer.d.ts +11 -2
- package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
- package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
- package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
- package/dist/file-explorer/FileRow.d.ts +1 -1
- package/dist/file-explorer/helpers.d.ts +4 -4
- package/dist/file-explorer/index.d.ts +3 -3
- package/dist/file-explorer/index.js +613 -647
- package/dist/file-explorer/lib/types.d.ts +6 -1
- package/dist/file-explorer/lib/utils.d.ts +1 -3
- package/dist/file-explorer/useNearEnd.d.ts +1 -1
- package/dist/form/FieldWrapper.d.ts +2 -2
- package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
- package/dist/form/Form.d.ts +4 -21
- package/dist/form/index.d.ts +11 -12
- package/dist/form/index.js +1488 -1611
- package/dist/form/lib.d.ts +6 -1
- package/dist/form/types/fieldComponentTypes.d.ts +3 -2
- package/dist/form/types/fieldTypes.d.ts +6 -20
- package/dist/form/useParsedOpts.d.ts +1 -1
- package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
- package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
- package/dist/{workflow → graph}/index.d.ts +1 -1
- package/dist/{workflow → graph}/index.js +215 -180
- package/dist/{workflow → graph}/types.d.ts +3 -3
- package/dist/icons.d.ts +20 -21
- package/dist/index.d.ts +38 -40
- package/dist/index.js +347 -346
- package/dist/list/ListTable.d.ts +1 -1
- package/dist/list/ListViewControls.d.ts +2 -2
- package/dist/list/index.d.ts +9 -9
- package/dist/list/index.js +2 -2
- package/dist/logviewer/LogViewer.d.ts +1 -1
- package/dist/logviewer/index.d.ts +1 -0
- package/dist/logviewer/index.js +2 -742
- package/dist/logviewer/segments.d.ts +9 -0
- package/dist/styles/fonts.css +4 -4
- package/dist/styles/theme.css +6 -4
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +2 -2
- package/package.json +38 -14
- package/LICENSE +0 -202
- package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
- package/dist/editor/usesGitlab.d.ts +0 -97
- package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
- package/dist/form/types/workflow-schema.d.ts +0 -1145
- package/dist/form/utils/pwResolver.d.ts +0 -18
- package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
- /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
- /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
- /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
- /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
- /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
- /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Allocation, ApprovalPart, AttachmentRef, ChatModel, Conversation, ConversationSummary, ProviderInfo, ShareGroup, SharePermission, SharePermissionLevel, TodoItem, ToolCall, UnreachableSession } from '../types.js';
|
|
2
|
+
import type { CompletionMessage } from './openai/wire.js';
|
|
3
|
+
export declare class ChatAdapterError extends Error {
|
|
4
|
+
status?: number | undefined;
|
|
5
|
+
constructor(message: string, options?: {
|
|
6
|
+
status?: number;
|
|
7
|
+
cause?: unknown;
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export interface ModelsList {
|
|
11
|
+
models: ChatModel[];
|
|
12
|
+
unreachableSessions: UnreachableSession[];
|
|
13
|
+
}
|
|
14
|
+
export interface StreamRequest {
|
|
15
|
+
model: string;
|
|
16
|
+
messages: CompletionMessage[];
|
|
17
|
+
conversationId: string;
|
|
18
|
+
parentMessageId?: string | null;
|
|
19
|
+
userMessageId: string;
|
|
20
|
+
allocation?: string | null;
|
|
21
|
+
useResponses?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface StreamHandlers {
|
|
24
|
+
onContent: (content: string) => void;
|
|
25
|
+
onReasoning?: (reasoning: string) => void;
|
|
26
|
+
onMessageId?: (messageId: string) => void;
|
|
27
|
+
onPart?: (delta: PartDelta) => void;
|
|
28
|
+
}
|
|
29
|
+
export type PartDelta = {
|
|
30
|
+
type: 'tool_start';
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
args: string;
|
|
34
|
+
startLine?: number;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'tool_update';
|
|
37
|
+
id: string;
|
|
38
|
+
args: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'tool_end';
|
|
41
|
+
id: string;
|
|
42
|
+
result: string;
|
|
43
|
+
isError?: boolean;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'subagent_start';
|
|
46
|
+
id: string;
|
|
47
|
+
agentType?: string;
|
|
48
|
+
color?: string;
|
|
49
|
+
background?: boolean;
|
|
50
|
+
description?: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: 'subagent_action';
|
|
53
|
+
id: string;
|
|
54
|
+
action: string;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'subagent_end';
|
|
57
|
+
id: string;
|
|
58
|
+
ok: boolean;
|
|
59
|
+
summary?: string;
|
|
60
|
+
report?: string;
|
|
61
|
+
} | {
|
|
62
|
+
type: 'approval_request';
|
|
63
|
+
approval: ApprovalPart;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'approval_resolved';
|
|
66
|
+
id: string;
|
|
67
|
+
answer?: string;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'notice' | 'warning';
|
|
70
|
+
text: string;
|
|
71
|
+
} | {
|
|
72
|
+
type: 'todo_snapshot';
|
|
73
|
+
todos: TodoItem[];
|
|
74
|
+
};
|
|
75
|
+
export interface StreamResult {
|
|
76
|
+
content: string;
|
|
77
|
+
messageId: string;
|
|
78
|
+
toolCalls: ToolCall[];
|
|
79
|
+
finishReason: string | null;
|
|
80
|
+
model: string | null;
|
|
81
|
+
reasoning: string;
|
|
82
|
+
responsesOutput: unknown[];
|
|
83
|
+
}
|
|
84
|
+
export type StreamCompletion = (req: StreamRequest, handlers: StreamHandlers, signal?: AbortSignal) => Promise<StreamResult>;
|
|
85
|
+
export interface ConversationsAdapter {
|
|
86
|
+
list(): Promise<ConversationSummary[]>;
|
|
87
|
+
get(id: string): Promise<Conversation>;
|
|
88
|
+
create(title?: string): Promise<ConversationSummary>;
|
|
89
|
+
rename(id: string, title: string): Promise<void>;
|
|
90
|
+
remove(id: string): Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
export interface ProvidersAdapter {
|
|
93
|
+
list(): Promise<ProviderInfo[]>;
|
|
94
|
+
}
|
|
95
|
+
export interface AttachmentPage {
|
|
96
|
+
attachments: AttachmentRef[];
|
|
97
|
+
total: number;
|
|
98
|
+
nextCursor?: string;
|
|
99
|
+
hasMore: boolean;
|
|
100
|
+
}
|
|
101
|
+
export interface AttachmentsAdapter {
|
|
102
|
+
list(opts: {
|
|
103
|
+
limit: number;
|
|
104
|
+
cursor?: string;
|
|
105
|
+
}): Promise<AttachmentPage>;
|
|
106
|
+
upload(file: File, conversationId?: string): Promise<AttachmentRef>;
|
|
107
|
+
remove(id: string): Promise<void>;
|
|
108
|
+
downloadUrl(id: string): string;
|
|
109
|
+
onOpen?(attachment: AttachmentRef): void;
|
|
110
|
+
}
|
|
111
|
+
export interface SharingAdapter {
|
|
112
|
+
listPermissions(conversationId: string): Promise<SharePermission[]>;
|
|
113
|
+
listGroups(): Promise<ShareGroup[]>;
|
|
114
|
+
addPermission(conversationId: string, permission: Omit<SharePermission, 'id' | 'teamName'>): Promise<void>;
|
|
115
|
+
updatePermission(conversationId: string, permissionId: string, permission: SharePermissionLevel): Promise<void>;
|
|
116
|
+
removePermission(conversationId: string, permissionId: string): Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
export interface AllocationsAdapter {
|
|
119
|
+
list(): Promise<Allocation[]>;
|
|
120
|
+
}
|
|
121
|
+
export interface ChatAdapter {
|
|
122
|
+
conversations: ConversationsAdapter;
|
|
123
|
+
models: {
|
|
124
|
+
list(): Promise<ModelsList>;
|
|
125
|
+
};
|
|
126
|
+
streamCompletion: StreamCompletion;
|
|
127
|
+
providers?: ProvidersAdapter;
|
|
128
|
+
attachments?: AttachmentsAdapter;
|
|
129
|
+
sharing?: SharingAdapter;
|
|
130
|
+
allocations?: AllocationsAdapter;
|
|
131
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const MAX_EDIT_DIFF_LINES = 100;
|
|
2
|
+
export declare const MAX_WRITE_DIFF_LINES = 50;
|
|
3
|
+
export declare const DIFF_CONTEXT = 3;
|
|
4
|
+
export interface EditToolArgs {
|
|
5
|
+
path?: string;
|
|
6
|
+
old_string?: string;
|
|
7
|
+
new_string?: string;
|
|
8
|
+
content?: string;
|
|
9
|
+
replace_all?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function isEditDiffTool(name: string): boolean;
|
|
12
|
+
export declare function parseEditArgs(argsJSON: string): EditToolArgs | null;
|
|
13
|
+
export declare function wordEmphasisRanges(oldLine: string, newLine: string): Array<[number, number]> | null;
|
|
14
|
+
export declare function lineDelta(oldLines: string[], newLines: string[]): [number, number];
|
|
15
|
+
export interface DiffRow {
|
|
16
|
+
kind: 'add' | 'del' | 'ctx' | 'gap';
|
|
17
|
+
oldNo?: number;
|
|
18
|
+
newNo?: number;
|
|
19
|
+
text: string;
|
|
20
|
+
emphasis?: Array<[number, number]>;
|
|
21
|
+
}
|
|
22
|
+
export interface EditDiffModel {
|
|
23
|
+
rows: DiffRow[];
|
|
24
|
+
added: number;
|
|
25
|
+
removed: number;
|
|
26
|
+
truncated: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function computeEditDiff(oldString: string, newString: string, startLine?: number): EditDiffModel;
|
|
29
|
+
export interface WriteModel {
|
|
30
|
+
rows: DiffRow[];
|
|
31
|
+
total: number;
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare function computeWriteRows(content: string): WriteModel;
|
|
35
|
+
export declare function editSummary(toolName: string, argsJSON: string): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface DiffToken {
|
|
2
|
+
content: string;
|
|
3
|
+
color?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function languageForPath(path: string | undefined): string | null;
|
|
6
|
+
export declare function tokenizeDiffLines(lines: string[], lang: string, isDark: boolean): Promise<DiffToken[][] | null>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { classifyPseudoUserMessage } from './classifier.js';
|
|
2
|
+
export { computeEditDiff, computeWriteRows, type DiffRow, type EditDiffModel, type EditToolArgs, editSummary, isEditDiffTool, lineDelta, MAX_EDIT_DIFF_LINES, MAX_WRITE_DIFF_LINES, parseEditArgs, type WriteModel, wordEmphasisRanges, } from './diff.js';
|
|
3
|
+
export { type DiffToken, languageForPath, tokenizeDiffLines, } from './diffHighlight.js';
|
|
4
|
+
export { clampPermissionMode, DEFAULT_PERMISSION_MODE, isNamedPermissionMode, NAMED_PERMISSION_MODES, type NamedPermissionMode, type PermissionMode, permissionModesUpTo, } from './permissions.js';
|
|
5
|
+
export { AGENT_COLOR_NAMES, agentColorHex, bashExitCode, clip, fullToolArgs, isGroupableTool, plural, resultFailed, rollupSentence, sanitizeLabel, sanitizePanelText, summarizeToolArgs, type ToolHeader, toolHeaderFor, toolSummary, } from './toolfmt.js';
|
|
6
|
+
export { agentTypeLabel, askQuestionFromArgs, firstNonEmptyLine, hiddenTranscriptTool, INTERRUPTED_NOTICE, interruptionNotice, parseSubagentNotice, planFromArgs, type SubagentNotice, subagentDeliveryLine, taskCallFromArgs, thinkingHeading, } from './transcript.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const REQUESTABLE_PERMISSION_MODES: readonly ['read-only', 'accept-edits', 'bypass-permissions'];
|
|
2
|
+
export declare const NAMED_PERMISSION_MODES: readonly ["read-only", "accept-edits", "bypass-permissions", "plan"];
|
|
3
|
+
export type PermissionMode = (typeof REQUESTABLE_PERMISSION_MODES)[number];
|
|
4
|
+
export type NamedPermissionMode = (typeof NAMED_PERMISSION_MODES)[number];
|
|
5
|
+
export declare const DEFAULT_PERMISSION_MODE: PermissionMode;
|
|
6
|
+
export declare function isNamedPermissionMode(mode: string | undefined): mode is NamedPermissionMode;
|
|
7
|
+
/** The daemon clamps a remote request to its owner's remoteMaxPermissionMode,
|
|
8
|
+
* so a menu offers only what that machine will honour. */
|
|
9
|
+
export declare function permissionModesUpTo(ceiling: string | undefined): PermissionMode[];
|
|
10
|
+
export declare function clampPermissionMode(mode: PermissionMode, ceiling: string | undefined): PermissionMode;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ToolHeader {
|
|
2
|
+
label: string;
|
|
3
|
+
arg?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function toolHeaderFor(name: string): ToolHeader;
|
|
6
|
+
export declare function clip(s: string, max: number): string;
|
|
7
|
+
export declare function sanitizeLabel(s: string): string;
|
|
8
|
+
export declare function sanitizePanelText(s: string): string;
|
|
9
|
+
export declare function summarizeToolArgs(primary: string | undefined, argsJSON: string): string;
|
|
10
|
+
export declare function fullToolArgs(primary: string | undefined, argsJSON: string): string;
|
|
11
|
+
export declare function plural(n: number, noun: string): string;
|
|
12
|
+
export declare function resultFailed(name: string, result: string): boolean;
|
|
13
|
+
export declare function bashExitCode(body: string): [string, number, boolean];
|
|
14
|
+
export declare function toolSummary(name: string, args: string, result: string, isError: boolean, editSummaryFn?: (toolName: string, argsJSON: string) => string): string;
|
|
15
|
+
export declare function isGroupableTool(name: string): boolean;
|
|
16
|
+
export declare function rollupSentence(names: string[]): string;
|
|
17
|
+
export declare const AGENT_COLOR_NAMES: readonly ['blue', 'green', 'yellow', 'purple', 'cyan', 'orange', 'pink', 'red'];
|
|
18
|
+
export declare function agentColorHex(name: string | undefined): string | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare function hiddenTranscriptTool(name: string): boolean;
|
|
2
|
+
export declare function askQuestionFromArgs(argsJSON: string): string;
|
|
3
|
+
export declare function planFromArgs(argsJSON: string): string;
|
|
4
|
+
/** A Task call's display label the way the tool itself picks it: the
|
|
5
|
+
* description, else the clipped prompt, plus its custom agent type. */
|
|
6
|
+
export declare function taskCallFromArgs(argsJSON: string): {
|
|
7
|
+
description: string;
|
|
8
|
+
agentType: string;
|
|
9
|
+
};
|
|
10
|
+
/** The built-in "default" type is the same general-purpose agent an untyped
|
|
11
|
+
* Task spawns, so naming it would only add noise. */
|
|
12
|
+
export declare function agentTypeLabel(t: string): string;
|
|
13
|
+
/** The first line when the model wrote it as a heading ("# Title" or
|
|
14
|
+
* "**Title**"), the way reasoning summaries open, so a folded thought says
|
|
15
|
+
* what it was about. Prose gets no label of its own. */
|
|
16
|
+
export declare function thinkingHeading(raw: string): string;
|
|
17
|
+
/** How a turn cut short reads, whether replayed or watched live. */
|
|
18
|
+
export declare const INTERRUPTED_NOTICE: string;
|
|
19
|
+
/** The line the daemon files as the assistant's when a turn is cut short;
|
|
20
|
+
* it is a status, not something the model said. */
|
|
21
|
+
export declare function interruptionNotice(text: string): string | null;
|
|
22
|
+
export declare function firstNonEmptyLine(text: string, max: number): string;
|
|
23
|
+
export interface SubagentNotice {
|
|
24
|
+
id: string;
|
|
25
|
+
description: string;
|
|
26
|
+
preview: string;
|
|
27
|
+
/** The report itself, without the closing line addressed to the model. */
|
|
28
|
+
body: string;
|
|
29
|
+
interim: boolean;
|
|
30
|
+
/** The interrupted form is written for the model alone; the child's own
|
|
31
|
+
* block already reads interrupted, so no line is drawn for it. */
|
|
32
|
+
silent: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Reads a "[Background subagent <id> (<desc>) completed]" header; null for
|
|
35
|
+
* any other notice, which keeps its full text. */
|
|
36
|
+
export declare function parseSubagentNotice(text: string): SubagentNotice | null;
|
|
37
|
+
/** The line that marks a child's report entering the main conversation. */
|
|
38
|
+
export declare function subagentDeliveryLine(n: SubagentNotice): string;
|
package/dist/ai/ai.css
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/* Chat-specific styles: markdown rendering (streamdown output) and the
|
|
2
|
+
* streaming/thinking animations. */
|
|
3
|
+
|
|
4
|
+
/* Answers are read at length, so their ink sits further from the page than
|
|
5
|
+
* the theme's UI text: pulled toward black on a light scheme and toward white
|
|
6
|
+
* on a dark one, from whatever ink the theme (or an org palette) supplies. */
|
|
7
|
+
.chat-ink {
|
|
8
|
+
--chat-ink: light-dark(
|
|
9
|
+
color-mix(in oklab, var(--theme-panel, #000) 60%, black),
|
|
10
|
+
color-mix(in oklab, var(--theme-panel, #fff) 75%, white)
|
|
11
|
+
);
|
|
12
|
+
color: var(--chat-ink);
|
|
13
|
+
--tw-prose-body: var(--chat-ink);
|
|
14
|
+
--tw-prose-headings: var(--chat-ink);
|
|
15
|
+
--tw-prose-bold: var(--chat-ink);
|
|
16
|
+
--tw-prose-code: var(--chat-ink);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Links */
|
|
20
|
+
.markdown a {
|
|
21
|
+
color: var(--theme-link, #428bca);
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
}
|
|
24
|
+
.markdown a:hover {
|
|
25
|
+
text-decoration: underline;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Lists hang their markers in the gutter so a wrapped line lines up with the
|
|
29
|
+
* text above it, not with the number. Streamdown sets them inside. */
|
|
30
|
+
.markdown ol,
|
|
31
|
+
.markdown ul {
|
|
32
|
+
list-style-position: outside;
|
|
33
|
+
padding-left: 1.625em;
|
|
34
|
+
}
|
|
35
|
+
.markdown li {
|
|
36
|
+
padding-left: 0.25em;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Horizontal rules */
|
|
40
|
+
.markdown hr {
|
|
41
|
+
display: block;
|
|
42
|
+
height: 0;
|
|
43
|
+
border: 0;
|
|
44
|
+
border-top: 1px solid var(--theme-border, #e5e7eb);
|
|
45
|
+
margin: 1.5em 0;
|
|
46
|
+
padding: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Inline code — code blocks are styled by Streamdown. A tint of the ink and
|
|
50
|
+
* no border: a hard outline turns every identifier into a keycap. */
|
|
51
|
+
.markdown code {
|
|
52
|
+
/* rem, not em: a table cell or list already sized down would size it twice. */
|
|
53
|
+
font-size: 0.875rem;
|
|
54
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
55
|
+
padding: 0.125em 0.375em;
|
|
56
|
+
background-color: color-mix(in oklab, var(--theme-panel, #000) 8%, transparent);
|
|
57
|
+
border-radius: 0.25rem;
|
|
58
|
+
/* Identifiers carry a colour of their own so they read as code at a glance
|
|
59
|
+
* without the weight the plugin gives them: the theme's link blue, which
|
|
60
|
+
* every palette already keeps legible on its surfaces. */
|
|
61
|
+
color: var(--theme-link, #2f6fa8);
|
|
62
|
+
font-weight: 400;
|
|
63
|
+
}
|
|
64
|
+
/* Reset inline code styles when inside a pre (code block) */
|
|
65
|
+
.markdown pre code {
|
|
66
|
+
padding: 0;
|
|
67
|
+
background-color: transparent;
|
|
68
|
+
border: none;
|
|
69
|
+
border-radius: 0;
|
|
70
|
+
font-size: inherit;
|
|
71
|
+
color: inherit;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* KaTeX overrides */
|
|
75
|
+
.katex-display {
|
|
76
|
+
margin: 1em 0;
|
|
77
|
+
overflow-x: auto;
|
|
78
|
+
overflow-y: hidden;
|
|
79
|
+
}
|
|
80
|
+
.katex {
|
|
81
|
+
font-size: 1.1em;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Subscript and superscript */
|
|
85
|
+
.markdown sub,
|
|
86
|
+
.markdown sup {
|
|
87
|
+
font-size: 75%;
|
|
88
|
+
line-height: 0;
|
|
89
|
+
position: relative;
|
|
90
|
+
vertical-align: baseline;
|
|
91
|
+
}
|
|
92
|
+
.markdown sup {
|
|
93
|
+
top: -0.5em;
|
|
94
|
+
}
|
|
95
|
+
.markdown sub {
|
|
96
|
+
bottom: -0.25em;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Images */
|
|
100
|
+
.markdown img {
|
|
101
|
+
border: 0;
|
|
102
|
+
max-width: 100%;
|
|
103
|
+
height: auto;
|
|
104
|
+
vertical-align: middle;
|
|
105
|
+
border-radius: 0.5rem;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Streamdown tables: the body's own type,
|
|
109
|
+
* hairlines at a tenth of the ink, a header on a five-percent tint, and the
|
|
110
|
+
* copy/download controls only while the pointer is over the table. */
|
|
111
|
+
.markdown [data-streamdown="table-wrapper"] {
|
|
112
|
+
--table-line: color-mix(in oklab, var(--theme-panel, #000) 10%, transparent);
|
|
113
|
+
position: relative;
|
|
114
|
+
display: block;
|
|
115
|
+
background: transparent;
|
|
116
|
+
border: none;
|
|
117
|
+
padding: 0;
|
|
118
|
+
margin: 0.75rem 0;
|
|
119
|
+
}
|
|
120
|
+
.markdown [data-streamdown="table-wrapper"] > div:first-child {
|
|
121
|
+
position: absolute;
|
|
122
|
+
top: 0.375rem;
|
|
123
|
+
right: 0.375rem;
|
|
124
|
+
z-index: 1;
|
|
125
|
+
gap: 0.125rem;
|
|
126
|
+
padding: 0.125rem;
|
|
127
|
+
border-radius: 0.375rem;
|
|
128
|
+
background: var(--theme-panel-bg, #fff);
|
|
129
|
+
border: 1px solid var(--table-line);
|
|
130
|
+
opacity: 0;
|
|
131
|
+
transition: opacity 150ms ease-out;
|
|
132
|
+
}
|
|
133
|
+
.markdown [data-streamdown="table-wrapper"]:hover > div:first-child,
|
|
134
|
+
.markdown [data-streamdown="table-wrapper"]:focus-within > div:first-child {
|
|
135
|
+
opacity: 1;
|
|
136
|
+
}
|
|
137
|
+
.markdown [data-streamdown="table-wrapper"] > div:last-child {
|
|
138
|
+
padding: 0;
|
|
139
|
+
border: 1px solid var(--table-line);
|
|
140
|
+
border-radius: 0.5rem;
|
|
141
|
+
background: transparent;
|
|
142
|
+
}
|
|
143
|
+
.markdown [data-streamdown="table-wrapper"] table {
|
|
144
|
+
margin: 0;
|
|
145
|
+
font-size: 1rem;
|
|
146
|
+
line-height: 1.5;
|
|
147
|
+
}
|
|
148
|
+
.markdown [data-streamdown="table"] th {
|
|
149
|
+
padding: 0.4375rem 0.75rem;
|
|
150
|
+
font-size: 1rem;
|
|
151
|
+
font-weight: 500;
|
|
152
|
+
color: inherit;
|
|
153
|
+
background: color-mix(in oklab, var(--theme-panel, #000) 5%, transparent);
|
|
154
|
+
border-bottom: 1px solid var(--table-line);
|
|
155
|
+
}
|
|
156
|
+
.markdown [data-streamdown="table"] td {
|
|
157
|
+
padding: 0.4375rem 0.75rem;
|
|
158
|
+
/* Streamdown sizes cells down with its own class; the table is body type. */
|
|
159
|
+
font-size: 1rem;
|
|
160
|
+
line-height: 1.5;
|
|
161
|
+
vertical-align: top;
|
|
162
|
+
color: inherit;
|
|
163
|
+
/* A prose column keeps enough room to read; a wide table scrolls instead. */
|
|
164
|
+
min-width: 9rem;
|
|
165
|
+
}
|
|
166
|
+
.markdown [data-streamdown="table"] tbody tr {
|
|
167
|
+
border-bottom: 1px solid var(--table-line);
|
|
168
|
+
}
|
|
169
|
+
.markdown [data-streamdown="table"] tbody tr:last-child {
|
|
170
|
+
border-bottom: 0;
|
|
171
|
+
}
|
|
172
|
+
@media (prefers-reduced-motion: reduce) {
|
|
173
|
+
.markdown [data-streamdown="table-wrapper"] > div:first-child {
|
|
174
|
+
transition: none;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Streamdown code blocks — tighten spacing, remove inner double-border */
|
|
179
|
+
.markdown [data-streamdown="code-block"] {
|
|
180
|
+
padding: 0.375rem 0.5rem 0;
|
|
181
|
+
margin: 0.5em 0;
|
|
182
|
+
gap: 0;
|
|
183
|
+
}
|
|
184
|
+
.markdown [data-streamdown="code-block-header"] {
|
|
185
|
+
padding: 0.25rem 0.25rem;
|
|
186
|
+
}
|
|
187
|
+
.markdown [data-streamdown="code-block-body"] {
|
|
188
|
+
border: none;
|
|
189
|
+
border-radius: 0 0 0.5rem 0.5rem;
|
|
190
|
+
padding: 0;
|
|
191
|
+
}
|
|
192
|
+
/* Remove prose pre margin and code block body inner pre margin */
|
|
193
|
+
.markdown [data-streamdown="code-block-body"] pre {
|
|
194
|
+
margin: 0;
|
|
195
|
+
padding: 0.75rem 1rem;
|
|
196
|
+
overflow-x: auto;
|
|
197
|
+
/* Code reads looser than prose; Streamdown's text-sm line is too tight. */
|
|
198
|
+
line-height: 1.6;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Shiki dual-theme color overrides (standard Shiki approach).
|
|
202
|
+
Streamdown uses Tailwind dark: arbitrary-value classes for theme switching,
|
|
203
|
+
but Tailwind v4's source scanner can misparse them from minified JS —
|
|
204
|
+
generating broken selectors that apply dark bg unconditionally while
|
|
205
|
+
missing the text color classes entirely. Override both light and dark
|
|
206
|
+
explicitly to ensure correct colors in all modes.
|
|
207
|
+
See: https://shiki.style/guide/dual-themes#class-based-dark-mode */
|
|
208
|
+
|
|
209
|
+
/* Light mode: use the primary Shiki theme (--sdm-bg/--sdm-c) */
|
|
210
|
+
.markdown [data-streamdown="code-block-body"] pre {
|
|
211
|
+
background-color: var(--sdm-bg, inherit) !important;
|
|
212
|
+
color: var(--sdm-fg, inherit);
|
|
213
|
+
}
|
|
214
|
+
.markdown [data-streamdown="code-block-body"] pre code > span > span {
|
|
215
|
+
color: var(--sdm-c, inherit);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Dark mode: switch to --shiki-dark variants */
|
|
219
|
+
.dark .markdown [data-streamdown="code-block-body"] pre {
|
|
220
|
+
background-color: var(--shiki-dark-bg, var(--sdm-bg, inherit)) !important;
|
|
221
|
+
color: var(--shiki-dark, var(--sdm-fg, inherit));
|
|
222
|
+
}
|
|
223
|
+
.dark .markdown [data-streamdown="code-block-body"] pre code > span > span {
|
|
224
|
+
color: var(--shiki-dark, inherit);
|
|
225
|
+
font-style: var(--shiki-dark-font-style, inherit);
|
|
226
|
+
font-weight: var(--shiki-dark-font-weight, inherit);
|
|
227
|
+
text-decoration: var(--shiki-dark-text-decoration, inherit);
|
|
228
|
+
}
|
|
229
|
+
.dark .markdown [data-streamdown="code-block-body"] pre code > span > span[style*="--sdm-tbg"] {
|
|
230
|
+
background-color: var(--shiki-dark-bg, var(--sdm-tbg));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Remove prose backtick pseudo-elements on inline code */
|
|
234
|
+
.markdown code::before,
|
|
235
|
+
.markdown code::after {
|
|
236
|
+
content: none !important;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Task lists (checkboxes) */
|
|
240
|
+
.markdown input[type="checkbox"] {
|
|
241
|
+
margin-right: 0.5em;
|
|
242
|
+
vertical-align: middle;
|
|
243
|
+
}
|
|
244
|
+
.markdown li:has(> input[type="checkbox"]) {
|
|
245
|
+
list-style: none;
|
|
246
|
+
margin-left: -1.5em;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* Touch device: always show chat actions */
|
|
250
|
+
@media (hover: none) {
|
|
251
|
+
.chat-actions,
|
|
252
|
+
.chat-meta {
|
|
253
|
+
opacity: 1 !important;
|
|
254
|
+
pointer-events: auto !important;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Long finished replies clamp with a bottom fade; mask keeps the fade
|
|
259
|
+
* background-agnostic across themes. */
|
|
260
|
+
.chat-message-clamp {
|
|
261
|
+
max-height: 600px;
|
|
262
|
+
overflow: hidden;
|
|
263
|
+
mask-image: linear-gradient(to bottom, black calc(100% - 96px), transparent);
|
|
264
|
+
-webkit-mask-image: linear-gradient(to bottom, black calc(100% - 96px), transparent);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* Theme-aware input styling (matches the host app's .theme-input; defined
|
|
268
|
+
* here too so the edit textarea is styled in standalone use) */
|
|
269
|
+
.theme-input {
|
|
270
|
+
background-color: var(--theme-input-bg, #f9fafb);
|
|
271
|
+
border-color: var(--theme-border, #d1d5db);
|
|
272
|
+
color: var(--theme-app, #374151);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.theme-input:focus {
|
|
276
|
+
border-color: var(--theme-element, #3b82f6);
|
|
277
|
+
outline: none;
|
|
278
|
+
box-shadow: 0 0 0 1px var(--theme-element, #3b82f6);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@keyframes shimmer {
|
|
282
|
+
0% {
|
|
283
|
+
background-position: 200% 0;
|
|
284
|
+
}
|
|
285
|
+
100% {
|
|
286
|
+
background-position: -200% 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@utility animate-shimmer {
|
|
291
|
+
animation: shimmer 1.75s linear infinite;
|
|
292
|
+
background-size: 200% 100%;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@utility text-shimmer {
|
|
296
|
+
background-image: linear-gradient(
|
|
297
|
+
90deg,
|
|
298
|
+
var(--theme-muted-text-color, #6a7282) 0%,
|
|
299
|
+
var(--theme-app, #d1d5db) 20%,
|
|
300
|
+
var(--theme-muted-text-color, #6a7282) 40%
|
|
301
|
+
);
|
|
302
|
+
-webkit-background-clip: text;
|
|
303
|
+
background-clip: text;
|
|
304
|
+
color: transparent;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* Entrance animation for chat messages (CSS replacement for a JS motion lib).
|
|
308
|
+
* Only `from` is defined so elements settle at their natural styles (queued
|
|
309
|
+
* messages render at reduced opacity). */
|
|
310
|
+
@keyframes chat-fade-in-up {
|
|
311
|
+
from {
|
|
312
|
+
opacity: 0;
|
|
313
|
+
transform: translateY(8px);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@utility animate-chat-enter {
|
|
318
|
+
animation: chat-fade-in-up 0.25s ease-out;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@media (prefers-reduced-motion: reduce) {
|
|
322
|
+
.animate-chat-enter {
|
|
323
|
+
animation: none;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function AttachmentManager(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface AttachmentUploadHandle {
|
|
2
|
+
addFiles: (files: FileList | File[]) => void;
|
|
3
|
+
}
|
|
4
|
+
export interface Attachment {
|
|
5
|
+
id?: string;
|
|
6
|
+
file?: File;
|
|
7
|
+
filename: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
size: number;
|
|
10
|
+
uploading?: boolean;
|
|
11
|
+
uploaded?: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
url?: string;
|
|
14
|
+
}
|
|
15
|
+
interface AttachmentUploadProps {
|
|
16
|
+
conversationId?: string | undefined;
|
|
17
|
+
attachments: Attachment[];
|
|
18
|
+
onAttachmentsChange: (attachments: Attachment[]) => void;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
maxFiles?: number;
|
|
21
|
+
maxFileSize?: number;
|
|
22
|
+
}
|
|
23
|
+
declare const AttachmentUpload: import("react").ForwardRefExoticComponent<AttachmentUploadProps & import("react").RefAttributes<AttachmentUploadHandle>>;
|
|
24
|
+
export default AttachmentUpload;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function BlockedGroupBanner(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ChatMessage as Message } from '../types.js';
|
|
2
|
+
interface BranchNavigatorProps {
|
|
3
|
+
messages: Message[];
|
|
4
|
+
currentMessageId: string;
|
|
5
|
+
onNavigate: (messageId: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export default function BranchNavigator({ messages, currentMessageId, onNavigate, }: BranchNavigatorProps): import("react").JSX.Element | null;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type SlashMenuConfig } from './SlashMenu.js';
|
|
3
|
+
interface ChatInputProps {
|
|
4
|
+
onSend: (content: string, attachmentIds?: string[], attachmentMeta?: Record<string, {
|
|
5
|
+
filename: string;
|
|
6
|
+
contentType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
}>) => void;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
placeholder?: string | undefined;
|
|
11
|
+
conversationId?: string;
|
|
12
|
+
onEditLastMessage?: () => void;
|
|
13
|
+
/** Only the box: no page padding, width cap, or settings row, for a host
|
|
14
|
+
* that lays out its own controls around it. */
|
|
15
|
+
flush?: boolean;
|
|
16
|
+
/** Send with nothing typed, for a surface where the text is optional. */
|
|
17
|
+
allowEmpty?: boolean;
|
|
18
|
+
/** Attach, paste, and drop files. Off for a target that takes text only. */
|
|
19
|
+
attachments?: boolean;
|
|
20
|
+
/** Hold sending until the provider's selected model is one it can serve.
|
|
21
|
+
* Off when the target picks its own model. */
|
|
22
|
+
requireModel?: boolean;
|
|
23
|
+
inputLabel?: string;
|
|
24
|
+
sendLabel?: string;
|
|
25
|
+
sendTestId?: string;
|
|
26
|
+
/** Offers the host's slash commands as the input starts with /. */
|
|
27
|
+
slash?: SlashMenuConfig | undefined;
|
|
28
|
+
/** Pills naming where the turn runs, rendered above the input. */
|
|
29
|
+
context?: ReactNode;
|
|
30
|
+
settingsLeft?: ReactNode;
|
|
31
|
+
settingsRight?: ReactNode;
|
|
32
|
+
/** A turn the chat provider does not run, such as an agent session's: it
|
|
33
|
+
* drives the Stop button in place of the provider's stream and queue. */
|
|
34
|
+
turn?: {
|
|
35
|
+
running: boolean;
|
|
36
|
+
onStop: () => void;
|
|
37
|
+
stopping?: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface ChatInputHandle {
|
|
41
|
+
addFiles: (files: FileList | File[]) => void;
|
|
42
|
+
focus: () => void;
|
|
43
|
+
}
|
|
44
|
+
declare const ChatInput: import("react").ForwardRefExoticComponent<ChatInputProps & import("react").RefAttributes<ChatInputHandle>>;
|
|
45
|
+
export default ChatInput;
|