Commit Graph

1797 Commits

Author SHA1 Message Date
Maurice 228db8541c chore(notices): show 5.0.1 in the release popup
The release popup still named 5.0.0 and linked the 5.0.0 release notes. It now names 5.0.1 and links its tag.
2026-10-28 09:52:18 +01:00
Maurice 6c0e39e287 fix(transit): name and record the backend that answered, not always Transitous
With Google as the transit provider, the result list still credited
Transitous, and a route added from the panel or through
create_transit_journey was saved with provider 'transitous'. The panel
now credits "Google Maps" (untranslated, as Google's terms ask) or
Transitous after the backend that answered and saves that one; the MCP
journey records the backend that plans routes for the caller, and
search_transit_routes reports it.
2026-10-27 21:30:18 +01:00
Maurice 22574a2270 fix(assistant): send Gemini's thought signatures back with its tool calls
Gemini 3 signs a tool call on its OpenAI-compatible endpoint
(extra_content.google.thought_signature) and refuses the next request
with a 400 when the call comes back without it, so every turn in which
the model called a tool failed. The Chat Completions client now keeps
the signature per call as the step's provider state and sends it back
with the call, to the model that signed it only.

An own server entered with Gemini's endpoint now also gets Gemini's
narrower tool schemas, which it refused before.
2026-10-27 21:06:29 +01:00
Maurice 1d880cb881 style(tours): format the route file reader 2026-10-27 15:29:00 +01:00
Maurice 3d076704f9 test: keep the new day-note and document-sync tests inside the lint and type gates 2026-10-27 15:16:50 +01:00
Maurice c383b11648 fix(assistant): propose a route file's track from before Tours instead of skipping it
The Tours import takes over a same-named track a trip kept from 4.x, but a
route file attached in the assistant chat was read with the plain duplicate
rule only, so that track was reported as already in the trip and never
proposed. The read now leaves such a track to the import, which takes it
over as a tour like the Tours dialog does.

Refs #2810
2026-10-27 15:02:24 +01:00
Maurice fed564e7c0 fix(assistant): answer the model's own calls of server tools when a thread is replayed
remember_for_trip runs at once during a turn, and read_attached_file and
keep_attached_file are answered by the server, but all three are calls the
model made. Rebuilding a thread from its stored steps left them unanswered,
and ChatGPT, the OpenAI reasoning models and Anthropic replay their own record
of each step, call included, so the provider refused the conversation with a
400: the continuation after applied changes failed, and every later message of
the thread with it. A step that kept a note also sent an empty user message.
Every call the model made is now answered as in the live turn, the attached
file's outcome as the answer of its call; threads that broke this way work
again on their next message. A refusal's log line names the refused field's
path, never its message.

Closes #2845
2026-10-27 14:53:13 +01:00
Maurice 0f0232491b fix(mcp): describe day-note title and body and allow the planner's 2000-character body
create_day_note and update_day_note described `time` as a clock label and capped
it at 250 characters, while the planner shows it as the Markdown body under the
title and allows 2000. The assistant put long text in the title and had to cut
notes it was asked to edit. Both tools now take text and time from the REST
contract with descriptions naming title and body, and an update still refuses an
empty title. The assistant's change card labels the two fields title and content
instead of text and time.

Closes #2840
2026-10-27 14:38:30 +01:00
Maurice 3bc75d2b1c fix(airports): keep airports OurAirports flags as having no scheduled service
The airport picker never offered Little Cayman (LYB): OurAirports marks it as
having no scheduled service although it has daily flights, and the build
dropped every airport on that flag. The same flag also hid Vestmannaeyjar,
Western Sydney and around 1,280 other large and medium airports with an IATA
code. The build now applies the flag to small airports only, where it keeps
private airstrips out.

The bundled list gains exactly those airports. Every entry it already carried
stays unchanged, because a fresh OurAirports export currently renames PBI to
DJT and drops nine other codes that saved bookings point at.

Closes #2820
2026-10-26 20:21:13 +01:00
Maurice 313198ba63 fix(places): read the dedup tracks off the dedup inputs, the places files stay within their size entries 2026-10-26 14:18:59 +01:00
Maurice e677d58f91 fix(places): a track is a duplicate only of a track, never of a sight of that name
A GPX or KML import skipped every row whose name was already a place of the
trip. A watch names a hike after where it went, so "Hokitika Gorge" was
refused as already in the trip because the gorge itself was a planned
place, with no track to show for it (#2810). A track now matches only the
tracks of that name; a pin still matches every place of its name.

The Places filter also hid its "Tracks" choice whenever Tours was on, on the
grounds that tracks are tours then. A track imported before Tours is a
plain place and stays in the list, so the choice now counts the tracks that
are no tour.
2026-10-26 14:08:56 +01:00
Maurice bc60aea839 test(studio): the book words read the new heading 2026-10-26 13:29:35 +01:00
Maurice fd818050bd fix(tours): pair the tracks to take over in the tours domain, off the places list 2026-10-26 12:47:09 +01:00
Maurice 0313597b10 fix(tours): read the tracks to take over through the typed query API, seed the tests through the factories 2026-10-26 12:35:19 +01:00
Maurice 2c867673bf test(tours): count the new preview key, lower the await-in-loop entry, type the adopt rows 2026-10-26 12:23:08 +01:00
Maurice 39ebf0976c fix(tours): a tour import takes over a track imported before Tours
A GPX track imported in 4.x is a plain place: a line, no tours row. It never
showed under Tours, and importing the same file there was refused as a
duplicate by its name, so there was no way to turn it into a tour (#2810).

The tour import now takes over a track of the trip that has the same name
and is no tour yet: the place keeps its name and line and gets the tours
row, with the recorded times the file adds. The preview says so instead of
"Already in the trip". New and taken-over tracks commit in one transaction.
2026-10-26 12:17:15 +01:00
Maurice 1ecc449f3e test(ai): fix the model-not-found pattern, guard the fetch mocks, and read the booking in an ORM context 2026-10-26 10:20:47 +01:00
Maurice b8990782cc fix(ai): connect and read bookings through any OpenAI-compatible own server
Connecting an own server asked Ollama's /api/tags and gave up on any answer
that was not a 404, and every failure, a refused key included, read as "not
responding". The model list is now looked for at /api/tags, at the address as
entered and at /v1/models, an answer only counts when it is a list, and a
refused key or a server that answered without a list say so (#2808).

AI parsing through an own server always called Ollama's /api/chat, which an
OpenAI-compatible server such as Groq answers with 404. A server without it
now gets the same extraction over /chat/completions at the address as
entered (#2806).
2026-10-26 10:20:46 +01:00
Maurice 8ba7add541 fix(plugins): give the runtime test's plugins table the accepted-range columns, and move the theme entry with the menu code 2026-10-26 09:49:22 +01:00
Maurice 0067b0ff19 fix(plugins): let an admin run a plugin outside its TREK range, and tidy the plugins panel
TREK 5.0 left most registry plugins blocked because their authors still declare
"<5.0.0", and the only way past that was TREK_PLUGINS_IGNORE_TREK_RANGE for every
plugin at once. An admin can now install or switch on one such plugin after a
warning; the consent is kept on its row for that plugin version and TREK major,
so an update or a new major asks again. The environment switch works as before.

Discover marks a plugin not confirmed for this TREK on its card, and Install opens
the warning first. Admin > Plugins reads cleaner: one row of alike facts per plugin
with each state that needs attention on its own line, type, status and order behind
one Filter button, and the containment notes in a dialog behind the shield in the
header. The row, the filter menu and the dialog moved into their own files.
2026-10-26 09:49:22 +01:00
Maurice d589da59f2 fix(wanderer): find the author of an account whose one actor wanderer expands as an object
PocketBase answers a back-relation with a single record as the object itself,
not a list, so the user lookup failed as an answer TREK did not understand and
every search with it.

Closes #2799
2026-10-26 01:03:35 +01:00
Allan Braun 69ff295184 fix(assistant): answer Brazilian Portuguese users in Portuguese, not Breton
TREK's code for Brazilian Portuguese is 'br', which Intl reads as Breton.
The assistant passed it straight to Intl.DisplayNames for the system
prompt's answer language and to the card formatters, so the model was told
to answer in Breton. Convert TREK codes to their BCP-47 tag with
getIntlLanguage before handing them to Intl.

Closes #2800
2026-10-26 00:04:56 +01:00
Maurice a48dd7645f fix(wanderer): say so when wanderer names no author for the token's account
A token whose account has no local ActivityPub author was reported as
invalid_response, which the settings show as 'The answer did not come from
wanderer', although wanderer had answered fine. It now has its own code,
no_author, with a message in every language that says what is missing.
2026-10-25 18:59:43 +01:00
Maurice 217a576e16 fix(wanderer): log why an answer from wanderer was not understood
A failed wanderer call kept its reason in WandererError.detail (the field that
did not match, or what came instead of JSON), and the client comment said it
stays in the log, but nothing wrote it anywhere. The log only had the generic
'wanderer answered with something TREK does not understand', so neither an
admin nor we could tell what wanderer had sent. Every refusal now logs its
code, message and detail.
2026-10-25 18:59:43 +01:00
Maurice f6976d5cec fix(assistant): send OpenAI reasoning models on an API key to the Responses API
gpt-5.6-sol, gpt-6.1-sol and the other reasoning models refuse function tools
on Chat Completions, so every assistant message on such a model came back as
HTTP 400. An OpenAI connection whose model is from the o-series or GPT-5 and
later now goes through the Responses API, the client a ChatGPT plan already
uses, with the key as its bearer token and no token refresh on a 401. Older
models and the -chat variants stay on Chat Completions.

Closes #2792
2026-10-25 16:55:39 +01:00
Maurice c1c2bbf146 fix(assistant): replay an Anthropic answer that thought with its thinking blocks
Sonnet 5.5 and Opus 5.5 think by default and write what they say between tool
calls into thinking blocks, which they want back unchanged with the rest of
the turn. The client dropped those blocks (and their signatures) and rebuilt
the turn from its text and calls, so after a tool result the next step came
back empty and the assistant gave up with empty_answer. A turn that thought
is now replayed block by block like one that searched the web; the cache mark
before the question skips a thinking block, and replayed blocks are copies so
a mark never sticks to the stored answer.

Closes #2789
2026-10-25 16:49:46 +01:00
Maurice a5342df648 fix(assistant): list the admin model switch among the routes a managed install withholds
The boot check pins every @ManagedForbidden route; the new
AiAdminController.setModel was missing, so the server refused to start.
2026-10-25 16:29:31 +01:00
Maurice d911122a37 fix(assistant): let an admin switch the model of a shared ChatGPT plan
The model picker in Admin > Addons did nothing for a ChatGPT connection: the
only way to change the instance's model was saving the connection again, which
needs an API key a plan does not have. A PATCH /api/admin/ai/connection/model
now switches it on its own, to a model the provider offers.

Closes #2783
2026-10-25 16:29:31 +01:00
Maurice a69eee191c test(plugins): let the instance-settings fixture run on TREK 5
The fixture plugin declared trek >=4.0.0 <5.0.0, so since the version bump to
5.0.0 the host refuses to spawn it and INS-012 fails on dev.
2026-10-25 15:59:59 +01:00
github-actions[bot] bd1de9e1d5 chore: bump version to 5.0.0 [skip ci] 2026-10-25 11:07:55 +00:00
Maurice 6b6d971f07 fix: the CI findings on the 5.0 release notes and the demo fixes
The overview of a trip's tours decides for itself when it shows, which keeps the planner page hook inside its complexity and length limits, and adds nothing to the camera's key while there is no tour to frame. The elevation helper names its empty case for the strict type check, the self-host wording exemption for the retired Dawarich card goes, the day plan test reads the wrapping pills, and the new tests drop their non-null assertions and loops.
2026-10-25 11:03:03 +01:00
Maurice 9fc98b5d49 feat(notices): the release notes present 5.0.0
The update dialog now shows the 5.0.0 headliners, Tours, TREK Studio, the assistant and help on every screen in 27 languages, each with a drawing of its own, translated into every language TREK ships. The 4.3.3 cards and their drawings are gone.
2026-10-25 10:51:57 +01:00
Maurice daaa6c425d fix(notices): a release's notes show to whoever dismissed them on its prerelease
Dismissals were compared with the prerelease part dropped, so a notice closed on 5.0.0-pre.2 counted as closed on 5.0.0 and the final release showed nothing to anyone who had tried a prerelease. Versions now compare in full.
2026-10-25 10:51:57 +01:00
Maurice e3eec8d6d1 fix(budget): a custom split in a foreign currency adds up to what was paid
Each member's amount was converted and rounded to a cent on its own, so four 34,000 ISK quarters of a 136,000 ISK bill came to 997.52 EUR against the 997.51 the payer was credited. The balances ended a few cents off zero and settle-up had no payment for them. A split whose amounts match the payers in the bill's own currency is now converted as one set by largest remainder, in the settlement and in the per-person summary alike.
2026-10-25 10:51:56 +01:00
Maurice 2372dde716 fix(demo): journey and collab uploads are refused for the demo account too
Six upload routes refused the shared demo account in demo mode; journey photos, videos, gallery media and covers, collab note files and chat images did not, so any visitor could put images in front of every other one for the hour. They answer the same 403 now, checked in the handler after the upload is read, and a text-only chat message still goes through. The Demo Mode wiki page lists them, and says document sync is not covered.
2026-10-25 00:46:24 +00:00
Maurice 42ed858853 fix(demo): a demo instance keeps the files its baseline points at
The hourly reset puts only the database back, so a cover, photo, place image or trip file a visitor deleted in between was missing from the restored rows for good. On a demo instance StorageService.delete now leaves the content categories alone; the caches, the backups and the assistant's attachments are still deleted, and the orphan thumb sweep no longer counts a kept thumb as removed.
2026-10-25 00:46:24 +00:00
Maurice 9c83386655 test(demo): the OAuth demo lock cases take their controller from OauthModule 2026-10-24 23:22:15 +00:00
Maurice 98961dadd5 fix(demo): the addon policy names the legacy memories row, which stays off
The trip Photos addon of old releases is still seeded, switched off, and nothing reads it any more. The policy test now fails on no row, and its checks run without awaiting in a loop.
2026-10-24 23:22:15 +00:00
Maurice 7ada99acfc fix(demo): the demo's addon set and the demo account's settings are written without awaiting in a loop
One UPDATE per shelf and state and one upsert for the switches, inside the same transaction, and the demo account's settings in one upsert. The two new log lines go through the logger.
2026-10-24 23:22:15 +00:00
Maurice 2ac333f842 fix(demo): skip the example trips when the demo account owns its own
The seed put the example trips in whenever the admin owned none, so a demo
whose content belongs to the demo account got them back on every reopen,
the hourly reset included, and the next baseline saved them along.
2026-10-24 23:22:15 +00:00
Maurice 270a13ff60 feat(demo): the AI assistant, AI parsing and the MCP server stay off in the demo
They spend the instance's AI credit or hand tokens to a shared account, so
they belong to a self-hosted install, not to the public demo.
2026-10-24 23:22:15 +00:00
Maurice cad7d54e83 feat(shared): the demo account's addresses live in one place for both sides
The client is about to lock settings sections for the shared demo account,
and it has to ask the same question the server does. DEMO_ACCOUNT_EMAILS and
isDemoAccountEmail now sit in @trek/shared, and the server's DEMO_EMAILS is
built from them instead of spelling the two addresses a second time.
2026-10-24 23:22:15 +00:00
Maurice 2df677d065 refactor(demo): the addon states type names its shelves inline
The shelf shape was an exported interface nothing outside the repository
imports, which knip counts as an unused export.
2026-10-24 23:22:15 +00:00
Maurice 03493d4f79 feat(demo): a fixed addon set on every boot and after every hourly reset
A demo instance now runs with one explicit addon policy (demo-addon-policy.ts)
instead of whatever its admin last switched: every trip, global and
integration addon on, and off only what reaches a server of the visitor's
own, the five document sync providers, wanderer under Tours, the Immich and
Synology Photos providers, AirTrail and Dawarich. The switches under the
addons (Tours maps, piste routing, bag tracking, the collab features) are on.

The demo seed applies it, together with the demo account's English
language, on every boot and after every reopen, and the hourly reset applies
it once more after the baseline swap, in one transaction each. A test pins
that every seeded addon and provider is named in exactly one list, so a new
addon has to be classified before it ships.
2026-10-24 23:22:15 +00:00
Maurice eae74c5605 feat(demo): the shared demo account keeps its keys, account and language
Every visitor of a demo instance signs in as the same account, so one
visitor's API key, MCP token, OAuth client, passkey or new email address
became everybody's. These writes now answer 403 for the demo account through
refuseForDemoAccount in demo-write.ts: creating API keys, creating and
deleting MCP tokens, registering, rotating and deleting OAuth clients,
approving an app and ending a connected app, changing the name, address or
picture, and enrolling, renaming or deleting passkeys. Password, 2FA,
account deletion, sessions and the own AI connection were refused already.

The demo account's language is fixed to English: a single settings write of
the language answers unchanged, a bulk save drops it and keeps the rest. The
MCP settings tool is held back for the demo account by the tool gate, as
every write tool is. The admin of a demo instance and every real instance
are untouched.
2026-10-24 23:22:15 +00:00
Maurice 53bd21a7d7 test(assistant): a changed journal entry can be undone
update_journey_entry answers the fields it replaced, so its card is
undoable now, as JRN-015 already checks for the undo itself.
2026-10-24 22:54:46 +02:00
Maurice 67d8f22622 test(assistant): the catalog check lists the Dawarich tools too
A stay taken into a journal now has a card of its own, so ASTTOOL-001
looks for its tool; Dawarich's tools are listed only with its addon on,
which the test now turns on beside the others.
2026-10-24 22:54:46 +02:00
Maurice 13449c3338 fix(assistant): no awaits in loops and no value only used as a type in the journal code
The journal header's tool list was a value read only for its type, so it is
a union now. A journey's session reads the entries a call names side by side,
the photo announcements go out together, and a photo move links its photos
one after another through a promise chain, so each still takes the next
place among the target's photos.
2026-10-24 22:54:46 +02:00
Maurice 35c3ab4bd7 fix(assistant): a journey's session no longer attaches delete_journey
isHeldInJourney took every tool of the journey's controllers from the Studio
side, delete_journey among them. The Studio never offered it (its writes are
the book's), so leaving it unattached changes nothing the model sees and
keeps the denial in one place.
2026-10-24 22:54:46 +02:00
Maurice 7356de5124 fix(journey): give the patched column shapes an index signature presenceSet accepts
presenceSet takes a Record<string, unknown>; an interface has no implicit
index signature, so the two column shapes are type aliases instead.
2026-10-24 22:54:46 +02:00