feat(ai): add gemini-3.7-flash with thinking level mapping and update google defaults - #1452
feat(ai): add gemini-3.7-flash with thinking level mapping and update google defaults#1452Kenmege wants to merge 47 commits into
Conversation
cleanupResources killed the kernel and removed its temp directory in the same
synchronous pass, so dispose() resolved while the child was still exiting. The
kernel is spawned with cwd set to that directory; Windows keeps it locked until
the process is really gone, so a caller deleting it after an awaited dispose()
got EPERM.
The defect is not Windows-specific. Nothing ever waited for "exit", so the
promise resolved early everywhere; Unix only hides it by unlinking files that
are still open.
dispose() now defers temp-dir removal, waits for the process to actually exit,
then removes the directory. Direct children are awaited on their "exit" event;
a forked kernel is not a direct child and emits no "exit", so its pid is polled
the same way forkedKernelDied checks liveness. Both paths are bounded by
KERNEL_EXIT_TIMEOUT_MS so a wedged kernel cannot hang disposal.
Removal retries explicitly. rmSync's own maxRetries does not cover this case:
the native implementation surfaces the directory-level EPERM without retrying.
disposeSync is unchanged. It runs from process.on("exit") where nothing async
can be awaited, so it keeps the previous best-effort synchronous removal.
fixes PrimeIntellect-ai#1049
…nd keep one failed worker from failing global heartbeats_list Two defects combined to make a single stale descriptor break every global heartbeat listing with "Cannot list heartbeats while session worker is failed" (PrimeIntellect-ai#1045): - stopWorker trusted kill(pid, 0) (EPERM included) as proof the worker was still running and never checked the descriptor's recorded processStartId, unlike the recovery path. After a worker exited, a pid-reusing (or EPERM-answering) unrelated process made the stop path signal the imposter's process group, wait out both deadlines, and persist lifecycle "failed" with "did not stop after SIGKILL" -- across supervisor restarts. - The global heartbeats_list fan-out included failed workers (isVisibleWorker only excludes client-owned ones) and returned the first failure snapshot as the whole command's result, so one zombie descriptor poisoned the entire listing while session-scoped listings kept working. stopWorker now verifies the pid's process start id against the descriptor before signalling or waiting on it, treating an identity mismatch as an already-stopped worker, and heartbeats_list skips failed workers, which cannot host firing heartbeats. Closes PrimeIntellect-ai#1045
…ntity at each stop-path signal Address both review findings on the initial identity fix: the tombstoned descriptor adoption path in adoptOrRecoverWorker sent an unconditional SIGKILL to the descriptor's pid before stopWorker ran, so a recycled pid could still be signalled during supervisor restart -- the exact incident path. It now checks workerDescriptorProcessIdentityMatches first. stopWorker also no longer caches the identity verdict in a boolean computed before the shutdown request: the worker can exit during the graceful wait and its pid be reassigned, in which case the cached "verified" flag would have followed the replacement process into SIGKILL. isWorkerProcessAlive now re-reads the process start id on every liveness check, immediately before each signal, narrowing the check-to-signal race to the kill(2) call itself. The stop-identity regression test now also covers the adoption path with a tombstoned descriptor and asserts the bystander process survives and the worker does not end up lifecycle "failed".
… to suite/regressions Move the process identity and heartbeat aggregation regression tests to the prescribed location under test/suite/regressions/ with the required <issue-number>-<slug>.test.ts naming convention. This consolidates all PrimeIntellect-ai#1045 regressions into a single file: - stopWorker identity verification for recycled pids - adoptOrRecoverWorker pre-kill identity guard - heartbeats_list skipping of failed workers
Tests moved to test/suite/regressions/1045-failed-worker-poison.test.ts
Test moved to test/suite/regressions/1045-failed-worker-poison.test.ts
…able When a descriptor has a recorded processStartId but getProcessStartId() returns undefined (e.g., /proc unavailable, ps failures), we now refuse to signal rather than assuming the pid belongs to our worker. This prevents accidentally signalling an unrelated process when the identity verification system itself cannot function. Old workers without processStartId remain trusted for backward compatibility. The three conditions in workerDescriptorProcessIdentityMatches now: 1. No recorded ID → trust (backward compat with old descriptors) 2. Process dead → harmless to proceed (signal will fail with ESRCH) 3. Have recorded ID but can't observe → REFUSE (can't verify = don't signal) 4. IDs match → signal 5. IDs don't match → don't signal
Split process identity checks into two functions with different semantics: 1. workerDescriptorProcessIdentityMatches() - for signaling decisions Returns true only for verified 'match', false for 'mismatch' or 'unverifiable'. Used before SIGTERM/SIGKILL to avoid signalling wrong processes. 2. workerDescriptorProcessMightBeAlive() - for cleanup decisions Returns true for 'match' or 'unverifiable', false only for verified 'mismatch'. Used in wait loops and final liveness check to avoid deleting descriptors of possibly-live workers. This fixes the issue where returning false for unverifiable identity caused stopWorker to skip the wait loop and delete the worker as though it had exited, leaving live workers untracked. The underlying workerDescriptorProcessIdentityCheck() returns a tri-state: - 'match': verified, process is ours - 'mismatch': verified, process is NOT ours (recycled pid) - 'unverifiable': can't check (old descriptor or platform limitation)
…rendering The portable start-time listing (ps -o lstart=) renders local time, so the same live worker produced a different identity when the supervisor restarted under a different TZ or locale - the mismatch was read as PID reuse, adoption skipped signalling, and the descriptor of a live worker was deleted, leaving it untracked. The process query now pins TZ=UTC and LC_ALL=C, and the token format is versioned (ps2:) so a legacy ps: token recorded by an older build degrades to the unverifiable tri-state instead of a false mismatch: the worker stays tracked and unsignalled until same-format evidence exists. Same-format inequality remains a trusted mismatch. Red-green verified: without the cross-format degradation, the legacy-token test observes the live worker's descriptor being reaped.
Expose pause and resume through the goal host bridge and Python skill so an agent can yield without completing its objective while external input is pending. Reuse the persisted paused state, clear queued goal contexts, and teach the continuation prompt to pause instead of emitting holding turns. Signed-off-by: Christian Stewart <christian@aperture.us>
A thinking stream settled into emitting "The the the the the the the " back to
back 2,366 times, 79,222 characters, and stopped only when the user aborted by
hand. No layer owned this: provider streamers are faithful assemblers and never
inspect content, request construction attaches no repetition penalties, and the
agent loop treats a completed stream as progress. A runaway response could burn
the whole 32k output cap.
Adds a stream-level guard on the reasoning channel of openai-completions. Two
detectors:
- Periodic tail. The tail is one short unit repeated many times, found with the
KMP failure function, which gives the smallest period in O(n) with no scan
over candidate lengths.
- Novelty stall. Distinct word trigrams over total, for loops that drift enough
that verbatim periodicity misses them.
The novelty floor is calibrated rather than guessed. Measured over the corpus in
the tests:
loops verbatim 0.001 drifting 0.136
legit enumerated analysis 0.286 markdown table 0.485 JSON 0.513
source code 0.611 numbered list 0.671 prose 1.000
0.20 sits in that gap. Word-trigram Jaccard between paragraphs was tried first
and rejected: drifting loops scored 0.38-0.58 and structurally similar
legitimate paragraphs scored in the same band, so no threshold separated them.
False positives are the real risk, since a wrong abort destroys real work, so
the tests assert that code, markdown tables, numbered lists, JSON, prose and
enumerated analysis do not trip it. The text channel is deliberately left
unguarded: a long legitimate answer can contain generated tables or code.
On a hit the stream fails with a new degenerate_output failure kind rather than
committing the garbage. Kill switch: PRIME_AGENT_NO_REPETITION_GUARD=1.
Also wires recordStreamFailure into the openai-completions terminal catch.
Every other provider already called it; this one did not, so failures on the
most widely used path (OpenRouter, llama.cpp, any OpenAI-compatible endpoint)
reached the session with no classification at all. The new kind depends on it,
but this fixes classification for every existing kind on that provider too.
fixes PrimeIntellect-ai#1029
…tensions Completes workstream 8 of the elite reliability plan: phase calibration, the human-extension lease lane, and their monitor/CLI surface. - operation-calibration: group terminal operations by kind and timeout class, report p50/p95/p99 and an advisory hard cap, and gate hard enforcement on minimum canary samples with zero uncertain outcomes or uncertain cleanups. The verdict stays telemetry_insufficient until that bar is met, so advisory caps never silently become enforcement. - operation-extension-inbox: append-only, restart-safe request/receipt records for capped human deadline extensions. - daemon sweeps the inbox and applies extensions through the ledger; the reliability monitor settles requests whose operation is no longer open. - pi monitor gains --calibration and --extend <id> --minutes <1-60>. The inbox creates its directory on first write rather than in its constructor. Building it eagerly in the AgentDaemon constructor made an unusable reliability directory fatal to daemon construction, which regressed the snapshot-cache replacement fallback. Both sweep call sites now degrade instead of throwing, so a broken extension lane can never stop the deadline watchdog. Verification: literal root `npm run check` passes; operation-ledger, operation-calibration, operation-extension-inbox, reliability-monitor and daemon-mode suites pass 205/205. The full coding-agent suite's only failures are three model-catalog regressions that also fail on a pristine tree at 059a842 and are unrelated to this change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TuxixGsgf1bVvxrpWJn7zB
…r saw finish Remediates defects found by independent adversarial review of the mission branch. Each fix has a regression test that fails against the previous commit. - closeAll can no longer promote a still-open operation to `completed`. A tool whose end event never arrived was being recorded as a clean success whenever its session closed with reason "completed", and those fabricated records then fed calibration as evidence of reliability. Survivors now terminalize as `uncertain`; `completed` is reachable only through the operation's own end event. - Calibration eligibility no longer opens by forgetting. Terminal records are trimmed to a bounded window, so `uncertainOutcomeCount === 0` returned to true once an uncertain record aged out, certifying the class canary-ready on the strength of evidence that had been discarded. Eligibility now reads monotonic per-group lifetime counters that trimming cannot touch, expressed as an uncertainty rate. Percentiles stay windowed, since recent latency is what an advisory cap should track. - A human deadline extension applies at most once. The sweep applied the extension and then wrote the receipt; if the receipt write failed the request stayed pending and re-applied on every tick, consuming the whole renewal cap. Requests are now durably claimed before they are applied, so an unwritable inbox grants zero extensions. - The monitor's liveness rule agrees with the ledger's. It compared start ids with `===`, so a legacy `ps:` token read against the current `ps2:` rendering counted as a mismatch and declared a live daemon missing. It now uses compareProcessStartIds, where an unverifiable comparison is not a mismatch, matching operation-ledger.ts. A missing process is also reported alongside the snapshot's other alerts rather than replacing them, so one liveness misjudgement can no longer discard every real deadline alert. - The notification outbox survives concurrent writers. It rewrote the whole file from constructor-time state, so an alert already on disk could be erased by an `--ack` from another process. Writes now re-read and merge per record. Verification: literal root `npm run check` passes. Focused daemon/reliability suites 6 files, 213 tests, all passing. Full package suite 4091 passed with 3 failures, which are the model-catalog tests that also fail at the untouched base a18809e. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TuxixGsgf1bVvxrpWJn7zB
…ldown Split out of the elite reliability branch so the lockfile churn can be reviewed on its own rather than mixed into daemon work. Adds overrides for three transitive dependencies carrying advisories that reach the runtime dependency tree, and moves undici to ^7.29.0 in both packages that depend on it. Production `npm audit --omit=dev` drops from four high plus one moderate to the single moderate self-package advisory, which is CVE-2026-54325 and is tracked separately. ip-address is pinned to 10.4.0, not the current 10.5.0. This repository sets `min-release-age=7` in .npmrc — a deliberate supply-chain cooldown that refuses to resolve versions published in the last seven days. 10.5.0 was published on 2026-08-10, hours before this change, and a clean `npm install` against it fails with ETARGET. 10.4.0 was published 2026-07-31 and already carries the fixes for all three ip-address advisories, so the cooldown costs nothing here. The lockfile was regenerated with no node_modules present. Regenerating with an installed tree resolves only the host platform and silently drops 45 cross-platform optional binaries, which would leave the lock unable to install on Linux or Windows. The committed lock retains them. Remaining deltas against the base lock are dependency hoisting plus the removal of the android-arm64 and wasm32-wasi rolldown bindings and their emnapi/wasm fallbacks. Two high-severity advisories remain in devDependencies only (nanoid, postcss) and are not addressed here. Not verified by an install: node_modules in this worktree still reflects the previous lock. Run `npm ci` in a clean checkout before relying on this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TuxixGsgf1bVvxrpWJn7zB
…oundary Project-provided instructions and executable resources were loaded from any working directory without consent. Trust is now resolved for the canonical cwd before project settings, resource discovery, or daemon-bound runtime services are created, and re-resolved whenever the cwd changes. The gate covers project settings, packages, extensions, skills, prompts, themes, SYSTEM.md/APPEND_SYSTEM.md, ancestor AGENTS.md/CLAUDE.md, and non-user .agents/skills. Decisions are keyed by canonical path in trust.json with ancestor inheritance; an unreadable or invalid store fails closed with a visible diagnostic. The interactive prompt appears only where the directory or an ancestor actually holds a trust-requiring resource, and --approve/-a and --no-approve/-na override a single run without persisting. Also in this change: - Carry the trust decision across daemon protocol 8 / schema revision 16, with create gated on protocol 8 in both directions rather than silently starting with mismatched trust semantics. - Make the operation ledger durable: validated checkpoint journal, snapshot-plus-journal recovery, torn-final-line tolerance, corrupt-interior warnings, exact-once reconciliation, and monotonic uncertainty counters that survive compaction. - Settle human deadline extensions through an atomic one-winner inbox claim. - Make the notification outbox restart-safe: reload under lock, atomic delivery cycles, acknowledgement precedence, and a durable 1/2/4/8/15-minute retry schedule. A corrupt outbox now fails loudly instead of being silently replaced with an empty one. - Add a repository-owned launchd monitor service with install/uninstall/status, packaged-runner validation, and 180-second stale detection. Its shell runner and the Node writer share one state mutex, and it no longer loses the monitor's exit code when that lock is contended. - Share one synchronous file-lock helper across the trust store, extension inbox, notification outbox, and monitor state, waiting on the monotonic scheduler rather than spinning on the wall clock. - Remove degenerate model-test coupling to ambient Google/Groq credentials. - Update nanoid to 3.3.17, postcss to 8.5.23, and undici to 7.29.0 within the supply-chain cooldown, and declare @opentelemetry/api for clean-install browser bundling. - Require every repository file, inherited work included, to enter a commit, while never committing local machine state (AGENTS.md). Uncommitted inherited work was being left behind as "caution" when it is the only unrecoverable state. Verified: npm run check exit 0; full coding-agent suite 319 files, 4163 tests passing, 58 skipped, matching the pre-change skip count. Each regression test added here was proven to fail with its own fix reverted.
# Conflicts: # packages/coding-agent/CHANGELOG.md
The blanket build prohibition is unworkable for two cases this repo actually has. packages/agent resolves through main: ./dist/index.js and the pi-* packages resolve via node_modules/@earendil-works symlinks into packages/*, so both --dist and tsx source mode load built artifacts: a locally installed agent cannot run current code without a build. And the full suite cannot pass from a fresh npm ci without one, failing extension loading with a missing pi-agent-core/dist/index.js, which is why every CI workflow runs npm ci -> npm run build -> npm run check. Both uses are audited and must be named in the receipt. Routine work still does not build.
Regenerated by npm run build against live provider data. Drops delisted entries including claude-opus-4-1, gemini-2.5-pro, gemini-2.0-flash and nemotron-3-ultra; adds current ones including grok-4.5, kimi-k3, gemini-3.6-flash, deepseek-v4-flash and qwen3.8-max. Kept as its own commit so the catalog can be reverted independently of the upstream reconciliation if a removed model is still referenced somewhere.
--approve/-a and --no-approve/-na were parsed but never shown, so the only discoverable reference was docs/usage.md.
The ai package gained a degenerate-generation abort, a regenerated model catalog with removals, and dependency changes, all with an empty [Unreleased]. Each package owns its own changelog, so these belong here rather than only in the coding-agent one.
The previous bullet read as though claude-opus-4-1, gemini-2.5-pro and gemini-2.0-flash were removed outright. They were not: the regeneration refreshes per-provider listings. claude-opus-4-1 dropped from anthropic and opencode but is still reachable via cloudflare-ai-gateway, gemini-2.5-pro dropped from github-copilot but remains on google and google-vertex, and gemini-2.0-flash dropped from google but remains on google-vertex. Only nemotron-3-ultra left the catalog entirely. Corrective commit rather than an amend; 114b96f is already published.
The build exception landed without its counterpart. A protected update reconciling this fork onto upstream can only be cleared against the whole tree, but the test rule still allowed nothing beyond user-named files, so the update protocol and this file contradicted each other. Cap the workers so the real-process daemon tests are not starved into a false failure.
prime-agent.sh exports PRIME_AGENT_BUILD_ID from the worktree's live git describe, and identity resolution preferred that environment value over the bundle's embedded __PI_BUILD_ID__. Committing without rebuilding and then restarting therefore made the daemon report the current checkout while it was still serving the older bundle, so the mismatch that is supposed to reveal a stale install became invisible. The embedded id is the only value that describes the code actually loaded. The environment now serves as the fallback for unbundled execution, where __PI_BUILD_ID__ is never substituted. Verified by reverting the precedence and confirming the new test fails.
packages/ai's build runs generate-models against live provider APIs, so every build rewrites tracked source with current pricing and leaves the tree dirty. Committing the drift so the working tree is clean.
packages/ai ran generate-models before every compile, fetching live provider and pricing data. Every build therefore rewrote tracked source and left the tree dirty, which made builds non-reproducible and stamped every locally built identity -dirty. It also broke release integrity: prepublishOnly rebuilds after the release commit and tag, so the published catalog was not the one in the tagged tree. The ordinary build now compiles the checked-in catalog with no network access. Refreshing it is an explicit step, and release.mjs runs it before the version bump so the refreshed catalog lands in the release commit itself. Verified: two consecutive builds leave git status unchanged.
Rebase private-lane opts onto upstream 965941c (v0.7.2 + worker lifecycle PrimeIntellect-ai#850/PrimeIntellect-ai#851/PrimeIntellect-ai#852, queue edit PrimeIntellect-ai#838, reasoning metadata, deps). Preserved: project trust, operation ledger, reliability monitor, build-id authority, repetition guard, AGENTS.md protected-update exceptions. Conflict policy: - CHANGELOGs: deduplicated union under [Unreleased] - typebox: upstream ^1.3.9; keep @opentelemetry/api for Mistral clean-install - models.generated: upstream catalog - daemon protocol: v8 + schema 18 (upstream revs 15-16 + local ledger/trust 17-18) - daemon-supervisor: upstream stop/finalization + local adopt SIGKILL + identity helpers
Conflict resolution left SIGKILL/stopWorker nested inside the identity backfill branch and dropped the closing brace, leaving the file one brace deep. Also resync package-lock for the kept @opentelemetry/api dep.
- schema revision 18 with computed SCHEMA_ID covering upstream queue/stop revisions plus local ledger/trust - processIdentity uses compareProcessStartIds so legacy ps: tokens stay unverifiable instead of treated as recycled pids - heartbeats_list skips failed workers (issue PrimeIntellect-ai#1045) - adopt path relies on upstream identity-aware stopWorker (no pre-SIGKILL)
This reverts commit f754efb.
# Conflicts: # packages/coding-agent/src/modes/daemon/daemon-catalog-process.ts # packages/coding-agent/src/modes/daemon/daemon-mode.ts # packages/coding-agent/test/daemon-catalog-process.test.ts # packages/coding-agent/test/daemon-mode.test.ts
Sync the zai section of the model snapshot with the models.dev catalog: adds glm-5.3, served on the coding plan endpoint since 2026-08-14. Other provider sections are left untouched.
Running the suite from inside a live Prime Agent daemon worker (an agent asked to run the tests by its own kernel) leaked live-session state into both in-process main() calls and spawned CLI children, failing 24 tests across 6 files identically at the merge tip, the pristine pre-merge tip, and the installed worktree: - NO_COLOR + FORCE_COLOR both set -> spawned node binaries warn on stderr -> 9 empty-stderr assertion failures in 4685-daemon-client-modes - RLM_MAX_DEPTH from the worker env -> AgentSession max-depth source "env" instead of "default" -> agent-session-recursion failure - PRIME_AGENT_INTERNAL_DAEMON_SUPERVISOR_SOCKET -> resolveUpdateDaemonSocketPath() bypassed TMPDIR/agent-dir redirects -> self-update probed the developer's real daemon and refused on live busy sessions -> 4 package-command-paths failures - PRIME_AGENT_INTERNAL_* worker identity env inherited by spawned test daemons -> slow/failed supervisor handshakes -> 10 timeouts across daemon-supervisor-process, 4600-supervisor-singleton, 4606-update-restart-coordinator Fix: test/setup-env.ts (vitest setupFiles) deletes the color conflict, the RLM session/harness vars, and the PRIME_AGENT_INTERNAL_/PI_INTERNAL_ worker identity class before any test module loads. Tests that need these vars set their own after setup. Verified: six affected files green with polluted env + resident daemon (157 passed/8 skipped), then full canonical suite (--maxWorkers=5) green in the same conditions: 328 files passed / 9 skipped, 4294 tests / 60 skipped / 0 failed, 114s.
…te google defaults
|
Hi @Kenmege, thanks for your interest in contributing! This project requires that pull request authors are vouched, and you are not in the list of vouched users. This PR will be closed automatically. See https://github.com/PrimeIntellect-ai/prime-agent/blob/main/CONTRIBUTING.md for more details. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8978a50e51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /** Create a SettingsManager from an arbitrary storage backend */ | ||
| static fromStorage(storage: SettingsStorage): SettingsManager { | ||
| static fromStorage(storage: SettingsStorage, options: SettingsManagerCreateOptions = {}): SettingsManager { | ||
| const projectTrusted = options.projectTrusted ?? true; |
There was a problem hiding this comment.
Default project settings to untrusted
When callers omit the new option, this defaults to trusted and immediately reads project settings. The public createAgentSession() SDK path does exactly that in core/sdk.ts:166, then reloads a DefaultResourceLoader, so opening an untrusted checkout through the SDK can still execute extensions and packages configured by that checkout without any trust decision; the early config/package command handlers have the same omission. Default this to false or require callers to pass an explicit resolved decision rather than preserving the old trust behavior.
AGENTS.md reference: AGENTS.md:L18-L19
Useful? React with 👍 / 👎.
| const startupSettingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted: false }); | ||
| reportDiagnostics(collectSettingsDiagnostics(startupSettingsManager, "startup session lookup")); | ||
| const projectTrustResolver = createMainProjectTrustResolver({ |
There was a problem hiding this comment.
Resolve trust before running project migrations
When normal startup begins in an untrusted checkout containing .prime/agent/commands, runMigrations(cwd) at line 1248 runs before this trust resolver is created. migrateExtensionSystem() then inspects project resource directories and can rename commands/ to prompts/ before the user sees the trust prompt, so choosing “Do not trust” still allows the checkout to trigger filesystem mutations. Resolve trust first, or defer project-scoped migrations until the project is trusted.
Useful? React with 👍 / 👎.
| ...(operationSummary || activeSession.summaryClassifierState | ||
| ? { | ||
| reliability: { |
There was a problem hiding this comment.
Gate reliability metadata on the negotiated capability
When a protocol-7 client without operation_ledger_v1 uses list, attach, or get_state, this code still includes the new reliability shape because summaryForActiveSession() has no client-capability context. The repository-wide search shows isOperationLedgerNegotiated() is used only by protocol tests, so the declared capability never controls the wire payload and strict older clients can reject responses they are still allowed to request. Strip this field unless both sides negotiated the capability, or make every response carrying it protocol-incompatible.
AGENTS.md reference: AGENTS.md:L41-L45
Useful? React with 👍 / 👎.
| get(cwd: string): ProjectTrustDecision { | ||
| return withTrustFileLock(this.trustPath, () => { | ||
| const data = readTrustFile(this.trustPath); | ||
| let currentDir = canonicalizeDirectory(cwd); |
There was a problem hiding this comment.
Bind saved trust to the lexical resource ancestry
When a previously trusted real directory is opened through a symlink under a different, untrusted ancestor, canonicalizing cwd here returns the saved true before that lexical ancestry is considered. loadProjectContextFiles() deliberately walks the lexical path in resource-loader.ts:98-112, so it then loads AGENTS.md or CLAUDE.md from the symlink's untrusted parent without prompting; for example, /untrusted/repo/link -> /trusted/project inherits /trusted/project's decision but loads /untrusted/repo/AGENTS.md. Canonicalize resource discovery too, or include the lexical ancestry when resolving saved decisions.
Useful? React with 👍 / 👎.
Summary
Adds full support for
gemini-3.7-flashwith thinking/reasoning effort mapping across Google Generative AI and Google Vertex AI providers, and setsgemini-3.7-flashas the default model for both providers.Key Changes
packages/ai/scripts/generate-models.ts:thinkingLevelMapfor Gemini 3.x Flash models (gemini-3.7-flash,gemini-3.6-flash,gemini-3.5-flash, etc.) to include{"off": null, "minimal": "MINIMAL", "low": "LOW", "medium": "MEDIUM", "high": "HIGH"}.gemini-3.7-flashundergoogle-vertexprovider and added fallback generator registration forgoogle.packages/coding-agent/src/core/model-resolver.ts:defaultModelPerProviderforgoogleandgoogle-vertextogemini-3.7-flash.packages/ai/test/google-gemini-37-flash.test.ts:gemini-3.7-flashregistration, reasoning capabilities, and thinking level clamping ongoogleandgoogle-vertex.Changelogs:
packages/ai/CHANGELOG.mdandpackages/coding-agent/CHANGELOG.md.Verification
npm run checkpasses 100% cleanly.packages/ai/test/google-gemini-37-flash.test.tsunit tests pass.models.generated.tsverified for accurate model metadata.Note
Add gemini-3.7-flash with thinking level mapping and update Google provider defaults
gemini-3.7-flashto bothgoogleandgoogle-vertexproviders in generate-models.ts with reasoning enabled and a fullthinkingLevelMap(minimal/low/medium/high); updatesdefaultModelPerProviderin model-resolver.ts fromgemini-3.1-pro-previewtogemini-3.7-flash.applyThinkingLevelMetadatato emit explicit MINIMAL/LOW/MEDIUM/HIGH thinking level constants in the generated catalog.StreamFailureErrorof kinddegenerate_output.gemini-3.7-flashinstead ofgemini-3.1-pro-preview, which may change response quality and cost.Macroscope summarized 8978a50.