gravity-cli 0.9.0__tar.gz → 0.11.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.
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/AGENT_STANDARD.md +1 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/AGENT_STANDARD_V2.md +1 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/PKG-INFO +4 -4
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/README.md +2 -2
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/catalog.yaml +45 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/contract.py +2 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/manifest.py +15 -3
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/manifest_v2.py +2 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/rules.py +50 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/rules_cases.json +36 -2
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/specs.py +67 -9
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/pyproject.toml +1 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/schema/manifest.schema.json +76 -3
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_manifest.py +8 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_rules.py +50 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/pyproject.toml +2 -2
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/BUILDER_GUIDE.md +4 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/BUILDER_GUIDE_V2.md +1 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/CHANGELOG.md +17 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/_runner_script.py +26 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/run.py +2 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/dev_page/index.html +9 -3
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/docs/Gravity.agent.md +49 -9
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/inputs.py +15 -4
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/timeline.py +17 -1
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_inputs_memory.py +28 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_templates.py +27 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_timeline.py +17 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/uv.lock +2 -2
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/.env.example +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/.github/workflows/ci.yml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/.github/workflows/composio-watch.yml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/.github/workflows/release.yml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/LICENSE +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/NOTICE +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/RELEASING.md +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/TEMPLATES.md +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/LICENSE +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/NOTICE +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/README.md +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/__main__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/built_ins.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/catalog.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/catalog_imported.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/cron.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/describe.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/errors.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/export.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/gen_catalog.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/gen_vocabulary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/instance.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/source_scan.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/validation.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/__main__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/capabilities.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/airtable.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/asana.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/browser_tool.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/composio_search.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/dropbox.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/exa.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/excel.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/firecrawl.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/github.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/gmail.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googlecalendar.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googledocs.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googledrive.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googlesheets.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googleslides.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/googletasks.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/hackernews.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/hubspot.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/instagram.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/jira.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/linear.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/linkedin.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/microsoft_teams.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/notion.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/outlook.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/perplexityai.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/pinterest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/reddit.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/slack.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/tavily.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/connectors/youtube.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/core_shapes.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/generated_shapes.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/policy.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/airtable.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/asana.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/browser_tool.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/composio_search.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/dropbox.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/exa.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/excel.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/firecrawl.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/github.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/gmail.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googlecalendar.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googledocs.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googledrive.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googlesheets.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googleslides.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/googletasks.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/hackernews.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/hubspot.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/instagram.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/jira.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/linear.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/linkedin.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/microsoft_teams.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/notion.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/outlook.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/perplexityai.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/pinterest.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/reddit.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/slack.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/tavily.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas/youtube.json +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/schemas.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ochat.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ocrm.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/ogh.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/oms.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/oweb.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/owork.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/shapes.d/shared.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/sync.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ochat.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ocrm.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/ogh.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/oms.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/oweb.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/owork.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rchat.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rfiles.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rgh.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rtrack.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.d/rwork.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/vocabulary/verbs.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/conftest.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/fixtures/demo_manifests.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_accounts.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_actions_memory.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_catalog_parity.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_cron.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_describe.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_errors.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_generated_tables.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_instance.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_json_schema.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_kind_outputs.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_manifest_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_place_maker.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_slots.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_source_scan.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_sync.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_validation.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/tests/test_vocabulary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/scripts/composio-watch.sh +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/__main__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/api.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/changelog.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/cli.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/adapt.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/build.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/capabilities.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/changelog.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/check.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/connect.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/dev.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/docs.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/guide.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/help.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/init.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/login.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/memory.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/push.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/runs.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/schedule.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/tools.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/update.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/commands/validate.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/config.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/dev.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/docs/Gravity.getting-started.md +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/docs/problem-to-agent.md +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/localrun.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/manifest.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/project.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/chat/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/chat/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/chat/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/chat/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/deepagent/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/deepagent/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/deepagent/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/deepagent/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/minimal/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/minimal/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/minimal/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/minimal/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/src/gateway.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/src/nodes/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/src/prompts.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/structured/src/state.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/chat/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/chat/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/chat/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/chat/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/chat/tests/test_agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/deepagent/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/deepagent/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/deepagent/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/deepagent/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/deepagent/tests/test_agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/minimal/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/minimal/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/minimal/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/minimal/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/minimal/tests/test_agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/.gitignore +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/gateway.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/nodes/__init__.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/nodes/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/prompts.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/src/state.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/templates/v2/structured/tests/test_agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/ui.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/updater.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/src/gravity_cli/workspace.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter/src/summary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter/tests/test_summary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter-v2/manifest.yaml +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter-v2/requirements.txt +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter-v2/src/agent.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter-v2/src/summary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/starter-v2/tests/test_summary.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/conftest.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_adapt.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_agent_guide.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_agents.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_api.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_build_push.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_changelog.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_check.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_connect.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_connect_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_dev.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_dev_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_gateway_token.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_localrun.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_manifest_integration.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_run.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_run_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_runs.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_schedule.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_schedule_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_session.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_templates_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_tools.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_ui.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_updater.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_v2_cli.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_validate.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_validate_v2.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_welcome.py +0 -0
- {gravity_cli-0.9.0 → gravity_cli-0.11.0}/tests/test_workspace.py +0 -0
|
@@ -348,7 +348,7 @@ to one address, with the output's content in the message body and no
|
|
|
348
348
|
attachment; a thread sends at most 200 a day. The platform sends it, not the
|
|
349
349
|
agent, so the agent needs no Gmail tool and no approval for it.
|
|
350
350
|
|
|
351
|
-
Renderers: `markdown`, `docx`, `pptx`, `rows` (the first table, as CSV). Each
|
|
351
|
+
Renderers: `markdown`, `docx`, `pptx`, `pdf`, `rows` (the first table, as CSV), `xlsx` (every table, a sheet each). Each
|
|
352
352
|
consumer picks outputs and destinations per run. The agent writes one
|
|
353
353
|
**corpus** into its final state, and every output is rendered from it:
|
|
354
354
|
|
|
@@ -384,7 +384,7 @@ record tagged with its app in `extra.app`. The platform delivers it after the
|
|
|
384
384
|
run, not the agent, so the agent declares no write for it; an email goes at
|
|
385
385
|
most once per run and a thread sends at most 200 a day, extra places included.
|
|
386
386
|
|
|
387
|
-
Renderers: `markdown`, `docx`, `pptx`, `rows` (the first table, as CSV). Each
|
|
387
|
+
Renderers: `markdown`, `docx`, `pptx`, `pdf`, `rows` (the first table, as CSV), `xlsx` (every table, a sheet each). Each
|
|
388
388
|
consumer picks outputs and destinations per run. The agent writes one
|
|
389
389
|
**corpus** into its final state, and every output is rendered from it:
|
|
390
390
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: gravity-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
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.
|
|
9
|
+
Requires-Dist: gravity-schema==0.11.0
|
|
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
|
|
@@ -720,7 +720,7 @@ slots: # a part the consumer chooses; each adapter ge
|
|
|
720
720
|
|
|
721
721
|
outputs: # extra formats the platform renders and delivers itself
|
|
722
722
|
report:
|
|
723
|
-
renderer: markdown # markdown | docx | pptx | rows
|
|
723
|
+
renderer: markdown # markdown | docx | pptx | pdf | rows | xlsx
|
|
724
724
|
label: "Digest as a document"
|
|
725
725
|
destinations: [download]
|
|
726
726
|
```
|
|
@@ -752,7 +752,7 @@ outputs: # extra formats the platform renders and deliv
|
|
|
752
752
|
| `triggers.webhook` | no | none | A list of events; `github.push` is the only one today. |
|
|
753
753
|
| `state.max_kb` | no | no memory | Include `state:` to keep memory between runs, in `state["memory"]`. 1 to 256 KB. |
|
|
754
754
|
| `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. |
|
|
755
|
-
| `outputs.<name>` | no | none | Up to 8 extra formats rendered from the result: `renderer` (`markdown`, `docx`, `pptx` or `
|
|
755
|
+
| `outputs.<name>` | no | none | Up to 8 extra formats rendered from the result: `renderer` (`markdown`, `docx`, `pptx`, `pdf`, `rows` or `xlsx`), `label` and `destinations` (`download`, or a catalog tool such as `gmail.send`). |
|
|
756
756
|
|
|
757
757
|
Unknown fields are rejected rather than ignored, so a typo is reported instead of silently dropped.
|
|
758
758
|
|
|
@@ -703,7 +703,7 @@ slots: # a part the consumer chooses; each adapter ge
|
|
|
703
703
|
|
|
704
704
|
outputs: # extra formats the platform renders and delivers itself
|
|
705
705
|
report:
|
|
706
|
-
renderer: markdown # markdown | docx | pptx | rows
|
|
706
|
+
renderer: markdown # markdown | docx | pptx | pdf | rows | xlsx
|
|
707
707
|
label: "Digest as a document"
|
|
708
708
|
destinations: [download]
|
|
709
709
|
```
|
|
@@ -735,7 +735,7 @@ outputs: # extra formats the platform renders and deliv
|
|
|
735
735
|
| `triggers.webhook` | no | none | A list of events; `github.push` is the only one today. |
|
|
736
736
|
| `state.max_kb` | no | no memory | Include `state:` to keep memory between runs, in `state["memory"]`. 1 to 256 KB. |
|
|
737
737
|
| `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. |
|
|
738
|
-
| `outputs.<name>` | no | none | Up to 8 extra formats rendered from the result: `renderer` (`markdown`, `docx`, `pptx` or `
|
|
738
|
+
| `outputs.<name>` | no | none | Up to 8 extra formats rendered from the result: `renderer` (`markdown`, `docx`, `pptx`, `pdf`, `rows` or `xlsx`), `label` and `destinations` (`download`, or a catalog tool such as `gmail.send`). |
|
|
739
739
|
|
|
740
740
|
Unknown fields are rejected rather than ignored, so a typo is reported instead of silently dropped.
|
|
741
741
|
|
{gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/catalog.yaml
RENAMED
|
@@ -74,6 +74,15 @@
|
|
|
74
74
|
guarantee: certified
|
|
75
75
|
side_effect: read
|
|
76
76
|
|
|
77
|
+
- name: treg.email_find
|
|
78
|
+
slug: null
|
|
79
|
+
toolkit: null
|
|
80
|
+
description: find and verify a person's work email from their LinkedIn URL, or a full name plus the company's email domain; served by the gateway through the team's lookup account (a fraction of a cent a call), capped per call and verified in the same call
|
|
81
|
+
scopes: []
|
|
82
|
+
breadth: generic
|
|
83
|
+
guarantee: certified
|
|
84
|
+
side_effect: read
|
|
85
|
+
|
|
77
86
|
- name: browser.act
|
|
78
87
|
slug: null
|
|
79
88
|
toolkit: null
|
|
@@ -155,6 +164,42 @@
|
|
|
155
164
|
guarantee: certified
|
|
156
165
|
side_effect: write
|
|
157
166
|
|
|
167
|
+
- name: sheets.create
|
|
168
|
+
slug: GOOGLESHEETS_CREATE_GOOGLE_SHEET1
|
|
169
|
+
toolkit: googlesheets
|
|
170
|
+
description: create a new Google Sheet in the connected Google account
|
|
171
|
+
scopes: [sheets]
|
|
172
|
+
breadth: generic
|
|
173
|
+
guarantee: certified
|
|
174
|
+
side_effect: write
|
|
175
|
+
|
|
176
|
+
- name: sheets.add_tab
|
|
177
|
+
slug: GOOGLESHEETS_ADD_SHEET
|
|
178
|
+
toolkit: googlesheets
|
|
179
|
+
description: add a tab to a Google Sheet in the connected Google account
|
|
180
|
+
scopes: [sheets]
|
|
181
|
+
breadth: generic
|
|
182
|
+
guarantee: certified
|
|
183
|
+
side_effect: write
|
|
184
|
+
|
|
185
|
+
- name: docs.read
|
|
186
|
+
slug: GOOGLEDOCS_GET_DOCUMENT_PLAINTEXT
|
|
187
|
+
toolkit: googledocs
|
|
188
|
+
description: read a Google Doc in the connected Google account as plain text (document_id, from a google-doc input)
|
|
189
|
+
scopes: [docs]
|
|
190
|
+
breadth: generic
|
|
191
|
+
guarantee: certified
|
|
192
|
+
side_effect: read
|
|
193
|
+
|
|
194
|
+
- name: docs.create
|
|
195
|
+
slug: GOOGLEDOCS_CREATE_DOCUMENT_MARKDOWN
|
|
196
|
+
toolkit: googledocs
|
|
197
|
+
description: create a Google Doc from markdown in the connected Google account
|
|
198
|
+
scopes: [docs]
|
|
199
|
+
breadth: generic
|
|
200
|
+
guarantee: certified
|
|
201
|
+
side_effect: write
|
|
202
|
+
|
|
158
203
|
- name: slack.send
|
|
159
204
|
slug: SLACK_SEND_MESSAGE
|
|
160
205
|
toolkit: slack
|
|
@@ -106,6 +106,8 @@ MAX_INPUTS: Final[int] = 50
|
|
|
106
106
|
MAX_TOOLS: Final[int] = 50
|
|
107
107
|
MAX_OPTIONS: Final[int] = 100
|
|
108
108
|
MAX_FILE_EXTENSIONS: Final[int] = 20
|
|
109
|
+
# A file input with `max` (several files): the most it may ask for. Each upload is up to 25 MB.
|
|
110
|
+
MAX_FILES: Final[int] = 20
|
|
109
111
|
MAX_NAME_LENGTH: Final[int] = 64
|
|
110
112
|
MAX_ENTRYPOINT_LENGTH: Final[int] = 256
|
|
111
113
|
MAX_LABEL_LENGTH: Final[int] = 200
|
|
@@ -319,11 +319,23 @@ class Manifest(BaseModel):
|
|
|
319
319
|
|
|
320
320
|
@model_validator(mode="after")
|
|
321
321
|
def _check_monitor_has_a_trigger(self) -> Manifest:
|
|
322
|
-
if self.kind is AgentKind.MONITOR and self.triggers.schedule is None and not self.triggers.webhook
|
|
322
|
+
if (self.kind is AgentKind.MONITOR and self.triggers.schedule is None and not self.triggers.webhook
|
|
323
|
+
and self.triggers.email is None):
|
|
323
324
|
raise PydanticCustomError(
|
|
324
325
|
ErrorCode.INVALID_KIND.value,
|
|
325
|
-
"A monitor needs a schedule or a webhook trigger.",
|
|
326
|
-
{"remediation": "Add triggers.schedule or triggers.webhook, or use kind: interactive."},
|
|
326
|
+
"A monitor needs a schedule, an email or a webhook trigger.",
|
|
327
|
+
{"remediation": "Add triggers.schedule, triggers.email or triggers.webhook, or use kind: interactive."},
|
|
328
|
+
)
|
|
329
|
+
return self
|
|
330
|
+
|
|
331
|
+
@model_validator(mode="after")
|
|
332
|
+
def _check_email_trigger_reads_gmail(self) -> Manifest:
|
|
333
|
+
# Gravity reads the new mail with the person's Gmail, under the agent's own permission.
|
|
334
|
+
if self.triggers.email is not None and "gmail.read" not in self.permissions.tools:
|
|
335
|
+
raise PydanticCustomError(
|
|
336
|
+
ErrorCode.INVALID_TRIGGER.value,
|
|
337
|
+
"triggers.email watches Gmail, but the agent does not declare gmail.read.",
|
|
338
|
+
{"remediation": "Add gmail.read to permissions.tools."},
|
|
327
339
|
)
|
|
328
340
|
return self
|
|
329
341
|
|
{gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/manifest_v2.py
RENAMED
|
@@ -53,7 +53,9 @@ RENDERER_DESTINATIONS: dict[Renderer, tuple[str, ...]] = {
|
|
|
53
53
|
"post.create", "file.create"),
|
|
54
54
|
Renderer.DOCX: ("file.create", "document.create", "message.send"),
|
|
55
55
|
Renderer.PPTX: ("file.create", "presentation.create", "message.send"),
|
|
56
|
+
Renderer.PDF: ("file.create", "message.send"),
|
|
56
57
|
Renderer.ROWS: ("row.append", "file.create"),
|
|
58
|
+
Renderer.XLSX: ("file.create",),
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
# A filter on one of these fields takes one of the shape's listed values.
|
|
@@ -14,6 +14,8 @@ would get them: a condition on an input nobody answered and nothing defaulted do
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
import datetime as dt
|
|
18
|
+
import re
|
|
17
19
|
from typing import Any
|
|
18
20
|
|
|
19
21
|
from .specs import ActionSpec, InputSpec, InputType
|
|
@@ -115,8 +117,52 @@ def apply_rules(manifest: Manifest, answers: dict[str, Any]) -> dict[str, Any]:
|
|
|
115
117
|
Problem = tuple[str, str] # (the input or choose_one label it is about, what to tell the person)
|
|
116
118
|
|
|
117
119
|
|
|
120
|
+
DAY = re.compile(r"^\d{4}-\d{2}-\d{2}$")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _is_day(value: Any) -> bool:
|
|
124
|
+
if not isinstance(value, str) or not DAY.match(value):
|
|
125
|
+
return False
|
|
126
|
+
try:
|
|
127
|
+
dt.date.fromisoformat(value)
|
|
128
|
+
except ValueError:
|
|
129
|
+
return False
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# The file id in a Google Doc or Sheet link, or a bare id (Google's are 25 or more of these characters).
|
|
134
|
+
_GOOGLE_PATH = {"google-doc": "document", "google-sheet": "spreadsheets"}
|
|
135
|
+
_GOOGLE_ID = re.compile(r"^[A-Za-z0-9_-]{25,}$")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def google_file_id(kind: str, value: Any) -> str | None:
|
|
139
|
+
"""'https://docs.google.com/spreadsheets/d/<id>/edit#gid=0' -> '<id>' for a google-sheet input (document for a
|
|
140
|
+
google-doc one); a bare id as it is; None for anything else, a Sheet's link in a Doc input included."""
|
|
141
|
+
text = value.strip() if isinstance(value, str) else ""
|
|
142
|
+
if _GOOGLE_ID.match(text):
|
|
143
|
+
return text
|
|
144
|
+
m = re.search(rf"docs\.google\.com/{_GOOGLE_PATH.get(kind, '-')}/d/([A-Za-z0-9_-]{{20,}})", text)
|
|
145
|
+
return m.group(1) if m else None
|
|
146
|
+
|
|
147
|
+
|
|
118
148
|
def _bounds(spec: InputSpec, value: Any) -> str | None:
|
|
119
149
|
label = spec.label or spec.name
|
|
150
|
+
if spec.many_days and not _blank(value):
|
|
151
|
+
if not isinstance(value, list) or not all(_is_day(v) for v in value):
|
|
152
|
+
return f'"{label}": pick days on the calendar.'
|
|
153
|
+
if spec.min is not None and len(value) < spec.min:
|
|
154
|
+
return f'"{label}": pick at least {spec.min} days.'
|
|
155
|
+
if spec.max is not None and len(value) > spec.max:
|
|
156
|
+
return f'"{label}": pick at most {spec.max} days.'
|
|
157
|
+
return None
|
|
158
|
+
if spec.many_files and not _blank(value):
|
|
159
|
+
if not isinstance(value, list) or not all(isinstance(v, str) and v.strip() for v in value):
|
|
160
|
+
return f'"{label}": upload the files again.'
|
|
161
|
+
if spec.min is not None and len(value) < spec.min:
|
|
162
|
+
return f'"{label}": upload at least {spec.min} files.'
|
|
163
|
+
if spec.max is not None and len(value) > spec.max:
|
|
164
|
+
return f'"{label}": upload at most {spec.max} files.'
|
|
165
|
+
return None
|
|
120
166
|
if spec.type is InputType.MULTI_SELECT and not _blank(value):
|
|
121
167
|
if not isinstance(value, list) or any(v not in (spec.options or []) for v in value):
|
|
122
168
|
return f'"{label}": pick from {", ".join(spec.options or [])}.'
|
|
@@ -141,6 +187,10 @@ def _check(inputs: list[InputSpec], shown: list[str], answers: dict[str, Any]) -
|
|
|
141
187
|
out.append((spec.name, f'"{spec.label or spec.name}" is required.'))
|
|
142
188
|
elif spec.type is InputType.MULTI_SELECT and spec.min and _blank(value):
|
|
143
189
|
out.append((spec.name, f'"{spec.label or spec.name}": pick at least {spec.min}.'))
|
|
190
|
+
elif spec.many_days and spec.min and _blank(value):
|
|
191
|
+
out.append((spec.name, f'"{spec.label or spec.name}": pick at least {spec.min} days.'))
|
|
192
|
+
elif spec.many_files and spec.min and _blank(value):
|
|
193
|
+
out.append((spec.name, f'"{spec.label or spec.name}": upload at least {spec.min} files.'))
|
|
144
194
|
elif (problem := _bounds(spec, value)) is not None:
|
|
145
195
|
out.append((spec.name, problem))
|
|
146
196
|
return out
|
{gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/gravity_schema/rules_cases.json
RENAMED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
{"name": "brand_kit", "type": "text", "label": "Brand kit link", "show_if": {"platforms": ["instagram", "youtube"]}},
|
|
12
12
|
{"name": "contact_source", "type": "static-dropdown", "label": "Contacts from", "options": ["gravity", "hunter", "both"], "default": "gravity"},
|
|
13
13
|
{"name": "hunter_key", "type": "secret", "label": "Your Hunter API key", "required": true, "show_if": {"contact_source": ["hunter", "both"]}},
|
|
14
|
-
{"name": "goal", "type": "action-choice", "label": "What do you want to do first?", "actions": ["find_companies", "write_emails"]}
|
|
14
|
+
{"name": "goal", "type": "action-choice", "label": "What do you want to do first?", "actions": ["find_companies", "write_emails"]},
|
|
15
|
+
{"name": "call_days", "type": "date", "label": "Days for a call", "min": 1, "max": 3, "show_if": {"goal": "write_emails"}},
|
|
16
|
+
{"name": "past_pitches", "type": "file", "label": "Past pitch decks", "accept": ["pdf"], "min": 1, "max": 2, "show_if": {"goal": "find_companies"}}
|
|
15
17
|
],
|
|
16
18
|
"slots": {
|
|
17
19
|
"deliver": {"label": "Deliver to", "default": "gravity", "adapters": {"gravity": [], "gmail": ["gmail.draft"]}},
|
|
@@ -62,6 +64,38 @@
|
|
|
62
64
|
{"name": "action choice must be offered",
|
|
63
65
|
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "delete_everything"},
|
|
64
66
|
"visible": ["resume_text", "platforms", "contact_source", "goal"],
|
|
65
|
-
"problems": ["goal"]}
|
|
67
|
+
"problems": ["goal"]},
|
|
68
|
+
{"name": "a date with max takes a list of days",
|
|
69
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "write_emails", "call_days": ["2026-11-03", "2026-11-05"]},
|
|
70
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "call_days"],
|
|
71
|
+
"problems": []},
|
|
72
|
+
{"name": "days must be real calendar days",
|
|
73
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "write_emails", "call_days": ["next tuesday", "2026-02-30"]},
|
|
74
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "call_days"],
|
|
75
|
+
"problems": ["call_days"]},
|
|
76
|
+
{"name": "no more days than max",
|
|
77
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "write_emails", "call_days": ["2026-11-03", "2026-11-04", "2026-11-05", "2026-11-06"]},
|
|
78
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "call_days"],
|
|
79
|
+
"problems": ["call_days"]},
|
|
80
|
+
{"name": "min days asks for at least one",
|
|
81
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "write_emails"},
|
|
82
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "call_days"],
|
|
83
|
+
"problems": ["call_days"]},
|
|
84
|
+
{"name": "a file with max takes a list of links",
|
|
85
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "find_companies", "past_pitches": ["https://x.test/uploads/a.pdf", "https://x.test/uploads/b.pdf"]},
|
|
86
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "past_pitches"],
|
|
87
|
+
"problems": []},
|
|
88
|
+
{"name": "no more files than max",
|
|
89
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "find_companies", "past_pitches": ["https://x.test/a.pdf", "https://x.test/b.pdf", "https://x.test/c.pdf"]},
|
|
90
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "past_pitches"],
|
|
91
|
+
"problems": ["past_pitches"]},
|
|
92
|
+
{"name": "several files are a list, not one link",
|
|
93
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "find_companies", "past_pitches": "https://x.test/a.pdf"},
|
|
94
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "past_pitches"],
|
|
95
|
+
"problems": ["past_pitches"]},
|
|
96
|
+
{"name": "min files asks for at least one",
|
|
97
|
+
"answers": {"resume_text": "cv", "platforms": ["x"], "goal": "find_companies"},
|
|
98
|
+
"visible": ["resume_text", "platforms", "contact_source", "goal", "past_pitches"],
|
|
99
|
+
"problems": ["past_pitches"]}
|
|
66
100
|
]
|
|
67
101
|
}
|
|
@@ -35,12 +35,16 @@ class InputType(str, Enum):
|
|
|
35
35
|
# An API key or password. The platform seals it with KMS when it is submitted, keeps it
|
|
36
36
|
# out of every API response and log, and opens it only to hand it to the running agent.
|
|
37
37
|
SECRET = "secret"
|
|
38
|
-
# The agent gets a short-lived URL it fetches through the gateway.
|
|
38
|
+
# The agent gets a short-lived URL it fetches through the gateway; with `max`, a list of them (several files).
|
|
39
39
|
FILE = "file"
|
|
40
40
|
# Several of `options`; the value is a list.
|
|
41
41
|
MULTI_SELECT = "multi-select"
|
|
42
42
|
# One of this agent's declared `actions`; the chosen action runs (rules.py).
|
|
43
43
|
ACTION_CHOICE = "action-choice"
|
|
44
|
+
# A Google Doc or Sheet of the person's: they paste its link, the agent gets the file id (rules.google_file_id),
|
|
45
|
+
# which is what docs.read and sheets.read take.
|
|
46
|
+
GOOGLE_DOC = "google-doc"
|
|
47
|
+
GOOGLE_SHEET = "google-sheet"
|
|
44
48
|
|
|
45
49
|
|
|
46
50
|
# Which Python types each input's `default` may be.
|
|
@@ -57,6 +61,8 @@ _PYTHON_TYPES: dict[InputType, tuple[type, ...]] = {
|
|
|
57
61
|
InputType.FILE: (), # never has a default
|
|
58
62
|
InputType.MULTI_SELECT: (list,),
|
|
59
63
|
InputType.ACTION_CHOICE: (str,),
|
|
64
|
+
InputType.GOOGLE_DOC: (str,),
|
|
65
|
+
InputType.GOOGLE_SHEET: (str,),
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
# A `show_if` value: what the named input or slot must be for this question to be asked.
|
|
@@ -86,7 +92,9 @@ class Renderer(str, Enum):
|
|
|
86
92
|
MARKDOWN = "markdown"
|
|
87
93
|
DOCX = "docx"
|
|
88
94
|
PPTX = "pptx"
|
|
89
|
-
|
|
95
|
+
PDF = "pdf"
|
|
96
|
+
ROWS = "rows" # CSV of the first table
|
|
97
|
+
XLSX = "xlsx" # every table a sheet
|
|
90
98
|
|
|
91
99
|
|
|
92
100
|
class WebhookSource(str, Enum):
|
|
@@ -204,7 +212,8 @@ class InputSpec(BaseModel):
|
|
|
204
212
|
default: Any | None = None
|
|
205
213
|
# Asked only when every named earlier input or slot has one of the given values (rules.py).
|
|
206
214
|
show_if: Annotated[ShowIf | None, Field(max_length=C.MAX_INPUTS)] = None
|
|
207
|
-
# multi-select
|
|
215
|
+
# multi-select: how many options may be picked. date: how many days; with `max` the answer is a list of
|
|
216
|
+
# "YYYY-MM-DD" days, picked on a calendar. file: how many files; with `max` the answer is a list of links.
|
|
208
217
|
min: Annotated[int | None, Field(ge=0, le=C.MAX_OPTIONS)] = None
|
|
209
218
|
max: Annotated[int | None, Field(ge=1, le=C.MAX_OPTIONS)] = None
|
|
210
219
|
# action-choice only: the declared actions offered, in order.
|
|
@@ -253,14 +262,40 @@ class InputSpec(BaseModel):
|
|
|
253
262
|
)
|
|
254
263
|
return self
|
|
255
264
|
|
|
265
|
+
@property
|
|
266
|
+
def many_days(self) -> bool:
|
|
267
|
+
"""A date input that takes several days: its answer is a list of "YYYY-MM-DD"."""
|
|
268
|
+
return self.type is InputType.DATE and self.max is not None
|
|
269
|
+
|
|
270
|
+
@property
|
|
271
|
+
def many_files(self) -> bool:
|
|
272
|
+
"""A file input that takes several files: its answer is a list of links, one per file."""
|
|
273
|
+
return self.type is InputType.FILE and self.max is not None
|
|
274
|
+
|
|
256
275
|
@model_validator(mode="after")
|
|
257
276
|
def _check_choice_fields(self) -> InputSpec:
|
|
258
277
|
multi = self.type is InputType.MULTI_SELECT
|
|
259
|
-
if (self.min is not None or self.max is not None) and not multi:
|
|
278
|
+
if (self.min is not None or self.max is not None) and not (multi or self.type in (InputType.DATE, InputType.FILE)):
|
|
279
|
+
raise PydanticCustomError(
|
|
280
|
+
ErrorCode.INVALID_INPUT.value,
|
|
281
|
+
"Input '{value}' sets min or max but is not a multi-select, a date or a file.",
|
|
282
|
+
{"value": self.name, "remediation": "Set type to 'multi-select', 'date' or 'file', or remove min and max."},
|
|
283
|
+
)
|
|
284
|
+
file_bounds = self.type is InputType.FILE and (self.min is not None or self.max is not None)
|
|
285
|
+
if file_bounds and (self.max is None or (self.min or 0) > self.max or self.max > C.MAX_FILES):
|
|
260
286
|
raise PydanticCustomError(
|
|
261
287
|
ErrorCode.INVALID_INPUT.value,
|
|
262
|
-
"
|
|
263
|
-
{"value": self.name, "
|
|
288
|
+
"File input '{value}' asks for between {lo} and {hi} files.",
|
|
289
|
+
{"value": self.name, "lo": self.min or 0, "hi": self.max,
|
|
290
|
+
"remediation": f"Set `max` (how many files may be uploaded, at most {C.MAX_FILES}), and keep min <= max."},
|
|
291
|
+
)
|
|
292
|
+
days_bounds = self.type is InputType.DATE and (self.min is not None or self.max is not None)
|
|
293
|
+
if days_bounds and (self.max is None or (self.min or 0) > self.max):
|
|
294
|
+
raise PydanticCustomError(
|
|
295
|
+
ErrorCode.INVALID_INPUT.value,
|
|
296
|
+
"Date input '{value}' asks for between {lo} and {hi} days.",
|
|
297
|
+
{"value": self.name, "lo": self.min or 0, "hi": self.max,
|
|
298
|
+
"remediation": "Set `max` (how many days may be picked), and keep min <= max."},
|
|
264
299
|
)
|
|
265
300
|
if multi:
|
|
266
301
|
count = len(self.options or [])
|
|
@@ -344,7 +379,7 @@ class InputSpec(BaseModel):
|
|
|
344
379
|
},
|
|
345
380
|
)
|
|
346
381
|
|
|
347
|
-
expected = _PYTHON_TYPES[self.type]
|
|
382
|
+
expected = (list,) if self.many_days else _PYTHON_TYPES[self.type]
|
|
348
383
|
# bool is an int subclass, so NUMBER needs this guard.
|
|
349
384
|
is_bool = isinstance(self.default, bool)
|
|
350
385
|
ok = (
|
|
@@ -451,6 +486,16 @@ class ScheduleSpec(BaseModel):
|
|
|
451
486
|
return v
|
|
452
487
|
|
|
453
488
|
|
|
489
|
+
class EmailTriggerSpec(BaseModel):
|
|
490
|
+
"""Run when new mail matching a Gmail search arrives in the person's inbox. Gravity checks every 5 minutes and
|
|
491
|
+
starts a run only when there is new mail, with the messages in inputs["event"]["emails"]."""
|
|
492
|
+
|
|
493
|
+
model_config = _STRICT
|
|
494
|
+
|
|
495
|
+
query: Annotated[str, Field(min_length=1, max_length=500)] # a Gmail search: "from:recruiting@acme.com is:unread"
|
|
496
|
+
consumer_can_change: bool = True
|
|
497
|
+
|
|
498
|
+
|
|
454
499
|
class TriggersSpec(BaseModel):
|
|
455
500
|
"""What starts a run. Declared so the consumer sees it before installing."""
|
|
456
501
|
|
|
@@ -459,14 +504,15 @@ class TriggersSpec(BaseModel):
|
|
|
459
504
|
manual: bool = True
|
|
460
505
|
schedule: ScheduleSpec | None = None
|
|
461
506
|
webhook: list[WebhookSource] = Field(default_factory=list)
|
|
507
|
+
email: EmailTriggerSpec | None = None
|
|
462
508
|
|
|
463
509
|
@model_validator(mode="after")
|
|
464
510
|
def _check_something_starts_it(self) -> TriggersSpec:
|
|
465
|
-
if not self.manual and self.schedule is None and not self.webhook:
|
|
511
|
+
if not self.manual and self.schedule is None and not self.webhook and self.email is None:
|
|
466
512
|
raise PydanticCustomError(
|
|
467
513
|
ErrorCode.INVALID_TRIGGER.value,
|
|
468
514
|
"Nothing can start this agent.",
|
|
469
|
-
{"remediation": "Set manual: true, or add a schedule or a webhook."},
|
|
515
|
+
{"remediation": "Set manual: true, or add a schedule, an email trigger or a webhook."},
|
|
470
516
|
)
|
|
471
517
|
return self
|
|
472
518
|
|
|
@@ -536,6 +582,15 @@ class ChartHint(BaseModel):
|
|
|
536
582
|
)
|
|
537
583
|
|
|
538
584
|
|
|
585
|
+
class TabHint(BaseModel):
|
|
586
|
+
"""One tab of the result, as the agent's page in Explore lists it: its name and what is on it."""
|
|
587
|
+
|
|
588
|
+
model_config = _HINT
|
|
589
|
+
|
|
590
|
+
name: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)]
|
|
591
|
+
about: Annotated[str, Field(max_length=C.MAX_LABEL_LENGTH)] | None = None
|
|
592
|
+
|
|
593
|
+
|
|
539
594
|
class DisplaySpec(BaseModel):
|
|
540
595
|
"""How the run's result shows on the page, when the builder wants to say so.
|
|
541
596
|
|
|
@@ -546,6 +601,8 @@ class DisplaySpec(BaseModel):
|
|
|
546
601
|
view: document | report | table | chart | code | files
|
|
547
602
|
field: the result key that is the main thing to show
|
|
548
603
|
chart: {type: line | bar, x: date, y: [reach, likes]}
|
|
604
|
+
tabs: [{name: Overview, about: "Your best options and what they cost"}], the
|
|
605
|
+
result's tabs in order, listed on the agent's page before anyone runs it
|
|
549
606
|
"""
|
|
550
607
|
|
|
551
608
|
model_config = _HINT
|
|
@@ -553,6 +610,7 @@ class DisplaySpec(BaseModel):
|
|
|
553
610
|
view: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None
|
|
554
611
|
field: Annotated[str, Field(max_length=C.MAX_NAME_LENGTH)] | None = None
|
|
555
612
|
chart: ChartHint | None = None
|
|
613
|
+
tabs: Annotated[list[TabHint], Field(max_length=12)] = Field(default_factory=list)
|
|
556
614
|
|
|
557
615
|
|
|
558
616
|
class ChooseOneSpec(BaseModel):
|
{gravity_cli-0.9.0 → gravity_cli-0.11.0}/packages/gravity-schema/schema/manifest.schema.json
RENAMED
|
@@ -301,7 +301,7 @@
|
|
|
301
301
|
"type": "object"
|
|
302
302
|
},
|
|
303
303
|
"DisplaySpec": {
|
|
304
|
-
"description": "How the run's result shows on the page, when the builder wants to say so.\n\nA hint, not a rule: without it the page reads the result's own shape, and a\nvalue the page doesn't know (a typo, a newer view) is ignored the same way,\nso it never fails a push or a run.\n\n view: document | report | table | chart | code | files\n field: the result key that is the main thing to show\n chart: {type: line | bar, x: date, y: [reach, likes]}",
|
|
304
|
+
"description": "How the run's result shows on the page, when the builder wants to say so.\n\nA hint, not a rule: without it the page reads the result's own shape, and a\nvalue the page doesn't know (a typo, a newer view) is ignored the same way,\nso it never fails a push or a run.\n\n view: document | report | table | chart | code | files\n field: the result key that is the main thing to show\n chart: {type: line | bar, x: date, y: [reach, likes]}\n tabs: [{name: Overview, about: \"Your best options and what they cost\"}], the\n result's tabs in order, listed on the agent's page before anyone runs it",
|
|
305
305
|
"properties": {
|
|
306
306
|
"chart": {
|
|
307
307
|
"anyOf": [
|
|
@@ -327,6 +327,14 @@
|
|
|
327
327
|
"default": null,
|
|
328
328
|
"title": "Field"
|
|
329
329
|
},
|
|
330
|
+
"tabs": {
|
|
331
|
+
"items": {
|
|
332
|
+
"$ref": "#/$defs/TabHint"
|
|
333
|
+
},
|
|
334
|
+
"maxItems": 12,
|
|
335
|
+
"title": "Tabs",
|
|
336
|
+
"type": "array"
|
|
337
|
+
},
|
|
330
338
|
"view": {
|
|
331
339
|
"anyOf": [
|
|
332
340
|
{
|
|
@@ -344,6 +352,28 @@
|
|
|
344
352
|
"title": "DisplaySpec",
|
|
345
353
|
"type": "object"
|
|
346
354
|
},
|
|
355
|
+
"EmailTriggerSpec": {
|
|
356
|
+
"additionalProperties": false,
|
|
357
|
+
"description": "Run when new mail matching a Gmail search arrives in the person's inbox. Gravity checks every 5 minutes and\nstarts a run only when there is new mail, with the messages in inputs[\"event\"][\"emails\"].",
|
|
358
|
+
"properties": {
|
|
359
|
+
"consumer_can_change": {
|
|
360
|
+
"default": true,
|
|
361
|
+
"title": "Consumer Can Change",
|
|
362
|
+
"type": "boolean"
|
|
363
|
+
},
|
|
364
|
+
"query": {
|
|
365
|
+
"maxLength": 500,
|
|
366
|
+
"minLength": 1,
|
|
367
|
+
"title": "Query",
|
|
368
|
+
"type": "string"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"required": [
|
|
372
|
+
"query"
|
|
373
|
+
],
|
|
374
|
+
"title": "EmailTriggerSpec",
|
|
375
|
+
"type": "object"
|
|
376
|
+
},
|
|
347
377
|
"InputSpec": {
|
|
348
378
|
"additionalProperties": false,
|
|
349
379
|
"description": "One value the consumer supplies. Renders as one form field.",
|
|
@@ -523,7 +553,9 @@
|
|
|
523
553
|
"secret",
|
|
524
554
|
"file",
|
|
525
555
|
"multi-select",
|
|
526
|
-
"action-choice"
|
|
556
|
+
"action-choice",
|
|
557
|
+
"google-doc",
|
|
558
|
+
"google-sheet"
|
|
527
559
|
],
|
|
528
560
|
"title": "InputType",
|
|
529
561
|
"type": "string"
|
|
@@ -1034,7 +1066,9 @@
|
|
|
1034
1066
|
"markdown",
|
|
1035
1067
|
"docx",
|
|
1036
1068
|
"pptx",
|
|
1037
|
-
"
|
|
1069
|
+
"pdf",
|
|
1070
|
+
"rows",
|
|
1071
|
+
"xlsx"
|
|
1038
1072
|
],
|
|
1039
1073
|
"title": "Renderer",
|
|
1040
1074
|
"type": "string"
|
|
@@ -1339,10 +1373,49 @@
|
|
|
1339
1373
|
"title": "StateSpec",
|
|
1340
1374
|
"type": "object"
|
|
1341
1375
|
},
|
|
1376
|
+
"TabHint": {
|
|
1377
|
+
"description": "One tab of the result, as the agent's page in Explore lists it: its name and what is on it.",
|
|
1378
|
+
"properties": {
|
|
1379
|
+
"about": {
|
|
1380
|
+
"anyOf": [
|
|
1381
|
+
{
|
|
1382
|
+
"maxLength": 200,
|
|
1383
|
+
"type": "string"
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
"type": "null"
|
|
1387
|
+
}
|
|
1388
|
+
],
|
|
1389
|
+
"default": null,
|
|
1390
|
+
"title": "About"
|
|
1391
|
+
},
|
|
1392
|
+
"name": {
|
|
1393
|
+
"maxLength": 64,
|
|
1394
|
+
"title": "Name",
|
|
1395
|
+
"type": "string"
|
|
1396
|
+
}
|
|
1397
|
+
},
|
|
1398
|
+
"required": [
|
|
1399
|
+
"name"
|
|
1400
|
+
],
|
|
1401
|
+
"title": "TabHint",
|
|
1402
|
+
"type": "object"
|
|
1403
|
+
},
|
|
1342
1404
|
"TriggersSpec": {
|
|
1343
1405
|
"additionalProperties": false,
|
|
1344
1406
|
"description": "What starts a run. Declared so the consumer sees it before installing.",
|
|
1345
1407
|
"properties": {
|
|
1408
|
+
"email": {
|
|
1409
|
+
"anyOf": [
|
|
1410
|
+
{
|
|
1411
|
+
"$ref": "#/$defs/EmailTriggerSpec"
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"type": "null"
|
|
1415
|
+
}
|
|
1416
|
+
],
|
|
1417
|
+
"default": null
|
|
1418
|
+
},
|
|
1346
1419
|
"manual": {
|
|
1347
1420
|
"default": true,
|
|
1348
1421
|
"title": "Manual",
|
|
@@ -765,6 +765,14 @@ def test_display_hint_parses(manifest_data):
|
|
|
765
765
|
assert (d.view, d.field, d.chart.x, d.chart.y) == ("chart", "daily", "date", ["reach"])
|
|
766
766
|
|
|
767
767
|
|
|
768
|
+
def test_display_tabs_parse_and_survive_the_dump(manifest_data):
|
|
769
|
+
# The push sends model_dump, so the tabs must be in it for the catalog to list them.
|
|
770
|
+
manifest_data["display"] = {"tabs": [{"name": "Overview", "about": "Your best options"}, {"name": "Money"}]}
|
|
771
|
+
d = validate_manifest(manifest_data).display
|
|
772
|
+
assert [t.name for t in d.tabs] == ["Overview", "Money"]
|
|
773
|
+
assert validate_manifest(manifest_data).model_dump(mode="json", exclude_none=True)["display"]["tabs"][0] == {"name": "Overview", "about": "Your best options"}
|
|
774
|
+
|
|
775
|
+
|
|
768
776
|
def test_display_never_fails_on_what_the_page_does_not_know(manifest_data):
|
|
769
777
|
# An unknown view is kept for the page to ignore; an unknown key is dropped.
|
|
770
778
|
manifest_data["display"] = {"view": "carousel", "colour": "blue"}
|