@adcp/sdk 15.9.0 → 15.9.2

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.
@@ -911,29 +911,53 @@ setInterval(() => {
911
911
  `revision_number`, `finality`, `period_date` (the period's date in its source
912
912
  timezone) and `ordinal` to your mapped columns.
913
913
  - Batches are planned durably before loading, and job IDs derive from the
914
- change-feed range. A crash between a load and the cursor commit replays the
915
- same batch under the same job ID, which BigQuery refuses to run twice. A job
916
- that finished with an error is retried under a new attempt for that table
917
- only.
914
+ change-feed range. Before every submission the sink looks that job ID up in
915
+ the destination project and location: a job that finished cleanly counts as
916
+ loaded, a job that is pending or running is waited for (never uploaded
917
+ again), and only a missing job (404) is uploaded. A crash or timeout between a
918
+ load and the cursor commit therefore replays the same batch under the same
919
+ job ID without a second upload. An upload an earlier run abandoned at its
920
+ deadline is still running in the same process (the official client cannot
921
+ abort it), so the next run waits for it, within its own deadline, rather than
922
+ starting another, however long ago it started (that age includes the gap
923
+ between runs). If that wait outlasts the run's deadline it counts as a timeout
924
+ and the deadline grows. Only an upload still pending after 6 hours, the
925
+ largest deadline, is abandoned and replaced; BigQuery refuses a duplicate job
926
+ ID, so a replacement can never load the batch twice. A job that finished with
927
+ an error is retried under a new attempt for that table only. Deadline and
928
+ timeout errors name the table (`rows` or `revisions`, and its ID), the
929
+ deadline in force and that table's timeout count, never a file path or
930
+ credential.
918
931
  - `projectId` scopes both load submission and replay status checks. When it is
919
932
  omitted, both use the BigQuery client's default project. Each replica must
920
- be able to read the BigQuery jobs submitted by the other replicas.
921
- - `loadTimeoutMilliseconds` (default 10 minutes) is a client-side deadline for
922
- one load. When a load passes it, the sink asks BigQuery to cancel that job by
923
- its deterministic ID, in `projectId` and `location`, and rejects with the
924
- plan retained. The next run finds the cancelled job finished with an error,
925
- advances that table's attempt and rejects; the run after that loads under the
926
- new attempt. If the cancel has not taken effect yet it waits for the job.
927
- Each attempt doubles the load deadline (up to 6 hours), so a slow but healthy
928
- load converges; set the deadline above your slowest expected load to avoid
929
- the cancelled attempts. Cancellation is best effort (BigQuery may finish the
930
- job anyway, which the next run then accepts), a failed cancel other than "not
931
- found" raises a `ADCP_BIGQUERY_SINK_CANCEL_FAILED` process warning, and a
932
- status check that times out is not cancelled. BigQuery's server-side
933
- `jobTimeoutMs` is not used: for a local-file load the official client builds
934
- `configuration.load` from the load options and cannot set job-level fields,
935
- and BigQuery silently drops `labels` and `jobTimeoutMs` found inside
936
- `configuration.load`. (Staging the file in GCS and submitting the load with
933
+ be able to read the BigQuery jobs submitted by the other replicas. Set
934
+ `location` for any dataset outside the US and EU multi-regions: BigQuery
935
+ answers a job lookup without the right location with 404, and the sink then
936
+ cannot find the jobs it created.
937
+ - `loadTimeoutMilliseconds` (default 10 minutes) is the base deadline for one
938
+ run's work on one load: uploading the file, or waiting for a job that is still
939
+ running. It bounds a run, not the job. BigQuery does not stop a load when the
940
+ client gives up (a cancel is accepted and the job finishes anyway), and it
941
+ refuses a resubmitted job ID only after the whole file is uploaded again, so
942
+ the sink never cancels and never relies on that refusal. When the deadline
943
+ passes, the run rejects with the plan retained and nothing advanced: the job
944
+ ID, the attempt and the cursor stay as they were, and the next run looks the
945
+ job up by its ID again. A job whose upload outlasted a deadline is created in
946
+ the background and is picked up by the next run with no second upload. Each
947
+ such timeout doubles that table's deadline for later runs (up to 6 hours).
948
+ The growth is kept with the plan in `planned_rows_timeouts` and
949
+ `planned_revisions_timeouts` (so it survives restarts and applies to every
950
+ replica, and clears when the batch commits), so an upload slower than the
951
+ deadline eventually gets enough time. Set the deadline above your slowest
952
+ expected load to avoid the extra runs. Only a job BigQuery reports as
953
+ finished with an error advances the attempt. A status check that times out
954
+ is bounded by the base deadline and does not grow it. Re-run
955
+ `REPORTING_WAREHOUSE_SINK_MIGRATION` after upgrading: it adds the two timeout
956
+ columns (a sink table without them rejects with a message saying so).
957
+ BigQuery's server-side `jobTimeoutMs` is not used: for a local-file load the
958
+ official client builds `configuration.load` from the load options and cannot
959
+ set job-level fields, and BigQuery silently drops `labels` and `jobTimeoutMs`
960
+ found inside `configuration.load`. (Staging the file in GCS and submitting the load with
937
961
  `bigquery.createJob` can set both; the sink does not stage files.) For the
938
962
  same reason the `labels` option has no effect (it warns once per process and
939
963
  is deprecated). To attribute load cost, query
@@ -974,7 +998,9 @@ setInterval(() => {
974
998
  jobs may have succeeded; reconcile the plan against BigQuery, then call
975
999
  `reset({ discardRetainedPlan: true })`. It does not touch the warehouse: a sink
976
1000
  that already loaded history reloads the retained revisions, so empty the
977
- destination tables first or use a new sink name against new tables. Every
1001
+ destination tables first (after stopping every worker and letting in-flight
1002
+ uploads and jobs finish, since the sink never cancels a load) or use a new
1003
+ sink name against new tables. Every
978
1004
  reset starts a new job ID generation, so reloaded batches submit fresh BigQuery
979
1005
  jobs instead of matching the finished jobs of the earlier history. Nothing holds
980
1006
  change retention between `reset()` and the first committed batch. If `reset()`
@@ -334,9 +334,20 @@ What it checks:
334
334
  duplicate rows, and that `current_rows` returns one revision per obligation.
335
335
  It also asserts (`PASS`/`FAIL`) that the sink sends no `labels` or
336
336
  `jobTimeoutMs` inside `configuration.load`, where BigQuery silently drops
337
- them, and that a job cancel addressed with the destination project and
338
- location (what the sink sends when a load passes its client-side deadline) is
339
- accepted by BigQuery.
337
+ them. A deadline scenario runs a sink with the minimum 1-second load deadline
338
+ and holds the first load's result past it: the run must reject with the plan
339
+ and job ID unchanged and that table's persisted deadline grown, the job must
340
+ end `DONE` without an error (the sink never cancels it), and later runs under
341
+ the same sink name must converge with no duplicate rows, the same job ID and
342
+ no second upload. A #3234 scenario runs a sink whose upload of a 50,000-row
343
+ batch outlasts its 1-second deadline and asserts that it converges within 8
344
+ runs, loads every row exactly once, never changes the job ID, and never
345
+ starts an upload after the job exists (a link fast enough to beat the
346
+ deadline passes and says so).
347
+ - **Cancel probe of the service** (`INFO`, never a failure). It cancels a
348
+ 5000-row load the moment it is created and reports whether BigQuery stopped
349
+ it; in practice it accepts the cancel and lets the load finish, which is why
350
+ the sink never cancels a load and finds it by job ID instead.
340
351
  - **Overlapping runs** (`INFO`, never a failure). Two concurrent `runOnce()`
341
352
  calls over one pending batch, and a deterministic reproduction of #3196: one
342
353
  run reads its sink state, another completes the batch and a new revision
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
- > Generated at: 2026-10-13
4
- > Library: @adcp/sdk v15.9.0
3
+ > Generated at: 2026-10-15
4
+ > Library: @adcp/sdk v15.9.2
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
  > Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
11
11
 
12
12
  | Fact | Value |
13
13
  | --- | --- |
14
- | Exact npm package | `@adcp/sdk@15.9.0` |
15
- | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@15.9.0 dist.integrity` |
14
+ | Exact npm package | `@adcp/sdk@15.9.2` |
15
+ | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@15.9.2 dist.integrity` |
16
16
  | Node.js runtime | `^20.19.0 || >=22.12.0` |
17
17
  | Default AdCP wire release | `3.2.4` |
18
18
  | Maintained wire releases | `v2.5`, `v2.6`, `v3`, `3.0.0`, `3.0`, `3.0.1`, `3.0.2`, `3.0.3`, `3.0.4`, `3.0.5`, `3.0.6`, `3.0.7`, `3.0.8`, `3.0.9`, `3.0.10`, `3.0.11`, `3.0.12`, `3.0.13`, `3.0.14`, `3.0.15`, `3.0.16`, `3.0.17`, `3.0.18`, `3.0.19`, `3.0.20`, `3.0.21`, `3.0.22`, `3.0.23`, `3.0.24`, `3.0.25`, `3.1.0`, `3.1`, `3.1.1`, `3.1.2`, `3.1.3`, `3.1.4`, `3.1.5`, `3.1.6`, `3.1.7`, `3.1.8`, `3.1.9`, `3.1.10`, `3.1.11`, `3.1.12`, `3.1.13`, `3.1.14`, `3.1.15`, `3.1.16`, `3.1.17`, `3.1.18`, `3.1.19`, `3.1.20`, `3.1.21`, `3.1.22`, `3.1.23`, `3.1.24`, `3.2.1`, `3.2`, `3.2.2`, `3.2.3`, `3.2.4` |
@@ -21,8 +21,8 @@ below as the publication/deployment gate.
21
21
  Install exact production inputs rather than a moving range or dist-tag:
22
22
 
23
23
  ```bash
24
- npm install --save-exact '@adcp/sdk@15.9.0'
25
- npm view '@adcp/sdk@15.9.0' dist.integrity
24
+ npm install --save-exact '@adcp/sdk@15.9.2'
25
+ npm view '@adcp/sdk@15.9.2' dist.integrity
26
26
  ```
27
27
 
28
28
  ### Required and optional peers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "15.9.0",
3
+ "version": "15.9.2",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",