chore(deps-dev): Update ruff requirement from <0.16,>=0.15 to >=0.15,<0.17 in /apps/api in the python group - #20
Closed
dependabot[bot] wants to merge 124 commits into
Closed
dependabot[bot] wants to merge 124 commits into
dependabot[bot] wants to merge 124 commits into
Conversation
…entity, and a production-hardening pass Bundles two bodies of previously-uncommitted work that share core files (main.py, services/runs.py, routers/runs.py, security.py); the "feature-only" state was never committed, so a faithful per-file split isn't possible — hence one commit. Features (already in the working tree before the hardening pass): - Generative-UI components: author HTML/CSS/props widgets exposed to agents as widget-tools; sandboxed iframe renderer; component frame on the run stream. - Embeddable chat widget: /embed page, publishable-key public router, floating launcher, frame-ancestors CSP. - End-user identity: server-minted session tokens, prompt awareness, REST tool entitlement gate. - GFM markdown structured responses. Hardening pass (2026-06-18) — full detail in docs/HARDENING-2026-06-18.md: - Security S1-S11: embed runs scoped by project; embed quota + per-IP limits; anonymous thread-takeover closed; body-identity role gate; code tool off by default + prod guard; fail-closed validate_production; SQL DSN SSRF guard; guarded OAuth token fetches; OAuth callback XSS escape; sanitized embed error frames; JWT kid/rotation + jti revocation + shorter TTL. - Correctness F1-F12: disconnect-safe run finalize; atomic quota admission; stale-run reaper; tracked/bounded webhook tasks; failure traces persisted; email/Teams thread continuity; per-thread run serialization; channel HITL handoff; app_event poller dedupe race; router/fanout dead-end logging; bounded + isolated + quota-gated evals; MCP cache TTL/invalidation/close; misc lows. - Production P1-P5 + ops: arq/Redis worker offload + per-tenant concurrency caps; Postgres checkpointer; single-leader scheduler; Dockerfiles + docker-compose + GitHub Actions CI + .env.example; idempotent Alembic 0002 migration; Redis-backed rate-limit/idempotency; /readyz + /livez + Prometheus /metrics; TrustedHost + trusted-proxy XFF; OTLP BatchSpanProcessor. Verified: 177 backend tests pass; ruff clean; web build clean; migration chain runs and is idempotent; adversarial diff review's one finding fixed + tested. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat+harden: generative-UI components, embeddable widget, end-user id…
…pped backfill Three latent bugs in the agent Q&A/FAQ path could silently turn a working knowledge lookup into "I don't have that info": - resolve_embedder silently fell back to FakeEmbedder (dim 256) for a real openai: model when the key was missing or the client failed to construct, flipping the dim-keyed Chroma collection with no signal. Now warns once per model in both fallback paths. - _ensure_qa_indexed skipped backfill on `count_where >= len(rows)`, which hid a missing/stale pair whenever the counts happened to match. Now indexes only the rows actually missing (id-diff via new ChromaStore.ids_where). - top_qa awaited the backfill outside its try/except (a failed re-index aborted the whole lookup) and create_qa swallowed its upsert error. Backfill moved inside the guard (degrades to no-match); both failures now logged. Tests: 26 passed (test_qa_vectorstore, test_knowledge, test_hybrid_search, test_fixes_2026_06_11). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix/qa retrieval hardening
- Add MIT LICENSE; set license to MIT in pyproject.toml and web/package.json - Rewrite root README: professional structure, feature tour with media (video + screenshots), quickstart, Docker, docs links - Remove internal/dated working docs from docs/ (audit, fixes, hardening, plans) - Remove internal _design_reference/ (research, design docs, chat log, UI prototype, screenshots) - Fix dangling references to removed design docs (ROADMAP, pyproject comment) - Normalize em-dashes to hyphens repo-wide Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Strip all emojis from headings, highlight bullets, feature list, and footer; fix table-of-contents anchors and the PRs-welcome badge link to match the plain-text headings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s direction - Restructure ROADMAP into Shipped / In progress / Planned (drop the internal dev-log) - Reflect now-shipped features (auth, full node catalog, channels, triggers, evals, generative UI, pgvector + Redis prod, fastembed) - Add forward-looking direction led by Connectors (one-click OAuth sign-in) - Update README roadmap description to match Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Updated video source link in README.md.
…ntext The production-shaped compose stack could not build/run as-is. Move the api/worker build context to the repo root and fix the driver/path assumptions that only held in a source checkout. - api/worker build context -> repo root (dockerfile: apps/api/Dockerfile) so the image can COPY packages/schemas, which lives above apps/api; schemas baked at /app/packages/schemas. - config.py: fall back REPO_ROOT -> API_ROOT when parents[3] is absent (the container flattens the tree to /app/forge); identical in a checkout. - migrations/env.py: map async drivers to psycopg v3 (+psycopg), not psycopg2 -- the `postgres` extra ships psycopg[binary], so the old +psycopg2 mapping raised ModuleNotFoundError at `alembic upgrade head`. - worker.py: enforce the same validate_production guard the API runs (arq skips the FastAPI lifespan), and guard _shutdown against a _stack that startup never set. - web: pass FORGE_API_URL as a build ARG (standalone Next freezes the rewrite at build time); default 127.0.0.1:8000 keeps host `pnpm dev`, compose overrides to http://api:8000. Kept out of NEXT_PUBLIC_*. - Dockerfile: stub-package + editable install + BuildKit pip cache mount so a pure source edit doesn't re-hit PyPI. - .dockerignore: fold apps/api/.dockerignore into the root one (context is now the repo root, so only the root ignore is read); keeps .data (master.key/secrets) and tests out of the image. - compose: gate worker/web on api `service_healthy` (/readyz) so nothing hits the DB/API before `alembic upgrade head`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
/app/.data (the Fernet master.key and the Chroma vector store) lived only in the container filesystem, so every `up --build` regenerated the key -- orphaning every secret already encrypted in Postgres -- and reset the vector store. The worker also had its own ephemeral copy, so it could not decrypt secrets the api encrypted. - compose: mount a shared `forge-data` named volume at /app/.data on both api and worker, so the key/vectors persist across rebuilds and both services use the SAME master.key. - Dockerfile: pre-create /app/.data owned by forge so the empty named volume inherits forge ownership on first mount (else it mounts root-owned and the non-root process can't write the key). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s + audit) Two independent ways a directly-connected client could forge its IP: 1. The api ran uvicorn with `--forwarded-allow-ips='*'`, so uvicorn rewrote the socket peer from X-Forwarded-For for ANY client -- defeating deps.client_ip()'s own trusted-proxy check (it reads the rewritten peer). 2. The audit middleware's _client_ip() trusted X-Forwarded-For unconditionally, so audit-log IPs were spoofable regardless of (1). - Drop uvicorn --proxy-headers/--forwarded-allow-ips from the CMD; the app derives the client IP itself. Behind a real proxy, set FORGE_TRUSTED_PROXIES to the proxy IP(s). - Consolidate both resolvers into forge.util.clientip.resolve_client_ip so they apply the same trust rule and can't drift (that drift is what let the audit path diverge from the rate-limit path). - Believe X-Forwarded-For only when the socket peer is in FORGE_TRUSTED_PROXIES (default empty => use the real socket peer). - Add tests/test_clientip.py asserting the anti-spoof property. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The worker reuses the api image, whose HEALTHCHECK curls :8000/readyz. The worker runs arq (no HTTP server), so the probe always fails and the container sits "unhealthy" -- a false signal that also hangs any `worker: service_healthy` gate and every `--scale worker=N` replica. Disable it; container run state already reflects arq liveness (it exits if arq dies), and nothing gates on it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…allow-private
Enable on-behalf-of tool calls: a trusted backend passes per-request secrets
(e.g. a per-user session cookie / CSRF token) into a run via the X-Forge-Context
header; tools inject them into outbound calls via {{ctx.*}}, and they are never
persisted, never placed in the LLM prompt, and never an LLM-visible arg.
Per-run context (ephemeral, in-memory):
- CompileContext.run_context, threaded through RunService.stream/run_to_completion/
resume -> build_compile_context. Carried on the EXECUTION request (stream/resume)
via the X-Forge-Context JSON header (deps.run_context), not on create -> never stored.
- REST tools template {{ctx.*}} in url, path, query, header, cookie, structured body
fields, and the free-form body_template (now wired: {{input.*}} + {{ctx.*}}).
Config-declared headers are server-authoritative (an LLM header field cannot override
them); a {{ctx.*}} that resolves to a missing key is dropped, not sent literally.
GraphQL tools merge the same context for the auth resolver.
- Web tool editor: per-field `in` (query/header/path/body/cookie) + `default` +
model-visible toggle; headers/body-template help note {{ctx.*}}.
Server-to-server integration primitives:
- FORGE_SERVICE_API_TOKEN: a static bearer that authenticates a trusted backend as a
least-privilege (editor) service identity (constant-time compare in get_current_user);
non-expiring, revoked by rotation. Only a gate when FORGE_AUTH_REQUIRED=true.
- FORGE_EGRESS_ALLOW_PRIVATE_HOSTS (+ per-project egress.allow_private_hosts): named
hosts bypass the SSRF private/loopback block while block_private stays on globally
(default-deny, explicit-allow), so localhost/internal targets are reachable in dev
without disabling the guard or blocking production boot.
Tests: apps/api/tests/test_run_context.py (16), test_service_token_egress.py (10);
full backend suite green (208).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ATE_HOSTS to the stack
The container only sees env listed in the compose `environment:` block, so the new
service-token and egress-allow-private settings need explicit passthrough (with
${...} substitution from the repo-root .env) to take effect in the Docker stack.
Added to `api` (both) and `worker` (egress, for worker-executed tool runs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
config's env_file pointed at apps/api/.env while docker-compose and the docs use the repo-root .env, so local (.venv) runs and the Docker stack read DIFFERENT files - the "many .env paths" confusion. Point env_file at REPO_ROOT/.env so both run modes are configured in one place. In the flattened container image REPO_ROOT == /app (no .env copied there) and env still comes from the compose environment block; pydantic skips the missing file. Real env vars still take precedence over the file. Full suite green (208). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ice-auth Feat/per run context and service auth
The async engine pooled aiosqlite connections; under pytest-asyncio's per-test event
loops a pooled connection could be torn down in a loop other than the one that opened it,
causing intermittent CI errors during the _ensure_tables fixture setup ("Task was
destroyed but it is pending" / "object NoneType can't be used in 'await'" from
AsyncAdaptedQueuePool). Use NullPool for SQLite (dev/test) so each connection is closed
immediately and nothing lingers across loops. Postgres (prod) keeps the default pooled
behaviour - no production perf change. Full suite green across repeated runs (5/5, 208 passed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(db): use NullPool for SQLite to stop cross-event-loop teardown flake
The api container failed to boot when FORGE_EGRESS_ALLOW_PRIVATE_HOSTS resolved to a
stray "[" from the ${VAR:-[]} compose default: pydantic-settings ran json.loads('[') ->
JSONDecodeError -> SettingsError, killing startup.
Mark the list[str] settings NoDecode and normalize them via _as_str_list: accept a JSON
array, a comma-separated string, or blank ("" -> []), and tolerate an unquoted/mangled
bracketed value. Applied to all list env fields (egress allow/deny/allow-private,
cors_origins, trusted_proxies/hosts, jwt_secret_previous) so none can crash boot on
env/compose quoting. Also drop the bracket from the compose default (${...:-}) so it
emits an empty string, not "[]".
Tests: apps/api/tests/test_config_env_lists.py; full suite green (215).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(config): parse list env settings leniently (JSON, CSV, or blank)
The Connect screen only documented the MCP endpoint - there was nowhere to get the server-to-server run API details. Add a panel that lets you pick the workflow and the Forge API base URL, then shows ready-to-copy Project ID, Workflow ID, and the fully built create / stream / resume endpoints plus a curl example (Authorization: Bearer FORGE_SERVICE_API_TOKEN + the X-Forge-Context per-user header). Retitle the screen "Connect" with MCP as a second section. Web typechecks clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Primary fix (verified): a streaming caller could capture the composite
LangGraph id ({tenant}:{uuid}) from the SSE `run` frame and echo it back as
thread_id. It never matched Thread.id, so every turn started a fresh thread
and the agent forgot the conversation.
- runs.py: the `run` SSE frame now emits the caller-facing DB thread_id
(same handle as the create response / `ready` frame), not lg_thread_id;
create_run reuses a thread on EITHER handle (Thread.id or lg_thread_id).
- project_run.py: HITL resume resolves either handle too.
- tests: streaming thread-id consistency regression + create_run tolerance
test; conftest resets sse_starlette's loop-bound singleton so more than one
SSE test can run per process.
Also lands this branch's pending work: single POST /v1/projects/{id}/run
endpoint, per-run X-Forge-Context, egress TLS verify + gated tls_skip_verify,
audit/quota updates, and the Connect panel UI. Backend suite: 225 passing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Feat/connect run api panel
…of truth The console's model pickers (chat / embedding / reranker) and the built-in pricing rates now derive from a single canonical list (forge/model_catalog.py, served at GET /v1/models). The frontend hardcodes no model lists — it fetches them via useModels / useEmbeddingModels / useRerankerModels — so a dropdown can only offer models the backend can actually run (and, for chat, price) and the two can't drift into silent $0 cost tracking. test_model_catalog enforces the invariants (every offered model priced, cheap defaults selectable, no dupes). Also folded in here because they share the touched files: the agent tool-count badge now counts DISTINCT tool names (matching what the model receives), and the middleware-stack row is a single compact truncating header.
resolve_tool_ids already de-dupes by id, but the final tool list mixes sources (tools + knowledge + MCP + components) and tool names are not unique per project, so two entries can still collide by name — which providers reject (OpenAI errors on a duplicate function name). De-dupe by name (keep the first, warn on drops) for both the agent and its subagents.
…compat The classifier resent the entire message history each call (progressively slower and pricier as a thread grows) and passed the prompt as a lone SystemMessage — which Gemini routes to system_instruction and then rejects for empty contents, and which Anthropic rejects for lacking a leading user turn. Fold a bounded slice of recent context into a single self-contained HumanMessage instead. UI: the classifier's model field now reads "Auto (cheapest model)" instead of "Project default", matching what actually runs when it is left blank.
A LangGraph bubble-up (interrupt() for human approval, or a Command reroute) is RAISED to suspend/redirect the graph — control flow, not a failure — but it reached the callback error hooks and rendered a run paused for approval as a crash. Recognize GraphBubbleUp and close the span cleanly, tagged `interrupted`, across the llm / tool / chain / retriever error hooks.
One user message can produce several Trace rows under the same run_id: a pause writes an `interrupted` trace, then the resume writes a `done` trace (both carry the same user_message, since run.input is unchanged). Count turns by distinct run_id in the conversation summary, and group segments by run_id in the Traces transcript, so a paused message reads as one turn that paused — not two. The expanded turn lazy-loads spans for every segment and labels them (Started / Paused for approval / Resumed).
langchain-openai renamed OpenAIModerationMiddleware's toggles apply_to_* -> check_* (and added check_tool_results / exit_behavior / model / violation_message). Enabling the middleware used to crash at compile with "unexpected keyword argument 'apply_to_input'". Translate from our schema's apply_to_* names to the library's current kwargs and pass the new options through from Advanced JSON.
Local architecture-alignment notes, not part of the product.
The .select class already draws its own chevron via a background-image, so the overlaid Icon rendered the arrow twice. Remove the overlay on the auth provider-kind and tool method/encoding/error/auth selects.
…erver
Native MCP clients (Claude Desktop, Cursor, VS Code) now connect directly over the
Streamable-HTTP transport — no `mcp-remote` proxy bridge. The endpoint serves both
transports from one auth + tool-resolution core, chosen per request:
- a POST that accepts text/event-stream (or any GET/DELETE) -> Streamable HTTP,
backed by the official `mcp` SDK's StreamableHTTPServerTransport in STATELESS
mode (a fresh transport per request), which matches Forge's model: every request
is authenticated on its own and the tool surface is resolved per project + per
acting identity. The reply is application/json or an SSE stream per the Accept.
- a plain-JSON POST -> the original request/response JSON-RPC path, preserved for
simple HTTP clients and internal callers.
Both paths share _resolve / _list_items / _dispatch, so behavior and tracing are
identical whichever transport a client uses. The transport's own DNS-rebinding guard
is disabled (Forge already enforces trusted-hosts at the app layer), and the SDK
import is guarded so the router still loads without the `mcp` extra (the streamable
branch then returns 501).
test_mcp_streamable.py drives the endpoint with the real `mcp` SDK client end-to-end
(initialize / list / call), plus SSE content-negotiation, the legacy-JSON fallback,
and per-project auth on the streaming path.
One admin-configurable screen (Settings > Guardrails & Egress) that enforces an I/O policy on every agent by default, with per-agent middleware left for exceptions. Compiles to two enforcement points that already existed: - config.default_middleware -> prepended to every agent's stack: PII redaction (built-in types + custom regex patterns) and a case-insensitive blocked-terms guardrail. Managed entries tagged _managed so hand-authored middleware is kept. - config.egress -> EgressPolicy (SSRF guard): block-private + allow/deny domain lists; project can only tighten, never loosen. No backend enforcement changes and no new deps; content guardrails are local regex (no added latency). Adds test_default_middleware.py locking the "injected into every agent, ahead of the agent's own middleware" guarantee.
…use LLM connections Chat turns took 15–40s. Root cause: the Docker/glibc resolver stalls ~4–5s on the IPv6 (AAAA) lookup for hosts with no IPv6 address (api.openai.com, …), and glibc waits for it before falling back to the A record — so the FIRST (cold) outbound call of every idle connection paid a multi-second penalty. On a multi-hop run (classifier + agent + tool + agent) that dominated latency, and it recurred whenever a connection went idle. Gemini was unaffected (it publishes IPv6). Authoritative fix: RES_OPTIONS=no-aaaa in the process env for the api and worker services (docker-compose), so glibc never issues the AAAA query. Works under uvloop — whose C-level resolver bypasses a Python socket.getaddrinfo patch — and for every client (LLM providers, REST tools, Postgres, Redis). Overridable via .env for an IPv6-only egress network. Needs glibc >= 2.36 (image has 2.41). - forge/util/netfix.py: best-effort fallback for non-compose / non-uvloop launches (sets RES_OPTIONS if unset + an IPv4-first socket.getaddrinfo wrapper), gated by the new prefer_ipv4_egress setting; installed in the API lifespan and worker startup. - forge/util/http.py + engine/models.py: reuse ONE keep-alive httpx connection pool for OpenAI model calls across runs (the per-run graph compile otherwise re-handshakes on the first call of every run), gated by the new llm_http_keepalive setting. No token/cost impact. Measured (Test project main_workflow): cold OpenAI call 5.0–6.4s -> ~0.9–2.6s; warm ~1s; a full "Hi" turn on an OpenAI agent ~5–6s -> ~2.5s (on par with Gemini); general query ~12s -> ~5s.
Bumps the actions group with 1 update: [actions/setup-node](https://github.com/actions/setup-node). Updates `actions/setup-node` from 6 to 7 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v6...v7) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com>
Adds a connector-safe self-service surface so each end user supplies their OWN downstream token for a per-user auth provider (no shared secret, no token passthrough); tools then act as that user, keyed server-side by the caller's user id.
- new /v1/projects/{id}/connections router (list/get/set/clear my own connection), gated at any real logged-in user and returning minimal fields so a least-privileged connector needs no auth-provider admin access
- resolver support for per-user bearer/api_key providers
- self-serve UI on the Auth and Connect screens, connector token page, and the api client + auth_provider schema wiring
…gents Each list screen gets Export (select-all picker -> downloadable single-type JSON bundle) and Import (upload -> re-create in the current project). Import goes through the normal create path (fresh UUID, same validation, version snapshot) so an imported entity is indistinguishable from a hand-built one. - PortabilityService serializes every authored field (strips runtime junk like a tool's _last_test; never exports secret values, only secret:// refs) - auto-rename on name collision (never overwrites; required for the component unique-name constraint) - intra-bundle id remap so references (workflow subworkflow_id, agent config.tools/components) follow the new ids - a tool's auth_provider_id is kept only if that provider exists in the target project, else cleared with a warning - 2 routes per type + reusable web ImportExport control; wrong-type bundles rejected with a clear 422 - tests: service round-trips, remap, auto-rename, auth resolution, scoping + in-process HTTP integration
…tions-eefdb6dedd chore(deps): Bump actions/setup-node from 6 to 7 in the actions group
…resh screenshots Bring all user-facing docs up to date with features shipped Jul 16-20 and the console reskin: - README: tool sets, MCP over Streamable-HTTP/SSE with PAT/OAuth 2.1, guardrails & egress, import/export, connector role, version history, expanded docs table. - MANUAL: grouped sidebar nav (Build/Deploy/Observe), corrected Settings sections, Connect (MCP) rewrite, new Import & export section, Guardrails & Egress explainer. - ROADMAP: shipped items moved up; PII redaction dropped from planned (ships via guardrails). - CHANGELOG: new Unreleased entries. - TECH_STACK: ruff pin >=0.15, add mypy + Vitest, croniter range. - apps/api/README: fix prod vector swap to pgvector; refresh router/service inventory. - Refresh Components/Embeddings screenshots to the current UI. - Remove internal docs/reports notes.
…ebugger, run-API & governance shots - Replace Agents/Tools/Components/Knowledge/Traces screenshots with current-UI (shadcn+indigo) captures on generic demo data. - Add Tools_dashboard (tool sets), Knowledge search debugger (chunk map), Integrations (run API) and Settings (governance) images. - New README sections: 'Deploy anywhere - one run API, MCP & channels' and 'Guardrails, budgets & governance'. - Note: forge-demo.mp4 (128MB) intentionally not tracked; exceeds GitHub's 100MB limit — host externally and reference by URL.
Updates the requirements on [ruff](https://github.com/astral-sh/ruff) to permit the latest version. Updates `ruff` to 0.16.0 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](astral-sh/ruff@0.15.0...0.16.0) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.16.0 dependency-type: direct:development dependency-group: python ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
Author
|
This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests. To ignore these dependencies, configure ignore rules in dependabot.yml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates the requirements on ruff to permit the latest version.
Updates
ruffto 0.16.0Release notes
Sourced from ruff's releases.
... (truncated)
Changelog
Sourced from ruff's changelog.
... (truncated)
Commits
a2635fdBump 0.16.0 (#27136)3433449[ty] Reuse full call diagnostics for implicit setter calls (#27115)2240070Reflectruff: ignoreand--add-ignorestabilization in documentation (#27...17ef711Stabilize--add-ignore(#27125)ef912bbAdd newly stabilized rules to defaults (#27055)b30f040Stabilize new default rules (#27035)bcd70c5Exclude Markdown files fromformat-devruns (#27052)87e51e2Fixformat --checkspans for syntax errors (#27045)afe2723[flake8-gettext] Stabilize qualified-name and built-in binding resolution (...a9702d8[flake8-bandit] Stabilize string literal binding resolution (S310) (#26944)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore <dependency name> major versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)@dependabot ignore <dependency name> minor versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)@dependabot ignore <dependency name>will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)@dependabot unignore <dependency name>will remove all of the ignore conditions of the specified dependency@dependabot unignore <dependency name> <ignore condition>will remove the ignore condition of the specified dependency and ignore conditions