@qilin-agent/client-ui-conversation 3.1.5 → 3.1.7
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.i18n.yaml +2 -2
- package/README.md +7 -3
- package/README.zh.md +7 -3
- package/lib/client.js +5147 -454
- package/lib/index.js +13 -9
- package/lib/types/client/contract/composer-submission.d.ts +23 -0
- package/lib/types/client/contract/conversation.d.ts +10 -0
- package/lib/types/client/contract/draft-editor.d.ts +23 -0
- package/lib/types/client/contract/input.d.ts +42 -10
- package/lib/types/client/contract/records.d.ts +8 -3
- package/lib/types/client/contract/slots.d.ts +61 -5
- package/lib/types/client/contract/views.d.ts +2 -1
- package/lib/types/client/conversation/assembler.d.ts +3 -0
- package/lib/types/client/draft.d.ts +22 -0
- package/lib/types/client/index.d.ts +3 -3
- package/lib/types/client/input/decorations.d.ts +1 -1
- package/lib/types/client/input/editor/CommandChip.d.ts +13 -0
- package/lib/types/client/input/editor/command-chip-node.d.ts +87 -0
- package/lib/types/client/input/editor/command-chip-selection.d.ts +20 -0
- package/lib/types/client/input/editor/keymap.d.ts +6 -2
- package/lib/types/client/input/editor/projection.d.ts +3 -0
- package/lib/types/client/input/editor/runtime.d.ts +33 -11
- package/lib/types/client/input/editor/text-ref.d.ts +2 -7
- package/lib/types/client/input/editor/view-binding.d.ts +1 -1
- package/lib/types/client/input/facade.d.ts +74 -18
- package/lib/types/client/input/hub.d.ts +2 -10
- package/lib/types/client/input/machine.d.ts +9 -5
- package/lib/types/client/input/submission-analytics.d.ts +10 -0
- package/lib/types/client/locales.d.ts +12 -16
- package/lib/types/client/skeleton/ConversationSession.d.ts +1 -1
- package/lib/types/client/skeleton/DefaultConversationViews.d.ts +2 -2
- package/lib/types/client/skeleton/InputBar.d.ts +1 -1
- package/lib/types/client/stores.d.ts +8 -1
- package/lib/types/client/view-pins.d.ts +22 -0
- package/lib/types/conversation-settings.d.ts +4 -0
- package/lib/types/index.d.ts +20 -5
- package/package.json +37 -35
- package/lib/types/client/input/editor/claim-decor.d.ts +0 -23
- package/lib/types/client/settings/ContentWidthRow.d.ts +0 -26
package/lib/index.js
CHANGED
|
@@ -26,21 +26,25 @@ const CONTENT_WIDTH_STEP = 20;
|
|
|
26
26
|
/** Content width before the user picks one. */
|
|
27
27
|
const DEFAULT_CONTENT_WIDTH = 0;
|
|
28
28
|
/** Durable conversation schema; also the wire envelope the browser scope validates against. */
|
|
29
|
-
const
|
|
29
|
+
const ConversationSettingsFields = {
|
|
30
30
|
[BUSY_ENTER_FIELD]: z.union([...BUSY_ENTER_BEHAVIORS]).default(DEFAULT_BUSY_ENTER_BEHAVIOR),
|
|
31
31
|
[CONTENT_WIDTH_FIELD]: z.natural().max(CONTENT_WIDTH_MAX).default(0)
|
|
32
|
-
}
|
|
32
|
+
};
|
|
33
|
+
z.object(ConversationSettingsFields);
|
|
33
34
|
//#endregion
|
|
34
35
|
//#region lib/types/index.js
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
/** Live preferences projected to the browser. */
|
|
37
|
+
const Config = z.object({
|
|
38
|
+
[BUSY_ENTER_FIELD]: ConversationSettingsFields[BUSY_ENTER_FIELD].volatile(),
|
|
39
|
+
[CONTENT_WIDTH_FIELD]: ConversationSettingsFields[CONTENT_WIDTH_FIELD].volatile()
|
|
40
|
+
});
|
|
41
|
+
/** Host preferences are consumed through the configuration form projection.
|
|
42
|
+
* @param ctx Plugin context used for optional settings presentation.
|
|
39
43
|
*/
|
|
40
44
|
function apply(ctx) {
|
|
41
|
-
ctx.inject(["settings"], (
|
|
42
|
-
|
|
45
|
+
ctx.inject(["settings"], (child) => {
|
|
46
|
+
child.effect(() => child.settings.configure({ auto: false }, ctx.fiber));
|
|
43
47
|
});
|
|
44
48
|
}
|
|
45
49
|
//#endregion
|
|
46
|
-
export { BUSY_ENTER_BEHAVIORS, BUSY_ENTER_FIELD, CONTENT_WIDTH_ADAPTIVE, CONTENT_WIDTH_FIELD, CONTENT_WIDTH_MAX, CONTENT_WIDTH_MIN, CONTENT_WIDTH_STEP, CONVERSATION_SETTINGS_NAMESPACE, DEFAULT_BUSY_ENTER_BEHAVIOR, DEFAULT_CONTENT_WIDTH, apply };
|
|
50
|
+
export { BUSY_ENTER_BEHAVIORS, BUSY_ENTER_FIELD, CONTENT_WIDTH_ADAPTIVE, CONTENT_WIDTH_FIELD, CONTENT_WIDTH_MAX, CONTENT_WIDTH_MIN, CONTENT_WIDTH_STEP, CONVERSATION_SETTINGS_NAMESPACE, Config, DEFAULT_BUSY_ENTER_BEHAVIOR, DEFAULT_CONTENT_WIDTH, apply };
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
/** Composer submission vocabulary shared by the input and settings domains. */
|
|
2
2
|
import type { BusyEnterBehavior } from '../../conversation-settings.ts';
|
|
3
|
+
import type { SessionId } from '@qilin-agent/session/types';
|
|
3
4
|
export type { BusyEnterBehavior } from '../../conversation-settings.ts';
|
|
4
5
|
/** Delivery mode requested for one ordinary composer message. */
|
|
5
6
|
export type InputSubmitMode = BusyEnterBehavior;
|
|
6
7
|
/** Keyboard gesture whose delivery mode the submission policy resolves. */
|
|
7
8
|
export type ComposerSubmitGesture = 'enter' | 'accelerated';
|
|
9
|
+
/** Session facts captured when a message submission starts, before asynchronous command arbitration. */
|
|
10
|
+
export interface MessageSubmissionState {
|
|
11
|
+
readonly sessionId?: SessionId;
|
|
12
|
+
readonly model?: {
|
|
13
|
+
readonly provider: string;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly effort?: string;
|
|
16
|
+
};
|
|
17
|
+
readonly runMode: 'default' | 'plan' | 'goal';
|
|
18
|
+
readonly running: boolean;
|
|
19
|
+
/** Whether the Session is still blank, so this message is its first. */
|
|
20
|
+
readonly newSession: boolean;
|
|
21
|
+
/** Agent preset id the Session records, when known. */
|
|
22
|
+
readonly agentPreset?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Immutable occurrence and delivery intent carried by one composer attempt. */
|
|
25
|
+
export interface MessageSubmission {
|
|
26
|
+
readonly timestamp: number;
|
|
27
|
+
readonly source?: 'click' | 'enter';
|
|
28
|
+
readonly mode: InputSubmitMode;
|
|
29
|
+
readonly state?: MessageSubmissionState;
|
|
30
|
+
}
|
|
8
31
|
//# sourceMappingURL=composer-submission.d.ts.map
|
|
@@ -5,6 +5,16 @@ import type { ConversationGroupData, ConversationGroupedView, ConversationGroupI
|
|
|
5
5
|
export interface ConversationMatchResult {
|
|
6
6
|
readonly id: string;
|
|
7
7
|
readonly role: 'start' | 'update';
|
|
8
|
+
/**
|
|
9
|
+
* Claim this event on the Definition's target: no other Definition of the
|
|
10
|
+
* same target receives it, and that target's unmatched-event fallback does
|
|
11
|
+
* not run. Definitions of other targets and Definitions without a target
|
|
12
|
+
* still receive it. Two claims on one target, or a claim from a Definition
|
|
13
|
+
* without a target, throw during dispatch. A claim returned by the fallback
|
|
14
|
+
* itself has no effect, because the fallback runs only when no Definition of
|
|
15
|
+
* its target matched.
|
|
16
|
+
*/
|
|
17
|
+
readonly exclusive?: true;
|
|
8
18
|
}
|
|
9
19
|
/** Merge-extensible business values published against one Turn. */
|
|
10
20
|
export interface ConversationTurnDataMap {
|
|
@@ -16,6 +16,29 @@ export interface ReferenceInsert {
|
|
|
16
16
|
readonly appearance?: 'session' | 'file' | 'folder';
|
|
17
17
|
readonly clipboardText: string;
|
|
18
18
|
}
|
|
19
|
+
/** Persisted reference data without the current editor's occurrence identity. */
|
|
20
|
+
export type DraftReference = Omit<Occurrence, 'occurrenceId'>;
|
|
21
|
+
/**
|
|
22
|
+
* Persisted command chip opening a draft. The claim itself (its submit
|
|
23
|
+
* closure) is not persisted; the input rebuilds it from the token through the
|
|
24
|
+
* trigger pipeline when the draft is restored.
|
|
25
|
+
*/
|
|
26
|
+
export interface DraftCommand {
|
|
27
|
+
/** Claim token with its argument separator, e.g. `/goal `; the draft text starts with the token without the separator. */
|
|
28
|
+
readonly token: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Editor-independent content. Reference spans are ordered, non-overlapping UTF-16
|
|
32
|
+
* ranges whose text equals clipboardText and that follow a leading command
|
|
33
|
+
* token; runtime node identities are excluded.
|
|
34
|
+
*/
|
|
35
|
+
export interface DraftSnapshot {
|
|
36
|
+
readonly text: string;
|
|
37
|
+
readonly references: readonly DraftReference[];
|
|
38
|
+
readonly command?: DraftCommand;
|
|
39
|
+
}
|
|
40
|
+
/** Plain initial text or an existing document with explicit reference identities. */
|
|
41
|
+
export type DraftInput = string | DraftSnapshot;
|
|
19
42
|
/** Keyboard keys intercepted by an open trigger menu. */
|
|
20
43
|
export type ArbitrateKey = 'up' | 'down' | 'enter' | 'escape' | 'tab' | 'tabBack';
|
|
21
44
|
/** Trigger-menu keyboard routing result. */
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* here is the submit plane (phase, claim, attempt) alone.
|
|
8
8
|
*/
|
|
9
9
|
import type { Context } from '@qilin-agent/kylin';
|
|
10
|
+
import type { SessionBinding } from '@qilin-agent/api-session-controller/client';
|
|
10
11
|
import type { InboxState } from '@qilin-agent/agent/types';
|
|
11
12
|
import type { ObservableSnapshot, SnapshotStore } from '@qilin-agent/client-store';
|
|
12
13
|
import type { Branded } from '@qilin-agent/brand';
|
|
@@ -35,7 +36,7 @@ export interface SubmitOutcome {
|
|
|
35
36
|
export interface CommandClaim {
|
|
36
37
|
/** Catalog command name without the leading slash (the key of per-command composer copy such as `hint.*`). */
|
|
37
38
|
readonly name: string;
|
|
38
|
-
/**
|
|
39
|
+
/** Command spelling followed by its argument separator; the composer shows the spelling as a chip and inserts the separator after it. */
|
|
39
40
|
readonly token: string;
|
|
40
41
|
readonly hint?: string;
|
|
41
42
|
readonly attachments?: boolean;
|
|
@@ -109,6 +110,13 @@ export interface InputTriggerController {
|
|
|
109
110
|
adjudicate(line: string, signal: AbortSignal, envelope: {
|
|
110
111
|
readonly attachments: number;
|
|
111
112
|
}): Promise<PickOutcome>;
|
|
113
|
+
/**
|
|
114
|
+
* Resolve the claim a persisted command chip names without acting on it.
|
|
115
|
+
* @param token - command spelling without its argument separator, e.g. '/goal'.
|
|
116
|
+
* @param signal - restore-attempt abort.
|
|
117
|
+
* @returns the claim, or undefined when no source claims the token; rejects when catalog warmup fails.
|
|
118
|
+
*/
|
|
119
|
+
resolveClaim(token: string, signal: AbortSignal): Promise<CommandClaim | undefined>;
|
|
112
120
|
/**
|
|
113
121
|
* @param source - chip owner, or undefined for a text reference.
|
|
114
122
|
* @param reference - source id and glyph.
|
|
@@ -154,14 +162,14 @@ export type DraftAttachmentId = Branded<'DraftAttachmentId'>;
|
|
|
154
162
|
* applied the edit after phase and span guards).
|
|
155
163
|
*/
|
|
156
164
|
export interface InputTarget {
|
|
157
|
-
/** Replace the trigger span with
|
|
165
|
+
/** Replace the leading trigger span with a command chip and enter claimed (span-CAS'd). */
|
|
158
166
|
beginCommand(claim: CommandClaim, span: TokenSpan): boolean;
|
|
159
167
|
/** Replace the trigger span with one reference chip (span-CAS'd). */
|
|
160
168
|
insertReference(ref: ReferenceInsert, span: TokenSpan): boolean;
|
|
161
169
|
}
|
|
162
170
|
/** Per-session input facade owned by the conversation wiring layer. */
|
|
163
171
|
export interface SessionInput extends InputTarget {
|
|
164
|
-
/** Replace the whole draft
|
|
172
|
+
/** Replace the whole draft with plain text, removing inline reference chips. */
|
|
165
173
|
setDraft(text: string): void;
|
|
166
174
|
/** Append ordered browser-owned attachment ids; busy admission phases refuse. */
|
|
167
175
|
addAttachments(ids: readonly DraftAttachmentId[]): boolean;
|
|
@@ -196,7 +204,29 @@ export interface SessionInput extends InputTarget {
|
|
|
196
204
|
export interface SessionInputResolver {
|
|
197
205
|
/** Resolve the facade for one session-scope ctx. */
|
|
198
206
|
for(actx: Context): SessionInput;
|
|
207
|
+
/**
|
|
208
|
+
* Prepare the exact retained Session before navigation publishes it.
|
|
209
|
+
* @param binding - target Session generation, already retained by the caller.
|
|
210
|
+
* @param options - content to adopt and the handling of an existing draft.
|
|
211
|
+
* @returns applied, preserved, or blocked by a pending submission or disposal.
|
|
212
|
+
*/
|
|
213
|
+
requestDraftInitialization(binding: SessionBinding, options: DraftInitializationOptions): DraftInitializationResult;
|
|
199
214
|
}
|
|
215
|
+
/** Initial text for a target Session; attachments remain under their existing owner. */
|
|
216
|
+
export interface DraftInitializationOptions {
|
|
217
|
+
readonly prompt?: string;
|
|
218
|
+
/** `true` acts as `whenDraftExists: 'replace'`; ignored when `whenDraftExists` is set. */
|
|
219
|
+
readonly clearPreviousDraft?: boolean;
|
|
220
|
+
/**
|
|
221
|
+
* Handling of a target that already has text or attachments: `replace` swaps the text and
|
|
222
|
+
* inline references for the prompt (or clears them without one), `append` adds the prompt
|
|
223
|
+
* as new paragraphs after the existing text, and `keep` leaves the draft unchanged. Omitted,
|
|
224
|
+
* it is `replace` when `clearPreviousDraft` is true and `keep` otherwise.
|
|
225
|
+
*/
|
|
226
|
+
readonly whenDraftExists?: 'replace' | 'append' | 'keep';
|
|
227
|
+
}
|
|
228
|
+
/** An initialization request never waits for a React mount or a remote catalog. */
|
|
229
|
+
export type DraftInitializationResult = 'applied' | 'preserved' | 'blocked';
|
|
200
230
|
/**
|
|
201
231
|
* The public input action face provided to every session-scope slot
|
|
202
232
|
* component: stable-identity void callbacks, mirroring the
|
|
@@ -213,8 +243,10 @@ export interface InputActions {
|
|
|
213
243
|
* @returns false when the draft changed or submission locked the editor.
|
|
214
244
|
*/
|
|
215
245
|
insertText(text: string, span: TokenSpan): boolean;
|
|
216
|
-
/** Replace the whole draft
|
|
246
|
+
/** Replace the whole draft with plain text, removing inline reference chips. */
|
|
217
247
|
setDraft(text: string): void;
|
|
248
|
+
/** Write the current semantic document through the mounted persistence callback. */
|
|
249
|
+
persistDraft(): void;
|
|
218
250
|
/** Append ordered browser-owned attachment ids; busy admission phases refuse. */
|
|
219
251
|
addAttachments(ids: readonly DraftAttachmentId[]): boolean;
|
|
220
252
|
/** Remove one browser-owned attachment id; busy admission phases refuse. */
|
|
@@ -272,15 +304,15 @@ export interface SubmitAttempt {
|
|
|
272
304
|
/**
|
|
273
305
|
* Submit-machine input events (the machine's single write path). Text
|
|
274
306
|
* mutation lives in the editor; the machine only observes the draft through
|
|
275
|
-
* event payloads (
|
|
307
|
+
* event payloads (leading command chip, enter snapshots, settlement decisions).
|
|
276
308
|
*/
|
|
277
309
|
export type InputEvent =
|
|
278
|
-
/**
|
|
310
|
+
/** Editor content changed; carries the claim of the leading command chip, if any (zero effects). */
|
|
279
311
|
{
|
|
280
312
|
readonly type: 'draft-changed';
|
|
281
|
-
readonly
|
|
313
|
+
readonly command: CommandClaim | undefined;
|
|
282
314
|
}
|
|
283
|
-
/** The editor
|
|
315
|
+
/** The editor inserted a command chip: enter claimed. */
|
|
284
316
|
| {
|
|
285
317
|
readonly type: 'claim';
|
|
286
318
|
readonly claim: CommandClaim;
|
|
@@ -299,12 +331,12 @@ export type InputEvent =
|
|
|
299
331
|
readonly attempt: SubmitAttempt;
|
|
300
332
|
readonly message: string;
|
|
301
333
|
}
|
|
302
|
-
/** Settlement carries the
|
|
334
|
+
/** Settlement carries the leading command chip's claim, which the claim follows after a failure. */
|
|
303
335
|
| {
|
|
304
336
|
readonly type: 'submit-settled';
|
|
305
337
|
readonly attempt: SubmitAttempt;
|
|
306
338
|
readonly ok: boolean;
|
|
307
|
-
readonly
|
|
339
|
+
readonly command: CommandClaim | undefined;
|
|
308
340
|
readonly outcome?: SubmitOutcome;
|
|
309
341
|
readonly message?: string;
|
|
310
342
|
}
|
|
@@ -122,8 +122,9 @@ export type ModelRetryNode = LlmRetryEventData & {
|
|
|
122
122
|
retryState: 'scheduled' | 'started' | 'cancelled';
|
|
123
123
|
};
|
|
124
124
|
/**
|
|
125
|
-
* Durable terminal
|
|
126
|
-
*
|
|
125
|
+
* Durable terminal notice for a turn that ended with an error, a sign-out
|
|
126
|
+
* cancellation, or an interruption by a QiLin stop; the turn's settled retry
|
|
127
|
+
* chain renders separately and never replaces this node.
|
|
127
128
|
*/
|
|
128
129
|
export interface TurnErrorNode {
|
|
129
130
|
kind: 'turn-error';
|
|
@@ -135,7 +136,11 @@ export interface TurnErrorNode {
|
|
|
135
136
|
step: number;
|
|
136
137
|
/** Sanitized provider message; empty when a known code owns localized copy. */
|
|
137
138
|
message: string;
|
|
138
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* Stable provider failure code when recorded, or a Client display code:
|
|
141
|
+
* `ACCOUNT_SIGNED_OUT` for a sign-out cancellation, `INTERRUPTED` for a turn
|
|
142
|
+
* closed after QiLin stopped.
|
|
143
|
+
*/
|
|
139
144
|
code?: string;
|
|
140
145
|
}
|
|
141
146
|
/** Durable notice for a turn ended by the per-request output-token cap. */
|
|
@@ -11,7 +11,7 @@ import type { SessionId } from '@qilin-agent/session/types';
|
|
|
11
11
|
import type { WorkspaceId } from '@qilin-agent/workspace/types';
|
|
12
12
|
import type { ComposerBlock } from './composer-blocks.ts';
|
|
13
13
|
import type { DraftAttachmentId, InputActions, InputNotice, InputState } from './input.ts';
|
|
14
|
-
import type { ComposerKeyboard, EditSelection } from './draft-editor.ts';
|
|
14
|
+
import type { ComposerKeyboard, DraftSnapshot, EditSelection } from './draft-editor.ts';
|
|
15
15
|
import type { createConversationStore } from '../stores.ts';
|
|
16
16
|
import type { BusyEnterBehavior } from './composer-submission.ts';
|
|
17
17
|
import type { ConversationSnapshot } from './snapshot.ts';
|
|
@@ -57,7 +57,7 @@ export interface ComposerAttachmentsOwnerProps {
|
|
|
57
57
|
/** Whether a document-level file drop may add attachments now. */
|
|
58
58
|
canAcceptDrop: boolean;
|
|
59
59
|
/** Add one dropped batch through the composer's validation path. */
|
|
60
|
-
onAddFiles: (files: readonly File[]) => void;
|
|
60
|
+
onAddFiles: (files: readonly File[], directories?: ReadonlySet<File>) => void;
|
|
61
61
|
/** Remove one draft attachment through the Conversation service. */
|
|
62
62
|
onRemoveAttachment: (id: DraftAttachmentId) => void;
|
|
63
63
|
/** Current per-draft upload states for file-kind attachments. */
|
|
@@ -181,6 +181,12 @@ declare module '@qilin-agent/client-ui-slots' {
|
|
|
181
181
|
scope: 'session';
|
|
182
182
|
owner: ConversationHeaderCornerOwnerProps;
|
|
183
183
|
};
|
|
184
|
+
/** Rows of the View tab row's More menu; the header shows More only while this list has registrations. */
|
|
185
|
+
'conversation.session.header.views.actions': {
|
|
186
|
+
kind: 'list';
|
|
187
|
+
scope: 'root';
|
|
188
|
+
owner: ConversationViewActionsOwnerProps;
|
|
189
|
+
};
|
|
184
190
|
/** Registered Conversation target Views, rendered one at a time. */
|
|
185
191
|
'conversation.view': {
|
|
186
192
|
kind: 'list';
|
|
@@ -211,6 +217,11 @@ declare module '@qilin-agent/client-ui-slots' {
|
|
|
211
217
|
scope: 'session-maybe';
|
|
212
218
|
owner: HeroAgentPresetOwnerProps;
|
|
213
219
|
};
|
|
220
|
+
/** Compact options right-aligned in the New Session row after the workspace and preset controls; rendered only with a Session. */
|
|
221
|
+
'conversation.hero.options': {
|
|
222
|
+
kind: 'list';
|
|
223
|
+
scope: 'session';
|
|
224
|
+
};
|
|
214
225
|
/** Full-width entries above the composer card. */
|
|
215
226
|
'conversation.input.dock': {
|
|
216
227
|
kind: 'list';
|
|
@@ -312,6 +323,10 @@ declare module '@qilin-agent/client-ui-slots' {
|
|
|
312
323
|
kind: 'single';
|
|
313
324
|
scope: 'session-maybe';
|
|
314
325
|
};
|
|
326
|
+
'conversation.hero.options': {
|
|
327
|
+
kind: 'list';
|
|
328
|
+
scope: 'session';
|
|
329
|
+
};
|
|
315
330
|
};
|
|
316
331
|
inject: ConversationInjected;
|
|
317
332
|
locale: 'conversation';
|
|
@@ -414,16 +429,55 @@ export interface ConversationSessionInjected {
|
|
|
414
429
|
readonly conversationViews: ObservableSnapshot<readonly ViewTab[]>;
|
|
415
430
|
};
|
|
416
431
|
/** Bind input draft persistence to the Session-owned store instance. */
|
|
417
|
-
|
|
432
|
+
bindDraftPersistence: (write: (draft: DraftSnapshot) => void) => () => void;
|
|
418
433
|
/** Select and activate one View while addressing an opaque focus request to it. */
|
|
419
434
|
openView: (view: string, focus: string) => void;
|
|
420
435
|
}
|
|
436
|
+
/** One customizable View tab listed in the More menu. */
|
|
437
|
+
export interface ConversationViewActionEntry {
|
|
438
|
+
/** View id. */
|
|
439
|
+
readonly id: string;
|
|
440
|
+
/** Resolved View label. */
|
|
441
|
+
readonly label: string;
|
|
442
|
+
/** False while the View is manually unpinned. A pinned View still enters More when the header's width budget cannot hold it. */
|
|
443
|
+
readonly pinned: boolean;
|
|
444
|
+
/** Whether this View is selected in this Session, independently of its pin state. */
|
|
445
|
+
readonly active?: boolean;
|
|
446
|
+
}
|
|
447
|
+
/** Owner share of the View tab row's More menu rows. */
|
|
448
|
+
export interface ConversationViewActionsOwnerProps {
|
|
449
|
+
/** Views outside the header in registration order. */
|
|
450
|
+
readonly entries: readonly ConversationViewActionEntry[];
|
|
451
|
+
/**
|
|
452
|
+
* Select a View in this Session without changing its pin state.
|
|
453
|
+
* @param id - Listed View id.
|
|
454
|
+
*/
|
|
455
|
+
readonly onOpen: (id: string) => void;
|
|
456
|
+
/**
|
|
457
|
+
* Pin or unpin a View in every Session.
|
|
458
|
+
* @param id - Listed View id.
|
|
459
|
+
* @param pinned - Whether the View is manually pinned; the width budget can still fold it into More.
|
|
460
|
+
*/
|
|
461
|
+
readonly onPinnedChange: (id: string, pinned: boolean) => void;
|
|
462
|
+
/** Close the More menu. */
|
|
463
|
+
readonly onDismiss: () => void;
|
|
464
|
+
}
|
|
421
465
|
/** Business callbacks injected into the strict Session header. */
|
|
422
466
|
export interface ConversationSessionHeaderInjected {
|
|
423
467
|
/** Package-owned View roster source bound only for the Conversation header. */
|
|
424
468
|
readonly hooks: {
|
|
425
469
|
readonly conversationViews: ObservableSnapshot<readonly ViewTab[]>;
|
|
470
|
+
/** Ids of unpinned View tabs held in memory and shared by every Session until plugin reload. */
|
|
471
|
+
readonly entryPins: ObservableSnapshot<readonly string[]>;
|
|
472
|
+
/** Whether `conversation.session.header.views.actions` has registrations. */
|
|
473
|
+
readonly entryActions: ObservableSnapshot<boolean>;
|
|
426
474
|
};
|
|
475
|
+
/**
|
|
476
|
+
* Pin or unpin one View tab in every Session; Chat is ignored.
|
|
477
|
+
* @param id - View id.
|
|
478
|
+
* @param pinned - Whether the View is manually pinned; the width budget can still fold it into More.
|
|
479
|
+
*/
|
|
480
|
+
setPinned: (id: string, pinned: boolean) => void;
|
|
427
481
|
/** Select a Session through the Session Controller. */
|
|
428
482
|
open: (sessionId: SessionId) => void;
|
|
429
483
|
/** Select and activate one registered Conversation View. */
|
|
@@ -450,7 +504,7 @@ export interface ComposerBarOwnerProps {
|
|
|
450
504
|
/** Package-private operations injected into the resident composer bar. */
|
|
451
505
|
export interface ComposerBarInjected {
|
|
452
506
|
keyboard: ComposerKeyboard | undefined;
|
|
453
|
-
addFiles: ((files: readonly File[]) => string | null) | undefined;
|
|
507
|
+
addFiles: ((files: readonly File[], directories?: ReadonlySet<File>) => string | null) | undefined;
|
|
454
508
|
removeAttachment: ((id: DraftAttachmentId) => void) | undefined;
|
|
455
509
|
resolveDraftAttachments: ((ids: readonly DraftAttachmentId[]) => readonly ComposerAttachment[]) | undefined;
|
|
456
510
|
/** Restart one failed file upload; absent without a session. */
|
|
@@ -458,6 +512,8 @@ export interface ComposerBarInjected {
|
|
|
458
512
|
toggleCommandMenu: ((selection: EditSelection) => void) | undefined;
|
|
459
513
|
stop: (() => void) | undefined;
|
|
460
514
|
hooks: {
|
|
515
|
+
/** Readable sequence while the fixed Stop command is registered. */
|
|
516
|
+
stopShortcut: ObservableSnapshot<readonly string[]>;
|
|
461
517
|
/**
|
|
462
518
|
* Live busy-state submission preference: the delivery mode plain Enter
|
|
463
519
|
* and the primary Send button use while the addressed agent is busy.
|
|
@@ -526,7 +582,7 @@ export type ConversationWidthControlsProps = FactoryLocalComponentPropsOf<'conve
|
|
|
526
582
|
/** Full props of the strict Session body. */
|
|
527
583
|
export type ConversationSessionSlotProps = PropsRuntime<'conversation.session'> & PropsRenderSlots<'conversation.view'> & PropsStore<ConversationStore> & InjectFace<ConversationSessionInjected>;
|
|
528
584
|
/** Full props of the strict Session header. */
|
|
529
|
-
export type ConversationSessionHeaderSlotProps = PropsRuntime<'conversation.session.header'> & PropsRenderSlots<'conversation.session.header.lineage' | 'conversation.session.header.actions' | 'conversation.session.header.utilities' | 'conversation.session.header.corner'> & PropsStore<ConversationStore> & InjectFace<ConversationSessionHeaderInjected> & PropsLocale<'conversation'>;
|
|
585
|
+
export type ConversationSessionHeaderSlotProps = PropsRuntime<'conversation.session.header'> & PropsRenderSlots<'conversation.session.header.lineage' | 'conversation.session.header.actions' | 'conversation.session.header.utilities' | 'conversation.session.header.corner' | 'conversation.session.header.views.actions'> & PropsStore<ConversationStore> & InjectFace<ConversationSessionHeaderInjected> & PropsLocale<'conversation'>;
|
|
530
586
|
/** Full props of the draft-attachment renderer. */
|
|
531
587
|
export type ComposerAttachmentsProps = PropsRuntime<'conversation.input.attachments'> & PropsLocale<'conversation'>;
|
|
532
588
|
/** Owner share common to blank-session Workspace pickers. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Conversation view and session-local presentation state. */
|
|
2
|
+
import type { DraftInput } from './draft-editor.ts';
|
|
2
3
|
/**
|
|
3
4
|
* One conversation view tab, projected from a 'conversation.view' slot
|
|
4
5
|
* entry's registration options (label falls back to the entry id).
|
|
@@ -27,7 +28,7 @@ export interface ConversationViewRequest {
|
|
|
27
28
|
/** The conversation store's own state: the composer draft, the selected View, and one pending focus request. */
|
|
28
29
|
export interface ConversationStoreState {
|
|
29
30
|
/** Composer draft (persisted; survives session switches and reloads). */
|
|
30
|
-
draft:
|
|
31
|
+
draft: DraftInput;
|
|
31
32
|
/** Preferred `conversation.view` entry id; null resolves to Chat when registered. */
|
|
32
33
|
view: string | null;
|
|
33
34
|
/** One-shot focus request addressed to the selected View. */
|
|
@@ -43,6 +43,9 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
|
|
|
43
43
|
private readonly groups;
|
|
44
44
|
private readonly pendingGroupStores;
|
|
45
45
|
private readonly activeTargets;
|
|
46
|
+
/** Matches of the event in dispatch, kept by index; dispatch is not reentrant and reuses both arrays. */
|
|
47
|
+
private readonly matchedDefinitions;
|
|
48
|
+
private readonly matchedResults;
|
|
46
49
|
private hasMore;
|
|
47
50
|
private replacePending;
|
|
48
51
|
private timelineDirty;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DraftInput, DraftSnapshot, Occurrence } from './contract/draft-editor.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Copy input into the semantic draft representation without editor runtime identities.
|
|
4
|
+
* @param input - plain text or caller-owned structured content.
|
|
5
|
+
* @returns an owned snapshot ready for editor import.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveDraftInput(input: DraftInput): DraftSnapshot;
|
|
8
|
+
/**
|
|
9
|
+
* Decode persisted drafts, accepting the earlier plain-string representation.
|
|
10
|
+
* @param value - JSON value read from browser storage.
|
|
11
|
+
* @returns the decoded draft, or undefined for invalid data.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseStoredDraft(value: unknown): DraftSnapshot | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Export reference identities without their editor-local occurrence ids.
|
|
16
|
+
* @param text - current clipboard projection.
|
|
17
|
+
* @param occurrences - matching reference projections from the same document revision.
|
|
18
|
+
* @param commandToken - claim token of the command chip opening the document, if any.
|
|
19
|
+
* @returns an editor-independent snapshot.
|
|
20
|
+
*/
|
|
21
|
+
export declare function snapshotDraft(text: string, occurrences: readonly Occurrence[], commandToken?: string): DraftSnapshot;
|
|
22
|
+
//# sourceMappingURL=draft.d.ts.map
|
|
@@ -24,9 +24,9 @@ export { ConversationLocationIndex } from './conversation/location-index.ts';
|
|
|
24
24
|
export type { ConversationLocationDataChange } from './conversation/location-index.ts';
|
|
25
25
|
export { ConversationViewRegistry } from './conversation/view-registry.ts';
|
|
26
26
|
export type { ConversationKey } from './locales.ts';
|
|
27
|
-
export type { ComposerAttachment, ComposerAttachmentsOwnerProps, ComposerAttachmentsProps, ComposerFileAttachment, ComposerImageAttachment, DraftFileUpload, DraftFileUploads, ComposerBarInjected, ComposerBarOwnerProps, ComposerBarProps, ComposerChainProps, ConversationHeaderActionOwnerProps, ConversationHeaderCornerOwnerProps, ConversationHeaderLineageOwnerProps, ConversationContentInputProps, ConversationContentProps, ConversationInjected, ConversationSessionHeaderInjected, ConversationSessionHeaderSlotProps, ConversationSessionInjected, ConversationSessionSlotProps, ConversationSlotProps, ConversationViewsProps, ConversationWidthControlsInputProps, ConversationWidthControlsProps, ConversationStore, ConvViewOwnerProps, ConvViewProps, EmptyWorkspaceOwnerProps, HeroAgentPresetOwnerProps, HeroBrandMarkOwnerProps, InputControlOwnerProps, InputZone, MessageImageLoader, MessageImageSource, MessageImagesOwnerProps, RenderMessageImages, UseConversation, UseConversationViews, } from './contract/slots.ts';
|
|
28
|
-
export type { BeginCommandRequest, CommandClaim, ConsumeTokenRequest, DraftAttachmentId, InputActions, InputState, InsertReferenceRequest, InsertTextRequest, PickOutcome, SessionInput, SessionInputResolver, SubmitAttachment, SubmitOutcome, } from './contract/input.ts';
|
|
29
|
-
export type { ArbitrateKey, ArbitrateOutcome, ReferenceInsert, TokenSpan } from './contract/draft-editor.ts';
|
|
27
|
+
export type { ComposerAttachment, ComposerAttachmentsOwnerProps, ComposerAttachmentsProps, ComposerFileAttachment, ComposerImageAttachment, DraftFileUpload, DraftFileUploads, ComposerBarInjected, ComposerBarOwnerProps, ComposerBarProps, ComposerChainProps, ConversationHeaderActionOwnerProps, ConversationHeaderCornerOwnerProps, ConversationHeaderLineageOwnerProps, ConversationContentInputProps, ConversationContentProps, ConversationInjected, ConversationSessionHeaderInjected, ConversationSessionHeaderSlotProps, ConversationSessionInjected, ConversationSessionSlotProps, ConversationSlotProps, ConversationViewActionEntry, ConversationViewActionsOwnerProps, ConversationViewsProps, ConversationWidthControlsInputProps, ConversationWidthControlsProps, ConversationStore, ConvViewOwnerProps, ConvViewProps, EmptyWorkspaceOwnerProps, HeroAgentPresetOwnerProps, HeroBrandMarkOwnerProps, InputControlOwnerProps, InputZone, MessageImageLoader, MessageImageSource, MessageImagesOwnerProps, RenderMessageImages, UseConversation, UseConversationViews, } from './contract/slots.ts';
|
|
28
|
+
export type { BeginCommandRequest, CommandClaim, ConsumeTokenRequest, DraftAttachmentId, DraftInitializationOptions, DraftInitializationResult, InputActions, InputState, InsertReferenceRequest, InsertTextRequest, PickOutcome, SessionInput, SessionInputResolver, SubmitAttachment, SubmitOutcome, } from './contract/input.ts';
|
|
29
|
+
export type { ArbitrateKey, ArbitrateOutcome, DraftInput, DraftReference, DraftSnapshot, ReferenceInsert, TokenSpan } from './contract/draft-editor.ts';
|
|
30
30
|
export type { ComposerBlock, ComposerBlocks } from './contract/composer-blocks.ts';
|
|
31
31
|
declare module '@qilin-agent/kylin' {
|
|
32
32
|
interface Context {
|
|
@@ -25,7 +25,7 @@ export interface TextRefRange {
|
|
|
25
25
|
* exact lexicon member; a `/name` token must end at whitespace or the draft
|
|
26
26
|
* end ('/name/x' is a path, '/name。' is prose).
|
|
27
27
|
* @param draft - draft text.
|
|
28
|
-
* @param lexicon - per-trigger name lists
|
|
28
|
+
* @param lexicon - per-trigger name lists; missing catalogs match no named tokens.
|
|
29
29
|
* @returns matched ranges in draft order.
|
|
30
30
|
*/
|
|
31
31
|
export declare function scanTextRefs(draft: string, lexicon: ReadonlyMap<'/' | '@', readonly string[]>): TextRefRange[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/** Display inputs of the command chip. */
|
|
3
|
+
export interface CommandChipProps {
|
|
4
|
+
/** Claimed token without its argument separator, e.g. `/goal`. */
|
|
5
|
+
readonly token: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Render the claimed command chip.
|
|
9
|
+
* @param props - the token to display.
|
|
10
|
+
* @returns the chip body.
|
|
11
|
+
*/
|
|
12
|
+
export declare function CommandChip({ token }: CommandChipProps): ReactNode;
|
|
13
|
+
//# sourceMappingURL=CommandChip.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommandChipNode: the claimed slash command as one atomic Lexical decorator
|
|
3
|
+
* on the document's leading seat. The node carries the claim it was inserted
|
|
4
|
+
* for, so a history restore of the node restores the claim with it.
|
|
5
|
+
* `getTextContent()` answers the token without its argument separator; the
|
|
6
|
+
* separator is an ordinary text node after the chip. The detect projection
|
|
7
|
+
* counts the chip as one U+FFFC; see projection.ts.
|
|
8
|
+
*/
|
|
9
|
+
import type { JSX } from 'react';
|
|
10
|
+
import type { LexicalEditor, LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';
|
|
11
|
+
import { DecoratorNode } from 'lexical';
|
|
12
|
+
import type { CommandClaim } from '../../contract/input.ts';
|
|
13
|
+
/** JSON form of one command chip (Lexical node serialization contract). */
|
|
14
|
+
export type SerializedCommandChipNode = Spread<{
|
|
15
|
+
text: string;
|
|
16
|
+
}, SerializedLexicalNode>;
|
|
17
|
+
/** One claimed command as an atomic decorator node. */
|
|
18
|
+
export declare class CommandChipNode extends DecoratorNode<JSX.Element> {
|
|
19
|
+
/** The claim this chip anchors; its submit closure has no JSON form. */
|
|
20
|
+
__claim: CommandClaim;
|
|
21
|
+
/** Lexical node registry type tag. */
|
|
22
|
+
static getType(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Clone with identity (Lexical writable-copy contract).
|
|
25
|
+
* @param node - node to clone.
|
|
26
|
+
* @returns a copy carrying the same NodeKey and claim.
|
|
27
|
+
*/
|
|
28
|
+
static clone(node: CommandChipNode): CommandChipNode;
|
|
29
|
+
/**
|
|
30
|
+
* Rebuild one chip from its JSON form. JSON cannot carry the claim's
|
|
31
|
+
* submit closure, so an imported command is its literal token text.
|
|
32
|
+
* @param json - serialized chip.
|
|
33
|
+
* @returns a plain text node holding the token.
|
|
34
|
+
*/
|
|
35
|
+
static importJSON(json: SerializedCommandChipNode): LexicalNode;
|
|
36
|
+
/**
|
|
37
|
+
* @param claim - the command claim the chip anchors.
|
|
38
|
+
* @param key - Lexical clone-path key; absent for fresh nodes.
|
|
39
|
+
*/
|
|
40
|
+
constructor(claim: CommandClaim, key?: NodeKey);
|
|
41
|
+
/** Serialize to the JSON node form (the token text alone). */
|
|
42
|
+
exportJSON(): SerializedCommandChipNode;
|
|
43
|
+
/**
|
|
44
|
+
* Mount the chip's host element; the decorator portal renders into it.
|
|
45
|
+
* @returns an inline, non-editable span carrying the test/e2e anchor.
|
|
46
|
+
*/
|
|
47
|
+
createDOM(): HTMLElement;
|
|
48
|
+
/** Host element never changes shape. */
|
|
49
|
+
updateDOM(): boolean;
|
|
50
|
+
/** The chip sits in the text line. */
|
|
51
|
+
isInline(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Arrows step across the chip and the default character deletion removes
|
|
54
|
+
* it whole, for the reason documented on ReferenceChipNode.isKeyboardSelectable;
|
|
55
|
+
* registerCommandChipSelection inserts the selecting step before that deletion.
|
|
56
|
+
*/
|
|
57
|
+
isKeyboardSelectable(): boolean;
|
|
58
|
+
/** Clipboard / persistence projection: the token without its separator. */
|
|
59
|
+
getTextContent(): string;
|
|
60
|
+
/** The claim this chip anchors. */
|
|
61
|
+
getClaim(): CommandClaim;
|
|
62
|
+
/** React face rendered into the host element by the decorator portal. */
|
|
63
|
+
decorate(): JSX.Element;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Mint one chip node for a claim.
|
|
67
|
+
* @param claim - the command claim.
|
|
68
|
+
* @returns the fresh node.
|
|
69
|
+
*/
|
|
70
|
+
export declare function $createCommandChipNode(claim: CommandClaim): CommandChipNode;
|
|
71
|
+
/**
|
|
72
|
+
* Command chip type guard.
|
|
73
|
+
* @param node - any node or nullish.
|
|
74
|
+
* @returns whether the node is a CommandChipNode.
|
|
75
|
+
*/
|
|
76
|
+
export declare function $isCommandChipNode(node: LexicalNode | null | undefined): node is CommandChipNode;
|
|
77
|
+
/**
|
|
78
|
+
* Keep command chips on the leading seat. A chip anywhere but the first
|
|
79
|
+
* child of the first block (text, a line break, or a block inserted before
|
|
80
|
+
* it) becomes its literal token, which releases the claim. Inserting a
|
|
81
|
+
* sibling before the chip or moving it to another block marks the chip dirty;
|
|
82
|
+
* a block inserted before the chip's block marks only that block dirty.
|
|
83
|
+
* @param editor - the shell-owned editor.
|
|
84
|
+
* @returns the unregister disposer.
|
|
85
|
+
*/
|
|
86
|
+
export declare function registerCommandChipSeat(editor: LexicalEditor): () => void;
|
|
87
|
+
//# sourceMappingURL=command-chip-node.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two-step command chip deletion. A character deletion whose direction
|
|
3
|
+
* reaches the command chip from a collapsed caret first selects the chip; the
|
|
4
|
+
* next deletion in that direction removes it. Deletions arrive as the
|
|
5
|
+
* character-deletion command (Backspace, Delete, and the platform shortcuts
|
|
6
|
+
* the engine maps to them) or as a deletion input event, which some platforms
|
|
7
|
+
* apply without that command. A key that produces no character deletion, a
|
|
8
|
+
* click, blur, or a caret that no longer touches the chip clears the
|
|
9
|
+
* selection. The selected state is presentation on the chip's host and the
|
|
10
|
+
* root element; the editor selection stays a collapsed range beside the chip,
|
|
11
|
+
* so typing and arrows keep their plain-text behavior.
|
|
12
|
+
*/
|
|
13
|
+
import type { LexicalEditor } from 'lexical';
|
|
14
|
+
/**
|
|
15
|
+
* Register two-step deletion for the command chip.
|
|
16
|
+
* @param editor - the shell-owned editor.
|
|
17
|
+
* @returns the unregister disposer, which also clears a selected chip.
|
|
18
|
+
*/
|
|
19
|
+
export declare function registerCommandChipSelection(editor: LexicalEditor): () => void;
|
|
20
|
+
//# sourceMappingURL=command-chip-selection.d.ts.map
|
|
@@ -28,8 +28,12 @@ export interface ComposerKeymapHandlers {
|
|
|
28
28
|
canSubmit(): boolean;
|
|
29
29
|
/** The Enter gesture after every guard passed; `accelerated` = Ctrl/Cmd held. */
|
|
30
30
|
submit(accelerated: boolean): void;
|
|
31
|
-
/**
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Pasted files with directory metadata supplied by the clipboard entry API.
|
|
33
|
+
* @param files - browser files in clipboard order.
|
|
34
|
+
* @param directories - known directory members; absent when no entry identifies a directory.
|
|
35
|
+
*/
|
|
36
|
+
intakeFiles(files: readonly File[], directories?: ReadonlySet<File>): void;
|
|
33
37
|
/** Pasted plain text (sanitized insertion through the shell). */
|
|
34
38
|
pasteText(text: string): void;
|
|
35
39
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { LexicalNode, NodeKey, Point } from 'lexical';
|
|
11
11
|
import type { Occurrence } from '../../contract/draft-editor.ts';
|
|
12
|
+
import type { CommandClaim } from '../../contract/input.ts';
|
|
12
13
|
/** The detect-projection stand-in for one chip (object replacement character). */
|
|
13
14
|
export declare const ATOMIC_CHAR = "\uFFFC";
|
|
14
15
|
/** One leaf (or gap) of the composer document in projection coordinates. */
|
|
@@ -75,6 +76,8 @@ export interface EditorProjection {
|
|
|
75
76
|
} | null;
|
|
76
77
|
/** Collapsed caret in detect coordinates; null while the selection is absent or ranged. */
|
|
77
78
|
readonly caret: number | null;
|
|
79
|
+
/** Claim of the command chip opening the document; undefined without one. */
|
|
80
|
+
readonly command: CommandClaim | undefined;
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
80
83
|
* Fold one selection point to a detect offset.
|