open-agent-guide 0.5.0__tar.gz
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.
- open_agent_guide-0.5.0/.gitignore +212 -0
- open_agent_guide-0.5.0/LICENSE +21 -0
- open_agent_guide-0.5.0/PKG-INFO +330 -0
- open_agent_guide-0.5.0/README.md +312 -0
- open_agent_guide-0.5.0/oag_client/__init__.py +8 -0
- open_agent_guide-0.5.0/oag_client/catalog.py +15 -0
- open_agent_guide-0.5.0/oag_client/cli.py +425 -0
- open_agent_guide-0.5.0/oag_client/client.py +273 -0
- open_agent_guide-0.5.0/oag_client/journal.py +110 -0
- open_agent_guide-0.5.0/oag_client/journal_lock.py +49 -0
- open_agent_guide-0.5.0/oag_client/pacing.py +234 -0
- open_agent_guide-0.5.0/oag_client/py.typed +0 -0
- open_agent_guide-0.5.0/oag_client/reads.py +187 -0
- open_agent_guide-0.5.0/oag_client/recovery.py +39 -0
- open_agent_guide-0.5.0/oag_client/render.py +177 -0
- open_agent_guide-0.5.0/oag_client/transport.py +101 -0
- open_agent_guide-0.5.0/oag_client/types.py +112 -0
- open_agent_guide-0.5.0/oag_client/workflows.py +432 -0
- open_agent_guide-0.5.0/pyproject.toml +26 -0
- open_agent_guide-0.5.0/tests/__init__.py +0 -0
- open_agent_guide-0.5.0/tests/test_cli.py +261 -0
- open_agent_guide-0.5.0/tests/test_idempotency.py +187 -0
- open_agent_guide-0.5.0/tests/test_journal_ownership.py +35 -0
- open_agent_guide-0.5.0/tests/test_pacing.py +385 -0
- open_agent_guide-0.5.0/tests/test_reads.py +235 -0
- open_agent_guide-0.5.0/tests/test_render.py +212 -0
- open_agent_guide-0.5.0/tests/test_transport.py +106 -0
- open_agent_guide-0.5.0/tests/test_workflows.py +1008 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
### Python template
|
|
2
|
+
# Byte-compiled / optimized / DLL files
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
*$py.class
|
|
6
|
+
|
|
7
|
+
# C extensions
|
|
8
|
+
*.so
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
.Python
|
|
12
|
+
build/
|
|
13
|
+
develop-eggs/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
|
|
28
|
+
# PyInstaller
|
|
29
|
+
*.manifest
|
|
30
|
+
*.spec
|
|
31
|
+
|
|
32
|
+
# Installer logs
|
|
33
|
+
pip-log.txt
|
|
34
|
+
pip-delete-this-directory.txt
|
|
35
|
+
|
|
36
|
+
# Unit test / coverage reports
|
|
37
|
+
htmlcov/
|
|
38
|
+
.tox/
|
|
39
|
+
.coverage
|
|
40
|
+
.coverage.*
|
|
41
|
+
.cache
|
|
42
|
+
nosetests.xml
|
|
43
|
+
coverage.xml
|
|
44
|
+
*.cover
|
|
45
|
+
.hypothesis/
|
|
46
|
+
|
|
47
|
+
# Translations
|
|
48
|
+
*.mo
|
|
49
|
+
*.pot
|
|
50
|
+
|
|
51
|
+
# Django stuff
|
|
52
|
+
staticfiles/
|
|
53
|
+
|
|
54
|
+
# Sphinx documentation
|
|
55
|
+
docs/_build/
|
|
56
|
+
|
|
57
|
+
# PyBuilder
|
|
58
|
+
target/
|
|
59
|
+
|
|
60
|
+
# Environments
|
|
61
|
+
.venv
|
|
62
|
+
venv/
|
|
63
|
+
ENV/
|
|
64
|
+
|
|
65
|
+
# Rope project settings
|
|
66
|
+
.ropeproject
|
|
67
|
+
|
|
68
|
+
# mkdocs documentation
|
|
69
|
+
/site
|
|
70
|
+
|
|
71
|
+
# mypy
|
|
72
|
+
.mypy_cache/
|
|
73
|
+
|
|
74
|
+
### Node template
|
|
75
|
+
# Logs
|
|
76
|
+
logs
|
|
77
|
+
*.log
|
|
78
|
+
npm-debug.log*
|
|
79
|
+
yarn-debug.log*
|
|
80
|
+
yarn-error.log*
|
|
81
|
+
|
|
82
|
+
# Runtime data
|
|
83
|
+
pids
|
|
84
|
+
*.pid
|
|
85
|
+
*.seed
|
|
86
|
+
*.pid.lock
|
|
87
|
+
|
|
88
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
89
|
+
lib-cov
|
|
90
|
+
|
|
91
|
+
# Coverage directory used by tools like istanbul
|
|
92
|
+
coverage
|
|
93
|
+
|
|
94
|
+
# nyc test coverage
|
|
95
|
+
.nyc_output
|
|
96
|
+
|
|
97
|
+
# Bower dependency directory
|
|
98
|
+
bower_components
|
|
99
|
+
|
|
100
|
+
# node-waf configuration
|
|
101
|
+
.lock-wscript
|
|
102
|
+
|
|
103
|
+
# Compiled binary addons
|
|
104
|
+
build/Release
|
|
105
|
+
|
|
106
|
+
# Dependency directories
|
|
107
|
+
node_modules/
|
|
108
|
+
jspm_packages/
|
|
109
|
+
|
|
110
|
+
# Built frontend bundle — generated from frontend/webmcp.js by `npm run build`
|
|
111
|
+
# at image-build time (ADR-0013); never committed. See package.json.
|
|
112
|
+
open_agent_guide/static/js/webmcp.bundle.js
|
|
113
|
+
|
|
114
|
+
# Typescript v1 declaration files
|
|
115
|
+
typings/
|
|
116
|
+
|
|
117
|
+
# Optional npm cache directory
|
|
118
|
+
.npm
|
|
119
|
+
|
|
120
|
+
# Optional eslint cache
|
|
121
|
+
.eslintcache
|
|
122
|
+
|
|
123
|
+
# Optional REPL history
|
|
124
|
+
.node_repl_history
|
|
125
|
+
|
|
126
|
+
# Output of 'npm pack'
|
|
127
|
+
*.tgz
|
|
128
|
+
|
|
129
|
+
# Yarn Integrity file
|
|
130
|
+
.yarn-integrity
|
|
131
|
+
|
|
132
|
+
### Linux template
|
|
133
|
+
*~
|
|
134
|
+
.fuse_hidden*
|
|
135
|
+
.directory
|
|
136
|
+
.Trash-*
|
|
137
|
+
.nfs*
|
|
138
|
+
|
|
139
|
+
### VisualStudioCode template
|
|
140
|
+
.vscode/*
|
|
141
|
+
!.vscode/settings.json
|
|
142
|
+
!.vscode/tasks.json
|
|
143
|
+
!.vscode/launch.json
|
|
144
|
+
!.vscode/extensions.json
|
|
145
|
+
*.code-workspace
|
|
146
|
+
|
|
147
|
+
# Local History for devcontainer
|
|
148
|
+
.devcontainer/bash_history
|
|
149
|
+
|
|
150
|
+
# Provided default Pycharm Run/Debug Configurations should be tracked by git.
|
|
151
|
+
### JetBrains template
|
|
152
|
+
.idea/**/workspace.xml
|
|
153
|
+
.idea/**/tasks.xml
|
|
154
|
+
.idea/dictionaries
|
|
155
|
+
.idea/**/dataSources/
|
|
156
|
+
.idea/**/dataSources.ids
|
|
157
|
+
.idea/**/dataSources.xml
|
|
158
|
+
.idea/**/dataSources.local.xml
|
|
159
|
+
.idea/**/sqlDataSources.xml
|
|
160
|
+
.idea/**/dynamic.xml
|
|
161
|
+
.idea/**/uiDesigner.xml
|
|
162
|
+
.idea/**/gradle.xml
|
|
163
|
+
.idea/**/libraries
|
|
164
|
+
cmake-build-debug/
|
|
165
|
+
.idea/**/mongoSettings.xml
|
|
166
|
+
*.iws
|
|
167
|
+
out/
|
|
168
|
+
.idea_modules/
|
|
169
|
+
atlassian-ide-plugin.xml
|
|
170
|
+
.idea/replstate.xml
|
|
171
|
+
com_crashlytics_export_strings.xml
|
|
172
|
+
crashlytics.properties
|
|
173
|
+
crashlytics-build.properties
|
|
174
|
+
fabric.properties
|
|
175
|
+
|
|
176
|
+
### Windows template
|
|
177
|
+
Thumbs.db
|
|
178
|
+
|
|
179
|
+
### Configuration
|
|
180
|
+
.env
|
|
181
|
+
# Local-only reference copies of production values (admin URL, etc.). Never
|
|
182
|
+
# commit these; .env.sample stays tracked because it doesn't match this pattern.
|
|
183
|
+
.env.*.local
|
|
184
|
+
|
|
185
|
+
### Playwright MCP
|
|
186
|
+
.playwright-mcp/
|
|
187
|
+
|
|
188
|
+
### Claude Code worktrees
|
|
189
|
+
# Agents using `isolation: worktree` materialize a sibling worktree here;
|
|
190
|
+
# its files belong to the linked branch, not the main checkout.
|
|
191
|
+
.claude/worktrees/
|
|
192
|
+
|
|
193
|
+
### UI screenshots (agent-generated, not tracked)
|
|
194
|
+
screenshots/*
|
|
195
|
+
!screenshots/.gitkeep
|
|
196
|
+
|
|
197
|
+
### Impeccable design tooling
|
|
198
|
+
# Commit the shared detector config (team-wide rule/file/value waivers so
|
|
199
|
+
# documented false positives aren't re-litigated in each checkout/worktree).
|
|
200
|
+
# Ignore per-developer state and regenerable caches (hook cache, critique
|
|
201
|
+
# snapshots, live-mode config, and the local per-developer override file).
|
|
202
|
+
.impeccable/*
|
|
203
|
+
!.impeccable/config.json
|
|
204
|
+
# Impeccable also writes per-directory hook caches when it runs against a
|
|
205
|
+
# nested skill bundle; those are regenerable and never committed.
|
|
206
|
+
**/.impeccable/hook.cache.json
|
|
207
|
+
|
|
208
|
+
# Built Tom Select JS/CSS and license notices (ADR-0054).
|
|
209
|
+
open_agent_guide/static/bundles/
|
|
210
|
+
|
|
211
|
+
# Local duplication reports contain source fragments.
|
|
212
|
+
/reports/jscpd/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Goshawk Solutions, LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: open-agent-guide
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Open Agent Guide submission client and CLI
|
|
5
|
+
Project-URL: Documentation, https://www.openagentguide.com/developers/
|
|
6
|
+
Project-URL: Homepage, https://www.openagentguide.com
|
|
7
|
+
Author-email: "Goshawk Solutions, LLC" <support@openagentguide.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Requires-Dist: httpx<0.29,>=0.28.1
|
|
16
|
+
Requires-Dist: typer<1,>=0.20
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# Open Agent Guide client
|
|
20
|
+
|
|
21
|
+
`oag` 0.3.1 requests guidance automatically. For direct API reads, request
|
|
22
|
+
`guidance` alongside `status`, `resolution`, and `check_feedback` when reading
|
|
23
|
+
your submissions. `guidance.next_action=wait` means keep watching;
|
|
24
|
+
`prepare_correction` means prepare the repair now but wait for terminal closure
|
|
25
|
+
before submitting it. `revise_and_resubmit` means inspect the rejection, correct
|
|
26
|
+
the proposal, then validate against the current catalog. `none` means read the
|
|
27
|
+
terminal resolution, including any successor links. Guidance never reserves an
|
|
28
|
+
identity or bypasses create conflicts. If it is absent, keep using lifecycle
|
|
29
|
+
status; never infer rejection from a check error. Preserve submit/watch
|
|
30
|
+
journals.
|
|
31
|
+
|
|
32
|
+
`oag` validates, submits, and watches immutable catalog proposals. The Python
|
|
33
|
+
library runs the same workflows without a subprocess or Django installation.
|
|
34
|
+
|
|
35
|
+
## Install and upgrade
|
|
36
|
+
|
|
37
|
+
Supported platforms are macOS and Linux with Python 3.12, 3.13, or 3.14. Obtain
|
|
38
|
+
the versioned wheel from your administrator, then install it:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
uv tool install --force ./open_agent_guide-*.whl
|
|
42
|
+
# Upgrade explicitly when given a newer wheel:
|
|
43
|
+
uv tool install --force ./open_agent_guide-*.whl
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
For library use, `uv add ./open_agent_guide-*.whl`. Maintainers build with
|
|
47
|
+
`uv build --package open-agent-guide` and can install from
|
|
48
|
+
`./packages/oag-client`. CI smoke-tests clean wheel installation on both
|
|
49
|
+
supported operating systems. The package is MIT-licensed. Public PyPI
|
|
50
|
+
publication as `open-agent-guide` is planned; until then contact
|
|
51
|
+
<support@openagentguide.com> for distribution. Windows and standalone
|
|
52
|
+
executables are not supported yet.
|
|
53
|
+
|
|
54
|
+
Package versions follow semantic versioning. JSON output remains version 1; new
|
|
55
|
+
and saved journals use version 2. Version-1 journals remain readable, but
|
|
56
|
+
unkeyed uncertain rows require manual reconciliation. Older clients reject
|
|
57
|
+
version-2 journals. Upgrading alone never sends requests or rewrites journals;
|
|
58
|
+
explicitly running `submit` resumes keyed uncertain rows. Use oag-client 0.2.0
|
|
59
|
+
or newer with a server that supports the create `Idempotency-Key` contract.
|
|
60
|
+
|
|
61
|
+
## Commands
|
|
62
|
+
|
|
63
|
+
Export `OAG_TOKEN` with your bearer token. `OAG_BASE_URL` defaults to
|
|
64
|
+
`https://www.openagentguide.com`; set it to your staging origin for testing. The
|
|
65
|
+
base URL cannot contain credentials, a path, query, or fragment. Bearer tokens
|
|
66
|
+
never appear in transport diagnostics. Redirects are not followed.
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
oag --version
|
|
70
|
+
oag validate batch.json --output json
|
|
71
|
+
cat batch.json | oag validate - --output jsonl
|
|
72
|
+
oag submit batch.json --journal batch.journal.json --output json
|
|
73
|
+
oag status 00000000-0000-0000-0000-000000000001 --output json
|
|
74
|
+
oag watch --file ids.txt --journal watch.journal.json --timeout 900 --output jsonl
|
|
75
|
+
oag watch 00000000-0000-0000-0000-000000000001 --journal watch-one.json
|
|
76
|
+
oag retire 00000000-0000-0000-0000-000000000001 --force --reason "stale"
|
|
77
|
+
oag retire 00000000-0000-0000-0000-000000000001 --force --successor UUID --output json
|
|
78
|
+
oag get /api/v1/catalog/products/?page_size=50
|
|
79
|
+
oag get https://www.openagentguide.com/api/v1/catalog/products/?page=2
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`get PATH` reads one catalog or submissions read-API path through the shared
|
|
83
|
+
read pacing lane and prints the JSON body. `PATH` is a relative read-API path or
|
|
84
|
+
a same-origin absolute URL, so a pagination `next` link can be passed straight
|
|
85
|
+
back without stripping its origin. An absolute `PATH` is accepted only when its
|
|
86
|
+
scheme and host match `OAG_BASE_URL` with no userinfo; a foreign origin,
|
|
87
|
+
userinfo, an unsupported scheme, or a path outside the catalog or submissions
|
|
88
|
+
read API exits 2 without a request. Catalog reads work anonymously; the
|
|
89
|
+
submissions field contract needs `OAG_TOKEN`.
|
|
90
|
+
|
|
91
|
+
`oag --version` (`-V`) prints the installed version and exits.
|
|
92
|
+
|
|
93
|
+
`validate` and `submit` accept one JSON object or an array, from a file or `-`
|
|
94
|
+
for stdin. Nested relation envelopes and explicit nulls pass through unchanged;
|
|
95
|
+
omitted keys stay omitted. Validation calls the server and returns its
|
|
96
|
+
field-path errors. Validation does not probe external citation URLs; the
|
|
97
|
+
existing batch preflight script remains available for that separate check.
|
|
98
|
+
|
|
99
|
+
Every command accepts `--output text|json|jsonl`. JSON contains `version`,
|
|
100
|
+
`records`, and `summary`; JSONL emits one `type: record` line per result
|
|
101
|
+
followed by a `type: summary` line. Output is emitted at completion, including
|
|
102
|
+
watch cancellation. Version 0.3.1 emits changed next-action guidance to stderr
|
|
103
|
+
during watch. Text includes the complete record with indented evidence, then
|
|
104
|
+
lists any check feedback and absence-attestation guidance as one scannable line
|
|
105
|
+
each so a reader sees why a row needs work without searching the JSON.
|
|
106
|
+
Diagnostics go to stderr. No command prompts.
|
|
107
|
+
|
|
108
|
+
`status` fetches one submission with all checks and reviews pages. In 0.3.1,
|
|
109
|
+
`watch` polls unresolved IDs in batches of up to 100 using
|
|
110
|
+
`ids=...&page_size=100&fields=id,status,review_ready,check_feedback,guidance`.
|
|
111
|
+
Pending records contain this compact submission snapshot. When an ID becomes
|
|
112
|
+
terminal, watch fetches its full detail and all checks and reviews pages,
|
|
113
|
+
preserving claim verdicts, rationales, citations, and resolution reasons.
|
|
114
|
+
Missing batch IDs remain `failed-to-read`. The server must support the `ids`
|
|
115
|
+
filter. Only lifecycle `merged` means `accepted`; ordinary `closed` means
|
|
116
|
+
`rejected`. Closed proposals with retirement dispositions report `withdrawn` or
|
|
117
|
+
`superseded`, with replacement IDs in `resolution.closed.successor_ids`. A check
|
|
118
|
+
error on an open submission remains `pending`. A failed detail or evidence
|
|
119
|
+
request means `failed-to-read`, including when a terminal lifecycle has been
|
|
120
|
+
seen. Watch retries unresolved records in later rounds and stops revisiting
|
|
121
|
+
terminal records only after capturing their evidence. The journal preserves
|
|
122
|
+
those terminal snapshots on restart. Use a fresh journal for a fresh view of
|
|
123
|
+
later evidence.
|
|
124
|
+
|
|
125
|
+
`retire` withdraws or supersedes one of your open submissions through the
|
|
126
|
+
server's retirement operation. With no `--successor` it withdraws the proposal;
|
|
127
|
+
one or more `--successor UUID` options supersede it with those explicit newer
|
|
128
|
+
replacement IDs, and `--reason TEXT` records an optional reason. The command
|
|
129
|
+
makes one request and never retries or runs automatically. `--force` is
|
|
130
|
+
required: without it `retire` refuses, makes no request, and exits 2, so the
|
|
131
|
+
tool never withdraws or supersedes on your behalf. The server still enforces
|
|
132
|
+
author-or-curator permission and newer-only successors. A successful retire
|
|
133
|
+
reports the server's terminal disposition, `withdrawn` or `superseded`, and
|
|
134
|
+
exits 0; a 403 or validation error exits 3. The command does not poll afterward;
|
|
135
|
+
use `status`/`watch` to observe the retired submission and its successors.
|
|
136
|
+
|
|
137
|
+
A failed read keeps the server's structured error. Every `failed-to-read` record
|
|
138
|
+
carries a `failure` object with a `kind` (`http`, `deadline`, `transport`, or
|
|
139
|
+
`client`); an `http` failure also carries `http_status`, and the server's
|
|
140
|
+
`code`, `detail`, and validation `errors` when present. The human-readable
|
|
141
|
+
`error` string stays as well. `coverage` wraps the same object in a
|
|
142
|
+
`{"version": 1, "error": {...}}` envelope on failure and exits 3; its successful
|
|
143
|
+
report is unchanged.
|
|
144
|
+
|
|
145
|
+
## Pacing and workflow deadlines
|
|
146
|
+
|
|
147
|
+
`--timeout` is an overall seconds budget, default 300 for validate/submit, 60
|
|
148
|
+
for status, and 900 for watch. It includes pacing waits, requests, retries, and
|
|
149
|
+
cooldowns. Watch pauses 15 seconds between rounds. Ctrl-C ends watch with a
|
|
150
|
+
final summary and exit 130; its journal can be resumed. Hard kills cannot emit a
|
|
151
|
+
summary.
|
|
152
|
+
|
|
153
|
+
The client spaces reads by 0.55 seconds and mutations by 3.5 seconds. Validation
|
|
154
|
+
POSTs use the mutation pace too. The `oag` CLI shares reservations and
|
|
155
|
+
Retry-After cooldowns across processes on one host that use the same pacing
|
|
156
|
+
directory, API origin, and token. The maintained population benchmark and pi
|
|
157
|
+
submitter also opt into this coordination. Python `Client` instances use local
|
|
158
|
+
pacing unless you pass `shared_pacer(base_url, token)`.
|
|
159
|
+
|
|
160
|
+
The default directory is `oag-client-pace` under the system temp directory;
|
|
161
|
+
`OAG_PACING_DIR` selects another directory. All cooperating processes must reach
|
|
162
|
+
the same directory and use the same base URL and token. The filename hashes the
|
|
163
|
+
origin and a one-way token fingerprint; the file stores timestamps, never the
|
|
164
|
+
raw token. A process crash releases the file lock, but its recorded reservations
|
|
165
|
+
remain. Separate directories, hosts, origins, or tokens do not share this state.
|
|
166
|
+
Server quotas apply account-wide across all of an account's tokens, so
|
|
167
|
+
coordinate those workers yourself. Shared pacing reduces collisions; it does not
|
|
168
|
+
guarantee that requests avoid throttling.
|
|
169
|
+
|
|
170
|
+
A transient 429 extends the shared cooldown, keeping the longest cooldown
|
|
171
|
+
reported by any cooperating process. Workers check it again after waiting for a
|
|
172
|
+
reserved slot. Numeric and HTTP-date Retry-After values are honored within the
|
|
173
|
+
workflow deadline. This cooldown applies to reads and mutations together. For
|
|
174
|
+
workers outside that shared state, pause every worker using the exhausted
|
|
175
|
+
`X-RateLimit-Scope` for at least `Retry-After` seconds and add jitter before
|
|
176
|
+
resuming. The scopes are `global_auth` for reads, and `submission` and
|
|
177
|
+
`submission_burst` for submission mutations. The open-submission-cap 429 returns
|
|
178
|
+
immediately without retrying.
|
|
179
|
+
|
|
180
|
+
Size batches against the combined workload. Fifty validation POSTs followed by
|
|
181
|
+
fifty create POSTs require about 350 seconds of mutation spacing alone, before
|
|
182
|
+
network time, retries, cooldowns, or other workers' reservations. Those are
|
|
183
|
+
separate command budgets: increase `--timeout` for each command based on its
|
|
184
|
+
share of the work, and allow additional time for watch to capture terminal
|
|
185
|
+
evidence. More concurrent processes do not increase shared throughput. Prefer
|
|
186
|
+
smaller batches, fewer simultaneous validators/submitters, and one watcher per
|
|
187
|
+
account with all unresolved IDs. Use the same pacing directory for concurrent
|
|
188
|
+
CLI validation, submission, and watch commands.
|
|
189
|
+
|
|
190
|
+
Future mutation reservations leave the read schedule unchanged. Create and
|
|
191
|
+
validate use the mutation lane; globally throttled writes such as review, merge,
|
|
192
|
+
close, and retire share the read lane. If a peer extends Retry-After during a
|
|
193
|
+
wait, the worker reserves a fresh slot to preserve spacing after the cooldown.
|
|
194
|
+
Cancelled or expired reservations remain on their lane until their slots pass;
|
|
195
|
+
restart preserves those reservations and cooldowns. Watch budgets also need time
|
|
196
|
+
for server processing, poll intervals, and terminal evidence reads across all
|
|
197
|
+
watchers. Shared pacing neither bounds outstanding server work nor eliminates
|
|
198
|
+
deadline failures. A watch timeout does not mean a submission failed: resume its
|
|
199
|
+
journal and inspect lifecycle and terminal evidence. Reuse the original submit
|
|
200
|
+
journal and idempotency keys after an uncertain create; never start a duplicate
|
|
201
|
+
batch to escape a deadline.
|
|
202
|
+
|
|
203
|
+
Requests have a 45-second total budget capped by the remaining workflow
|
|
204
|
+
deadline. Validation and keyed creates retry transport failures, 5xx, and
|
|
205
|
+
transient 429 responses, at most five attempts. Unkeyed writes retry only
|
|
206
|
+
transient 429 responses. Exhausted HTTP failures retain `http_status` alongside
|
|
207
|
+
the response. Polling makes one attempt per round. Keep terminal evidence in the
|
|
208
|
+
journal and remove those IDs from future polls.
|
|
209
|
+
|
|
210
|
+
A pacing timeout reports the lane, reserved wait, remaining budget, and requests
|
|
211
|
+
sent by that client. Submit journals retain this diagnostic with the original
|
|
212
|
+
idempotency key. Watch adds `deadline_error` to unresolved records and saves it
|
|
213
|
+
in the watch journal, preserving earlier read errors and submission snapshots.
|
|
214
|
+
Resume the same journal with a larger budget after investigating shared load.
|
|
215
|
+
Never clear the pacing file to bypass a cooldown or delete the journal to retry
|
|
216
|
+
uncertain submissions.
|
|
217
|
+
|
|
218
|
+
| Exit | Meaning |
|
|
219
|
+
| ---- | -------------------------------------------------------------------- |
|
|
220
|
+
| 0 | Validation/submission succeeded, or all watched records are terminal |
|
|
221
|
+
| 2 | Invalid arguments, configuration, input, or journal |
|
|
222
|
+
| 3 | At least one failed/ambiguous batch row or failed-to-read record |
|
|
223
|
+
| 4 | Pending records remain at the deadline or in one-shot status |
|
|
224
|
+
| 5 | All records were read, but `--require-all-merged` found a rejection |
|
|
225
|
+
| 130 | Cancelled by Ctrl-C |
|
|
226
|
+
|
|
227
|
+
Failures take precedence over pending records, which take precedence over
|
|
228
|
+
`--require-all-merged`. By default, a fully read rejection exits 0: watching has
|
|
229
|
+
completed. Use `--require-all-merged` on status/watch to require acceptance.
|
|
230
|
+
Summaries always distinguish accepted, rejected, pending, and failed-to-read;
|
|
231
|
+
batch summaries also count valid, created, failed, and ambiguous rows as
|
|
232
|
+
present.
|
|
233
|
+
|
|
234
|
+
## Resume and reconcile
|
|
235
|
+
|
|
236
|
+
Always reuse the same submit journal for the same batch. It binds the ordered
|
|
237
|
+
input hash, base URL, and token fingerprint; changed inputs, environments, or
|
|
238
|
+
tokens fail rather than replay. Tokens themselves are never stored. The journal
|
|
239
|
+
contains server evidence and may contain private submission data. Keep it
|
|
240
|
+
private.
|
|
241
|
+
|
|
242
|
+
Each new row gets a random UUID `Idempotency-Key`, flushed to the journal before
|
|
243
|
+
its first POST. Every attempt and restart reuses that key and the same input. A
|
|
244
|
+
confirmed `201` records the original submission ID as `created`, even if the
|
|
245
|
+
server has already merged or closed it. Confirmed and definitively failed rows
|
|
246
|
+
are skipped on restart. Keyed ambiguous or pending rows are retried within the
|
|
247
|
+
command's deadline. Exhausted transient failures remain unresolved.
|
|
248
|
+
|
|
249
|
+
Journal writes are atomic and flushed to disk. A lock prevents simultaneous
|
|
250
|
+
writers; after a hard kill, verify no writer remains before deleting the `.lock`
|
|
251
|
+
file. Never delete a journal or change its keys to recover from a timeout. A
|
|
252
|
+
deadline or cancellation after an uncertain attempt preserves its key.
|
|
253
|
+
|
|
254
|
+
Older entries without keys cannot be replayed safely. Inspect your submissions
|
|
255
|
+
on the server, including all statuses, and compare the complete payload and
|
|
256
|
+
submitter. After positively identifying an ID, associate it with the input row:
|
|
257
|
+
|
|
258
|
+
```sh
|
|
259
|
+
oag reconcile batch.json --journal batch.journal.json --row 2 --id UUID
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
This checks that the ID is readable; the operator verifies the row-to-ID match.
|
|
263
|
+
It does not create or edit a server submission. If no match can be found,
|
|
264
|
+
absence is not proof of failure. Reconcile with an administrator before creating
|
|
265
|
+
a new batch and journal. A server `409 idempotency_key_reused` also requires
|
|
266
|
+
inspection, not a fresh key for the uncertain write. The effective callback URL
|
|
267
|
+
must remain unchanged for a retry; changing a token's default callback can cause
|
|
268
|
+
that conflict.
|
|
269
|
+
|
|
270
|
+
For a definitive failed row, correct the payload and explicitly submit a new
|
|
271
|
+
batch with a new journal. Existing submissions are immutable. To supersede a
|
|
272
|
+
stalled open create, inspect the existing submission first, then explicitly set
|
|
273
|
+
`"force": true` in a new payload and submit with a new journal. The client never
|
|
274
|
+
adds `force` or edits an existing proposal. Preserve prior journals for audit.
|
|
275
|
+
|
|
276
|
+
## Python API
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
from oag_client import Client, shared_pacer
|
|
280
|
+
from oag_client.transport import HTTPTransport
|
|
281
|
+
from oag_client.workflows import payloads, validate
|
|
282
|
+
|
|
283
|
+
base_url = "https://www.openagentguide.com"
|
|
284
|
+
# Omit `pacer` for in-process pacing; pass `shared_pacer` to coordinate with
|
|
285
|
+
# other processes on this host that share the token.
|
|
286
|
+
client = Client(HTTPTransport(token), base_url, pacer=shared_pacer(base_url, token))
|
|
287
|
+
records = validate(client, payloads(json_text), deadline=client.clock.monotonic() + 60)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`submit`, `status`, `watch`, `summary`, and `exit_code` are also available from
|
|
291
|
+
`oag_client.workflows`; `Journal` lives in `oag_client.journal`. `Clock` and
|
|
292
|
+
`Transport` protocols allow deterministic testing. Custom transports must accept
|
|
293
|
+
the optional `idempotency_key` keyword and forward it as `Idempotency-Key` for
|
|
294
|
+
create requests. The HTTP transport is a synchronous entry point; async callers
|
|
295
|
+
should use a worker thread. Application code supplies authorization. Pacing is
|
|
296
|
+
in-process by default; pass `shared_pacer(base_url, token)` (or any `Pacer`) to
|
|
297
|
+
coordinate processes using the same directory, origin, and token on one host.
|
|
298
|
+
Coordinate other tokens or hosts yourself because server quotas cover the whole
|
|
299
|
+
account.
|
|
300
|
+
|
|
301
|
+
### Trusted bulk read pacing
|
|
302
|
+
|
|
303
|
+
The default read spacing is 0.55 seconds. If a maintainer has granted your
|
|
304
|
+
account `submissions.bulk_submit_catalogsubmission`, set `OAG_READ_SPACING=0.11`
|
|
305
|
+
for the CLI, or pass `read_spacing=0.11` to
|
|
306
|
+
`shared_pacer(base_url, token, ...)`. This targets about 545 reads/minute under
|
|
307
|
+
the server's default 600/minute trusted read quota. The server setting is
|
|
308
|
+
`BULK_AUTHENTICATED_READ_RATE`.
|
|
309
|
+
|
|
310
|
+
Use the same spacing, token, and `OAG_PACING_DIR` for coordinated workers on one
|
|
311
|
+
host. Keep status reads batched through `watch`; more quota doesn't require
|
|
312
|
+
polling each submission separately. Separate tokens for one account share the
|
|
313
|
+
server quota but need caller-managed pacing coordination. After permission
|
|
314
|
+
revocation, restore 0.55 seconds. The server checks permission on each request
|
|
315
|
+
and clients continue to honor shared Retry-After cooldowns.
|
|
316
|
+
|
|
317
|
+
Create/validate spacing stays at 3.5 seconds. Review, merge, close, and retire
|
|
318
|
+
writes keep a separate 0.55-second minimum interval even with faster reads.
|
|
319
|
+
Custom `Pacer.reserve` implementations must accept `global_mutation=False`.
|
|
320
|
+
|
|
321
|
+
## Research an existing product's gaps
|
|
322
|
+
|
|
323
|
+
Use `oag coverage PRODUCT --output json` for one compact report of the product's
|
|
324
|
+
coverage and unknown scored fields. The default text output includes evidence
|
|
325
|
+
guidance. The equivalent reads are
|
|
326
|
+
`GET /api/v1/catalog/products/{uuid-or-slug}/coverage/` and the MCP tool
|
|
327
|
+
`get_product_coverage`. Read each gap's shared semantics, schema reference, and
|
|
328
|
+
absence page class before drafting. Keep unsupported values unknown. A confirmed
|
|
329
|
+
absence can improve coverage without improving the AI-native score. Use
|
|
330
|
+
submission validation to inspect projected changes after collecting evidence.
|