agentkernel 0.2.7__tar.gz → 0.2.8__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 (88) hide show
  1. {agentkernel-0.2.7 → agentkernel-0.2.8}/PKG-INFO +5 -1
  2. {agentkernel-0.2.7 → agentkernel-0.2.8}/pyproject.toml +7 -1
  3. agentkernel-0.2.8/src/agentkernel/api/handler.py +304 -0
  4. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/cli/cli.py +5 -2
  5. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/base.py +44 -13
  6. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/config.py +22 -0
  7. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/service.py +10 -0
  8. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/adk/adk.py +76 -29
  9. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/openai/openai.py +79 -22
  10. agentkernel-0.2.8/src/agentkernel/instagram.py +8 -0
  11. agentkernel-0.2.8/src/agentkernel/integration/instagram/README.md +153 -0
  12. agentkernel-0.2.8/src/agentkernel/integration/instagram/__init__.py +14 -0
  13. agentkernel-0.2.8/src/agentkernel/integration/instagram/instagram_chat.py +324 -0
  14. agentkernel-0.2.8/src/agentkernel/integration/telegram/README.md +174 -0
  15. agentkernel-0.2.8/src/agentkernel/integration/telegram/__init__.py +10 -0
  16. agentkernel-0.2.8/src/agentkernel/integration/telegram/telegram_chat.py +299 -0
  17. agentkernel-0.2.8/src/agentkernel/telegram.py +8 -0
  18. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/adk.py +2 -3
  19. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/crewai.py +2 -3
  20. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/langgraph.py +2 -3
  21. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/openai.py +2 -3
  22. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/adk.py +6 -5
  23. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/crewai.py +6 -5
  24. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/langgraph.py +6 -5
  25. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/openai.py +6 -5
  26. agentkernel-0.2.7/src/agentkernel/api/handler.py +0 -131
  27. {agentkernel-0.2.7 → agentkernel-0.2.8}/README.md +0 -0
  28. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/__init__.py +0 -0
  29. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/adk.py +0 -0
  30. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/__init__.py +0 -0
  31. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/a2a/__init__.py +0 -0
  32. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/a2a/a2a.py +0 -0
  33. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/a2a/handler.py +0 -0
  34. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/http.py +0 -0
  35. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/mcp/__init__.py +0 -0
  36. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/api/mcp/akmcp.py +0 -0
  37. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/aws.py +0 -0
  38. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/cli/__init__.py +0 -0
  39. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/__init__.py +0 -0
  40. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/builder.py +0 -0
  41. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/hooks.py +0 -0
  42. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/model.py +0 -0
  43. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/module.py +0 -0
  44. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/runtime.py +0 -0
  45. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/__init__.py +0 -0
  46. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/base.py +0 -0
  47. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/dynamodb.py +0 -0
  48. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/in_memory.py +0 -0
  49. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/redis.py +0 -0
  50. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/session/serde.py +0 -0
  51. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/util/config_yaml_util.py +0 -0
  52. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/core/util/key_value_cache.py +0 -0
  53. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/crewai.py +0 -0
  54. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/deployment/__init__.py +0 -0
  55. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/deployment/aws/__init__.py +0 -0
  56. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/deployment/aws/aklambda.py +0 -0
  57. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/__init__.py +0 -0
  58. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/adk/__init__.py +0 -0
  59. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/crewai/__init__.py +0 -0
  60. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/crewai/crewai.py +0 -0
  61. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/langgraph/__init__.py +0 -0
  62. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/langgraph/langgraph.py +0 -0
  63. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/framework/openai/__init__.py +0 -0
  64. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/__init__.py +0 -0
  65. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/messenger/README.md +0 -0
  66. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/messenger/__init__.py +0 -0
  67. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/messenger/messenger_chat.py +0 -0
  68. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/slack/README.md +0 -0
  69. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/slack/__init__.py +0 -0
  70. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/slack/slack_chat.py +0 -0
  71. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/whatsapp/README.md +0 -0
  72. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/whatsapp/__init__.py +0 -0
  73. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/integration/whatsapp/whatsapp_chat.py +0 -0
  74. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/langgraph.py +0 -0
  75. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/mcp.py +0 -0
  76. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/messenger.py +0 -0
  77. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/openai.py +0 -0
  78. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/slack.py +0 -0
  79. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/test/__init__.py +0 -0
  80. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/test/test.py +0 -0
  81. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/__init__.py +0 -0
  82. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/base.py +0 -0
  83. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/__init__.py +0 -0
  84. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/langfuse/langfuse.py +0 -0
  85. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/__init__.py +0 -0
  86. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/openllmetry/openllmetry.py +0 -0
  87. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/trace/trace.py +0 -0
  88. {agentkernel-0.2.7 → agentkernel-0.2.8}/src/agentkernel/whatsapp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: agentkernel
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: Agent Kernel - Unified AI Agents Runtime
5
5
  Author: Yaala Labs
6
6
  Author-email: Yaala Labs <agentkernel@yaalalabs.com>
@@ -21,6 +21,7 @@ Requires-Dist: boto3>=1.41.4 ; extra == 'aws'
21
21
  Requires-Dist: crewai>=0.150.0 ; extra == 'crewai'
22
22
  Requires-Dist: openinference-instrumentation-crewai>=0.1.16 ; extra == 'crewai'
23
23
  Requires-Dist: openinference-instrumentation-litellm>=0.1.28 ; extra == 'crewai'
24
+ Requires-Dist: httpx>=0.27.0 ; extra == 'instagram'
24
25
  Requires-Dist: langfuse>=3.9.2 ; extra == 'langfuse'
25
26
  Requires-Dist: nest-asyncio>=1.6.0 ; extra == 'langfuse'
26
27
  Requires-Dist: langgraph~=0.6.2 ; extra == 'langgraph'
@@ -34,6 +35,7 @@ Requires-Dist: openinference-instrumentation-openai-agents>=1.3.0 ; extra == 'op
34
35
  Requires-Dist: traceloop-sdk>=0.48.0 ; extra == 'openllmetry'
35
36
  Requires-Dist: redis>=7.1.0 ; extra == 'redis'
36
37
  Requires-Dist: slack-bolt==1.22.0 ; extra == 'slack'
38
+ Requires-Dist: httpx>=0.27.0 ; extra == 'telegram'
37
39
  Requires-Dist: pytest>=8.4.1 ; extra == 'test'
38
40
  Requires-Dist: pytest-asyncio>=1.2.0 ; extra == 'test'
39
41
  Requires-Dist: pytest-cov>=6.2.1 ; extra == 'test'
@@ -48,6 +50,7 @@ Provides-Extra: api
48
50
  Provides-Extra: aws
49
51
  Provides-Extra: cli
50
52
  Provides-Extra: crewai
53
+ Provides-Extra: instagram
51
54
  Provides-Extra: langfuse
52
55
  Provides-Extra: langgraph
53
56
  Provides-Extra: mcp
@@ -56,6 +59,7 @@ Provides-Extra: openai
56
59
  Provides-Extra: openllmetry
57
60
  Provides-Extra: redis
58
61
  Provides-Extra: slack
62
+ Provides-Extra: telegram
59
63
  Provides-Extra: test
60
64
  Provides-Extra: whatsapp
61
65
  Description-Content-Type: text/markdown
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "agentkernel"
7
- version = "0.2.7"
7
+ version = "0.2.8"
8
8
  description = "Agent Kernel - Unified AI Agents Runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -71,6 +71,12 @@ whatsapp = [
71
71
  messenger = [
72
72
  "httpx>=0.27.0"
73
73
  ]
74
+ instagram = [
75
+ "httpx>=0.27.0"
76
+ ]
77
+ telegram = [
78
+ "httpx>=0.27.0"
79
+ ]
74
80
  test = [
75
81
  "pytest>=8.4.1",
76
82
  "pytest-asyncio>=1.2.0",
@@ -0,0 +1,304 @@
1
+ import base64
2
+ import logging
3
+ import traceback
4
+ from abc import ABC, abstractmethod
5
+ from http import HTTPStatus
6
+ from typing import List, Optional
7
+
8
+ from fastapi import APIRouter, File, Form, HTTPException, UploadFile
9
+ from pydantic import BaseModel, ConfigDict
10
+
11
+ from agentkernel.core.model import (
12
+ AgentReplyImage,
13
+ AgentReplyText,
14
+ AgentRequestAny,
15
+ AgentRequestFile,
16
+ AgentRequestImage,
17
+ AgentRequestText,
18
+ )
19
+
20
+ from ..core import AgentService, GlobalRuntime
21
+
22
+
23
+ class RESTRequestHandler(ABC):
24
+ @abstractmethod
25
+ def get_router(self) -> APIRouter:
26
+ """
27
+ Returns the APIRouter instance which has configured routes
28
+ E.g.:
29
+ - GET /health: Health check
30
+ - GET /agents: List available agents
31
+
32
+ router = APIRouter()
33
+
34
+ @router.get("/health")
35
+ def health():
36
+ return {"status": "ok"}
37
+
38
+ @router.get("/agents")
39
+ def list_agents():
40
+ return {"agents": list(GlobalRuntime.instance().agents().keys())}
41
+
42
+ """
43
+ pass
44
+
45
+
46
+ class AgentRESTRequestHandler(RESTRequestHandler):
47
+ """
48
+ API routers that expose endpoints to interact with Agent Kernel.
49
+ Endpoints:
50
+ - GET /health: Health check
51
+ - GET /agents: List available agents
52
+ - POST /run: Run an agent with a prompt
53
+ Payload JSON: { "prompt": str, "agent": str | null, "session_id": str | null }
54
+ """
55
+
56
+ def __init__(self):
57
+ self._log = logging.getLogger("ak.api.agent")
58
+
59
+ class FileData(BaseModel):
60
+ """Represents a file attachment"""
61
+
62
+ file_data: str # base64 encoded string or URL
63
+ name: str
64
+ mime_type: Optional[str] = None
65
+
66
+ class ImageData(BaseModel):
67
+ """Represents an image attachment"""
68
+
69
+ image_data: str # base64 encoded string
70
+ name: str
71
+ mime_type: Optional[str] = None
72
+
73
+ class RunRequest(BaseModel):
74
+ model_config = ConfigDict(extra="allow")
75
+
76
+ prompt: str
77
+ agent: Optional[str] = None
78
+ session_id: Optional[str] = None
79
+ files: Optional[List["AgentRESTRequestHandler.FileData"]] = None
80
+ images: Optional[List["AgentRESTRequestHandler.ImageData"]] = None
81
+
82
+ def get_router(self) -> APIRouter:
83
+ """
84
+ Returns the APIRouter instance.
85
+ """
86
+
87
+ router = APIRouter()
88
+
89
+ @router.get("/health")
90
+ def health():
91
+ return {"status": "ok"}
92
+
93
+ @router.get("/agents")
94
+ def list_agents():
95
+ return {"agents": list(GlobalRuntime.instance().agents().keys())}
96
+
97
+ @router.post("/run")
98
+ async def run(body: AgentRESTRequestHandler.RunRequest):
99
+ return await self.run(body)
100
+
101
+ @router.post("/run-multipart")
102
+ async def run_multipart(
103
+ prompt: str = Form(...),
104
+ agent: Optional[str] = Form(None),
105
+ session_id: Optional[str] = Form(None),
106
+ files: Optional[List[UploadFile]] = File(None),
107
+ images: Optional[List[UploadFile]] = File(None),
108
+ ):
109
+ return await self.run_multipart(prompt, agent, session_id, files, images)
110
+
111
+ return router
112
+
113
+ async def run(self, req: RunRequest):
114
+ """
115
+ Async method to run the agent.
116
+ :param req: Request object containing the prompt, optional agent name, attachments, images, and additional properties.
117
+ """
118
+ requests = []
119
+ requests.append(AgentRequestText(text=req.prompt))
120
+ service = None
121
+ try:
122
+ # Process attachments (documents, PDFs, CSVs, etc.)
123
+ if req.files:
124
+ for file in req.files:
125
+ self._log.debug(f"Adding file attachment: {file.name}")
126
+ if not file.file_data.startswith(("http://", "https://", "data:", "s3://")) and not file.mime_type:
127
+ raise ValueError("mime_type is missing for file input, either in the base64 or explicitly")
128
+ requests.append(
129
+ AgentRequestFile(
130
+ file_data=file.file_data,
131
+ name=file.name,
132
+ mime_type=file.mime_type if file.mime_type else None,
133
+ )
134
+ )
135
+
136
+ # Process images (JPEG, PNG, etc.)
137
+ if req.images:
138
+ for image in req.images:
139
+ self._log.debug(f"Adding image: {image.name}")
140
+ if (
141
+ not image.image_data.startswith(("http://", "https://", "data:", "s3://"))
142
+ and not image.mime_type
143
+ ):
144
+ raise ValueError("mime_type is missing for image input, either in the base64 or explicitly")
145
+ requests.append(
146
+ AgentRequestImage(
147
+ image_data=image.image_data,
148
+ name=image.name,
149
+ mime_type=image.mime_type if image.mime_type else None,
150
+ )
151
+ )
152
+
153
+ # Pack additional properties into AgentRequestAny
154
+ known_fields = {"prompt", "agent", "session_id", "files", "images"}
155
+ for key, value in req.model_dump().items():
156
+ if key not in known_fields:
157
+ self._log.debug(f"Adding additional context: {key}={value}")
158
+ requests.append(AgentRequestAny(name=key, content=value))
159
+ service = AgentService()
160
+
161
+ service.select(req.session_id, req.agent)
162
+ if not service.agent:
163
+ raise ValueError("No agent available")
164
+
165
+ result = await service.run_multi(requests=requests)
166
+ self._log.debug(f"Result: {result}")
167
+
168
+ return {
169
+ "result": (
170
+ str(result)
171
+ if isinstance(result, (AgentReplyText, AgentReplyImage))
172
+ else "Non textual result received"
173
+ ), # sending image is not supported at the moment
174
+ "session_id": service.get_response_session_id(req.session_id),
175
+ }
176
+
177
+ except HTTPException:
178
+ raise
179
+ except ValueError as e:
180
+ self._log.error(f"POST /run error: {e}\n{traceback.format_exc()}")
181
+ raise HTTPException(
182
+ status_code=HTTPStatus.BAD_REQUEST,
183
+ detail={
184
+ "error": str(e),
185
+ "session_id": (
186
+ service.get_response_session_id(req.session_id) if service is not None else req.session_id
187
+ ),
188
+ },
189
+ )
190
+ except Exception as e:
191
+ self._log.error(f"POST /run error: {e}\n{traceback.format_exc()}")
192
+ raise HTTPException(
193
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
194
+ detail={
195
+ "error": str(e),
196
+ "session_id": service.get_response_session_id(None) if service is not None else req.session_id,
197
+ },
198
+ )
199
+
200
+ async def run_multipart(
201
+ self,
202
+ prompt: str,
203
+ agent: Optional[str] = None,
204
+ session_id: Optional[str] = None,
205
+ files: Optional[List[UploadFile]] = None,
206
+ images: Optional[List[UploadFile]] = None,
207
+ ):
208
+ """
209
+ Async method to run the agent with multipart file uploads.
210
+ :param prompt: The text prompt for the agent.
211
+ :param agent: Optional agent name.
212
+ :param session_id: Optional session ID.
213
+ :param files: Optional list of uploaded files (documents, PDFs, CSVs, etc.).
214
+ :param images: Optional list of uploaded images (JPEG, PNG, etc.).
215
+ """
216
+ requests = []
217
+ requests.append(AgentRequestText(text=prompt))
218
+ service = None
219
+
220
+ try:
221
+ # Process file uploads
222
+ if files:
223
+ for file in files:
224
+ self._log.debug(f"Processing uploaded file: {file.filename}")
225
+ # Read file content
226
+ content = await file.read()
227
+ # Encode to base64
228
+ file_data_base64 = base64.b64encode(content).decode("utf-8")
229
+
230
+ # Get mime type from the upload
231
+ mime_type = file.content_type
232
+
233
+ self._log.debug(f"Adding file attachment: {file.filename} (type: {mime_type})")
234
+ requests.append(
235
+ AgentRequestFile(
236
+ file_data=file_data_base64,
237
+ name=file.filename or "unknown",
238
+ mime_type=mime_type,
239
+ )
240
+ )
241
+
242
+ # Process image uploads
243
+ if images:
244
+ for image in images:
245
+ self._log.debug(f"Processing uploaded image: {image.filename}")
246
+ # Read image content
247
+ content = await image.read()
248
+ # Encode to base64
249
+ image_data_base64 = base64.b64encode(content).decode("utf-8")
250
+
251
+ # Get mime type from the upload
252
+ mime_type = image.content_type
253
+
254
+ # Validate it's an image mime type
255
+ if mime_type and not mime_type.startswith("image/"):
256
+ raise ValueError(f"Invalid image type: {mime_type} for file {image.filename}")
257
+
258
+ self._log.debug(f"Adding image: {image.filename} (type: {mime_type})")
259
+ requests.append(
260
+ AgentRequestImage(
261
+ image_data=image_data_base64,
262
+ name=image.filename or "unknown",
263
+ mime_type=mime_type,
264
+ )
265
+ )
266
+
267
+ service = AgentService()
268
+ service.select(session_id, agent)
269
+
270
+ if not service.agent:
271
+ raise ValueError("No agent available")
272
+
273
+ result = await service.run_multi(requests=requests)
274
+ self._log.debug(f"Result: {result}")
275
+
276
+ return {
277
+ "result": (
278
+ str(result)
279
+ if isinstance(result, (AgentReplyText, AgentReplyImage))
280
+ else "Non textual result received"
281
+ ),
282
+ "session_id": service.get_response_session_id(session_id),
283
+ }
284
+
285
+ except HTTPException:
286
+ raise
287
+ except ValueError as e:
288
+ self._log.error(f"POST /run-multipart error: {e}\n{traceback.format_exc()}")
289
+ raise HTTPException(
290
+ status_code=HTTPStatus.BAD_REQUEST,
291
+ detail={
292
+ "error": str(e),
293
+ "session_id": service.get_response_session_id(session_id) if service is not None else session_id,
294
+ },
295
+ )
296
+ except Exception as e:
297
+ self._log.error(f"POST /run-multipart error: {e}\n{traceback.format_exc()}")
298
+ raise HTTPException(
299
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
300
+ detail={
301
+ "error": str(e),
302
+ "session_id": service.get_response_session_id(None) if service is not None else session_id,
303
+ },
304
+ )
@@ -35,6 +35,7 @@ class CLI:
35
35
  self._print("!ld, !load <module_name> - Load agent module")
36
36
  self._print("!ls, !list - List available agents")
37
37
  self._print("!n, !new - Start a new session")
38
+ self._print("!c, !clear - Clear the current session memory")
38
39
  self._print("!s, !select <agent_name> - Select an agent to run the prompt")
39
40
  self._print("!q, !quit - Exit the program")
40
41
  self._print()
@@ -67,14 +68,16 @@ class CLI:
67
68
  command = tokens[0]
68
69
  if command in ["!h", "!help"]:
69
70
  self.help()
70
- elif command in ["!ls", "!list"]:
71
- self.list()
71
+ elif command in ["!c", "!clear"]:
72
+ self._service.clear()
72
73
  elif command in ["!ld", "!load"]:
73
74
  if len(tokens) != 2:
74
75
  self._print("Usage: !load <module_name>")
75
76
  continue
76
77
  session_id = self._service.session.id if self._service.session else None
77
78
  self._service.load(name=tokens[1], session_id=session_id)
79
+ elif command in ["!ls", "!list"]:
80
+ self.list()
78
81
  elif command in ["!n", "!new"]:
79
82
  self._service.new()
80
83
  elif command in ["!q", "!quit"]:
@@ -12,7 +12,7 @@ current_session = contextvars.ContextVar("session_id", default="")
12
12
 
13
13
  class Session:
14
14
  """
15
- Session is the base class for a stacking state across related interactions with agents.
15
+ Session is the base class for a tracking state across related interactions with agents.
16
16
 
17
17
  Agent Kernel provides an implementation of the Session class for each supported agent framework,
18
18
  allowing the runtime to track and share state across multiple related agent logic invocations.
@@ -20,6 +20,15 @@ class Session:
20
20
  Sessions may be volatile (meaning that they are not persisted) or durable (meaning that they
21
21
  are persisted and are available across multiple invocations of the runtime). This is governed by
22
22
  the runtime configuration.
23
+
24
+ Session class stores framework-specific session data objects in a key-value store, allowing
25
+ different agent frameworks to store and retrieve their own session data without interfering with
26
+ each other.
27
+
28
+ In addition, there are two pre-defined key-value caches for storing data that is either volatile
29
+ (i.e., not persisted across runtime invocations) or non-volatile (i.e., persisted across runtime
30
+ invocations). These caches can be used by application code to store data that is not part of the
31
+ agent context but needs to be retained across multiple interactions within the same session.
23
32
  """
24
33
 
25
34
  VOLATILE_CACHE_KEY = "v_cache"
@@ -28,8 +37,8 @@ class Session:
28
37
  @classmethod
29
38
  def get_current_session_id(cls) -> str:
30
39
  """
31
- Returns the current session ID from the context variable.
32
- :return: The current session ID.
40
+ Returns the current session identifier from the context variable.
41
+ :return: The current session identifier.
33
42
  """
34
43
  return current_session.get()
35
44
 
@@ -56,7 +65,8 @@ class Session:
56
65
  self._id = id
57
66
  self._data = {}
58
67
 
59
- # Pre-initialize key-value caches to be used by application code which will not be part of the agent context
68
+ # Pre-initialize key-value caches to be used by application code
69
+ # which will not be part of the agent context.
60
70
  self.set(self.VOLATILE_CACHE_KEY, KeyValueCache())
61
71
  self.set(self.NON_VOLATILE_CACHE_KEY, KeyValueCache())
62
72
 
@@ -72,13 +82,13 @@ class Session:
72
82
 
73
83
  def get(self, key: str) -> Any:
74
84
  """
75
- Retrieves a framework-specific session object from the session data.
76
- :param key: The key to retrieve the session object for.
77
- :return: The framework-specific session object associated with the key, or None if the key
78
- does not exist.
85
+ Retrieves the specified session data object.
86
+ :param key: The key of the session data object.
87
+ :return: The matching session object associated with the key, or None
88
+ if there is no data object with the specified key.
79
89
  """
80
90
  result = self._data.get(key)
81
- self._log.debug(f"Retrieved session object for key {key}: {result}")
91
+ self._log.debug(f"Retrieved session {self._id} data object for key {key}: {result}")
82
92
  return result
83
93
 
84
94
  def get_all_keys(self):
@@ -90,14 +100,35 @@ class Session:
90
100
 
91
101
  def set(self, key: str, value: Any) -> Any:
92
102
  """
93
- Sets a framework-specific session object in the session data.
94
- :param key: The key to set the session object for.
95
- :param value: The framework-specific session object to set.
103
+ Sets a session data object for the specified key.
104
+ :param key: The key of the session data object.
105
+ :param value: The session data object.
96
106
  """
97
- self._log.debug(f"Setting session object for key {key}: {value}")
107
+ self._log.debug(f"Setting session {self._id} data object for key {key}: {value}")
98
108
  self._data[key] = value
99
109
  return value
100
110
 
111
+ def delete(self, key: str) -> None:
112
+ """
113
+ Deletes the session data object for the specified key.
114
+ :param key: The key of the session data object to be deleted.
115
+ """
116
+ if key in self._data:
117
+ self._log.debug(f"Deleting session {self._id} data object for key {key}")
118
+ del self._data[key]
119
+
120
+ def clear(self) -> None:
121
+ """
122
+ Clears all session data objects.
123
+ """
124
+ self._log.debug(f"Clearing session {self._id} data objects")
125
+ self._data = {
126
+ self.VOLATILE_CACHE_KEY: self.get_volatile_cache(),
127
+ self.NON_VOLATILE_CACHE_KEY: self.get_non_volatile_cache(),
128
+ }
129
+ self.get_volatile_cache().clear()
130
+ self.get_non_volatile_cache().clear()
131
+
101
132
  def set_context(self):
102
133
  """
103
134
  Sets the current session context variable to this session's ID.
@@ -92,6 +92,22 @@ class _MessengerConfig(BaseModel):
92
92
  api_version: str = Field(default="v24.0", description="Facebook Graph API version")
93
93
 
94
94
 
95
+ class _InstagramConfig(BaseModel):
96
+ agent: str = Field(default="", description="Default agent to use for Instagram interactions")
97
+ verify_token: str = Field(default="", description="Instagram webhook verify token")
98
+ access_token: str = Field(default="", description="Instagram Business access token")
99
+ app_secret: str = Field(default="", description="Instagram app secret for signature verification")
100
+ instagram_account_id: str = Field(default="", description="Instagram Business Account ID (IGSID)")
101
+ api_version: str = Field(default="v21.0", description="Instagram Graph API version")
102
+
103
+
104
+ class _TelegramConfig(BaseModel):
105
+ agent: str = Field(default="", description="Default agent to use for Telegram")
106
+ bot_token: str = Field(default="", description="Telegram bot token from BotFather")
107
+ webhook_secret: str = Field(default="", description="Optional secret token for webhook security")
108
+ api_version: str = Field(default="bot", description="Telegram Bot API version prefix")
109
+
110
+
95
111
  class _TraceConfig(BaseModel):
96
112
  enabled: bool = Field(default=False, description="Enable tracing")
97
113
  type: str = Field(default="langfuse", pattern="^(langfuse|openllmetry)$")
@@ -114,6 +130,12 @@ class AKConfig(YamlBaseSettingsModified):
114
130
  messenger: _MessengerConfig = Field(
115
131
  description="Facebook Messenger related configurations", default_factory=_MessengerConfig
116
132
  )
133
+ instagram: _InstagramConfig = Field(
134
+ description="Instagram Business API related configurations", default_factory=_InstagramConfig
135
+ )
136
+ telegram: _TelegramConfig = Field(
137
+ description="Telegram Bot related configurations", default_factory=_TelegramConfig
138
+ )
117
139
  trace: _TraceConfig = Field(description="Tracing related configurations", default_factory=_TraceConfig)
118
140
  library_version: str = Field(default=_get_ak_version(), description="Library version")
119
141
 
@@ -94,6 +94,16 @@ class AgentService:
94
94
  self._log.info(f"Starting new session: {session_id}")
95
95
  self._session = self._runtime.sessions().new(session_id)
96
96
 
97
+ def clear(self):
98
+ """
99
+ Clears the current session data.
100
+ """
101
+ if self._session:
102
+ self._log.info(f"Clearing session: {self._session.id}")
103
+ self._session.clear()
104
+ else:
105
+ self._log.warning("No session available to clear.")
106
+
97
107
  def load(self, session_id: str, name: str):
98
108
  """
99
109
  Loads an agent module by name.