ruby_llm-browser 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,16 @@ After reading this guide, you will know:
18
18
 
19
19
  ## Installation
20
20
 
21
- The stable release is `{{ site.version }}`. Add it to your Gemfile:
21
+ {% if site.docs_unreleased %}This guide follows `main` at source version `{{ site.version }}`.
22
+ Install the default branch to use the APIs documented here:
23
+
24
+ ```sh
25
+ bundle add ruby_llm-browser --git https://github.com/yorzi/ruby_llm-browser --branch main
26
+ ```
27
+
28
+ The latest stable release is `{{ site.stable_version }}`; select its documentation
29
+ from the version menu before installing that release.
30
+ {% else %}The stable release is `{{ site.version }}`. Add it to your Gemfile:
22
31
 
23
32
  ```ruby
24
33
  gem "ruby_llm-browser", "~> {{ site.version }}"
@@ -29,6 +38,7 @@ For unreleased development changes, install the default branch instead:
29
38
  ```sh
30
39
  bundle add ruby_llm-browser --git https://github.com/yorzi/ruby_llm-browser --branch main
31
40
  ```
41
+ {% endif %}
32
42
 
33
43
  Use Ruby 3.2 or later. The gem supports RubyLLM `>= 2.0, < 3` and pins Stagehand to the
34
44
  3.21.x series. Rails is optional and is not loaded by the core entry point. See
@@ -0,0 +1,47 @@
1
+ ---
2
+ layout: default
3
+ title: What's New in 0.2
4
+ redirect_from:
5
+ - /whats-new/
6
+ nav_order: 4
7
+ description: Use the read-only tool factory and backend-aware diagnostics in this release.
8
+ ---
9
+
10
+ # {{ page.title }}
11
+
12
+ {{ page.description }}
13
+
14
+ After reading this guide, you will know:
15
+
16
+ - How to register the read-only tool pair.
17
+ - How to distinguish offline diagnostics from live-backend checks.
18
+ - Where to verify changes locally before upgrading.
19
+
20
+ ## Read-only Tool Factory
21
+
22
+ You can register the read-only tools in one call:
23
+
24
+ ```ruby
25
+ chat.with_tools(*RubyLLM::Browser.tools(context: context, schema: schema))
26
+ ```
27
+
28
+ The host still supplies context and schema. The factory returns Inspect and Extract
29
+ instances and never registers Act. Individual constructors remain supported. Read
30
+ [Inspecting and extracting]({% link _core_features/inspect-extract.md %}) for a complete
31
+ offline example and the validation behavior.
32
+
33
+ ## Backend-aware Diagnostics
34
+
35
+ Doctor adds a `mode` field while preserving `ok`, `summary`, and `checks`. FakeBackend
36
+ reports `offline` mode and skips provider environment and SDK checks. Stagehand
37
+ reports `live` mode and remains blocked. Custom backends no longer receive unrelated
38
+ Stagehand warnings. Read [Checking Configuration]({% link _core_features/diagnostics.md %}).
39
+
40
+ ## Development Verification
41
+
42
+ Use `bin/check` for offline contracts, lint, alternate bundles, and examples. Use
43
+ `bin/check-browser` for desktop/mobile workflows and fixture screenshots. The
44
+ [development guide]({% link _advanced/development-and-testing.md %}) explains setup,
45
+ package verification, and the limits of this evidence.
46
+
47
+ Stagehand and live Act remain unsupported. This release remains offline-only.
@@ -6,9 +6,9 @@
6
6
  # while _config.yml says `released: false`. Pages use it to show the install
7
7
  # command for the default branch. A build of a release tag is never
8
8
  # unreleased, even when that tag forgot to set `released: true`.
9
- # - A versioned build takes `version` from _data/versions.yml, which
9
+ # - A stable or archive build takes `version` from _data/versions.yml, which
10
10
  # bin/prepare_versions.rb fills in from the tag, so a tag that forgot to bump
11
- # `version` still shows the right install command.
11
+ # `version` still shows the right install command. Next keeps its source version.
12
12
  # - An absolute canonical_url on this site becomes a path, so the theme adds
13
13
  # this build's base path (/next/, /v1/) and the page stays in its own
14
14
  # build's llms.txt and sitemap.
@@ -22,7 +22,7 @@ Jekyll::Hooks.register :site, :post_read, priority: :high do |site|
22
22
  else
23
23
  site.config['docs_unreleased'] = [ 'next', 'Next (unreleased)' ].include?(current)
24
24
  release = versions['release'].to_s
25
- site.config['version'] = release unless release.empty?
25
+ site.config['version'] = release unless release.empty? || site.config['docs_unreleased']
26
26
  end
27
27
 
28
28
  origin = site.config['url'].to_s.delete_suffix('/')
@@ -0,0 +1,188 @@
1
+ ---
2
+ layout: default
3
+ title: API and Configuration
4
+ nav_order: 3
5
+ permalink: /api-and-configuration/
6
+ description: Configure trusted host objects and interpret bounded untrusted results.
7
+ ---
8
+
9
+ # API and configuration
10
+
11
+ Configure trusted host objects and interpret bounded, untrusted results.
12
+
13
+ After reading this guide, you will know:
14
+
15
+ - How to register read-only tools.
16
+ - Which inputs belong to the host and which belong to the model.
17
+ - How to configure budgets, schemas, backends, and error handling.
18
+
19
+ ## Creating a context
20
+
21
+ Use the complete offline example in [Getting Started]({% link _getting_started/getting-started.md %}). `Context.new` requires:
22
+
23
+ | Keyword | Type and meaning |
24
+ | --- | --- |
25
+ | `actor_id`, `run_id` | Nonempty strings from authenticated host records. Convert numeric database IDs with `to_s`. |
26
+ | `backend` | A `Backend` instance. Use `FakeBackend` for offline tests. |
27
+ | `source_policy` | A host-created `Policy`. |
28
+ | `operation_store` | An `OperationStore`; durable storage is required across restarts or workers. |
29
+ | `approval_store` | Optional `ApprovalStore`, needed only for experimental Act. |
30
+ | `budget` | Optional `Budget`; defaults listed below. |
31
+ | `clock` | Optional callable returning a UTC `Time`. |
32
+ | `logger` | Optional host logger. Do not enable raw provider or tool payload logging. |
33
+ | `consent` | Optional host consent record. The gem records its presence; it does not collect or authenticate consent. |
34
+ | `metadata` | Optional host metadata. Never supply credentials here. |
35
+
36
+ The host must reauthorize actor/run access when building a context, including background
37
+ jobs. Passing IDs alone is not authentication. The model must never choose a backend,
38
+ credential, schema, source allowlist, consent record, or budget.
39
+
40
+ ## Registering tools
41
+
42
+ ```ruby
43
+ chat.with_tools(*RubyLLM::Browser.tools(context: context, schema: schema))
44
+ ```
45
+
46
+ `Browser.tools` returns fresh Inspect and Extract instances in that order, sharing
47
+ the supplied context. It never includes Act or dispatches an operation. You can also
48
+ construct either tool separately with `Inspect.new(context:)` and
49
+ `Extract.new(context:, schema:)`. Constructors reject missing host bindings; schema
50
+ contents are validated by policy when Extract runs, before a session starts.
51
+
52
+ Both tools expose `url`, optional `instruction`, and optional positive integer
53
+ `max_bytes`. `max_bytes` can only tighten the policy and operation ceilings.
54
+ `Extract` takes its schema in the constructor, not in model arguments.
55
+
56
+ `Inspect` returns **candidate interactions**, not a screenshot or arbitrary page dump.
57
+ Neither read-only tool dispatches candidates automatically. Pages may still run scripts
58
+ and initiate requests; read-only does not mean browsing has no external effects.
59
+
60
+ `Tool#execute` and RubyLLM `Tool#call` return a Hash. If you need a `Result` object, use:
61
+
62
+ ```ruby
63
+ engine = RubyLLM::Browser::Engine.new(context: context)
64
+ result = engine.inspect(url: url)
65
+ result = engine.extract(url: url, schema: schema, instruction: "Find the title")
66
+ ```
67
+
68
+ The optional `operation:` Engine keyword accepts a host-reserved operation with the
69
+ same actor/run and budget. Starting it is an atomic reserved-to-starting claim. It is
70
+ not a resume or retry API for active, unknown, or closed operations.
71
+
72
+ ## Source policy
73
+
74
+ `Policy.new(allowed_hosts: [...])` accepts exact hosts and `*.example.com` subdomains.
75
+ A wildcard does not allow the bare domain. Defaults are HTTP/HTTPS and ports 80/443.
76
+ Keep `verify_dns: true`; `resolver:` is injectable for offline fixtures.
77
+
78
+ Other options are `allowed_schemes`, `allowed_ports`, `max_result_bytes` (65,536),
79
+ `max_schema_depth` (8), `max_schema_properties` (64 root properties), and
80
+ `max_schema_bytes` (16,384). Browser-side enforcement must also cover explicitly
81
+ approved asset origins, redirects, frames, popups, WebSockets, and subresources.
82
+
83
+ ## Extraction schemas
84
+
85
+ Schemas must be bounded object JSON Schemas, passed as a Hash, JSON object string, or
86
+ an object/class supporting `to_json_schema`. Supported keywords are `type`,
87
+ `description`, `properties`, `required`, `items`, `enum`, `additionalProperties`,
88
+ `title`, `minimum`, `maximum`, `minLength`, `maxLength`, `minItems`, `maxItems`,
89
+ `format`, and `default`. Remote references and arbitrary schema extensions are refused.
90
+
91
+ Use `required` and `additionalProperties: false` when an exact shape matters. Provider
92
+ data must satisfy the schema before redaction or truncation. Invalid data returns
93
+ `PROVIDER_ERROR`; it is not returned as a successful extraction. A truncated preview
94
+ or redacted field need not retain the original schema's type. Always check the status.
95
+
96
+ ## Results and errors
97
+
98
+ `Result#to_h` contains symbol keys: `status`, `operation_id`, `final_url`,
99
+ `captured_at` (UTC ISO 8601), `locator`, `digest`, `truncated`, `data`, and optional
100
+ `error: { code:, message: }`. Locator/data objects use string keys. JSON encodes all
101
+ keys as strings. Credential-like query values are redacted in URL provenance.
102
+
103
+ Statuses are `ok`, `truncated`, `error`, `unknown`, and `cleanup_pending`.
104
+ `Result#ok?` accepts `ok` and `truncated`; it makes no factual verification claim.
105
+ `digest` is SHA-256 of canonical JSON of the returned, sanitized data. Very small byte
106
+ limits can produce an empty string or scalar preview; `truncated` is authoritative.
107
+
108
+ Engine preflight denials raise typed errors. Tools convert them into error Hashes.
109
+ After a session starts, the Engine attempts cleanup and returns a failure result.
110
+ Cleanup failure can supersede the original result with `cleanup_pending`; inspect the
111
+ durable operation's `error_code` and arrange host review for unknown effects.
112
+
113
+ Safe error codes: `INVALID_INPUT`, `NOT_AUTHORIZED`, `UNSUPPORTED_SECURITY_CAPABILITY`,
114
+ `BUDGET_EXHAUSTED`, `SESSION_UNKNOWN`, `CLEANUP_PENDING`, `APPROVAL_REQUIRED`,
115
+ `APPROVAL_STALE`, and `PROVIDER_ERROR`.
116
+
117
+ ## Budgets
118
+
119
+ `Budget.new` defaults to `max_seconds: 60`, `max_steps: 12`, `max_bytes: 262_144`,
120
+ `max_concurrent: 1`, and `max_cost_usd: nil`.
121
+
122
+ `RubyLLM::Browser.configure` sets process defaults for `default_budget`,
123
+ `max_result_bytes`, `clock`, and `logger`. New contexts/policies use those defaults;
124
+ existing objects do not change. `configuration.backend` is only a reserved host slot:
125
+ contexts always require an explicitly supplied backend and never use a fallback.
126
+
127
+ - Steps count navigation, observation, extraction, and action calls, not start/cleanup.
128
+ - Bytes count retained sanitized result data, not all bytes the remote browser receives.
129
+ - Wall-clock checks refuse new calls after expiry. Stagehand request timeouts are bounded
130
+ by remaining time. Cleanup has a separate timeout and may outlive this budget.
131
+ - Concurrency is scoped to the actor across runs. Unknown/pending cleanup holds a slot.
132
+ - `max_cost_usd` is **advisory only**. There is no cost ledger or provider hard spending
133
+ cap in this release. Enforce billing limits in the provider/host.
134
+
135
+ ## Stagehand backend status
136
+
137
+ `StagehandBackend` is unsupported for live operations in this release. It always reports
138
+ `egress_isolation: :unverified` and `act_supported?: false`. `Engine` refuses it before
139
+ the first provider request, and direct start, navigation, observation, extraction, and
140
+ Act calls also fail closed. No constructor option or injected client enables live use.
141
+
142
+ The adapter remains in the source for future qualification. Its client pins credentials
143
+ and base URL, disables retries, self-healing, CAPTCHA solving, session recording and
144
+ session logging, and requests a provider timeout. These controls do not prove egress,
145
+ TTL, billing, final-URL reporting, or cleanup. `end_session` sends no request in this
146
+ release and returns `false`; the operation remains `cleanup_pending`.
147
+
148
+ The constructor accepts `server: :remote`, `base_url:`, `timeout: 60.0`,
149
+ `custom_headers_approved: false`, `env: ENV`, and an injected `client:` for internal
150
+ contract tests. A future live implementation must verify all relevant environment
151
+ settings, egress across every browser request path, TTL and closure status, and provider
152
+ billing controls before it can advertise support.
153
+
154
+ ## Configuration diagnostics
155
+
156
+ For diagnostics without network requests, use `Doctor.new(backend:).report`. It
157
+ returns `mode`, `ok`, `summary`, and `checks`. See
158
+ [Checking Configuration]({% link _core_features/diagnostics.md %}) for the backend-specific checks.
159
+
160
+ ## Dependency security floors
161
+
162
+ Old Ruby installations can supply vulnerable default gems even when a developer's
163
+ lockfile audit passes. Runtime requirements explicitly exclude those versions:
164
+ `cgi >= 0.4.2, < 1`, `resolv >= 0.7.2, < 1`, `uri >= 1.0.4, < 2`, and
165
+ `zlib >= 3.2.3, < 4`. A fresh install may build native extensions for these gems.
166
+ Use a supported, patched Ruby interpreter as well; these floors do not patch Ruby or
167
+ system libraries. Audit the versions actually activated by your application, including
168
+ default gems, not just a development lockfile.
169
+
170
+ ## Experimental Act
171
+
172
+ `Act.new(context:)` declares RubyLLM `requires_approval`. Its arguments are `url`,
173
+ `approval_id`, `method`, `selector`, optional `description`, and optional `arguments`.
174
+ The resolver reads the host store without consuming. Consumption immediately before
175
+ dispatch checks actor/run, exact URL/action digest, expiry, and any supplied
176
+ page/operation/session bindings. Revocation and consumption are atomic in the stores.
177
+
178
+ **Do not use this as a production authorization protocol yet.** Bindings are currently
179
+ optional; a candidate-list digest is not a DOM/target revision, and each Engine action
180
+ opens a fresh session. The same-session host approval flow required by the specification
181
+ is deferred to a later version. The Engine refuses all non-fake Act calls before starting
182
+ a session. Selector/description keyword filters are defense in depth, not semantic proof
183
+ that a click is harmless. The Stagehand adapter does not support Act in this release.
184
+
185
+ ## Next steps
186
+
187
+ - Read [Rails integration]({% link _advanced/rails-integration.md %}) for durable workers and recovery.
188
+ - Read [security boundaries]({% link SECURITY_MODEL.md %}) before qualifying a live backend.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: API Reference
4
- nav_order: 1
4
+ nav_order: 4
5
5
  guide: false
6
6
  description: Find the RubyLLM::Browser classes for tools, policy, results, backends, and Rails jobs.
7
7
  ---
@@ -20,10 +20,11 @@ The [generated RDoc reference]({{ '/api/' | relative_url }}) documents classes a
20
20
  | Simulate one host-approved action offline | `Act`, `Approval`, `ApprovalStore` |
21
21
  | Read a bounded result | `Result` |
22
22
  | Use an offline backend | `FakeBackend` |
23
+ | Diagnose configuration without dispatch | `Doctor` ([guide]({% link _core_features/diagnostics.md %})) |
23
24
  | Adapt the Stagehand Ruby SDK | `StagehandBackend`, `Capabilities`, `Doctor` |
24
25
  | Persist operation or approval state | `OperationStore`, `ApprovalStore` and their implementations |
25
26
  | Run Rails background jobs and cleanup | `RubyLLM::Browser::Rails::OperationJob`, `Reaper` |
26
27
 
27
- Start with [Getting Started]({% link _getting_started/getting-started.md %}) for a runnable offline example. The [API and configuration guide]({% link API.md %}) explains inputs, results, limits, and errors.
28
+ Start with [Getting Started]({% link _getting_started/getting-started.md %}) for a runnable offline example. The [API and configuration guide]({% link _reference/api-and-configuration.md %}) explains inputs, results, limits, and errors.
28
29
 
29
30
  The reference is generated from source comments. Build it locally with `docs/bin/build-api.sh tmp/api`.
@@ -11,13 +11,14 @@ description: Follow release tags and their documentation for RubyLLM::Browser.
11
11
  {{ page.description }}
12
12
  {: .fs-6 .fw-300 }
13
13
 
14
- {% if site.docs_unreleased %}The current source build follows `main`. The latest stable release is `0.1.0`.
14
+ {% if site.docs_unreleased %}The current source build follows `main`. The latest stable release is `{{ site.stable_version }}`.
15
15
  {% else %}This documentation describes the `{{ site.version }}` release. Use the tag and
16
16
  release notes to identify the exact source for this version.
17
17
  {% endif %}
18
18
 
19
19
  | Release | Date | Highlights |
20
20
  | --- | --- | --- |
21
+ | [0.2.0]({% link _getting_started/whats-new-in-0-2.md %}) | 2026-10-19 | Read-only tool factory, backend-aware Doctor, and agent development/browser verification |
21
22
  | [0.1.0](https://github.com/yorzi/ruby_llm-browser/releases/tag/v0.1.0) | 2026-10-18 | Offline read-only Inspect and Extract, Rails adapter, and Act simulation; live Stagehand and live Act are unsupported |
22
23
 
23
24
  For changes to existing applications, follow [Upgrading]({% link _reference/upgrading.md %}).
@@ -0,0 +1,163 @@
1
+ ---
2
+ layout: default
3
+ title: Roadmap to 1.0
4
+ nav_order: 8
5
+ description: Plan small releases toward a reliable read-only browser integration for RubyLLM.
6
+ ---
7
+
8
+ # {{ page.title }}
9
+
10
+ {{ page.description }}
11
+
12
+ After reading this guide, you will know:
13
+
14
+ - What works today and what still blocks practical live use.
15
+ - Which small features belong in the next release.
16
+ - What must pass before the project releases 1.0.0.
17
+
18
+ ## Start with a Narrow 1.0
19
+
20
+ The proposed 1.0 supports one complete workflow: your RubyLLM application inspects an
21
+ approved public page or extracts schema-checked data, receives a bounded result with
22
+ provenance, and can account for the browser session through cleanup. It works in plain
23
+ Ruby and through the optional Rails adapter.
24
+
25
+ Version 0.1.0 introduced the offline foundation: Inspect, Extract, URL policy, bounded
26
+ results, operation bookkeeping, Rails jobs, and Act simulation. It does not provide a
27
+ supported live backend. The current Stagehand adapter refuses live operations. Rails
28
+ jobs track state but do not durably deliver result bodies.
29
+
30
+ **This is a proposed development sequence, not a list of available features or release
31
+ dates.** Future API names below are proposals. Keep each release small; use patch
32
+ releases for fixes and split a milestone if implementation reveals a larger change.
33
+
34
+ ## Release Sequence
35
+
36
+ Build convenience on the current offline API first. Complete the Rails result path
37
+ next. Qualify one live deployment before advertising browser support, then use pilot
38
+ feedback to settle the public API.
39
+
40
+ | Version | Outcome | Release condition |
41
+ | --- | --- | --- |
42
+ | 0.2.0 | Easier tool setup and clearer offline diagnostics | Two additive features, tested with no provider requests |
43
+ | 0.3.0 | Usable Rails result delivery | A host can retrieve a job's result after the worker exits |
44
+ | 0.4.0 | One supported live read-only deployment | Egress, final URL, session expiry and cleanup qualified on that deployment |
45
+ | 0.5.0 | Pilot feedback and recovery hardening | Plain-Ruby and Rails workflows exercised outside the test suite |
46
+ | 1.0.0-rc.1 | Stable API candidate | Feature freeze, complete upgrade instructions, candidate package verified |
47
+ | 1.0.0 | Supported read-only integration | All acceptance criteria below pass on the release candidate |
48
+
49
+ ### 0.2.0: Two Small Features
50
+
51
+ Version `0.2.0` adds both features below. Later milestones remain proposed scope. See
52
+ [What's New]({% link _getting_started/whats-new-in-0-2.md %}) for usage and
53
+ [development and testing]({% link _advanced/development-and-testing.md %}) for validation.
54
+
55
+ 1. Add the read-only tool factory `RubyLLM::Browser.tools(context:, schema:)`.
56
+ Return Inspect and Extract instances suitable for `chat.with_tools(*tools)`. Keep
57
+ the context and extraction schema explicit; never include Act. Reuse the existing
58
+ constructors and validation instead of creating a second configuration API.
59
+ 2. Make Doctor distinguish offline and live-backend checks. FakeBackend diagnostics
60
+ should not warn that provider credentials are missing. Live-backend reports must
61
+ keep the unsupported Stagehand reason visible. Preserve the structured report and
62
+ make clear that a passing local check does not qualify a provider.
63
+
64
+ Acceptance: exercise the factory through RubyLLM's public tool-registration API on
65
+ both supported RubyLLM versions; reject an invalid schema; verify no Act registration,
66
+ provider request, credential discovery, or Rails load. Test Doctor with fake and
67
+ unsupported live backends. Update the relevant guides and changelog with the features.
68
+
69
+ Do not add a CLI, a context builder, new database tables, or live support in this slice.
70
+ The factory and Doctor are implemented in separate commits. Local and remote
71
+ validation precede the release tag and publication.
72
+
73
+ ### 0.3.0: Complete the Rails Result Path
74
+
75
+ Add an opt-in result-delivery hook that lets the host persist the sanitized `Result`
76
+ against its operation ID. Provide a runnable host example that stores and retrieves
77
+ the result after an asynchronous job finishes. The host owns access checks, retention,
78
+ and storage; the gem does not need an admin interface or a general results database.
79
+
80
+ Acceptance: retrieve a schema-checked extraction after worker exit; refuse cross-actor
81
+ reads in the host example; handle success, truncation, failure, and pending cleanup.
82
+ A delivery failure must be visible and must never cause the browser operation to run
83
+ again. Document delivery semantics, duplicate handling, and recovery separately from
84
+ the operation's session state. Verify generator upgrades preserve existing records.
85
+
86
+ ### 0.4.0: Qualify One Live Read-only Deployment
87
+
88
+ Begin with a feasibility check of the pinned SDK and a named deployment. Determine
89
+ whether the deployment can enforce every required browser request boundary and report
90
+ verified final URLs and terminal session state. Implement only the missing adapter
91
+ integration needed for that deployment. Keep live Act disabled.
92
+
93
+ Acceptance requires deployment-specific evidence for redirects, subresources, frames,
94
+ popups, WebSockets, connection-time DNS/IP restrictions, final URLs, session expiry,
95
+ and confirmed cleanup. Exercise timeouts, worker death, and lost start responses with
96
+ controlled fixtures. Unknown sessions retain quota and have an explicit host review
97
+ path; an SDK acknowledgement alone cannot release them.
98
+
99
+ Prepare the fixtures and opt-in qualification runner offline first. Live runs require
100
+ separate owner authorization for the deployment, data, and spending. Keep default CI
101
+ offline. Report provider billing controls separately from the advisory cost field.
102
+
103
+ If the deployment cannot meet the required controls, stop this milestone and record
104
+ the gap. Keep live support disabled. Do not replace qualification with a boolean flag
105
+ or promote an offline-only package to 1.0 under this plan.
106
+
107
+ ### 0.5.0: Exercise Real Application Workflows
108
+
109
+ Run two authorized pilots: a plain-Ruby extraction and a Rails background extraction
110
+ with durable host result retrieval. Record the exact dependency/deployment versions,
111
+ fixture expectations, observed results, failures, and cleanup outcomes. A controlled
112
+ host application is sufficient; customer adoption is not a release prerequisite.
113
+
114
+ Use pilot findings to improve errors, delivery, cancellation, and recovery. Confirm
115
+ that duplicate jobs do not repeat provider starts, unknown outcomes remain visible,
116
+ and result limits and redaction behave as documented. Resolve public API changes now
117
+ and provide migrations before freezing the API.
118
+
119
+ ### 1.0.0-rc.1: Freeze and Verify
120
+
121
+ Freeze tool constructors, factory arguments, result fields, error codes, backend/store
122
+ contracts, and Rails schema/delivery hooks. Publish migration instructions for every
123
+ breaking pre-1.0 change. Run the declared Ruby/RubyLLM/Rails matrix, build the gem,
124
+ install the actual artifact in a clean environment, and verify its shipped examples,
125
+ generator, guides, and dependency audit.
126
+
127
+ Repeat the live qualification against the candidate's exact artifact and deployment.
128
+ Fix defects through further release candidates. Feature requests return to a later
129
+ minor release. A candidate with an unresolved blocker does not advance to 1.0.0.
130
+
131
+ ## 1.0.0 Acceptance Criteria
132
+
133
+ - **Useful:** both pilot workflows complete, and one named live read-only deployment
134
+ is supported with reproducible evidence and documented limits.
135
+ - **Controlled:** URL policy, schema validation, result bounds, and redaction pass
136
+ positive and denial cases. Deployment qualification covers all browser request paths.
137
+ - **Recoverable:** cancellation, duplicate jobs, worker death, unknown starts, and
138
+ pending cleanup preserve correct state and quota. Host recovery steps are tested.
139
+ - **Retrievable:** a Rails host can persist and authorize result retrieval after a job
140
+ exits. Delivery failure cannot trigger a repeated browser action.
141
+ - **Stable:** the public API and database upgrade path are documented and covered by
142
+ compatibility checks. Unsupported databases and backends are identified explicitly.
143
+ - **Distributable:** the release artifact passes the compatibility matrix, clean
144
+ installation, examples, documentation build, and dependency checks. Version, tag,
145
+ changelog, and stable documentation agree. The owner authorizes publication.
146
+
147
+ Live Act, multiple providers, PostgreSQL qualification, authenticated browsing,
148
+ screenshots, downloads, arbitrary JavaScript, a hosted UI, and a cost ledger are not
149
+ required for this 1.0. Keep unsupported capabilities explicit. Consider live Act only
150
+ as a separate feature with same-session approval and target identity guarantees.
151
+
152
+ ## Keep Planning and Documentation Separate
153
+
154
+ The README introduces the project. Site guides teach supported behavior and provide
155
+ the API reference. This page owns future scope; the changelog records shipped changes.
156
+ Historical release audits remain evidence for their exact versions, not a current
157
+ task queue. Plan changes do not rewrite the approved specification baseline.
158
+
159
+ Read [API and configuration]({% link _reference/api-and-configuration.md %}),
160
+ [Rails jobs and recovery]({% link _advanced/rails-integration.md %}), and
161
+ [live-backend qualification]({% link _advanced/live-backend-qualification.md %}) for
162
+ the current contracts. Follow [the release checklist]({% link RELEASING.md %}) when a
163
+ milestone is ready to ship.
@@ -2,32 +2,63 @@
2
2
  layout: default
3
3
  title: Upgrading
4
4
  nav_order: 2
5
- description: Check the supported upgrade path before moving a RubyLLM::Browser application to a new version.
5
+ description: Upgrade from 0.1.0 while preserving tool registration, diagnostics, and operation data.
6
6
  ---
7
7
 
8
8
  # {{ page.title }}
9
9
 
10
10
  {{ page.description }}
11
- {: .fs-6 .fw-300 }
12
11
 
13
12
  After reading this guide, you will know:
14
13
 
15
- * What changed in the first public release.
16
- * Where to find migration steps for earlier development snapshots.
17
- * What evidence must exist before a release tag is treated as supported.
14
+ - How to update an application from 0.1.0.
15
+ - Which tool and diagnostic contracts remain compatible.
16
+ - How to preserve data from earlier development snapshots.
18
17
 
19
- ## Public Releases
18
+ ## Upgrade from 0.1.0
20
19
 
21
- Version `{{ site.version }}` is the first public release. It has no earlier public version
22
- to migrate from. Install it with `bundle add ruby_llm-browser --version "~> {{ site.version }}"`.
20
+ Update your Gemfile and bundle:
21
+
22
+ ```ruby
23
+ gem "ruby_llm-browser", "~> {{ site.version }}"
24
+ ```
25
+
26
+ ```sh
27
+ bundle update ruby_llm-browser
28
+ ```
29
+
30
+ There is no database migration or new runtime dependency. Keep existing operation and
31
+ approval records. The individual Inspect and Extract constructors remain supported.
32
+ You can optionally replace their registration with:
33
+
34
+ ```ruby
35
+ chat.with_tools(*RubyLLM::Browser.tools(context: context, schema: schema))
36
+ ```
37
+
38
+ The host still supplies the context and extraction schema. The factory never adds Act.
39
+
40
+ ## Read Doctor Reports by Name
41
+
42
+ Doctor adds `mode` while retaining `ok`, `summary`, and `checks`. Check names now depend
43
+ on the backend. Do not require Stagehand or credential checks in every report, and do
44
+ not rely on check order. FakeBackend diagnostics skip provider environment and SDK
45
+ checks. Stagehand still reports a failure; `mode: :live` does not enable it.
46
+
47
+ Read [Checking Configuration]({% link _core_features/diagnostics.md %}) for the report
48
+ fields. No live browser provider is supported by this release.
23
49
 
24
50
  ## Earlier Development Snapshots
25
51
 
26
- If you ran an earlier development Rails generator, do not drop existing operation data
27
- or rerun a create-table migration. Follow the additive migration instructions under
28
- "Upgrading an earlier development snapshot" in the [Rails guide]({% link RAILS.md %}). Drain workers during the migration and do not reuse idempotency keys for legacy rows that lack request digests.
52
+ If you used an earlier development Rails generator, preserve operation data and follow
53
+ the additive migration instructions in the
54
+ [Rails guide]({% link _advanced/rails-integration.md %}). Drain workers during migration;
55
+ do not reuse idempotency keys for legacy rows without request digests.
56
+
57
+ For the previous version's instructions, read the
58
+ [0.1.0 upgrading guide](https://github.com/yorzi/ruby_llm-browser/blob/v0.1.0/docs/_reference/upgrading.md).
29
59
 
30
60
  ## Next Steps
31
61
 
32
- * Review the [release history]({% link _reference/release-history.md %}) for version records.
33
- * Review the [release audit]({% link RELEASE_AUDIT.md %}) before enabling a live backend.
62
+ - Read [What's New in 0.2]({% link _getting_started/whats-new-in-0-2.md %}).
63
+ - Review [release history]({% link _reference/release-history.md %}) and
64
+ [live-backend qualification]({% link _advanced/live-backend-qualification.md %}).
data/docs/index.md CHANGED
@@ -35,7 +35,7 @@ features:
35
35
 
36
36
  ## Before You Install
37
37
 
38
- The first release is `0.1.0` and supports only the offline `FakeBackend`. The built-in
38
+ Version `{{ site.version }}` supports only the offline `FakeBackend`. The built-in
39
39
  Stagehand adapter is unsupported until provider egress and confirmed cleanup are
40
40
  qualified. The full live Act protocol is deferred to a later version.
41
41
 
@@ -70,8 +70,7 @@ schema = {
70
70
  "required" => [ "title" ], "additionalProperties" => false
71
71
  }
72
72
 
73
- inspect_tool = RubyLLM::Browser::Inspect.new(context: context)
74
- extract_tool = RubyLLM::Browser::Extract.new(context: context, schema: schema)
73
+ inspect_tool, extract_tool = RubyLLM::Browser.tools(context: context, schema: schema)
75
74
  puts inspect_tool.execute(url: "https://docs.example.com/")[:status] # => ok
76
75
  puts extract_tool.execute(url: "https://docs.example.com/")[:data] # => {"title"=>"Example"}
77
76
  ```
@@ -23,12 +23,15 @@ context = RubyLLM::Browser::Context.new(
23
23
  budget: RubyLLM::Browser::Budget.new(max_seconds: 30, max_steps: 6)
24
24
  )
25
25
 
26
- inspect = RubyLLM::Browser::Inspect.new(context: context)
27
- puts "Inspect: #{inspect.execute(url: "https://docs.example.com/")}"
28
-
29
26
  schema = { "type" => "object", "properties" => { "title" => { "type" => "string" } } }
30
- extract = RubyLLM::Browser::Extract.new(context: context, schema: schema)
27
+ inspect, extract = RubyLLM::Browser.tools(context: context, schema: schema)
28
+ puts "Inspect: #{inspect.execute(url: "https://docs.example.com/")}"
31
29
  puts "Extract: #{extract.execute(url: "https://docs.example.com/", instruction: "the title")}"
32
30
 
33
31
  blocked = inspect.execute(url: "http://169.254.169.254/latest/meta-data")
34
32
  puts "Blocked: #{blocked[:error][:code]}"
33
+
34
+ report = RubyLLM::Browser::Doctor.new(backend: context.backend).report
35
+ raise "offline diagnostic failed" unless report[:ok] && report[:mode] == :offline
36
+ raise "provider checks ran offline" if report[:checks].any? { |check| check[:name] == :credentials }
37
+ puts "Doctor: #{report[:mode]}"