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