Skip to content

【WIP】feat: implement LLM gateway, core service updates, and project restructuring#142

Open
miaobuao wants to merge 19 commits into
nutstore:mainfrom
miaobuao:feat/ns-llm-gateway
Open

【WIP】feat: implement LLM gateway, core service updates, and project restructuring#142
miaobuao wants to merge 19 commits into
nutstore:mainfrom
miaobuao:feat/ns-llm-gateway

Conversation

@miaobuao

@miaobuao miaobuao commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

@miaobuao miaobuao changed the title feat: implement LLM gateway, core service updates, and project restructuring 【WIP】feat: implement LLM gateway, core service updates, and project restructuring Jun 3, 2026
@miaobuao miaobuao force-pushed the feat/ns-llm-gateway branch 3 times, most recently from 1b67820 to 193fcd0 Compare June 22, 2026 04:06
miaobuao added 13 commits June 22, 2026 15:06
Filter out disconnected/background leaves in workspace context capture.

Refresh workspace context on the last user message when retrying, so file switches since the original send are reflected in the regenerated response.
When Obsidian's internal metadata cache (getAbstractFileByPath) does not
contain a file that exists on disk, operations like existsLocalPath,
writeLocalBinary, and writeLocalText incorrectly assumed the file was
absent. Similarly, statVaultItem returned undefined instead of falling
through to the adapter stat.

- existsLocalPath: fall through to vault.adapter.exists when
  getAbstractFileByPath returns null
- writeLocalBinary / writeLocalText: check vault.adapter.exists before
  creating, to avoid duplicate creation errors
- statVaultItem: remove early returns so the adapter stat path is
  reached when the file is not in Obsidian's metadata cache
Propagate error messages through ModelsPresetService on HTTP failures, invalid payloads, and exceptions instead of swallowing them. Show success/failure notices in ProvidersManagerModal with descriptive messages via the new i18n key 'presetModelsRefreshFailedWithReason'.

Relax shape field from z.enum(['completions']) to z.string() to accommodate future API values. Log zod parse errors in preset provider validation.
Migrate from custom ChatMessage/ChatToolCall to ai SDK types
(ToolCallPart, ImagePart, TextPart, LanguageModelUsage, etc.).
Tool calls now in content array as tool-call/tool-result parts.
image_url -> image type, unknown parts -> text.
Add migrateMessageFromV0 for backward compatibility with stored
messages.

Fix User-Agent assignment: NS_SYNC_USER_AGENT for Nutstore hosts,
MOCK_USER_AGENT for others (was previously swapped). Extract UA
logic to src/utils/ua.ts, broaden Nutstore host detection.

Remove interleaved-message-field (replaced by ai SDK).
Remove unused tests. Rename i18n key: exportSession -> exportAsMarkdown.
i18n: Move component-level TS locale files (Chatbox, TaskSelectionVirtualList, WebDAVExplorer) into centralized JSON under src/i18n/locales/, delete per-component i18n wrappers, update all imports to use shared translator

Mount: Extract generic createMount utility in src/components/solid-js/mount.tsx, refactor mountChatbox/mountTaskSelectionVirtualList/mountWebDAVExplorer to use it

Display blocks: Introduce ChatDisplayBlock types and projectFragmentMessageGroups utility, replace single toolCall field with displayBlocks array on timeline items, add ToolCallBlock/ToolResultBlock components and wire them into ContentBlock

Recall: Add recallMessageHasReversibleOps guard, skip non-empty directory deletion during restore, add detailed logging

Session history: Add SessionHistorySheet component and otherBusySessionIds to show concurrently running sessions
Extract settings load/save/reload from NutstorePlugin into a dedicated SettingsService with debounced disk reload. After sync modifies plugin's data.json or data.local.json, settings are automatically reloaded and the settings tab is conditionally re-rendered. Improve scheduled-sync lifecycle with explicit startupSyncCompleted tracking.
Merge CacheSettings + LogSettings into TroubleshootingSettings and remove the old LogSettings class.
Remove the manual garbage collection UI from settings (GC still runs automatically after each sync).
Wrap GC blocking notices behind IN_DEV guard for cleaner production UX.
Fix AI yolo toggle persist call to suppress unnecessary side effects.
…ation

- Introduce LogEntry interface for structured timestamp/level/args logging
- Replace vague logger.error(this, e) with descriptive tagged messages
- Add info logging for task lifecycle and sync decision summary
- Add 503 retry count logging and chunked download progress
- Rewrite deepStringify to handle Error, circular refs, proxies gracefully
- Rewrite logsStringify for structured LogEntry with full stack traces
- Remove noisy debug stat dumps from deciders
- Add comprehensive test suites for deep-stringify and logs-stringify
Introduce a customisable enterprise base URL for Nutstore Enterprise users.

- Extract endpoint resolution into nutstore-endpoints.ts with
  normalizeNutstoreBaseUrl, getNutstoreDavEndpoint, getNutstoreNsdavEndpoint
- Add NutstoreEnterpriseBaseUrlModal component for configuring the URL
- Rename NS_DAV_ENDPOINT/NS_NSDAV_ENDPOINT to DEFAULT_NS_* to clarify intent
- Make NSAPI async so it reads settings dynamically
- Update WebDAV service and API layer to use resolved endpoints
- Add nutstoreEnterpriseBaseUrl setting, i18n strings, and UI badge styles
Introduce adaptMessagesByInputModalities to strip or replace unsupported
multimodal parts (image, audio, video, pdf) before messages reach the
model. Unsupported FilePart and ImagePart are replaced with a text
placeholder identifying the omitted content; unsupported TextPart is
kept as-is. Modality constraints are read from the model config's
modalities.input array.
@miaobuao miaobuao force-pushed the feat/ns-llm-gateway branch from 78a38ab to d6098d8 Compare June 22, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant