Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,39 @@ Individual commands:
- **Type checker**: `poetry run mypy .` — strict mode with `warn_unused_ignores`
- **Tests**: `poetry run pytest tests/ -q`

## Quality gates (must pass to report completion)

- **ALL tests must pass with ZERO failures. No exceptions.** CI/CD runs the full test suite on every PR. A test failure blocks the build.
- **ALL lint checks (including mypy) must pass with ZERO errors.** Run `make lint` — all files, not just ones you modified.
- **Do not dismiss test or lint failures as pre-existing or unrelated.** The `main` branch CI/CD is green. Any failure on a feature branch was caused by changes on that branch.
- **CRITICAL — NEVER INVESTIGATE ERROR ORIGIN OR BLAME**: When a lint, type-check, or test error appears, **fix it immediately**. Do NOT run `git blame` or use git history to argue that an error is "pre-existing" or not your responsibility. Tools like `git diff`, `git log`, and `git show` may be used to understand and review changes, but never to avoid fixing an error. There is no scenario where knowing the origin of an error changes what you must do: **fix it**.
- **CRITICAL — NEVER PIPE TEST OR LINT OUTPUT**: Do not append `| tail`, `| head`, `| grep`, or any pipe to `pytest`, `make lint`, `make test`, or similar commands. Piping hides errors. Use pytest flags like `--tb=short -q` to reduce verbosity — never pipe.

## Key Rules

- Always run `poetry run black .` after making changes — CI will fail if formatting differs.
- When fixing a type issue, remove the corresponding `# type: ignore` comment or mypy will error on the unused suppression.
- Do NOT edit files under `seclai/_generated/` — they are auto-generated from the OpenAPI spec.
- The OpenAPI spec at `openapi/seclai.openapi.json` is shared identically with `seclai-go`. Changes must be synced to both repos.
- OpenAPI specs are generated from the main `seclai` app repo. Description or endpoint changes made here must also be applied upstream, or they will be overwritten on the next generation.
- `.github/copilot-instructions.md` shares common sections (quality gates, git rules, editing rules, self-correction rules) across all SDK repos. When updating shared rules, apply the same change to all repos: `seclai-python`, `seclai-javascript`, `seclai-go`, `seclai-csharp`, `seclai-cli`, `seclai-mcp`.
- Use the existing virtualenv (`poetry run ...`); do not create or reconfigure Python environments.
- **CRITICAL — USE EXISTING VIRTUAL ENV**: The workspace Python virtual environment is already set up. Reuse with `poetry run ...`; do **not** create, activate, or reconfigure another environment unless the user explicitly asks.
- **CRITICAL — NEVER CALL PYTHON ENVIRONMENT TOOLS**: Do not call `configure_python_environment`, `activate_python_environment_tools`, or any similar environment-management tool unless the user explicitly asks.
- Do not run ad-hoc Python snippets; add tests instead.

## Git rules

- **NEVER use `git stash`.** Use `git diff`, `git log`, or `git show` instead.
Comment thread
burgaard marked this conversation as resolved.
- Do not run `git checkout` to switch branches, `git reset`, or any other destructive git operation without explicit user approval.

## Editing rules

- Do not use CLI text tools (sed/awk). Use the editor-based patch tool.

## Self-correction rules

- **NEVER promise to "do better" without updating these instruction files.** If a recurring mistake is identified, edit this file with a concrete rule that prevents the mistake. Do that FIRST, then continue work.

## Architecture Notes

Expand Down
182 changes: 180 additions & 2 deletions openapi/seclai.openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"name": "X-Account-Id",
"required": false,
"schema": {
"format": "uuid",
"type": "string"
}
}
Expand Down Expand Up @@ -107,6 +106,114 @@
"title": "AgentEvaluationTier",
"type": "string"
},
"AgentExportResponse": {
"description": "Portable JSON snapshot of an agent definition.",
"properties": {
"agent": {
"additionalProperties": true,
"description": "Agent metadata and full definition. Keys: name, description, schema_version, definition, default_evaluation_tier, evaluation_mode, sampling_config, max_retries, retry_on_failure, prompt_model_auto_upgrade_strategy, prompt_model_auto_rollback_enabled, prompt_model_auto_rollback_triggers, created_at, updated_at.",
"title": "Agent",
"type": "object"
},
"alert_configs": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Alert configurations.",
"title": "Alert Configs"
},
"dependencies": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"description": "Resolved dependency manifest. Keys: knowledge_bases, memory_banks, source_connections, agents, users \u2014 each a list of {id, name, description, \u2026}.",
"title": "Dependencies"
},
"evaluation_criteria": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Evaluation criteria for agent steps.",
"title": "Evaluation Criteria"
},
"export_version": {
"description": "Schema version of the export format (currently \"2\").",
"title": "Export Version",
"type": "string"
},
"exported_at": {
"description": "ISO-8601 timestamp of when the export was generated.",
"title": "Exported At",
"type": "string"
},
"governance_policies": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Agent-scoped governance policies.",
"title": "Governance Policies"
},
"software_version": {
"description": "Application version that produced this export.",
"title": "Software Version",
"type": "string"
},
"trigger": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"description": "Trigger configuration with schedules.",
"title": "Trigger"
}
},
"required": [
"export_version",
"exported_at",
"software_version",
"agent"
],
"title": "AgentExportResponse",
"type": "object"
},
"AgentRunAttemptResponse": {
"properties": {
"duration": {
Expand Down Expand Up @@ -354,6 +461,18 @@
"description": "Timestamp when the step attempt ended.",
"title": "Ended At"
},
"input": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Input provided to the step, if any.",
"title": "Input"
},
"output": {
"anyOf": [
{
Expand Down Expand Up @@ -404,6 +523,7 @@
"agent_step_id",
"step_type",
"status",
"input",
"output",
"output_content_type",
"started_at",
Expand Down Expand Up @@ -8871,6 +8991,64 @@
]
}
},
"/agents/{agent_id}/export": {
"get": {
"description": "Export an agent definition as a portable JSON snapshot.\n\nThe response contains the full definition, trigger configuration with schedules, alert configs, evaluation criteria, agent-scoped governance policies, and a resolved dependency manifest that maps every referenced external entity UUID to its human-readable name.\n\nResponse shape:\n- `export_version`: schema version (currently `\"2\"`)\n- `exported_at`: ISO-8601 timestamp\n- `agent`: name, description, schema_version, definition, timestamps\n- `trigger`: trigger type, input template, schedules\n- `alert_configs`: alert type, thresholds, recipients\n- `evaluation_criteria`: evaluation settings per step\n- `governance_policies`: agent-scoped governance policies\n- `dependencies`: knowledge_bases, memory_banks, source_connections, agents, users\n\nQuery params:\n- `download` (default true): when true, sets `Content-Disposition: attachment` so clients treat the response as a file download.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token.\n- When using OAuth, you may target a different organization account with `X-Account-Id`; for API keys, the key's account is always used.\n- You can only export agents belonging to the resolved account.",
"operationId": "export_agent_api_agents__agent_id__export_get",
Comment thread
burgaard marked this conversation as resolved.
"parameters": [
{
"in": "path",
"name": "agent_id",
"required": true,
"schema": {
"title": "Agent Id",
"type": "string"
}
},
{
"description": "Return as file download",
"in": "query",
"name": "download",
"required": false,
"schema": {
"default": true,
"description": "Return as file download",
"title": "Download",
"type": "boolean"
}
},
{
"$ref": "#/components/parameters/X-Account-Id"
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AgentExportResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Export agent definition",
"tags": [
"agents"
]
}
},
"/agents/{agent_id}/input-uploads/{upload_id}": {
"get": {
"description": "Poll the processing status of a file upload created via `POST /agents/{agent_id}/upload-input`.\n\nPossible `status` values: `processing`, `ready`, `failed`.\n\nAuth & scoping:\n- Requires `X-API-Key` header or OAuth Bearer token. All resources are scoped to the caller's account.",
Expand Down Expand Up @@ -11290,7 +11468,7 @@
},
"/me": {
"get": {
"description": "Returns the authenticated user's personal account ID and a list of organisations they belong to. Each organisation entry includes the organisation's own id, display name, and account_id. Useful for CLI tooling that needs to let the user pick an org context.",
"description": "Returns the authenticated user's personal account ID and a list of organizations they belong to. Each organization entry includes the organization's id, name, and account_id. Useful for CLI tooling that needs to let the user pick an organization context.",
"operationId": "get_me_api_me_get",
"parameters": [
{
Expand Down
14 changes: 13 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ mypy = ">=1,<2"
black = ">=24,<26"
openapi-python-client = ">=0.25,<1"
pdoc = ">=14,<15"
types-python-dateutil = "^2.9.0.20260402"
Comment thread
burgaard marked this conversation as resolved.

[tool.pytest.ini_options]
addopts = [
Expand Down
1 change: 1 addition & 0 deletions seclai/_generated/api/agent_evaluations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Contains endpoint functions for accessing the API"""
Loading
Loading