agentkernel 0.2.8__tar.gz → 0.2.10__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 (95) hide show
  1. {agentkernel-0.2.8 → agentkernel-0.2.10}/PKG-INFO +194 -3
  2. {agentkernel-0.2.8 → agentkernel-0.2.10}/README.md +181 -0
  3. {agentkernel-0.2.8 → agentkernel-0.2.10}/pyproject.toml +15 -4
  4. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/a2a/a2a.py +3 -2
  5. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/handler.py +24 -3
  6. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/mcp/akmcp.py +3 -2
  7. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/__init__.py +2 -2
  8. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/base.py +39 -0
  9. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/builder.py +30 -3
  10. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/config.py +27 -0
  11. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/hooks.py +11 -6
  12. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/module.py +35 -4
  13. agentkernel-0.2.10/src/agentkernel/core/runtime.py +237 -0
  14. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/service.py +4 -7
  15. agentkernel-0.2.10/src/agentkernel/core/session/base.py +118 -0
  16. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/session/dynamodb.py +21 -4
  17. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/session/redis.py +20 -3
  18. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/adk/adk.py +30 -2
  19. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/crewai/crewai.py +30 -2
  20. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/langgraph/langgraph.py +24 -1
  21. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/openai/openai.py +30 -1
  22. agentkernel-0.2.10/src/agentkernel/gmail.py +8 -0
  23. agentkernel-0.2.10/src/agentkernel/integration/gmail/README.md +294 -0
  24. agentkernel-0.2.10/src/agentkernel/integration/gmail/__init__.py +10 -0
  25. agentkernel-0.2.10/src/agentkernel/integration/gmail/gmail_chat.py +646 -0
  26. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/slack/README.md +11 -2
  27. agentkernel-0.2.10/src/agentkernel/integration/slack/slack_chat.py +307 -0
  28. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/telegram/telegram_chat.py +1 -1
  29. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/whatsapp/README.md +13 -2
  30. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/whatsapp/whatsapp_chat.py +182 -11
  31. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/test/__init__.py +1 -1
  32. agentkernel-0.2.10/src/agentkernel/test/test.py +289 -0
  33. agentkernel-0.2.8/src/agentkernel/core/runtime.py +0 -319
  34. agentkernel-0.2.8/src/agentkernel/core/session/base.py +0 -45
  35. agentkernel-0.2.8/src/agentkernel/integration/slack/slack_chat.py +0 -160
  36. agentkernel-0.2.8/src/agentkernel/test/test.py +0 -126
  37. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/__init__.py +0 -0
  38. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/adk.py +0 -0
  39. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/__init__.py +0 -0
  40. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/a2a/__init__.py +0 -0
  41. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/a2a/handler.py +0 -0
  42. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/http.py +0 -0
  43. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/api/mcp/__init__.py +0 -0
  44. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/aws.py +0 -0
  45. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/cli/__init__.py +0 -0
  46. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/cli/cli.py +0 -0
  47. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/model.py +0 -0
  48. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/session/__init__.py +0 -0
  49. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/session/in_memory.py +0 -0
  50. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/session/serde.py +0 -0
  51. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/util/config_yaml_util.py +0 -0
  52. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/core/util/key_value_cache.py +0 -0
  53. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/crewai.py +0 -0
  54. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/deployment/__init__.py +0 -0
  55. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/deployment/aws/__init__.py +0 -0
  56. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/deployment/aws/aklambda.py +0 -0
  57. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/__init__.py +0 -0
  58. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/adk/__init__.py +0 -0
  59. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/crewai/__init__.py +0 -0
  60. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/langgraph/__init__.py +0 -0
  61. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/framework/openai/__init__.py +0 -0
  62. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/instagram.py +0 -0
  63. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/__init__.py +0 -0
  64. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/instagram/README.md +0 -0
  65. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/instagram/__init__.py +0 -0
  66. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/instagram/instagram_chat.py +0 -0
  67. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/messenger/README.md +0 -0
  68. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/messenger/__init__.py +0 -0
  69. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/messenger/messenger_chat.py +0 -0
  70. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/slack/__init__.py +0 -0
  71. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/telegram/README.md +0 -0
  72. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/telegram/__init__.py +0 -0
  73. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/integration/whatsapp/__init__.py +0 -0
  74. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/langgraph.py +0 -0
  75. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/mcp.py +0 -0
  76. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/messenger.py +0 -0
  77. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/openai.py +0 -0
  78. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/slack.py +0 -0
  79. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/telegram.py +0 -0
  80. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/__init__.py +0 -0
  81. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/base.py +0 -0
  82. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/__init__.py +0 -0
  83. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/adk.py +0 -0
  84. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/crewai.py +0 -0
  85. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/langfuse.py +0 -0
  86. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/langgraph.py +0 -0
  87. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/langfuse/openai.py +0 -0
  88. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/__init__.py +0 -0
  89. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/adk.py +0 -0
  90. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/crewai.py +0 -0
  91. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/langgraph.py +0 -0
  92. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/openai.py +0 -0
  93. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/openllmetry/openllmetry.py +0 -0
  94. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/trace/trace.py +0 -0
  95. {agentkernel-0.2.8 → agentkernel-0.2.10}/src/agentkernel/whatsapp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: agentkernel
3
- Version: 0.2.8
3
+ Version: 0.2.10
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,10 @@ 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: google-auth>=2.0.0 ; extra == 'gmail'
25
+ Requires-Dist: google-auth-oauthlib>=1.0.0 ; extra == 'gmail'
26
+ Requires-Dist: google-auth-httplib2>=0.2.0 ; extra == 'gmail'
27
+ Requires-Dist: google-api-python-client>=2.0.0 ; extra == 'gmail'
24
28
  Requires-Dist: httpx>=0.27.0 ; extra == 'instagram'
25
29
  Requires-Dist: langfuse>=3.9.2 ; extra == 'langfuse'
26
30
  Requires-Dist: nest-asyncio>=1.6.0 ; extra == 'langfuse'
@@ -30,11 +34,12 @@ Requires-Dist: langchain-community~=0.3.27 ; extra == 'langgraph'
30
34
  Requires-Dist: litellm~=1.74.3 ; extra == 'langgraph'
31
35
  Requires-Dist: fastmcp>=2.12.4 ; extra == 'mcp'
32
36
  Requires-Dist: httpx>=0.27.0 ; extra == 'messenger'
33
- Requires-Dist: openai-agents>=0.2.3 ; extra == 'openai'
34
- Requires-Dist: openinference-instrumentation-openai-agents>=1.3.0 ; extra == 'openai'
37
+ Requires-Dist: openai-agents>=0.6.3 ; extra == 'openai'
38
+ Requires-Dist: openinference-instrumentation-openai-agents>=1.4.0 ; extra == 'openai'
35
39
  Requires-Dist: traceloop-sdk>=0.48.0 ; extra == 'openllmetry'
36
40
  Requires-Dist: redis>=7.1.0 ; extra == 'redis'
37
41
  Requires-Dist: slack-bolt==1.22.0 ; extra == 'slack'
42
+ Requires-Dist: httpx>=0.27.0 ; extra == 'slack'
38
43
  Requires-Dist: httpx>=0.27.0 ; extra == 'telegram'
39
44
  Requires-Dist: pytest>=8.4.1 ; extra == 'test'
40
45
  Requires-Dist: pytest-asyncio>=1.2.0 ; extra == 'test'
@@ -42,6 +47,10 @@ Requires-Dist: pytest-cov>=6.2.1 ; extra == 'test'
42
47
  Requires-Dist: pytest-html>=4.1.1 ; extra == 'test'
43
48
  Requires-Dist: pytest-order>=1.3.0 ; extra == 'test'
44
49
  Requires-Dist: rapidfuzz>=3.14.1 ; extra == 'test'
50
+ Requires-Dist: ragas>=0.4.1 ; extra == 'test'
51
+ Requires-Dist: datasets>=2.14.0 ; extra == 'test'
52
+ Requires-Dist: pandas>=2.0.0 ; extra == 'test'
53
+ Requires-Dist: litellm>=1.74.9 ; extra == 'test'
45
54
  Requires-Dist: httpx>=0.27.0 ; extra == 'whatsapp'
46
55
  Requires-Python: >=3.12
47
56
  Provides-Extra: a2a
@@ -50,6 +59,7 @@ Provides-Extra: api
50
59
  Provides-Extra: aws
51
60
  Provides-Extra: cli
52
61
  Provides-Extra: crewai
62
+ Provides-Extra: gmail
53
63
  Provides-Extra: instagram
54
64
  Provides-Extra: langfuse
55
65
  Provides-Extra: langgraph
@@ -463,6 +473,122 @@ trace:
463
473
  type: openllmetry
464
474
  ```
465
475
 
476
+ #### Test Configuration
477
+
478
+ Configure test comparison modes for automated testing.
479
+
480
+ - **Mode**
481
+ - **Field**: `test.mode`
482
+ - **Options**: `fuzzy`, `judge`, `fallback`
483
+ - **Default**: `fallback`
484
+ - **Description**: Test comparison mode
485
+ - **Environment Variable**: `AK_TEST__MODE`
486
+
487
+ - **Judge Model**
488
+ - **Field**: `test.judge.model`
489
+ - **Default**: `gpt-4o-mini`
490
+ - **Description**: LLM model for judge evaluation
491
+ - **Environment Variable**: `AK_TEST__JUDGE__MODEL`
492
+
493
+ - **Judge Provider**
494
+ - **Field**: `test.judge.provider`
495
+ - **Default**: `openai`
496
+ - **Description**: LLM provider for judge evaluation
497
+ - **Environment Variable**: `AK_TEST__JUDGE__PROVIDER`
498
+
499
+ - **Judge Embedding Model**
500
+ - **Field**: `test.judge.embedding_model`
501
+ - **Default**: `text-embedding-3-small`
502
+ - **Description**: Embedding model for similarity evaluation
503
+ - **Environment Variable**: `AK_TEST__JUDGE__EMBEDDING_MODEL`
504
+
505
+ **Test Modes:**
506
+ - `fuzzy`: Uses fuzzy string matching (RapidFuzz)
507
+ - `judge`: Uses LLM-based evaluation (Ragas) for semantic similarity
508
+ - `fallback`: Tries fuzzy first, falls back to judge if fuzzy fails
509
+
510
+ ```yaml
511
+ test:
512
+ mode: fallback
513
+ judge:
514
+ model: gpt-4o-mini
515
+ provider: openai
516
+ embedding_model: text-embedding-3-small
517
+ ```
518
+
519
+ #### Messaging Platform Integrations
520
+
521
+ Configure integrations with messaging platforms.
522
+
523
+ ##### Slack
524
+
525
+ - **Agent**
526
+ - **Field**: `slack.agent`
527
+ - **Default**: `""`
528
+ - **Description**: Default agent for Slack interactions
529
+ - **Environment Variable**: `AK_SLACK__AGENT`
530
+
531
+ - **Agent Acknowledgement**
532
+ - **Field**: `slack.agent_acknowledgement`
533
+ - **Default**: `""`
534
+ - **Description**: Acknowledgement message when Slack message is received
535
+ - **Environment Variable**: `AK_SLACK__AGENT_ACKNOWLEDGEMENT`
536
+
537
+ ##### WhatsApp
538
+
539
+ - **Agent**
540
+ - **Field**: `whatsapp.agent`
541
+ - **Default**: `""`
542
+ - **Description**: Default agent for WhatsApp interactions
543
+ - **Environment Variable**: `AK_WHATSAPP__AGENT`
544
+
545
+ - **Verify Token**, **Access Token**, **App Secret**, **Phone Number ID**, **API Version**
546
+ - **Environment Variables**: `AK_WHATSAPP__VERIFY_TOKEN`, `AK_WHATSAPP__ACCESS_TOKEN`, `AK_WHATSAPP__APP_SECRET`, `AK_WHATSAPP__PHONE_NUMBER_ID`, `AK_WHATSAPP__API_VERSION`
547
+
548
+ ##### Facebook Messenger
549
+
550
+ - **Agent**
551
+ - **Field**: `messenger.agent`
552
+ - **Default**: `""`
553
+ - **Description**: Default agent for Facebook Messenger interactions
554
+ - **Environment Variable**: `AK_MESSENGER__AGENT`
555
+
556
+ - **Verify Token**, **Access Token**, **App Secret**, **API Version**
557
+ - **Environment Variables**: `AK_MESSENGER__VERIFY_TOKEN`, `AK_MESSENGER__ACCESS_TOKEN`, `AK_MESSENGER__APP_SECRET`, `AK_MESSENGER__API_VERSION`
558
+
559
+ ##### Instagram
560
+
561
+ - **Agent**
562
+ - **Field**: `instagram.agent`
563
+ - **Default**: `""`
564
+ - **Description**: Default agent for Instagram interactions
565
+ - **Environment Variable**: `AK_INSTAGRAM__AGENT`
566
+
567
+ - **Instagram Account ID**, **Verify Token**, **Access Token**, **App Secret**, **API Version**
568
+ - **Environment Variables**: `AK_INSTAGRAM__INSTAGRAM_ACCOUNT_ID`, `AK_INSTAGRAM__VERIFY_TOKEN`, `AK_INSTAGRAM__ACCESS_TOKEN`, `AK_INSTAGRAM__APP_SECRET`, `AK_INSTAGRAM__API_VERSION`
569
+
570
+ ##### Telegram
571
+
572
+ - **Agent**
573
+ - **Field**: `telegram.agent`
574
+ - **Default**: `""`
575
+ - **Description**: Default agent for Telegram interactions
576
+ - **Environment Variable**: `AK_TELEGRAM__AGENT`
577
+
578
+ - **Bot Token**, **Webhook Secret**, **API Version**
579
+ - **Environment Variables**: `AK_TELEGRAM__BOT_TOKEN`, `AK_TELEGRAM__WEBHOOK_SECRET`, `AK_TELEGRAM__API_VERSION`
580
+
581
+ ##### Gmail
582
+
583
+ - **Agent**
584
+ - **Field**: `gmail.agent`
585
+ - **Default**: `"general"`
586
+ - **Description**: Default agent for Gmail interactions
587
+ - **Environment Variable**: `AK_GMAIL__AGENT`
588
+
589
+ - **Client ID**, **Client Secret**, **Token File**, **Poll Interval**, **Label Filter**
590
+ - **Environment Variables**: `AK_GMAIL__CLIENT_ID`, `AK_GMAIL__CLIENT_SECRET`, `AK_GMAIL__TOKEN_FILE`, `AK_GMAIL__POLL_INTERVAL`, `AK_GMAIL__LABEL_FILTER`
591
+
466
592
  ### Configuration Examples
467
593
 
468
594
  #### Environment Variables
@@ -487,6 +613,19 @@ export AK_TRACE__TYPE=langfuse # or openllmetry
487
613
  # export LANGFUSE_HOST=https://cloud.langfuse.com
488
614
  # For OpenLLMetry:
489
615
  # export TRACELOOP_API_KEY=your-api-key
616
+ export AK_TEST__MODE=fallback # Options: fuzzy, judge, fallback
617
+ export AK_TEST__JUDGE__MODEL=gpt-4o-mini
618
+ export AK_TEST__JUDGE__PROVIDER=openai
619
+ export AK_TEST__JUDGE__EMBEDDING_MODEL=text-embedding-3-small
620
+ # Messaging platforms (optional)
621
+ export AK_SLACK__AGENT=my-agent
622
+ export AK_WHATSAPP__AGENT=my-agent
623
+ export AK_MESSENGER__AGENT=my-agent
624
+ export AK_INSTAGRAM__AGENT=my-agent
625
+ export AK_TELEGRAM__AGENT=my-agent
626
+ export AK_GMAIL__AGENT=my-agent
627
+ export AK_GMAIL__CLIENT_ID=your-google-client-id
628
+ export AK_GMAIL__CLIENT_SECRET=your-google-client-secret
490
629
  ```
491
630
 
492
631
  #### .env File
@@ -541,6 +680,28 @@ mcp:
541
680
  trace:
542
681
  enabled: true
543
682
  type: langfuse
683
+ test:
684
+ mode: fallback
685
+ judge:
686
+ model: gpt-4o-mini
687
+ provider: openai
688
+ embedding_model: text-embedding-3-small
689
+ slack:
690
+ agent: my-agent
691
+ agent_acknowledgement: "Processing your request..."
692
+ whatsapp:
693
+ agent: my-agent
694
+ agent_acknowledgement: "Processing..."
695
+ messenger:
696
+ agent: my-agent
697
+ instagram:
698
+ agent: my-agent
699
+ telegram:
700
+ agent: my-agent
701
+ gmail:
702
+ agent: my-agent
703
+ poll_interval: 30
704
+ label_filter: "INBOX"
544
705
  ```
545
706
 
546
707
  #### config.json
@@ -578,6 +739,36 @@ trace:
578
739
  "trace": {
579
740
  "enabled": true,
580
741
  "type": "langfuse"
742
+ },
743
+ "test": {
744
+ "mode": "fallback",
745
+ "judge": {
746
+ "model": "gpt-4o-mini",
747
+ "provider": "openai",
748
+ "embedding_model": "text-embedding-3-small"
749
+ }
750
+ },
751
+ "slack": {
752
+ "agent": "my-agent",
753
+ "agent_acknowledgement": "Processing your request..."
754
+ },
755
+ "whatsapp": {
756
+ "agent": "my-agent",
757
+ "agent_acknowledgement": "Processing..."
758
+ },
759
+ "messenger": {
760
+ "agent": "my-agent"
761
+ },
762
+ "instagram": {
763
+ "agent": "my-agent"
764
+ },
765
+ "telegram": {
766
+ "agent": "my-agent"
767
+ },
768
+ "gmail": {
769
+ "agent": "my-agent",
770
+ "poll_interval": 30,
771
+ "label_filter": "INBOX"
581
772
  }
582
773
  }
583
774
  ```
@@ -397,6 +397,122 @@ trace:
397
397
  type: openllmetry
398
398
  ```
399
399
 
400
+ #### Test Configuration
401
+
402
+ Configure test comparison modes for automated testing.
403
+
404
+ - **Mode**
405
+ - **Field**: `test.mode`
406
+ - **Options**: `fuzzy`, `judge`, `fallback`
407
+ - **Default**: `fallback`
408
+ - **Description**: Test comparison mode
409
+ - **Environment Variable**: `AK_TEST__MODE`
410
+
411
+ - **Judge Model**
412
+ - **Field**: `test.judge.model`
413
+ - **Default**: `gpt-4o-mini`
414
+ - **Description**: LLM model for judge evaluation
415
+ - **Environment Variable**: `AK_TEST__JUDGE__MODEL`
416
+
417
+ - **Judge Provider**
418
+ - **Field**: `test.judge.provider`
419
+ - **Default**: `openai`
420
+ - **Description**: LLM provider for judge evaluation
421
+ - **Environment Variable**: `AK_TEST__JUDGE__PROVIDER`
422
+
423
+ - **Judge Embedding Model**
424
+ - **Field**: `test.judge.embedding_model`
425
+ - **Default**: `text-embedding-3-small`
426
+ - **Description**: Embedding model for similarity evaluation
427
+ - **Environment Variable**: `AK_TEST__JUDGE__EMBEDDING_MODEL`
428
+
429
+ **Test Modes:**
430
+ - `fuzzy`: Uses fuzzy string matching (RapidFuzz)
431
+ - `judge`: Uses LLM-based evaluation (Ragas) for semantic similarity
432
+ - `fallback`: Tries fuzzy first, falls back to judge if fuzzy fails
433
+
434
+ ```yaml
435
+ test:
436
+ mode: fallback
437
+ judge:
438
+ model: gpt-4o-mini
439
+ provider: openai
440
+ embedding_model: text-embedding-3-small
441
+ ```
442
+
443
+ #### Messaging Platform Integrations
444
+
445
+ Configure integrations with messaging platforms.
446
+
447
+ ##### Slack
448
+
449
+ - **Agent**
450
+ - **Field**: `slack.agent`
451
+ - **Default**: `""`
452
+ - **Description**: Default agent for Slack interactions
453
+ - **Environment Variable**: `AK_SLACK__AGENT`
454
+
455
+ - **Agent Acknowledgement**
456
+ - **Field**: `slack.agent_acknowledgement`
457
+ - **Default**: `""`
458
+ - **Description**: Acknowledgement message when Slack message is received
459
+ - **Environment Variable**: `AK_SLACK__AGENT_ACKNOWLEDGEMENT`
460
+
461
+ ##### WhatsApp
462
+
463
+ - **Agent**
464
+ - **Field**: `whatsapp.agent`
465
+ - **Default**: `""`
466
+ - **Description**: Default agent for WhatsApp interactions
467
+ - **Environment Variable**: `AK_WHATSAPP__AGENT`
468
+
469
+ - **Verify Token**, **Access Token**, **App Secret**, **Phone Number ID**, **API Version**
470
+ - **Environment Variables**: `AK_WHATSAPP__VERIFY_TOKEN`, `AK_WHATSAPP__ACCESS_TOKEN`, `AK_WHATSAPP__APP_SECRET`, `AK_WHATSAPP__PHONE_NUMBER_ID`, `AK_WHATSAPP__API_VERSION`
471
+
472
+ ##### Facebook Messenger
473
+
474
+ - **Agent**
475
+ - **Field**: `messenger.agent`
476
+ - **Default**: `""`
477
+ - **Description**: Default agent for Facebook Messenger interactions
478
+ - **Environment Variable**: `AK_MESSENGER__AGENT`
479
+
480
+ - **Verify Token**, **Access Token**, **App Secret**, **API Version**
481
+ - **Environment Variables**: `AK_MESSENGER__VERIFY_TOKEN`, `AK_MESSENGER__ACCESS_TOKEN`, `AK_MESSENGER__APP_SECRET`, `AK_MESSENGER__API_VERSION`
482
+
483
+ ##### Instagram
484
+
485
+ - **Agent**
486
+ - **Field**: `instagram.agent`
487
+ - **Default**: `""`
488
+ - **Description**: Default agent for Instagram interactions
489
+ - **Environment Variable**: `AK_INSTAGRAM__AGENT`
490
+
491
+ - **Instagram Account ID**, **Verify Token**, **Access Token**, **App Secret**, **API Version**
492
+ - **Environment Variables**: `AK_INSTAGRAM__INSTAGRAM_ACCOUNT_ID`, `AK_INSTAGRAM__VERIFY_TOKEN`, `AK_INSTAGRAM__ACCESS_TOKEN`, `AK_INSTAGRAM__APP_SECRET`, `AK_INSTAGRAM__API_VERSION`
493
+
494
+ ##### Telegram
495
+
496
+ - **Agent**
497
+ - **Field**: `telegram.agent`
498
+ - **Default**: `""`
499
+ - **Description**: Default agent for Telegram interactions
500
+ - **Environment Variable**: `AK_TELEGRAM__AGENT`
501
+
502
+ - **Bot Token**, **Webhook Secret**, **API Version**
503
+ - **Environment Variables**: `AK_TELEGRAM__BOT_TOKEN`, `AK_TELEGRAM__WEBHOOK_SECRET`, `AK_TELEGRAM__API_VERSION`
504
+
505
+ ##### Gmail
506
+
507
+ - **Agent**
508
+ - **Field**: `gmail.agent`
509
+ - **Default**: `"general"`
510
+ - **Description**: Default agent for Gmail interactions
511
+ - **Environment Variable**: `AK_GMAIL__AGENT`
512
+
513
+ - **Client ID**, **Client Secret**, **Token File**, **Poll Interval**, **Label Filter**
514
+ - **Environment Variables**: `AK_GMAIL__CLIENT_ID`, `AK_GMAIL__CLIENT_SECRET`, `AK_GMAIL__TOKEN_FILE`, `AK_GMAIL__POLL_INTERVAL`, `AK_GMAIL__LABEL_FILTER`
515
+
400
516
  ### Configuration Examples
401
517
 
402
518
  #### Environment Variables
@@ -421,6 +537,19 @@ export AK_TRACE__TYPE=langfuse # or openllmetry
421
537
  # export LANGFUSE_HOST=https://cloud.langfuse.com
422
538
  # For OpenLLMetry:
423
539
  # export TRACELOOP_API_KEY=your-api-key
540
+ export AK_TEST__MODE=fallback # Options: fuzzy, judge, fallback
541
+ export AK_TEST__JUDGE__MODEL=gpt-4o-mini
542
+ export AK_TEST__JUDGE__PROVIDER=openai
543
+ export AK_TEST__JUDGE__EMBEDDING_MODEL=text-embedding-3-small
544
+ # Messaging platforms (optional)
545
+ export AK_SLACK__AGENT=my-agent
546
+ export AK_WHATSAPP__AGENT=my-agent
547
+ export AK_MESSENGER__AGENT=my-agent
548
+ export AK_INSTAGRAM__AGENT=my-agent
549
+ export AK_TELEGRAM__AGENT=my-agent
550
+ export AK_GMAIL__AGENT=my-agent
551
+ export AK_GMAIL__CLIENT_ID=your-google-client-id
552
+ export AK_GMAIL__CLIENT_SECRET=your-google-client-secret
424
553
  ```
425
554
 
426
555
  #### .env File
@@ -475,6 +604,28 @@ mcp:
475
604
  trace:
476
605
  enabled: true
477
606
  type: langfuse
607
+ test:
608
+ mode: fallback
609
+ judge:
610
+ model: gpt-4o-mini
611
+ provider: openai
612
+ embedding_model: text-embedding-3-small
613
+ slack:
614
+ agent: my-agent
615
+ agent_acknowledgement: "Processing your request..."
616
+ whatsapp:
617
+ agent: my-agent
618
+ agent_acknowledgement: "Processing..."
619
+ messenger:
620
+ agent: my-agent
621
+ instagram:
622
+ agent: my-agent
623
+ telegram:
624
+ agent: my-agent
625
+ gmail:
626
+ agent: my-agent
627
+ poll_interval: 30
628
+ label_filter: "INBOX"
478
629
  ```
479
630
 
480
631
  #### config.json
@@ -512,6 +663,36 @@ trace:
512
663
  "trace": {
513
664
  "enabled": true,
514
665
  "type": "langfuse"
666
+ },
667
+ "test": {
668
+ "mode": "fallback",
669
+ "judge": {
670
+ "model": "gpt-4o-mini",
671
+ "provider": "openai",
672
+ "embedding_model": "text-embedding-3-small"
673
+ }
674
+ },
675
+ "slack": {
676
+ "agent": "my-agent",
677
+ "agent_acknowledgement": "Processing your request..."
678
+ },
679
+ "whatsapp": {
680
+ "agent": "my-agent",
681
+ "agent_acknowledgement": "Processing..."
682
+ },
683
+ "messenger": {
684
+ "agent": "my-agent"
685
+ },
686
+ "instagram": {
687
+ "agent": "my-agent"
688
+ },
689
+ "telegram": {
690
+ "agent": "my-agent"
691
+ },
692
+ "gmail": {
693
+ "agent": "my-agent",
694
+ "poll_interval": 30,
695
+ "label_filter": "INBOX"
515
696
  }
516
697
  }
517
698
  ```
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "agentkernel"
7
- version = "0.2.8"
7
+ version = "0.2.10"
8
8
  description = "Agent Kernel - Unified AI Agents Runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -49,8 +49,8 @@ redis = [
49
49
  "redis>=7.1.0",
50
50
  ]
51
51
  openai = [
52
- "openai-agents>=0.2.3",
53
- "openinference-instrumentation-openai-agents>=1.3.0",
52
+ "openai-agents>=0.6.3",
53
+ "openinference-instrumentation-openai-agents>=1.4.0",
54
54
  ]
55
55
  adk = [
56
56
  "google-adk>=1.14.1",
@@ -63,7 +63,8 @@ api = [
63
63
  "gunicorn>=23.0.0"
64
64
  ]
65
65
  slack = [
66
- "slack-bolt==1.22.0"
66
+ "slack-bolt==1.22.0",
67
+ "httpx>=0.27.0"
67
68
  ]
68
69
  whatsapp = [
69
70
  "httpx>=0.27.0"
@@ -77,6 +78,12 @@ instagram = [
77
78
  telegram = [
78
79
  "httpx>=0.27.0"
79
80
  ]
81
+ gmail = [
82
+ "google-auth>=2.0.0",
83
+ "google-auth-oauthlib>=1.0.0",
84
+ "google-auth-httplib2>=0.2.0",
85
+ "google-api-python-client>=2.0.0",
86
+ ]
80
87
  test = [
81
88
  "pytest>=8.4.1",
82
89
  "pytest-asyncio>=1.2.0",
@@ -84,6 +91,10 @@ test = [
84
91
  "pytest-html>=4.1.1",
85
92
  "pytest-order>=1.3.0",
86
93
  "rapidfuzz>=3.14.1",
94
+ "ragas>=0.4.1",
95
+ "datasets>=2.14.0",
96
+ "pandas>=2.0.0",
97
+ "litellm>=1.74.9",
87
98
  ]
88
99
  a2a = [
89
100
  "a2a-sdk[http-server]>=0.3.6",
@@ -9,8 +9,9 @@ from a2a.types import AgentCard, InternalError, UnsupportedOperationError
9
9
  from a2a.utils import new_agent_text_message
10
10
  from a2a.utils.errors import ServerError
11
11
 
12
- from ...core import Agent, AgentService, GlobalRuntime
12
+ from ...core import Agent, AgentService
13
13
  from ...core.config import AKConfig
14
+ from ...core.runtime import Runtime
14
15
 
15
16
 
16
17
  class A2A:
@@ -69,7 +70,7 @@ class A2A:
69
70
  return
70
71
  if not AKConfig.get().a2a.enabled:
71
72
  return
72
- agents: dict[str, Agent] = GlobalRuntime.instance().agents()
73
+ agents: dict[str, Agent] = Runtime.current().agents()
73
74
  for name, agent in agents.items():
74
75
  whitelisted = AKConfig.get().a2a.agents == ["*"] or name in AKConfig.get().a2a.agents
75
76
  if not whitelisted:
@@ -17,7 +17,8 @@ from agentkernel.core.model import (
17
17
  AgentRequestText,
18
18
  )
19
19
 
20
- from ..core import AgentService, GlobalRuntime
20
+ from ..core import AgentService, Config
21
+ from ..core.runtime import Runtime
21
22
 
22
23
 
23
24
  class RESTRequestHandler(ABC):
@@ -37,7 +38,8 @@ class RESTRequestHandler(ABC):
37
38
 
38
39
  @router.get("/agents")
39
40
  def list_agents():
40
- return {"agents": list(GlobalRuntime.instance().agents().keys())}
41
+ from ..core.runtime import Runtime
42
+ return {"agents": list(Runtime.current().agents().keys())}
41
43
 
42
44
  """
43
45
  pass
@@ -55,6 +57,7 @@ class AgentRESTRequestHandler(RESTRequestHandler):
55
57
 
56
58
  def __init__(self):
57
59
  self._log = logging.getLogger("ak.api.agent")
60
+ self._max_file_size = Config.get().api.max_file_size
58
61
 
59
62
  class FileData(BaseModel):
60
63
  """Represents a file attachment"""
@@ -92,7 +95,7 @@ class AgentRESTRequestHandler(RESTRequestHandler):
92
95
 
93
96
  @router.get("/agents")
94
97
  def list_agents():
95
- return {"agents": list(GlobalRuntime.instance().agents().keys())}
98
+ return {"agents": list(Runtime.current().agents().keys())}
96
99
 
97
100
  @router.post("/run")
98
101
  async def run(body: AgentRESTRequestHandler.RunRequest):
@@ -224,6 +227,15 @@ class AgentRESTRequestHandler(RESTRequestHandler):
224
227
  self._log.debug(f"Processing uploaded file: {file.filename}")
225
228
  # Read file content
226
229
  content = await file.read()
230
+
231
+ # Validate file size
232
+ file_size = len(content)
233
+ if file_size > self._max_file_size:
234
+ raise ValueError(
235
+ f"File {file.filename} exceeds maximum size of {self._max_file_size / (1024 * 1024):.2f} MB "
236
+ f"(size: {file_size / (1024 * 1024):.2f} MB)"
237
+ )
238
+
227
239
  # Encode to base64
228
240
  file_data_base64 = base64.b64encode(content).decode("utf-8")
229
241
 
@@ -245,6 +257,15 @@ class AgentRESTRequestHandler(RESTRequestHandler):
245
257
  self._log.debug(f"Processing uploaded image: {image.filename}")
246
258
  # Read image content
247
259
  content = await image.read()
260
+
261
+ # Validate image size
262
+ image_size = len(content)
263
+ if image_size > self._max_file_size:
264
+ raise ValueError(
265
+ f"Image {image.filename} exceeds maximum size of {self._max_file_size / (1024 * 1024):.2f} MB "
266
+ f"(size: {image_size / (1024 * 1024):.2f} MB)"
267
+ )
268
+
248
269
  # Encode to base64
249
270
  image_data_base64 = base64.b64encode(content).decode("utf-8")
250
271
 
@@ -4,8 +4,9 @@ from typing import Any
4
4
  from fastmcp import Context, FastMCP
5
5
  from fastmcp.server.http import StarletteWithLifespan
6
6
 
7
- from ...core import Agent, AgentService, GlobalRuntime
7
+ from ...core import Agent, AgentService
8
8
  from ...core.config import AKConfig
9
+ from ...core.runtime import Runtime
9
10
 
10
11
 
11
12
  class MCP:
@@ -60,7 +61,7 @@ class MCP:
60
61
  if cls._fastmcp is None:
61
62
  cls._fastmcp = FastMCP("Agent Kernel FastMCP Instance")
62
63
  if AKConfig.get().mcp.expose_agents:
63
- agents: dict[str, Agent] = GlobalRuntime.instance().agents()
64
+ agents: dict[str, Agent] = Runtime.current().agents()
64
65
  for name, agent in agents.items():
65
66
  whitelisted = AKConfig.get().mcp.agents == ["*"] or name in AKConfig.get().mcp.agents
66
67
  if not whitelisted:
@@ -24,7 +24,7 @@ from .model import (
24
24
  )
25
25
  from .config import AKConfig as Config
26
26
  from .module import Module
27
- from .runtime import GlobalRuntime, Runtime
27
+ from .runtime import Runtime, AuxiliaryCache
28
28
  from .service import AgentService
29
- from .hooks import Prehook, Posthook
29
+ from .hooks import PreHook, PostHook
30
30
  from .util.key_value_cache import KeyValueCache
@@ -3,6 +3,7 @@ import logging
3
3
  from abc import ABC, abstractmethod
4
4
  from typing import Any, List
5
5
 
6
+ from ..core.hooks import PostHook, PreHook
6
7
  from .config import AKConfig
7
8
  from .model import AgentReply, AgentRequest
8
9
  from .util.key_value_cache import KeyValueCache
@@ -197,6 +198,8 @@ class Agent(ABC):
197
198
  """
198
199
  self._name = name
199
200
  self._runner = runner
201
+ self._pre_hooks = []
202
+ self._post_hooks = []
200
203
 
201
204
  @property
202
205
  def name(self) -> str:
@@ -212,6 +215,42 @@ class Agent(ABC):
212
215
  """
213
216
  return self._runner
214
217
 
218
+ @property
219
+ def pre_hooks(self) -> list[PreHook]:
220
+ """
221
+ Returns the list of pre-execution hooks registered for the agent.
222
+ """
223
+ return self._pre_hooks
224
+
225
+ @property
226
+ def post_hooks(self) -> list[PostHook]:
227
+ """
228
+ Returns the list of post-execution hooks registered for the agent.
229
+ """
230
+ return self._post_hooks
231
+
232
+ def attach_pre_hooks(self, hooks: list[PreHook]):
233
+ """
234
+ Attaches pre-execution hooks to the agent.
235
+ Duplicate hook objects are ignored to prevent multiple registrations
236
+ of the same hook.
237
+ :param hooks: List of pre-execution hooks to attach.
238
+ """
239
+ for hook in hooks:
240
+ if hook not in self._pre_hooks:
241
+ self._pre_hooks.append(hook)
242
+
243
+ def attach_post_hooks(self, hooks: list[PostHook]):
244
+ """
245
+ Attaches post-execution hooks to the agent.
246
+ Duplicate hook objects are ignored to prevent multiple registrations
247
+ of the same hook.
248
+ :param hooks: List of post-execution hooks to attach.
249
+ """
250
+ for hook in hooks:
251
+ if hook not in self._post_hooks:
252
+ self._post_hooks.append(hook)
253
+
215
254
  @staticmethod
216
255
  def _generate_a2a_card(agent_name: str, description: str, skills: List):
217
256
  """