hundredflags-sdk 0.4.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.
@@ -0,0 +1,240 @@
1
+ Metadata-Version: 2.3
2
+ Name: hundredflags-sdk
3
+ Version: 0.4.0
4
+ Summary: Python client for HundredFlags agent environment documentation and actions
5
+ Author: germankochnev
6
+ Author-email: germankochnev <kochgerm@gmail.com>
7
+ Requires-Dist: httpx>=0.28,<1
8
+ Requires-Dist: pydantic>=2.10,<3
9
+ Requires-Dist: jsonschema>=4.23,<5
10
+ Requires-Dist: referencing>=0.35,<1
11
+ Requires-Python: >=3.12
12
+ Project-URL: Homepage, https://github.com/ai-security-lab-itmo/hundredflags-sdk
13
+ Project-URL: Documentation, https://github.com/ai-security-lab-itmo/hundredflags-sdk#readme
14
+ Project-URL: Issues, https://github.com/ai-security-lab-itmo/hundredflags-sdk/issues
15
+ Description-Content-Type: text/markdown
16
+
17
+ # HundredFlags SDK
18
+
19
+ Python-клиент для работы с агентными средами полигона HundredFlags.
20
+ SDK получает документацию конкретной задачи и вызывает тот же `agent-env` API,
21
+ которым пользуется браузер: состояние, действия, проверку и сброс.
22
+
23
+ ## Установка
24
+
25
+ Требуется Python 3.12 или новее.
26
+
27
+ ```sh
28
+ python -m pip install hundredflags-sdk
29
+ ```
30
+
31
+ Для воспроизводимой установки этой версии:
32
+
33
+ ```sh
34
+ python -m pip install hundredflags-sdk==0.4.0
35
+ ```
36
+
37
+ Версия 0.4.0 использует контракт платформы `2026-09-runtime-1` и работает с
38
+ существующими экземплярами `agent-env` и их задачами. Обновляйте SDK вместе с
39
+ платформой; отдельные лаборатории или прогоны создавать не нужно.
40
+
41
+ ## Переход с ai-security-school-sdk
42
+
43
+ Начиная с 0.4.0 пакет называется `hundredflags-sdk`, а основной импорт —
44
+ `hundredflags_sdk`. API задач и контракт `2026-09-runtime-1` сохранены.
45
+
46
+ Для перехода из существующего окружения:
47
+
48
+ ```sh
49
+ python -m pip uninstall ai-security-school-sdk
50
+ python -m pip install --upgrade hundredflags-sdk
51
+ ```
52
+
53
+ Удалите старую зависимость из `pyproject.toml` или `requirements.txt`, заменив
54
+ её на `hundredflags-sdk`. Не устанавливайте оба дистрибутива одновременно:
55
+ они содержат общий совместимый модуль `ai_security_school_sdk`.
56
+ Старые импорты клиентов, моделей и исключений продолжают работать через этот
57
+ модуль; реализация у него общая с `hundredflags_sdk`.
58
+
59
+ `AI_SECURITY_SCHOOL_TOKEN` и `AI_SECURITY_SCHOOL_BASE_URL` остаются совместимыми
60
+ именами переменных окружения. `HUNDREDFLAGS_TOKEN` и `HUNDREDFLAGS_BASE_URL`
61
+ имеют приоритет, когда заданы; аргументы `from_env(...)` имеют приоритет над ними.
62
+
63
+ ## Подключение и документация
64
+
65
+ На странице операции откройте инструкцию подключения. Создайте временный API-ключ
66
+ в личном кабинете платформы и передайте его через переменную окружения. Ключ
67
+ принадлежит вашему аккаунту и работает со всеми доступными вам задачами;
68
+ конкретную задачу выбирайте по её `task_id` в SDK.
69
+ `HUNDREDFLAGS_BASE_URL` можно задать для другого развёртывания; по умолчанию
70
+ используется `https://plgn.hundredflags.ru`.
71
+
72
+ ```sh
73
+ export HUNDREDFLAGS_TOKEN="YOUR_TOKEN"
74
+ ```
75
+
76
+ ```python
77
+ from hundredflags_sdk import Client
78
+
79
+ with Client.from_env() as client:
80
+ for env in client.envs.list():
81
+ print(env.instance_id, env.title)
82
+ for task in env.tasks.list():
83
+ print(task.task_id, task.title)
84
+
85
+ task = client.tasks.get("YOUR_TASK_ID")
86
+ docs = task.documentation()
87
+ print(docs.instructions)
88
+ print(docs.action_payload_schema)
89
+ print(docs.action_payload_examples)
90
+ for action in docs.actions:
91
+ print(action.name, action.description, action.input_schema, action.examples)
92
+ ```
93
+
94
+ `client.envs.get(instance_id)` возвращает одну среду. `env.tasks.list()` возвращает
95
+ задачи из полученного списка; `env.tasks.get(task_id)` загружает документацию
96
+ выбранной задачи. Среда соответствует `agent-env-instance`, задача —
97
+ `ctf-instance`. Документация описывает доступные студенту точки входа, а не
98
+ внутренние инструменты агента. Набор действий и схемы приходят с сервера, поэтому
99
+ новая задача не требует новой версии SDK.
100
+
101
+ ## Выполнение действий
102
+
103
+ Для действия с именем используйте `task.actions.call(name, arguments)`.
104
+ Имя и аргументы выбираются из документации конкретной задачи:
105
+
106
+ ```python
107
+ with Client.from_env() as client:
108
+ task = client.tasks.get("YOUR_TASK_ID")
109
+ print(task.actions.list())
110
+
111
+ # Используйте это имя только если оно есть в документации выбранной задачи.
112
+ result = task.actions.call("send_message", {"message": "Проверь новый документ"})
113
+ print(result.status, result.response, result.state)
114
+ print(task.state().model_dump())
115
+ ```
116
+
117
+ Метод вставляет поле `action` в тело запроса. В `arguments` передаются остальные
118
+ поля; `input_schema` и `examples` описанного действия не содержат `action`.
119
+ SDK проверяет аргументы и полное тело по JSON Schema перед отправкой. Сервер
120
+ применяет проверки существующего обработчика действия, а также контролирует
121
+ доступ, пререквизиты и бюджет пользователя.
122
+
123
+ `task.act(payload)` принимает полное нативное тело действия. Так поддерживаются
124
+ и существующие среды, у которых нет именованных действий, например чат:
125
+
126
+ ```python
127
+ with Client.from_env() as client:
128
+ task = client.tasks.get("YOUR_CHAT_TASK_ID")
129
+ docs = task.documentation()
130
+ print(docs.action_payload_schema, docs.action_payload_examples)
131
+ result = task.act({"message": "Привет"})
132
+ print(result.model_dump())
133
+ ```
134
+
135
+ Пустой `docs.actions` не означает отсутствие возможностей: используйте полную
136
+ схему `action_payload_schema`. SDK не угадывает имена действий по коду runtime.
137
+ Документация не исполняется как Python-код, внешние ссылки JSON Schema не
138
+ загружаются. Внешние поверхности сценария, например MCP-сервис или реестр
139
+ зависимостей, используются через их собственные интерфейсы.
140
+
141
+ ## Состояние, проверка и сброс
142
+
143
+ ```python
144
+ with Client.from_env() as client:
145
+ task = client.tasks.get("YOUR_TASK_ID")
146
+ current = task.state()
147
+ print(current.status, current.missing_prerequisites)
148
+
149
+ if task.documentation().supports_standalone_grading:
150
+ verdict = task.grade()
151
+ print(verdict.grader_passed, verdict.grader_result, verdict.completed)
152
+
153
+ # При необходимости передайте task.grade({...}) полезную нагрузку проверки.
154
+ # Явный сброс через существующее поведение среды:
155
+ # task.reset()
156
+ ```
157
+
158
+ `supports_grading` означает наличие оценивания вообще; `supports_standalone_grading`
159
+ разрешает отдельный вызов `grade()`. Некоторые задания оценивают ответ внутри
160
+ своих действий, например `submit_card` или `submit_finding`.
161
+
162
+ У одного пользователя задачи одной среды разделяют состояние с браузером и
163
+ другими скриптами. Получение нового handle или создание второго клиента не
164
+ создаёт отдельную попытку. Сброс затрагивает общее состояние среды; сохранение
165
+ зачётов и пререквизитов определяется её существующим поведением. Локальный
166
+ контекстный менеджер закрывает только HTTP-соединения.
167
+
168
+ Алгоритм атаки работает в вашем Python-процессе. Вызовы возвращают обычные ответы
169
+ runtime без фоновых заданий SDK, checkpoint, fork или воспроизведения сценария.
170
+ Вызовы одной среды выполняйте последовательно: параллельные кандидаты будут
171
+ менять одно состояние. Async-клиент удобен для неблокирующего ожидания и работы
172
+ с разными независимыми средами.
173
+
174
+ ## Async
175
+
176
+ ```python
177
+ import asyncio
178
+ from hundredflags_sdk import AsyncClient
179
+
180
+
181
+ async def main():
182
+ async with AsyncClient.from_env() as client:
183
+ task = await client.tasks.get("YOUR_TASK_ID")
184
+ docs = await task.documentation()
185
+ print(docs.instructions)
186
+ result = await task.act({"message": "Привет"}) # Если разрешено схемой.
187
+ print(result.response)
188
+ print((await task.state()).state)
189
+
190
+
191
+ asyncio.run(main())
192
+ ```
193
+
194
+ Методы async-ресурсов, включая `env.tasks.list()`, вызываются через `await`.
195
+ Конструкторы, `from_env()`, поля `.info`, `.task_id`, `.instance_id` и `.title`
196
+ синхронные. `task.documentation()` обновляет снимок `.info`; `task.state()`
197
+ получает текущее серверное состояние. Дополнительные поля ответов сохраняются
198
+ в моделях и доступны через `model_dump()`.
199
+
200
+ Примеры: [документация и вызов](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/first_experiment.py),
201
+ [последовательный поиск кандидатов](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/async_search.py),
202
+ [связанные задачи одной среды](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/multistage.py).
203
+
204
+ ## Ошибки и сетевые повторы
205
+
206
+ - `APIError` содержит `code`, `message`, `status_code`, `details` и `usage`.
207
+ Для HTTP 401/403/404/409/429 используются `AuthenticationError`,
208
+ `PermissionDeniedError`, `NotFoundError`, `ConflictError`, `LimitExceededError`.
209
+ - Успешный HTTP-ответ с `status="locked"` остаётся `RuntimeResponse`:
210
+ проверьте `status` и `missing_prerequisites` перед дальнейшими действиями.
211
+ - `ActionValidationError` означает локальное несоответствие схеме,
212
+ `ProtocolError` — некорректный ответ или неподдерживаемую ссылку в схеме.
213
+ - Автоматические повторы допускаются только для GET: при сетевых ошибках и
214
+ HTTP 429/502/503/504. Параметры клиента: `timeout=120`, `max_retries=2`,
215
+ `retry_backoff=0.25`; `max_retries=0` отключает повторы.
216
+ - Действия, проверка и сброс **никогда не повторяются автоматически**.
217
+ При сетевом сбое `TransportError.may_have_executed` показывает, что изменение
218
+ могло уже выполниться. Сначала изучите `task.state()` и только затем решайте,
219
+ нужен ли повтор. Таймаут или отмена async-корутины не доказывают, что сервер
220
+ остановил исполнение.
221
+ - Для удалённого сервера требуется HTTPS. HTTP доступен для локальной разработки;
222
+ перенаправления HTTP не выполняются, чтобы не передавать токен другому адресу.
223
+
224
+ ## Разработка
225
+
226
+ ```sh
227
+ uv sync --python 3.12
228
+ uv run pytest
229
+ uv run ruff check .
230
+ uv run mypy src
231
+ uv build
232
+ ```
233
+
234
+ Пакет не импортирует backend платформы. Sync/async тестируются через HTTPX
235
+ MockTransport против одного контракта `/api/agent-env`.
236
+ Публикация описана в [PUBLISHING.md](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/main/PUBLISHING.md).
237
+
238
+ ## Runtime contract
239
+
240
+ Version 0.3 targets the coordinated `2026-09-runtime-1` platform release. HTTP failures use `{ "error": { "code", "message", "details" }, "usage", "retry_after" }`. Task prerequisite and completion metadata refer to explicit task IDs; shared environment state does not imply shared task credit. Upgrade the platform, course clients, and SDK together.
@@ -0,0 +1,224 @@
1
+ # HundredFlags SDK
2
+
3
+ Python-клиент для работы с агентными средами полигона HundredFlags.
4
+ SDK получает документацию конкретной задачи и вызывает тот же `agent-env` API,
5
+ которым пользуется браузер: состояние, действия, проверку и сброс.
6
+
7
+ ## Установка
8
+
9
+ Требуется Python 3.12 или новее.
10
+
11
+ ```sh
12
+ python -m pip install hundredflags-sdk
13
+ ```
14
+
15
+ Для воспроизводимой установки этой версии:
16
+
17
+ ```sh
18
+ python -m pip install hundredflags-sdk==0.4.0
19
+ ```
20
+
21
+ Версия 0.4.0 использует контракт платформы `2026-09-runtime-1` и работает с
22
+ существующими экземплярами `agent-env` и их задачами. Обновляйте SDK вместе с
23
+ платформой; отдельные лаборатории или прогоны создавать не нужно.
24
+
25
+ ## Переход с ai-security-school-sdk
26
+
27
+ Начиная с 0.4.0 пакет называется `hundredflags-sdk`, а основной импорт —
28
+ `hundredflags_sdk`. API задач и контракт `2026-09-runtime-1` сохранены.
29
+
30
+ Для перехода из существующего окружения:
31
+
32
+ ```sh
33
+ python -m pip uninstall ai-security-school-sdk
34
+ python -m pip install --upgrade hundredflags-sdk
35
+ ```
36
+
37
+ Удалите старую зависимость из `pyproject.toml` или `requirements.txt`, заменив
38
+ её на `hundredflags-sdk`. Не устанавливайте оба дистрибутива одновременно:
39
+ они содержат общий совместимый модуль `ai_security_school_sdk`.
40
+ Старые импорты клиентов, моделей и исключений продолжают работать через этот
41
+ модуль; реализация у него общая с `hundredflags_sdk`.
42
+
43
+ `AI_SECURITY_SCHOOL_TOKEN` и `AI_SECURITY_SCHOOL_BASE_URL` остаются совместимыми
44
+ именами переменных окружения. `HUNDREDFLAGS_TOKEN` и `HUNDREDFLAGS_BASE_URL`
45
+ имеют приоритет, когда заданы; аргументы `from_env(...)` имеют приоритет над ними.
46
+
47
+ ## Подключение и документация
48
+
49
+ На странице операции откройте инструкцию подключения. Создайте временный API-ключ
50
+ в личном кабинете платформы и передайте его через переменную окружения. Ключ
51
+ принадлежит вашему аккаунту и работает со всеми доступными вам задачами;
52
+ конкретную задачу выбирайте по её `task_id` в SDK.
53
+ `HUNDREDFLAGS_BASE_URL` можно задать для другого развёртывания; по умолчанию
54
+ используется `https://plgn.hundredflags.ru`.
55
+
56
+ ```sh
57
+ export HUNDREDFLAGS_TOKEN="YOUR_TOKEN"
58
+ ```
59
+
60
+ ```python
61
+ from hundredflags_sdk import Client
62
+
63
+ with Client.from_env() as client:
64
+ for env in client.envs.list():
65
+ print(env.instance_id, env.title)
66
+ for task in env.tasks.list():
67
+ print(task.task_id, task.title)
68
+
69
+ task = client.tasks.get("YOUR_TASK_ID")
70
+ docs = task.documentation()
71
+ print(docs.instructions)
72
+ print(docs.action_payload_schema)
73
+ print(docs.action_payload_examples)
74
+ for action in docs.actions:
75
+ print(action.name, action.description, action.input_schema, action.examples)
76
+ ```
77
+
78
+ `client.envs.get(instance_id)` возвращает одну среду. `env.tasks.list()` возвращает
79
+ задачи из полученного списка; `env.tasks.get(task_id)` загружает документацию
80
+ выбранной задачи. Среда соответствует `agent-env-instance`, задача —
81
+ `ctf-instance`. Документация описывает доступные студенту точки входа, а не
82
+ внутренние инструменты агента. Набор действий и схемы приходят с сервера, поэтому
83
+ новая задача не требует новой версии SDK.
84
+
85
+ ## Выполнение действий
86
+
87
+ Для действия с именем используйте `task.actions.call(name, arguments)`.
88
+ Имя и аргументы выбираются из документации конкретной задачи:
89
+
90
+ ```python
91
+ with Client.from_env() as client:
92
+ task = client.tasks.get("YOUR_TASK_ID")
93
+ print(task.actions.list())
94
+
95
+ # Используйте это имя только если оно есть в документации выбранной задачи.
96
+ result = task.actions.call("send_message", {"message": "Проверь новый документ"})
97
+ print(result.status, result.response, result.state)
98
+ print(task.state().model_dump())
99
+ ```
100
+
101
+ Метод вставляет поле `action` в тело запроса. В `arguments` передаются остальные
102
+ поля; `input_schema` и `examples` описанного действия не содержат `action`.
103
+ SDK проверяет аргументы и полное тело по JSON Schema перед отправкой. Сервер
104
+ применяет проверки существующего обработчика действия, а также контролирует
105
+ доступ, пререквизиты и бюджет пользователя.
106
+
107
+ `task.act(payload)` принимает полное нативное тело действия. Так поддерживаются
108
+ и существующие среды, у которых нет именованных действий, например чат:
109
+
110
+ ```python
111
+ with Client.from_env() as client:
112
+ task = client.tasks.get("YOUR_CHAT_TASK_ID")
113
+ docs = task.documentation()
114
+ print(docs.action_payload_schema, docs.action_payload_examples)
115
+ result = task.act({"message": "Привет"})
116
+ print(result.model_dump())
117
+ ```
118
+
119
+ Пустой `docs.actions` не означает отсутствие возможностей: используйте полную
120
+ схему `action_payload_schema`. SDK не угадывает имена действий по коду runtime.
121
+ Документация не исполняется как Python-код, внешние ссылки JSON Schema не
122
+ загружаются. Внешние поверхности сценария, например MCP-сервис или реестр
123
+ зависимостей, используются через их собственные интерфейсы.
124
+
125
+ ## Состояние, проверка и сброс
126
+
127
+ ```python
128
+ with Client.from_env() as client:
129
+ task = client.tasks.get("YOUR_TASK_ID")
130
+ current = task.state()
131
+ print(current.status, current.missing_prerequisites)
132
+
133
+ if task.documentation().supports_standalone_grading:
134
+ verdict = task.grade()
135
+ print(verdict.grader_passed, verdict.grader_result, verdict.completed)
136
+
137
+ # При необходимости передайте task.grade({...}) полезную нагрузку проверки.
138
+ # Явный сброс через существующее поведение среды:
139
+ # task.reset()
140
+ ```
141
+
142
+ `supports_grading` означает наличие оценивания вообще; `supports_standalone_grading`
143
+ разрешает отдельный вызов `grade()`. Некоторые задания оценивают ответ внутри
144
+ своих действий, например `submit_card` или `submit_finding`.
145
+
146
+ У одного пользователя задачи одной среды разделяют состояние с браузером и
147
+ другими скриптами. Получение нового handle или создание второго клиента не
148
+ создаёт отдельную попытку. Сброс затрагивает общее состояние среды; сохранение
149
+ зачётов и пререквизитов определяется её существующим поведением. Локальный
150
+ контекстный менеджер закрывает только HTTP-соединения.
151
+
152
+ Алгоритм атаки работает в вашем Python-процессе. Вызовы возвращают обычные ответы
153
+ runtime без фоновых заданий SDK, checkpoint, fork или воспроизведения сценария.
154
+ Вызовы одной среды выполняйте последовательно: параллельные кандидаты будут
155
+ менять одно состояние. Async-клиент удобен для неблокирующего ожидания и работы
156
+ с разными независимыми средами.
157
+
158
+ ## Async
159
+
160
+ ```python
161
+ import asyncio
162
+ from hundredflags_sdk import AsyncClient
163
+
164
+
165
+ async def main():
166
+ async with AsyncClient.from_env() as client:
167
+ task = await client.tasks.get("YOUR_TASK_ID")
168
+ docs = await task.documentation()
169
+ print(docs.instructions)
170
+ result = await task.act({"message": "Привет"}) # Если разрешено схемой.
171
+ print(result.response)
172
+ print((await task.state()).state)
173
+
174
+
175
+ asyncio.run(main())
176
+ ```
177
+
178
+ Методы async-ресурсов, включая `env.tasks.list()`, вызываются через `await`.
179
+ Конструкторы, `from_env()`, поля `.info`, `.task_id`, `.instance_id` и `.title`
180
+ синхронные. `task.documentation()` обновляет снимок `.info`; `task.state()`
181
+ получает текущее серверное состояние. Дополнительные поля ответов сохраняются
182
+ в моделях и доступны через `model_dump()`.
183
+
184
+ Примеры: [документация и вызов](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/first_experiment.py),
185
+ [последовательный поиск кандидатов](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/async_search.py),
186
+ [связанные задачи одной среды](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/v0.4.0/examples/multistage.py).
187
+
188
+ ## Ошибки и сетевые повторы
189
+
190
+ - `APIError` содержит `code`, `message`, `status_code`, `details` и `usage`.
191
+ Для HTTP 401/403/404/409/429 используются `AuthenticationError`,
192
+ `PermissionDeniedError`, `NotFoundError`, `ConflictError`, `LimitExceededError`.
193
+ - Успешный HTTP-ответ с `status="locked"` остаётся `RuntimeResponse`:
194
+ проверьте `status` и `missing_prerequisites` перед дальнейшими действиями.
195
+ - `ActionValidationError` означает локальное несоответствие схеме,
196
+ `ProtocolError` — некорректный ответ или неподдерживаемую ссылку в схеме.
197
+ - Автоматические повторы допускаются только для GET: при сетевых ошибках и
198
+ HTTP 429/502/503/504. Параметры клиента: `timeout=120`, `max_retries=2`,
199
+ `retry_backoff=0.25`; `max_retries=0` отключает повторы.
200
+ - Действия, проверка и сброс **никогда не повторяются автоматически**.
201
+ При сетевом сбое `TransportError.may_have_executed` показывает, что изменение
202
+ могло уже выполниться. Сначала изучите `task.state()` и только затем решайте,
203
+ нужен ли повтор. Таймаут или отмена async-корутины не доказывают, что сервер
204
+ остановил исполнение.
205
+ - Для удалённого сервера требуется HTTPS. HTTP доступен для локальной разработки;
206
+ перенаправления HTTP не выполняются, чтобы не передавать токен другому адресу.
207
+
208
+ ## Разработка
209
+
210
+ ```sh
211
+ uv sync --python 3.12
212
+ uv run pytest
213
+ uv run ruff check .
214
+ uv run mypy src
215
+ uv build
216
+ ```
217
+
218
+ Пакет не импортирует backend платформы. Sync/async тестируются через HTTPX
219
+ MockTransport против одного контракта `/api/agent-env`.
220
+ Публикация описана в [PUBLISHING.md](https://github.com/ai-security-lab-itmo/hundredflags-sdk/blob/main/PUBLISHING.md).
221
+
222
+ ## Runtime contract
223
+
224
+ Version 0.3 targets the coordinated `2026-09-runtime-1` platform release. HTTP failures use `{ "error": { "code", "message", "details" }, "usage", "retry_after" }`. Task prerequisite and completion metadata refer to explicit task IDs; shared environment state does not imply shared task credit. Upgrade the platform, course clients, and SDK together.
@@ -0,0 +1,60 @@
1
+ [project]
2
+ name = "hundredflags-sdk"
3
+ version = "0.4.0"
4
+ description = "Python client for HundredFlags agent environment documentation and actions"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "httpx>=0.28,<1",
9
+ "pydantic>=2.10,<3",
10
+ "jsonschema>=4.23,<5",
11
+ "referencing>=0.35,<1",
12
+ ]
13
+
14
+ [[project.authors]]
15
+ name = "germankochnev"
16
+ email = "kochgerm@gmail.com"
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/ai-security-lab-itmo/hundredflags-sdk"
20
+ Documentation = "https://github.com/ai-security-lab-itmo/hundredflags-sdk#readme"
21
+ Issues = "https://github.com/ai-security-lab-itmo/hundredflags-sdk/issues"
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "pytest>=8.3,<9",
26
+ "pytest-asyncio>=0.25,<2",
27
+ "ruff>=0.9,<1",
28
+ "mypy>=1.15,<2",
29
+ "types-jsonschema>=4.23",
30
+ ]
31
+
32
+ [tool.pytest.ini_options]
33
+ asyncio_mode = "auto"
34
+ testpaths = ["tests"]
35
+
36
+ [tool.ruff]
37
+ line-length = 100
38
+ target-version = "py312"
39
+
40
+ [tool.ruff.lint]
41
+ select = [
42
+ "E",
43
+ "F",
44
+ "I",
45
+ "UP",
46
+ ]
47
+
48
+ [tool.mypy]
49
+ python_version = "3.12"
50
+ strict = true
51
+
52
+ [tool.uv.build-backend]
53
+ module-name = [
54
+ "hundredflags_sdk",
55
+ "ai_security_school_sdk",
56
+ ]
57
+
58
+ [build-system]
59
+ requires = ["uv_build>=0.12.5,<0.13.0"]
60
+ build-backend = "uv_build"
@@ -0,0 +1,45 @@
1
+ [project]
2
+ name = "hundredflags-sdk"
3
+ version = "0.4.0"
4
+ description = "Python client for HundredFlags agent environment documentation and actions"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "germankochnev", email = "kochgerm@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "httpx>=0.28,<1",
12
+ "pydantic>=2.10,<3",
13
+ "jsonschema>=4.23,<5",
14
+ "referencing>=0.35,<1",
15
+ ]
16
+
17
+ [project.urls]
18
+ Homepage = "https://github.com/ai-security-lab-itmo/hundredflags-sdk"
19
+ Documentation = "https://github.com/ai-security-lab-itmo/hundredflags-sdk#readme"
20
+ Issues = "https://github.com/ai-security-lab-itmo/hundredflags-sdk/issues"
21
+
22
+ [dependency-groups]
23
+ dev = ["pytest>=8.3,<9", "pytest-asyncio>=0.25,<2", "ruff>=0.9,<1", "mypy>=1.15,<2", "types-jsonschema>=4.23"]
24
+
25
+ [tool.pytest.ini_options]
26
+ asyncio_mode = "auto"
27
+ testpaths = ["tests"]
28
+
29
+ [tool.ruff]
30
+ line-length = 100
31
+ target-version = "py312"
32
+
33
+ [tool.ruff.lint]
34
+ select = ["E", "F", "I", "UP"]
35
+
36
+ [tool.mypy]
37
+ python_version = "3.12"
38
+ strict = true
39
+
40
+ [build-system]
41
+ requires = ["uv_build>=0.12.5,<0.13.0"]
42
+ build-backend = "uv_build"
43
+
44
+ [tool.uv.build-backend]
45
+ module-name = ["hundredflags_sdk", "ai_security_school_sdk"]
@@ -0,0 +1,62 @@
1
+ """Compatibility imports; use :mod:`hundredflags_sdk` for new code."""
2
+
3
+ from hundredflags_sdk import (
4
+ ActionDescriptor as ActionDescriptor,
5
+ )
6
+ from hundredflags_sdk import (
7
+ ActionValidationError as ActionValidationError,
8
+ )
9
+ from hundredflags_sdk import (
10
+ APIError as APIError,
11
+ )
12
+ from hundredflags_sdk import (
13
+ AsyncClient as AsyncClient,
14
+ )
15
+ from hundredflags_sdk import (
16
+ AuthenticationError as AuthenticationError,
17
+ )
18
+ from hundredflags_sdk import (
19
+ Client as Client,
20
+ )
21
+ from hundredflags_sdk import (
22
+ ConfigurationError as ConfigurationError,
23
+ )
24
+ from hundredflags_sdk import (
25
+ ConflictError as ConflictError,
26
+ )
27
+ from hundredflags_sdk import (
28
+ InstanceDocumentation as InstanceDocumentation,
29
+ )
30
+ from hundredflags_sdk import (
31
+ LimitExceededError as LimitExceededError,
32
+ )
33
+ from hundredflags_sdk import (
34
+ NotFoundError as NotFoundError,
35
+ )
36
+ from hundredflags_sdk import (
37
+ PermissionDeniedError as PermissionDeniedError,
38
+ )
39
+ from hundredflags_sdk import (
40
+ ProtocolError as ProtocolError,
41
+ )
42
+ from hundredflags_sdk import (
43
+ RuntimeResponse as RuntimeResponse,
44
+ )
45
+ from hundredflags_sdk import (
46
+ SDKError as SDKError,
47
+ )
48
+ from hundredflags_sdk import (
49
+ TaskDocumentation as TaskDocumentation,
50
+ )
51
+ from hundredflags_sdk import (
52
+ TaskSummary as TaskSummary,
53
+ )
54
+ from hundredflags_sdk import (
55
+ TransportError as TransportError,
56
+ )
57
+ from hundredflags_sdk import (
58
+ __all__ as __all__,
59
+ )
60
+ from hundredflags_sdk import (
61
+ __version__ as __version__,
62
+ )
@@ -0,0 +1,23 @@
1
+ """Compatibility imports; use :mod:`hundredflags_sdk.async_client` for new code."""
2
+
3
+ from hundredflags_sdk.async_client import (
4
+ AsyncActions as AsyncActions,
5
+ )
6
+ from hundredflags_sdk.async_client import (
7
+ AsyncClient as AsyncClient,
8
+ )
9
+ from hundredflags_sdk.async_client import (
10
+ AsyncEnvironmentResource as AsyncEnvironmentResource,
11
+ )
12
+ from hundredflags_sdk.async_client import (
13
+ AsyncEnvironments as AsyncEnvironments,
14
+ )
15
+ from hundredflags_sdk.async_client import (
16
+ AsyncEnvironmentTasks as AsyncEnvironmentTasks,
17
+ )
18
+ from hundredflags_sdk.async_client import (
19
+ AsyncTaskResource as AsyncTaskResource,
20
+ )
21
+ from hundredflags_sdk.async_client import (
22
+ AsyncTasks as AsyncTasks,
23
+ )