gravity-cli 0.5.2__tar.gz → 0.5.4__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.
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/AGENT_STANDARD.md +50 -19
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/PKG-INFO +53 -14
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/README.md +51 -12
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/catalog_imported.yaml +478 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/cron.py +26 -1
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/manifest.py +56 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/validation.py +11 -1
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/pyproject.toml +1 -1
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_cron.py +16 -1
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_manifest.py +106 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/pyproject.toml +2 -2
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/BUILDER_GUIDE.md +38 -26
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/_runner_script.py +10 -3
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/api.py +57 -15
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/cli.py +15 -0
- gravity_cli-0.5.4/src/gravity_cli/commands/adapt.py +182 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/build.py +13 -2
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/connect.py +21 -4
- gravity_cli-0.5.4/src/gravity_cli/commands/dev.py +40 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/login.py +19 -3
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/push.py +16 -2
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/run.py +182 -62
- gravity_cli-0.5.4/src/gravity_cli/commands/runs.py +103 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/schedule.py +23 -6
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/validate.py +95 -19
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/config.py +27 -8
- gravity_cli-0.5.4/src/gravity_cli/dev.py +315 -0
- gravity_cli-0.5.4/src/gravity_cli/dev_page/index.html +406 -0
- gravity_cli-0.5.4/src/gravity_cli/localrun.py +228 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/project.py +7 -2
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/timeline.py +3 -2
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/ui.py +49 -6
- gravity_cli-0.5.4/tests/test_adapt.py +134 -0
- gravity_cli-0.5.4/tests/test_agents.py +91 -0
- gravity_cli-0.5.4/tests/test_api.py +218 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_build_push.py +70 -3
- gravity_cli-0.5.4/tests/test_connect.py +146 -0
- gravity_cli-0.5.4/tests/test_dev.py +291 -0
- gravity_cli-0.5.4/tests/test_localrun.py +83 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_run.py +95 -7
- gravity_cli-0.5.4/tests/test_runs.py +91 -0
- gravity_cli-0.5.4/tests/test_schedule.py +63 -0
- gravity_cli-0.5.4/tests/test_session.py +146 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_templates.py +21 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_ui.py +14 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_validate.py +69 -2
- gravity_cli-0.5.4/tests/test_welcome.py +98 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/uv.lock +2 -2
- gravity_cli-0.5.2/src/gravity_cli/commands/adapt.py +0 -154
- gravity_cli-0.5.2/src/gravity_cli/commands/runs.py +0 -49
- gravity_cli-0.5.2/tests/test_adapt.py +0 -71
- gravity_cli-0.5.2/tests/test_api.py +0 -101
- gravity_cli-0.5.2/tests/test_connect.py +0 -78
- gravity_cli-0.5.2/tests/test_session.py +0 -80
- gravity_cli-0.5.2/tests/test_welcome.py +0 -43
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/.env.example +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/.github/workflows/ci.yml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/.github/workflows/release.yml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/.gitignore +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/LICENSE +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/NOTICE +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/RELEASING.md +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/TEMPLATES.md +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/LICENSE +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/NOTICE +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/README.md +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/__init__.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/__main__.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/catalog.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/catalog.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/contract.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/errors.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/export.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/gen_catalog.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/gravity_schema/source_scan.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/schema/manifest.schema.json +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/conftest.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_catalog_parity.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_errors.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_json_schema.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_kind_outputs.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_slots.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_source_scan.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/packages/gravity-schema/tests/test_validation.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/__init__.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/__main__.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/__init__.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/guide.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/init.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/commands/tools.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/manifest.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/chat/.gitignore +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/chat/manifest.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/chat/requirements.txt +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/chat/src/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/deepagent/.gitignore +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/deepagent/manifest.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/deepagent/requirements.txt +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/deepagent/src/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/minimal/.gitignore +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/minimal/manifest.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/minimal/requirements.txt +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/minimal/src/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/.gitignore +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/manifest.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/requirements.txt +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/src/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/src/gateway.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/src/nodes/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/src/prompts.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/src/gravity_cli/templates/structured/src/state.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/starter/manifest.yaml +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/starter/requirements.txt +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/starter/src/agent.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/starter/src/summary.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/starter/tests/test_summary.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/conftest.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_gateway_token.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_manifest_integration.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_timeline.py +0 -0
- {gravity_cli-0.5.2 → gravity_cli-0.5.4}/tests/test_tools.py +0 -0
|
@@ -39,7 +39,7 @@ description: One line. # ≤500 chars
|
|
|
39
39
|
|
|
40
40
|
runtime:
|
|
41
41
|
framework: langgraph # only value accepted
|
|
42
|
-
python: "3.
|
|
42
|
+
python: "3.12" # the platform runs 3.12; validate refuses any other
|
|
43
43
|
entrypoint: src/agent.py:graph # file:object — see §3
|
|
44
44
|
timeout_seconds: 300 # 10–900
|
|
45
45
|
|
|
@@ -67,7 +67,7 @@ resources:
|
|
|
67
67
|
triggers: # optional — what starts a run
|
|
68
68
|
manual: true # default
|
|
69
69
|
# schedule:
|
|
70
|
-
# cron: "0 9 * * 1" # 5 fields: digits, * / , - only (no @daily, no MON)
|
|
70
|
+
# cron: "0 9 * * 1" # 5 fields: digits, * / , - only (no @daily, no MON); every 5 minutes at the fastest; one day field at most; Asia/Kolkata
|
|
71
71
|
# consumer_can_change: true
|
|
72
72
|
|
|
73
73
|
approvals: # optional — tools that pause the run for the consumer's yes
|
|
@@ -78,8 +78,9 @@ approvals: # optional — tools that pause the run for th
|
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
**`approvals` is enforced by the gateway.** A listed tool is held until a
|
|
81
|
-
human answers: in `gravity run` you're asked (`
|
|
82
|
-
no answer is a no)
|
|
81
|
+
human answers: in `gravity run` you're asked (`y approve · n reject · enter reject`,
|
|
82
|
+
default no; no answer is a no) and `gravity dev` shows Approve/Reject buttons; in the
|
|
83
|
+
product it's the consumer's approval inbox. Not
|
|
83
84
|
approved, the call returns `APPROVAL_REJECTED` (or `APPROVAL_TIMEOUT` after 4
|
|
84
85
|
minutes) and never runs — handle that and fall back, as `meeting-notes`
|
|
85
86
|
keeps the recap as a draft. Your code can't skip the question: the gateway
|
|
@@ -109,7 +110,7 @@ async def graph(): # ✓ recommended — an async factory
|
|
|
109
110
|
...
|
|
110
111
|
return workflow.compile()
|
|
111
112
|
|
|
112
|
-
graph = asyncio.run(_build()) #
|
|
113
|
+
graph = asyncio.run(_build()) # ✗ gravity validate refuses asyncio.run at import
|
|
113
114
|
graph = _build() # ✓ also fine — a coroutine is awaited
|
|
114
115
|
```
|
|
115
116
|
|
|
@@ -179,9 +180,10 @@ tools = await client.get_tools() # exactly permissions.tools, nothing else
|
|
|
179
180
|
Tool names are `<app>.<action>`, lowercase, from `gravity tools` — Gravity's
|
|
180
181
|
names, never a vendor's (`gmail.read`, not `GMAIL_FETCH_EMAILS`). The gateway
|
|
181
182
|
hands them to your model with `_` for `.` (`gmail_read`), because
|
|
182
|
-
OpenAI-family models reject dots in function names.
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
OpenAI-family models reject dots in function names. Outbound network from the
|
|
184
|
+
sandbox is open today (it may be locked down later), but anything that acts on a
|
|
185
|
+
user's account must go through a tool: that is where the credentials are, and a
|
|
186
|
+
direct call would have none. Declare what you need; don't reach around it.
|
|
185
187
|
|
|
186
188
|
**Models** go through the LLM gateway with the same token:
|
|
187
189
|
|
|
@@ -202,6 +204,26 @@ emb = OpenAIEmbeddings(model="voyageai/voyage-4-lite", # or google/gemini-embe
|
|
|
202
204
|
vectors = await emb.aembed_documents(["first text", "second text"])
|
|
203
205
|
```
|
|
204
206
|
|
|
207
|
+
**Images** come from an image model through the same URL and token: no tool to
|
|
208
|
+
declare. Ask for image output; the picture comes back as a data URL, which is
|
|
209
|
+
exactly what the corpus takes (§8):
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
async with httpx.AsyncClient(timeout=120) as http:
|
|
213
|
+
resp = await http.post(f"{os.environ['GRAVITY_LLM_URL']}/chat/completions",
|
|
214
|
+
headers={"Authorization": f"Bearer {os.environ['GRAVITY_RUN_TOKEN']}"},
|
|
215
|
+
json={"model": "google/gemini-2.5-flash-image", # or openai/gpt-5-image-mini
|
|
216
|
+
"modalities": ["image", "text"],
|
|
217
|
+
"messages": [{"role": "user", "content": "A flat illustration of ..., no text"}]})
|
|
218
|
+
resp.raise_for_status()
|
|
219
|
+
src = resp.json()["choices"][0]["message"]["images"][0]["image_url"]["url"] # data:image/png;base64,...
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
An image is a few MB and the whole state is checkpointed after every step, so
|
|
223
|
+
make pictures in the **last** node (or the one that builds the corpus) and keep
|
|
224
|
+
them out of state until then. Each one is metered and counts toward the run's
|
|
225
|
+
budget like any model call.
|
|
226
|
+
|
|
205
227
|
Those three env vars — `GRAVITY_GATEWAY_URL`, `GRAVITY_LLM_URL`,
|
|
206
228
|
`GRAVITY_RUN_TOKEN` — are the entire Gravity surface, plus the `gravity`
|
|
207
229
|
package for tools on the platform (§8). No `OPENAI_API_KEY`: locally and in
|
|
@@ -221,12 +243,17 @@ Windows or macOS pins the wrong wheels and only fails at deploy.
|
|
|
221
243
|
|
|
222
244
|
`gravity run --input k=v` runs your graph in your own venv against a real
|
|
223
245
|
gateway, exactly as production does: tools over `GRAVITY_GATEWAY_URL`,
|
|
224
|
-
models over `GRAVITY_LLM_URL`, both with `GRAVITY_RUN_TOKEN`.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
`
|
|
246
|
+
models over `GRAVITY_LLM_URL`, both with `GRAVITY_RUN_TOKEN`. `gravity login`
|
|
247
|
+
gives you a gateway token; each run trades it for a run token scoped to your
|
|
248
|
+
`permissions.tools`, so an undeclared tool is refused locally exactly as it
|
|
249
|
+
will be when hosted. Your agent only ever sees the run token. The gateway is
|
|
250
|
+
the one Gravity names (`GET /api/cli/config`); set `GRAVITY_GATEWAY_URL` (and
|
|
251
|
+
`GRAVITY_DEV_TOKEN`, in `~/.gravity/.env`) only for a gateway you run yourself.
|
|
252
|
+
|
|
253
|
+
`gravity dev` opens a local dashboard over the same runs: a form from your
|
|
254
|
+
manifest, a live timeline, approvals, the result and a history. A run from
|
|
255
|
+
`gravity run` in the same folder shows up in it, and the other way round (both
|
|
256
|
+
leave their record in `.gravity/runs/`; one run is live per folder).
|
|
230
257
|
|
|
231
258
|
## 7. What's checked where
|
|
232
259
|
|
|
@@ -250,10 +277,10 @@ graph. `gravity` is preinstalled in the image; don't put it in
|
|
|
250
277
|
|
|
251
278
|
**Tools: `await gravity.tools()`** instead of your own `MultiServerMCPClient`.
|
|
252
279
|
The same LangChain tools under the same names (`gmail_read`), from the same env
|
|
253
|
-
vars. Off the platform (`gravity run`, tests)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
280
|
+
vars. Off the platform (`gravity run`, `gravity dev`, tests) the package is not
|
|
281
|
+
installed and is not on PyPI: use the client in §4 directly, as the templates do
|
|
282
|
+
(it is the same tools under the same names), or guard the import
|
|
283
|
+
(`try: import gravity except ImportError: ...`). A plain dict works for the corpus.
|
|
257
284
|
On the platform, each tool in `approvals.required_for` is wrapped: calling it
|
|
258
285
|
checkpoints the run and stops it until the consumer decides, with no
|
|
259
286
|
connection held open. Approved, the call runs with the arguments the consumer
|
|
@@ -328,6 +355,7 @@ corpus = gravity.Corpus(
|
|
|
328
355
|
facts=[gravity.Fact(label="TAM", value="$18B", source="s1")], # value: text or a number
|
|
329
356
|
table=gravity.Table(columns=["Segment", "Teams"], rows=[["Founders", "1.2M"]]),
|
|
330
357
|
notes="speaker notes / read-out text",
|
|
358
|
+
images=[gravity.Image(src=src, alt="server rack", caption="Option A")], # data URL, see §4
|
|
331
359
|
sections=[gravity.Section(heading="one level of nesting, same shape")],
|
|
332
360
|
)],
|
|
333
361
|
sources=[gravity.Source(id="s1", title="Report", url="https://example.com")],
|
|
@@ -336,7 +364,10 @@ return {**corpus.to_state(), "result": {"title": corpus.title}}
|
|
|
336
364
|
```
|
|
337
365
|
|
|
338
366
|
A plain dict of the same shape works too. The models catch a typo when the
|
|
339
|
-
corpus is built rather than when it's rendered.
|
|
367
|
+
corpus is built rather than when it's rendered. Images (`png`, `jpeg`, `webp`
|
|
368
|
+
or `gif` data URLs, at most 8 MB each and 12 per corpus) are embedded in the
|
|
369
|
+
Word, PowerPoint and Markdown downloads and shown on `/app` and in `gravity
|
|
370
|
+
dev`; an emailed output names each one as `[image: alt — caption]` instead. Set `result` as well: it's
|
|
340
371
|
what the run returns.
|
|
341
372
|
|
|
342
373
|
## 9. Checklist
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: gravity-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: gravity cli — init, run, and push python agents to the Gravity marketplace
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
License-File: NOTICE
|
|
8
8
|
Requires-Python: >=3.12
|
|
9
|
-
Requires-Dist: gravity-schema==0.5.
|
|
9
|
+
Requires-Dist: gravity-schema==0.5.4
|
|
10
10
|
Requires-Dist: httpx>=0.27.0
|
|
11
11
|
Requires-Dist: keyring>=25.0.0
|
|
12
12
|
Requires-Dist: python-dotenv>=1.0.0
|
|
@@ -108,10 +108,10 @@ The same rules apply on your laptop and when the agent runs hosted, because both
|
|
|
108
108
|
|
|
109
109
|
| | |
|
|
110
110
|
|---|---|
|
|
111
|
-
| Commands |
|
|
111
|
+
| Commands | 18, grouped into build an agent, publish, your agents, account and help |
|
|
112
112
|
| Starter templates | 4: `minimal`, `structured`, `deepagent`, `chat` |
|
|
113
|
-
| Tool catalog | 1,
|
|
114
|
-
| Test suite |
|
|
113
|
+
| Tool catalog | 1,402 tools across 15 apps (Gmail, Slack, Linear, GitHub, Calendar, Drive, Sheets, LinkedIn, Jira, Confluence, Notion, WhatsApp, web search, and two built-ins), 28 of them curated |
|
|
114
|
+
| Test suite | 466 tests (214 CLI, 252 schema), run on Ubuntu and Windows with Python 3.12 and 3.13 |
|
|
115
115
|
| Runtime contract | 3 environment variables, no Gravity import in your code |
|
|
116
116
|
|
|
117
117
|
## Five things to know before you start
|
|
@@ -196,6 +196,7 @@ Run `gravity help` for this list in the terminal, and add `-h` to any command fo
|
|
|
196
196
|
| **Build an agent** | [`gravity init`](#gravity-init) | Create a new agent from a template |
|
|
197
197
|
| | [`gravity validate`](#gravity-validate) | Check your agent for mistakes before it runs |
|
|
198
198
|
| | [`gravity run`](#gravity-run) | Run your agent locally against real tools |
|
|
199
|
+
| | [`gravity dev`](#gravity-dev) | Open a local dashboard to run and watch your agent |
|
|
199
200
|
| | [`gravity schedule`](#gravity-schedule) | Run your agent on its schedule, locally |
|
|
200
201
|
| | [`gravity adapt`](#gravity-adapt) | Write a new slot adapter with AI, kept only if its tests pass |
|
|
201
202
|
| **Publish** | [`gravity build`](#gravity-build) | Package your agent into `build/agent.zip` |
|
|
@@ -211,7 +212,7 @@ Run `gravity help` for this list in the terminal, and add `-h` to any command fo
|
|
|
211
212
|
| **Help** | [`gravity guide`](#gravity-guide) | Read the builder guide: how to build a good agent |
|
|
212
213
|
| | [`gravity help`](#gravity-help) | Show the list of commands |
|
|
213
214
|
|
|
214
|
-
`gravity --api-url URL <command>` saves a different control-plane address to `~/.gravity/config.json
|
|
215
|
+
`gravity --api-url URL <command>` saves a different control-plane address to `~/.gravity/config.json`; it must start with `http://` or `https://`. The flag applies to the command it is given with; on later commands a `GRAVITY_API_URL` in `~/.gravity/.env` or the shell still wins over `config.json`, and the CLI says so when that is the case. `gravity --version` (or `-V`) prints the installed version. Wherever a command takes `[path]`, it is the agent's folder and defaults to the current one.
|
|
215
216
|
|
|
216
217
|
### `gravity init`
|
|
217
218
|
|
|
@@ -260,6 +261,9 @@ What it checks:
|
|
|
260
261
|
- every imported write tool is under `approvals.required_for`
|
|
261
262
|
- your code never names a write tool the manifest does not grant
|
|
262
263
|
- a warning, never a failure, for read tools your code names but the manifest does not declare
|
|
264
|
+
- `graph` is an `async def` (or a compiled graph), not a plain `def` or a bare value; a name bound by an import counts
|
|
265
|
+
- nothing under `src/` reads `os.environ` or calls `asyncio.run` at module level, and no import is relative
|
|
266
|
+
- a schedule runs at most every 5 minutes and restricts the day of the month or the weekday, not both
|
|
263
267
|
|
|
264
268
|
```bash
|
|
265
269
|
gravity validate
|
|
@@ -291,10 +295,33 @@ gravity run --reply "make it shorter"
|
|
|
291
295
|
- Requires a gateway token: the one `gravity login` stores, or `GRAVITY_DEV_TOKEN`.
|
|
292
296
|
- A call to a tool in `approvals.required_for` pauses, shows what it would do, and waits for `y` or `n`. With no terminal to ask in, it is rejected.
|
|
293
297
|
- Exits with code 0 when the run finishes and 1 when it fails.
|
|
298
|
+
- Leaves a record in `.gravity/runs/<id>/` (`run.json` and `events.jsonl`), which is what `gravity dev` reads. One run is live per folder at a time, because runs share the folder's memory, store and thread files.
|
|
299
|
+
|
|
300
|
+
### `gravity dev`
|
|
301
|
+
|
|
302
|
+
Open a local dashboard for the agent in this folder: a form built from the manifest's inputs, a live timeline of each step, model call and tool call, approval buttons for held calls, the result, and a history of runs.
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
gravity dev [path] [--port 4747] [--no-open] [--llm-url URL]
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
| Option | Description |
|
|
309
|
+
|---|---|
|
|
310
|
+
| `--port N` | Port to listen on (default 4747). If it is taken, a free one is used and printed. |
|
|
311
|
+
| `--no-open` | Print the address without opening a browser (SSH, WSL, CI) |
|
|
312
|
+
| `--llm-url URL` | Model endpoint to use instead of `GRAVITY_LLM_URL` |
|
|
313
|
+
|
|
314
|
+
- A run from `gravity run` in the same folder shows up in the dashboard live, and a run started in the dashboard is the same run (same engine, same memory, store and thread files), so `gravity run --reply` continues it.
|
|
315
|
+
- It listens on `127.0.0.1` only, behind a random token in the printed address, for as long as the command runs. Ctrl+C stops it and any run it started. Nothing keeps running in the background.
|
|
316
|
+
- Connected accounts: it shows the accounts your tools need and a Connect button for each one that is missing.
|
|
317
|
+
- Approvals: a call held for approval can be decided in the terminal or in the dashboard; whichever answers first wins.
|
|
318
|
+
- Cancel a run from the dashboard only if the dashboard started it; stop a terminal run with Ctrl+C in that terminal.
|
|
319
|
+
- Results show as text. Word, PowerPoint and CSV files are produced by Gravity after you push. A file input is read as text here.
|
|
320
|
+
- Same requirements as `gravity run`: a gateway token from `gravity login`, or `GRAVITY_DEV_TOKEN`.
|
|
294
321
|
|
|
295
322
|
### `gravity schedule`
|
|
296
323
|
|
|
297
|
-
Run the agent on its `triggers.schedule`, the way the platform will, until you press Ctrl+C. Each tick is an ordinary run with the same inputs.
|
|
324
|
+
Run the agent on its `triggers.schedule`, the way the platform will, until you press Ctrl+C. Ticks are timed in Asia/Kolkata, as the hosted schedules are. Each tick is an ordinary run with the same inputs; a missing required input is refused before the first tick.
|
|
298
325
|
|
|
299
326
|
```
|
|
300
327
|
gravity schedule [path] [--input KEY=VALUE]... [--cron EXPR] [--now]
|
|
@@ -334,7 +361,7 @@ gravity adapt <slot> <name> --tools TOOLS [--hint TEXT] [--model MODEL] [--path
|
|
|
334
361
|
gravity adapt deliver slack --tools slack.send,slack.list_channels --hint "post to #leads"
|
|
335
362
|
```
|
|
336
363
|
|
|
337
|
-
Requires `tests/test_<slot>_adapters.py` in the project
|
|
364
|
+
Requires `tests/test_<slot>_adapters.py` in the project and a gateway token (`gravity login`, or `GRAVITY_DEV_TOKEN`). It makes up to 3 attempts, feeding each test failure back to the model.
|
|
338
365
|
|
|
339
366
|
### `gravity build`
|
|
340
367
|
|
|
@@ -344,7 +371,7 @@ Validate the agent, then bundle it into `build/agent.zip` with its hashes in `bu
|
|
|
344
371
|
gravity build [path]
|
|
345
372
|
```
|
|
346
373
|
|
|
347
|
-
The bundle holds `manifest.yaml`, `requirements.txt`, `requirements.lock`, `src/` and `tests
|
|
374
|
+
The bundle holds `manifest.yaml`, `requirements.txt`, `requirements.lock`, `src/`, `tests/` and `tools_needed.yaml` when present; dotfiles under `src/` and `tests/` are left out. It refuses to build without `requirements.lock` (run `gravity validate` first). The same source always produces the same bytes.
|
|
348
375
|
|
|
349
376
|
```bash
|
|
350
377
|
gravity build
|
|
@@ -362,6 +389,9 @@ gravity push [path]
|
|
|
362
389
|
- Refuses if there is no build, or if the source changed since the build. Run `gravity build` again.
|
|
363
390
|
- A published version can never be replaced. Raise `version` in the manifest to publish again.
|
|
364
391
|
- Press Ctrl+C to stop waiting; the build carries on, and `gravity agents` shows its status.
|
|
392
|
+
- The bundle may be at most 30 MB; a larger `agent.zip` is refused before upload. Remove large files from `src/` or `tests/` and build again.
|
|
393
|
+
- The manifest travels in a request header, so `manifest.yaml` must stay under 12 KB once encoded; a larger one is refused before upload. Keep descriptions and help text short.
|
|
394
|
+
- Re-pushing a version whose build failed, without changing the source, is refused with the failure reason: fix it and raise `version` in the manifest.
|
|
365
395
|
|
|
366
396
|
```bash
|
|
367
397
|
gravity build && gravity push
|
|
@@ -369,7 +399,7 @@ gravity build && gravity push
|
|
|
369
399
|
|
|
370
400
|
### `gravity agents`
|
|
371
401
|
|
|
372
|
-
List your published agents with their version, status and last update.
|
|
402
|
+
List your published agents with their version, status, review and last update. Under the table it prints what the Gravity team told you: the reviewer's notes on an approved or rejected version, and the reason if an agent was turned off. A rejected version needs a fix and a new `version:` in `manifest.yaml` before you push again. A failed build prints its reason under the table.
|
|
373
403
|
|
|
374
404
|
```
|
|
375
405
|
gravity agents
|
|
@@ -428,7 +458,7 @@ gravity logout
|
|
|
428
458
|
|
|
429
459
|
### `gravity whoami`
|
|
430
460
|
|
|
431
|
-
Show the account you are signed in as, and whether you hold a gateway token and until when.
|
|
461
|
+
Show the account you are signed in as, and whether you hold a gateway token and until when (an expired one is a warning).
|
|
432
462
|
|
|
433
463
|
```
|
|
434
464
|
gravity whoami
|
|
@@ -628,7 +658,7 @@ resources:
|
|
|
628
658
|
triggers:
|
|
629
659
|
manual: true # the consumer can start a run
|
|
630
660
|
schedule:
|
|
631
|
-
cron: "0 8 * * 1-5" # weekdays at 08:00,
|
|
661
|
+
cron: "0 8 * * 1-5" # weekdays at 08:00, Asia/Kolkata
|
|
632
662
|
consumer_can_change: true
|
|
633
663
|
|
|
634
664
|
state:
|
|
@@ -672,7 +702,7 @@ outputs: # extra formats the platform renders and deliv
|
|
|
672
702
|
| `approvals.required_for` | no | none | Tools that pause until a person approves. Each must also be declared under `permissions.tools` or a slot adapter. |
|
|
673
703
|
| `resources.memory_mb` | no | `512` | 128 to 4096. A request; the platform may lower it. |
|
|
674
704
|
| `triggers.manual` | no | `true` | Whether the consumer can start a run. Something must start the agent: `manual`, a `schedule` or a `webhook`. |
|
|
675
|
-
| `triggers.schedule` | no | none | `cron` (5 fields,
|
|
705
|
+
| `triggers.schedule` | no | none | `cron` (5 fields, Asia/Kolkata, such as `"0 9 * * 1"`; every 5 minutes at the fastest; day of month or weekday, not both) and `consumer_can_change` (default `true`). |
|
|
676
706
|
| `triggers.webhook` | no | none | A list of events; `github.push` is the only one today. |
|
|
677
707
|
| `state.max_kb` | no | no memory | Include `state:` to keep memory between runs, in `state["memory"]`. 1 to 256 KB. |
|
|
678
708
|
| `slots.<name>` | no | none | A swappable part: `label`, `default` adapter, and `adapters` mapping each adapter name to the tools it may call. Code lives in `src/adapters/<slot>/<adapter>.py`. Slot names cannot repeat an input's name. |
|
|
@@ -700,6 +730,8 @@ Files the CLI writes:
|
|
|
700
730
|
| `.gravity/payload.json` | `run` | The inputs passed to the agent |
|
|
701
731
|
| `.gravity/thread.json` | `run` | The last conversation of a chat agent, for `--reply` |
|
|
702
732
|
| `.gravity/memory.json` | `run` | Memory kept between runs, when the manifest declares `state` |
|
|
733
|
+
| `.gravity/payload.json` | `run`, `dev` | The run's inputs for the runner; deleted when the run ends (`run.json` keeps them with secret inputs redacted) |
|
|
734
|
+
| `.gravity/tool_schemas.json` | `adapt` | Argument schemas of every tool the slot uses, read from the gateway |
|
|
703
735
|
|
|
704
736
|
The template `.gitignore` excludes `build/`, `.gravity/` and `.env`.
|
|
705
737
|
|
|
@@ -747,7 +779,12 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
|
|
|
747
779
|
| `Can't reach the gateway at …` | No gateway at that address. Set `GRAVITY_GATEWAY_URL` to your gateway's `/mcp` address. |
|
|
748
780
|
| `The gateway refused this run` | The gateway rejected the token or a declared tool. Run `gravity whoami` to check the token, or `gravity login` for a fresh one. |
|
|
749
781
|
| `You are not signed in` | A control-plane command without credentials. Run `gravity login`. |
|
|
750
|
-
| `Can't reach Gravity at …` | The control plane did not answer. Check `GRAVITY_API_URL` in `~/.gravity/.env
|
|
782
|
+
| `Can't reach Gravity at …` | The control plane did not answer. Check `GRAVITY_API_URL` in `~/.gravity/.env`, or `api_url` in `~/.gravity/config.json` (set by `gravity --api-url`). |
|
|
783
|
+
| `Gravity refused GRAVITY_API_TOKEN` | The dev token in `~/.gravity/.env` is wrong or revoked. Fix it there, or remove it and run `gravity login`. |
|
|
784
|
+
| `… did not answer with JSON` or `Gravity answered 5xx at …` | A proxy, VPN sign-in page or outage is answering instead of Gravity. Check `GRAVITY_API_URL`; for a 5xx wait a minute and retry, then tell Gravity if it persists. |
|
|
785
|
+
| `Another run is live` | Runs in one folder take turns. Wait for it, or stop it; if none is live, delete `.gravity/run.lock`. |
|
|
786
|
+
| `Manifest is not UTF-8 text` | Notepad saved it as "Unicode" (UTF-16). Re-save it with Encoding: UTF-8. |
|
|
787
|
+
| `could not load the agent: No module named …` only on Windows | Windows limits paths to 260 characters and some packages in `.venv` exceed it from a deep folder. Move the agent to a shorter path or enable long paths. |
|
|
751
788
|
| `Missing required input: …` | Pass each required input with `--input name=value`, or give it a `default` in the manifest. |
|
|
752
789
|
| `No build to push` or `The build is stale` | Run `gravity build` again after any change to `src/`, the manifest or the requirements. |
|
|
753
790
|
| `✗ requirements.lock` in `gravity validate` | A dependency has no prebuilt package for the platform image (ARM64 Linux). Pick a version that publishes one, or a different package. |
|
|
@@ -755,6 +792,8 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
|
|
|
755
792
|
|
|
756
793
|
## What's new
|
|
757
794
|
|
|
795
|
+
- **0.5.4** `gravity agents` shows each agent's review: a REVIEW column (not submitted, submitted, approved, rejected), and under "From the Gravity team" the reviewer's notes and what to do next. An agent the Gravity team turned off shows as `off` with the reason. UPDATED reads "3 min ago" instead of a timestamp, and status and review are coloured. Also, from a full audit of every command: `gravity --version`. Clear messages instead of tracebacks for: a proxy or sign-in page answering instead of Gravity, a refused `GRAVITY_API_TOKEN` or `GRAVITY_DEV_TOKEN`, an expired sign-in code, a non-UTF-8 manifest, an out-of-range `--port`, a missing agent folder, a malformed session file. `gravity validate` now refuses what the build would refuse: a `graph` that is not an async factory, `os.environ` or `asyncio.run` at import, relative imports, unquoted `python: 3.12`, schedules faster than every 5 minutes or with both day fields, out-of-range cron fields; it accepts a re-exported `graph`. `gravity agents` shows the review status and failure reasons; `gravity runs` never shortens an id; `gravity logs` never wraps. `gravity push` refuses a bundle over 30 MB or a manifest over 12 KB before uploading, and says why when a failed version is re-pushed. `gravity build` ships `tools_needed.yaml`, leaves dotfiles out, and refuses to build without `requirements.lock`. `gravity adapt` leaves the folder untouched when a model call fails. `gravity schedule` checks inputs before the first tick and runs on Asia/Kolkata like the hosted schedules. `gravity run` deletes `.gravity/payload.json` after the run, warns when no `.venv` is present, and keeps a plain agent's `result`. `gravity connect <app>` refuses on the shared test account instead of attaching your account to it. The builder guide and agent standard describe the real flow (init, validate, run or dev, build, push, review on /app).
|
|
796
|
+
- **0.5.3** `gravity dev` opens a local dashboard for your agent: a form from your manifest, a live timeline, approvals, the result and run history; runs from `gravity run` in the same folder show up in it live, and the other way round. WhatsApp joins the catalog (51 tools; 1,402 across 15 apps including the curated and built-in ones). Agents can return generated images: put them in a corpus section's `images` and they land in the Word, PowerPoint and Markdown outputs. The agent standard now shows how to generate images and embeddings through the gateway. `NEEDS_RECONNECT` on the shared test account tells you to ask Gravity, not to connect your own account.
|
|
758
797
|
- **0.5.2** Jira, Confluence and Notion join the catalog: 1,351 tools across 11 apps. `get_store()` works in local runs, kept in `.gravity/store.json`. Renewing an expired sign-in keeps your gateway token, so `gravity run` keeps working after an hour. Commands start faster: the catalog loads in a quarter of the time.
|
|
759
798
|
- **0.5.0** `gravity connect` links your own accounts. `web.search` and `web.fetch` join the catalog. `gravity validate` now refuses a tool that isn't in the catalog, an imported write tool without an approval, and code that names a write tool the manifest doesn't grant. `gravity tools` reads the gateway's list and needs no sign-in. On Windows the session stays in the keychain instead of a file.
|
|
760
799
|
- **0.4.4** Same code as 0.4.3, released from this repository so the GitHub release, the tag and PyPI line up again. Adds `RELEASING.md`.
|
|
@@ -91,10 +91,10 @@ The same rules apply on your laptop and when the agent runs hosted, because both
|
|
|
91
91
|
|
|
92
92
|
| | |
|
|
93
93
|
|---|---|
|
|
94
|
-
| Commands |
|
|
94
|
+
| Commands | 18, grouped into build an agent, publish, your agents, account and help |
|
|
95
95
|
| Starter templates | 4: `minimal`, `structured`, `deepagent`, `chat` |
|
|
96
|
-
| Tool catalog | 1,
|
|
97
|
-
| Test suite |
|
|
96
|
+
| Tool catalog | 1,402 tools across 15 apps (Gmail, Slack, Linear, GitHub, Calendar, Drive, Sheets, LinkedIn, Jira, Confluence, Notion, WhatsApp, web search, and two built-ins), 28 of them curated |
|
|
97
|
+
| Test suite | 466 tests (214 CLI, 252 schema), run on Ubuntu and Windows with Python 3.12 and 3.13 |
|
|
98
98
|
| Runtime contract | 3 environment variables, no Gravity import in your code |
|
|
99
99
|
|
|
100
100
|
## Five things to know before you start
|
|
@@ -179,6 +179,7 @@ Run `gravity help` for this list in the terminal, and add `-h` to any command fo
|
|
|
179
179
|
| **Build an agent** | [`gravity init`](#gravity-init) | Create a new agent from a template |
|
|
180
180
|
| | [`gravity validate`](#gravity-validate) | Check your agent for mistakes before it runs |
|
|
181
181
|
| | [`gravity run`](#gravity-run) | Run your agent locally against real tools |
|
|
182
|
+
| | [`gravity dev`](#gravity-dev) | Open a local dashboard to run and watch your agent |
|
|
182
183
|
| | [`gravity schedule`](#gravity-schedule) | Run your agent on its schedule, locally |
|
|
183
184
|
| | [`gravity adapt`](#gravity-adapt) | Write a new slot adapter with AI, kept only if its tests pass |
|
|
184
185
|
| **Publish** | [`gravity build`](#gravity-build) | Package your agent into `build/agent.zip` |
|
|
@@ -194,7 +195,7 @@ Run `gravity help` for this list in the terminal, and add `-h` to any command fo
|
|
|
194
195
|
| **Help** | [`gravity guide`](#gravity-guide) | Read the builder guide: how to build a good agent |
|
|
195
196
|
| | [`gravity help`](#gravity-help) | Show the list of commands |
|
|
196
197
|
|
|
197
|
-
`gravity --api-url URL <command>` saves a different control-plane address to `~/.gravity/config.json
|
|
198
|
+
`gravity --api-url URL <command>` saves a different control-plane address to `~/.gravity/config.json`; it must start with `http://` or `https://`. The flag applies to the command it is given with; on later commands a `GRAVITY_API_URL` in `~/.gravity/.env` or the shell still wins over `config.json`, and the CLI says so when that is the case. `gravity --version` (or `-V`) prints the installed version. Wherever a command takes `[path]`, it is the agent's folder and defaults to the current one.
|
|
198
199
|
|
|
199
200
|
### `gravity init`
|
|
200
201
|
|
|
@@ -243,6 +244,9 @@ What it checks:
|
|
|
243
244
|
- every imported write tool is under `approvals.required_for`
|
|
244
245
|
- your code never names a write tool the manifest does not grant
|
|
245
246
|
- a warning, never a failure, for read tools your code names but the manifest does not declare
|
|
247
|
+
- `graph` is an `async def` (or a compiled graph), not a plain `def` or a bare value; a name bound by an import counts
|
|
248
|
+
- nothing under `src/` reads `os.environ` or calls `asyncio.run` at module level, and no import is relative
|
|
249
|
+
- a schedule runs at most every 5 minutes and restricts the day of the month or the weekday, not both
|
|
246
250
|
|
|
247
251
|
```bash
|
|
248
252
|
gravity validate
|
|
@@ -274,10 +278,33 @@ gravity run --reply "make it shorter"
|
|
|
274
278
|
- Requires a gateway token: the one `gravity login` stores, or `GRAVITY_DEV_TOKEN`.
|
|
275
279
|
- A call to a tool in `approvals.required_for` pauses, shows what it would do, and waits for `y` or `n`. With no terminal to ask in, it is rejected.
|
|
276
280
|
- Exits with code 0 when the run finishes and 1 when it fails.
|
|
281
|
+
- Leaves a record in `.gravity/runs/<id>/` (`run.json` and `events.jsonl`), which is what `gravity dev` reads. One run is live per folder at a time, because runs share the folder's memory, store and thread files.
|
|
282
|
+
|
|
283
|
+
### `gravity dev`
|
|
284
|
+
|
|
285
|
+
Open a local dashboard for the agent in this folder: a form built from the manifest's inputs, a live timeline of each step, model call and tool call, approval buttons for held calls, the result, and a history of runs.
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
gravity dev [path] [--port 4747] [--no-open] [--llm-url URL]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
| Option | Description |
|
|
292
|
+
|---|---|
|
|
293
|
+
| `--port N` | Port to listen on (default 4747). If it is taken, a free one is used and printed. |
|
|
294
|
+
| `--no-open` | Print the address without opening a browser (SSH, WSL, CI) |
|
|
295
|
+
| `--llm-url URL` | Model endpoint to use instead of `GRAVITY_LLM_URL` |
|
|
296
|
+
|
|
297
|
+
- A run from `gravity run` in the same folder shows up in the dashboard live, and a run started in the dashboard is the same run (same engine, same memory, store and thread files), so `gravity run --reply` continues it.
|
|
298
|
+
- It listens on `127.0.0.1` only, behind a random token in the printed address, for as long as the command runs. Ctrl+C stops it and any run it started. Nothing keeps running in the background.
|
|
299
|
+
- Connected accounts: it shows the accounts your tools need and a Connect button for each one that is missing.
|
|
300
|
+
- Approvals: a call held for approval can be decided in the terminal or in the dashboard; whichever answers first wins.
|
|
301
|
+
- Cancel a run from the dashboard only if the dashboard started it; stop a terminal run with Ctrl+C in that terminal.
|
|
302
|
+
- Results show as text. Word, PowerPoint and CSV files are produced by Gravity after you push. A file input is read as text here.
|
|
303
|
+
- Same requirements as `gravity run`: a gateway token from `gravity login`, or `GRAVITY_DEV_TOKEN`.
|
|
277
304
|
|
|
278
305
|
### `gravity schedule`
|
|
279
306
|
|
|
280
|
-
Run the agent on its `triggers.schedule`, the way the platform will, until you press Ctrl+C. Each tick is an ordinary run with the same inputs.
|
|
307
|
+
Run the agent on its `triggers.schedule`, the way the platform will, until you press Ctrl+C. Ticks are timed in Asia/Kolkata, as the hosted schedules are. Each tick is an ordinary run with the same inputs; a missing required input is refused before the first tick.
|
|
281
308
|
|
|
282
309
|
```
|
|
283
310
|
gravity schedule [path] [--input KEY=VALUE]... [--cron EXPR] [--now]
|
|
@@ -317,7 +344,7 @@ gravity adapt <slot> <name> --tools TOOLS [--hint TEXT] [--model MODEL] [--path
|
|
|
317
344
|
gravity adapt deliver slack --tools slack.send,slack.list_channels --hint "post to #leads"
|
|
318
345
|
```
|
|
319
346
|
|
|
320
|
-
Requires `tests/test_<slot>_adapters.py` in the project
|
|
347
|
+
Requires `tests/test_<slot>_adapters.py` in the project and a gateway token (`gravity login`, or `GRAVITY_DEV_TOKEN`). It makes up to 3 attempts, feeding each test failure back to the model.
|
|
321
348
|
|
|
322
349
|
### `gravity build`
|
|
323
350
|
|
|
@@ -327,7 +354,7 @@ Validate the agent, then bundle it into `build/agent.zip` with its hashes in `bu
|
|
|
327
354
|
gravity build [path]
|
|
328
355
|
```
|
|
329
356
|
|
|
330
|
-
The bundle holds `manifest.yaml`, `requirements.txt`, `requirements.lock`, `src/` and `tests
|
|
357
|
+
The bundle holds `manifest.yaml`, `requirements.txt`, `requirements.lock`, `src/`, `tests/` and `tools_needed.yaml` when present; dotfiles under `src/` and `tests/` are left out. It refuses to build without `requirements.lock` (run `gravity validate` first). The same source always produces the same bytes.
|
|
331
358
|
|
|
332
359
|
```bash
|
|
333
360
|
gravity build
|
|
@@ -345,6 +372,9 @@ gravity push [path]
|
|
|
345
372
|
- Refuses if there is no build, or if the source changed since the build. Run `gravity build` again.
|
|
346
373
|
- A published version can never be replaced. Raise `version` in the manifest to publish again.
|
|
347
374
|
- Press Ctrl+C to stop waiting; the build carries on, and `gravity agents` shows its status.
|
|
375
|
+
- The bundle may be at most 30 MB; a larger `agent.zip` is refused before upload. Remove large files from `src/` or `tests/` and build again.
|
|
376
|
+
- The manifest travels in a request header, so `manifest.yaml` must stay under 12 KB once encoded; a larger one is refused before upload. Keep descriptions and help text short.
|
|
377
|
+
- Re-pushing a version whose build failed, without changing the source, is refused with the failure reason: fix it and raise `version` in the manifest.
|
|
348
378
|
|
|
349
379
|
```bash
|
|
350
380
|
gravity build && gravity push
|
|
@@ -352,7 +382,7 @@ gravity build && gravity push
|
|
|
352
382
|
|
|
353
383
|
### `gravity agents`
|
|
354
384
|
|
|
355
|
-
List your published agents with their version, status and last update.
|
|
385
|
+
List your published agents with their version, status, review and last update. Under the table it prints what the Gravity team told you: the reviewer's notes on an approved or rejected version, and the reason if an agent was turned off. A rejected version needs a fix and a new `version:` in `manifest.yaml` before you push again. A failed build prints its reason under the table.
|
|
356
386
|
|
|
357
387
|
```
|
|
358
388
|
gravity agents
|
|
@@ -411,7 +441,7 @@ gravity logout
|
|
|
411
441
|
|
|
412
442
|
### `gravity whoami`
|
|
413
443
|
|
|
414
|
-
Show the account you are signed in as, and whether you hold a gateway token and until when.
|
|
444
|
+
Show the account you are signed in as, and whether you hold a gateway token and until when (an expired one is a warning).
|
|
415
445
|
|
|
416
446
|
```
|
|
417
447
|
gravity whoami
|
|
@@ -611,7 +641,7 @@ resources:
|
|
|
611
641
|
triggers:
|
|
612
642
|
manual: true # the consumer can start a run
|
|
613
643
|
schedule:
|
|
614
|
-
cron: "0 8 * * 1-5" # weekdays at 08:00,
|
|
644
|
+
cron: "0 8 * * 1-5" # weekdays at 08:00, Asia/Kolkata
|
|
615
645
|
consumer_can_change: true
|
|
616
646
|
|
|
617
647
|
state:
|
|
@@ -655,7 +685,7 @@ outputs: # extra formats the platform renders and deliv
|
|
|
655
685
|
| `approvals.required_for` | no | none | Tools that pause until a person approves. Each must also be declared under `permissions.tools` or a slot adapter. |
|
|
656
686
|
| `resources.memory_mb` | no | `512` | 128 to 4096. A request; the platform may lower it. |
|
|
657
687
|
| `triggers.manual` | no | `true` | Whether the consumer can start a run. Something must start the agent: `manual`, a `schedule` or a `webhook`. |
|
|
658
|
-
| `triggers.schedule` | no | none | `cron` (5 fields,
|
|
688
|
+
| `triggers.schedule` | no | none | `cron` (5 fields, Asia/Kolkata, such as `"0 9 * * 1"`; every 5 minutes at the fastest; day of month or weekday, not both) and `consumer_can_change` (default `true`). |
|
|
659
689
|
| `triggers.webhook` | no | none | A list of events; `github.push` is the only one today. |
|
|
660
690
|
| `state.max_kb` | no | no memory | Include `state:` to keep memory between runs, in `state["memory"]`. 1 to 256 KB. |
|
|
661
691
|
| `slots.<name>` | no | none | A swappable part: `label`, `default` adapter, and `adapters` mapping each adapter name to the tools it may call. Code lives in `src/adapters/<slot>/<adapter>.py`. Slot names cannot repeat an input's name. |
|
|
@@ -683,6 +713,8 @@ Files the CLI writes:
|
|
|
683
713
|
| `.gravity/payload.json` | `run` | The inputs passed to the agent |
|
|
684
714
|
| `.gravity/thread.json` | `run` | The last conversation of a chat agent, for `--reply` |
|
|
685
715
|
| `.gravity/memory.json` | `run` | Memory kept between runs, when the manifest declares `state` |
|
|
716
|
+
| `.gravity/payload.json` | `run`, `dev` | The run's inputs for the runner; deleted when the run ends (`run.json` keeps them with secret inputs redacted) |
|
|
717
|
+
| `.gravity/tool_schemas.json` | `adapt` | Argument schemas of every tool the slot uses, read from the gateway |
|
|
686
718
|
|
|
687
719
|
The template `.gitignore` excludes `build/`, `.gravity/` and `.env`.
|
|
688
720
|
|
|
@@ -730,7 +762,12 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
|
|
|
730
762
|
| `Can't reach the gateway at …` | No gateway at that address. Set `GRAVITY_GATEWAY_URL` to your gateway's `/mcp` address. |
|
|
731
763
|
| `The gateway refused this run` | The gateway rejected the token or a declared tool. Run `gravity whoami` to check the token, or `gravity login` for a fresh one. |
|
|
732
764
|
| `You are not signed in` | A control-plane command without credentials. Run `gravity login`. |
|
|
733
|
-
| `Can't reach Gravity at …` | The control plane did not answer. Check `GRAVITY_API_URL` in `~/.gravity/.env
|
|
765
|
+
| `Can't reach Gravity at …` | The control plane did not answer. Check `GRAVITY_API_URL` in `~/.gravity/.env`, or `api_url` in `~/.gravity/config.json` (set by `gravity --api-url`). |
|
|
766
|
+
| `Gravity refused GRAVITY_API_TOKEN` | The dev token in `~/.gravity/.env` is wrong or revoked. Fix it there, or remove it and run `gravity login`. |
|
|
767
|
+
| `… did not answer with JSON` or `Gravity answered 5xx at …` | A proxy, VPN sign-in page or outage is answering instead of Gravity. Check `GRAVITY_API_URL`; for a 5xx wait a minute and retry, then tell Gravity if it persists. |
|
|
768
|
+
| `Another run is live` | Runs in one folder take turns. Wait for it, or stop it; if none is live, delete `.gravity/run.lock`. |
|
|
769
|
+
| `Manifest is not UTF-8 text` | Notepad saved it as "Unicode" (UTF-16). Re-save it with Encoding: UTF-8. |
|
|
770
|
+
| `could not load the agent: No module named …` only on Windows | Windows limits paths to 260 characters and some packages in `.venv` exceed it from a deep folder. Move the agent to a shorter path or enable long paths. |
|
|
734
771
|
| `Missing required input: …` | Pass each required input with `--input name=value`, or give it a `default` in the manifest. |
|
|
735
772
|
| `No build to push` or `The build is stale` | Run `gravity build` again after any change to `src/`, the manifest or the requirements. |
|
|
736
773
|
| `✗ requirements.lock` in `gravity validate` | A dependency has no prebuilt package for the platform image (ARM64 Linux). Pick a version that publishes one, or a different package. |
|
|
@@ -738,6 +775,8 @@ Real tools act on a connected account. Connect one with `gravity-gateway connect
|
|
|
738
775
|
|
|
739
776
|
## What's new
|
|
740
777
|
|
|
778
|
+
- **0.5.4** `gravity agents` shows each agent's review: a REVIEW column (not submitted, submitted, approved, rejected), and under "From the Gravity team" the reviewer's notes and what to do next. An agent the Gravity team turned off shows as `off` with the reason. UPDATED reads "3 min ago" instead of a timestamp, and status and review are coloured. Also, from a full audit of every command: `gravity --version`. Clear messages instead of tracebacks for: a proxy or sign-in page answering instead of Gravity, a refused `GRAVITY_API_TOKEN` or `GRAVITY_DEV_TOKEN`, an expired sign-in code, a non-UTF-8 manifest, an out-of-range `--port`, a missing agent folder, a malformed session file. `gravity validate` now refuses what the build would refuse: a `graph` that is not an async factory, `os.environ` or `asyncio.run` at import, relative imports, unquoted `python: 3.12`, schedules faster than every 5 minutes or with both day fields, out-of-range cron fields; it accepts a re-exported `graph`. `gravity agents` shows the review status and failure reasons; `gravity runs` never shortens an id; `gravity logs` never wraps. `gravity push` refuses a bundle over 30 MB or a manifest over 12 KB before uploading, and says why when a failed version is re-pushed. `gravity build` ships `tools_needed.yaml`, leaves dotfiles out, and refuses to build without `requirements.lock`. `gravity adapt` leaves the folder untouched when a model call fails. `gravity schedule` checks inputs before the first tick and runs on Asia/Kolkata like the hosted schedules. `gravity run` deletes `.gravity/payload.json` after the run, warns when no `.venv` is present, and keeps a plain agent's `result`. `gravity connect <app>` refuses on the shared test account instead of attaching your account to it. The builder guide and agent standard describe the real flow (init, validate, run or dev, build, push, review on /app).
|
|
779
|
+
- **0.5.3** `gravity dev` opens a local dashboard for your agent: a form from your manifest, a live timeline, approvals, the result and run history; runs from `gravity run` in the same folder show up in it live, and the other way round. WhatsApp joins the catalog (51 tools; 1,402 across 15 apps including the curated and built-in ones). Agents can return generated images: put them in a corpus section's `images` and they land in the Word, PowerPoint and Markdown outputs. The agent standard now shows how to generate images and embeddings through the gateway. `NEEDS_RECONNECT` on the shared test account tells you to ask Gravity, not to connect your own account.
|
|
741
780
|
- **0.5.2** Jira, Confluence and Notion join the catalog: 1,351 tools across 11 apps. `get_store()` works in local runs, kept in `.gravity/store.json`. Renewing an expired sign-in keeps your gateway token, so `gravity run` keeps working after an hour. Commands start faster: the catalog loads in a quarter of the time.
|
|
742
781
|
- **0.5.0** `gravity connect` links your own accounts. `web.search` and `web.fetch` join the catalog. `gravity validate` now refuses a tool that isn't in the catalog, an imported write tool without an approval, and code that names a write tool the manifest doesn't grant. `gravity tools` reads the gateway's list and needs no sign-in. On Windows the session stays in the keychain instead of a file.
|
|
743
782
|
- **0.4.4** Same code as 0.4.3, released from this repository so the GitHub release, the tag and PyPI line up again. Adds `RELEASING.md`.
|