Commit Graph
839 Commits
Author SHA1 Message Date
Sameh Khamis f86d1c3296 fix: recover near-view places through the application's place search 2026-10-05 19:27:36 -07:00
Said TurkseverandClaude Opus 5.5 d70f468781 fix(street-level): harden the Mapillary tile proxy
From gekh's review of #768, each with a test that fails before:

- The routes refuse cross-site requests (sameSiteGated, as the paid
  proxies do) and the tile route has a generous per-IP limit (600/min), so
  another page cannot burn the token's quota or trip the shared 429 hold.
- At most six upstream fetches run at once; a queued request that is
  abandoned never fetches, nor does one abandoned during the disk read.
- A body past the 48 MB cap aborts the upstream request as it streams.
- Empty tiles are charged against the memory and disk budgets.
- Each disk write uses its own temp file and a retrim is skipped while a
  write of that tile is pending, so concurrent hits cannot extend a tile's
  life or fail a rename.
- Upstream refusals other than 401/403/429 answer 502.
- The tile route's success path is tested end to end (200 with the image
  layer stripped and the right headers, 204 when empty, an abandoned
  response aborts upstream); the teardown race that made this file flaky
  is gone (240 parallel runs, no failure); the QA-constant tautologies are
  replaced by a check against the real provider registry; the boundary
  group lists the modules the provider actually imports.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 18:35:44 +01:00
Said TurkseverandClaude Opus 5.5 5f98b871e8 fix(street-level): sequence loads, playback and nearest-photo edge cases
From gekh's review of #768, each bug with a test that fails before:

- P2: a failed sequence load clears the previous sequence's cones, resets
  the selection and can be retried; a second click while loading starts no
  second lookup. sequences.js had no tests: sequences.test.mjs now covers
  failure and retry, a superseded late answer, the cache and clearSelection.
- P2: closing a photo stops MapillaryJS sequence playback, which kept the
  hidden viewer stepping and downloading images.
- openNearest without the panel reports it instead of loading forever, and
  stops if the layer (or its provider) went off during the lookup; the
  mesh sampler's misses are bounded and forgotten with its samples; the
  sequence count is the union of ids across tiles; a provider withdraws
  only its own error, so a sequence error cannot mask KEY REJECTED; hover
  stays on (throttled) under an orbiting camera and re-picks when it
  stops; "since N days" follows the clock in a long-open tab.
- A prewarm waits for one in flight and then builds if it gave up.
- New coverage for the layer core (credits, KEY REJECTED vs REQUIRED,
  switching a provider off), the refresh wiring of the tilted-view fix and
  the draped-to-cast swap completion.
- Cleanup: loading is derived from pending; freshStreet(); tile ranking
  computes distances once and shares one path for the date line; shared
  metresBetween / whenIdle / redrawTile; one NEAREST_RADIUS_M and one
  source method list; unused contract fields, exports, getImage and the
  decoder's image branch removed; PROVIDER_COLORS lists only Mapillary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 18:35:44 +01:00
Said TurkseverandClaude Opus 5.5 48276450ec fix(street-level): the panel respects restores, modes, focus and keys
From gekh's review of #768, each with a test that fails before:

- P2: the panel no longer reopens on every page load. The shell reports
  who asked for Street Level to switch on; only a user, voice or tool
  request (isExplicitLayerStateOrigin) or an opening photo opens it, and
  those automatic opens are never stored. Without the hook, a stored or
  shared "collapsed" choice wins during the restore window.
- P2: the expanded photo hides in Clean View, recording and the cockpit,
  and holds neither Esc nor Tab while hidden.
- Esc/Tab are taken only from the viewer, body or globe, not app-wide;
  FIT/FILL show the right choice while expanded; a 0x0 viewer is never
  resized (no z=NaN tile request); the expanded viewer keeps the panel's
  CSS tokens; KEY REQUIRED hides the raw "no_key" code.
- Share links carry the panel's collapsed state (ui token t); the Cyber
  theme frames the panel like its rail peers (the pinned Cyber selector
  tests now list it).
- Accessibility: radiogroups move with arrow keys and are one tab stop,
  their focus ring is no longer clipped, and the provider chips sit
  outside the disabled fieldset so the "how to add the key" hint stays
  reachable (a gated chip explains instead of toggling).
- Renders write only changed attributes (the rail's MutationObserver
  relaid out on every write); one coalesced resize per open; the legacy
  render-mode key migration is gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 18:35:30 +01:00
Said TurkseverandClaude Opus 5.5 bbe7aff242 fix(ui): floating panels stay on-screen and clear of the command dock
From gekh's review of #768, each with a test that fails before:

- P2: a floating panel whose content grows (CCTV expanded, a photo opened)
  is pulled back on-screen: every portable panel is observed and re-clamped,
  not only on window resize.
- P2: a floating header can never land under #command-dock or the voice
  pill (the rail's stacking context paints below them): clamping keeps the
  header clear of their rects on drag, restore and every re-clamp.
- A live window resize shrinks a floating window wider or taller than the
  viewport; Cyber's accordion no longer collapses docked panels when a
  floating one opens.
- The three pointer gestures share one helper (threshold, mouse/pen only,
  cancel reverts), and the header-drag threshold now has a test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 18:35:30 +01:00
Said Turksever bb88a8b034 Merge branch 'main' of https://github.com/bilawalsidhu/gods-eye-view into pr/mapillary-layer
# Conflicts:
#	README.md
2026-10-05 17:06:24 +01:00
Said Turksever a08a53cf94 Merge pull request #903 from SomaFroghyar-TomTom/fix-tomtom-link
fix: point TomTom links to my.tomtom.com
2026-10-05 17:03:08 +01:00
Soma Froghyar 9ba1b345e6 Merge branch 'main' into fix-tomtom-link 2026-10-05 17:48:49 +02:00
Said TurkseverandClaude Opus 5.5 c320b47cca test(ui): retry a header press the rail shifted away, never a real miss
The diagnostics from d9b13c7 named the CI failure: the press landed on the
globe canvas, not the header, because the CCTV panel had moved 32 px down
between the hit check and the press (docked at 234, 266 at the press) -
something above it in the rail grows on the runner after load. A press that
provably missed the header (the page records the pointerdown target) says
nothing about dragging, so it is retried up to twice, logging what sat
above CCTV at dock and at the retry; a press that landed in the header and
did not lift still fails at once.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 16:07:27 +01:00
Said TurkseverandClaude Opus 5.5 0a3dc4c4ae fix(street-level): bound the tile proxy's disk cache and keep tiles' age
From the IC8 review of #768 (P2s), each with a test that fails before:

- A tile read from disk keeps its real age in memory, and the trim rewrite
  keeps the file's mtime, so nothing is served past the 24 h TTL.
- The disk cache is swept in the background at most every 15 min: expired
  tiles go, then the oldest past 1 GiB. Coverage zooms the app never
  requests (z6-10) are refused with a 400, and layer names are matched as
  own keys only.
- The tests run against a temporary cache directory (a test seam) instead
  of writing into and deleting from the developer's real .gev-cache.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:55:18 +01:00
Said TurkseverandClaude Opus 5.5 539d514adb fix(street-level): viewer lifecycle, hover cost, keyboard focus, panel lift
From the IC8 review of #768 (P2s), each with a test that fails before:

- Switching the layer off and on during the first photo download no longer
  leaves the viewer stuck on "not mounted": an outdated mount only unmounts
  an adapter nobody else holds and subscribes poses only once current, and
  the MapillaryJS adapter never builds a viewer after it was unmounted.
- Hover picks at most every 120 ms (the CCTV convention), not while the
  camera moves or a button is held, and not after the layer went off.
- Esc shrinks the expanded viewer wherever focus is (document capture), so
  the map keeps its selection, and Tab from outside returns into it.
  Closing a photo moves focus to the panel instead of dropping it on body.
- Portable panels lift only after a mouse or pen moves past the drag
  threshold: a click on a docked panel's edge or a touch swipe on its
  header no longer turns it into a floating window, and pointercancel
  saves nothing and puts the panel back.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:55:18 +01:00
Said TurkseverandClaude Opus 5.5 b1924ebb3e fix(street-level): coverage keeps its filter, selection and ground
From the IC8 review of #768 (P2s), each with a test that fails before:

- Far-side overview dots no longer show through the globe. They skip the
  depth test so they stay above Google 3D terrain, so points behind the
  horizon are now hidden with an EllipsoidalOccluder (as the cyclones layer
  does), re-culled only when the camera moves.
- The per-tile cap applies after the imagery filter: a dense tile of newer
  flat captures kept no 360° lines at all. Lookup, picking and counts use
  the drawn set.
- Lines whose ground heights were evicted, or whose terrain lookup failed,
  are cast again on the next refresh instead of staying draped for good
  (castRequested no longer latches; castAbort marks a cast in flight). The
  height cache now drops its oldest corners instead of all of them.
- A selection made or cleared while a tile's lines rebuild is applied once
  they are ready (each primitive remembers the selection it was built with).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:55:18 +01:00
Said TurkseverandClaude Opus 5.5 f75cdf3626 perf(street-level): load the MapillaryJS stylesheet with the viewer
The 92 KB stylesheet was vendored into the main CSS, so every page load
paid for it (render-blocking) although the viewer itself is lazy. It now
comes with the lazy chunk: `import('mapillary-js/dist/mapillary.css')`
next to `import('mapillary-js')`, which Vite applies before the import
resolves, so the viewer is styled from its first frame. Main CSS in a
production build: 386 KB -> 302 KB; the MapillaryJS CSS is its own 84 KB
file. Checked in the dev server that its rules arrive with the viewer.

The vendored copy also named the wrong copyright holder and omitted the
MIT text; it is gone, and THIRD_PARTY_NOTICES.md now records mapillary-js
(MIT, Facebook, Inc. and its affiliates) and its rxjs (Apache-2.0) and
three (MIT) dependencies.

Found in the IC8 review of #768 (P2).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:55:03 +01:00
Said TurkseverandClaude Opus 5.5 d9b13c733b test(ui): press the CCTV header where it is, and say what a failed lift hit
On the CI runner the header drag stopped lifting CCTV (it did not float),
right after a run where its box never held still: the rail is shifting
there, so the press can land beside the header. It does not reproduce
locally (both gates pass on a fresh key-less dev server). The gate now
waits, bounded at 10 s, until the title point is on the CCTV header before
pressing, and a failed lift reports the element pressed, whether it was in
the header, and where the panel was when docked and at the press.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:27:15 +01:00
Said TurkseverandClaude Opus 5.5 8482daa377 test(ui): the panel gate waits for the rail on a timer, and never fails on it
On the CI runner the CCTV box never held pixel-identical for ten animation
frames within 15 s, so settle() timed out and failed the gate although the
street-level gate before it passed. The wait now rounds the box to whole
pixels, polls every 100 ms for half a second of stillness, and only logs if
the rail keeps moving: the lift is checked against the box recorded at
pointerdown, so settling is only there to make that box the docked one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:18:14 +01:00
Said TurkseverandClaude Opus 5.5 69beda99fa test(street-level): the CI gate covers the keyless, rejected-key and viewer paths
The fixture gate always reported a configured key, so the KEY REQUIRED path
most installs see never ran in CI, nothing checked that the lazily imported
MapillaryJS viewer loads, and the FOLLOW step (which needs an open photo)
failed for anyone with a Google key. Fixture runs now:

- check the viewer is stood up in the panel ahead of the first photo;
- serve a rejected key and assert KEY REJECTED, no further tile requests on
  a pan, and no stale message once the layer is off;
- open a second page whose server has no key and assert KEY REQUIRED;
- treat FOLLOW as a photo step.

Passes 16/16 locally against a dev server with Google 3D available.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:12:03 +01:00
Said TurkseverandClaude Opus 5.5 63280e22c0 fix(street-level): load the coverage in view, and name a rejected token
Tilted views: the visible box came from screen rays against the bare
ellipsoid and the 9 tiles kept were the ones nearest its centre, so a view
over high ground (Denver, 1,600 m up) or near the horizon dropped the
streets in front of the camera. At street zooms the rays now meet an
ellipsoid raised to the ground under the camera, hits beyond a range tied
to camera height are ignored, tilted views also keep the ground around the
camera, and tiles are ranked along the line of sight (nadir to screen
centre). Simulated with real Cesium ray maths over Sacramento and Denver
from 2 m to 1,000 m: the nearest visible ground and the screen centre are
always loaded.

Rejected token: Mapillary's 401/403 reached the panel as a raw "Mapillary
tiles HTTP 403" while the pill said ON, and every pan asked Mapillary again.
The proxy now answers a refusal as {keyRejected: true} and holds it for that
token (5 min), and a 429 with its Retry-After (held until then). The panel
reads KEY REJECTED, names MAPILLARY_CLIENT_TOKEN and Provider Settings,
gates its controls like KEY REQUIRED, requests nothing more, and clears the
message when the layer goes off. A rate limit keeps the drawn tiles and
refreshes once the wait is over.

Found in the IC8 review of #768 (P1 tile selection, P2 rejected token).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:12:03 +01:00
Said TurkseverandClaude Opus 5.5 57c58a862a fix(street-level): prepare ground heights for the mesh densifying too
castLine densifies at 0.0002° when mesh heights refine it, but prepareLines
only fetched grid corners for the 0.0005° points. The finer points could
land in cells nobody fetched, so the cast came back null and the whole line
stayed draped over roofs and trees on Google 3D. prepareLines now prepares
both sets (corners are deduplicated, so the extra cost is small).

A seeded test of 300 walks with 50-300 m segments: 130 failed before, 0 now.
Found in the IC8 review of #768 (P1).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 15:12:03 +01:00
Said Turksever 91d8bba4a3 Merge branch 'main' of https://github.com/bilawalsidhu/gods-eye-view into pr/mapillary-layer
# Conflicts:
#	CHANGELOG.md
#	README.md
2026-10-05 13:47:54 +01:00
Said Turksever b74a0233d9 Merge pull request #929 from trygvehhh/feat/cctv-norway-vegvesen
feat: add Statens vegvesen (Norway) road cameras as a CCTV pack
2026-10-05 13:44:59 +01:00
Said TurkseverandClaude Opus 5.5 a5e16e9470 fix(street-level): settle loading on pan, keep zoom 0, drop late poses
Fixes from gekh's re-review of 061d269, each with a regression test that
fails on the old code:

- A pan that drops a tile still loading now settles the loading count
  (the aborted request no longer owns its key, so its `finally` never
  did), and purges the previous zoom's tiles once nothing is pending.
  LOADING no longer sticks on the status pill and chip.
- Zoom 0 (above 15,000 km) is a zoom: `zoom == null` instead of `!zoom`.
- A pose that arrives after a photo was closed is dropped, in the
  MapillaryJS adapter and in the viewer host, so the marker and sequence
  selection do not come back.
- Ground casting passes the tile's signal to the terrain request, so a
  cancelled tile stops its height batch instead of holding the queue.
- The server's in-memory tile cache honours the 24 h TTL like the disk.
- The viewer's one-time resize runs for every photo, not just the first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 12:44:27 +01:00
Huanyi Xie 1c3748e3bd fix(satellites): recover TLE parsing after incomplete sets 2026-10-05 13:02:20 +03:00
daikaginza c6b43a365d fix(tiles): derive the tile origin from the configured TileJSON (#933)
`createVectorTileSource` took `tileJsonUrl` and `allowedOrigin` as independent
options, and `createOpenFreeMapSource` hardcoded both to the default host. A
caller that repointed only `tileJsonUrl` — the obvious single change — kept the
default `allowedOrigin`, so the TileJSON's absolute upstream `tiles[0]` passed
the origin check and every tile was fetched from the default host instead. No
error, no warning, and nothing reached the configured mirror.

`allowedOrigin` now defaults to the origin of `tileJsonUrl`, so repointing one
option is enough, and a mirror that serves the default host's TileJSON verbatim
fails with the existing `Invalid vector tile origin` instead of silently
bypassing itself. The origin check is unchanged: a TileJSON still cannot point
the client at a host the caller did not configure.

All three existing callers pass `allowedOrigin` explicitly
(`openFreeMap.js`, `alpr/source.js`, `traffic/flowSource.js`), and an explicit
value still overrides the derived one, so behaviour is unchanged for every
current call site.
2026-10-05 16:50:30 +07:00
Huanyi Xie b7b606b5b7 docs(mcp): use the default app port in client setup 2026-10-05 12:43:58 +03:00
Soma FroghyarandClaude Sonnet 5.5 ee7a5fb30b fix: link TomTom key setup to /keys and terms to docs.tomtom.com
Address review feedback on #903: the DATA_SOURCES terms link now points
at the actual terms page instead of a sign-in page, key-creation links
go straight to my.tomtom.com/keys, and the README table row is realigned.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-05 09:34:55 +02:00
Soma FroghyarandClaude Sonnet 5.5 491a856a6b fix: point remaining developer.tomtom.com links to my.tomtom.com
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-05 09:34:55 +02:00
Soma Froghyar 19d8ed5867 fix: MyTomTom link to the new one 2026-10-05 09:34:39 +02:00
H4ldenandClaude Opus 5.5 10d10eab6b fix: address review on the Statens vegvesen CCTV pack
- Lower the Vegvesen default cap to 900, still above the ~850 working
  cameras, so the per-pack defaults stay closer to the catalog default.
- Name the flat ground-elevation prior as a known limitation: the feed
  is 2D, and mountain-pass cameras can sit below terrain where neither
  the point-height prior nor the ground snap resolves.
- README: ~3,900 public cameras.
- Use one HLS figure (~135 working) in CHANGELOG and DATA_SOURCES.
- DATA_SOURCES: list the frame and HLS hosts alongside the catalog host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 05:47:50 +02:00
Said TurkseverandClaude Opus 5.5 061d2698f5 test(ui): lift the CCTV window from where the pointer grabbed it
The panel gate read the docked box after a fixed 600 ms sleep and expected
the lifted window 100 px above it. On the Linux CI runner the rail was still
moving and the panel sat 8 px lower when the drag began, so the gate failed
("lifted top: expected 156.5, got 164.8") although the window followed the
pointer exactly. Wait for the box to hold still for ten frames, record it at
pointerdown, and compare the lifted window against that.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 04:46:15 +01:00
Shayan khan 99f120d393 Merge branch 'main' into codex/chatgpt-realtime-oauth 2026-10-05 05:27:13 +05:00
manjunath22466 ae3612a356 fix voice debug-log privacy and docs drift
omit tool arguments unless content logging is enabled
correct the remaining current tool-count references
2026-10-05 05:46:47 +05:30
manjunath22466 a697ceae40 correct the documented voice tool count
list all 30 tools including set_cyber_sonar
2026-10-05 04:38:13 +05:30
manjunath22466 0343b4495e fix the remaining voice review gaps
keep analyst counts, speech, cards, cancellation, pointer capture, tool schema boundaries, and session lifetime consistent
add the exact Alps fallback and focused regression coverage
2026-10-05 04:37:28 +05:30
manjunath22466 6858976b01 reconcile feat/voice-core with current main
preserve Bilawal's merge history, OpenAI schema-combinator startup fix, and Contacts viewport note
keep the validated voice and analyst behavior while adopting the current provider-neutral feed routes and Google token fallback
2026-10-05 04:36:14 +05:30
Said TurkseverandClaude Opus 5.5 284cd0a93d ci(street-level): run the browser gate hermetically with Mapillary fixtures
The Street Level and panel gates never ran in CI, and the live gate needs a
Mapillary token, the Mapillary network and real coverage at its test site,
so everything users see was guarded only by manual runs (which a bad token
and expired tile caches blocked twice this week).

`qa-street-level.mjs --fixtures` (npm run qa:street-level:fixtures) answers
the page's /api/mapillary/status and coverage-tile requests from generated
tiles (a street grid with flat and 360 deg sequences, half captured three
years ago; overview points from orbit) and blocks mapillary.com. Only the
six steps that open a photo are skipped. Because the data is known, the 360
deg and SINCE steps also assert that the filters remove sequences, not just
that counts do not grow. A unit test pins the fixture contents.

New CI job "Street Level browser gate": install with headless Chrome, start
a key-less dev server, run the fixture gate and qa:panel-resize. Locally,
against a dev server with every key blanked: 14/14 on three consecutive
runs, panel gate all pass.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:50:21 +01:00
Said TurkseverandClaude Opus 5.5 7ae5f52c89 test(street-level): coverage race, camera framing and panel-control tests
From the test-engineering review of #768: the rendering and panel code had
thin unit coverage (coverage.js 29% of lines, sequences/viewer/selection
~30%, cameraFollow 50%, streetLevelControls only source-text checks), and
two shipped bugs were caught only by the manual browser gate.

- coverage.test.mjs drives the real createCoverage against a fake scene and
  a source whose tile requests the test resolves. It reproduces gekh's P0 #2:
  a request superseded by retire() finishes after a newer one for the same
  tile. Without the ownership checks it drops the newer request's key and a
  refresh starts a duplicate whose lines nothing can remove (fails on the old
  loadTile, passes now). It also covers the draped-to-cast swap keeping both
  line sets on the globe until the cast one is built and clear() removing
  both mid-swap, and a tile with nothing castable not being rebuilt.
- coverageFixture.mjs encodes Mapillary-shaped coverage tiles (sequence
  lines, overview points) from lon/lat; the tests and the hermetic gate use it.
- cameraFollow.test.mjs pins the underground-camera fix: a -14,886 m sample
  is ignored for bare earth, a plausible sample wins, and following stands at
  eye height. Three of the four fail on the pre-fix module (the first reports
  "centre at -14884 m").
- streetLevelControls.test.mjs is a contract test through the real
  DataLayerManager and LayerStateCoordinator: a 360 deg click and a SINCE
  release reach the durable layer state and the encoded share link under
  Street Level's token. Against a stand-in layer it also covers the chip rule
  (darkening the last lit chip turns the layer off, provider kept on; lighting
  a dark chip is a user params request, then enable), the legend rebuilding
  on a same-count swap (review #9) and the viewer resizing only on open
  (review #8). With the old direct-to-layer routing, three of these fail,
  including both share-link tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:50:21 +01:00
H4ldenandClaude Opus 5.5 d43478a547 feat: add Statens vegvesen (Norway) road cameras as a CCTV pack
Norway's ~850 working road cameras load from one keyless GeoJSON request
to the agency's OGC API view of its DATEX 3.1 CCTV table, so no DATEX
account is needed. Faulty cameras are dropped, every camera sits under a
"Norway" category, and the ~135 that publish HLS play as live video
through the existing in-memory relay with the still as fallback. Frames
and manifests are pinned to each camera's own path on the agency hosts.

CCTV_VEGVESEN_ENABLED=0 disables the pack, CCTV_VEGVESEN_MAX_SOURCES
caps it (nearest the largest cities first) and CCTV_VEGVESEN_VIDEO=0
keeps stills only. Attributed under NLOD 2.0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 22:23:16 +02:00
Sameh Khamis e1cc7afacf Merge pull request #926 from bilawalsidhu/feat/google-3d-access-tokens
feat: load Google 3D with short-lived server tokens
2026-10-04 11:13:46 -07:00
devv-shayan 467c4e928d test(voice): match API-key realtime auth response 2026-10-04 23:03:09 +05:00
Sameh Khamis a2f61d4def feat: load Google 3D with short-lived server tokens
Without a browser key, the app asks its server for a short-lived Google
access token (GET /api/google/tiles-token, answering accessToken and
expiresAt) and loads Photorealistic 3D Tiles directly with it as a
header. A tile refused for an expired token gets a renewed one and is
retried once. A server that does not offer tokens changes nothing: the
app continues through ion or the keyless globe as before.
2026-10-04 10:49:06 -07:00
devv-shayan 8f5710e7cb fix(voice): track OAuth login lifecycle and storage readiness 2026-10-04 17:24:30 +05:00
devv-shayan 6c88b78140 Merge upstream main into ChatGPT Realtime OAuth 2026-10-04 12:29:54 +05:00
Bilawal Sidhu e7cb9b02b5 Merge main into feat/voice-core
Keeps the voice-core prompt rules and adds main's world-query and
vessels-vs-visuals rules; the tool catalog wraps the deixis-aware runner.

Also fixes two things the branch had before the merge:
- Live voice could not start: OpenAI rejects track_entity's top-level
  anyOf. Model-facing tools now omit top-level combinators; the runner
  and benchmark still require a query or a referent.
- The Contacts-centred analyst answer dropped the viewport coverage note.
2026-10-03 23:30:02 -07:00
Sameh Khamis e1bd2f7bf1 Merge pull request #921 from bilawalsidhu/feat/provider-neutral-feed-routes
feat: name live feed routes and sources for what they serve
2026-10-03 23:25:25 -07:00
Sameh Khamis b0483dc546 test: name the vessel provider in the feed-failure QA fixture
The fixture answers /api/vessels without X-Feed-Source, so the source
fell back to the feed's name and the attribution check failed. Send
AISStream as the bundled server does.
2026-10-03 23:20:42 -07:00
Sameh Khamis 60644c5f5d feat: name live feed routes and sources for what they serve
The flight, military and vessel feeds were named after the providers the
bundled server uses (/api/opensky, /api/adsblol/mil, /api/ais-live and
their track routes; createOpenSkySource, createAdsbLolSource,
createAisStreamSource). Any server should be able to answer a feed from
its own provider, so the feeds are now:

  /api/flights   /api/flights/track?icao24=
  /api/military  /api/military/track?hex=
  /api/vessels   /api/vessels/track?mmsi=

with createFlightSource, createMilitarySource and createVesselSource. The
old routes are removed. Each server names its provider in X-Feed-Source
(the bundled server sends OpenSky Network, adsb.lol and AISStream, so its
attribution is unchanged) and the military feed's cache state and age in
X-Feed-Cache and X-Feed-Age-Ms. Sources report the provider the server
names and fall back to the feed's name.
2026-10-03 23:10:32 -07:00
Sameh Khamis 5bf3beea84 Merge pull request #920 from bilawalsidhu/feat/area-vessel-requests
feat: ask for vessels by area
2026-10-03 22:50:02 -07:00
Sameh Khamis e8e49a49e0 feat: ask for vessels by area
The vessel source accepts an optional area and sends it as lat, lon and
radius_km. The vessel layer asks for the area the camera shows (centered
on the middle of the screen, sized by camera height), or every vessel
from high enough up, and asks again when the view moves or zooms by a
quarter of that radius. vessels_in_area names its area too. Servers that
hold every vessel may ignore the area; callers still keep only what is
inside it.
2026-10-03 22:44:45 -07:00
Sameh Khamis 88b8406073 Merge pull request #919 from bilawalsidhu/feat/export-globe-panel
feat: export the globe panel for MCP servers
2026-10-03 21:24:41 -07:00
Sameh Khamis a2099358fd chore: classify the tools/panel export
Add the tools-panel boundary group for the new export.
2026-10-03 21:20:04 -07:00