Commit Graph
7091 Commits
Author SHA1 Message Date
Daniel Salazar 2d75058441 Limit only Gemini TTS text to 3000 characters; charge overrun replies
The 3000-character text cap moves from the TTS driver into the Gemini
provider, so other providers keep their own limits.

The Gemini reply cap rises to 64 MiB, which fits the full 16,384-token
audio budget. A reply that still overruns it or times out reports no
usage, so it is charged the held budget and the error tells the caller
to split the text.
2026-10-17 00:27:54 -04:00
404oops 7c65f97a8f Clarify speech accounting for bounded responses 2026-10-17 00:27:54 -04:00
404oops 1d188a02b5 Reserve the published Gemini speech token budget 2026-10-17 00:27:54 -04:00
404oops 689aed2a60 Clarify speech settlement for unreadable responses 2026-10-17 00:27:54 -04:00
404oops 33c84b4f1b Validate speech requests and settle reported Gemini usage 2026-10-17 00:27:54 -04:00
404oopsandClaude Opus 5.5 f80f479a19 style(ai-tts): keep Gemini cost comment prettier-clean
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 00:27:40 -04:00
404oops 98140ca09f Clarify Gemini speech instructions 2026-10-17 00:27:40 -04:00
404oops b4629f7aa7 fix(ai): keep Gemini speech instructions separate from transcript 2026-10-17 00:27:40 -04:00
Daniel Salazar dbf851badf Bill Gemini 2.5 Pro at its current list rates
Cache reads are $0.125/M, and prompts over 200k tokens bill every rate at
the long-context tier ($2.50 in, $15 out, $0.25 cached).
2026-10-17 00:27:23 -04:00
404oops 9843f26c84 Exclude deprecated Flash Image additions and share scheduled pricing 2026-10-17 00:27:23 -04:00
404oops 024d233164 feat(ai): restore available Gemini models and align pricing 2026-10-17 00:27:07 -04:00
Daniel Salazar dda3c52fe2 Keep Gemini extra_content off other providers; report Gemini timeouts as 504
Replayed tool calls only carry extra_content for providers that opt in
(Gemini), so OpenAI-compatible and Responses vendors don't see an unknown
field. The native Gemini client now owns its request deadline: the SDK's
own timeout aborted without a reason and read as an internal error. A
deadline timeout returns 504 upstream_timeout and leaves the route in
rotation.
2026-10-16 21:22:01 -07:00
404oops ea7cfab92d Describe provider-specific chat timeout boundaries 2026-10-16 21:22:01 -07:00
404oops 2caa83b6c1 Keep Gemini tool metadata out of Claude requests 2026-10-16 21:22:01 -07:00
404oops 97487e7ce1 Bound unary Argon requests and reject unsupported content 2026-10-16 21:22:01 -07:00
404oops 2bc4106e13 Refer model specifications and pricing to the directory 2026-10-16 21:22:01 -07:00
404oops 46d1395715 fix(ai): preserve Gemini native completion and refusal reasons 2026-10-16 21:22:01 -07:00
404oops ed51042820 test(ai): isolate Argon HTTP smoke test from optional extensions 2026-10-16 21:22:01 -07:00
404oops 10aaf4dfec feat(ai): add Gemini 4 Argon with native usage metering 2026-10-16 21:22:01 -07:00
Daniel Salazar ea5903413b Raise a low alarm when a provider denies model access
A 403 model_not_found still returns 400 upstream_bad_request, but now
alarms at info so a lost provider entitlement gets noticed. HttpError
gains an alarmSeverity option the terminal alarm gate honors.
2026-10-16 21:22:00 -07:00
404oops f2445fdd2d Handle model access denials and filter batch chat variants 2026-10-16 21:22:00 -07:00
Reynaldi ChernandoandClaude Opus 5.5 471b900462 remove private access routing from docs (#4252)
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 20:14:21 +07:00
Daniel Salazar 2b254b8892 fix: misc bugs (#4251)
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
2026-10-15 23:49:17 -07:00
Neal Shah 2a15afc570 Resolve PUT-2059 (#4250) 2026-10-16 01:45:56 -04:00
dependabot[bot] f9860b036b chore(deps-dev): bump prettier from 3.9.9 to 3.9.10 (#4240)
Notify HeyPuter / notify (push) Canceled after 0s
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Bumps [prettier](https://github.com/prettier/prettier) from 3.9.9 to 3.9.10.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.9.9...3.9.10)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.9.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 14:46:31 -07:00
dependabot[bot] 76e1f79b5e chore(deps): bump smtp-server from 3.19.17 to 3.19.21 (#4242)
Bumps [smtp-server](https://github.com/nodemailer/smtp-server) from 3.19.17 to 3.19.21.
- [Release notes](https://github.com/nodemailer/smtp-server/releases)
- [Changelog](https://github.com/nodemailer/smtp-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/smtp-server/compare/v3.19.17...v3.19.21)

---
updated-dependencies:
- dependency-name: smtp-server
  dependency-version: 3.19.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 14:43:54 -07:00
dependabot[bot] 943a3427c6 chore(deps-dev): bump @types/busboy from 1.5.4 to 1.5.5 (#4241)
Bumps [@types/busboy](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/busboy) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/busboy)

---
updated-dependencies:
- dependency-name: "@types/busboy"
  dependency-version: 1.5.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 14:38:42 -07:00
dependabot[bot] 38469a3615 chore(deps): bump libphonenumber-js from 1.13.14 to 1.13.15 (#4239)
Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.13.14 to 1.13.15.
- [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.13.14...v1.13.15)

---
updated-dependencies:
- dependency-name: libphonenumber-js
  dependency-version: 1.13.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 14:35:15 -07:00
dependabot[bot] a4d4a5595e chore(deps-dev): bump vite from 8.1.5 to 8.1.6 (#4238)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.1.5 to 8.1.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v8.1.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.1.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.1.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 14:35:07 -07:00
dependabot[bot] de69269b10 chore(deps): bump uuid from 14.0.2 to 14.0.3 (#4237);'''"????????????????????
Bumps [uuid](https://github.com/uuidjs/uuid) from 14.0.2 to 14.0.3.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v14.0.2...v14.0.3)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 14.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 13:25:49 -07:00
Neal Shah 8faff74793 PUT 2057 and PUT 2068 (#4245)
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
2026-10-15 02:02:00 -04:00
Neal Shah e5ca303c50 PUT-1903 (#4226) 2026-10-14 20:29:55 -04:00
Juan Fernando Castro c6c0dd5e29 fix: bound how many accounts a team owner can provision (#4223)
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
* feat: bound provisioning by what an owner may mint, not only what is live

Seat and team caps express how much may exist at one time. This adds the
other half of the rule: how much an owner may create over a window, and the
checks a provisioned account answers to.

- Provisioning puts each seat through `SignupService.runSignupGate`, the same
  extension-owned gate a signup answers, and refuses what it blocks. It fails
  closed, since a check that could not run is not a check that passed.
- A per-owner budget over a rolling window, sized to every seat the owner may
  hold live across every team they may own, times the churn allowed on top.
  It is spent on creation and is not returned.

Keyed on the owner's uuid so a recycled id cannot inherit someone else's
spend, and charged after validation so a taken username costs nothing.

* refactor: tighten the provisioning gate and budget after review

- The gate runs before the seat-cap lock. A listener has no deadline and the
  lease is ten seconds with nothing to renew it, so the lock must not be held
  across one.
- `failOpen: false` rethrows rather than returning false, so a backend outage
  is answered 503 instead of escaping the handler.
- An address goes through `validateEmail` first, as it does on every other
  path that creates an account.
- The gate always runs; a request only enriches what it is told, so one being
  absent is no reason to skip it.
- The gate is told it is looking at a seat, whose address is optional.
- A refusal carries the gate's own code and request code, as a blocked signup
  does, so support can correlate it.
- Restored `provisionAccount`'s docblock, which an insert had displaced.

Tests: the spy restores in `finally`, and the cap overrides are taken after
the fixtures, so one failure cannot cascade through the file.

* fix: show a provisioning refusal as a rule, not a failure

The console special-cases the seat cap and sends everything else to
"Something went wrong", which reads as a fault rather than an answer. The
provisioning budget refuses the same way the cap does, so it is presented
the same way.
2026-10-14 11:54:35 -04:00
Juan Fernando Castro e32bfa839d fix: count one app open per account per app per hour (#4152)
* fix: count one app open per account per app per day

`app_opens` is read two ways at once: `open_count` is a row count and
`user_count` is distinct accounts. A repeated open moves the first
without the first moving the second, and the incentive report prices
opens.

An open is now marked as it is recorded and skipped for the rest of the
day, before both the row and the event ClickHouse ingests, so the two
stores agree. The marker is set only when absent, so the first open of
the day wins a race; an unreachable marker counts the open, since
counting twice beats not counting.

* fix: count one app open per account per app per day, at the count

Dropped the row-suppression approach. `app_opens` is not only a counter:
`getRecentAppOpens` orders the desktop's recent list by `MAX(_id)`, and
`app.opened` is the socket event other tabs reorder on. Suppressing the
repeat row froze both at the first open of the day.

Every open is recorded as before. `open_count` counts each account once
per day instead, which is the figure `user_count` is read against.

`countDistinctUserDays` folds the pair into one number because
`COUNT(DISTINCT a, b)` is MySQL-only, and `dayBucket` covers MySQL's
decimal division. ClickHouse has uniqExact over the tuple.

Note the figure's meaning changes at deploy: a period spanning it mixes
rows with account-days, so a comparison across that point is not one.

* fix: count one app open per account per app per hour

Review feedback: a day is too long a window for the repeat to collapse
into. The period is now an argument rather than a baked-in 86400, held in
one constant on AppStore beside the other store policy numbers, so the SQL
and ClickHouse sites cannot drift and a future change is one line.

The fold `COUNT(DISTINCT user * N + bucket)` is only injective while the
bucket index stays under N. Hourly buckets are 24x the day index and pass
the old 1000000 in 2084, so N moves to 10000000.

Buckets are clock hours, not a rolling window, so two opens a minute apart
either side of the hour still count twice — tested, and the same property
the day version had at UTC midnight.

The detailed-stats fixture gave its repeat open a 60s offset, which under
hourly buckets would have counted twice whenever the suite ran in the first
minute of an hour. It now shares a timestamp with the open it repeats.
2026-10-14 11:54:17 -04:00
Daniel Salazar ff815f730d fix: harden token delivery, session revokes, app identity and fs scoping (#4229)
release-please / release-please (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
- relay sign-in popups take the opener origin from the referrer only
- session revokes read the primary, batch per user, and tombstone caches in every region
- wisp relay tokens bound to the minting session; verify rechecks the account
- hosted origins keep app identity with the site owner; deleted app uids recorded in deleted_apps
- subdomain cache tombstoned on delete, update, reclaim and app/account cascades
- email lookups require an exact address match after the SQL lookup
- workers deploy only from files the deployer owns
- share_app_data:false enforced at ACL time, plus copy/move/rename/share/recursive listing
- kv remove returns no value without read; kv:expire op grant usable
- fs errors name the entry instead of the owner's path
- shared-by-me drops rows a delegate no longer has authority over
- private apps can't move index_url onto another user's origin
- GUI: default apps saved and launched by uid; save picker accepts only copy/move; permission dialog waits for focus; Publish as Worker hidden on others' files
2026-10-14 06:56:44 -07:00
Juan Fernando Castro 84aaf005ec fix: give every route behind the user-protected gate a password budget (#4150)
* fix: give every route behind the user-protected gate a password budget

Five of the six routes behind the gate declare a per-user hourly bucket
for the password check. The sixth, delete-own-user, declared none.

The bucket moves into the gate itself, so it covers every route behind
it and a new one cannot be added without one.

It is charged by the outcome rather than by the request: a wrong answer
spends one and a right answer spends nothing, so a caller who knows the
password never meets the limit.

* fix: the review's findings on the password budget

Reading the budget and spending it on the outcome bounded rounds rather
than attempts: everything already in flight read the same budget and was
answered before any of it was spent. The charge lands before the
comparison now, so a burst is bounded by the same number as a sequence.

The key gained a route component. One bucket across all six meant ten
mistyped passwords on one route closed the other five for the hour,
including the one an account owing its team's 2FA has to reach.
2026-10-14 09:52:23 -04:00
Daniel Salazar f6a1e54642 fix(fs): keep S3 read stream errors from crashing the process (#4227)
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
getObjectStream now attaches an 'error' listener to every body it returns.
A body that fails before its consumer attaches (socket timeout, reset, or a
checksum mismatch on a truncated read) used to emit 'error' with no listener
and exit the process, failing every in-flight request on the task. It now
logs a warning; consumers that attach later still receive the error.
2026-10-13 17:42:28 -07:00
Filip Kujundžić d211a25c6d Merge pull request #4218 from HeyPuter/codex/put-1851-deepseek-peak
Backend Tests / changes (push) Canceled after 0s
Backend Tests / typecheck (push) Canceled after 0s
Backend Tests / test shard 1/4 (push) Canceled after 0s
Backend Tests / test shard 2/4 (push) Canceled after 0s
Backend Tests / test shard 3/4 (push) Canceled after 0s
Backend Tests / test shard 4/4 (push) Canceled after 0s
Backend Tests / test (main) (push) Canceled after 0s
Backend Tests / coverage (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
Protect direct DeepSeek peak-only pricing
2026-10-14 00:54:11 +02:00
404oops 2e1bf86d2b test(ai): protect direct DeepSeek peak-only pricing 2026-10-13 20:44:00 +02:00
404oops 8c31670453 Align ZAI modality metadata with source conventions 2026-10-13 20:43:58 +02:00
404oops 16d0ce8b3e Advertise supported image input for ZAI Flash models 2026-10-13 20:43:58 +02:00
404oops 8c64f54a87 Remove ignored-option paragraph from speech reference 2026-10-13 20:43:54 +02:00
404oops 7abd7b4417 Remove unsupported speaker reference option 2026-10-13 20:43:54 +02:00
404oops 29e0e1e2aa Clarify speech catalog units and cover ignored transcription options 2026-10-13 20:43:54 +02:00
404oops 4857898af4 Assert finite ElevenLabs catalog prices 2026-10-13 20:43:54 +02:00
404oops 526a250c95 Correct speech catalog pricing and legacy option declarations 2026-10-13 20:43:54 +02:00
404oops 8c18c45e63 feat(ai): refresh verified provider pricing catalogs 2026-10-13 20:43:43 +02:00
404oops 124f95a5f9 Label provider catalog fixtures as test data 2026-10-13 20:43:43 +02:00
Neal ShahandClaude Opus 5.5 4401b4c4dc Fix worker test (#4156)
* PUT-2012 fix broadcast service drops

* Revert pre-commit lint churn on files merged from main

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix test bug

* Remove other test

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 14:10:10 -04:00
Neal Shah 62270ff9aa Delete worker sessions when workers are deleted, don't treat sessions from deleted workers as still valid. (#4163) 2026-10-13 12:43:45 -04:00