адаптация для установки пакетом
This commit is contained in:
parent
a5ef5abac7
commit
b34cbaf677
9 changed files with 260 additions and 258 deletions
243
README.md
243
README.md
|
|
@ -1,7 +1,238 @@
|
||||||
## Contributing
|
# Lambda Agent API
|
||||||
|
|
||||||
- В качестве таск-трекера - раздел "Задачи" (Issues).
|
WebSocket API SDK для взаимодействия с AI-агентом.
|
||||||
- В названии коммита обязательно указывать ID задачи. Пример: "#1 Описание коммита"
|
|
||||||
- При закрытии задачи в комментарии делать ссылку на PR.
|
## Установка
|
||||||
- Одна задача, одна ветка, один PR.
|
|
||||||
- Формат названия ветки: #<ID задачи>-<короткое описание>. Пример: "#1-task-description".
|
```bash
|
||||||
|
pip install .
|
||||||
|
```
|
||||||
|
|
||||||
|
Требуется Python 3.14+.
|
||||||
|
|
||||||
|
## Быстрый старт (с использованием AgentApi)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
from lambda_agent_api.agent_api import AgentApi, OM
|
||||||
|
|
||||||
|
|
||||||
|
def my_callback(message):
|
||||||
|
if isinstance(message, OM.Error):
|
||||||
|
print(f"\n[Ошибка: {message.code}] {message.details}")
|
||||||
|
elif isinstance(message, OM.Status):
|
||||||
|
print("✓ Agent status update")
|
||||||
|
elif isinstance(message, OM.GracefulDisconnect):
|
||||||
|
print("✓ Agent gracefully requested disconnect")
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
api = AgentApi("agent-1", "ws://localhost:8000/ws", callback=my_callback)
|
||||||
|
|
||||||
|
await api.connect()
|
||||||
|
try:
|
||||||
|
response = await api.send_message("Привет, агент!")
|
||||||
|
|
||||||
|
async for chunk in response:
|
||||||
|
if isinstance(chunk, OM.EventTextChunk):
|
||||||
|
print(chunk.text, end="", flush=True)
|
||||||
|
|
||||||
|
# После окончания Generation возможно получить EventEnd в очереди и сохранить tokens
|
||||||
|
# (в current implementation: `response` - генератор, для токенов смотрите `EventEnd` в callback)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
await api.close()
|
||||||
|
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
|
```
|
||||||
|
|
||||||
|
## AgentApi - Асинхронный Python клиент
|
||||||
|
|
||||||
|
Новая библиотека `AgentApi` предоставляет типизированный асинхронный клиент для WebSocket взаимодействия с агентом.
|
||||||
|
|
||||||
|
### Характеристики
|
||||||
|
|
||||||
|
- ✅ **Асинхронный клиент** на основе `aiohttp`
|
||||||
|
- ✅ **Явное подключение/закрытие** через `connect()`/`close()`
|
||||||
|
- ✅ **Защита от параллельных запросов** через `AgentBusyException`
|
||||||
|
- ✅ **ResponseIterator** для асинхронной итерации по чанкам ответа
|
||||||
|
- ✅ **Callback** для обработки событий вне генерации ответа (`Status`, `Error`, `GracefulDisconnect`)
|
||||||
|
- ✅ **Типизированные сообщения** через Pydantic с дискриминированными объединениями
|
||||||
|
- ✅ **Обработка ошибок** с кастомным исключением `AgentException`
|
||||||
|
- ✅ **Логирование** на всех уровнях операций
|
||||||
|
- ✅ **Полная документация** всех методов
|
||||||
|
|
||||||
|
### Использование
|
||||||
|
|
||||||
|
```python
|
||||||
|
from lambda_agent_api.agent_api import AgentApi, OM
|
||||||
|
|
||||||
|
api = AgentApi("agent-1", "ws://localhost:8000/ws", callback=my_callback)
|
||||||
|
|
||||||
|
await api.connect()
|
||||||
|
try:
|
||||||
|
response = await api.send_message("Your question here")
|
||||||
|
|
||||||
|
async for chunk in response:
|
||||||
|
if isinstance(chunk, OM.EventTextChunk):
|
||||||
|
print(chunk.text, end="", flush=True)
|
||||||
|
|
||||||
|
print("\nDone!")
|
||||||
|
finally:
|
||||||
|
await api.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
# Обработка ошибок
|
||||||
|
|
||||||
|
- `AgentBusyException` возникает, если отправить `send_message` пока предыдущий запрос ещё в процессе.
|
||||||
|
- `AgentException` возникает, если агент возвращает `ERROR` или есть проблемы с подключением.
|
||||||
|
- `on_disconnect` callback вызывается один раз при закрытии/разрыве соединения.
|
||||||
|
|
||||||
|
Callback функция для обработки событий вне генерации:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def my_callback(message):
|
||||||
|
if isinstance(message, OM.Status):
|
||||||
|
print("Agent status update")
|
||||||
|
elif isinstance(message, OM.Error):
|
||||||
|
print(f"Agent error: {message.code} - {message.details}")
|
||||||
|
elif isinstance(message, OM.GracefulDisconnect):
|
||||||
|
print("Agent disconnecting gracefully")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Классический подход (низкоуровневый)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
import websockets
|
||||||
|
from lambda_agent_api.models import ServerMessage, OM
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
uri = "ws://localhost:8000/ws"
|
||||||
|
|
||||||
|
async with websockets.connect(uri) as ws:
|
||||||
|
# 1. Ждём STATUS - подтверждение готовности
|
||||||
|
status = await ws.recv()
|
||||||
|
print(f"Connected: {status}")
|
||||||
|
|
||||||
|
# 2. Отправляем сообщение
|
||||||
|
await ws.send('{"type": "USER_MESSAGE", "text": "Привет!"}')
|
||||||
|
|
||||||
|
# 3. Читаем ответ в виде потока событий
|
||||||
|
while True:
|
||||||
|
msg = await ws.recv()
|
||||||
|
data = ServerMessage.model_validate_json(msg)
|
||||||
|
|
||||||
|
match data:
|
||||||
|
case OM.AgentEvent(subtype=OM.AgentEventType.TEXT_CHUNK):
|
||||||
|
print(data.text, end="", flush=True)
|
||||||
|
case OM.EventEnd():
|
||||||
|
print(f"\n[Завершено, использовано токенов: {data.tokens_used}]")
|
||||||
|
break
|
||||||
|
case OM.Error():
|
||||||
|
print(f"\n[Ошибка: {data.code}] {data.details}")
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
|
```
|
||||||
|
|
||||||
|
## Протокол
|
||||||
|
|
||||||
|
### Клиент → Сервер
|
||||||
|
|
||||||
|
#### USER_MESSAGE
|
||||||
|
|
||||||
|
Полное сообщение от пользователя.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "USER_MESSAGE",
|
||||||
|
"text": "Текст сообщения"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|------|-------|-------------------|
|
||||||
|
| type | string | Всегда `USER_MESSAGE` |
|
||||||
|
| text | string | Текст сообщения |
|
||||||
|
|
||||||
|
### Сервер → Клиент
|
||||||
|
|
||||||
|
#### STATUS
|
||||||
|
|
||||||
|
Отправляется сервером при открытии соединения с клиентом. Будет дополнен информацией о готовности агента принимать сообщения.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "STATUS"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### AGENT_EVENT
|
||||||
|
|
||||||
|
Базовый класс для ивентов, которые стримит агент во время генерации ответа. Конкретный класс для ивента определяется по `subtype`.
|
||||||
|
|
||||||
|
##### TEXT_CHUNK
|
||||||
|
|
||||||
|
Чанк текста ответа агента.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "AGENT_EVENT",
|
||||||
|
"subtype": "TEXT_CHUNK",
|
||||||
|
"text": "Фрагмент текста"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### END
|
||||||
|
|
||||||
|
Агент закончил генерацию ответа.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "AGENT_EVENT",
|
||||||
|
"subtype": "END",
|
||||||
|
"tokens_used": 42
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|-------------|--------|-----------------------|
|
||||||
|
| tokens_used | int | Количество использованных токенов |
|
||||||
|
|
||||||
|
#### ERROR
|
||||||
|
|
||||||
|
Неопределенная ошибка в работе агента.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "ERROR",
|
||||||
|
"code": "error_code",
|
||||||
|
"details": "Описание ошибки"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Поле | Тип | Описание |
|
||||||
|
|---------|-------|----------------|
|
||||||
|
| code | string | Код ошибки |
|
||||||
|
| details | string | Подробности |
|
||||||
|
|
||||||
|
#### GRACEFUL_DISCONNECT
|
||||||
|
|
||||||
|
Отправляется перед завершением работы контейнера с агентом. Например, при долгом бездействии. Нужно, чтобы отделять обрыв соединения из-за ошибки с необходимостью повторного подключения. Приход этого сообщения означает, что агент осознанно завершает работу с клиентом по какой-то причине. Для дальнейшего взаимодействия нужно снова обратиться к мастеру.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "GRACEFUL_DISCONNECT"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
- Python 3.14+
|
||||||
|
- pydantic >= 2.12.5
|
||||||
|
|
|
||||||
233
api/README.md
233
api/README.md
|
|
@ -1,233 +0,0 @@
|
||||||
# Lambda Agent API
|
|
||||||
|
|
||||||
WebSocket API SDK для взаимодействия с AI-агентом.
|
|
||||||
|
|
||||||
## Установка
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install .
|
|
||||||
```
|
|
||||||
|
|
||||||
Требуется Python 3.14+.
|
|
||||||
|
|
||||||
## Быстрый старт (с использованием AgentApi)
|
|
||||||
|
|
||||||
```python
|
|
||||||
import asyncio
|
|
||||||
from agent_api import AgentApi, OM
|
|
||||||
|
|
||||||
def my_callback(message):
|
|
||||||
if isinstance(message, OM.Error):
|
|
||||||
print(f"\n[Ошибка: {message.code}] {message.details}")
|
|
||||||
elif isinstance(message, OM.Status):
|
|
||||||
print("✓ Agent status update")
|
|
||||||
elif isinstance(message, OM.GracefulDisconnect):
|
|
||||||
print("✓ Agent gracefully requested disconnect")
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
api = AgentApi("agent-1", "ws://localhost:8000/ws", callback=my_callback)
|
|
||||||
|
|
||||||
await api.connect()
|
|
||||||
try:
|
|
||||||
response = await api.send_message("Привет, агент!")
|
|
||||||
|
|
||||||
async for chunk in response:
|
|
||||||
if isinstance(chunk, OM.EventTextChunk):
|
|
||||||
print(chunk.text, end="", flush=True)
|
|
||||||
|
|
||||||
# После окончания Generation возможно получить EventEnd в очереди и сохранить tokens
|
|
||||||
# (в current implementation: `response` - генератор, для токенов смотрите `EventEnd` в callback)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
await api.close()
|
|
||||||
|
|
||||||
asyncio.run(main())
|
|
||||||
```
|
|
||||||
|
|
||||||
## AgentApi - Асинхронный Python клиент
|
|
||||||
|
|
||||||
Новая библиотека `AgentApi` предоставляет типизированный асинхронный клиент для WebSocket взаимодействия с агентом.
|
|
||||||
|
|
||||||
### Характеристики
|
|
||||||
|
|
||||||
- ✅ **Асинхронный клиент** на основе `aiohttp`
|
|
||||||
- ✅ **Явное подключение/закрытие** через `connect()`/`close()`
|
|
||||||
- ✅ **Защита от параллельных запросов** через `AgentBusyException`
|
|
||||||
- ✅ **ResponseIterator** для асинхронной итерации по чанкам ответа
|
|
||||||
- ✅ **Callback** для обработки событий вне генерации ответа (`Status`, `Error`, `GracefulDisconnect`)
|
|
||||||
- ✅ **Типизированные сообщения** через Pydantic с дискриминированными объединениями
|
|
||||||
- ✅ **Обработка ошибок** с кастомным исключением `AgentException`
|
|
||||||
- ✅ **Логирование** на всех уровнях операций
|
|
||||||
- ✅ **Полная документация** всех методов
|
|
||||||
|
|
||||||
### Использование
|
|
||||||
|
|
||||||
```python
|
|
||||||
from agent_api import AgentApi, OM
|
|
||||||
|
|
||||||
api = AgentApi("agent-1", "ws://localhost:8000/ws", callback=my_callback)
|
|
||||||
|
|
||||||
await api.connect()
|
|
||||||
try:
|
|
||||||
response = await api.send_message("Your question here")
|
|
||||||
|
|
||||||
async for chunk in response:
|
|
||||||
if isinstance(chunk, OM.EventTextChunk):
|
|
||||||
print(chunk.text, end="", flush=True)
|
|
||||||
|
|
||||||
print("\nDone!")
|
|
||||||
finally:
|
|
||||||
await api.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
# Обработка ошибок
|
|
||||||
|
|
||||||
- `AgentBusyException` возникает, если отправить `send_message` пока предыдущий запрос ещё в процессе.
|
|
||||||
- `AgentException` возникает, если агент возвращает `ERROR` или есть проблемы с подключением.
|
|
||||||
- `on_disconnect` callback вызывается один раз при закрытии/разрыве соединения.
|
|
||||||
|
|
||||||
Callback функция для обработки событий вне генерации:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def my_callback(message):
|
|
||||||
if isinstance(message, OM.Status):
|
|
||||||
print("Agent status update")
|
|
||||||
elif isinstance(message, OM.Error):
|
|
||||||
print(f"Agent error: {message.code} - {message.details}")
|
|
||||||
elif isinstance(message, OM.GracefulDisconnect):
|
|
||||||
print("Agent disconnecting gracefully")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Классический подход (низкоуровневый)
|
|
||||||
|
|
||||||
```python
|
|
||||||
import asyncio
|
|
||||||
import websockets
|
|
||||||
from models import ServerMessage, OM
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
uri = "ws://localhost:8000/ws"
|
|
||||||
|
|
||||||
async with websockets.connect(uri) as ws:
|
|
||||||
# 1. Ждём STATUS - подтверждение готовности
|
|
||||||
status = await ws.recv()
|
|
||||||
print(f"Connected: {status}")
|
|
||||||
|
|
||||||
# 2. Отправляем сообщение
|
|
||||||
await ws.send('{"type": "USER_MESSAGE", "text": "Привет!"}')
|
|
||||||
|
|
||||||
# 3. Читаем ответ в виде потока событий
|
|
||||||
while True:
|
|
||||||
msg = await ws.recv()
|
|
||||||
data = ServerMessage.model_validate_json(msg)
|
|
||||||
|
|
||||||
match data:
|
|
||||||
case OM.AgentEvent(subtype=OM.AgentEventType.TEXT_CHUNK):
|
|
||||||
print(data.text, end="", flush=True)
|
|
||||||
case OM.EventEnd():
|
|
||||||
print(f"\n[Завершено, использовано токенов: {data.tokens_used}]")
|
|
||||||
break
|
|
||||||
case OM.Error():
|
|
||||||
print(f"\n[Ошибка: {data.code}] {data.details}")
|
|
||||||
break
|
|
||||||
|
|
||||||
asyncio.run(main())
|
|
||||||
```
|
|
||||||
|
|
||||||
## Протокол
|
|
||||||
|
|
||||||
### Клиент → Сервер
|
|
||||||
|
|
||||||
#### USER_MESSAGE
|
|
||||||
|
|
||||||
Полное сообщение от пользователя.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "USER_MESSAGE",
|
|
||||||
"text": "Текст сообщения"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
|
||||||
|------|-------|-------------------|
|
|
||||||
| type | string | Всегда `USER_MESSAGE` |
|
|
||||||
| text | string | Текст сообщения |
|
|
||||||
|
|
||||||
### Сервер → Клиент
|
|
||||||
|
|
||||||
#### STATUS
|
|
||||||
|
|
||||||
Отправляется сервером при открытии соединения с клиентом. Будет дополнен информацией о готовности агента принимать сообщения.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "STATUS"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### AGENT_EVENT
|
|
||||||
|
|
||||||
Базовый класс для ивентов, которые стримит агент во время генерации ответа. Конкретный класс для ивента определяется по `subtype`.
|
|
||||||
|
|
||||||
##### TEXT_CHUNK
|
|
||||||
|
|
||||||
Чанк текста ответа агента.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "AGENT_EVENT",
|
|
||||||
"subtype": "TEXT_CHUNK",
|
|
||||||
"text": "Фрагмент текста"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### END
|
|
||||||
|
|
||||||
Агент закончил генерацию ответа.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "AGENT_EVENT",
|
|
||||||
"subtype": "END",
|
|
||||||
"tokens_used": 42
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
|
||||||
|-------------|--------|-----------------------|
|
|
||||||
| tokens_used | int | Количество использованных токенов |
|
|
||||||
|
|
||||||
#### ERROR
|
|
||||||
|
|
||||||
Неопределенная ошибка в работе агента.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "ERROR",
|
|
||||||
"code": "error_code",
|
|
||||||
"details": "Описание ошибки"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
|
||||||
|---------|-------|----------------|
|
|
||||||
| code | string | Код ошибки |
|
|
||||||
| details | string | Подробности |
|
|
||||||
|
|
||||||
#### GRACEFUL_DISCONNECT
|
|
||||||
|
|
||||||
Отправляется перед завершением работы контейнера с агентом. Например, при долгом бездействии. Нужно, чтобы отделять обрыв соединения из-за ошибки с необходимостью повторного подключения. Приход этого сообщения означает, что агент осознанно завершает работу с клиентом по какой-то причине. Для дальнейшего взаимодействия нужно снова обратиться к мастеру.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"type": "GRACEFUL_DISCONNECT"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Зависимости
|
|
||||||
|
|
||||||
- Python 3.14+
|
|
||||||
- pydantic >= 2.12.5
|
|
||||||
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
|
|
@ -7,8 +7,8 @@
|
||||||
- IM, OM, IncomingMessage, OutgoingMessage: Pydantic модели контракта
|
- IM, OM, IncomingMessage, OutgoingMessage: Pydantic модели контракта
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .agent_api import AgentApi, AgentException
|
from lambda_agent_api.agent_api import AgentApi, AgentException
|
||||||
from .models import CM, SM, ClientMessage, ServerMessage
|
from lambda_agent_api.models import CM, SM, ClientMessage, ServerMessage
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"AgentApi",
|
"AgentApi",
|
||||||
|
|
@ -2,7 +2,8 @@ import logging
|
||||||
from typing import Callable, Optional, AsyncIterator
|
from typing import Callable, Optional, AsyncIterator
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
from models import CM, SM, ClientMessage, ServerMessage
|
|
||||||
|
from lambda_agent_api.models import CM, SM, ClientMessage, ServerMessage
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[project]
|
[project]
|
||||||
name = "api"
|
name = "lambda_agent_api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "WebSocket API SDK для взаимодействия с AI-агентом"
|
description = "WebSocket API SDK для взаимодействия с AI-агентом"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
@ -8,3 +8,6 @@ dependencies = [
|
||||||
"aiohttp>=3.13.4",
|
"aiohttp>=3.13.4",
|
||||||
"pydantic>=2.12.5",
|
"pydantic>=2.12.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
packages = ["lambda_agent_api"]
|
||||||
30
api/uv.lock → uv.lock
generated
30
api/uv.lock → uv.lock
generated
|
|
@ -83,21 +83,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "api"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = { virtual = "." }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "aiohttp" },
|
|
||||||
{ name = "pydantic" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
requires-dist = [
|
|
||||||
{ name = "aiohttp", specifier = ">=3.13.4" },
|
|
||||||
{ name = "pydantic", specifier = ">=2.12.5" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "26.1.0"
|
version = "26.1.0"
|
||||||
|
|
@ -157,6 +142,21 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lambda-agent-api"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { virtual = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "aiohttp" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "aiohttp", specifier = ">=3.13.4" },
|
||||||
|
{ name = "pydantic", specifier = ">=2.12.5" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multidict"
|
name = "multidict"
|
||||||
version = "6.7.1"
|
version = "6.7.1"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue