@cellarnode/ui 0.201.1 → 0.203.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/dist/agent/composer.d.ts +6 -1
- package/dist/agent/composer.d.ts.map +1 -1
- package/dist/agent/composer.js +43 -9
- package/dist/agent/composer.js.map +1 -1
- package/dist/agent/conversation.d.ts +20 -2
- package/dist/agent/conversation.d.ts.map +1 -1
- package/dist/agent/conversation.js +39 -5
- package/dist/agent/conversation.js.map +1 -1
- package/dist/agent/copy.d.ts +7 -0
- package/dist/agent/copy.d.ts.map +1 -1
- package/dist/agent/copy.js +9 -0
- package/dist/agent/copy.js.map +1 -1
- package/dist/agent/fixtures.d.ts +34 -0
- package/dist/agent/fixtures.d.ts.map +1 -1
- package/dist/agent/fixtures.js +83 -0
- package/dist/agent/fixtures.js.map +1 -1
- package/dist/agent/index.d.ts +18 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +18 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/markdown.d.ts +64 -0
- package/dist/agent/markdown.d.ts.map +1 -0
- package/dist/agent/markdown.js +338 -0
- package/dist/agent/markdown.js.map +1 -0
- package/dist/agent/masked-value.d.ts +1 -0
- package/dist/agent/masked-value.d.ts.map +1 -1
- package/dist/agent/masked-value.js +4 -1
- package/dist/agent/masked-value.js.map +1 -1
- package/dist/agent/message.d.ts +26 -6
- package/dist/agent/message.d.ts.map +1 -1
- package/dist/agent/message.js +47 -11
- package/dist/agent/message.js.map +1 -1
- package/dist/agent/panel-frame.js +1 -1
- package/dist/agent/panel-frame.js.map +1 -1
- package/dist/agent/role-cards/card-kit.d.ts +111 -0
- package/dist/agent/role-cards/card-kit.d.ts.map +1 -0
- package/dist/agent/role-cards/card-kit.js +68 -0
- package/dist/agent/role-cards/card-kit.js.map +1 -0
- package/dist/agent/role-cards/data-table-card.d.ts +80 -0
- package/dist/agent/role-cards/data-table-card.d.ts.map +1 -0
- package/dist/agent/role-cards/data-table-card.js +214 -0
- package/dist/agent/role-cards/data-table-card.js.map +1 -0
- package/dist/agent/role-cards/fixtures.d.ts +124 -0
- package/dist/agent/role-cards/fixtures.d.ts.map +1 -0
- package/dist/agent/role-cards/fixtures.js +401 -0
- package/dist/agent/role-cards/fixtures.js.map +1 -0
- package/dist/agent/role-cards/host-contract.d.ts +214 -0
- package/dist/agent/role-cards/host-contract.d.ts.map +1 -0
- package/dist/agent/role-cards/host-contract.js +348 -0
- package/dist/agent/role-cards/host-contract.js.map +1 -0
- package/dist/agent/role-cards/inspector-drawer.d.ts +42 -0
- package/dist/agent/role-cards/inspector-drawer.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-drawer.js +68 -0
- package/dist/agent/role-cards/inspector-drawer.js.map +1 -0
- package/dist/agent/role-cards/inspector-fixtures.d.ts +84 -0
- package/dist/agent/role-cards/inspector-fixtures.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-fixtures.js +162 -0
- package/dist/agent/role-cards/inspector-fixtures.js.map +1 -0
- package/dist/agent/role-cards/inspector-record.d.ts +109 -0
- package/dist/agent/role-cards/inspector-record.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-record.js +346 -0
- package/dist/agent/role-cards/inspector-record.js.map +1 -0
- package/dist/agent/role-cards/inspector-view.d.ts +137 -0
- package/dist/agent/role-cards/inspector-view.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-view.js +261 -0
- package/dist/agent/role-cards/inspector-view.js.map +1 -0
- package/dist/agent/role-cards/match-card.d.ts +21 -0
- package/dist/agent/role-cards/match-card.d.ts.map +1 -0
- package/dist/agent/role-cards/match-card.js +30 -0
- package/dist/agent/role-cards/match-card.js.map +1 -0
- package/dist/agent/role-cards/offer-card.d.ts +27 -0
- package/dist/agent/role-cards/offer-card.d.ts.map +1 -0
- package/dist/agent/role-cards/offer-card.js +68 -0
- package/dist/agent/role-cards/offer-card.js.map +1 -0
- package/dist/agent/role-cards/opportunity-card.d.ts +26 -0
- package/dist/agent/role-cards/opportunity-card.d.ts.map +1 -0
- package/dist/agent/role-cards/opportunity-card.js +50 -0
- package/dist/agent/role-cards/opportunity-card.js.map +1 -0
- package/dist/agent/role-cards/product-card.d.ts +32 -0
- package/dist/agent/role-cards/product-card.d.ts.map +1 -0
- package/dist/agent/role-cards/product-card.js +50 -0
- package/dist/agent/role-cards/product-card.js.map +1 -0
- package/dist/agent/role-cards/proposal-diff.d.ts +38 -0
- package/dist/agent/role-cards/proposal-diff.d.ts.map +1 -0
- package/dist/agent/role-cards/proposal-diff.js +74 -0
- package/dist/agent/role-cards/proposal-diff.js.map +1 -0
- package/dist/agent/role-cards/registry.d.ts +43 -0
- package/dist/agent/role-cards/registry.d.ts.map +1 -0
- package/dist/agent/role-cards/registry.js +46 -0
- package/dist/agent/role-cards/registry.js.map +1 -0
- package/dist/agent/role-cards/score-meter.d.ts +12 -0
- package/dist/agent/role-cards/score-meter.d.ts.map +1 -0
- package/dist/agent/role-cards/score-meter.js +17 -0
- package/dist/agent/role-cards/score-meter.js.map +1 -0
- package/dist/agent/role-cards/surface-links.d.ts +54 -0
- package/dist/agent/role-cards/surface-links.d.ts.map +1 -0
- package/dist/agent/role-cards/surface-links.js +149 -0
- package/dist/agent/role-cards/surface-links.js.map +1 -0
- package/dist/agent/role-cards/text-safety.d.ts +27 -0
- package/dist/agent/role-cards/text-safety.d.ts.map +1 -0
- package/dist/agent/role-cards/text-safety.js +77 -0
- package/dist/agent/role-cards/text-safety.js.map +1 -0
- package/dist/agent/schema.d.ts +10 -0
- package/dist/agent/schema.d.ts.map +1 -1
- package/dist/agent/schema.js +31 -3
- package/dist/agent/schema.js.map +1 -1
- package/dist/agent/states.d.ts +1 -0
- package/dist/agent/states.d.ts.map +1 -1
- package/dist/agent/states.js +1 -1
- package/dist/agent/states.js.map +1 -1
- package/dist/agent/thinking.d.ts +13 -4
- package/dist/agent/thinking.d.ts.map +1 -1
- package/dist/agent/thinking.js +15 -6
- package/dist/agent/thinking.js.map +1 -1
- package/dist/agent/thread-list.d.ts +45 -2
- package/dist/agent/thread-list.d.ts.map +1 -1
- package/dist/agent/thread-list.js +175 -8
- package/dist/agent/thread-list.js.map +1 -1
- package/dist/agent/thread-title.d.ts +46 -0
- package/dist/agent/thread-title.d.ts.map +1 -0
- package/dist/agent/thread-title.js +99 -0
- package/dist/agent/thread-title.js.map +1 -0
- package/dist/agent/tool-activity-model.d.ts +136 -0
- package/dist/agent/tool-activity-model.d.ts.map +1 -0
- package/dist/agent/tool-activity-model.js +288 -0
- package/dist/agent/tool-activity-model.js.map +1 -0
- package/dist/agent/tool-activity.d.ts +61 -0
- package/dist/agent/tool-activity.d.ts.map +1 -0
- package/dist/agent/tool-activity.js +199 -0
- package/dist/agent/tool-activity.js.map +1 -0
- package/dist/agent/tool-call-card.d.ts +11 -1
- package/dist/agent/tool-call-card.d.ts.map +1 -1
- package/dist/agent/tool-call-card.js +19 -4
- package/dist/agent/tool-call-card.js.map +1 -1
- package/dist/agent/ui.js +1 -1
- package/dist/agent/ui.js.map +1 -1
- package/dist/agent/use-motion.d.ts +15 -0
- package/dist/agent/use-motion.d.ts.map +1 -0
- package/dist/agent/use-motion.js +52 -0
- package/dist/agent/use-motion.js.map +1 -0
- package/dist/chat/use-stick-to-bottom.d.ts +5 -0
- package/dist/chat/use-stick-to-bottom.d.ts.map +1 -1
- package/dist/chat/use-stick-to-bottom.js +11 -1
- package/dist/chat/use-stick-to-bottom.js.map +1 -1
- package/dist/components/sheet.d.ts +3 -1
- package/dist/components/sheet.d.ts.map +1 -1
- package/dist/components/sheet.js +2 -2
- package/dist/components/sheet.js.map +1 -1
- package/dist/portfolio-import/import-job-panels.d.ts +6 -0
- package/dist/portfolio-import/import-job-panels.d.ts.map +1 -1
- package/dist/portfolio-import/import-job-panels.js +11 -4
- package/dist/portfolio-import/import-job-panels.js.map +1 -1
- package/dist/portfolio-import/job-error-copy.d.ts +62 -0
- package/dist/portfolio-import/job-error-copy.d.ts.map +1 -0
- package/dist/portfolio-import/job-error-copy.js +78 -0
- package/dist/portfolio-import/job-error-copy.js.map +1 -0
- package/dist/realtime/organisation-events/schemas.d.ts +2 -2
- package/package.json +4 -1
- package/src/theme/tokens.css +66 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentThread } from "./schema.js";
|
|
2
|
+
import { THREAD_TITLE_MAX } from "./thread-title.js";
|
|
2
3
|
export interface AgentThreadListCopy {
|
|
3
4
|
search: string;
|
|
4
5
|
noResults: string;
|
|
@@ -9,17 +10,59 @@ export interface AgentThreadListCopy {
|
|
|
9
10
|
cancel: string;
|
|
10
11
|
retention: string;
|
|
11
12
|
list: string;
|
|
13
|
+
/** Name of a conversation that has no title and no first message to take one from. */
|
|
14
|
+
newConversation: string;
|
|
15
|
+
/** Placeholder while the service chooses a title for a conversation that has none yet. */
|
|
16
|
+
naming: string;
|
|
17
|
+
/** Rename button; `{title}` is the conversation's name. */
|
|
18
|
+
rename: string;
|
|
19
|
+
/** Accessible name of the title field while renaming. */
|
|
20
|
+
renameInput: string;
|
|
21
|
+
renameHint: string;
|
|
22
|
+
renameSaving: string;
|
|
23
|
+
/** Announced after a rename was saved. */
|
|
24
|
+
renamed: string;
|
|
25
|
+
/** The host's save failed. */
|
|
26
|
+
renameError: string;
|
|
27
|
+
titleRequired: string;
|
|
28
|
+
/** `{max}` is the longest title allowed. */
|
|
29
|
+
titleTooLong: string;
|
|
12
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* What `onRename` rejects with when the service refused the title and said why ("Use 80 characters or fewer."): the list
|
|
33
|
+
* shows that reason, in the service's own words, instead of the generic `renameError`. Any other rejection (a network error,
|
|
34
|
+
* a 500) shows the generic copy, so an internal message never reaches the screen. Matched by `name`, so a copy of this class
|
|
35
|
+
* from a second bundle of the package still counts.
|
|
36
|
+
*/
|
|
37
|
+
export declare class AgentThreadRenameError extends Error {
|
|
38
|
+
constructor(reason: string);
|
|
39
|
+
}
|
|
40
|
+
/** The longest title a person can give a conversation, in code points (see `thread-title.ts`); the service counts the same way. */
|
|
41
|
+
export { THREAD_TITLE_MAX };
|
|
42
|
+
/**
|
|
43
|
+
* A title taken from the first thing the user asked: whitespace collapsed, cut at a word boundary near `max`
|
|
44
|
+
* characters with an ellipsis. `undefined` for nothing to take a title from.
|
|
45
|
+
*/
|
|
46
|
+
export declare function deriveThreadTitle(firstMessage: string | undefined, max?: number): string | undefined;
|
|
47
|
+
/** What the list calls a conversation: its title, else the first words of its first message, else `fallback`. */
|
|
48
|
+
export declare function threadDisplayTitle(thread: AgentThread, fallback: string): string;
|
|
13
49
|
export interface AgentThreadListProps {
|
|
14
50
|
threads: readonly AgentThread[];
|
|
15
51
|
activeId?: string;
|
|
16
52
|
onSelect: (id: string) => void;
|
|
17
53
|
onDelete: (id: string) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Saves a new title (the one the service will store: cleaned of control, format and blank characters and of extra whitespace,
|
|
56
|
+
* 1 to {@link THREAD_TITLE_MAX} code points, with a letter, number, symbol or punctuation in it). Without it a row has no rename
|
|
57
|
+
* button. A rejected promise shows the rename error and keeps the field open with what was typed; reject with an
|
|
58
|
+
* {@link AgentThreadRenameError} to show the service's reason instead of the generic one.
|
|
59
|
+
*/
|
|
60
|
+
onRename?: (id: string, title: string) => Promise<void>;
|
|
18
61
|
retentionDays?: number;
|
|
19
62
|
formatTime?: (iso: string) => string;
|
|
20
63
|
copy?: Partial<AgentThreadListCopy>;
|
|
21
64
|
className?: string;
|
|
22
65
|
}
|
|
23
|
-
/** @internal Thread list with search, select and confirm-first delete. */
|
|
24
|
-
export declare function AgentThreadList({ threads, activeId, onSelect, onDelete, retentionDays, formatTime, copy, className, }: AgentThreadListProps): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
/** @internal Thread list with search, select, rename and confirm-first delete. */
|
|
67
|
+
export declare function AgentThreadList({ threads, activeId, onSelect, onDelete, onRename, retentionDays, formatTime, copy, className, }: AgentThreadListProps): import("react/jsx-runtime").JSX.Element;
|
|
25
68
|
//# sourceMappingURL=thread-list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list.d.ts","sourceRoot":"","sources":["../../src/agent/thread-list.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"thread-list.d.ts","sourceRoot":"","sources":["../../src/agent/thread-list.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAIL,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,eAAe,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAgCD;;;;;GAKG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,MAAM,EAAE,MAAM;CAI3B;AAWD,mIAAmI;AACnI,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAG5B;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,GAAG,GAAE,MAA0B,GAC9B,MAAM,GAAG,SAAS,CAQpB;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8JD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,aAAkB,EAClB,UAAqB,EACrB,IAAI,EACJ,SAAS,GACV,EAAE,oBAAoB,2CAsItB"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useState } from "react";
|
|
3
|
-
import { Trash2 } from "lucide-react";
|
|
2
|
+
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { LoaderCircle, Pencil, Trash2 } from "lucide-react";
|
|
4
4
|
import { ConfirmationDialog } from "../components/confirmation-dialog.js";
|
|
5
|
+
import { LiveRegion, useAnnounce } from "../components/live-region/index.js";
|
|
5
6
|
import { cn } from "../lib/utils.js";
|
|
6
7
|
import { fmt, useCopy } from "./copy.js";
|
|
8
|
+
import { cleanInline } from "./role-cards/text-safety.js";
|
|
7
9
|
import { AgentEmptyState } from "./states.js";
|
|
10
|
+
import { cleanTitleText, isBlankTitle, normalizeThreadTitle, THREAD_TITLE_MAX, } from "./thread-title.js";
|
|
8
11
|
import { focusRing } from "./ui.js";
|
|
12
|
+
import { useChanged } from "./use-motion.js";
|
|
9
13
|
const DEFAULT_COPY = {
|
|
10
14
|
search: "Search conversations",
|
|
11
15
|
noResults: "No conversations match.",
|
|
@@ -16,24 +20,187 @@ const DEFAULT_COPY = {
|
|
|
16
20
|
cancel: "Cancel",
|
|
17
21
|
retention: "Conversations are kept for {days} days.",
|
|
18
22
|
list: "Conversations",
|
|
23
|
+
newConversation: "New conversation",
|
|
24
|
+
naming: "Naming…",
|
|
25
|
+
rename: "Rename conversation: {title}",
|
|
26
|
+
renameInput: "Conversation title",
|
|
27
|
+
renameHint: "Enter to save, Escape to cancel",
|
|
28
|
+
renameSaving: "Saving",
|
|
29
|
+
renamed: "Conversation renamed",
|
|
30
|
+
renameError: "Could not rename the conversation. Try again.",
|
|
31
|
+
titleRequired: "Enter a title.",
|
|
32
|
+
titleTooLong: "Use {max} characters or fewer.",
|
|
19
33
|
};
|
|
20
|
-
/**
|
|
21
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The title a thread carries, trimmed; "" when it has none. A title that draws nothing is no title: one with no letter, number,
|
|
36
|
+
* symbol or punctuation once cleaned (`thread-title.ts`: whitespace, control and format characters, the Hangul fillers, the Braille
|
|
37
|
+
* blank, combining marks, private-use and unassigned code points alone). That is a test only: the title shown is the one the
|
|
38
|
+
* service stored.
|
|
39
|
+
*/
|
|
40
|
+
const titleOf = (thread) => isBlankTitle(thread.title) ? "" : thread.title.trim();
|
|
41
|
+
/**
|
|
42
|
+
* What `onRename` rejects with when the service refused the title and said why ("Use 80 characters or fewer."): the list
|
|
43
|
+
* shows that reason, in the service's own words, instead of the generic `renameError`. Any other rejection (a network error,
|
|
44
|
+
* a 500) shows the generic copy, so an internal message never reaches the screen. Matched by `name`, so a copy of this class
|
|
45
|
+
* from a second bundle of the package still counts.
|
|
46
|
+
*/
|
|
47
|
+
export class AgentThreadRenameError extends Error {
|
|
48
|
+
constructor(reason) {
|
|
49
|
+
super(reason);
|
|
50
|
+
this.name = "AgentThreadRenameError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Longest reason shown, in code points. */
|
|
54
|
+
const RENAME_REASON_MAX = 200;
|
|
55
|
+
/** The reason a refused rename carries, cleaned of control and bidi characters, or `undefined` for any other failure. */
|
|
56
|
+
const renameReason = (e) => e instanceof Error && e.name === "AgentThreadRenameError"
|
|
57
|
+
? cleanInline(e.message, RENAME_REASON_MAX, true)
|
|
58
|
+
: undefined;
|
|
59
|
+
/** The longest title a person can give a conversation, in code points (see `thread-title.ts`); the service counts the same way. */
|
|
60
|
+
export { THREAD_TITLE_MAX };
|
|
61
|
+
const DERIVED_TITLE_MAX = 48;
|
|
62
|
+
/**
|
|
63
|
+
* A title taken from the first thing the user asked: whitespace collapsed, cut at a word boundary near `max`
|
|
64
|
+
* characters with an ellipsis. `undefined` for nothing to take a title from.
|
|
65
|
+
*/
|
|
66
|
+
export function deriveThreadTitle(firstMessage, max = DERIVED_TITLE_MAX) {
|
|
67
|
+
const text = (firstMessage ?? "").replace(/\s+/g, " ").trim();
|
|
68
|
+
if (isBlankTitle(text))
|
|
69
|
+
return undefined;
|
|
70
|
+
const chars = [...text];
|
|
71
|
+
if (chars.length <= max)
|
|
72
|
+
return chars.join("");
|
|
73
|
+
const head = chars.slice(0, max - 1);
|
|
74
|
+
const at = head.lastIndexOf(" ");
|
|
75
|
+
return `${(at > max / 2 ? head.slice(0, at) : head).join("").trimEnd()}…`;
|
|
76
|
+
}
|
|
77
|
+
/** What the list calls a conversation: its title, else the first words of its first message, else `fallback`. */
|
|
78
|
+
export function threadDisplayTitle(thread, fallback) {
|
|
79
|
+
return titleOf(thread) || deriveThreadTitle(thread.firstMessage) || fallback;
|
|
80
|
+
}
|
|
81
|
+
function RenameField({ initial, c, onSave, onClose, }) {
|
|
82
|
+
const [value, setValue] = useState(initial);
|
|
83
|
+
const [status, setStatus] = useState("idle");
|
|
84
|
+
const [problem, setProblem] = useState(null);
|
|
85
|
+
const inputRef = useRef(null);
|
|
86
|
+
const finishedRef = useRef(false);
|
|
87
|
+
const hintId = useId();
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
inputRef.current?.focus();
|
|
90
|
+
inputRef.current?.select();
|
|
91
|
+
}, []);
|
|
92
|
+
const finish = (via, saved) => {
|
|
93
|
+
finishedRef.current = true;
|
|
94
|
+
onClose(via, saved);
|
|
95
|
+
};
|
|
96
|
+
const submit = async (via) => {
|
|
97
|
+
if (finishedRef.current || status === "saving")
|
|
98
|
+
return;
|
|
99
|
+
// The title the service will store (cleaned, then counted): what is checked here is what it checks, what is sent is what it keeps.
|
|
100
|
+
const normalized = normalizeThreadTitle(value);
|
|
101
|
+
if (!normalized.ok) {
|
|
102
|
+
// Enter says what is wrong and waits; clicking away from a field that cannot be saved just puts the old name back.
|
|
103
|
+
if (via === "blur")
|
|
104
|
+
finish("blur", false);
|
|
105
|
+
else
|
|
106
|
+
setProblem(normalized.reason === "empty"
|
|
107
|
+
? c.titleRequired
|
|
108
|
+
: fmt(c.titleTooLong, { max: THREAD_TITLE_MAX }));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const title = normalized.title;
|
|
112
|
+
if (title === cleanTitleText(initial)) {
|
|
113
|
+
finish(via, false);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
setStatus("saving");
|
|
117
|
+
setProblem(null);
|
|
118
|
+
try {
|
|
119
|
+
await onSave(title);
|
|
120
|
+
finish(via, true);
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
setStatus("error");
|
|
124
|
+
setProblem(renameReason(e) ?? c.renameError);
|
|
125
|
+
if (via === "keyboard")
|
|
126
|
+
inputRef.current?.focus();
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const onKeyDown = (e) => {
|
|
130
|
+
if (e.key === "Enter") {
|
|
131
|
+
// Enter that picks an IME candidate is not a save.
|
|
132
|
+
if (e.nativeEvent.isComposing)
|
|
133
|
+
return;
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
void submit("keyboard");
|
|
136
|
+
}
|
|
137
|
+
else if (e.key === "Escape") {
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
e.stopPropagation();
|
|
140
|
+
if (status !== "saving")
|
|
141
|
+
finish("keyboard", false);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const saving = status === "saving";
|
|
145
|
+
return (_jsxs("div", { className: "flex flex-col gap-1 rounded-xl bg-muted px-2 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { ref: inputRef, type: "text", "aria-label": c.renameInput, "aria-invalid": problem ? true : undefined, "aria-describedby": problem ? `${hintId}-problem` : hintId, "aria-busy": saving || undefined, autoComplete: "off", spellCheck: false, readOnly: saving, value: value, onChange: (e) => {
|
|
146
|
+
setValue(e.target.value);
|
|
147
|
+
if (status === "error" || problem) {
|
|
148
|
+
setStatus("idle");
|
|
149
|
+
setProblem(null);
|
|
150
|
+
}
|
|
151
|
+
}, onKeyDown: onKeyDown, onBlur: () => void submit("blur"), className: cn("min-w-0 flex-1 rounded-lg border bg-background px-2.5 py-1 text-sm/5 text-foreground pointer-coarse:min-h-11", problem ? "border-[var(--tone-danger-fg)]" : "border-input", saving && "text-muted-foreground", focusRing) }), saving && (_jsxs("span", { className: "inline-flex shrink-0 items-center text-muted-foreground", children: [_jsx(LoaderCircle, { "aria-hidden": true, className: "size-4 animate-spin motion-reduce:animate-none" }), _jsx("span", { className: "sr-only", children: c.renameSaving })] }))] }), problem ? (_jsx("p", { id: `${hintId}-problem`, role: "alert", className: "text-xs/4 break-words text-[var(--tone-danger-fg)]", children: problem }, "problem")) : (_jsx("p", { id: hintId, className: "text-xs/4 text-muted-foreground", children: c.renameHint }, "hint"))] }));
|
|
152
|
+
}
|
|
153
|
+
function ThreadTitle({ thread, c }) {
|
|
154
|
+
const naming = Boolean(thread.titlePending) && titleOf(thread) === "";
|
|
155
|
+
const display = threadDisplayTitle(thread, c.newConversation);
|
|
156
|
+
const fallback = !naming && titleOf(thread) === "" && display === c.newConversation;
|
|
157
|
+
const shown = naming ? "\u0000naming" : display;
|
|
158
|
+
// A title that arrives or changes fades in. The first one shown does not animate.
|
|
159
|
+
const swapped = useChanged(shown);
|
|
160
|
+
return (_jsx("span", { "data-naming": naming ? "true" : undefined, className: cn("block truncate text-sm/5 font-medium text-foreground", (naming || fallback) && "text-muted-foreground", naming && "agent-pulse", swapped && "agent-swap-in"), children: naming ? c.naming : display }, shown));
|
|
161
|
+
}
|
|
162
|
+
/** @internal Thread list with search, select, rename and confirm-first delete. */
|
|
163
|
+
export function AgentThreadList({ threads, activeId, onSelect, onDelete, onRename, retentionDays = 30, formatTime = (s) => s, copy, className, }) {
|
|
22
164
|
const c = useCopy(DEFAULT_COPY, copy);
|
|
23
165
|
const [q, setQ] = useState("");
|
|
24
166
|
const [pendingDelete, setPendingDelete] = useState(null);
|
|
167
|
+
const [renamingId, setRenamingId] = useState(null);
|
|
168
|
+
const { message, seq, announce } = useAnnounce();
|
|
169
|
+
const selectButtonsRef = useRef(new Map());
|
|
25
170
|
const shown = useMemo(() => {
|
|
26
171
|
const needle = q.trim().toLowerCase();
|
|
27
172
|
return needle
|
|
28
|
-
? threads.filter((t) => `${t.
|
|
173
|
+
? threads.filter((t) => `${threadDisplayTitle(t, c.newConversation)} ${t.preview ?? ""}`
|
|
174
|
+
.toLowerCase()
|
|
175
|
+
.includes(needle))
|
|
29
176
|
: threads;
|
|
30
|
-
}, [threads, q]);
|
|
177
|
+
}, [threads, q, c.newConversation]);
|
|
31
178
|
if (threads.length === 0)
|
|
32
179
|
return _jsx(AgentEmptyState, { variant: "no-threads" });
|
|
33
|
-
return (_jsxs("div", { className: cn("flex flex-col gap-3", className), children: [_jsx("input", { type: "search", "aria-label": c.search, placeholder: c.search, value: q, onChange: (e) => setQ(e.target.value), className: cn("w-full rounded-lg border border-input bg-background px-3 py-1.5 text-sm/5", focusRing) }), shown.length === 0 ? (_jsx("p", { className: "py-6 text-center text-sm/5 text-muted-foreground", children: c.noResults })) : (_jsx("ul", { "aria-label": c.list, className: "flex flex-col gap-1", children: shown.map((t) =>
|
|
180
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-3 px-4 pt-4 pb-3", className), children: [_jsx(LiveRegion, { message: message, seq: seq }), _jsx("input", { type: "search", "aria-label": c.search, placeholder: c.search, value: q, onChange: (e) => setQ(e.target.value), className: cn("w-full rounded-lg border border-input bg-background px-3 py-1.5 text-sm/5", focusRing) }), shown.length === 0 ? (_jsx("p", { className: "py-6 text-center text-sm/5 text-muted-foreground", children: c.noResults })) : (_jsx("ul", { "aria-label": c.list, className: "-mx-2 flex flex-col gap-1", children: shown.map((t) => {
|
|
181
|
+
const name = threadDisplayTitle(t, c.newConversation);
|
|
182
|
+
if (renamingId === t.id && onRename) {
|
|
183
|
+
return (_jsx("li", { children: _jsx(RenameField, { initial: titleOf(t) || name, c: c, onSave: (title) => onRename(t.id, title), onClose: (via, saved) => {
|
|
184
|
+
setRenamingId(null);
|
|
185
|
+
if (saved)
|
|
186
|
+
announce(c.renamed);
|
|
187
|
+
// Back to the row after Enter or Escape; not after a click elsewhere, which already moved focus.
|
|
188
|
+
if (via === "keyboard")
|
|
189
|
+
window.setTimeout(() => selectButtonsRef.current.get(t.id)?.focus(), 0);
|
|
190
|
+
} }) }, t.id));
|
|
191
|
+
}
|
|
192
|
+
return (_jsxs("li", { "aria-busy": t.titlePending && titleOf(t) === "" ? true : undefined, className: "group flex items-center gap-1 rounded-xl hover:bg-muted", children: [_jsxs("button", { type: "button", ref: (el) => {
|
|
193
|
+
if (el)
|
|
194
|
+
selectButtonsRef.current.set(t.id, el);
|
|
195
|
+
else
|
|
196
|
+
selectButtonsRef.current.delete(t.id);
|
|
197
|
+
}, "aria-current": t.id === activeId ? "true" : undefined, onClick: () => onSelect(t.id), className: cn("min-w-0 flex-1 rounded-xl px-2 py-2 text-left", focusRing, t.id === activeId && "bg-muted"), children: [_jsx(ThreadTitle, { thread: t, c: c }), _jsxs("span", { className: "block truncate text-xs/4 text-muted-foreground", children: [formatTime(t.updatedAt), t.preview ? ` · ${t.preview}` : ""] })] }), onRename && (_jsx("button", { type: "button", "aria-label": fmt(c.rename, { title: name }), onClick: () => setRenamingId(t.id), className: cn("inline-flex size-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground pointer-coarse:size-11 transition-opacity duration-[var(--duration-micro)] hover:text-foreground motion-reduce:transition-none", "pointer-fine:opacity-0 pointer-fine:group-hover:opacity-100 pointer-fine:group-focus-within:opacity-100", focusRing), children: _jsx(Pencil, { "aria-hidden": true, className: "size-4" }) })), _jsx("button", { type: "button", "aria-label": fmt(c.delete, { title: name }), onClick: () => setPendingDelete(t), className: cn("mr-1 inline-flex size-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground pointer-coarse:size-11 hover:text-[var(--tone-danger-fg)]", focusRing), children: _jsx(Trash2, { "aria-hidden": true, className: "size-4" }) })] }, t.id));
|
|
198
|
+
}) })), _jsx("p", { className: "text-xs/4 text-muted-foreground", children: fmt(c.retention, { days: retentionDays }) }), _jsx(ConfirmationDialog, { open: pendingDelete !== null, onClose: () => setPendingDelete(null), onConfirm: () => {
|
|
34
199
|
if (pendingDelete)
|
|
35
200
|
onDelete(pendingDelete.id);
|
|
36
201
|
setPendingDelete(null);
|
|
37
|
-
}, title: c.deleteTitle, description: pendingDelete
|
|
202
|
+
}, title: c.deleteTitle, description: pendingDelete
|
|
203
|
+
? `${threadDisplayTitle(pendingDelete, c.newConversation)}. ${c.deleteBody}`
|
|
204
|
+
: c.deleteBody, confirmLabel: c.deleteConfirm, cancelLabel: c.cancel, tone: "danger" })] }));
|
|
38
205
|
}
|
|
39
206
|
//# sourceMappingURL=thread-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list.js","sourceRoot":"","sources":["../../src/agent/thread-list.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"thread-list.js","sourceRoot":"","sources":["../../src/agent/thread-list.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAsB,MAAM,OAAO,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA8B1C,MAAM,YAAY,GAAwB;IACxC,MAAM,EAAE,sBAAsB;IAC9B,SAAS,EAAE,yBAAyB;IACpC,MAAM,EAAE,8BAA8B;IACtC,WAAW,EAAE,2BAA2B;IACxC,UAAU,EAAE,gDAAgD;IAC5D,aAAa,EAAE,QAAQ;IACvB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,yCAAyC;IACpD,IAAI,EAAE,eAAe;IACrB,eAAe,EAAE,kBAAkB;IACnC,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,8BAA8B;IACtC,WAAW,EAAE,oBAAoB;IACjC,UAAU,EAAE,iCAAiC;IAC7C,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,sBAAsB;IAC/B,WAAW,EAAE,+CAA+C;IAC5D,aAAa,EAAE,gBAAgB;IAC/B,YAAY,EAAE,gCAAgC;CAC/C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,OAAO,GAAG,CAAC,MAAmB,EAAU,EAAE,CAC9C,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAExD;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,MAAc;QACxB,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,4CAA4C;AAC5C,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,yHAAyH;AACzH,MAAM,YAAY,GAAG,CAAC,CAAU,EAAsB,EAAE,CACtD,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,wBAAwB;IACvD,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,CAAC;IACjD,CAAC,CAAC,SAAS,CAAC;AAEhB,mIAAmI;AACnI,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAAgC,EAChC,MAAc,iBAAiB;IAE/B,MAAM,IAAI,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,IAAI,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACxB,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AAC5E,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,kBAAkB,CAAC,MAAmB,EAAE,QAAgB;IACtE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,CAAC;AAC/E,CAAC;AAsBD,SAAS,WAAW,CAAC,EACnB,OAAO,EACP,CAAC,EACD,MAAM,EACN,OAAO,GAOR;IACC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,MAAM,CAAC,CAAC;IACrD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,CAAC,GAAwB,EAAE,KAAc,EAAE,EAAE;QAC1D,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,EAAE,GAAwB,EAAE,EAAE;QAChD,IAAI,WAAW,CAAC,OAAO,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO;QACvD,mIAAmI;QACnI,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACnB,mHAAmH;YACnH,IAAI,GAAG,KAAK,MAAM;gBAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;;gBAExC,UAAU,CACR,UAAU,CAAC,MAAM,KAAK,OAAO;oBAC3B,CAAC,CAAC,CAAC,CAAC,aAAa;oBACjB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CACnD,CAAC;YACJ,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC/B,IAAI,KAAK,KAAK,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC;YAC7C,IAAI,GAAG,KAAK,UAAU;gBAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,CAAkC,EAAE,EAAE;QACvD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,mDAAmD;YACnD,IAAI,CAAC,CAAC,WAAW,CAAC,WAAW;gBAAE,OAAO;YACtC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC9B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,IAAI,MAAM,KAAK,QAAQ;gBAAE,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,KAAK,QAAQ,CAAC;IACnC,OAAO,CACL,eAAK,SAAS,EAAC,mDAAmD,aAChE,eAAK,SAAS,EAAC,yBAAyB,aACtC,gBACE,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,MAAM,gBACC,CAAC,CAAC,WAAW,kBACX,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,sBACtB,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,UAAU,CAAC,CAAC,CAAC,MAAM,eAC7C,MAAM,IAAI,SAAS,EAC9B,YAAY,EAAC,KAAK,EAClB,UAAU,EAAE,KAAK,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;4BACd,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BACzB,IAAI,MAAM,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC;gCAClC,SAAS,CAAC,MAAM,CAAC,CAAC;gCAClB,UAAU,CAAC,IAAI,CAAC,CAAC;4BACnB,CAAC;wBACH,CAAC,EACD,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,EACjC,SAAS,EAAE,EAAE,CACX,8GAA8G,EAC9G,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,cAAc,EAC3D,MAAM,IAAI,uBAAuB,EACjC,SAAS,CACV,GACD,EACD,MAAM,IAAI,CACT,gBAAM,SAAS,EAAC,yDAAyD,aACvE,KAAC,YAAY,yBAAa,SAAS,EAAC,gDAAgD,GAAG,EACvF,eAAM,SAAS,EAAC,SAAS,YAAE,CAAC,CAAC,YAAY,GAAQ,IAC5C,CACR,IACG,EAEL,OAAO,CAAC,CAAC,CAAC,CACT,YAEE,EAAE,EAAE,GAAG,MAAM,UAAU,EACvB,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,oDAAoD,YAE7D,OAAO,IALJ,SAAS,CAMX,CACL,CAAC,CAAC,CAAC,CACF,YAAc,EAAE,EAAE,MAAM,EAAE,SAAS,EAAC,iCAAiC,YAClE,CAAC,CAAC,UAAU,IADR,MAAM,CAET,CACL,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAmD;IACjF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,OAAO,KAAK,CAAC,CAAC,eAAe,CAAC;IACpF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,kFAAkF;IAClF,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,CACL,8BAEe,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACxC,SAAS,EAAE,EAAE,CACX,sDAAsD,EACtD,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,uBAAuB,EAC/C,MAAM,IAAI,aAAa,EACvB,OAAO,IAAI,eAAe,CAC3B,YAEA,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IATvB,KAAK,CAUL,CACR,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,EAC9B,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,aAAa,GAAG,EAAE,EAClB,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EACrB,IAAI,EACJ,SAAS,GACY;IACrB,MAAM,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAClE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,WAAW,EAAE,CAAC;IACjD,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,GAAG,EAA6B,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtC,OAAO,MAAM;YACX,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnB,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE;iBAC7D,WAAW,EAAE;iBACb,QAAQ,CAAC,MAAM,CAAC,CACpB;YACH,CAAC,CAAC,OAAO,CAAC;IACd,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;IAEpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAC,eAAe,IAAC,OAAO,EAAC,YAAY,GAAG,CAAC;IAE1E,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,oCAAoC,EAAE,SAAS,CAAC,aACjE,KAAC,UAAU,IAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAI,EAC1C,gBACE,IAAI,EAAC,QAAQ,gBACD,CAAC,CAAC,MAAM,EACpB,WAAW,EAAE,CAAC,CAAC,MAAM,EACrB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACrC,SAAS,EAAE,EAAE,CACX,2EAA2E,EAC3E,SAAS,CACV,GACD,EACD,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACpB,YAAG,SAAS,EAAC,kDAAkD,YAAE,CAAC,CAAC,SAAS,GAAK,CAClF,CAAC,CAAC,CAAC,CACF,2BAAgB,CAAC,CAAC,IAAI,EAAE,SAAS,EAAC,2BAA2B,YAC1D,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACf,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;oBACtD,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;wBACpC,OAAO,CACL,uBACE,KAAC,WAAW,IACV,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,EAC3B,CAAC,EAAE,CAAC,EACJ,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EACxC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;oCACtB,aAAa,CAAC,IAAI,CAAC,CAAC;oCACpB,IAAI,KAAK;wCAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;oCAC/B,iGAAiG;oCACjG,IAAI,GAAG,KAAK,UAAU;wCACpB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;gCAC5E,CAAC,GACD,IAZK,CAAC,CAAC,EAAE,CAaR,CACN,CAAC;oBACJ,CAAC;oBACD,OAAO,CACL,2BAEa,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EACjE,SAAS,EAAC,yDAAyD,aAEnE,kBACE,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;oCACV,IAAI,EAAE;wCAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;;wCAC1C,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gCAC7C,CAAC,kBACa,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACpD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAC7B,SAAS,EAAE,EAAE,CACX,+CAA+C,EAC/C,SAAS,EACT,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,UAAU,CAChC,aAED,KAAC,WAAW,IAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAI,EAChC,gBAAM,SAAS,EAAC,gDAAgD,aAC7D,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,EACvB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAC9B,IACA,EACR,QAAQ,IAAI,CACX,iBACE,IAAI,EAAC,QAAQ,gBACD,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,yNAAyN,EACzN,yGAAyG,EACzG,SAAS,CACV,YAED,KAAC,MAAM,yBAAa,SAAS,EAAC,QAAQ,GAAG,GAClC,CACV,EACD,iBACE,IAAI,EAAC,QAAQ,gBACD,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAC1C,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,yJAAyJ,EACzJ,SAAS,CACV,YAED,KAAC,MAAM,yBAAa,SAAS,EAAC,QAAQ,GAAG,GAClC,KAhDJ,CAAC,CAAC,EAAE,CAiDN,CACN,CAAC;gBACJ,CAAC,CAAC,GACC,CACN,EACD,YAAG,SAAS,EAAC,iCAAiC,YAAE,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,GAAK,EAC9F,KAAC,kBAAkB,IACjB,IAAI,EAAE,aAAa,KAAK,IAAI,EAC5B,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACrC,SAAS,EAAE,GAAG,EAAE;oBACd,IAAI,aAAa;wBAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;oBAC9C,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC,EACD,KAAK,EAAE,CAAC,CAAC,WAAW,EACpB,WAAW,EACT,aAAa;oBACX,CAAC,CAAC,GAAG,kBAAkB,CAAC,aAAa,EAAE,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE;oBAC5E,CAAC,CAAC,CAAC,CAAC,UAAU,EAElB,YAAY,EAAE,CAAC,CAAC,aAAa,EAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EACrB,IAAI,EAAC,QAAQ,GACb,IACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal CEL-2530 - the conversation title rules, the SAME ones the service applies when a title is saved, so the rename field
|
|
3
|
+
* refuses exactly what the service would (a 422 is then only version skew) and sends what it will store.
|
|
4
|
+
*
|
|
5
|
+
* MIRRORS the backend BFF (cellarnode-backend-v2 `features/agent-threads/rename-thread.ts`, `normalizeThreadTitle`) and the agents
|
|
6
|
+
* service (cellarnode-mcp `agents/src/thread-title.ts`, `parseUserTitle`). All three run the same vectors
|
|
7
|
+
* (`title-vectors.test.fixture.ts` here, `title-vectors.ts` in the others; byte-identical copies): change the rules in all three.
|
|
8
|
+
* Written as code points and property classes, never as literal characters, so this source carries no invisible text.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The longest title a person can give a conversation, in code points: an emoji is one whatever its UTF-16 length, so 80 emoji
|
|
12
|
+
* fit and 81 do not. Counted AFTER cleaning (see {@link cleanTitleText}), as the service does.
|
|
13
|
+
*/
|
|
14
|
+
export declare const THREAD_TITLE_MAX = 80;
|
|
15
|
+
/**
|
|
16
|
+
* Collapses every whitespace run (newlines, tabs, line and paragraph separators and the Braille blank included) to one space, strips
|
|
17
|
+
* unsafe and blank-looking characters (a stripped character is simply gone: it does not make a space), and trims. The byte order
|
|
18
|
+
* mark is a format character that JavaScript also calls whitespace; it is stripped, not turned into a space.
|
|
19
|
+
*/
|
|
20
|
+
export declare function cleanTitleText(raw: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Every run of whitespace and blank or invisible code points (the Braille blank, the Hangul fillers, no-break and other spaces, zero-width
|
|
23
|
+
* and other format characters, the soft hyphen...; the joiners ZWJ and ZWNJ excepted) becomes ONE space. For text that is drawn rather than stored (a link's words): 700 blank glyphs would otherwise push
|
|
24
|
+
* whatever follows them hundreds of pixels away.
|
|
25
|
+
*/
|
|
26
|
+
export declare function collapseBlankRuns(raw: string): string;
|
|
27
|
+
export type NormalizedTitle = {
|
|
28
|
+
ok: true;
|
|
29
|
+
title: string;
|
|
30
|
+
} | {
|
|
31
|
+
ok: false;
|
|
32
|
+
reason: "empty";
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: "too_long";
|
|
36
|
+
length: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The title as it is stored: cleaned as above, with at least one visible character (a letter, number, symbol or punctuation: a
|
|
40
|
+
* title of combining marks, private-use or unassigned code points alone has none), and 1 to {@link THREAD_TITLE_MAX} code points
|
|
41
|
+
* counted after cleaning. Never silently shortened. `length` on a refusal is the CLEANED length.
|
|
42
|
+
*/
|
|
43
|
+
export declare function normalizeThreadTitle(raw: string): NormalizedTitle;
|
|
44
|
+
/** Whether `text` shows nothing as a title (see {@link normalizeThreadTitle}): no letter, number, symbol or punctuation once cleaned. */
|
|
45
|
+
export declare const isBlankTitle: (text: string) => boolean;
|
|
46
|
+
//# sourceMappingURL=thread-title.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-title.d.ts","sourceRoot":"","sources":["../../src/agent/thread-title.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,KAAK,CAAC;AA2BnC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAclD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAarD;AAKD,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC9B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAMjE;AAED,yIAAyI;AACzI,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,OAA8C,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal CEL-2530 - the conversation title rules, the SAME ones the service applies when a title is saved, so the rename field
|
|
3
|
+
* refuses exactly what the service would (a 422 is then only version skew) and sends what it will store.
|
|
4
|
+
*
|
|
5
|
+
* MIRRORS the backend BFF (cellarnode-backend-v2 `features/agent-threads/rename-thread.ts`, `normalizeThreadTitle`) and the agents
|
|
6
|
+
* service (cellarnode-mcp `agents/src/thread-title.ts`, `parseUserTitle`). All three run the same vectors
|
|
7
|
+
* (`title-vectors.test.fixture.ts` here, `title-vectors.ts` in the others; byte-identical copies): change the rules in all three.
|
|
8
|
+
* Written as code points and property classes, never as literal characters, so this source carries no invisible text.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The longest title a person can give a conversation, in code points: an emoji is one whatever its UTF-16 length, so 80 emoji
|
|
12
|
+
* fit and 81 do not. Counted AFTER cleaning (see {@link cleanTitleText}), as the service does.
|
|
13
|
+
*/
|
|
14
|
+
export const THREAD_TITLE_MAX = 80;
|
|
15
|
+
/** Control, format (bidi controls, zero-width, soft hyphen, tag characters), lone surrogate, line and paragraph separator characters. */
|
|
16
|
+
const STRIPPED_CLASSES = /^[\p{Cc}\p{Cf}\p{Cs}\p{Zl}\p{Zp}]$/u;
|
|
17
|
+
/** ZWNJ and ZWJ are format characters that emoji sequences and several scripts need, so they stay. */
|
|
18
|
+
const KEPT_JOINERS = new Set([0x200c, 0x200d]);
|
|
19
|
+
/** Blank-looking letters and separators that are not in the classes above: Hangul fillers, soft hyphen, Mongolian vowel separator. */
|
|
20
|
+
const BLANK_LOOKING = new Set([0x115f, 0x1160, 0x3164, 0xffa0, 0x00ad, 0x180e]);
|
|
21
|
+
/** The Braille pattern blank is a symbol (category So, so it would count as visible) that draws nothing: it is the Braille space. */
|
|
22
|
+
const BRAILLE_BLANK = 0x2800;
|
|
23
|
+
/** A title needs at least one real character: a letter, a number, a symbol (emoji) or punctuation. */
|
|
24
|
+
const VISIBLE = /[\p{L}\p{N}\p{S}\p{P}]/u;
|
|
25
|
+
const WHITESPACE = /^\s$/u;
|
|
26
|
+
const BYTE_ORDER_MARK = 0xfeff;
|
|
27
|
+
/** Whitespace as far as a title goes: what JavaScript calls whitespace, except the byte order mark, plus the Braille blank. */
|
|
28
|
+
const isSpace = (ch) => {
|
|
29
|
+
const c = ch.codePointAt(0) ?? 0;
|
|
30
|
+
return c === BRAILLE_BLANK || (c !== BYTE_ORDER_MARK && WHITESPACE.test(ch));
|
|
31
|
+
};
|
|
32
|
+
function isStripped(ch) {
|
|
33
|
+
const c = ch.codePointAt(0) ?? 0;
|
|
34
|
+
if (KEPT_JOINERS.has(c))
|
|
35
|
+
return false;
|
|
36
|
+
return BLANK_LOOKING.has(c) || (c >= 0xe0000 && c <= 0xe007f) || STRIPPED_CLASSES.test(ch);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Collapses every whitespace run (newlines, tabs, line and paragraph separators and the Braille blank included) to one space, strips
|
|
40
|
+
* unsafe and blank-looking characters (a stripped character is simply gone: it does not make a space), and trims. The byte order
|
|
41
|
+
* mark is a format character that JavaScript also calls whitespace; it is stripped, not turned into a space.
|
|
42
|
+
*/
|
|
43
|
+
export function cleanTitleText(raw) {
|
|
44
|
+
let out = "";
|
|
45
|
+
let space = false;
|
|
46
|
+
for (const ch of raw) {
|
|
47
|
+
if (isSpace(ch)) {
|
|
48
|
+
space = true;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (isStripped(ch))
|
|
52
|
+
continue;
|
|
53
|
+
if (space && out !== "")
|
|
54
|
+
out += " ";
|
|
55
|
+
space = false;
|
|
56
|
+
out += ch;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Every run of whitespace and blank or invisible code points (the Braille blank, the Hangul fillers, no-break and other spaces, zero-width
|
|
62
|
+
* and other format characters, the soft hyphen...; the joiners ZWJ and ZWNJ excepted) becomes ONE space. For text that is drawn rather than stored (a link's words): 700 blank glyphs would otherwise push
|
|
63
|
+
* whatever follows them hundreds of pixels away.
|
|
64
|
+
*/
|
|
65
|
+
export function collapseBlankRuns(raw) {
|
|
66
|
+
let out = "";
|
|
67
|
+
let run = false;
|
|
68
|
+
for (const ch of raw) {
|
|
69
|
+
if (isSpace(ch) || isStripped(ch)) {
|
|
70
|
+
if (!run)
|
|
71
|
+
out += " ";
|
|
72
|
+
run = true;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
out += ch;
|
|
76
|
+
run = false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
/** The number of code points in `s` (what a person counts: U+1F600 is one character, though `.length` says two). */
|
|
82
|
+
const codePointLength = (s) => [...s].length;
|
|
83
|
+
/**
|
|
84
|
+
* The title as it is stored: cleaned as above, with at least one visible character (a letter, number, symbol or punctuation: a
|
|
85
|
+
* title of combining marks, private-use or unassigned code points alone has none), and 1 to {@link THREAD_TITLE_MAX} code points
|
|
86
|
+
* counted after cleaning. Never silently shortened. `length` on a refusal is the CLEANED length.
|
|
87
|
+
*/
|
|
88
|
+
export function normalizeThreadTitle(raw) {
|
|
89
|
+
const title = cleanTitleText(raw);
|
|
90
|
+
if (!VISIBLE.test(title))
|
|
91
|
+
return { ok: false, reason: "empty" };
|
|
92
|
+
const length = codePointLength(title);
|
|
93
|
+
if (length > THREAD_TITLE_MAX)
|
|
94
|
+
return { ok: false, reason: "too_long", length };
|
|
95
|
+
return { ok: true, title };
|
|
96
|
+
}
|
|
97
|
+
/** Whether `text` shows nothing as a title (see {@link normalizeThreadTitle}): no letter, number, symbol or punctuation once cleaned. */
|
|
98
|
+
export const isBlankTitle = (text) => !VISIBLE.test(cleanTitleText(text));
|
|
99
|
+
//# sourceMappingURL=thread-title.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-title.js","sourceRoot":"","sources":["../../src/agent/thread-title.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { type AgentMessagePart, type AgentToolCall } from "./schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* @internal Pure helpers behind the tool-activity trail: tool and card names in words, the result of a call without the
|
|
4
|
+
* model-facing envelope, and which calls a domain card shows. Host- and role-agnostic: nothing here knows an admin route or a
|
|
5
|
+
* producer tool. The defaults are English; every table is overridable (`AgentToolNaming`).
|
|
6
|
+
*/
|
|
7
|
+
/** The role prefixes the MCP tools carry (`admin_get_mcp_overview`, `producer_get_offer_workspace`). Stripped from a name. */
|
|
8
|
+
export declare const DEFAULT_TOOL_PREFIXES: readonly string[];
|
|
9
|
+
export declare const DEFAULT_ACRONYMS: Readonly<Record<string, string>>;
|
|
10
|
+
export type ToolTense = "active" | "done" | "failed";
|
|
11
|
+
/** The leading verb of a tool name, as a finished call, one still running and one that failed. */
|
|
12
|
+
export type ToolVerb = Readonly<Record<ToolTense, string>>;
|
|
13
|
+
export declare const DEFAULT_TOOL_VERBS: Readonly<Record<string, ToolVerb>>;
|
|
14
|
+
/** A host's wording for one tool: one string for every state, or one per state (a missing state uses `done`, then `active`). */
|
|
15
|
+
export type ToolLabel = string | Partial<Record<ToolTense, string>>;
|
|
16
|
+
/**
|
|
17
|
+
* How tool and card names read. All optional: without it generic names are humanised in English
|
|
18
|
+
* (`admin_get_mcp_overview` becomes "Checked MCP overview"). A host that is not in English supplies its own words.
|
|
19
|
+
*/
|
|
20
|
+
export interface AgentToolNaming {
|
|
21
|
+
/** The host's own wording per tool name. Wins over the generic wording. */
|
|
22
|
+
toolLabels?: Readonly<Record<string, ToolLabel>>;
|
|
23
|
+
/** Asked before `toolLabels`: return the wording for this tool in this state, or `undefined` to fall through. */
|
|
24
|
+
formatToolLabel?: (name: string, tense: ToolTense) => string | undefined;
|
|
25
|
+
/** A card type's name in words (`{ McpUsageCard: "MCP usage" }`); the default is the type name split into words. */
|
|
26
|
+
cardLabels?: Readonly<Record<string, string>>;
|
|
27
|
+
/** Replaces entries of the English defaults: the leading verbs, the acronyms kept in capitals, the role prefixes stripped. */
|
|
28
|
+
toolWording?: {
|
|
29
|
+
verbs?: Readonly<Record<string, ToolVerb>>;
|
|
30
|
+
acronyms?: Readonly<Record<string, string>>;
|
|
31
|
+
prefixes?: readonly string[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface ToolNamer {
|
|
35
|
+
tool: (name: string, tense: ToolTense) => string;
|
|
36
|
+
card: (cardType: string) => string;
|
|
37
|
+
}
|
|
38
|
+
/** A name that is an identifier (snake_case or camelCase with no spaces), not a sentence the host already wrote. */
|
|
39
|
+
export declare const looksLikeIdentifier: (name: string) => boolean;
|
|
40
|
+
/** Builds the namer a component uses: the host's wording first, then the (overridable) English defaults. */
|
|
41
|
+
export declare function createToolNamer(naming?: AgentToolNaming): ToolNamer;
|
|
42
|
+
/**
|
|
43
|
+
* `admin_get_mcp_overview` becomes "Checked MCP overview" (done) or "Checking MCP overview" (active);
|
|
44
|
+
* `producer_get_offer_workspace` becomes "Checked offer workspace"; `admin_platform_stats` becomes "Platform stats".
|
|
45
|
+
* A host label for the exact name wins.
|
|
46
|
+
*/
|
|
47
|
+
export declare function humanizeToolName(name: string, options?: AgentToolNaming & {
|
|
48
|
+
tense?: ToolTense;
|
|
49
|
+
}): string;
|
|
50
|
+
/** `McpUsageCard` becomes "MCP usage", `OfferCard` becomes "Offer", `DataTable` becomes "Data table". */
|
|
51
|
+
export declare function humanizeCardType(cardType: string, naming?: AgentToolNaming): string;
|
|
52
|
+
export type ToolResultView = {
|
|
53
|
+
kind: "json";
|
|
54
|
+
text: string;
|
|
55
|
+
lines: number;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "text";
|
|
58
|
+
text: string;
|
|
59
|
+
lines: number;
|
|
60
|
+
};
|
|
61
|
+
/** A preview never holds more than this many characters, however large the result. */
|
|
62
|
+
export declare const MAX_PREVIEW_CHARS = 20000;
|
|
63
|
+
/** The wrapper the tool layer puts around a result for the model: `{ untrusted: true, source, data }`. Only that exact flag. */
|
|
64
|
+
export declare function isResultEnvelope(v: unknown): v is Record<string, unknown>;
|
|
65
|
+
/** The result with the envelope's own keys dropped: its `data` when there is one, else the other keys. */
|
|
66
|
+
export declare function unwrapResultEnvelope(v: unknown): unknown;
|
|
67
|
+
/**
|
|
68
|
+
* What a call's result looks like to a person: the envelope's `data` (the envelope's `untrusted` and `source` keys are never
|
|
69
|
+
* shown), pretty-printed, masked cells as their masked text, at most {@link MAX_PREVIEW_CHARS} characters. A string is parsed
|
|
70
|
+
* as JSON when it is JSON; a string that is not (plain text, or JSON shortened by the host) keeps the text, minus a
|
|
71
|
+
* recognisable envelope prefix. The envelope is only unwrapped when it says `untrusted: true`: a result that merely has a
|
|
72
|
+
* `source` or `data` key is the host's own data and is shown whole.
|
|
73
|
+
*
|
|
74
|
+
* `result` is shown as given: the host redacts it the way it redacts `args` (masked cells are marked, never raw).
|
|
75
|
+
*/
|
|
76
|
+
export declare function formatToolResult(raw: unknown): ToolResultView | undefined;
|
|
77
|
+
/** What a call returned for the preview: the full `result` when the host sent one, else its (usually shortened) summary. */
|
|
78
|
+
export declare const resultOf: (call: AgentToolCall) => unknown;
|
|
79
|
+
/** Whether there is anything to preview. Cheap: no parsing or printing, so it can run on every render. */
|
|
80
|
+
export declare function hasResult(call: AgentToolCall): boolean;
|
|
81
|
+
export interface AgentToolStep {
|
|
82
|
+
kind: "tool";
|
|
83
|
+
call: AgentToolCall;
|
|
84
|
+
/** A domain card in the same message shows this call's data, so its preview starts collapsed. */
|
|
85
|
+
shownBelow: boolean;
|
|
86
|
+
/** The card's name in words (`"MCP usage"`), shown as a chip on the step. */
|
|
87
|
+
cardTitle?: string;
|
|
88
|
+
}
|
|
89
|
+
/** The model's own one-line summary of its reasoning ("Thought"), a step like any other. */
|
|
90
|
+
export interface AgentThoughtStep {
|
|
91
|
+
kind: "thought";
|
|
92
|
+
id: string;
|
|
93
|
+
summary: string;
|
|
94
|
+
/** The message is still streaming and this is its last part: the agent is thinking right now. */
|
|
95
|
+
running: boolean;
|
|
96
|
+
}
|
|
97
|
+
export type AgentActivityStep = AgentToolStep | AgentThoughtStep;
|
|
98
|
+
/** @deprecated Use {@link AgentToolStep}. */
|
|
99
|
+
export type AgentToolActivityStep = AgentToolStep;
|
|
100
|
+
export declare const stepId: (s: AgentActivityStep) => string;
|
|
101
|
+
/** A step the agent is still working on. */
|
|
102
|
+
export declare const stepInFlight: (s: AgentActivityStep) => boolean;
|
|
103
|
+
export type AgentMessageItem = {
|
|
104
|
+
kind: "part";
|
|
105
|
+
part: AgentMessagePart;
|
|
106
|
+
index: number;
|
|
107
|
+
} | {
|
|
108
|
+
kind: "activity";
|
|
109
|
+
key: string;
|
|
110
|
+
steps: AgentActivityStep[];
|
|
111
|
+
startIndex: number;
|
|
112
|
+
};
|
|
113
|
+
export type CardCoversCall = (call: AgentToolCall, card: {
|
|
114
|
+
cardType: string;
|
|
115
|
+
data: unknown;
|
|
116
|
+
}) => boolean;
|
|
117
|
+
export interface PlanOptions extends Pick<AgentToolNaming, "cardLabels" | "toolWording"> {
|
|
118
|
+
/**
|
|
119
|
+
* Whether a domain card shows a call's data. Without it (and without a card part's `forCallId`) no step is marked "shown
|
|
120
|
+
* below": a card is not assumed to show anything.
|
|
121
|
+
*/
|
|
122
|
+
covers?: CardCoversCall;
|
|
123
|
+
/** The message is still streaming: a trailing `thinking` part is the agent thinking now. */
|
|
124
|
+
streaming?: boolean;
|
|
125
|
+
/** Indexes of the `card` parts that actually rendered something. A card that rendered nothing covers nothing. Default: all. */
|
|
126
|
+
renderedCards?: ReadonlySet<number>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Folds a message's parts for display: every run of consecutive `toolCall` and `thinking` parts becomes one activity trail;
|
|
130
|
+
* everything else (text, approvals, cards) stays a part in its place. An approval is never folded into a trail.
|
|
131
|
+
*
|
|
132
|
+
* A call is "shown below" only when a later, rendered `card` part names it (`forCallId`), or, when no card names a call,
|
|
133
|
+
* when the host's `covers` says so. There is no default: guessing which card shows which call marks the wrong steps.
|
|
134
|
+
*/
|
|
135
|
+
export declare function planMessageParts(parts: readonly AgentMessagePart[], options?: PlanOptions): AgentMessageItem[];
|
|
136
|
+
//# sourceMappingURL=tool-activity-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-activity-model.d.ts","sourceRoot":"","sources":["../../src/agent/tool-activity-model.ts"],"names":[],"mappings":"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"}
|