@tangle-network/agent-app 0.46.3 → 0.46.4
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/dist/assistant/index.js +2 -1
- package/dist/assistant/index.js.map +1 -1
- package/dist/chunk-RLOHIX5Y.js +36 -0
- package/dist/chunk-RLOHIX5Y.js.map +1 -0
- package/dist/{chunk-RZ6MYWMJ.js → chunk-YTEUZXX2.js} +169 -43
- package/dist/chunk-YTEUZXX2.js.map +1 -0
- package/dist/mention-editor-GVLG3W7C.js +521 -0
- package/dist/mention-editor-GVLG3W7C.js.map +1 -0
- package/dist/teams/drizzle/invitations-schema.d.ts +1 -1
- package/dist/teams/drizzle/schema.d.ts +1 -1
- package/dist/web-react/chat-composer.d.ts +24 -4
- package/dist/web-react/index.d.ts +1 -0
- package/dist/web-react/index.js +5 -1
- package/dist/web-react/mention-boundaries.d.ts +33 -0
- package/dist/web-react/mention-editor.d.ts +84 -0
- package/dist/web-react/mention-list.d.ts +35 -0
- package/dist/web-react/mention-pill.d.ts +10 -0
- package/dist/web-react/mention-serialize.d.ts +44 -0
- package/dist/web-react/use-file-mentions.d.ts +28 -14
- package/package.json +32 -1
- package/dist/chunk-RZ6MYWMJ.js.map +0 -1
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
* ChatComposer — the shared message input every agent app used to hand-roll:
|
|
3
3
|
* an auto-resizing textarea (Enter sends, Shift+Enter inserts a newline), an
|
|
4
4
|
* opt-in attach + drag-and-drop + clipboard-paste surface with pending-file
|
|
5
|
-
* chips,
|
|
6
|
-
*
|
|
5
|
+
* chips, an opt-in `@`-mention mode (`mention`) that swaps the textarea for a
|
|
6
|
+
* lazily loaded rich input with atomic mention pills, a streaming Stop/Send
|
|
7
|
+
* toggle, a slot for inline controls (model picker, reasoning effort), and a
|
|
8
|
+
* Cmd/Ctrl+L focus shortcut.
|
|
7
9
|
*
|
|
8
10
|
* Files arrive by three routes — the picker dialog, a drop, and a paste — and
|
|
9
11
|
* all three funnel through `accept` (`./composer-file-accept`) before they
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
import { type ReactNode } from 'react';
|
|
36
38
|
import { type ComposerFileRejection } from './composer-file-accept';
|
|
37
39
|
import { type DictationAudio } from './use-dictation';
|
|
40
|
+
import type { ComposerMentionProp } from './use-file-mentions';
|
|
38
41
|
/** Prompt-part descriptor an uploaded file carries (the upload route's
|
|
39
42
|
* `UploadedChatFile.part`), echoed back in the turn body on send. Mirrors
|
|
40
43
|
* `/chat-routes`' wire shape structurally — no server import here. */
|
|
@@ -259,8 +262,25 @@ export interface ChatComposerProps {
|
|
|
259
262
|
* status line. It sits outside the controls slot and never shrinks, so a
|
|
260
263
|
* wrapping picker set cannot push it away. */
|
|
261
264
|
trailing?: ReactNode;
|
|
265
|
+
/**
|
|
266
|
+
* Opt-in `@`-mentions. Present ⇒ the textarea is swapped for a lazily
|
|
267
|
+
* loaded TipTap rich input that renders mentions as atomic pills and
|
|
268
|
+
* serializes them to `@<id>` in the value; absent ⇒ exactly the plain
|
|
269
|
+
* textarea, with no TipTap in the bundle. Wire `useFileMentions().mention`
|
|
270
|
+
* straight in. The six `@tiptap/*` packages (core, extension-mention, pm,
|
|
271
|
+
* react, starter-kit, suggestion) are OPTIONAL peers — a consumer installs
|
|
272
|
+
* them to use this prop.
|
|
273
|
+
*
|
|
274
|
+
* The rich input owns its own keyboard surface, so `slashCommands` is
|
|
275
|
+
* disabled while `mention` is set rather than left half-armed with a menu
|
|
276
|
+
* no key can reach; no shipped surface combines the two. Seed and
|
|
277
|
+
* failed-send drafts still apply in mention mode, but caret placement (a
|
|
278
|
+
* textarea affordance) degrades to content-only.
|
|
279
|
+
*/
|
|
280
|
+
mention?: ComposerMentionProp;
|
|
262
281
|
/** `/` commands offered when the draft is exactly a leading slash token.
|
|
263
|
-
* Omit (or pass []) and `/` types as ordinary text.
|
|
282
|
+
* Omit (or pass []) and `/` types as ordinary text. Inert while `mention`
|
|
283
|
+
* is set — see {@link mention}. */
|
|
264
284
|
slashCommands?: SlashCommand[];
|
|
265
285
|
/** Dictation is opt-in: pass `onDictate` and the action row gains a mic
|
|
266
286
|
* button (browsers without `MediaRecorder`/`getUserMedia` render none).
|
|
@@ -286,4 +306,4 @@ export interface ChatComposerProps {
|
|
|
286
306
|
sendVariant?: 'pill' | 'icon';
|
|
287
307
|
className?: string;
|
|
288
308
|
}
|
|
289
|
-
export declare function ChatComposer({ onSend, onSendParts, onSendFailed, sendFailureMessage, onCancel, isStreaming, disabled, placeholder, value, onValueChange, initialValue, seed, onSeedApplied, controls, controlsPlacement, onAttach, onAttachFolder, pendingFiles, onRemoveFile, onRetryFile, accept, onRejectFiles, dropTitle, dropDescription, contextItems, canSubmitAttachmentsOnly, attachmentsNotReadyMessage, canSubmitWhileBusy, autoFocus, minRows, maxHeight, trailing, slashCommands, onDictate, onDictateError, focusShortcut, floating, sendLabel, sendVariant, className, }: ChatComposerProps): import("react").JSX.Element;
|
|
309
|
+
export declare function ChatComposer({ onSend, onSendParts, onSendFailed, sendFailureMessage, onCancel, isStreaming, disabled, placeholder, value, onValueChange, initialValue, seed, onSeedApplied, controls, controlsPlacement, onAttach, onAttachFolder, pendingFiles, onRemoveFile, onRetryFile, accept, onRejectFiles, dropTitle, dropDescription, contextItems, canSubmitAttachmentsOnly, attachmentsNotReadyMessage, canSubmitWhileBusy, autoFocus, minRows, maxHeight, trailing, mention, slashCommands, onDictate, onDictateError, focusShortcut, floating, sendLabel, sendVariant, className, }: ChatComposerProps): import("react").JSX.Element;
|
|
@@ -41,6 +41,7 @@ export * from './durable-interaction-submit';
|
|
|
41
41
|
export * from './use-chat-interactions';
|
|
42
42
|
export * from './use-file-mentions';
|
|
43
43
|
export * from './chat-mentions';
|
|
44
|
+
export * from './mention-pill';
|
|
44
45
|
export * from './chat-attachments';
|
|
45
46
|
export * from './message-attachments';
|
|
46
47
|
export * from './use-composer-attachments';
|
package/dist/web-react/index.js
CHANGED
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
withoutRecordGridCreated,
|
|
133
133
|
withoutRecordGridRemoved,
|
|
134
134
|
withoutRecordGridUpdate
|
|
135
|
-
} from "../chunk-
|
|
135
|
+
} from "../chunk-YTEUZXX2.js";
|
|
136
136
|
import {
|
|
137
137
|
SessionHistoryPanel,
|
|
138
138
|
formatSessionTimestamp,
|
|
@@ -140,6 +140,9 @@ import {
|
|
|
140
140
|
useSessionActions,
|
|
141
141
|
useSessionHistory
|
|
142
142
|
} from "../chunk-KKBTPZIE.js";
|
|
143
|
+
import {
|
|
144
|
+
MENTION_PILL_CLASS
|
|
145
|
+
} from "../chunk-RLOHIX5Y.js";
|
|
143
146
|
import "../chunk-FBVLEGEG.js";
|
|
144
147
|
import {
|
|
145
148
|
EvidenceLineageTable,
|
|
@@ -288,6 +291,7 @@ export {
|
|
|
288
291
|
InteractionBadge,
|
|
289
292
|
InteractionPlanCard,
|
|
290
293
|
InteractionQuestionCard,
|
|
294
|
+
MENTION_PILL_CLASS,
|
|
291
295
|
MessageAttachments,
|
|
292
296
|
MissionActivityLane,
|
|
293
297
|
ModelPicker,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one boundary vocabulary for reading `@<path>` mention tokens out of
|
|
3
|
+
* plain text. Two inverse readings share it — the transcript segmenter
|
|
4
|
+
* (`chat-mentions.ts`) and editor-pill restore (`mention-serialize.ts`) — and
|
|
5
|
+
* they must agree, or a token one accepts the other mangles. Kept OUT of the
|
|
6
|
+
* `/web-react` barrel on purpose: these are internals of the grammar, not
|
|
7
|
+
* public API.
|
|
8
|
+
*/
|
|
9
|
+
/** A character that could plausibly continue the SAME path/filename past a
|
|
10
|
+
* matched token. Without this lookahead a mention of `@a/b.md` would match
|
|
11
|
+
* inside the unrelated `@a/b.md.bak` and split it mid-filename.
|
|
12
|
+
*
|
|
13
|
+
* Unicode-aware because the wire validator (`validateSandboxMentionPath`)
|
|
14
|
+
* deliberately ALLOWS non-ASCII paths — in-box filenames are arbitrary. An
|
|
15
|
+
* ASCII-only class here would accept input the readers then mangle.
|
|
16
|
+
* `\p{M}` keeps DECOMPOSED filenames whole: without it, a combining accent
|
|
17
|
+
* (`a` + U+0301) reads as a boundary and splits the name after its base
|
|
18
|
+
* letter. */
|
|
19
|
+
export declare const PATH_CONTINUATION_CHAR: RegExp;
|
|
20
|
+
/** A character that, immediately BEFORE an `@`, means the `@` is part of a
|
|
21
|
+
* longer token (an email local part, a handle) rather than a mention start.
|
|
22
|
+
* Unicode-aware for the same reasons, combining marks included. */
|
|
23
|
+
export declare const WORD_CHAR: RegExp;
|
|
24
|
+
/** The full character (code point) ENDING just before `index`, or undefined
|
|
25
|
+
* at the start. Indexing `text[index - 1]` hands a lone UTF-16 surrogate to
|
|
26
|
+
* the Unicode-aware classes above, which then misread every astral letter —
|
|
27
|
+
* boundary checks must see whole characters. `index` must be a code-point
|
|
28
|
+
* boundary (both callers derive it from `@` positions and id lengths, which
|
|
29
|
+
* are). */
|
|
30
|
+
export declare function charBefore(text: string, index: number): string | undefined;
|
|
31
|
+
/** The full character (code point) starting at `index`, or undefined past the
|
|
32
|
+
* end — same surrogate rationale and precondition as {@link charBefore}. */
|
|
33
|
+
export declare function charAt(text: string, index: number): string | undefined;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mention-capable rich input behind `ChatComposer`'s `mention` prop.
|
|
3
|
+
*
|
|
4
|
+
* The five `@tiptap/*` packages are OPTIONAL peers, and every value access to
|
|
5
|
+
* them goes through `loadTiptapModules()`'s dynamic `import()` — never a
|
|
6
|
+
* static named import. A bundler resolves a missing optional peer to a stub
|
|
7
|
+
* module with a default export only, so a static `import { mergeAttributes }`
|
|
8
|
+
* fails the CONSUMER'S build even when nothing ever renders the mention path
|
|
9
|
+
* (measured against Vite 7's `__vite-optional-peer-dep` stub). The dynamic
|
|
10
|
+
* form builds clean and defers the failure to the first actual editor load,
|
|
11
|
+
* where it throws with the missing packages named — the same doctrine as
|
|
12
|
+
* `sequences-react`'s transcription peer. Type-only imports are erased and
|
|
13
|
+
* stay allowed.
|
|
14
|
+
*/
|
|
15
|
+
import type { MentionOptions } from '@tiptap/extension-mention';
|
|
16
|
+
import type * as TiptapCore from '@tiptap/core';
|
|
17
|
+
import type * as TiptapExtensionMention from '@tiptap/extension-mention';
|
|
18
|
+
import type * as TiptapReact from '@tiptap/react';
|
|
19
|
+
import type * as TiptapStarterKit from '@tiptap/starter-kit';
|
|
20
|
+
import type * as TiptapSuggestion from '@tiptap/suggestion';
|
|
21
|
+
import { type ComponentType } from 'react';
|
|
22
|
+
import type { ComposerMentionProp } from './use-file-mentions';
|
|
23
|
+
/** The loaded namespaces of the five optional peers, as one bag. */
|
|
24
|
+
export interface TiptapModules {
|
|
25
|
+
core: typeof TiptapCore;
|
|
26
|
+
extensionMention: typeof TiptapExtensionMention;
|
|
27
|
+
react: typeof TiptapReact;
|
|
28
|
+
starterKit: typeof TiptapStarterKit;
|
|
29
|
+
suggestion: typeof TiptapSuggestion;
|
|
30
|
+
}
|
|
31
|
+
/** Resolve the optional peers, or throw naming every one of them. */
|
|
32
|
+
export declare function loadTiptapModules(): Promise<TiptapModules>;
|
|
33
|
+
export interface MentionEditorProps {
|
|
34
|
+
value: string;
|
|
35
|
+
onChange: (value: string) => void;
|
|
36
|
+
/** Fired when Enter (no Shift, popover closed, not composing) should send. */
|
|
37
|
+
onSubmit: () => void;
|
|
38
|
+
placeholder: string;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
autoFocus?: boolean;
|
|
41
|
+
/** Pixel floor for the input box. The composer computes it from `minRows`
|
|
42
|
+
* against its own line metrics, so the two input modes cannot drift. */
|
|
43
|
+
minHeight: number;
|
|
44
|
+
/** Pixel height the input grows to before it scrolls. */
|
|
45
|
+
maxHeight: number;
|
|
46
|
+
mention: ComposerMentionProp;
|
|
47
|
+
/** Registers a focus callback the composer wires to Cmd/Ctrl+L; called with
|
|
48
|
+
* `null` on unmount so the composer never focuses a destroyed editor. */
|
|
49
|
+
registerFocus?: (focus: (() => void) | null) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Clipboard files pulled off a paste. Returns true when consumed so the
|
|
52
|
+
* editor suppresses its default text paste — the same funnel the textarea
|
|
53
|
+
* path routes through to `onAttach`.
|
|
54
|
+
*/
|
|
55
|
+
onPasteFiles?: (files: FileList) => boolean;
|
|
56
|
+
}
|
|
57
|
+
/** Only text, hard breaks, and atomic mention pills — no marks, no formatting. */
|
|
58
|
+
export declare function buildComposerStarterKit(tiptap: TiptapModules): TiptapCore.Extension<TiptapStarterKit.StarterKitOptions, any>;
|
|
59
|
+
/**
|
|
60
|
+
* The mention node: an inline atom (`inline: true, selectable: false,
|
|
61
|
+
* atom: true` from `@tiptap/extension-mention`) carrying `{ id, label, kind }`,
|
|
62
|
+
* rendered as a themed pill showing the label with the full id in `title`. Atom
|
|
63
|
+
* means the cursor can't enter it and a single backspace removes the whole
|
|
64
|
+
* thing. The `suggestion` config is supplied by the caller so the popover's
|
|
65
|
+
* fetch/keyboard wiring stays in the component.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildMentionExtension(tiptap: TiptapModules, trigger: string, suggestion: MentionOptions['suggestion']): TiptapCore.Node<MentionOptions<any, TiptapExtensionMention.MentionNodeAttrs>, any>;
|
|
68
|
+
/** `React.lazy` payload: resolve the peers, then build the component. */
|
|
69
|
+
export declare function loadMentionEditor(): Promise<{
|
|
70
|
+
default: ComponentType<MentionEditorProps>;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Builds the mention-capable rich input against loaded tiptap modules. Loaded
|
|
74
|
+
* lazily by `ChatComposer` so textarea-only consumers never pull TipTap into
|
|
75
|
+
* their initial bundle. It preserves every textarea behavior — controlled
|
|
76
|
+
* plain-text `value`, Enter to send / Shift+Enter for a newline, placeholder,
|
|
77
|
+
* disabled, autofocus, file-paste routing — and adds `@`-mention pills backed
|
|
78
|
+
* by an async provider.
|
|
79
|
+
*
|
|
80
|
+
* The suggestion list renders through `PopoverSurface` anchored to the input
|
|
81
|
+
* box, like the composer's slash menu: an in-place panel is a panel the host
|
|
82
|
+
* clips away (see the popover canon in AGENTS.md).
|
|
83
|
+
*/
|
|
84
|
+
export declare function createMentionEditor(tiptap: TiptapModules): ComponentType<MentionEditorProps>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { MentionItem } from './use-file-mentions';
|
|
3
|
+
/** Imperative surface the editor's suggestion keymap drives. */
|
|
4
|
+
export interface MentionListHandle {
|
|
5
|
+
/** Returns true when the key was consumed — the editor must not also act. */
|
|
6
|
+
onKeyDown: (event: KeyboardEvent) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface MentionListProps {
|
|
9
|
+
items: MentionItem[];
|
|
10
|
+
loading: boolean;
|
|
11
|
+
error: boolean;
|
|
12
|
+
/** Shown when the fetch resolved to zero items. Default "No matches". */
|
|
13
|
+
emptyText?: string;
|
|
14
|
+
renderItem?: (item: MentionItem) => ReactNode;
|
|
15
|
+
onSelect: (item: MentionItem) => void;
|
|
16
|
+
/** Root `role="listbox"` element id; option rows derive stable ids from it
|
|
17
|
+
* (`<id>-opt-<index>`) so the editor can point `aria-activedescendant` at
|
|
18
|
+
* the highlighted row. */
|
|
19
|
+
id?: string;
|
|
20
|
+
/** Fired whenever the highlight moves (keys, hover, or a result-set
|
|
21
|
+
* re-home) — what keeps the editor's `aria-activedescendant` current. */
|
|
22
|
+
onActiveChange?: (index: number) => void;
|
|
23
|
+
/** Extra classes merged onto the panel's root element, applied last so
|
|
24
|
+
* they win over the component's own. */
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The mention suggestion list: a flat, keyboard-driven menu with loading,
|
|
29
|
+
* empty, and error states. Selection is owned here so ↑/↓ and Enter/Tab
|
|
30
|
+
* resolve against the highlighted row; every key it handles is reported
|
|
31
|
+
* consumed so the composer's Enter-to-send never fires while open. The panel
|
|
32
|
+
* carries its own surface classes but no positioning — the editor places it
|
|
33
|
+
* through `PopoverSurface`, per the popover canon.
|
|
34
|
+
*/
|
|
35
|
+
export declare const MentionList: import("react").ForwardRefExoticComponent<MentionListProps & import("react").RefAttributes<MentionListHandle>>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual contract for a rendered mention pill. The TipTap extension in
|
|
3
|
+
* `mention-editor.tsx` styles its inline atom node with this, and any other
|
|
4
|
+
* surface that renders a resolved mention (e.g. a sent-message transcript)
|
|
5
|
+
* uses the same constant so the two stay one visual contract instead of
|
|
6
|
+
* silently drifting apart. Kept in its own module (no TipTap import) so
|
|
7
|
+
* importing it never pulls the lazily-loaded editor chunk into a consumer's
|
|
8
|
+
* bundle.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MENTION_PILL_CLASS = "rounded-md bg-primary/10 px-1 py-0.5 font-medium text-primary";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Round-trip between the mention editor's document and the composer's plain
|
|
3
|
+
* `value` string. A mention node serializes to `@<id>`; parsing restores a
|
|
4
|
+
* pill only for ids the session already knows (fetched, inserted, or
|
|
5
|
+
* restored), so unknown `@…` runs stay literal text.
|
|
6
|
+
*
|
|
7
|
+
* The document shape is kept structural (no TipTap import) so this round-trip
|
|
8
|
+
* is unit-testable on its own and never pulls the editor chunk into a bundle.
|
|
9
|
+
*/
|
|
10
|
+
import type { MentionItem } from './use-file-mentions';
|
|
11
|
+
/**
|
|
12
|
+
* The subset of a TipTap/ProseMirror JSON document the mention editor
|
|
13
|
+
* produces: a `doc` of paragraphs, each holding text, hard breaks, and atomic
|
|
14
|
+
* mention nodes.
|
|
15
|
+
*/
|
|
16
|
+
export interface MentionDocNode {
|
|
17
|
+
type: string;
|
|
18
|
+
text?: string;
|
|
19
|
+
attrs?: {
|
|
20
|
+
id?: string | null;
|
|
21
|
+
label?: string | null;
|
|
22
|
+
kind?: string | null;
|
|
23
|
+
};
|
|
24
|
+
content?: MentionDocNode[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Plain-text serialization of the editor document. Paragraphs join with a
|
|
28
|
+
* newline, hard breaks become a newline, and a mention node becomes `@<id>` —
|
|
29
|
+
* the stable text form the controlled `value` carries.
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeMentionDoc(doc: MentionDocNode): string;
|
|
32
|
+
/** Every mention node in the document, in order, as `MentionItem`s. */
|
|
33
|
+
export declare function collectMentions(doc: MentionDocNode): MentionItem[];
|
|
34
|
+
/**
|
|
35
|
+
* Parse a controlled `value` string back into an editor document. `@<id>`
|
|
36
|
+
* runs that match a currently-known mention restore as atomic mention nodes;
|
|
37
|
+
* every other `@…` stays literal text. Each line becomes a paragraph — a
|
|
38
|
+
* deliberate asymmetry with `serializeMentionDoc`, which also flattens an
|
|
39
|
+
* in-paragraph `hardBreak` to `\n`: the string round-trips byte-identically,
|
|
40
|
+
* but a restored Shift+Enter comes back as a paragraph break. The two render
|
|
41
|
+
* identically under the composer's styling (no paragraph margins), so the
|
|
42
|
+
* plain-text `value` contract stays the source of truth.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseMentionValue(value: string, known: Map<string, MentionItem>): MentionDocNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `useFileMentions` — the glue a host passes straight into `
|
|
3
|
-
* `mention` prop
|
|
4
|
-
*
|
|
2
|
+
* `useFileMentions` — the glue a host passes straight into `ChatComposer`'s
|
|
3
|
+
* `mention` prop to wire up `@`-file mentions against
|
|
4
|
+
* `createSandboxFileIndexRoute` (`/chat-routes`).
|
|
5
5
|
*
|
|
6
6
|
* Fetches the index once per session from `indexUrl`, refreshes it in the
|
|
7
7
|
* background whenever the popover opens (a `fetchItems` call) if the cached
|
|
@@ -10,31 +10,45 @@
|
|
|
10
10
|
* `refresh()` lets a caller force a re-fetch immediately instead of waiting
|
|
11
11
|
* on `refreshAfterMs` — e.g. right after the agent creates a file mid-session.
|
|
12
12
|
*
|
|
13
|
-
* `MentionItem
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* `MentionItem` and `ComposerMentionProp` are the mention contract this
|
|
14
|
+
* package defines and `mention-editor.tsx` renders. The shape stays
|
|
15
|
+
* structurally identical to sandbox-ui#184's `AgentComposerProps['mention']`,
|
|
16
|
+
* so the same value drives sandbox-ui's `AgentComposer` during migration
|
|
17
|
+
* (tangle-network/agent-dev-container#5934) without an import either way.
|
|
16
18
|
*/
|
|
17
19
|
import type { ReactNode } from 'react';
|
|
18
20
|
import type { FileMention } from '../chat-routes/wire';
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
/** The atomic pill's payload. For a file mention, `id` is the
|
|
22
|
+
* workspace-relative path (the pill's stable identity and the `@<id>`
|
|
23
|
+
* serialization the editor uses to round-trip `value`), `label` is the
|
|
24
|
+
* display name, and `detail` carries the full path for the popover row's
|
|
25
|
+
* secondary line. */
|
|
24
26
|
export interface MentionItem {
|
|
25
27
|
id: string;
|
|
26
28
|
label: string;
|
|
27
29
|
detail?: string;
|
|
28
30
|
kind?: string;
|
|
29
31
|
}
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
+
/** `ChatComposer`'s `mention` prop shape — plug the hook's `mention` return
|
|
33
|
+
* value straight into it. Structurally identical to sandbox-ui#184's
|
|
34
|
+
* `AgentComposerProps['mention']`, so it also drives `AgentComposer`. */
|
|
32
35
|
export interface ComposerMentionProp {
|
|
36
|
+
/** The character that opens the popover. Default "@". Read once when the
|
|
37
|
+
* editor mounts — a runtime change does not re-key the editor. */
|
|
33
38
|
trigger?: string;
|
|
39
|
+
/** Async provider called with the query typed after the trigger. */
|
|
34
40
|
fetchItems(query: string): Promise<MentionItem[]>;
|
|
41
|
+
/** Fired with the mentions currently in the document whenever they change. */
|
|
35
42
|
onMentionsChange?(mentions: MentionItem[]): void;
|
|
43
|
+
/** Custom row renderer for a popover item. */
|
|
36
44
|
renderItem?(item: MentionItem): ReactNode;
|
|
45
|
+
/** Shown when a fetch resolves to zero items. Default "No matches". */
|
|
37
46
|
emptyText?: string;
|
|
47
|
+
/** Extra classes merged onto the suggestion panel's root element
|
|
48
|
+
* (`role="listbox"`), applied last so they win over the component's own —
|
|
49
|
+
* the supported way to retheme the popover instead of targeting it by its
|
|
50
|
+
* ARIA attributes. */
|
|
51
|
+
popoverClassName?: string;
|
|
38
52
|
}
|
|
39
53
|
/**
|
|
40
54
|
* Ranks `files` against `query` (case-insensitive), capped to `limit`:
|
|
@@ -77,7 +91,7 @@ export interface UseFileMentionsOptions {
|
|
|
77
91
|
}
|
|
78
92
|
/** Provide properties and methods to manage and refresh file mentions in a composer interface */
|
|
79
93
|
export interface UseFileMentionsResult {
|
|
80
|
-
/** Spread straight into `
|
|
94
|
+
/** Spread straight into `ChatComposer`'s `mention` prop. */
|
|
81
95
|
mention: ComposerMentionProp;
|
|
82
96
|
/** The files currently referenced by mentions in the composer's value —
|
|
83
97
|
* the send-body list (map through `fileMentionsToParts`). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-app",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.4",
|
|
4
4
|
"packageManager": "pnpm@11.17.0",
|
|
5
5
|
"description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
|
|
6
6
|
"keywords": [
|
|
@@ -530,6 +530,13 @@
|
|
|
530
530
|
"@tangle-network/ui": "^11.5.0",
|
|
531
531
|
"@testing-library/dom": "^10.4.1",
|
|
532
532
|
"@testing-library/react": "^16.3.2",
|
|
533
|
+
"@testing-library/user-event": "^14.6.1",
|
|
534
|
+
"@tiptap/core": "^3.28.0",
|
|
535
|
+
"@tiptap/extension-mention": "^3.28.0",
|
|
536
|
+
"@tiptap/pm": "^3.28.0",
|
|
537
|
+
"@tiptap/react": "^3.28.0",
|
|
538
|
+
"@tiptap/starter-kit": "^3.28.0",
|
|
539
|
+
"@tiptap/suggestion": "^3.28.0",
|
|
533
540
|
"@types/better-sqlite3": "^7.6.13",
|
|
534
541
|
"@types/node": "^22.20.1",
|
|
535
542
|
"@types/react": "^19.0.0",
|
|
@@ -579,6 +586,12 @@
|
|
|
579
586
|
"@tangle-network/sandbox": ">=0.29.0 <0.30.0",
|
|
580
587
|
"@tangle-network/sandbox-ui": ">=0.105.0",
|
|
581
588
|
"@tangle-network/ui": ">=11.5.0",
|
|
589
|
+
"@tiptap/core": ">=3.28.0 <4.0.0",
|
|
590
|
+
"@tiptap/extension-mention": ">=3.28.0 <4.0.0",
|
|
591
|
+
"@tiptap/pm": ">=3.28.0 <4.0.0",
|
|
592
|
+
"@tiptap/react": ">=3.28.0 <4.0.0",
|
|
593
|
+
"@tiptap/starter-kit": ">=3.28.0 <4.0.0",
|
|
594
|
+
"@tiptap/suggestion": ">=3.28.0 <4.0.0",
|
|
582
595
|
"@xyflow/react": ">=12.0.0",
|
|
583
596
|
"better-auth": ">=1.6.16",
|
|
584
597
|
"drizzle-orm": ">=0.36",
|
|
@@ -634,6 +647,24 @@
|
|
|
634
647
|
"@tangle-network/brand": {
|
|
635
648
|
"optional": true
|
|
636
649
|
},
|
|
650
|
+
"@tiptap/core": {
|
|
651
|
+
"optional": true
|
|
652
|
+
},
|
|
653
|
+
"@tiptap/extension-mention": {
|
|
654
|
+
"optional": true
|
|
655
|
+
},
|
|
656
|
+
"@tiptap/pm": {
|
|
657
|
+
"optional": true
|
|
658
|
+
},
|
|
659
|
+
"@tiptap/react": {
|
|
660
|
+
"optional": true
|
|
661
|
+
},
|
|
662
|
+
"@tiptap/starter-kit": {
|
|
663
|
+
"optional": true
|
|
664
|
+
},
|
|
665
|
+
"@tiptap/suggestion": {
|
|
666
|
+
"optional": true
|
|
667
|
+
},
|
|
637
668
|
"@xyflow/react": {
|
|
638
669
|
"optional": true
|
|
639
670
|
},
|