Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ If this returns `{"job_id": "...", "state": "COMPLETED", "rowCount": 1, "rows":
| `dremio role` | `list`, `get`, `create`, `update`, `delete` | Full CRUD for organization roles |
| `dremio grant` | `get`, `update`, `delete` | Manage grants on projects, engines, org resources |
| `dremio project` | `list`, `get`, `create`, `update`, `delete` | Full CRUD for Dremio Cloud projects |
| `dremio skill` | `list`, `get`, `create`, `update`, `delete` | Manage saved AI Agent Skills |
| `dremio search` | *(top-level)* | Full-text search across all catalog entities |
| `dremio describe` | *(top-level)* | Machine-readable schema for any command |

Expand Down Expand Up @@ -171,8 +172,15 @@ dremio job list --status FAILED --output pretty

# Audit what roles and permissions a user has
dremio user audit rahim.bhojani

# Manage saved AI Agent Skills
dremio skill list --status DRAFT
dremio skill create --name "Revenue analyst" --description "Helps analyze revenue questions." --prompt-file ./skill.md
dremio skill update skill-abc --status PUBLISHED --tag 7
```

Saved Skill commands require the project Skills feature to be enabled. If it is disabled, the CLI returns the API's feature-disabled error.

### Output formats

Every command supports three output formats via `--output` / `-o`:
Expand Down Expand Up @@ -271,6 +279,7 @@ All endpoints target `https://api.dremio.cloud`. See the [Dremio Cloud API refer
| `GET /v1/roles[/{id}]`, `GET /v1/roles/name/{name}` | `role list/get` | [Roles](https://docs.dremio.com/dremio-cloud/api/) |
| `POST /v1/roles`, `PUT /v1/roles/{id}`, `DELETE /v1/roles/{id}` | `role create/update/delete` | [Roles](https://docs.dremio.com/dremio-cloud/api/) |
| `GET/PUT/DELETE /v1/{scope}/{id}/grants/{type}/{id}` | `grant get/update/delete` | [Grants](https://docs.dremio.com/dremio-cloud/api/) |
| `GET/POST/PUT/DELETE /v1/projects/{pid}/agent/skills[/{id}]` | `skill list/get/create/update/delete` | AI Agent Skills |

Commands that query system tables (`job list`, `job profile`, `reflection list`, `schema sample`) use `POST /v0/projects/{pid}/sql` to submit SQL against `sys.project.*` tables.

Expand Down Expand Up @@ -371,6 +380,7 @@ src/drs/
role.py # list, get, create, update, delete
grant.py # get, update, delete
project.py # list, get, create, update, delete
skill.py # list, get, create, update, delete
```

## Related projects
Expand Down
2 changes: 2 additions & 0 deletions src/drs/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
role,
schema,
setup,
skill,
tag,
user,
wiki,
Expand Down Expand Up @@ -69,6 +70,7 @@
app.add_typer(grant.app, name="grant")
app.add_typer(project.app, name="project")
app.add_typer(chat.app, name="chat")
app.add_typer(skill.app, name="skill")
app.command("setup")(setup.setup_command)

# Global state for config
Expand Down
27 changes: 27 additions & 0 deletions src/drs/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,33 @@ async def cancel_conversation_run(
self._agent(f"/conversations/{conversation_id}/runs/{run_id}:cancel"),
)

# -- Skills (v1 project-scoped agent API) --

async def list_skills(
self,
status: str | None = None,
limit: int = 100,
page_token: str | None = None,
) -> dict:
params: dict[str, str | int] = {"limit": limit}
if status:
params["status"] = status
if page_token:
params["pageToken"] = page_token
return await self._get(self._agent("/skills"), params=params)

async def get_skill(self, skill_id: str) -> dict:
return await self._get(self._agent(f"/skills/{skill_id}"))

async def create_skill(self, body: dict) -> dict:
return await self._post(self._agent("/skills"), json=body)

async def update_skill(self, skill_id: str, body: dict) -> dict:
return await self._put(self._agent(f"/skills/{skill_id}"), json=body)

async def delete_skill(self, skill_id: str) -> dict:
return await self._delete(self._agent(f"/skills/{skill_id}"))

# -- Grants (v1) --

async def get_grants(self, scope: str, scope_id: str, grantee_type: str, grantee_id: str) -> dict:
Expand Down
Loading