cortex-agent-sdk 0.1.0__tar.gz → 0.2.1__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.
Files changed (55) hide show
  1. cortex_agent_sdk-0.2.1/PKG-INFO +177 -0
  2. cortex_agent_sdk-0.2.1/README.md +151 -0
  3. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/pyproject.toml +5 -18
  4. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/__init__.py +5 -0
  5. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/src/cortex_agent_sdk/errores/__init__.py +2 -0
  6. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/errores/catalogo.py +18 -0
  7. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/src/cortex_agent_sdk/errores/excepcion.py +1 -4
  8. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/src/cortex_agent_sdk/redis/__init__.py +2 -0
  9. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/src/cortex_agent_sdk/redis/scripts.py +3 -18
  10. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/redis/store.py +355 -0
  11. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/sessions/__init__.py +5 -0
  12. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/sessions/codec.py +16 -0
  13. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/sessions/memory.py +132 -0
  14. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/sessions/models.py +21 -0
  15. cortex_agent_sdk-0.2.1/src/cortex_agent_sdk/sessions/store.py +17 -0
  16. cortex_agent_sdk-0.1.0/PKG-INFO +0 -139
  17. cortex_agent_sdk-0.1.0/README.md +0 -105
  18. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/__init__.py +0 -16
  19. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/agent.py +0 -712
  20. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/control.py +0 -159
  21. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/engine.py +0 -154
  22. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/errores/catalogo.py +0 -35
  23. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/gateway.py +0 -22
  24. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/google/__init__.py +0 -1
  25. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/history/__init__.py +0 -2
  26. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/history/models.py +0 -154
  27. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/history/pipeline.py +0 -53
  28. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/history/transform.py +0 -16
  29. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/hooks.py +0 -102
  30. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/immutable.py +0 -75
  31. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/lifecycle.py +0 -67
  32. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/openai/__init__.py +0 -3
  33. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/openai/engine.py +0 -311
  34. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/openai/models.py +0 -57
  35. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/openai/options.py +0 -19
  36. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/postgres/__init__.py +0 -1
  37. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/postgres/store.py +0 -468
  38. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/redis/store.py +0 -308
  39. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/results.py +0 -34
  40. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/runtime.py +0 -39
  41. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/__init__.py +0 -4
  42. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/codec.py +0 -27
  43. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/lease.py +0 -85
  44. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/memory.py +0 -186
  45. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/models.py +0 -70
  46. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/sessions/store.py +0 -38
  47. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/__init__.py +0 -1
  48. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/approval.py +0 -20
  49. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/contracts.py +0 -323
  50. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/decorators.py +0 -151
  51. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/execution.py +0 -233
  52. cortex_agent_sdk-0.1.0/src/cortex_agent_sdk/tools/models.py +0 -81
  53. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/.gitignore +0 -0
  54. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/LICENSE +0 -0
  55. {cortex_agent_sdk-0.1.0 → cortex_agent_sdk-0.2.1}/src/cortex_agent_sdk/py.typed +0 -0
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: cortex-agent-sdk
3
+ Version: 0.2.1
4
+ Summary: Sesiones Memory y Redis para agentes multiprovider con Pydantic AI
5
+ Project-URL: Repository, https://github.com/epok200/cortex_agent_sdk
6
+ Project-URL: Issues, https://github.com/epok200/cortex_agent_sdk/issues
7
+ Author: EPOK
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE
10
+ Keywords: agents,pydantic-ai,redis,sessions
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.13
19
+ Requires-Dist: pydantic-ai-slim[google,openai]<3,>=2.27
20
+ Provides-Extra: all
21
+ Requires-Dist: redis>=8.1.0; extra == 'all'
22
+ Provides-Extra: openai
23
+ Provides-Extra: redis
24
+ Requires-Dist: redis>=8.1.0; extra == 'redis'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # Cortex Agent SDK
28
+
29
+ Cortex agrega sesiones Memory y Redis a agentes multiprovider construidos directamente con
30
+ Pydantic AI.
31
+
32
+ No implementa otro loop, otra capa de tools ni otra API de agentes. Pydantic AI conserva el control
33
+ de providers, modelos, tools, tipado, `RunContext`, hooks, límites, approvals, outputs, usage e
34
+ historial. Cortex sólo cubre la pieza que Pydantic AI no incluye: persistencia conversacional con un
35
+ turno activo por sesión.
36
+
37
+ > Cortex Agent SDK está en alfa. La API puede cambiar antes de la versión `1.0.0`.
38
+
39
+ ## Requisitos
40
+
41
+ - Python `>=3.13`.
42
+ - Pydantic AI `>=2.27,<3`, con Google y OpenAI instalados por Cortex.
43
+
44
+ ## Instalación
45
+
46
+ Google, OpenAI y sesiones en memoria:
47
+
48
+ ```bash
49
+ uv add cortex-agent-sdk
50
+ ```
51
+
52
+ Google, OpenAI y Redis:
53
+
54
+ ```bash
55
+ uv add "cortex-agent-sdk[redis]"
56
+ ```
57
+
58
+ La instalación base incluye Google y OpenAI, además de los endpoints compatibles con OpenAI. Otros
59
+ providers pueden agregarse desde los extras oficiales de Pydantic AI cuando un producto realmente
60
+ los necesite. Cortex no implementa adapters paralelos.
61
+
62
+ ## Uso
63
+
64
+ El agente es el `Agent` nativo de Pydantic AI. El store entrega el historial bajo exclusión y lo
65
+ guarda cuando `session.replace(...)` marca un resultado completo.
66
+
67
+ ```python
68
+ import asyncio
69
+
70
+ from pydantic_ai import Agent
71
+
72
+ from cortex_agent_sdk.sessions import MemorySessionStore
73
+
74
+
75
+ async def main() -> None:
76
+ agent = Agent("openai-responses:gpt-5.6-luna")
77
+ sessions = MemorySessionStore()
78
+
79
+ async with agent, sessions:
80
+ async with sessions.turn("usuario:42") as session:
81
+ result = await agent.run(
82
+ "Recuerda que mi color favorito es verde.",
83
+ message_history=session.messages,
84
+ conversation_id=session.session_id,
85
+ )
86
+ session.replace(result.all_messages())
87
+
88
+ print(result.output)
89
+
90
+
91
+ asyncio.run(main())
92
+ ```
93
+
94
+ `replace()` es explícito por diseño:
95
+
96
+ - Si no se llama, el store no modifica el historial.
97
+ - Si el bloque termina con una excepción, el store no guarda el reemplazo.
98
+ - Si guardar falla, la excepción se propaga.
99
+
100
+ ## Redis
101
+
102
+ ```python
103
+ from cortex_agent_sdk.redis import RedisSessionStore
104
+
105
+ sessions = RedisSessionStore(
106
+ "redis://localhost:6379/0",
107
+ key_prefix="mi-producto:sesiones:v1",
108
+ ttl_seconds=86_400,
109
+ )
110
+ ```
111
+
112
+ Redis mantiene un lease renovable durante todo el turno. Mientras conserva el lease, dos procesos no
113
+ pueden usar la misma sesión al mismo tiempo y las sesiones distintas siguen siendo concurrentes. Si
114
+ la renovación falla, Cortex interrumpe el turno propietario y no guarda como owner obsoleto. El
115
+ historial se serializa con `ModelMessagesTypeAdapter`, el formato público de Pydantic AI.
116
+
117
+ Al cambiar desde el runtime anterior, usa un prefix nuevo. Los formatos no son compatibles y Cortex
118
+ no intenta convertir el historial legacy.
119
+
120
+ ## Endpoint compatible con OpenAI
121
+
122
+ Pydantic AI puede conectarse directamente. Para un endpoint que no debe reintentar peticiones,
123
+ configura el provider una vez:
124
+
125
+ ```python
126
+ from pydantic_ai import Agent
127
+ from pydantic_ai.models.openai import OpenAIResponsesModel
128
+ from pydantic_ai.providers.openai import OpenAIProvider
129
+
130
+ provider = OpenAIProvider(
131
+ base_url="https://example.com/v1",
132
+ api_key="...",
133
+ )
134
+ provider.client.max_retries = 0
135
+ model = OpenAIResponsesModel("gpt-5.6-luna", provider=provider)
136
+ agent = Agent(model)
137
+ ```
138
+
139
+ El context manager de `Agent` administra el transporte del provider.
140
+
141
+ ## Migración desde el runtime anterior
142
+
143
+ | Antes | Ahora |
144
+ |---|---|
145
+ | `cortex_agent_sdk.Agent` | `pydantic_ai.Agent` |
146
+ | `OpenAIEngine` | `OpenAIResponsesModel` + `OpenAIProvider` |
147
+ | `OpenAICompatibleGateway` | `OpenAIProvider(base_url=..., api_key=...)` |
148
+ | `OpenAIOptions` | `OpenAIResponsesModelSettings` y argumentos de `Agent.run` |
149
+ | `@tool` e `Injected` | tools nativas + `RunContext[Deps]` |
150
+ | `ToolBinding` | `FunctionToolset` o tools preparadas por run |
151
+ | `AgentHooks` | `pydantic_ai.capabilities.Hooks` |
152
+ | `turn_finished` | `Hooks(after_run=...)` |
153
+ | `history_transform` | `Hooks(before_model_request=...)` |
154
+ | `fallback_answer` | política local del producto sobre `AgentRunResult` |
155
+ | `AgentOptions` | `UsageLimits`, settings del modelo y argumentos de `Agent` |
156
+ | `AgentResult.text` | `AgentRunResult.output` |
157
+ | `SessionStore.acquire` | `SessionStore.turn` + `Session.replace` |
158
+ | `agent.reset_session(id)` | `store.reset(id)` |
159
+
160
+ No se ofrece una capa de compatibilidad. Mantenerla volvería a duplicar la API y el runtime de
161
+ Pydantic AI.
162
+
163
+ ## Superficie pública
164
+
165
+ - `cortex_agent_sdk.sessions.Session`
166
+ - `cortex_agent_sdk.sessions.SessionStore`
167
+ - `cortex_agent_sdk.sessions.MemorySessionStore`
168
+ - `cortex_agent_sdk.redis.RedisSessionStore`
169
+ - `cortex_agent_sdk.errores.AppError`
170
+ - `cortex_agent_sdk.errores.CodigoError`
171
+ - `cortex_agent_sdk.errores.Severidad`
172
+
173
+ El loop, tools, hooks, approvals, modelos y resultados se importan desde `pydantic_ai`.
174
+
175
+ ## Licencia
176
+
177
+ Apache License 2.0.
@@ -0,0 +1,151 @@
1
+ # Cortex Agent SDK
2
+
3
+ Cortex agrega sesiones Memory y Redis a agentes multiprovider construidos directamente con
4
+ Pydantic AI.
5
+
6
+ No implementa otro loop, otra capa de tools ni otra API de agentes. Pydantic AI conserva el control
7
+ de providers, modelos, tools, tipado, `RunContext`, hooks, límites, approvals, outputs, usage e
8
+ historial. Cortex sólo cubre la pieza que Pydantic AI no incluye: persistencia conversacional con un
9
+ turno activo por sesión.
10
+
11
+ > Cortex Agent SDK está en alfa. La API puede cambiar antes de la versión `1.0.0`.
12
+
13
+ ## Requisitos
14
+
15
+ - Python `>=3.13`.
16
+ - Pydantic AI `>=2.27,<3`, con Google y OpenAI instalados por Cortex.
17
+
18
+ ## Instalación
19
+
20
+ Google, OpenAI y sesiones en memoria:
21
+
22
+ ```bash
23
+ uv add cortex-agent-sdk
24
+ ```
25
+
26
+ Google, OpenAI y Redis:
27
+
28
+ ```bash
29
+ uv add "cortex-agent-sdk[redis]"
30
+ ```
31
+
32
+ La instalación base incluye Google y OpenAI, además de los endpoints compatibles con OpenAI. Otros
33
+ providers pueden agregarse desde los extras oficiales de Pydantic AI cuando un producto realmente
34
+ los necesite. Cortex no implementa adapters paralelos.
35
+
36
+ ## Uso
37
+
38
+ El agente es el `Agent` nativo de Pydantic AI. El store entrega el historial bajo exclusión y lo
39
+ guarda cuando `session.replace(...)` marca un resultado completo.
40
+
41
+ ```python
42
+ import asyncio
43
+
44
+ from pydantic_ai import Agent
45
+
46
+ from cortex_agent_sdk.sessions import MemorySessionStore
47
+
48
+
49
+ async def main() -> None:
50
+ agent = Agent("openai-responses:gpt-5.6-luna")
51
+ sessions = MemorySessionStore()
52
+
53
+ async with agent, sessions:
54
+ async with sessions.turn("usuario:42") as session:
55
+ result = await agent.run(
56
+ "Recuerda que mi color favorito es verde.",
57
+ message_history=session.messages,
58
+ conversation_id=session.session_id,
59
+ )
60
+ session.replace(result.all_messages())
61
+
62
+ print(result.output)
63
+
64
+
65
+ asyncio.run(main())
66
+ ```
67
+
68
+ `replace()` es explícito por diseño:
69
+
70
+ - Si no se llama, el store no modifica el historial.
71
+ - Si el bloque termina con una excepción, el store no guarda el reemplazo.
72
+ - Si guardar falla, la excepción se propaga.
73
+
74
+ ## Redis
75
+
76
+ ```python
77
+ from cortex_agent_sdk.redis import RedisSessionStore
78
+
79
+ sessions = RedisSessionStore(
80
+ "redis://localhost:6379/0",
81
+ key_prefix="mi-producto:sesiones:v1",
82
+ ttl_seconds=86_400,
83
+ )
84
+ ```
85
+
86
+ Redis mantiene un lease renovable durante todo el turno. Mientras conserva el lease, dos procesos no
87
+ pueden usar la misma sesión al mismo tiempo y las sesiones distintas siguen siendo concurrentes. Si
88
+ la renovación falla, Cortex interrumpe el turno propietario y no guarda como owner obsoleto. El
89
+ historial se serializa con `ModelMessagesTypeAdapter`, el formato público de Pydantic AI.
90
+
91
+ Al cambiar desde el runtime anterior, usa un prefix nuevo. Los formatos no son compatibles y Cortex
92
+ no intenta convertir el historial legacy.
93
+
94
+ ## Endpoint compatible con OpenAI
95
+
96
+ Pydantic AI puede conectarse directamente. Para un endpoint que no debe reintentar peticiones,
97
+ configura el provider una vez:
98
+
99
+ ```python
100
+ from pydantic_ai import Agent
101
+ from pydantic_ai.models.openai import OpenAIResponsesModel
102
+ from pydantic_ai.providers.openai import OpenAIProvider
103
+
104
+ provider = OpenAIProvider(
105
+ base_url="https://example.com/v1",
106
+ api_key="...",
107
+ )
108
+ provider.client.max_retries = 0
109
+ model = OpenAIResponsesModel("gpt-5.6-luna", provider=provider)
110
+ agent = Agent(model)
111
+ ```
112
+
113
+ El context manager de `Agent` administra el transporte del provider.
114
+
115
+ ## Migración desde el runtime anterior
116
+
117
+ | Antes | Ahora |
118
+ |---|---|
119
+ | `cortex_agent_sdk.Agent` | `pydantic_ai.Agent` |
120
+ | `OpenAIEngine` | `OpenAIResponsesModel` + `OpenAIProvider` |
121
+ | `OpenAICompatibleGateway` | `OpenAIProvider(base_url=..., api_key=...)` |
122
+ | `OpenAIOptions` | `OpenAIResponsesModelSettings` y argumentos de `Agent.run` |
123
+ | `@tool` e `Injected` | tools nativas + `RunContext[Deps]` |
124
+ | `ToolBinding` | `FunctionToolset` o tools preparadas por run |
125
+ | `AgentHooks` | `pydantic_ai.capabilities.Hooks` |
126
+ | `turn_finished` | `Hooks(after_run=...)` |
127
+ | `history_transform` | `Hooks(before_model_request=...)` |
128
+ | `fallback_answer` | política local del producto sobre `AgentRunResult` |
129
+ | `AgentOptions` | `UsageLimits`, settings del modelo y argumentos de `Agent` |
130
+ | `AgentResult.text` | `AgentRunResult.output` |
131
+ | `SessionStore.acquire` | `SessionStore.turn` + `Session.replace` |
132
+ | `agent.reset_session(id)` | `store.reset(id)` |
133
+
134
+ No se ofrece una capa de compatibilidad. Mantenerla volvería a duplicar la API y el runtime de
135
+ Pydantic AI.
136
+
137
+ ## Superficie pública
138
+
139
+ - `cortex_agent_sdk.sessions.Session`
140
+ - `cortex_agent_sdk.sessions.SessionStore`
141
+ - `cortex_agent_sdk.sessions.MemorySessionStore`
142
+ - `cortex_agent_sdk.redis.RedisSessionStore`
143
+ - `cortex_agent_sdk.errores.AppError`
144
+ - `cortex_agent_sdk.errores.CodigoError`
145
+ - `cortex_agent_sdk.errores.Severidad`
146
+
147
+ El loop, tools, hooks, approvals, modelos y resultados se importan desde `pydantic_ai`.
148
+
149
+ ## Licencia
150
+
151
+ Apache License 2.0.
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "cortex-agent-sdk"
3
- version = "0.1.0"
4
- description = "SDK async y multiproveedor para construir agentes con control explícito"
3
+ version = "0.2.1"
4
+ description = "Sesiones Memory y Redis para agentes multiprovider con Pydantic AI"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
7
7
  requires-python = ">=3.13"
8
8
  authors = [{ name = "EPOK" }]
9
- keywords = ["agents", "asyncio", "openai", "sdk"]
9
+ keywords = ["agents", "pydantic-ai", "redis", "sessions"]
10
10
  classifiers = [
11
11
  "Development Status :: 3 - Alpha",
12
12
  "Intended Audience :: Developers",
@@ -17,8 +17,7 @@ classifiers = [
17
17
  "Typing :: Typed",
18
18
  ]
19
19
  dependencies = [
20
- "jsonschema>=4.25,<5",
21
- "pydantic>=2.13,<3",
20
+ "pydantic-ai-slim[google,openai]>=2.27,<3",
22
21
  ]
23
22
 
24
23
  [project.urls]
@@ -26,28 +25,16 @@ Repository = "https://github.com/epok200/cortex_agent_sdk"
26
25
  Issues = "https://github.com/epok200/cortex_agent_sdk/issues"
27
26
 
28
27
  [project.optional-dependencies]
29
- openai = [
30
- "openai>=2.52,<3",
31
- ]
32
- gateway = [
33
- "openai>=2.52,<3",
34
- ]
28
+ openai = []
35
29
  all = [
36
- "asyncpg>=0.31.0",
37
- "openai>=2.52,<3",
38
30
  "redis>=8.1.0",
39
31
  ]
40
32
  redis = [
41
33
  "redis>=8.1.0",
42
34
  ]
43
- postgres = [
44
- "asyncpg>=0.31.0",
45
- ]
46
35
 
47
36
  [dependency-groups]
48
37
  dev = [
49
- "asyncpg>=0.31.0",
50
- "openai>=2.52,<3",
51
38
  "pyright>=1.1.408",
52
39
  "pytest>=9.0",
53
40
  "pytest-asyncio>=1.3",
@@ -0,0 +1,5 @@
1
+ from importlib.metadata import version as _package_version
2
+
3
+ __version__ = _package_version("cortex-agent-sdk")
4
+
5
+ __all__ = ["__version__"]
@@ -1,2 +1,4 @@
1
1
  from cortex_agent_sdk.errores.catalogo import CodigoError, Severidad
2
2
  from cortex_agent_sdk.errores.excepcion import AppError
3
+
4
+ __all__ = ["AppError", "CodigoError", "Severidad"]
@@ -0,0 +1,18 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class Severidad(StrEnum):
5
+ INFO = "INFO"
6
+ WARNING = "WARNING"
7
+ ERROR = "ERROR"
8
+ CRITICAL = "CRITICAL"
9
+
10
+
11
+ class CodigoError(StrEnum):
12
+ UNKNOWN = "UNKNOWN"
13
+ CONFIG_INVALIDA = "CONFIG_INVALIDA"
14
+ RECURSO_CERRADO = "RECURSO_CERRADO"
15
+ SESION_OCUPADA = "SESION_OCUPADA"
16
+ SESION_LEASE_PERDIDO = "SESION_LEASE_PERDIDO"
17
+ SESION_INVALIDA = "SESION_INVALIDA"
18
+ SESION_STORE_FALLO = "SESION_STORE_FALLO"
@@ -2,18 +2,15 @@ from cortex_agent_sdk.errores.catalogo import CodigoError, Severidad
2
2
 
3
3
 
4
4
  class AppError(Exception):
5
- """Error del SDK con código estable y mensaje seguro opcional."""
5
+ """Error de Cortex con código estable."""
6
6
 
7
7
  def __init__(
8
8
  self,
9
9
  codigo: CodigoError,
10
10
  detalle: str,
11
11
  severidad: Severidad = Severidad.ERROR,
12
- mensaje_seguro: str | None = None,
13
12
  ) -> None:
14
13
  self.codigo = codigo
15
14
  self.detalle = detalle
16
15
  self.severidad = severidad
17
- self.mensaje_seguro = mensaje_seguro
18
16
  super().__init__(f"[{codigo.value}] {detalle}")
19
-
@@ -1 +1,3 @@
1
1
  from cortex_agent_sdk.redis.store import RedisSessionStore
2
+
3
+ __all__ = ["RedisSessionStore"]
@@ -1,14 +1,5 @@
1
1
  ACQUIRE = """
2
- if redis.call('exists', KEYS[1]) == 0 then
3
- local token = redis.call('incr', KEYS[2])
4
- redis.call('psetex', KEYS[1], ARGV[2], ARGV[1] .. ':' .. token)
5
- return token
6
- end
7
- return 0
8
- """
9
-
10
- VERIFY = """
11
- if redis.call('get', KEYS[1]) == ARGV[1] then
2
+ if redis.call('set', KEYS[1], ARGV[1], 'NX', 'PX', ARGV[2]) then
12
3
  return 1
13
4
  end
14
5
  return 0
@@ -26,7 +17,7 @@ LOAD = """
26
17
  if redis.call('get', KEYS[1]) ~= ARGV[1] then
27
18
  return {0}
28
19
  end
29
- local payload = redis.call('hget', KEYS[2], 'payload')
20
+ local payload = redis.call('get', KEYS[2])
30
21
  if payload then
31
22
  redis.call('pexpire', KEYS[2], ARGV[2])
32
23
  return {1, payload}
@@ -38,12 +29,7 @@ SAVE = """
38
29
  if redis.call('get', KEYS[1]) ~= ARGV[1] then
39
30
  return 0
40
31
  end
41
- local current = tonumber(redis.call('hget', KEYS[2], 'version') or '0')
42
- if current ~= tonumber(ARGV[2]) then
43
- return -1
44
- end
45
- redis.call('hset', KEYS[2], 'version', ARGV[3], 'payload', ARGV[4])
46
- redis.call('pexpire', KEYS[2], ARGV[5])
32
+ redis.call('psetex', KEYS[2], ARGV[3], ARGV[2])
47
33
  return 1
48
34
  """
49
35
 
@@ -62,4 +48,3 @@ if redis.call('get', KEYS[1]) == ARGV[1] then
62
48
  end
63
49
  return 0
64
50
  """
65
-