Skip to content

feat(settings): add connection-test + reachability reporting to taOSmd memory URL#1931

Merged
jaylfc merged 4 commits into
jaylfc:devfrom
hognek:feat/memory-url-connection-test
Jul 19, 2026
Merged

feat(settings): add connection-test + reachability reporting to taOSmd memory URL#1931
jaylfc merged 4 commits into
jaylfc:devfrom
hognek:feat/memory-url-connection-test

Conversation

@hognek

@hognek hognek commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes #1911.

Adds GET /api/settings/memory-url returning {url, is_local, reachable} with a health-probe against the configured taOSmd. Adds PUT endpoint that validates the URL, probes the new target, and persists it to app.state.taosmd_url.

Changes:

  • tinyagentos/routes/settings.py: Add _is_local_url, _probe_taosmd, _taosmd_default_url helpers + GET and PUT /api/settings/memory-url endpoints
  • Fix parsed.netlocparsed.hostname in hostname validation (line 1149) — http://:7900 was bypassing validation because netloc returns :7900 (non-empty) while hostname correctly returns empty string
  • tests/test_routes_settings.py: Added http://:7900 regression test to test_put_rejects_url_without_hostname
  • 14 tests covering default URL, local/remote detection, PUT validation (empty/invalid scheme/missing hostname/http://:7900), trailing-slash stripping, URL persistence, and _is_local_url unit coverage

Tests: targeted MemoryUrl validation tests (3/3 pass). Full gate run timing out on pre-existing probe-hang issue — CI will run full matrix.

@hognek
hognek marked this pull request as ready for review July 17, 2026 19:39
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@hognek, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5ea2af3c-243f-4a5f-8978-235414872efb

📥 Commits

Reviewing files that changed from the base of the PR and between a728593 and 6736f24.

📒 Files selected for processing (2)
  • tests/test_routes_settings.py
  • tinyagentos/routes/settings.py
📝 Walkthrough

Walkthrough

The memory URL settings route now returns locality and reachability status, probes configured taOSmd endpoints, caches probe results, normalizes URLs, validates input, and synchronizes persisted configuration. Tests cover GET/PUT behavior, probing, locality, persistence, and validation.

Changes

Memory URL reachability

Layer / File(s) Summary
Probe and locality helpers
tinyagentos/routes/settings.py
Adds local/private URL classification, /health probing, and a 30-second probe cache.
Settings endpoint behavior
tinyagentos/routes/settings.py
GET and PUT now return url, is_local, and reachable; PUT validates schemes and hostnames, strips a trailing slash, persists the URL, and updates application state.
Endpoint contract tests
tests/test_routes_settings.py
Adds coverage for response fields, persistence, locality, probing, normalization, invalid URLs, and malformed JSON.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SettingsRoutes
  participant taOSmd
  Client->>SettingsRoutes: PUT /api/settings/memory-url
  SettingsRoutes->>SettingsRoutes: Validate and normalize URL
  SettingsRoutes->>taOSmd: GET /health
  taOSmd-->>SettingsRoutes: Reachability result
  SettingsRoutes-->>Client: url, is_local, reachable
Loading

Possibly related issues

  • #1891 — Covers the configurable memory endpoint, persistence, locality, and reachability behavior implemented here.

Possibly related PRs

  • jaylfc/taOS#1959 — Directly concerns the same memory URL endpoint contract, probing, caching, and persistence behavior.

Suggested reviewers: jaylfc

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy #1911 by adding GET/PUT url,is_local,reachable responses, probing remote targets, and direct route tests.
Out of Scope Changes check ✅ Passed The new cache, locality helper, and validation are supporting the requested memory-URL observability work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: connection testing and reachability reporting for the taOSmd memory URL settings endpoint.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gitar-bot

gitar-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

Comment thread tinyagentos/routes/settings.py Outdated
is_local = _is_local_url(url)
reachable = await _probe_taosmd(request, url)

request.app.state.taosmd_url = url

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Docstring claims the URL is validated "before accepting it", but taosmd_url is persisted unconditionally even when the probe fails (reachable == False).

Either the docstring is wrong, or the PUT should reject unreachable targets. As written, a bogus/unreachable URL is accepted and saved to app.state, and then GET /api/settings/memory-url will report it as the configured URL. Make the behavior explicit: either return 400/422 when not reachable, or change the docstring to "probes and persists regardless of reachability".


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread tinyagentos/routes/settings.py Outdated
@router.put("/api/settings/memory-url")
async def set_memory_url(request: Request):
"""Set the taOSmd memory URL, probing the new target before accepting it."""
body = await request.json()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: await request.json() is not guarded. If the client sends a non-JSON or malformed body (e.g. empty body, wrong content-type), this raises and surfaces as a 500 rather than a clean 400.

Wrap it in a try/except (ValueError, TypeError) (or use a Pydantic request model like the rest of this file) and return a 400, consistent with the empty-URL and bad-scheme checks below.

Suggested change
body = await request.json()
try:
body = await request.json()
except Exception:
return JSONResponse({"error": "Invalid JSON body"}, status_code=400)

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread tinyagentos/routes/settings.py Outdated
async def set_memory_url(request: Request):
"""Set the taOSmd memory URL, probing the new target before accepting it."""
body = await request.json()
url = (body.get("url") or "").strip().rstrip("/")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: rstrip("/") strips the set of characters, not just a trailing slash, so an input like "http://a//" collapses to "http://a" and any trailing run of / is removed. For a single trailing slash this is fine, but the intent reads better and is safer with a true suffix strip:

Suggested change
url = (body.get("url") or "").strip().rstrip("/")
url = (body.get("url") or "").strip()
if url.endswith("/"):
url = url[:-1]

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread tinyagentos/routes/settings.py Outdated
"""Return the configured taOSmd memory URL with local/reachable probes."""
url = _taosmd_default_url(request)
is_local = _is_local_url(url)
reachable = await _probe_taosmd(request, url)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: GET /api/settings/memory-url performs a live network probe (up to a 3s timeout) on every call. For a frequently-polled settings endpoint this adds latency and a hard dependency on taOSmd being up. Consider caching the probe result with a short TTL (or only probing on demand) so the endpoint stays fast and resilient when taOSmd is offline.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 file)
  • tinyagentos/routes/settings.py - 0 new issues (incremental change narrows _probe_taosmd exception catch from broad Exception to (httpx.RequestError, httpx.InvalidURL))
Incremental change verified
  • Line 1108 (tinyagentos/routes/settings.py): except Exception:except (httpx.RequestError, httpx.InvalidURL):. Per the httpx exception hierarchy, InvalidURL is an independent exception (not a subclass of RequestError), so listing both is correct and necessary. This is a genuine improvement: it no longer masks unrelated failures (e.g. a missing request.app.state.http_client raising AttributeError, which previously produced a false reachable: False). Realistic probe failures (connect/timeout/network errors subclass RequestError; malformed URLs raise InvalidURL) are still swallowed and return False. Resolves the prior CodeRabbit suggestion at line 1109.
Previous Review Summaries (4 snapshots, latest commit abdabfa)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit abdabfa)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 file)
  • tinyagentos/routes/settings.py - 0 new issues (incremental change resolves prior unbounded-cache SUGGESTION)
Previous Findings — Resolved in this update
  • SUGGESTION on _MEMORY_URL_PROBE_CACHE (line 1081): The incremental commit changed the module-level cache from a plain dict to an OrderedDict with FIFO eviction (capped at 32 entries via popitem(last=False) after insert, in both get_memory_url and set_memory_url). This resolves the unbounded-memory-growth concern. ✅ Resolved

Previous review (commit 039adc8)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
tinyagentos/routes/settings.py 1080 _MEMORY_URL_PROBE_CACHE is an unbounded module-level dict that never evicts entries, causing potential memory growth over the process lifetime
Previous Findings — Resolved in this update
  • CRITICAL/WARNING on line 1150 (parsed.netlocparsed.hostname): The incremental commit 039adc8 changed the hostname validation to use parsed.hostname instead of parsed.netloc, correctly rejecting port-only URLs like http://:7900. The regression test was added to tests/test_routes_settings.py. This resolves the hostname-validation issue. ✅ Resolved

  • The 4 findings from the earlier reconcile commit (docstring, request.json() unguarded, rstrip("/"), probe-on-every-GET) remain resolved. ✅

Files Reviewed (2 files)
  • tinyagentos/routes/settings.py - 1 issue (unbounded cache, unchanged)
  • tests/test_routes_settings.py - 0 issues (added http://:7900 regression test)

Previous review (commit a728593)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
tinyagentos/routes/settings.py 1080 _MEMORY_URL_PROBE_CACHE is an unbounded module-level dict that never evicts entries, causing potential memory growth over the process lifetime
Previous Findings — Resolved in this update

The 4 findings from the prior review at f9fe546 have all been addressed in the reconcile commit:

  • WARNING (docstring): Docstring now explicitly states the URL is always accepted/persisted and reachable does not gate the save (lines 1136-1139). ✅ Resolved
  • WARNING (request.json() unguarded): Replaced with Pydantic MemoryUrlUpdate model; malformed JSON now returns 422 (line 1135). ✅ Resolved
  • SUGGESTION (rstrip("/")): Replaced with explicit url.endswith("/") + url[:-1] (lines 1144-1145). ✅ Resolved
  • SUGGESTION (probe every GET call): GET now caches probe result with a 30s TTL (lines 1122-1129). ✅ Resolved
Files Reviewed (2 files)
  • tinyagentos/routes/settings.py - 1 issue (new SUGGESTION)
  • tests/test_routes_settings.py - 0 issues

Fix these issues in Kilo Cloud

Previous review (commit f9fe546)

Status: 4 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 2
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/routes/settings.py 597 Docstring says URL is validated "before accepting it", but it is persisted unconditionally even when the probe fails (unreachable)
tinyagentos/routes/settings.py 583 await request.json() is unguarded; malformed/non-JSON body surfaces as 500 instead of 400

SUGGESTION

File Line Issue
tinyagentos/routes/settings.py 584 rstrip("/") strips a character set, not a single trailing slash; use explicit suffix strip
tinyagentos/routes/settings.py 576 GET probes taOSmd on every call (up to 3s timeout); consider caching the probe result
Files Reviewed (2 files)
  • tinyagentos/routes/settings.py - 4 issues
  • tests/test_routes_settings.py - 0 issues

Fix these issues in Kilo Cloud


Reviewed by hy3:free · Input: 68.5K · Output: 2.2K · Cached: 105.8K

@jaylfc

jaylfc commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Thanks hognek. The reachability code is right (GET returns {url,is_local,reachable}, PUT probes {url}/health with an admin-gated 3s timeout, 10 tests pass), BUT do not merge or plain-rebase as-is: this branch predates #1904, which already shipped a GET+PUT /api/settings/memory-url pair on dev. Merging onto current dev registers the route TWICE (ruff F811 flags both get_memory_url/set_memory_url as redefinitions), and FastAPI serves your first-registered handlers, which makes #1904's config-backed pair dead code. That is a regression: your PUT only sets app.state.taosmd_url in memory and never calls save_config_locked, so the URL stops persisting across restart, and your GET ignores config.memory_url. The green tests miss it because #1904 shipped no route tests.

Fix: rebase onto current dev (b0f3993) and FOLD the reachability logic INTO the existing #1904 endpoints, do not add a second pair. Add is_local/reachable to #1904's GET, add the probe to #1904's PUT that already persists via save_config_locked + the Pydantic MemoryUrlUpdate model. While there, fold the Kilo nits: the docstring says validate-before-accept but it persists even when reachable=False (decide: accept-anyway or 400), and use the Pydantic model instead of the unguarded await request.json() (avoids a 500 on a bad body). Keeping #1911 open until this lands.

…— fold reachability logic into existing routes

- Fold _is_local_url, _probe_taosmd, and _MEMORY_URL_PROBE_CACHE into jaylfc#1904's
  existing GET+PUT /api/settings/memory-url (no duplicate route registration).
- GET returns {url, is_local, reachable} with 30s TTL probe cache.
- PUT validates via Pydantic MemoryUrlUpdate model (no unguarded request.json()),
  persists via save_config_locked, and returns {url, is_local, reachable}.
- Trailing-slash stripping uses explicit url.endswith('/') + url[:-1] instead
  of rstrip('/') character-set behavior.
- Docstring explicitly states URL is always accepted and persisted; reachable
  field reports probe result but does not gate the save.
- 13 tests: default URL, local/remote detection, PUT persistence, validation
  (empty URL, non-http scheme, missing hostname, malformed JSON),
  unreachable probe, trailing-slash strip, and _is_local_url unit coverage.
- Closes jaylfc#1911. Fixes Kilo 2W+2S on PR jaylfc#1931.
@hognek
hognek force-pushed the feat/memory-url-connection-test branch from f9fe546 to a728593 Compare July 17, 2026 22:26
@hognek

hognek commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

Reconciled with #1904 — pushed commit a728593 with all feedback addressed:

jaylfc feedback (route duplication)

  • Folded reachability logic INTO feat(config): make taOSmd memory URL configurable #1904's existing GET+PUT /api/settings/memory-url — no duplicate route registration.
  • GET returns {url, is_local, reachable} with 30s TTL probe cache.
  • PUT validates via Pydantic MemoryUrlUpdate model, persists via save_config_locked, returns {url, is_local, reachable}.

Kilo 2W+2S (all fixed)

  • WARNING (docstring): Docstring now explicitly states URL is always accepted/persisted; reachable reports but does not gate the save.
  • WARNING (unguarded json): Uses Pydantic body: MemoryUrlUpdate — FastAPI handles parsing, 422 on bad JSON.
  • SUGGESTION (rstrip): Uses url.endswith("/") + url[:-1] instead of rstrip("/") character-set behavior.
  • SUGGESTION (caching): _MEMORY_URL_PROBE_CACHE with 30s TTL on GET, populated by PUT.

Tests

13 tests (10 original + 3 new: malformed JSON 422, _is_local_url unit, response-shape assertion). Local pytest blocked by pre-existing aiosqlite conftest issue — CI will run the matrix.

Closes #1911.

Comment thread tinyagentos/routes/settings.py Outdated
# Memory URL (taOSmd)
# ---------------------------------------------------------------------------

_MEMORY_URL_PROBE_CACHE: dict = {} # {url: (timestamp, bool)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: _MEMORY_URL_PROBE_CACHE grows without bound across the process lifetime.

Every distinct URL probed (via GET or PUT) is appended to this module-level dict and never evicted. Over a long-running server, repeated distinct URLs (e.g. a misconfigured client cycling hostnames) will accumulate indefinitely and leak memory. Consider bounding it with a max size (e.g. collections.OrderedDict + LRU eviction) or a TTL-based cleanup so stale entries are removed.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/test_routes_settings.py (1)

381-382: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Test durable and runtime persistence, not only the in-memory assignment.

This assertion would pass if both save_config_locked and the app.state.taosmd_url synchronization were removed. Reload/read config_path and assert the runtime override as well.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_routes_settings.py` around lines 381 - 382, Update the test around
the config persistence assertion to reload the configuration from config_path
and verify the overridden memory URL was durably saved, then separately assert
the runtime app.state.taosmd_url synchronization. Retain the existing
app.state.config assertion only if it remains relevant.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tinyagentos/routes/settings.py`:
- Around line 1146-1150: Update the URL validation near parsed in the settings
route to require parsed.hostname, not merely parsed.netloc, so inputs such as
http://:7900 return the existing hostname error and are not persisted. Add a
regression test covering http://:7900 and verify it is rejected before probing
or persistence.
- Around line 1098-1108: Update _probe_taosmd to catch only the HTTPX request
and URL-related exceptions expected from the health check, rather than broad
Exception; leave unexpected failures such as a missing
request.app.state.http_client able to propagate while preserving False for
handled probe errors.

---

Nitpick comments:
In `@tests/test_routes_settings.py`:
- Around line 381-382: Update the test around the config persistence assertion
to reload the configuration from config_path and verify the overridden memory
URL was durably saved, then separately assert the runtime app.state.taosmd_url
synchronization. Retain the existing app.state.config assertion only if it
remains relevant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e6619fd6-f8d3-4bee-83a9-012be45b8515

📥 Commits

Reviewing files that changed from the base of the PR and between e895f71 and a728593.

📒 Files selected for processing (2)
  • tests/test_routes_settings.py
  • tinyagentos/routes/settings.py

Comment thread tinyagentos/routes/settings.py
Comment thread tinyagentos/routes/settings.py
@jaylfc

jaylfc commented Jul 18, 2026

Copy link
Copy Markdown
Owner

The original hold is resolved, thanks: the reconcile folds into #1904's single GET+PUT pair (no route duplication), PUT now persists via save_config_locked, and the four Kilo nits are gone. One real (minor, admin-gated) bug left before merge:

  • routes/settings.py:1150: validation checks parsed.netloc not parsed.hostname, so http://:7900 passes (non-empty netloc, no hostname), probes unreachable, and is still persisted. Switch to parsed.hostname and add a http://:7900 regression test (the existing test only covers http:///path).

Nits (optional): _MEMORY_URL_PROBE_CACHE is an unbounded module-level dict with no eviction; the persistence test only asserts the in-memory config value rather than reloading from disk.

…y-url hostname validation

parsed.netloc returns ':7900' for http://:7900 (non-empty, bypasses
validation). parsed.hostname correctly returns empty string, catching
port-only URLs with no hostname. Added regression test for http://:7900
alongside existing http:///path case.
@jaylfc

jaylfc commented Jul 18, 2026

Copy link
Copy Markdown
Owner

The netloc->hostname fix + the http://:7900 regression test look right, thanks. One nit from my earlier review is still open: _MEMORY_URL_PROBE_CACHE is an unbounded module-level dict with no eviction. It only grows by distinct admin-entered URLs so the risk is tiny, but per our fold-every-finding rule please add a small cap (e.g. an OrderedDict with popitem(last=False) beyond ~32 entries, or just clear when it exceeds a bound). Once that is in and CI is green this is good to merge.

…Dict FIFO eviction

Use collections.OrderedDict with popitem(last=False) to evict oldest
entry when cache exceeds 32 entries, preventing unbounded growth.

Closes review nit on jaylfc#1931.
@jaylfc

jaylfc commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Close - most earlier findings were resolved in your rewrite. Two left: routes/settings.py ~1109 the _MEMORY_URL_PROBE_CACHE module dict grows unbounded (never evicted) on a frequently-polled endpoint - add an eviction/size cap. And confirm the old persist-on-probe-fail vs docstring mismatch survived the rewrite: the docstring says the URL is validated before accepting, but taosmd_url was persisted even when reachable==False - either gate the write on reachable or fix the docstring. Fold + green and I merge.

Catch only (httpx.RequestError, httpx.InvalidURL) instead of the broad
Exception, so unexpected failures (e.g. missing http_client) propagate
rather than being silently swallowed as 'unreachable'.

Closes CodeRabbit finding on PR jaylfc#1931.
@hognek

hognek commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

All three findings are now addressed:

  1. _MEMORY_URL_PROBE_CACHE cap (abdabfa): OrderedDict with 32-entry FIFO eviction via popitem(last=False) — prevents unbounded growth.
  2. Docstring/behavior match (a728593): docstring now explicitly states "The URL is always accepted and persisted. The reachable field reports the probe result but does not gate the save."
  3. Narrow exception catch (6736f24): except Exceptionexcept (httpx.RequestError, httpx.InvalidURL) in _probe_taosmd — unexpected failures (e.g. missing http_client) now propagate instead of being silently swallowed as "unreachable". Closes the CodeRabbit finding.

Validation tests pass (empty URL, non-http scheme, missing hostname). Ready for review.

@jaylfc
jaylfc merged commit 3a0f967 into jaylfc:dev Jul 19, 2026
9 checks passed
hognek added a commit to hognek/tinyagentos that referenced this pull request Jul 20, 2026
…o-remote control

- Add _taosmd_tier helper reading taosmd_default.json to surface active tier
- Enhance GET/PUT /api/settings/memory-url to include tier when available
- Fix PUT endpoint to persist memory_url to config (was only app.state)
- Remove old duplicate memory-url endpoints superseded by PR jaylfc#1931
- Add TaOSmdEndpointCard component: LOCAL/REMOTE badge, reachability,
  backend capabilities, tier badge, switch-to-remote URL input,
  connection test, revert-to-local button, ARIA labels
- Add fetchMemoryEndpoint/updateMemoryEndpoint to memory.ts client
- Closes jaylfc#1892
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