Skip to content

feat: add sensory framework core - #114

Open
Nothing1596 wants to merge 9 commits into
Rvosy:devfrom
Nothing1596:feat/sensory-core
Open

Nothing1596 wants to merge 9 commits into
Rvosy:devfrom
Nothing1596:feat/sensory-core

Conversation

@Nothing1596

Copy link
Copy Markdown
Contributor

Summary

  • Split from feat: add sensory framework #99 to keep review scope small.
  • Adds the core sensory middleware: settings, provider routing, structured observations, JSONL storage, dynamic context provider, tool scaffolding, and settings UI hooks.
  • Keeps heavyweight model/runtime work out of this PR.

Validation

  • Full test suite on this stack branch: 1280 passed.

Stack

This is PR 1/6. Downstream clean-diff PRs are opened in the fork because this account cannot push intermediate base branches to Rvosy/Sakura.

@Nothing1596

Copy link
Copy Markdown
Contributor Author

已按复审建议把 #99 拆成 stacked PR。

Stack 顺序:

  1. feat: add sensory framework core #114 — sensory core,base dev
  2. feat: add sensory visual summary bridge Nothing1596/sakura#3 — visual summary bridge,base feat/sensory-core
  3. feat: add cross-platform sensory audio capture Nothing1596/sakura#4 — cross-platform audio capture,base feat/sensory-vision-summary
  4. feat: add sensory Hugging Face model downloads Nothing1596/sakura#5 — Hugging Face model downloads,base feat/sensory-audio-capture
  5. feat: add short audio inference routing Nothing1596/sakura#6 — short audio inference routing,base feat/sensory-model-downloads
  6. feat: add managed llama.cpp audio runtime Nothing1596/sakura#7 — managed llama.cpp runtime/CLI/manifest,base feat/sensory-audio-inference

说明:当前账号没有向 Rvosy/Sakura 推送中间 base 分支的权限,所以只有第一个 PR 能作为干净 diff 开到上游;后五个先在 fork 内保持 clean diff。每个分支已本地跑全量 pytest,最终 feat/sensory-managed-llama 内容与原 feat/sensory-framework-clean head 一致。

@Nothing1596
Nothing1596 marked this pull request as ready for review June 24, 2026 02:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fcf2d98858

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/sensory/providers.py
Comment on lines +423 to +426
path = Path(ref).expanduser()
if path.is_file():
mime = mimetypes.guess_type(path.name)[0] or "image/png"
return f"data:{mime};base64,{base64.b64encode(path.read_bytes()).decode('ascii')}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict model-supplied local media paths

When a remote API or LAN vision sensory provider is enabled, the model controls observe_sensory arguments and can pass a local media_ref/metadata path. This branch treats any readable file path as image input and base64-embeds its bytes into the provider request, so a tool call can exfiltrate arbitrary local files, not just temporary screenshots, before the provider has a chance to reject the payload. Restrict this to trusted temp capture paths and validate that the file is an expected image, or require explicit confirmation for local paths.

Useful? React with 👍 / 👎.

Comment thread app/ui/settings_dialog.py Outdated
Comment on lines +1025 to +1026
if mode != SensoryProviderMode.OFF:
validation_error = _validate_sensory_state(source, state)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip provider validation when sensory is disabled

When the user unchecks the global “启用增强感知工具” box, this loop still validates every source whose per-source mode is not off before building the returned SensorySettings(enabled=...). If a user has a half-filled source, such as Local selected with an empty model, choosing to disable enhanced sensing still gets blocked by _validate_sensory_state, so they cannot save the disabled state without first fixing or turning off each individual source.

Useful? React with 👍 / 👎.

Comment thread app/sensory/context.py
Comment on lines +83 to +84
source_settings = settings.sources[observation.source]
if not source_settings.context_enabled:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor disabled sources when injecting context

When a user turns an individual sensory source off after observations have already been recorded, those stale records can still be injected because this filter only checks context_enabled and confidence. SensorySourceSettings defaults context_enabled to true even for mode=off, so disabling speech/vision/sound stops new provider calls but does not stop old observations from appearing in prompts; check the source mode/enabled flag here before admitting the observation.

Useful? React with 👍 / 👎.

Comment thread app/ui/settings_dialog.py Outdated
sources[source] = SensorySourceSettings(
mode=mode,
provider_id=provider_id,
confidence_threshold=float(state.get("confidence_threshold") or 0.5),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve zero confidence thresholds

The settings UI allows the minimum confidence to be set to 0.00, and the settings model accepts it, but this or 0.5 coercion turns that explicit zero back into the default 0.5 when saving. Users who intentionally want to include all observations will see the value silently change on save/reopen; only fall back when the key is missing or invalid, not when it is 0.0.

Useful? React with 👍 / 👎.

Comment thread app/ui/settings/pages/sections.py Outdated
owner.sensory_enabled_check.toggled.connect(owner._sync_sensory_controls)
owner.sensory_context_enabled_check.toggled.connect(owner._sync_sensory_controls)
owner.sensory_source_combo.currentIndexChanged.connect(owner._handle_sensory_source_changed)
owner.sensory_mode_combo.currentIndexChanged.connect(owner._handle_sensory_control_changed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh endpoint when changing sensory mode

When a new sensory source is switched from the default/off state to “远端 API” or “局域网”, the mode change only captures and syncs the controls; unlike backend changes, it never replaces the existing LM Studio endpoint text. Saving API mode after entering just a model therefore configures http://127.0.0.1:1234/v1, and LAN mode immediately fails validation until the user manually overwrites the stale localhost value, so the selected mode does not produce a usable default.

Useful? React with 👍 / 👎.

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.

2 participants