dsh-hypatia-auto-memory 0.3.0 → 0.5.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/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","useMemo","useRef","useCallback","css","IconChevronDownOutline14","Input","Button","createElement"],"sources":["../src/client/consolidation-models.ts","../src/client/shelves.ts","../src/client/locales.ts","../src/client/SettingsCard.tsx","../src/client/index.tsx"],"sourcesContent":["/** Model-directory projection shared by the consolidation settings card. */\n\nimport type { ModelProviderGroup } from '@deepseek-ai/dsh-api-remotes/client'\n\n/** One exact provider/model route used for a consolidation attempt. */\nexport interface ConsolidationModelRoute {\n provider: string\n model: string\n}\n\n/** One catalog route, including stored routes no longer advertised by an adapter. */\nexport interface ConsolidationModelCandidate extends ConsolidationModelRoute {\n key: string\n providerName: string\n modelName: string\n available: boolean\n selected: boolean\n}\n\n/** One catalog response retained by the settings card. */\nexport interface ConsolidationModelCatalog {\n groups: readonly ModelProviderGroup[]\n partial: boolean\n}\n\n/** Load the current Host model directory for the settings card. */\nexport type LoadConsolidationModelCatalog = () => Promise<ConsolidationModelCatalog>\n\n/** Stable opaque key for one exact route. */\nexport function consolidationModelKey(route: ConsolidationModelRoute): string {\n return `${route.provider}\\0${route.model}`\n}\n\n/**\n * Join the live model directory with selected routes that disappeared from it.\n * Disappeared routes remain visible so users can remove them deliberately.\n */\nexport function consolidationModelCandidates(\n groups: readonly ModelProviderGroup[],\n stored: readonly ConsolidationModelRoute[],\n selected: ReadonlySet<string>,\n): ConsolidationModelCandidate[] {\n const storedByKey = new Map(stored.map(route => [consolidationModelKey(route), route]))\n const candidates = groups.flatMap(group => group.models.map((model): ConsolidationModelCandidate => {\n const route = { provider: group.id, model: model.id }\n const key = consolidationModelKey(route)\n storedByKey.delete(key)\n return {\n ...route,\n key,\n providerName: group.name,\n modelName: model.name,\n available: true,\n selected: selected.has(key),\n }\n }))\n for (const route of storedByKey.values()) {\n const key = consolidationModelKey(route)\n candidates.push({\n ...route,\n key,\n providerName: route.provider,\n modelName: route.model,\n available: false,\n selected: selected.has(key),\n })\n }\n return candidates\n}\n","/**\n * Shelf choices for the settings card.\n *\n * The Host publishes `hypatia list` as the read-only `hypatia-auto-memory-shelves`\n * settings namespace (see `src/config.js`); the card reads it through the\n * settings descriptor. Zero runtime imports, so it is unit-tested under\n * `node:test` like `card-form.ts`.\n */\n\n/** Namespace the Host publishes the shelf listing under. */\nexport const INVENTORY_NAMESPACE = 'hypatia-auto-memory-shelves'\n\n/** Shelf hypatia uses when none is named. */\nexport const DEFAULT_SHELF = 'default'\n\n/** One shelf as `hypatia list` reports it. */\nexport interface ShelfInfo {\n name: string\n path: string\n connected: boolean\n}\n\n/** The Host's latest listing; `error` is non-empty when it could not list. */\nexport interface ShelfInventory {\n shelves: ShelfInfo[]\n error: string\n}\n\n/** Load the Host's latest listing for the settings card. */\nexport type LoadShelfInventory = () => Promise<ShelfInventory>\n\n/** One dropdown option. */\nexport interface ShelfChoice {\n name: string\n path: string\n /** False for a shelf that is registered but not connected. */\n connected: boolean\n /** False for a stored value the listing no longer reports. */\n listed: boolean\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Pick the inventory namespace out of a settings descriptor.\n *\n * Reads the composition layer (`base`), which only the Host sets, rather than\n * the resolved value: a stray user-layer section for this namespace would\n * otherwise freeze the list.\n * @param described - the `namespaces` array a settings `describe()` returns.\n * @returns the listing, or undefined when the Host does not serve one.\n */\nexport function readShelfInventory(described: readonly unknown[]): ShelfInventory | undefined {\n const view = described.find(entry => isRecord(entry) && entry.ns === INVENTORY_NAMESPACE)\n if (!isRecord(view) || !isRecord(view.base)) return undefined\n const { shelves, error } = view.base\n return {\n shelves: Array.isArray(shelves)\n ? shelves.flatMap((shelf): ShelfInfo[] => isRecord(shelf) && typeof shelf.name === 'string'\n ? [{\n name: shelf.name,\n path: typeof shelf.path === 'string' ? shelf.path : '',\n connected: shelf.connected === true,\n }]\n : [])\n : [],\n error: typeof error === 'string' ? error : '',\n }\n}\n\n/**\n * Every shelf the dropdown offers: the listing, plus the stored and composed\n * values when the listing does not carry them, so the current choice always\n * renders and never silently changes to the first option.\n * @param shelves - the Host's listing.\n * @param keep - values that must stay selectable (current draft, stored, composed).\n * @returns options, listed shelves first in listing order.\n */\nexport function shelfChoices(shelves: readonly ShelfInfo[], keep: readonly string[]): ShelfChoice[] {\n const choices: ShelfChoice[] = shelves.map(shelf => ({ ...shelf, listed: true }))\n for (const name of keep) {\n if (name === '' || choices.some(choice => choice.name === name)) continue\n choices.push({ name, path: '', connected: false, listed: false })\n }\n return choices\n}\n","/** `hypatia-auto-memory` namespace dictionaries. */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'hypatia-auto-memory'\n\n/** Simplified Chinese dictionary and key source of truth. */\nexport const zh = {\n loading: '正在加载 {ns} 设置…',\n unavailable: '当前上下文不可用 {ns} 设置。',\n title: 'Hypatia Auto Memory',\n description:\n '自动将对话轮次记录到 Hypatia,并在新内容足够多时通过独立模型路由进行后台整合。',\n enable: '启用自动记忆',\n autoApprove: '自动批准模型发起的 hypatia 命令',\n autoApproveHint: '仅限不含管道、重定向、命令串联的纯 hypatia 调用;插件自身的写入不经过此路径。关闭后模型每次检索都会弹出批准框。修改后需重载配置档生效。',\n shelf: '记忆写入的 shelf',\n shelfHint: '插件的记录、整合与会话开始时的规则预加载都读写这个 shelf;不是 default 时,会话开头会提示模型为 hypatia 命令加上 --shelf。修改后需重载配置档生效。每个 shelf 的记录进度单独保存,切回原来的 shelf 会从上次的位置继续;切到新的 shelf 后,每个有活动的会话会把完整历史重新记录进去并整合一遍(会消耗模型调用)。列表来自 hypatia list,约每分钟刷新一次。',\n shelfLoading: '正在读取 hypatia list…',\n shelfLoadFailed: '无法读取 shelf 列表。',\n shelfListingFailed: 'hypatia list 执行失败,列表可能已过时:{message}',\n shelfDisconnected: '未连接',\n shelfOptionStatus: '({status})',\n shelfNotListed: '不在 hypatia list 中',\n shelfDisconnectedWarning: 'shelf {shelf} 已注册但未连接,写入会失败。',\n shelfNotListedWarning: 'hypatia 没有注册 shelf {shelf},写入会失败;请先执行 hypatia connect <目录> --name {shelf}。',\n consolidationTitle: '整合候选模型',\n modelSelectionHint: '选择一个或多个模型。每次整合尝试(含重试)会按所选顺序轮转;未选择时只记录对话,不执行整合。',\n modelCatalogLoading: '正在读取可用模型…',\n modelCatalogFailed: '无法读取可用模型。',\n modelCatalogPartial: '部分提供方未能返回模型目录。',\n modelCatalogEmpty: '当前没有可选择的模型。',\n selectedModels: '用于轮转的模型',\n unavailableModels: '不可用或未再声明的模型',\n modelUnavailable: '当前不可用',\n retry: '重试',\n checkEveryTurns: '两次整合至少间隔 N 轮',\n minNewTokens: '最小新增 token 数',\n cascadeBatchSize: '归档批量',\n dedupMaxDistance: '关联距离上限',\n cascadeHint: '每积累这么多同层摘要,就归档为上一层的一条;关联距离上限决定新记忆要多接近既有条目才值得判定关系。',\n limitsTitle: '单次整合体量',\n limitsHint: '输入预算决定送入模型的对话长度(超出部分截断保留最近内容);输出预算需容纳摘要与全部工作单元,过小会导致整合失败。',\n maxInputTokens: '输入预算(token)',\n maxOutputTokens: '输出预算(token)',\n maxWorkUnitsPerRun: '每次最多提取工作单元数',\n recallPreload: '召回:会话开始时预加载规则与禁忌',\n advancedHint:\n '高级字段(二进制、收集器上限、队列调优)可直接在 settings.yaml 的 {ns} 键下编辑。',\n reset: '重置',\n discard: '放弃',\n save: '保存',\n saving: '保存中…',\n saveFailed: '保存失败:{message}',\n readOnly: '只读:当前上下文不可写入设置文档。',\n unsaved: '未保存',\n} as const satisfies Record<string, string>\n\n/** Key domain of the `hypatia-auto-memory` namespace. */\nexport type AutoMemoryLocaleKey = keyof typeof zh\n\n/** English dictionary checked against the Chinese key set. */\nexport const en = {\n loading: 'Loading {ns} settings…',\n unavailable: '{ns} settings are not available in this context.',\n title: 'Hypatia Auto Memory',\n description:\n 'Auto-memory logs conversation turns into Hypatia and runs background consolidation on a dedicated model route.',\n enable: 'Enable auto-memory',\n autoApprove: \"Auto-approve the agent's own hypatia commands\",\n autoApproveHint: 'Only plain hypatia calls with no pipe, redirect or chaining; this plugin\\'s own writes never take that path. With it off, every retrieval raises an approval prompt. Takes effect after a profile reload.',\n shelf: 'Memory shelf',\n shelfHint: 'Logging, consolidation and the session-start rules preload all read and write this shelf; when it is not default, each session is told to pass --shelf to its hypatia commands. Takes effect after a profile reload. Progress is kept per shelf, so switching back resumes where that shelf left off; on a new shelf, each session is logged from its start the next time it is active, and consolidated again (model calls). Choices come from hypatia list, refreshed about once a minute.',\n shelfLoading: 'Reading hypatia list…',\n shelfLoadFailed: 'Unable to load the shelf list.',\n shelfListingFailed: 'hypatia list failed; the list may be stale: {message}',\n shelfDisconnected: 'not connected',\n shelfOptionStatus: ' ({status})',\n shelfNotListed: 'not in hypatia list',\n shelfDisconnectedWarning: 'Shelf {shelf} is registered but not connected; writes will fail.',\n shelfNotListedWarning: 'hypatia has no shelf named {shelf}; writes will fail until you run hypatia connect <dir> --name {shelf}.',\n consolidationTitle: 'Consolidation candidate models',\n modelSelectionHint: 'Choose one or more models. Every consolidation attempt, including a retry, rotates through this order; without a selection, conversations continue logging but consolidation stays idle.',\n modelCatalogLoading: 'Loading available models…',\n modelCatalogFailed: 'Unable to load available models.',\n modelCatalogPartial: 'Some providers did not return a model catalog.',\n modelCatalogEmpty: 'No models are currently available.',\n selectedModels: 'Models used for rotation',\n unavailableModels: 'Unavailable or no longer advertised',\n modelUnavailable: 'Unavailable',\n retry: 'Retry',\n checkEveryTurns: 'Minimum turns between consolidations',\n minNewTokens: 'Min new tokens',\n cascadeBatchSize: 'Archive batch',\n dedupMaxDistance: 'Relation distance',\n cascadeHint: 'Every batch of same-tier summaries is archived into one entry a tier up. Relation distance is how near a new memory must be to an existing one to be worth judging a relationship.',\n limitsTitle: 'Per-run consolidation size',\n limitsHint: 'The input budget caps how much conversation is sent to the model (overflow keeps the most recent content); the output budget must fit the summary plus every work unit — too small and consolidation fails.',\n maxInputTokens: 'Input budget (tokens)',\n maxOutputTokens: 'Output budget (tokens)',\n maxWorkUnitsPerRun: 'Max work units per run',\n recallPreload: 'Recall: preload rules & taboos at session start',\n advancedHint:\n 'Advanced fields (binaries, collector caps, queue tuning) can be edited directly in settings.yaml under the {ns} key.',\n reset: 'Reset',\n discard: 'Discard',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'Save failed: {message}',\n readOnly: 'Read-only: settings document is not writable in this context.',\n unsaved: 'Unsaved',\n} satisfies Record<AutoMemoryLocaleKey, string>\n","/**\n * Settings card for the `hypatia-auto-memory` namespace.\n *\n * The card owns its disclosure state and stages edits until Save. Its visual\n * treatment mirrors the DSH plugin-settings cards while remaining bundle-local.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, IconChevronDownOutline14, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n consolidationModelCandidates,\n consolidationModelKey,\n type ConsolidationModelCandidate,\n type ConsolidationModelRoute,\n type LoadConsolidationModelCatalog,\n} from './consolidation-models'\nimport { DEFAULT_SHELF, shelfChoices, type LoadShelfInventory, type ShelfInfo } from './shelves'\nimport css from './SettingsCard.module.css'\nimport { NS } from './locales'\nimport './slot-contract'\n\nconst DEFAULT_CONSOLIDATION = {\n models: [] as ConsolidationModelRoute[],\n maxInputTokens: 16000,\n maxOutputTokens: 2000,\n timeoutMs: 120000,\n checkEveryTurns: 5,\n minNewTokens: 3000,\n maxWorkUnitsPerRun: 3,\n adjudicate: true,\n dedupMaxDistance: 0.45,\n cascade: { enabled: true, batchSize: 16 },\n}\n\nexport interface ConfigShape {\n enabled?: boolean\n autoApprove?: boolean\n shelf?: string\n consolidation?: typeof DEFAULT_CONSOLIDATION\n recall?: { preloadRulesTaboos?: boolean }\n}\n\nfunction getSnapshotValue<T>(scope: SettingsScope<T>): SettingsScopeSnapshot<T> {\n return scope.getSnapshot()\n}\n\nfunction subscribe(scope: SettingsScope<unknown>, cb: () => void) {\n return scope.subscribe(cb)\n}\n\nfunction sectionValue<T>(snap: SettingsScopeSnapshot<T>): T | undefined {\n return snap.value ?? (snap.base as T | undefined) ?? undefined\n}\n\nfunction useScopeValue<T>(scope: SettingsScope<T>) {\n const [snap, setSnap] = useState(() => getSnapshotValue(scope))\n useEffect(() => {\n setSnap(getSnapshotValue(scope))\n return subscribe(scope as SettingsScope<unknown>, () => setSnap(getSnapshotValue(scope)))\n }, [scope])\n const value = useMemo(() => sectionValue(snap), [snap])\n return { snap, value }\n}\n\nfunction same(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport type SettingsCardProps = {\n scope: SettingsScope<ConfigShape>\n loadModelCatalog: LoadConsolidationModelCatalog\n loadShelfInventory: LoadShelfInventory\n} & PropsLocale<typeof NS>\n\nexport function SettingsCard({ scope, loadModelCatalog, loadShelfInventory, t }: SettingsCardProps) {\n const { snap, value } = useScopeValue(scope)\n const disabled = !snap.writable\n const base = useMemo(() => (snap.base ?? {}) as ConfigShape, [snap.base])\n\n const resolved: ConfigShape = useMemo(() => (value ?? base ?? {\n enabled: true,\n autoApprove: true,\n shelf: DEFAULT_SHELF,\n consolidation: DEFAULT_CONSOLIDATION,\n recall: { preloadRulesTaboos: true },\n }), [value, base])\n\n const [draft, setDraft] = useState(resolved)\n const [open, setOpen] = useState(false)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [catalogStatus, setCatalogStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [catalogGroups, setCatalogGroups] = useState<Parameters<typeof consolidationModelCandidates>[0]>([])\n const [catalogPartial, setCatalogPartial] = useState(false)\n const catalogGeneration = useRef(0)\n const [shelfStatus, setShelfStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [shelves, setShelves] = useState<ShelfInfo[]>([])\n const [shelfListingError, setShelfListingError] = useState('')\n const shelfGeneration = useRef(0)\n\n useEffect(() => {\n setDraft(resolved)\n }, [resolved])\n\n const dirty = useMemo(() => !same(draft, resolved), [draft, resolved])\n const consolidation = draft.consolidation ?? DEFAULT_CONSOLIDATION\n const recall = draft.recall ?? { preloadRulesTaboos: true }\n const saveBlocked = disabled || !dirty || saving\n\n const updateConsolidation = useCallback((patch: Partial<typeof DEFAULT_CONSOLIDATION>) => {\n setDraft((prev) => ({\n ...prev,\n consolidation: { ...(prev.consolidation ?? DEFAULT_CONSOLIDATION), ...patch },\n }))\n }, [])\n\n const loadCatalog = useCallback(async () => {\n const generation = ++catalogGeneration.current\n setCatalogStatus('loading')\n setCatalogPartial(false)\n try {\n const catalog = await loadModelCatalog()\n if (generation !== catalogGeneration.current) return\n setCatalogGroups(catalog.groups)\n setCatalogPartial(catalog.partial)\n setCatalogStatus('ready')\n } catch {\n if (generation !== catalogGeneration.current) return\n setCatalogStatus('error')\n }\n }, [loadModelCatalog])\n\n useEffect(() => {\n if (!open) return\n void loadCatalog()\n return () => { catalogGeneration.current += 1 }\n }, [open, loadCatalog])\n\n const loadShelves = useCallback(async () => {\n const generation = ++shelfGeneration.current\n setShelfStatus('loading')\n try {\n const inventory = await loadShelfInventory()\n if (generation !== shelfGeneration.current) return\n setShelves(inventory.shelves)\n setShelfListingError(inventory.error)\n setShelfStatus('ready')\n } catch {\n if (generation !== shelfGeneration.current) return\n setShelfStatus('error')\n }\n }, [loadShelfInventory])\n\n useEffect(() => {\n if (!open) return\n void loadShelves()\n return () => { shelfGeneration.current += 1 }\n }, [open, loadShelves])\n\n const draftShelf = draft.shelf ?? DEFAULT_SHELF\n const baseShelf = base.shelf ?? DEFAULT_SHELF\n const choices = useMemo(\n () => shelfChoices(shelves, [draftShelf, resolved.shelf ?? DEFAULT_SHELF, baseShelf]),\n [shelves, draftShelf, resolved.shelf, baseShelf],\n )\n const chosen = choices.find(choice => choice.name === draftShelf)\n\n const candidates = useMemo(() => {\n const models = consolidation.models ?? []\n return consolidationModelCandidates(\n catalogGroups,\n models,\n new Set(models.map(consolidationModelKey)),\n )\n }, [catalogGroups, consolidation.models])\n\n const toggleModel = useCallback((candidate: ConsolidationModelCandidate) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n const key = consolidationModelKey(candidate)\n const selected = currentModels.some(route => consolidationModelKey(route) === key)\n const models = selected\n ? currentModels.filter(route => consolidationModelKey(route) !== key)\n : [...currentModels, { provider: candidate.provider, model: candidate.model }]\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n const discard = useCallback(() => {\n setDraft(resolved)\n setError(null)\n }, [resolved])\n\n const save = useCallback(async () => {\n if (saveBlocked) return\n setSaving(true)\n setError(null)\n try {\n const tasks: Promise<void>[] = []\n if (!same(draft.enabled, resolved.enabled)) {\n tasks.push(scope.set('enabled', draft.enabled))\n }\n if (!same(draft.autoApprove, resolved.autoApprove)) {\n tasks.push(scope.set('autoApprove', draft.autoApprove))\n }\n if (!same(draft.shelf, resolved.shelf)) {\n tasks.push(scope.set('shelf', draft.shelf))\n }\n if (!same(draft.consolidation, resolved.consolidation)) {\n tasks.push(scope.set('consolidation', draft.consolidation))\n }\n if (!same(draft.recall, resolved.recall)) {\n tasks.push(scope.set('recall', draft.recall))\n }\n await Promise.all(tasks)\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console\n console.error(`[${NS}] save failed:`, err)\n setError(message)\n } finally {\n setSaving(false)\n }\n }, [draft, resolved, saveBlocked, scope])\n\n if (snap.status === 'loading') {\n return <li className={css.status}>{t('loading', { ns: NS })}</li>\n }\n if (snap.status === 'unavailable') {\n return <li className={css.status}>{t('unavailable', { ns: NS })}</li>\n }\n\n const availableGroups = new Map<string, {\n providerName: string\n candidates: ConsolidationModelCandidate[]\n }>()\n const unavailable: ConsolidationModelCandidate[] = []\n for (const candidate of candidates) {\n if (!candidate.available) {\n unavailable.push(candidate)\n continue\n }\n const group = availableGroups.get(candidate.provider)\n if (group === undefined) {\n availableGroups.set(candidate.provider, {\n providerName: candidate.providerName,\n candidates: [candidate],\n })\n } else {\n group.candidates.push(candidate)\n }\n }\n\n const renderCandidate = (candidate: ConsolidationModelCandidate) => (\n <label key={candidate.key} className={css.model}>\n <input\n type=\"checkbox\"\n checked={candidate.selected}\n disabled={disabled || saving}\n onChange={() => toggleModel(candidate)}\n />\n <span>\n <span className={css.modelName}>{candidate.modelName}</span>\n <span className={css.route}>{`${candidate.providerName} · ${candidate.provider}/${candidate.model}`}</span>\n </span>\n {!candidate.available ? <span className={css.unavailable}>{t('modelUnavailable')}</span> : null}\n </label>\n )\n\n return (\n <li className={`${css.card} ${open ? css.cardOpen : ''}`}>\n <button\n type=\"button\"\n className={css.header}\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n <IconChevronDownOutline14 className={`${css.chevron} ${open ? css.chevronOpen : ''}`} />\n </button>\n\n {open ? (\n <div className={css.body}>\n {!snap.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-enabled\">{t('enable')}</label>\n {draft.enabled !== (base.enabled ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: base.enabled ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-enabled\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.enabled ?? true}\n aria-label={t('enable')}\n className={`${css.switch} ${draft.enabled ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: !(current.enabled ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-autoApprove\">{t('autoApprove')}</label>\n {(draft.autoApprove ?? true) !== (base.autoApprove ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: base.autoApprove ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-autoApprove\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.autoApprove ?? true}\n aria-label={t('autoApprove')}\n className={`${css.switch} ${draft.autoApprove ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: !(current.autoApprove ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.hint}>{t('autoApproveHint')}</p>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-shelf\">{t('shelf')}</label>\n {draftShelf !== baseShelf ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, shelf: baseShelf }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <select\n id=\"ham-shelf\"\n className={css.select}\n value={draftShelf}\n disabled={disabled || saving}\n onChange={(event) => {\n const shelf = event.target.value\n setDraft((current) => ({ ...current, shelf }))\n }}\n >\n {choices.map(choice => (\n <option key={choice.name} value={choice.name}>\n {choice.name}\n {choice.path !== '' ? ` — ${choice.path}` : ''}\n {!choice.listed\n ? t('shelfOptionStatus', { status: t('shelfNotListed') })\n : !choice.connected ? t('shelfOptionStatus', { status: t('shelfDisconnected') }) : ''}\n </option>\n ))}\n </select>\n {shelfStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('shelfLoading')}</p> : null}\n {shelfStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('shelfLoadFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadShelves() }}>{t('retry')}</button>\n </div>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError !== '' ? (\n <p className={css.notice} role=\"status\">{t('shelfListingFailed', { message: shelfListingError })}</p>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError === '' && chosen !== undefined && (!chosen.listed || !chosen.connected) ? (\n <p className={css.warning} role=\"status\">{t(chosen.listed ? 'shelfDisconnectedWarning' : 'shelfNotListedWarning', { shelf: chosen.name })}</p>\n ) : null}\n <p className={css.hint}>{t('shelfHint')}</p>\n </div>\n\n <section className={css.group} aria-labelledby=\"ham-consolidation-title\">\n <h3 id=\"ham-consolidation-title\" className={css.groupTitle}>{t('consolidationTitle')}</h3>\n <p className={css.hint}>{t('modelSelectionHint')}</p>\n\n <div className={css.modelSelection}>\n {catalogStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('modelCatalogLoading')}</p> : null}\n {catalogStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('modelCatalogFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadCatalog() }}>{t('retry')}</button>\n </div>\n ) : null}\n {catalogPartial ? <p className={css.notice}>{t('modelCatalogPartial')}</p> : null}\n {candidates.length > 0 ? (\n <fieldset className={css.models}>\n <legend>{t('selectedModels')}</legend>\n {[...availableGroups].map(([provider, group]) => (\n <div key={provider} className={css.modelGroup}>\n <div className={css.providerName}>{group.providerName}</div>\n {group.candidates.map(renderCandidate)}\n </div>\n ))}\n {unavailable.length > 0 ? (\n <div className={css.modelGroup}>\n <div className={css.providerName}>{t('unavailableModels')}</div>\n {unavailable.map(renderCandidate)}\n </div>\n ) : null}\n </fieldset>\n ) : catalogStatus === 'ready' ? <p className={css.notice}>{t('modelCatalogEmpty')}</p> : null}\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-checkEveryTurns\">{t('checkEveryTurns')}</label>\n {consolidation.checkEveryTurns !== (base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ checkEveryTurns: base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-checkEveryTurns\"\n className={css.input}\n type=\"number\"\n min={1}\n value={consolidation.checkEveryTurns}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ checkEveryTurns: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-minNewTokens\">{t('minNewTokens')}</label>\n {consolidation.minNewTokens !== (base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ minNewTokens: base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-minNewTokens\"\n className={css.input}\n type=\"number\"\n min={0}\n value={consolidation.minNewTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ minNewTokens: Number(event.target.value) })}\n />\n </div>\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-cascadeBatchSize\">{t('cascadeBatchSize')}</label>\n {(consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize)\n !== (base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize,\n },\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-cascadeBatchSize\"\n className={css.input}\n type=\"number\"\n min={2}\n value={consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize}\n disabled={disabled}\n onChange={(event) => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: Number(event.target.value),\n },\n })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-dedupMaxDistance\">{t('dedupMaxDistance')}</label>\n {(consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance)\n !== (base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n dedupMaxDistance: base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance,\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-dedupMaxDistance\"\n className={css.input}\n type=\"number\"\n min={0}\n step={0.05}\n value={consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ dedupMaxDistance: Number(event.target.value) })}\n />\n </div>\n </div>\n <p className={css.hint}>{t('cascadeHint')}</p>\n\n <h4 className={css.limitsTitle}>{t('limitsTitle')}</h4>\n <p className={css.hint}>{t('limitsHint')}</p>\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxInputTokens\">{t('maxInputTokens')}</label>\n {consolidation.maxInputTokens !== (base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxInputTokens: base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxInputTokens\"\n className={css.input}\n type=\"number\"\n min={1000}\n step={1000}\n value={consolidation.maxInputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxInputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxOutputTokens\">{t('maxOutputTokens')}</label>\n {consolidation.maxOutputTokens !== (base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxOutputTokens: base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxOutputTokens\"\n className={css.input}\n type=\"number\"\n min={200}\n step={200}\n value={consolidation.maxOutputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxOutputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxWorkUnitsPerRun\">{t('maxWorkUnitsPerRun')}</label>\n {consolidation.maxWorkUnitsPerRun !== (base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxWorkUnitsPerRun: base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxWorkUnitsPerRun\"\n className={css.input}\n type=\"number\"\n min={1}\n max={10}\n value={consolidation.maxWorkUnitsPerRun}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxWorkUnitsPerRun: Number(event.target.value) })}\n />\n </div>\n </div>\n </section>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-preloadRulesTaboos\">{t('recallPreload')}</label>\n {(recall.preloadRulesTaboos ?? true) !== (base.recall?.preloadRulesTaboos ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: base.recall?.preloadRulesTaboos ?? true,\n },\n }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-preloadRulesTaboos\"\n type=\"button\"\n role=\"switch\"\n aria-checked={recall.preloadRulesTaboos ?? true}\n aria-label={t('recallPreload')}\n className={`${css.switch} ${recall.preloadRulesTaboos ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: !(current.recall?.preloadRulesTaboos ?? true),\n },\n }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <p className={css.advancedHint}>{t('advancedHint', { ns: NS })}</p>\n {error ? <p className={css.error} role=\"status\">{t('saveFailed', { message: error })}</p> : null}\n\n <div className={css.footer}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!dirty || saving}\n onClick={discard}\n >\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={saveBlocked}\n onClick={save}\n >\n {saving ? t('saving') : t('save')}\n </Button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n","/**\n * Browser half of dsh-hypatia-auto-memory: contributes a settings card under\n * Settings → Plugins, keyed by the `hypatia-auto-memory` namespace.\n *\n * The Host plugin already registers the schema and namespace; this half only\n * renders the form and routes edits through `ctx.settingsScope`.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { RemoteResult } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScopeBinder } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { createElement } from 'react'\nimport { SettingsCard } from './SettingsCard'\nimport type { ConfigShape } from './SettingsCard'\nimport type { LoadConsolidationModelCatalog } from './consolidation-models'\nimport { readShelfInventory, type LoadShelfInventory } from './shelves'\nimport { en, NS, zh } from './locales'\n\nconst APPLY_CLAIM = '__dshHypatiaAutoMemoryApplied'\n\n/**\n * The one settings-controller method this card calls. The remotes assembly\n * mounts the `settings` namespace at runtime, but its declaration merge lives\n * in `@deepseek-ai/dsh-api-settings-controller`, which this bundle does not\n * depend on for one method.\n */\ninterface SettingsDescribeRemote {\n describe(): Promise<RemoteResult<{ namespaces: readonly unknown[] }>>\n}\n\nfunction claimApply(): boolean {\n const scope = globalThis as Record<string, unknown>\n if (scope[APPLY_CLAIM] === true) return false\n scope[APPLY_CLAIM] = true\n return true\n}\n\nfunction releaseApply(): void {\n delete (globalThis as Record<string, unknown>)[APPLY_CLAIM]\n}\n\n/**\n * Required client services: settings, locale, slots, the Host model catalog,\n * and the settings descriptor. Each Remote namespace is its own service, so\n * `remote.settings` must be declared here or reading it throws.\n */\nexport const inject = ['slots', 'settingsScope', 'locale', 'remote', 'remote.session', 'remote.settings']\n\n/** Mount the browser half. */\nexport function apply(ctx: Context): void {\n if (!claimApply()) return\n\n const settingsScope = ctx.get('settingsScope') as SettingsScopeBinder\n const scope = settingsScope.bind<ConfigShape>({ namespace: NS })\n\n // Resolve through ctx.get with an explicit type rather than ctx.locale: the\n // locale package's cordis Context merge only applies when its types resolve\n // to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const locale = ctx.get('locale') as unknown as LocaleRuntime\n ctx.effect(() => locale.register(NS, { zh, en }), 'dsh-hypatia-auto-memory: locale dictionaries')\n\n const loadModelCatalog: LoadConsolidationModelCatalog = async () => {\n const response = await ctx.remote.session.modelCatalog()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n return {\n groups: response.value.groups,\n partial: response.value.failures.length > 0,\n }\n }\n // The Host re-publishes `hypatia list` as a settings namespace no card\n // claims; the descriptor is the only wire path a plugin's Host half has.\n // Read directly rather than through the shared describe mirror: the mirror\n // re-reads only on document commits, and a re-registration is not one.\n const loadShelfInventory: LoadShelfInventory = async () => {\n const settings = (ctx.remote as unknown as { settings: SettingsDescribeRemote }).settings\n const response = await settings.describe()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n const inventory = readShelfInventory(response.value.namespaces)\n if (inventory === undefined) throw new Error('the Host publishes no shelf listing')\n return inventory\n }\n const renderCard = (props: PropsLocale<typeof NS>) => createElement(SettingsCard, {\n scope,\n loadModelCatalog,\n loadShelfInventory,\n ...props,\n })\n const unregister = ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n { name: 'settings.plugin.item', key: NS, locale: NS },\n renderCard,\n ),\n )\n\n ctx.effect(() => () => {\n unregister()\n releaseApply()\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["isRecord","useState","useMemo","useRef","useCallback","css","IconChevronDownOutline14","Input","Button","css","MarkdownText","useState","useMemo","useRef","useCallback","createElement"],"sources":["../src/client/consolidation-models.ts","../src/client/shelves.ts","../src/client/locales.ts","../src/client/SettingsCard.tsx","../src/client/memory-client.ts","../src/client/MemoryView.tsx","../src/client/index.tsx"],"sourcesContent":["/** Model-directory projection shared by the consolidation settings card. */\n\nimport type { ModelProviderGroup } from '@deepseek-ai/dsh-api-remotes/client'\n\n/** One exact provider/model route used for a consolidation attempt. */\nexport interface ConsolidationModelRoute {\n provider: string\n model: string\n}\n\n/** One catalog route, including stored routes no longer advertised by an adapter. */\nexport interface ConsolidationModelCandidate extends ConsolidationModelRoute {\n key: string\n providerName: string\n modelName: string\n available: boolean\n selected: boolean\n}\n\n/** One catalog response retained by the settings card. */\nexport interface ConsolidationModelCatalog {\n groups: readonly ModelProviderGroup[]\n partial: boolean\n}\n\n/** Load the current Host model directory for the settings card. */\nexport type LoadConsolidationModelCatalog = () => Promise<ConsolidationModelCatalog>\n\n/** Stable opaque key for one exact route. */\nexport function consolidationModelKey(route: ConsolidationModelRoute): string {\n return `${route.provider}\\0${route.model}`\n}\n\n/**\n * Join the live model directory with selected routes that disappeared from it.\n * Disappeared routes remain visible so users can remove them deliberately.\n */\nexport function consolidationModelCandidates(\n groups: readonly ModelProviderGroup[],\n stored: readonly ConsolidationModelRoute[],\n selected: ReadonlySet<string>,\n): ConsolidationModelCandidate[] {\n const storedByKey = new Map(stored.map(route => [consolidationModelKey(route), route]))\n const candidates = groups.flatMap(group => group.models.map((model): ConsolidationModelCandidate => {\n const route = { provider: group.id, model: model.id }\n const key = consolidationModelKey(route)\n storedByKey.delete(key)\n return {\n ...route,\n key,\n providerName: group.name,\n modelName: model.name,\n available: true,\n selected: selected.has(key),\n }\n }))\n for (const route of storedByKey.values()) {\n const key = consolidationModelKey(route)\n candidates.push({\n ...route,\n key,\n providerName: route.provider,\n modelName: route.model,\n available: false,\n selected: selected.has(key),\n })\n }\n return candidates\n}\n","/**\n * Shelf choices for the settings card.\n *\n * The Host publishes `hypatia list` as the read-only `hypatia-auto-memory-shelves`\n * settings namespace (see `src/config.js`); the card reads it through the\n * settings descriptor. Zero runtime imports, so it is unit-tested under\n * `node:test` like `card-form.ts`.\n */\n\n/** Namespace the Host publishes the shelf listing under. */\nexport const INVENTORY_NAMESPACE = 'hypatia-auto-memory-shelves'\n\n/** Shelf hypatia uses when none is named. */\nexport const DEFAULT_SHELF = 'default'\n\n/** One shelf as `hypatia list` reports it. */\nexport interface ShelfInfo {\n name: string\n path: string\n connected: boolean\n}\n\n/** The Host's latest listing; `error` is non-empty when it could not list. */\nexport interface ShelfInventory {\n shelves: ShelfInfo[]\n error: string\n}\n\n/** Load the Host's latest listing for the settings card. */\nexport type LoadShelfInventory = () => Promise<ShelfInventory>\n\n/** One dropdown option. */\nexport interface ShelfChoice {\n name: string\n path: string\n /** False for a shelf that is registered but not connected. */\n connected: boolean\n /** False for a stored value the listing no longer reports. */\n listed: boolean\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Pick the inventory namespace out of a settings descriptor.\n *\n * Reads the composition layer (`base`), which only the Host sets, rather than\n * the resolved value: a stray user-layer section for this namespace would\n * otherwise freeze the list.\n * @param described - the `namespaces` array a settings `describe()` returns.\n * @returns the listing, or undefined when the Host does not serve one.\n */\nexport function readShelfInventory(described: readonly unknown[]): ShelfInventory | undefined {\n const view = described.find(entry => isRecord(entry) && entry.ns === INVENTORY_NAMESPACE)\n if (!isRecord(view) || !isRecord(view.base)) return undefined\n const { shelves, error } = view.base\n return {\n shelves: Array.isArray(shelves)\n ? shelves.flatMap((shelf): ShelfInfo[] => isRecord(shelf) && typeof shelf.name === 'string'\n ? [{\n name: shelf.name,\n path: typeof shelf.path === 'string' ? shelf.path : '',\n connected: shelf.connected === true,\n }]\n : [])\n : [],\n error: typeof error === 'string' ? error : '',\n }\n}\n\n/**\n * Every shelf the dropdown offers: the listing, plus the stored and composed\n * values when the listing does not carry them, so the current choice always\n * renders and never silently changes to the first option.\n * @param shelves - the Host's listing.\n * @param keep - values that must stay selectable (current draft, stored, composed).\n * @returns options, listed shelves first in listing order.\n */\nexport function shelfChoices(shelves: readonly ShelfInfo[], keep: readonly string[]): ShelfChoice[] {\n const choices: ShelfChoice[] = shelves.map(shelf => ({ ...shelf, listed: true }))\n for (const name of keep) {\n if (name === '' || choices.some(choice => choice.name === name)) continue\n choices.push({ name, path: '', connected: false, listed: false })\n }\n return choices\n}\n","/** `hypatia-auto-memory` namespace dictionaries. */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'hypatia-auto-memory'\n\n/** Simplified Chinese dictionary and key source of truth. */\nexport const zh = {\n loading: '正在加载 {ns} 设置…',\n unavailable: '当前上下文不可用 {ns} 设置。',\n title: 'Hypatia Auto Memory',\n description:\n '自动将对话轮次记录到 Hypatia,并在新内容足够多时通过独立模型路由进行后台整合。',\n enable: '启用自动记忆',\n autoApprove: '自动批准模型发起的 hypatia 命令',\n autoApproveHint: '仅限不含管道、重定向、命令串联的纯 hypatia 调用;插件自身的写入不经过此路径。关闭后模型每次检索都会弹出批准框。修改后需重载配置档生效。',\n shelf: '记忆写入的 shelf',\n shelfHint: '插件的记录、整合与会话开始时的规则预加载都读写这个 shelf;不是 default 时,会话开头会提示模型为 hypatia 命令加上 --shelf。修改后需重载配置档生效。每个 shelf 的记录进度单独保存,切回原来的 shelf 会从上次的位置继续;切到新的 shelf 后,每个有活动的会话会把完整历史重新记录进去并整合一遍(会消耗模型调用)。列表来自 hypatia list,约每分钟刷新一次。',\n shelfLoading: '正在读取 hypatia list…',\n shelfLoadFailed: '无法读取 shelf 列表。',\n shelfListingFailed: 'hypatia list 执行失败,列表可能已过时:{message}',\n shelfDisconnected: '未连接',\n shelfOptionStatus: '({status})',\n shelfNotListed: '不在 hypatia list 中',\n shelfDisconnectedWarning: 'shelf {shelf} 已注册但未连接,写入会失败。',\n shelfNotListedWarning: 'hypatia 没有注册 shelf {shelf},写入会失败;请先执行 hypatia connect <目录> --name {shelf}。',\n consolidationTitle: '整合候选模型',\n modelSelectionHint: '选择一个或多个模型。每次整合尝试(含重试)会按所选顺序轮转;未选择时只记录对话,不执行整合。',\n modelCatalogLoading: '正在读取可用模型…',\n modelCatalogFailed: '无法读取可用模型。',\n modelCatalogPartial: '部分提供方未能返回模型目录。',\n modelCatalogEmpty: '当前没有可选择的模型。',\n selectedModels: '用于轮转的模型',\n unavailableModels: '不可用或未再声明的模型',\n modelUnavailable: '当前不可用',\n retry: '重试',\n checkEveryTurns: '两次整合至少间隔 N 轮',\n minNewTokens: '最小新增 token 数',\n cascadeBatchSize: '归档批量',\n dedupMaxDistance: '关联距离上限',\n cascadeHint: '每积累这么多同层摘要,就归档为上一层的一条;关联距离上限决定新记忆要多接近既有条目才值得判定关系。',\n limitsTitle: '单次整合体量',\n limitsHint: '输入预算决定送入模型的对话长度(超出部分截断保留最近内容);输出预算需容纳摘要与全部工作单元,过小会导致整合失败。',\n maxInputTokens: '输入预算(token)',\n maxOutputTokens: '输出预算(token)',\n maxWorkUnitsPerRun: '每次最多提取工作单元数',\n recallPreload: '召回:会话开始时预加载规则与禁忌',\n advancedHint:\n '高级字段(二进制、收集器上限、队列调优)可直接在 settings.yaml 的 {ns} 键下编辑。',\n reset: '重置',\n discard: '放弃',\n save: '保存',\n saving: '保存中…',\n saveFailed: '保存失败:{message}',\n readOnly: '只读:当前上下文不可写入设置文档。',\n unsaved: '未保存',\n viewMemory: '记忆',\n memoryTitle: '本会话的记忆',\n memoryUpdatedAt: '状态更新于 {time}',\n memoryRefresh: '刷新',\n memoryLoading: '正在读取记忆状态…',\n memoryNoSnapshot: '插件还没有发布记忆状态。启用后完成一轮对话再回来看看。',\n memoryLoadFailed: '无法读取记忆状态:{message}',\n memoryUnknown: '这个会话还没有记忆记录。第一轮对话结束后会开始记录。',\n memoryLogged: '对话记录',\n memorySeqValue: '第 {seq} 条事件',\n memoryConsolidated: '摘要整合',\n memoryCaughtUp: '已结清',\n memoryBehind: '较记录落后 {behind} 条',\n memoryPending: '待整合内容',\n memoryPendingValue: '约 {tokens} token',\n memorySessionNode: '会话节点',\n memorySessionNodeYes: '已建立',\n memorySessionNodeNo: '未建立(宿主未提供会话摘要)',\n memoryBelongTo: '已链接消息',\n memoryBelongToValue: '{count} 条',\n memoryDeferred: '等待会话载入的任务',\n memoryFailedTitle: '失败任务',\n memoryFailedItem: '{kind} 连续失败 {attempts} 次',\n memoryContentTitle: '记忆内容',\n memoryContentFailed: '无法读取 shelf 中的记忆内容:{message}',\n memorySummariesTitle: '跨度摘要',\n memoryWorkUnitsTitle: '工作单元',\n memoryNoSummaries: '这个会话还没有产生摘要。整合运行后会出现在这里。',\n memoryNoWorkUnits: '这个会话还没有提炼出工作单元。',\n memoryCount: '显示 {shown} / 共 {total}',\n memoryTier: '{level} 级',\n memoryWorkUnit: '工作单元',\n memoryEntryExpand: '展开',\n memoryEntryCollapse: '收起',\n memoryEntryEmpty: '这条条目的正文为空,或已超过展示上限。',\n memoryCopyCode: '复制',\n memoryCopiedCode: '已复制',\n memoryFootnotes: '脚注',\n memoryTruncated: '内容超出展示上限,较早的条目或过长的正文已被截断。',\n memoryHint: '诊断视图:原始 msg-* 对话正文不在此显示,需要时让 Agent 通过 hypatia 检索。状态每 5 秒重读一次;「状态更新于」是宿主最近一次看到这些状态发生变化的时间(首次读取也算一次),不变说明这段时间没有新进展。两个条数都按会话日志的事件序号计(含工具调用,不是消息条数),所以它们之差就是还没总结的部分。',\n} as const satisfies Record<string, string>\n\n/** Key domain of the `hypatia-auto-memory` namespace. */\nexport type AutoMemoryLocaleKey = keyof typeof zh\n\n/** English dictionary checked against the Chinese key set. */\nexport const en = {\n loading: 'Loading {ns} settings…',\n unavailable: '{ns} settings are not available in this context.',\n title: 'Hypatia Auto Memory',\n description:\n 'Auto-memory logs conversation turns into Hypatia and runs background consolidation on a dedicated model route.',\n enable: 'Enable auto-memory',\n autoApprove: \"Auto-approve the agent's own hypatia commands\",\n autoApproveHint: 'Only plain hypatia calls with no pipe, redirect or chaining; this plugin\\'s own writes never take that path. With it off, every retrieval raises an approval prompt. Takes effect after a profile reload.',\n shelf: 'Memory shelf',\n shelfHint: 'Logging, consolidation and the session-start rules preload all read and write this shelf; when it is not default, each session is told to pass --shelf to its hypatia commands. Takes effect after a profile reload. Progress is kept per shelf, so switching back resumes where that shelf left off; on a new shelf, each session is logged from its start the next time it is active, and consolidated again (model calls). Choices come from hypatia list, refreshed about once a minute.',\n shelfLoading: 'Reading hypatia list…',\n shelfLoadFailed: 'Unable to load the shelf list.',\n shelfListingFailed: 'hypatia list failed; the list may be stale: {message}',\n shelfDisconnected: 'not connected',\n shelfOptionStatus: ' ({status})',\n shelfNotListed: 'not in hypatia list',\n shelfDisconnectedWarning: 'Shelf {shelf} is registered but not connected; writes will fail.',\n shelfNotListedWarning: 'hypatia has no shelf named {shelf}; writes will fail until you run hypatia connect <dir> --name {shelf}.',\n consolidationTitle: 'Consolidation candidate models',\n modelSelectionHint: 'Choose one or more models. Every consolidation attempt, including a retry, rotates through this order; without a selection, conversations continue logging but consolidation stays idle.',\n modelCatalogLoading: 'Loading available models…',\n modelCatalogFailed: 'Unable to load available models.',\n modelCatalogPartial: 'Some providers did not return a model catalog.',\n modelCatalogEmpty: 'No models are currently available.',\n selectedModels: 'Models used for rotation',\n unavailableModels: 'Unavailable or no longer advertised',\n modelUnavailable: 'Unavailable',\n retry: 'Retry',\n checkEveryTurns: 'Minimum turns between consolidations',\n minNewTokens: 'Min new tokens',\n cascadeBatchSize: 'Archive batch',\n dedupMaxDistance: 'Relation distance',\n cascadeHint: 'Every batch of same-tier summaries is archived into one entry a tier up. Relation distance is how near a new memory must be to an existing one to be worth judging a relationship.',\n limitsTitle: 'Per-run consolidation size',\n limitsHint: 'The input budget caps how much conversation is sent to the model (overflow keeps the most recent content); the output budget must fit the summary plus every work unit — too small and consolidation fails.',\n maxInputTokens: 'Input budget (tokens)',\n maxOutputTokens: 'Output budget (tokens)',\n maxWorkUnitsPerRun: 'Max work units per run',\n recallPreload: 'Recall: preload rules & taboos at session start',\n advancedHint:\n 'Advanced fields (binaries, collector caps, queue tuning) can be edited directly in settings.yaml under the {ns} key.',\n reset: 'Reset',\n discard: 'Discard',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'Save failed: {message}',\n readOnly: 'Read-only: settings document is not writable in this context.',\n unsaved: 'Unsaved',\n viewMemory: 'Memory',\n memoryTitle: 'This session\\'s memory',\n memoryUpdatedAt: 'State updated {time}',\n memoryRefresh: 'Refresh',\n memoryLoading: 'Reading memory status…',\n memoryNoSnapshot: 'The plugin has not published a status snapshot yet. Enable it, finish a turn, and come back.',\n memoryLoadFailed: 'Unable to read memory status: {message}',\n memoryUnknown: 'This session has no memory record yet. Logging starts once the first turn ends.',\n memoryLogged: 'Conversation log',\n memorySeqValue: 'event {seq}',\n memoryConsolidated: 'Summarisation',\n memoryCaughtUp: 'caught up',\n memoryBehind: '{behind} events behind the log',\n memoryPending: 'Waiting to summarise',\n memoryPendingValue: '~{tokens} tokens',\n memorySessionNode: 'Session node',\n memorySessionNodeYes: 'created',\n memorySessionNodeNo: 'not created (the Host supplied no session summary)',\n memoryBelongTo: 'Linked messages',\n memoryBelongToValue: '{count}',\n memoryDeferred: 'Tasks waiting for the session to load',\n memoryFailedTitle: 'Failed tasks',\n memoryFailedItem: '{kind} failed {attempts} times',\n memoryContentTitle: 'Memory content',\n memoryContentFailed: 'Unable to read memory content from the shelf: {message}',\n memorySummariesTitle: 'Span summaries',\n memoryWorkUnitsTitle: 'Work units',\n memoryNoSummaries: 'This session has produced no summary yet. They appear here once consolidation runs.',\n memoryNoWorkUnits: 'This session has yielded no work units yet.',\n memoryCount: 'showing {shown} of {total}',\n memoryTier: 'tier {level}',\n memoryWorkUnit: 'work unit',\n memoryEntryExpand: 'Expand',\n memoryEntryCollapse: 'Collapse',\n memoryEntryEmpty: 'This entry has no body, or it exceeded the display cap.',\n memoryCopyCode: 'Copy',\n memoryCopiedCode: 'Copied',\n memoryFootnotes: 'Footnotes',\n memoryTruncated: 'Content exceeded the display cap: earlier entries or over-long bodies were cut.',\n memoryHint: 'Diagnostic view: raw msg-* conversation text is not shown here — ask the agent to retrieve it through hypatia. Status is re-read every 5 seconds; the timestamp is when the Host last saw that state change (the first read counts as one), so an unchanged one means nothing new happened. Both counts index the session log\\'s event sequence (tool calls included, not messages), so their difference is what is left to summarise.',\n} satisfies Record<AutoMemoryLocaleKey, string>\n","/**\n * Settings card for the `hypatia-auto-memory` namespace.\n *\n * The card owns its disclosure state and stages edits until Save. Its visual\n * treatment mirrors the DSH plugin-settings cards while remaining bundle-local.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, IconChevronDownOutline14, Input } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n consolidationModelCandidates,\n consolidationModelKey,\n type ConsolidationModelCandidate,\n type ConsolidationModelRoute,\n type LoadConsolidationModelCatalog,\n} from './consolidation-models'\nimport { DEFAULT_SHELF, shelfChoices, type LoadShelfInventory, type ShelfInfo } from './shelves'\nimport css from './SettingsCard.module.css'\nimport { NS } from './locales'\nimport './slot-contract'\n\nconst DEFAULT_CONSOLIDATION = {\n models: [] as ConsolidationModelRoute[],\n maxInputTokens: 16000,\n maxOutputTokens: 2000,\n timeoutMs: 120000,\n checkEveryTurns: 5,\n minNewTokens: 3000,\n maxWorkUnitsPerRun: 3,\n adjudicate: true,\n dedupMaxDistance: 0.45,\n cascade: { enabled: true, batchSize: 16 },\n}\n\nexport interface ConfigShape {\n enabled?: boolean\n autoApprove?: boolean\n shelf?: string\n consolidation?: typeof DEFAULT_CONSOLIDATION\n recall?: { preloadRulesTaboos?: boolean }\n}\n\nfunction getSnapshotValue<T>(scope: SettingsScope<T>): SettingsScopeSnapshot<T> {\n return scope.getSnapshot()\n}\n\nfunction subscribe(scope: SettingsScope<unknown>, cb: () => void) {\n return scope.subscribe(cb)\n}\n\nfunction sectionValue<T>(snap: SettingsScopeSnapshot<T>): T | undefined {\n return snap.value ?? (snap.base as T | undefined) ?? undefined\n}\n\nfunction useScopeValue<T>(scope: SettingsScope<T>) {\n const [snap, setSnap] = useState(() => getSnapshotValue(scope))\n useEffect(() => {\n setSnap(getSnapshotValue(scope))\n return subscribe(scope as SettingsScope<unknown>, () => setSnap(getSnapshotValue(scope)))\n }, [scope])\n const value = useMemo(() => sectionValue(snap), [snap])\n return { snap, value }\n}\n\nfunction same(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport type SettingsCardProps = {\n scope: SettingsScope<ConfigShape>\n loadModelCatalog: LoadConsolidationModelCatalog\n loadShelfInventory: LoadShelfInventory\n} & PropsLocale<typeof NS>\n\nexport function SettingsCard({ scope, loadModelCatalog, loadShelfInventory, t }: SettingsCardProps) {\n const { snap, value } = useScopeValue(scope)\n const disabled = !snap.writable\n const base = useMemo(() => (snap.base ?? {}) as ConfigShape, [snap.base])\n\n const resolved: ConfigShape = useMemo(() => (value ?? base ?? {\n enabled: true,\n autoApprove: true,\n shelf: DEFAULT_SHELF,\n consolidation: DEFAULT_CONSOLIDATION,\n recall: { preloadRulesTaboos: true },\n }), [value, base])\n\n const [draft, setDraft] = useState(resolved)\n const [open, setOpen] = useState(false)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [catalogStatus, setCatalogStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [catalogGroups, setCatalogGroups] = useState<Parameters<typeof consolidationModelCandidates>[0]>([])\n const [catalogPartial, setCatalogPartial] = useState(false)\n const catalogGeneration = useRef(0)\n const [shelfStatus, setShelfStatus] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle')\n const [shelves, setShelves] = useState<ShelfInfo[]>([])\n const [shelfListingError, setShelfListingError] = useState('')\n const shelfGeneration = useRef(0)\n\n useEffect(() => {\n setDraft(resolved)\n }, [resolved])\n\n const dirty = useMemo(() => !same(draft, resolved), [draft, resolved])\n const consolidation = draft.consolidation ?? DEFAULT_CONSOLIDATION\n const recall = draft.recall ?? { preloadRulesTaboos: true }\n const saveBlocked = disabled || !dirty || saving\n\n const updateConsolidation = useCallback((patch: Partial<typeof DEFAULT_CONSOLIDATION>) => {\n setDraft((prev) => ({\n ...prev,\n consolidation: { ...(prev.consolidation ?? DEFAULT_CONSOLIDATION), ...patch },\n }))\n }, [])\n\n const loadCatalog = useCallback(async () => {\n const generation = ++catalogGeneration.current\n setCatalogStatus('loading')\n setCatalogPartial(false)\n try {\n const catalog = await loadModelCatalog()\n if (generation !== catalogGeneration.current) return\n setCatalogGroups(catalog.groups)\n setCatalogPartial(catalog.partial)\n setCatalogStatus('ready')\n } catch {\n if (generation !== catalogGeneration.current) return\n setCatalogStatus('error')\n }\n }, [loadModelCatalog])\n\n useEffect(() => {\n if (!open) return\n void loadCatalog()\n return () => { catalogGeneration.current += 1 }\n }, [open, loadCatalog])\n\n const loadShelves = useCallback(async () => {\n const generation = ++shelfGeneration.current\n setShelfStatus('loading')\n try {\n const inventory = await loadShelfInventory()\n if (generation !== shelfGeneration.current) return\n setShelves(inventory.shelves)\n setShelfListingError(inventory.error)\n setShelfStatus('ready')\n } catch {\n if (generation !== shelfGeneration.current) return\n setShelfStatus('error')\n }\n }, [loadShelfInventory])\n\n useEffect(() => {\n if (!open) return\n void loadShelves()\n return () => { shelfGeneration.current += 1 }\n }, [open, loadShelves])\n\n const draftShelf = draft.shelf ?? DEFAULT_SHELF\n const baseShelf = base.shelf ?? DEFAULT_SHELF\n const choices = useMemo(\n () => shelfChoices(shelves, [draftShelf, resolved.shelf ?? DEFAULT_SHELF, baseShelf]),\n [shelves, draftShelf, resolved.shelf, baseShelf],\n )\n const chosen = choices.find(choice => choice.name === draftShelf)\n\n const candidates = useMemo(() => {\n const models = consolidation.models ?? []\n return consolidationModelCandidates(\n catalogGroups,\n models,\n new Set(models.map(consolidationModelKey)),\n )\n }, [catalogGroups, consolidation.models])\n\n const toggleModel = useCallback((candidate: ConsolidationModelCandidate) => {\n if (disabled || saving) return\n setDraft((current) => {\n const currentConsolidation = current.consolidation ?? DEFAULT_CONSOLIDATION\n const currentModels = currentConsolidation.models ?? []\n const key = consolidationModelKey(candidate)\n const selected = currentModels.some(route => consolidationModelKey(route) === key)\n const models = selected\n ? currentModels.filter(route => consolidationModelKey(route) !== key)\n : [...currentModels, { provider: candidate.provider, model: candidate.model }]\n return {\n ...current,\n consolidation: { ...currentConsolidation, models },\n }\n })\n }, [disabled, saving])\n\n const discard = useCallback(() => {\n setDraft(resolved)\n setError(null)\n }, [resolved])\n\n const save = useCallback(async () => {\n if (saveBlocked) return\n setSaving(true)\n setError(null)\n try {\n const tasks: Promise<void>[] = []\n if (!same(draft.enabled, resolved.enabled)) {\n tasks.push(scope.set('enabled', draft.enabled))\n }\n if (!same(draft.autoApprove, resolved.autoApprove)) {\n tasks.push(scope.set('autoApprove', draft.autoApprove))\n }\n if (!same(draft.shelf, resolved.shelf)) {\n tasks.push(scope.set('shelf', draft.shelf))\n }\n if (!same(draft.consolidation, resolved.consolidation)) {\n tasks.push(scope.set('consolidation', draft.consolidation))\n }\n if (!same(draft.recall, resolved.recall)) {\n tasks.push(scope.set('recall', draft.recall))\n }\n await Promise.all(tasks)\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console\n console.error(`[${NS}] save failed:`, err)\n setError(message)\n } finally {\n setSaving(false)\n }\n }, [draft, resolved, saveBlocked, scope])\n\n if (snap.status === 'loading') {\n return <li className={css.status}>{t('loading', { ns: NS })}</li>\n }\n if (snap.status === 'unavailable') {\n return <li className={css.status}>{t('unavailable', { ns: NS })}</li>\n }\n\n const availableGroups = new Map<string, {\n providerName: string\n candidates: ConsolidationModelCandidate[]\n }>()\n const unavailable: ConsolidationModelCandidate[] = []\n for (const candidate of candidates) {\n if (!candidate.available) {\n unavailable.push(candidate)\n continue\n }\n const group = availableGroups.get(candidate.provider)\n if (group === undefined) {\n availableGroups.set(candidate.provider, {\n providerName: candidate.providerName,\n candidates: [candidate],\n })\n } else {\n group.candidates.push(candidate)\n }\n }\n\n const renderCandidate = (candidate: ConsolidationModelCandidate) => (\n <label key={candidate.key} className={css.model}>\n <input\n type=\"checkbox\"\n checked={candidate.selected}\n disabled={disabled || saving}\n onChange={() => toggleModel(candidate)}\n />\n <span>\n <span className={css.modelName}>{candidate.modelName}</span>\n <span className={css.route}>{`${candidate.providerName} · ${candidate.provider}/${candidate.model}`}</span>\n </span>\n {!candidate.available ? <span className={css.unavailable}>{t('modelUnavailable')}</span> : null}\n </label>\n )\n\n return (\n <li className={`${css.card} ${open ? css.cardOpen : ''}`}>\n <button\n type=\"button\"\n className={css.header}\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}\n <IconChevronDownOutline14 className={`${css.chevron} ${open ? css.chevronOpen : ''}`} />\n </button>\n\n {open ? (\n <div className={css.body}>\n {!snap.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-enabled\">{t('enable')}</label>\n {draft.enabled !== (base.enabled ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: base.enabled ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-enabled\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.enabled ?? true}\n aria-label={t('enable')}\n className={`${css.switch} ${draft.enabled ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, enabled: !(current.enabled ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-autoApprove\">{t('autoApprove')}</label>\n {(draft.autoApprove ?? true) !== (base.autoApprove ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: base.autoApprove ?? true }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-autoApprove\"\n type=\"button\"\n role=\"switch\"\n aria-checked={draft.autoApprove ?? true}\n aria-label={t('autoApprove')}\n className={`${css.switch} ${draft.autoApprove ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, autoApprove: !(current.autoApprove ?? true) }))}\n >\n <span className={css.switchThumb} />\n </button>\n <p className={css.hint}>{t('autoApproveHint')}</p>\n </div>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-shelf\">{t('shelf')}</label>\n {draftShelf !== baseShelf ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({ ...current, shelf: baseShelf }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <select\n id=\"ham-shelf\"\n className={css.select}\n value={draftShelf}\n disabled={disabled || saving}\n onChange={(event) => {\n const shelf = event.target.value\n setDraft((current) => ({ ...current, shelf }))\n }}\n >\n {choices.map(choice => (\n <option key={choice.name} value={choice.name}>\n {choice.name}\n {choice.path !== '' ? ` — ${choice.path}` : ''}\n {!choice.listed\n ? t('shelfOptionStatus', { status: t('shelfNotListed') })\n : !choice.connected ? t('shelfOptionStatus', { status: t('shelfDisconnected') }) : ''}\n </option>\n ))}\n </select>\n {shelfStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('shelfLoading')}</p> : null}\n {shelfStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('shelfLoadFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadShelves() }}>{t('retry')}</button>\n </div>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError !== '' ? (\n <p className={css.notice} role=\"status\">{t('shelfListingFailed', { message: shelfListingError })}</p>\n ) : null}\n {shelfStatus === 'ready' && shelfListingError === '' && chosen !== undefined && (!chosen.listed || !chosen.connected) ? (\n <p className={css.warning} role=\"status\">{t(chosen.listed ? 'shelfDisconnectedWarning' : 'shelfNotListedWarning', { shelf: chosen.name })}</p>\n ) : null}\n <p className={css.hint}>{t('shelfHint')}</p>\n </div>\n\n <section className={css.group} aria-labelledby=\"ham-consolidation-title\">\n <h3 id=\"ham-consolidation-title\" className={css.groupTitle}>{t('consolidationTitle')}</h3>\n <p className={css.hint}>{t('modelSelectionHint')}</p>\n\n <div className={css.modelSelection}>\n {catalogStatus === 'loading' ? <p className={css.notice} role=\"status\">{t('modelCatalogLoading')}</p> : null}\n {catalogStatus === 'error' ? (\n <div className={css.catalogError} role=\"alert\">\n <span>{t('modelCatalogFailed')}</span>\n <button type=\"button\" disabled={saving} onClick={() => { void loadCatalog() }}>{t('retry')}</button>\n </div>\n ) : null}\n {catalogPartial ? <p className={css.notice}>{t('modelCatalogPartial')}</p> : null}\n {candidates.length > 0 ? (\n <fieldset className={css.models}>\n <legend>{t('selectedModels')}</legend>\n {[...availableGroups].map(([provider, group]) => (\n <div key={provider} className={css.modelGroup}>\n <div className={css.providerName}>{group.providerName}</div>\n {group.candidates.map(renderCandidate)}\n </div>\n ))}\n {unavailable.length > 0 ? (\n <div className={css.modelGroup}>\n <div className={css.providerName}>{t('unavailableModels')}</div>\n {unavailable.map(renderCandidate)}\n </div>\n ) : null}\n </fieldset>\n ) : catalogStatus === 'ready' ? <p className={css.notice}>{t('modelCatalogEmpty')}</p> : null}\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-checkEveryTurns\">{t('checkEveryTurns')}</label>\n {consolidation.checkEveryTurns !== (base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ checkEveryTurns: base.consolidation?.checkEveryTurns ?? DEFAULT_CONSOLIDATION.checkEveryTurns })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-checkEveryTurns\"\n className={css.input}\n type=\"number\"\n min={1}\n value={consolidation.checkEveryTurns}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ checkEveryTurns: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-minNewTokens\">{t('minNewTokens')}</label>\n {consolidation.minNewTokens !== (base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ minNewTokens: base.consolidation?.minNewTokens ?? DEFAULT_CONSOLIDATION.minNewTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-minNewTokens\"\n className={css.input}\n type=\"number\"\n min={0}\n value={consolidation.minNewTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ minNewTokens: Number(event.target.value) })}\n />\n </div>\n </div>\n\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-cascadeBatchSize\">{t('cascadeBatchSize')}</label>\n {(consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize)\n !== (base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: base.consolidation?.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize,\n },\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-cascadeBatchSize\"\n className={css.input}\n type=\"number\"\n min={2}\n value={consolidation.cascade?.batchSize ?? DEFAULT_CONSOLIDATION.cascade.batchSize}\n disabled={disabled}\n onChange={(event) => updateConsolidation({\n cascade: {\n ...(consolidation.cascade ?? DEFAULT_CONSOLIDATION.cascade),\n batchSize: Number(event.target.value),\n },\n })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-dedupMaxDistance\">{t('dedupMaxDistance')}</label>\n {(consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance)\n !== (base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({\n dedupMaxDistance: base.consolidation?.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance,\n })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-dedupMaxDistance\"\n className={css.input}\n type=\"number\"\n min={0}\n step={0.05}\n value={consolidation.dedupMaxDistance ?? DEFAULT_CONSOLIDATION.dedupMaxDistance}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ dedupMaxDistance: Number(event.target.value) })}\n />\n </div>\n </div>\n <p className={css.hint}>{t('cascadeHint')}</p>\n\n <h4 className={css.limitsTitle}>{t('limitsTitle')}</h4>\n <p className={css.hint}>{t('limitsHint')}</p>\n <div className={css.pairedFields}>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxInputTokens\">{t('maxInputTokens')}</label>\n {consolidation.maxInputTokens !== (base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxInputTokens: base.consolidation?.maxInputTokens ?? DEFAULT_CONSOLIDATION.maxInputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxInputTokens\"\n className={css.input}\n type=\"number\"\n min={1000}\n step={1000}\n value={consolidation.maxInputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxInputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxOutputTokens\">{t('maxOutputTokens')}</label>\n {consolidation.maxOutputTokens !== (base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxOutputTokens: base.consolidation?.maxOutputTokens ?? DEFAULT_CONSOLIDATION.maxOutputTokens })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxOutputTokens\"\n className={css.input}\n type=\"number\"\n min={200}\n step={200}\n value={consolidation.maxOutputTokens}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxOutputTokens: Number(event.target.value) })}\n />\n </div>\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-maxWorkUnitsPerRun\">{t('maxWorkUnitsPerRun')}</label>\n {consolidation.maxWorkUnitsPerRun !== (base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => updateConsolidation({ maxWorkUnitsPerRun: base.consolidation?.maxWorkUnitsPerRun ?? DEFAULT_CONSOLIDATION.maxWorkUnitsPerRun })}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <Input\n id=\"ham-maxWorkUnitsPerRun\"\n className={css.input}\n type=\"number\"\n min={1}\n max={10}\n value={consolidation.maxWorkUnitsPerRun}\n disabled={disabled}\n onChange={(event) => updateConsolidation({ maxWorkUnitsPerRun: Number(event.target.value) })}\n />\n </div>\n </div>\n </section>\n\n <div className={css.field}>\n <div className={css.fieldHead}>\n <label className={css.label} htmlFor=\"ham-preloadRulesTaboos\">{t('recallPreload')}</label>\n {(recall.preloadRulesTaboos ?? true) !== (base.recall?.preloadRulesTaboos ?? true) ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: base.recall?.preloadRulesTaboos ?? true,\n },\n }))}\n >\n {t('reset')}\n </button>\n ) : null}\n </div>\n <button\n id=\"ham-preloadRulesTaboos\"\n type=\"button\"\n role=\"switch\"\n aria-checked={recall.preloadRulesTaboos ?? true}\n aria-label={t('recallPreload')}\n className={`${css.switch} ${recall.preloadRulesTaboos ?? true ? css.switchOn : ''}`}\n disabled={disabled}\n onClick={() => setDraft((current) => ({\n ...current,\n recall: {\n ...(current.recall ?? { preloadRulesTaboos: true }),\n preloadRulesTaboos: !(current.recall?.preloadRulesTaboos ?? true),\n },\n }))}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n\n <p className={css.advancedHint}>{t('advancedHint', { ns: NS })}</p>\n {error ? <p className={css.error} role=\"status\">{t('saveFailed', { message: error })}</p> : null}\n\n <div className={css.footer}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!dirty || saving}\n onClick={discard}\n >\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={saveBlocked}\n onClick={save}\n >\n {saving ? t('saving') : t('save')}\n </Button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n","/**\n * The Memory tab's read side: one same-origin request per refresh.\n *\n * The Host half serves it from `/api/dsh-hypatia-auto-memory/session`\n * (see `src/memory-api.js`), which is parameterized by session and authenticates\n * itself — unlike a settings namespace, it can answer for the one session the\n * tab is bound to instead of shipping every session's state to the browser.\n *\n * Zero runtime imports beyond `fetch`, so the parsing half is unit-tested under\n * `node:test` like `shelves.ts`.\n */\n\n/** Route prefix the Host claims; the tab appends `/session`. */\nexport const MEMORY_API_PREFIX = '/api/dsh-hypatia-auto-memory'\n\n/** One task that exhausted its attempts. */\nexport interface FailedMemoryTask {\n kind: string\n sessionId: string\n attempts: number\n error: string\n}\n\n/** What the Host derived for one session out of the state tables. */\nexport interface SessionMemoryStatus {\n sessionId: string\n /** False when the Host has no row and no task for this session yet. */\n known: boolean\n loggedSeq: number\n consolidatedSeq: number\n /** True when consolidation has covered everything logged. */\n caughtUp: boolean\n pendingTokens: number\n sessionNode: boolean\n belongTo: number\n deferred: number\n failed: number\n failedTasks: FailedMemoryTask[]\n error: string\n}\n\n/** One distilled entry: a span summary or a work unit. */\nexport interface MemoryEntry {\n name: string\n /** Markdown body, already capped by the Host. */\n markdown: string\n /** Archive tier, summaries only; 1 condenses messages. */\n level: number\n createdAt: string\n}\n\n/**\n * The shelf half of a response.\n *\n * Kept as one object rather than spread across the payload so \"the Host did not\n * read the shelf\" is representable: the five-second poll asks for status only,\n * and a reader that cannot tell that apart from \"the shelf is empty\" wipes the\n * content it already showed.\n */\nexport interface MemoryContent {\n summaries: MemoryEntry[]\n workUnits: MemoryEntry[]\n /** How many the shelf holds, before the response caps. */\n summaryCount: number\n workUnitCount: number\n /** True when a cap dropped entries or cut a body short. */\n truncated: boolean\n /** Non-empty when the shelf could not be read; the status half is still valid. */\n error: string\n}\n\n/** One response from the Host. */\nexport interface MemoryPayload {\n session: SessionMemoryStatus\n /** Epoch milliseconds the Host last saw this session's status change. */\n updatedAt: number\n /** Absent when this response carried status only. */\n content: MemoryContent | undefined\n}\n\n/** Read one session's memory. `content` also asks the Host to read the shelf. */\nexport type FetchMemory = (sessionId: string, options: { content: boolean }) => Promise<MemoryPayload>\n\n/**\n * The URL one refresh reads.\n * @param sessionId - the session the tab is bound to.\n * @param content - whether to ask the Host to read the shelf as well.\n * @returns a same-origin path with its query.\n */\nexport function memoryUrl(sessionId: string, content: boolean): string {\n const query = new URLSearchParams({ session: sessionId })\n if (content) query.set('content', '1')\n return `${MEMORY_API_PREFIX}/session?${query.toString()}`\n}\n\n/** Fetch one session's memory from the Host. */\nexport const fetchMemory: FetchMemory = async (sessionId, { content }) => {\n const response = await fetch(memoryUrl(sessionId, content), {\n method: 'GET',\n credentials: 'same-origin',\n headers: { accept: 'application/json' },\n })\n const body: unknown = await response.json().catch(() => undefined)\n if (!response.ok) {\n const message = isRecord(body) && typeof body.error === 'string' ? body.error : `HTTP ${String(response.status)}`\n throw new Error(message)\n }\n const payload = parseMemoryPayload(body, sessionId)\n if (payload === undefined) throw new Error('the Host returned an unreadable memory payload')\n return payload\n}\n\n/**\n * Session-log events that are recorded but not yet consolidated.\n *\n * Both watermarks index the same log, so their difference is exactly the work\n * consolidation still owes. Clamped at zero: a consolidation run may cover a\n * range the logging watermark has not caught up to yet, which is not a backlog.\n *\n * @param session - the session half of a payload.\n * @returns the gap in session-log events.\n */\nexport function consolidationGap(session: SessionMemoryStatus): number {\n return Math.max(0, session.loggedSeq - session.consolidatedSeq)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction num(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value : ''\n}\n\nfunction parseFailedTasks(value: unknown): FailedMemoryTask[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): FailedMemoryTask[] => isRecord(entry)\n ? [{\n kind: str(entry.kind),\n sessionId: str(entry.sessionId),\n attempts: num(entry.attempts),\n error: str(entry.error),\n }]\n : [])\n}\n\nfunction parseEntries(value: unknown): MemoryEntry[] {\n if (!Array.isArray(value)) return []\n return value.flatMap((entry): MemoryEntry[] => {\n if (!isRecord(entry)) return []\n const name = str(entry.name)\n if (name === '') return []\n return [{\n name,\n markdown: str(entry.markdown),\n level: num(entry.level) || 1,\n createdAt: str(entry.createdAt),\n }]\n })\n}\n\n/**\n * Read the Host's answer into the tab's shape, defensively.\n *\n * A malformed field falls back to its zero value rather than reaching the DOM;\n * a payload with no usable `session` is rejected outright, because rendering a\n * panel of zeros for a session the Host never answered about would be a lie.\n *\n * A status-only answer parses to `content: undefined` — never to empty lists,\n * which is what made the five-second poll erase the shelf content. The Host also\n * states which half it sent (`content`), and that flag is what this prefers; the\n * key sniffing beside it keeps a bundle built after the flag from misreading a\n * Host that predates it, so the fix does not need a profile restart to land.\n *\n * @param value - the parsed response body.\n * @param sessionId - the session that was asked for.\n * @returns the payload, or undefined when the body is not one.\n */\nexport function parseMemoryPayload(value: unknown, sessionId: string): MemoryPayload | undefined {\n if (!isRecord(value) || !isRecord(value.session)) return undefined\n const session = value.session\n const carried = value.content === true\n || Object.hasOwn(value, 'summaries')\n || Object.hasOwn(value, 'contentError')\n return {\n session: {\n sessionId: str(session.sessionId) || sessionId,\n known: session.known === true,\n loggedSeq: num(session.loggedSeq),\n consolidatedSeq: num(session.consolidatedSeq),\n caughtUp: session.caughtUp === true,\n pendingTokens: num(session.pendingTokens),\n sessionNode: session.sessionNode === true,\n belongTo: num(session.belongTo),\n deferred: num(session.deferred),\n failed: num(session.failed),\n failedTasks: parseFailedTasks(session.failedTasks),\n error: str(session.error),\n },\n updatedAt: num(value.updatedAt),\n content: carried\n ? {\n summaries: parseEntries(value.summaries),\n workUnits: parseEntries(value.workUnits),\n summaryCount: num(value.summaryCount),\n workUnitCount: num(value.workUnitCount),\n truncated: value.truncated === true,\n error: str(value.contentError),\n }\n : undefined,\n }\n}\n\n/**\n * Fold a new answer onto the one on screen.\n *\n * Status is always the newest. Content is only replaced by an answer that\n * carried content, so the poll cannot erase it. An answer whose shelf read\n * failed keeps the content already shown — entries, counts and the truncation\n * flag together, so the header still describes the list under it — and records\n * the error beside it, because a transient hypatia failure should not blank\n * what the reader was looking at.\n *\n * @param previous - the payload on screen, if any.\n * @param next - the answer just parsed.\n * @returns the payload to render.\n */\nexport function mergeMemory(\n previous: MemoryPayload | undefined,\n next: MemoryPayload,\n): MemoryPayload {\n if (next.content === undefined) return { ...next, content: previous?.content }\n // A failed read keeps whatever was on screen — the entries AND the counts that\n // describe them — and replaces only the reason. The guard must not consult the\n // previous error: on the SECOND consecutive failure it is already set, and\n // testing for it fell through to the zeroed answer, blanking the panel the\n // first failure had deliberately preserved.\n if (next.content.error !== '' && previous?.content !== undefined) {\n return { ...next, content: { ...previous.content, error: next.content.error } }\n }\n return next\n}\n","/**\n * The conversation's Memory tab: what this session has been remembered as, what\n * it was remembered into, and what is stuck.\n *\n * Three sections, in the order a reader wants them: the pipeline's status\n * (watermarks, backlog, failures), then the span summaries consolidation\n * produced, then the work units derived from them. Bodies render through the\n * shell's own `MarkdownText`, so a summary reads exactly like assistant Markdown\n * elsewhere in the GUI and costs no bundle weight.\n *\n * Raw `msg-*` entries are deliberately absent: they hold the conversation\n * verbatim, the reader just wrote them, and the agent is the right reader for\n * them (see `src/memory-api.js` for the same rule on the Host side).\n *\n * Status is polled; content is fetched only when it can have changed — on mount,\n * on a session switch, on a manual refresh, and whenever consolidation advances\n * the session's watermark. Reading the shelf costs hypatia round trips, and\n * consolidation is the only thing that changes it.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n consolidationGap,\n mergeMemory,\n type FetchMemory,\n type MemoryEntry,\n type MemoryPayload,\n} from './memory-client'\nimport { NS } from './locales'\nimport css from './MemoryView.module.css'\nimport './slot-contract'\n\n/** How often the tab re-reads the status half while it is on screen. */\nconst POLL_MS = 5000\n\nexport type MemoryViewProps = {\n /** The session this tab is bound to; supplied by the session-scoped slot. */\n sessionId: string\n fetch: FetchMemory\n} & PropsLocale<typeof NS>\n\n/** Local wall-clock stamp for the freshness line. */\nfunction formatTime(epochMs: number): string {\n if (!Number.isFinite(epochMs) || epochMs <= 0) return '—'\n return new Date(epochMs).toLocaleTimeString()\n}\n\n/**\n * hypatia stamps `created_at` as `YYYY-MM-DD HH:MM:SS.ffffff`; the microseconds\n * are noise in a row that is 11px tall, so the tab shows down to the minute.\n * Slice rather than `new Date`: the space-separated form is not the ISO shape\n * every engine is required to parse.\n */\nfunction formatEntryTime(stamp: string): string {\n return stamp.length >= 16 ? stamp.slice(0, 16).replace('T', ' ') : stamp\n}\n\n/** The first non-empty line of a body, for a collapsed row's preview. */\nfunction firstLine(markdown: string): string {\n for (const line of markdown.split('\\n')) {\n const trimmed = line.replace(/^[#>\\-*\\s]+/, '').trim()\n if (trimmed !== '') return trimmed\n }\n return ''\n}\n\n/** One collapsible distilled entry. */\nfunction Entry({ entry, badge, open, onToggle, labels, t }: {\n entry: MemoryEntry\n badge: string\n open: boolean\n onToggle: () => void\n labels: { code: { copyLabel: string; copiedLabel: string }; footnotes: string }\n t: MemoryViewProps['t']\n}) {\n return (\n <li className={css.entry}>\n <button type=\"button\" className={css.entryHead} aria-expanded={open} onClick={onToggle}>\n <span className={css.entryName}>{entry.name}</span>\n <span className={css.entryMeta}>\n <span className={css.badge}>{badge}</span>\n {entry.createdAt !== '' ? <span className={css.entryTime}>{formatEntryTime(entry.createdAt)}</span> : null}\n <span className={css.entryToggle}>{open ? t('memoryEntryCollapse') : t('memoryEntryExpand')}</span>\n </span>\n </button>\n {open\n ? (\n <div className={css.entryBody}>\n {entry.markdown === ''\n ? <p className={css.status}>{t('memoryEntryEmpty')}</p>\n : <MarkdownText text={entry.markdown} labels={labels} />}\n </div>\n )\n : <p className={css.entryPreview}>{firstLine(entry.markdown)}</p>}\n </li>\n )\n}\n\nexport function MemoryView({ sessionId, fetch, t }: MemoryViewProps) {\n const [payload, setPayload] = useState<MemoryPayload | undefined>(undefined)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState('')\n /**\n * The entries the reader opened, by name. Absent means closed, which is the\n * default: a toggle survives the poll that replaces the payload, and an entry\n * a later poll adds starts closed rather than inheriting a neighbour's state.\n */\n const [overrides, setOverrides] = useState<Readonly<Record<string, boolean>>>({})\n /** The watermark whose content is already in hand, so a poll never re-reads it. */\n const [contentAt, setContentAt] = useState<number | undefined>(undefined)\n\n const copyLabel = t('memoryCopyCode')\n const copiedLabel = t('memoryCopiedCode')\n const footnotes = t('memoryFootnotes')\n // MarkdownText caches its render against the labels identity, so this must be\n // one object per locale, not a fresh one per render.\n const labels = useMemo(\n () => ({ code: { copyLabel, copiedLabel }, footnotes }),\n [copyLabel, copiedLabel, footnotes],\n )\n\n /**\n * The session the tab is showing now. A request outlives the session it was\n * made for — a slow shelf read, or a poll already in flight at a switch — and\n * its answer must be dropped rather than folded into the next session's view.\n */\n const activeSession = useRef(sessionId)\n\n const load = useCallback(async (content: boolean) => {\n const current = () => activeSession.current === sessionId\n try {\n const next = await fetch(sessionId, { content })\n if (!current()) return\n // Folded, not assigned: a status-only poll must not erase the shelf\n // content it did not ask for (see `mergeMemory`).\n setPayload((previous) => mergeMemory(previous, next))\n setError('')\n if (content) setContentAt(next.session.consolidatedSeq)\n } catch (failure) {\n if (!current()) return\n setError(failure instanceof Error ? failure.message : String(failure))\n } finally {\n if (current()) setLoading(false)\n }\n }, [fetch, sessionId])\n\n // A session switch starts over: the previous session's content and the\n // previous session's collapsed rows must not leak into this one.\n useEffect(() => {\n activeSession.current = sessionId\n setPayload(undefined)\n setOverrides({})\n setContentAt(undefined)\n setLoading(true)\n void load(true)\n }, [load, sessionId])\n\n useEffect(() => {\n const timer = setInterval(() => {\n // A hidden tab has nobody reading it; the panel is a snapshot, not a stream.\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return\n void load(false)\n }, POLL_MS)\n return () => clearInterval(timer)\n }, [load])\n\n // Consolidation is the only thing that changes the shelf, so a watermark that\n // moved is the signal to read it again.\n useEffect(() => {\n const at = payload?.session.consolidatedSeq\n if (at === undefined || contentAt === undefined) return\n if (at !== contentAt) void load(true)\n }, [payload?.session.consolidatedSeq, contentAt, load])\n\n const toggle = useCallback((name: string, open: boolean) => {\n setOverrides((current) => ({ ...current, [name]: !open }))\n }, [])\n\n const session = payload?.session\n const content = payload?.content\n const summaries = content?.summaries ?? []\n const workUnits = content?.workUnits ?? []\n\n // Every entry starts closed and previews its first line: the list stays\n // scannable at any length, and the bodies are one click away. `overrides`\n // holds what the reader opened, so a poll that replaces the payload does not\n // close it again.\n const renderEntries = (entries: MemoryEntry[], kind: 'summary' | 'workUnit') => (\n <ul className={css.entries}>\n {entries.map((entry) => {\n const open = overrides[entry.name] === true\n return (\n <Entry\n key={entry.name}\n entry={entry}\n badge={kind === 'summary' ? t('memoryTier', { level: String(entry.level) }) : t('memoryWorkUnit')}\n open={open}\n onToggle={() => toggle(entry.name, open)}\n labels={labels}\n t={t}\n />\n )\n })}\n </ul>\n )\n\n return (\n // Opts into the composer overlay the way the trajectory ledger does: the\n // view owns its scroller and gets the full height, with the composer\n // floating over it. Without the marker the Conversation shell seats the\n // composer below a short panel instead.\n <div className={css.panel} data-conversation-composer-overlay=\"\">\n <div className={css.column}>\n <header className={css.head}>\n <h2 className={css.title}>{t('memoryTitle')}</h2>\n <div className={css.headMeta}>\n <span className={css.updated}>{t('memoryUpdatedAt', { time: formatTime(payload?.updatedAt ?? 0) })}</span>\n <button type=\"button\" className={css.refresh} onClick={() => { void load(true) }}>\n {t('memoryRefresh')}\n </button>\n </div>\n </header>\n\n {error !== '' ? <p className={css.error} role=\"status\">{t('memoryLoadFailed', { message: error })}</p> : null}\n\n {loading && payload === undefined\n ? <p className={css.status}>{t('memoryLoading')}</p>\n : session === undefined\n ? <p className={css.status}>{t('memoryNoSnapshot')}</p>\n : !session.known\n ? <p className={css.status}>{t('memoryUnknown')}</p>\n : (\n <section className={css.group} aria-label={t('memoryTitle')}>\n <dl className={css.rows}>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryLogged')}</dt>\n <dd className={css.value}>{t('memorySeqValue', { seq: String(session.loggedSeq) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryConsolidated')}</dt>\n <dd className={css.value}>\n {t('memorySeqValue', { seq: String(session.consolidatedSeq) })}\n {/* Quantified, not a bare \"pending\": a reader has to know HOW\n far behind to judge whether to wait. */}\n <span className={session.caughtUp ? css.calm : css.busy}>\n {session.caughtUp\n ? t('memoryCaughtUp')\n : t('memoryBehind', { behind: String(consolidationGap(session)) })}\n </span>\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryPending')}</dt>\n <dd className={css.value}>{t('memoryPendingValue', { tokens: String(session.pendingTokens) })}</dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memorySessionNode')}</dt>\n <dd className={css.value}>\n {session.sessionNode ? t('memorySessionNodeYes') : t('memorySessionNodeNo')}\n </dd>\n </div>\n <div className={css.row}>\n <dt className={css.label}>{t('memoryBelongTo')}</dt>\n <dd className={css.value}>{t('memoryBelongToValue', { count: String(session.belongTo) })}</dd>\n </div>\n {session.deferred > 0 ? (\n <div className={css.row}>\n <dt className={css.label}>{t('memoryDeferred')}</dt>\n <dd className={css.value}>{String(session.deferred)}</dd>\n </div>\n ) : null}\n </dl>\n </section>\n )}\n\n {session !== undefined && (session.failed > 0 || session.failedTasks.length > 0) ? (\n <section className={css.group} aria-label={t('memoryFailedTitle')}>\n <h3 className={css.groupTitle}>{t('memoryFailedTitle')}</h3>\n <ul className={css.failures}>\n {session.failedTasks.map((task, index) => (\n <li key={`${task.kind}-${String(index)}`} className={css.failure}>\n <span className={css.failureKind}>\n {t('memoryFailedItem', { kind: task.kind, attempts: String(task.attempts) })}\n </span>\n {task.error !== '' ? <span className={css.failureError}>{task.error}</span> : null}\n </li>\n ))}\n {session.failedTasks.length === 0 ? <li className={css.failure}>{session.error}</li> : null}\n </ul>\n </section>\n ) : null}\n\n {content !== undefined && content.error !== '' ? (\n <section className={css.group} aria-label={t('memoryContentTitle')}>\n <h3 className={css.groupTitle}>{t('memoryContentTitle')}</h3>\n <p className={css.error} role=\"status\">{t('memoryContentFailed', { message: content.error })}</p>\n </section>\n ) : null}\n\n {content !== undefined ? (\n <>\n <section className={css.group} aria-label={t('memorySummariesTitle')}>\n <h3 className={css.groupTitle}>\n {t('memorySummariesTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(summaries.length), total: String(content.summaryCount) })}\n </span>\n </h3>\n {summaries.length === 0\n ? <p className={css.status}>{t('memoryNoSummaries')}</p>\n : renderEntries(summaries, 'summary')}\n </section>\n\n <section className={css.group} aria-label={t('memoryWorkUnitsTitle')}>\n <h3 className={css.groupTitle}>\n {t('memoryWorkUnitsTitle')}\n <span className={css.count}>\n {t('memoryCount', { shown: String(workUnits.length), total: String(content.workUnitCount) })}\n </span>\n </h3>\n {workUnits.length === 0\n ? <p className={css.status}>{t('memoryNoWorkUnits')}</p>\n : renderEntries(workUnits, 'workUnit')}\n </section>\n\n {content.truncated ? <p className={css.hint}>{t('memoryTruncated')}</p> : null}\n <p className={css.hint}>{t('memoryHint')}</p>\n </>\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * Browser half of dsh-hypatia-auto-memory: contributes a settings card under\n * Settings → Plugins, keyed by the `hypatia-auto-memory` namespace, and a\n * per-session Memory tab beside the conversation's Chat and Trajectory tabs.\n *\n * The Host plugin already registers the schema and namespace; this half only\n * renders the form and routes edits through `ctx.settingsScope`. The Memory tab\n * reads the Host's read-only status namespace (see `src/memory-status.js`).\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { RemoteResult } from '@deepseek-ai/dsh-api-remotes/client'\nimport type { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsScopeBinder } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: the 'conversation.view' SlotMap row is declared by the conversation\n// shell, so the registration below only type-checks with its merge in the program.\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { createElement } from 'react'\nimport { SettingsCard } from './SettingsCard'\nimport type { ConfigShape } from './SettingsCard'\nimport type { LoadConsolidationModelCatalog } from './consolidation-models'\nimport { MemoryView } from './MemoryView'\nimport { fetchMemory } from './memory-client'\nimport { readShelfInventory, type LoadShelfInventory } from './shelves'\nimport { en, NS, zh } from './locales'\n\nconst APPLY_CLAIM = '__dshHypatiaAutoMemoryApplied'\n\n/**\n * The one settings-controller method this card calls. The remotes assembly\n * mounts the `settings` namespace at runtime, but its declaration merge lives\n * in `@deepseek-ai/dsh-api-settings-controller`, which this bundle does not\n * depend on for one method.\n */\ninterface SettingsDescribeRemote {\n describe(): Promise<RemoteResult<{ namespaces: readonly unknown[] }>>\n}\n\nfunction claimApply(): boolean {\n const scope = globalThis as Record<string, unknown>\n if (scope[APPLY_CLAIM] === true) return false\n scope[APPLY_CLAIM] = true\n return true\n}\n\nfunction releaseApply(): void {\n delete (globalThis as Record<string, unknown>)[APPLY_CLAIM]\n}\n\n/**\n * Required client services: settings, locale, slots, the Host model catalog,\n * and the settings descriptor. Each Remote namespace is its own service, so\n * `remote.settings` must be declared here or reading it throws.\n */\nexport const inject = ['slots', 'settingsScope', 'locale', 'remote', 'remote.session', 'remote.settings']\n\n/** Mount the browser half. */\nexport function apply(ctx: Context): void {\n if (!claimApply()) return\n\n const settingsScope = ctx.get('settingsScope') as SettingsScopeBinder\n const scope = settingsScope.bind<ConfigShape>({ namespace: NS })\n\n // Resolve through ctx.get with an explicit type rather than ctx.locale: the\n // locale package's cordis Context merge only applies when its types resolve\n // to the same cordis module identity, which is not guaranteed for an\n // npm-installed plugin (symlinked workspace checkouts diverge).\n const locale = ctx.get('locale') as unknown as LocaleRuntime\n ctx.effect(() => locale.register(NS, { zh, en }), 'dsh-hypatia-auto-memory: locale dictionaries')\n\n const loadModelCatalog: LoadConsolidationModelCatalog = async () => {\n const response = await ctx.remote.session.modelCatalog()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n return {\n groups: response.value.groups,\n partial: response.value.failures.length > 0,\n }\n }\n // The Host re-publishes `hypatia list` as a settings namespace no card\n // claims; the descriptor is the only wire path a plugin's Host half has.\n // Read directly rather than through the shared describe mirror: the mirror\n // re-reads only on document commits, and a re-registration is not one.\n const loadShelfInventory: LoadShelfInventory = async () => {\n const settings = (ctx.remote as unknown as { settings: SettingsDescribeRemote }).settings\n const response = await settings.describe()\n if (!response.ok) throw new Error(`${response.error.code}: ${response.error.message}`)\n const inventory = readShelfInventory(response.value.namespaces)\n if (inventory === undefined) throw new Error('the Host publishes no shelf listing')\n return inventory\n }\n const renderCard = (props: PropsLocale<typeof NS>) => createElement(SettingsCard, {\n scope,\n loadModelCatalog,\n loadShelfInventory,\n ...props,\n })\n const unregister = ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n { name: 'settings.plugin.item', key: NS, locale: NS },\n renderCard,\n ),\n )\n\n // The Memory tab's data: one same-origin request to the route this plugin's\n // Host half registers (see `src/memory-api.js`), parameterized by the session\n // the tab is bound to — which is why it is a route and not the settings\n // descriptor read the shelf listing uses.\n // The tab label reads through a bound translate so it follows the active\n // locale without re-registration, exactly as ui-trajectory's does.\n const t = locale.bind(NS)\n const unregisterMemoryView = ctx.slots.inject('conversation.view', () =>\n ctx.slots.register(\n {\n name: 'conversation.view',\n id: 'memory',\n // After Chat (0) and Trajectory (10).\n order: 20,\n locale: NS,\n label: () => t('viewMemory'),\n inject: () => ({ fetch: fetchMemory }),\n },\n MemoryView,\n ),\n )\n\n ctx.effect(() => () => {\n unregister()\n unregisterMemoryView()\n releaseApply()\n })\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-hypatia-auto-memory",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Event-driven Hypatia memory for DSH: automatic conversation logging via session events, queued background consolidation (span summaries + work-unit extraction) with a dedicated model route, and recall injection — zero per-call model work in the main session.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -59,8 +59,9 @@
59
59
  "@deepseek-ai/dsh-api-remotes": "^0.1.2-rc.1",
60
60
  "@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
61
61
  "@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
62
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
62
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-rc.1",
63
63
  "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
64
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
64
65
  "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-rc.1",
65
66
  "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-rc.1",
66
67
  "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
package/src/cascade.js CHANGED
@@ -22,6 +22,7 @@
22
22
  import { createHash } from 'node:crypto'
23
23
 
24
24
  import { PLUGIN_NAME } from './consolidator.js'
25
+ import { NULL_MODEL_LOG } from './model-log.js'
25
26
 
26
27
  /** Tag marking the tier an entry belongs to. */
27
28
  export function levelTag(level) {
@@ -80,9 +81,10 @@ function archiveInstruction(level, count) {
80
81
  * selectRoute: (routes: any) => any,
81
82
  * getConfig: () => any,
82
83
  * status: import('./status.js').StatusLog,
84
+ * modelLog?: ReturnType<import('./model-log.js').createModelLog>,
83
85
  * }} deps
84
86
  */
85
- export function createCascade({ cli, llm, selectRoute, getConfig, status }) {
87
+ export function createCascade({ cli, llm, selectRoute, getConfig, status, modelLog = NULL_MODEL_LOG }) {
86
88
  /**
87
89
  * Ask the model to archive one batch.
88
90
  * @returns {Promise<{title: string, summary: string} | undefined>}
@@ -93,8 +95,11 @@ export function createCascade({ cli, llm, selectRoute, getConfig, status }) {
93
95
  return `### ${i + 1}. ${row.name}\n${data}`
94
96
  }).join('\n\n')
95
97
 
98
+ const attempt = modelLog.begin('memory-cascade', route)
96
99
  const controller = new AbortController()
97
100
  const timer = setTimeout(() => controller.abort(), timeoutMs)
101
+ let outcome = 'incomplete'
102
+ let detail = ''
98
103
  try {
99
104
  const { createUserMessage, BlockAssembler } = await import('@deepseek-ai/dsh-llm')
100
105
  const assembler = new BlockAssembler()
@@ -112,18 +117,38 @@ export function createCascade({ cli, llm, selectRoute, getConfig, status }) {
112
117
  })) {
113
118
  assembler.push(chunk)
114
119
  }
115
- if (assembler.finish.kind !== 'stop') return undefined
120
+ if (assembler.finish.kind !== 'stop') {
121
+ detail = String(assembler.finish.kind)
122
+ return undefined
123
+ }
116
124
  const text = assembler.blocks().filter((b) => b.type === 'text').map((b) => b.text).join('\n').trim()
117
125
  const fence = /^```(?:json)?\s*([\s\S]*?)```\s*$/.exec(text)
118
- const parsed = JSON.parse(fence ? fence[1].trim() : text)
126
+ // Its own catch: a parse failure is an unusable reply, not a failed call,
127
+ // and Node's parse error quotes the reply's opening characters.
128
+ let parsed
129
+ try {
130
+ parsed = JSON.parse(fence ? fence[1].trim() : text)
131
+ } catch {
132
+ detail = 'unparseable reply'
133
+ return undefined
134
+ }
119
135
  const summary = typeof parsed?.summary === 'string' ? parsed.summary.trim() : ''
120
- if (summary === '') return undefined
136
+ if (summary === '') {
137
+ detail = 'no summary'
138
+ return undefined
139
+ }
121
140
  const title = typeof parsed?.title === 'string' && parsed.title.trim() !== ''
122
141
  ? parsed.title.trim()
123
142
  : `Archive tier ${level}`
143
+ outcome = 'ok'
124
144
  return { title, summary }
145
+ } catch (error) {
146
+ outcome = 'error'
147
+ detail = error instanceof Error ? error.message : String(error)
148
+ throw error
125
149
  } finally {
126
150
  clearTimeout(timer)
151
+ void attempt.finish(outcome, detail)
127
152
  }
128
153
  }
129
154