naas-abi-core 1.0.0__py3-none-any.whl
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.
- naas_abi_core/__init__.py +1 -0
- naas_abi_core/apps/api/api.py +242 -0
- naas_abi_core/apps/api/api_test.py +281 -0
- naas_abi_core/apps/api/openapi_doc.py +307 -0
- naas_abi_core/apps/mcp/mcp_server.py +243 -0
- naas_abi_core/apps/mcp/mcp_server_test.py +163 -0
- naas_abi_core/apps/terminal_agent/main.py +555 -0
- naas_abi_core/apps/terminal_agent/terminal_style.py +175 -0
- naas_abi_core/cli/__init__.py +53 -0
- naas_abi_core/cli/agent.py +30 -0
- naas_abi_core/cli/chat.py +26 -0
- naas_abi_core/cli/config.py +49 -0
- naas_abi_core/cli/init.py +13 -0
- naas_abi_core/cli/module.py +28 -0
- naas_abi_core/cli/new.py +13 -0
- naas_abi_core/cli/secret.py +79 -0
- naas_abi_core/engine/Engine.py +87 -0
- naas_abi_core/engine/EngineProxy.py +109 -0
- naas_abi_core/engine/Engine_test.py +6 -0
- naas_abi_core/engine/IEngine.py +91 -0
- naas_abi_core/engine/conftest.py +45 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration.py +160 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_GenericLoader.py +49 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService.py +131 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService_test.py +26 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService.py +116 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService.py +171 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService.py +65 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_test.py +9 -0
- naas_abi_core/engine/engine_configuration/utils/PydanticModelValidator.py +15 -0
- naas_abi_core/engine/engine_loaders/EngineModuleLoader.py +302 -0
- naas_abi_core/engine/engine_loaders/EngineOntologyLoader.py +16 -0
- naas_abi_core/engine/engine_loaders/EngineServiceLoader.py +47 -0
- naas_abi_core/integration/__init__.py +7 -0
- naas_abi_core/integration/integration.py +28 -0
- naas_abi_core/models/Model.py +198 -0
- naas_abi_core/models/OpenRouter.py +15 -0
- naas_abi_core/models/OpenRouter_test.py +36 -0
- naas_abi_core/module/Module.py +245 -0
- naas_abi_core/module/ModuleAgentLoader.py +49 -0
- naas_abi_core/module/ModuleUtils.py +20 -0
- naas_abi_core/modules/templatablesparqlquery/README.md +196 -0
- naas_abi_core/modules/templatablesparqlquery/__init__.py +39 -0
- naas_abi_core/modules/templatablesparqlquery/ontologies/TemplatableSparqlQueryOntology.ttl +116 -0
- naas_abi_core/modules/templatablesparqlquery/workflows/GenericWorkflow.py +48 -0
- naas_abi_core/modules/templatablesparqlquery/workflows/TemplatableSparqlQueryLoader.py +192 -0
- naas_abi_core/pipeline/__init__.py +6 -0
- naas_abi_core/pipeline/pipeline.py +70 -0
- naas_abi_core/services/__init__.py +0 -0
- naas_abi_core/services/agent/Agent.py +1619 -0
- naas_abi_core/services/agent/AgentMemory_test.py +28 -0
- naas_abi_core/services/agent/Agent_test.py +214 -0
- naas_abi_core/services/agent/IntentAgent.py +1171 -0
- naas_abi_core/services/agent/IntentAgent_test.py +139 -0
- naas_abi_core/services/agent/beta/Embeddings.py +180 -0
- naas_abi_core/services/agent/beta/IntentMapper.py +119 -0
- naas_abi_core/services/agent/beta/LocalModel.py +88 -0
- naas_abi_core/services/agent/beta/VectorStore.py +89 -0
- naas_abi_core/services/agent/test_agent_memory.py +278 -0
- naas_abi_core/services/agent/test_postgres_integration.py +145 -0
- naas_abi_core/services/cache/CacheFactory.py +31 -0
- naas_abi_core/services/cache/CachePort.py +63 -0
- naas_abi_core/services/cache/CacheService.py +246 -0
- naas_abi_core/services/cache/CacheService_test.py +85 -0
- naas_abi_core/services/cache/adapters/secondary/CacheFSAdapter.py +39 -0
- naas_abi_core/services/object_storage/ObjectStorageFactory.py +57 -0
- naas_abi_core/services/object_storage/ObjectStoragePort.py +47 -0
- naas_abi_core/services/object_storage/ObjectStorageService.py +41 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterFS.py +52 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterNaas.py +131 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterS3.py +171 -0
- naas_abi_core/services/ontology/OntologyPorts.py +36 -0
- naas_abi_core/services/ontology/OntologyService.py +17 -0
- naas_abi_core/services/ontology/adaptors/secondary/OntologyService_SecondaryAdaptor_NERPort.py +37 -0
- naas_abi_core/services/secret/Secret.py +138 -0
- naas_abi_core/services/secret/SecretPorts.py +40 -0
- naas_abi_core/services/secret/Secret_test.py +65 -0
- naas_abi_core/services/secret/adaptors/secondary/Base64Secret.py +57 -0
- naas_abi_core/services/secret/adaptors/secondary/Base64Secret_test.py +39 -0
- naas_abi_core/services/secret/adaptors/secondary/NaasSecret.py +81 -0
- naas_abi_core/services/secret/adaptors/secondary/NaasSecret_test.py +25 -0
- naas_abi_core/services/secret/adaptors/secondary/dotenv_secret_secondaryadaptor.py +26 -0
- naas_abi_core/services/triple_store/TripleStoreFactory.py +116 -0
- naas_abi_core/services/triple_store/TripleStorePorts.py +223 -0
- naas_abi_core/services/triple_store/TripleStoreService.py +419 -0
- naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune.py +1284 -0
- naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune_test.py +284 -0
- naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph.py +597 -0
- naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph_test.py +1474 -0
- naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__Filesystem.py +223 -0
- naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__ObjectStorage.py +234 -0
- naas_abi_core/services/triple_store/adaptors/secondary/base/TripleStoreService__SecondaryAdaptor__FileBase.py +18 -0
- naas_abi_core/services/vector_store/IVectorStorePort.py +101 -0
- naas_abi_core/services/vector_store/IVectorStorePort_test.py +189 -0
- naas_abi_core/services/vector_store/VectorStoreFactory.py +47 -0
- naas_abi_core/services/vector_store/VectorStoreService.py +171 -0
- naas_abi_core/services/vector_store/VectorStoreService_test.py +185 -0
- naas_abi_core/services/vector_store/__init__.py +13 -0
- naas_abi_core/services/vector_store/adapters/QdrantAdapter.py +251 -0
- naas_abi_core/services/vector_store/adapters/QdrantAdapter_test.py +57 -0
- naas_abi_core/utils/Expose.py +53 -0
- naas_abi_core/utils/Graph.py +182 -0
- naas_abi_core/utils/JSON.py +49 -0
- naas_abi_core/utils/LazyLoader.py +44 -0
- naas_abi_core/utils/Logger.py +12 -0
- naas_abi_core/utils/OntologyReasoner.py +141 -0
- naas_abi_core/utils/OntologyYaml.disabled.py +679 -0
- naas_abi_core/utils/SPARQL.py +256 -0
- naas_abi_core/utils/Storage.py +33 -0
- naas_abi_core/utils/StorageUtils.py +398 -0
- naas_abi_core/utils/String.py +52 -0
- naas_abi_core/utils/Workers.py +114 -0
- naas_abi_core/utils/__init__.py +0 -0
- naas_abi_core/utils/onto2py/README.md +0 -0
- naas_abi_core/utils/onto2py/__init__.py +10 -0
- naas_abi_core/utils/onto2py/__main__.py +29 -0
- naas_abi_core/utils/onto2py/onto2py.py +611 -0
- naas_abi_core/utils/onto2py/tests/ttl2py_test.py +271 -0
- naas_abi_core/workflow/__init__.py +5 -0
- naas_abi_core/workflow/workflow.py +48 -0
- naas_abi_core-1.0.0.dist-info/METADATA +75 -0
- naas_abi_core-1.0.0.dist-info/RECORD +124 -0
- naas_abi_core-1.0.0.dist-info/WHEEL +4 -0
- naas_abi_core-1.0.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
TAGS_METADATA = [
|
|
2
|
+
{
|
|
3
|
+
"name": "Overview",
|
|
4
|
+
"description": """
|
|
5
|
+
### Project Overview
|
|
6
|
+
The **ABI** (Artificial Business Intelligence) project is a Python-based backend framework designed to serve as the core infrastructure for building an Organizational AI System.
|
|
7
|
+
This system empowers businesses to integrate, manage, and scale AI-driven operations with a focus on ontology, assistant-driven workflows, and analytics.\n
|
|
8
|
+
Designed for flexibility and scalability, ABI provides a customizable framework suitable for organizations aiming to create intelligent, automated systems tailored to their needs.
|
|
9
|
+
|
|
10
|
+
### API Overview
|
|
11
|
+
The ABI API allows users and applications to interact with ABI's capabilities for business process automation and intelligence.\n
|
|
12
|
+
This document describes the current version of the ABI API, which provides access to agents, pipelines, workflows, integrations, ontology management and analytics features.
|
|
13
|
+
""",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "Authentication",
|
|
17
|
+
"description": """
|
|
18
|
+
Authentication uses a Bearer token that can be provided either in the Authorization header (e.g. 'Authorization: Bearer `<token>`') or as a query parameter (e.g. '?token=`<token>`').
|
|
19
|
+
The token must match the `ABI_API_KEY` environment variable.
|
|
20
|
+
Contact your administrator to get the token.
|
|
21
|
+
|
|
22
|
+
*Authentication with Authorization header:*
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import requests
|
|
26
|
+
|
|
27
|
+
url = "https://<your-registry-name>.default.space.naas.ai/agents/abi/completion"
|
|
28
|
+
|
|
29
|
+
headers = {
|
|
30
|
+
"Authorization": f"Bearer {token}"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
response = requests.post(url, headers=headers)
|
|
34
|
+
print(response.json())
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
*Authentication with query parameter:*
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import requests
|
|
41
|
+
|
|
42
|
+
url = "https://<your-registry-name>.default.space.naas.ai/agents/abi/completion?token=<token>"
|
|
43
|
+
|
|
44
|
+
response = requests.post(url)
|
|
45
|
+
print(response.json())
|
|
46
|
+
```
|
|
47
|
+
""",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "Connections",
|
|
51
|
+
"description": """
|
|
52
|
+
Connections are currently configured using Integration secrets (API keys, credentials) set up in the GitHub project settings. \n
|
|
53
|
+
Learn more about the data access and secrets key [here](https://github.com/jupyter-naas/abi/blob/main/README.md#setup-github-repository-secrets).
|
|
54
|
+
|
|
55
|
+
### Agicap
|
|
56
|
+
Required:
|
|
57
|
+
- `AGICAP_USERNAME`: Username of your Agicap account
|
|
58
|
+
- `AGICAP_PASSWORD`: Password of your Agicap account
|
|
59
|
+
- `AGICAP_CLIENT_ID`: Client ID of your Agicap account. [Get your client ID](https://app.agicap.com/fr/app/organization-advanced-settings/public-api)
|
|
60
|
+
- `AGICAP_CLIENT_SECRET`: Client Secret of your Agicap account. [Get your client secret](https://app.agicap.com/fr/app/organization-advanced-settings/public-api)
|
|
61
|
+
- `AGICAP_BEARER_TOKEN`: Bearer Token of your Agicap account.
|
|
62
|
+
- `AGICAP_API_TOKEN`: API token of your Agicap account. [Get your API token](https://app.agicap.com/fr/app/parametres/openapi)
|
|
63
|
+
|
|
64
|
+
### Algolia
|
|
65
|
+
Required:
|
|
66
|
+
- `ALGOLIA_API_KEY`: API key of your Algolia account. [Get your API key](https://www.algolia.com/api-keys)
|
|
67
|
+
- `ALGOLIA_APPLICATION_ID`: Application ID of your Algolia account. [Get your application ID](https://www.algolia.com/api-keys)
|
|
68
|
+
|
|
69
|
+
### Airtable
|
|
70
|
+
Required:
|
|
71
|
+
- `AIRTABLE_API_KEY`: API key of your Airtable account. [Get your API key](https://airtable.com/create/tokens)
|
|
72
|
+
- `AIRTABLE_BASE_ID`: Base ID of your Airtable account. [Get your base ID](https://airtable.com/create/tokens)
|
|
73
|
+
|
|
74
|
+
### AWS
|
|
75
|
+
Required:
|
|
76
|
+
- `AWS_ACCESS_KEY_ID`: Access key ID of your AWS account. [Get your access key ID](https://us-east-1.console.aws.amazon.com/iam/home)
|
|
77
|
+
- `AWS_SECRET_ACCESS_KEY`: Secret access key of your AWS account. [Get your secret access key](https://us-east-1.console.aws.amazon.com/iam/home)
|
|
78
|
+
- `AWS_REGION`: Region of your AWS account. [Get your region](https://us-east-1.console.aws.amazon.com/iam/home)
|
|
79
|
+
|
|
80
|
+
### Brevo
|
|
81
|
+
Required:
|
|
82
|
+
- `BREVO_API_KEY`: API key of your Brevo account. [Get your API key](https://help.brevo.com/hc/en-us/articles/209467485)
|
|
83
|
+
|
|
84
|
+
### Clockify
|
|
85
|
+
Required:
|
|
86
|
+
- `CLOCKIFY_API_KEY`: API key of your Clockify account. [Get your API key](https://clockify.me/user/settings)
|
|
87
|
+
|
|
88
|
+
### Discord
|
|
89
|
+
Required:
|
|
90
|
+
- `DISCORD_API_KEY`: API key of your Discord account. [Get your API key](https://discord.com/developers/applications)
|
|
91
|
+
|
|
92
|
+
### Github
|
|
93
|
+
Required:
|
|
94
|
+
- `GITHUB_ACCESS_TOKEN`: Access token of your Github account. [Get your access token](https://github.com/settings/tokens)
|
|
95
|
+
|
|
96
|
+
### Gladia
|
|
97
|
+
Required:
|
|
98
|
+
- `GLADIA_API_KEY`: API key of your Gladia account. [Get your API key](https://www.gladia.ai/)
|
|
99
|
+
|
|
100
|
+
### Gmail
|
|
101
|
+
Required:
|
|
102
|
+
- `GMAIL_EMAIL`: Email of your Gmail account.
|
|
103
|
+
- `GMAIL_APP_PASSWORD`: App password of your Gmail account. [Get your app password](https://support.google.com/mail/answer/185833)
|
|
104
|
+
|
|
105
|
+
### Harvest
|
|
106
|
+
Required:
|
|
107
|
+
- `HARVEST_API_KEY`: API key of your Harvest account. [Get your API key](https://app.harvestapp.com/account/api)
|
|
108
|
+
- `HARVEST_ACCOUNT_ID`: Account ID of your Harvest account.
|
|
109
|
+
|
|
110
|
+
### HubSpot
|
|
111
|
+
Required:
|
|
112
|
+
- `HUBSPOT_ACCESS_TOKEN`: Access token of your HubSpot account. [Get your access token](https://developers.hubspot.com/docs/api/private-apps)
|
|
113
|
+
|
|
114
|
+
### Instagram
|
|
115
|
+
Required:
|
|
116
|
+
- `INSTAGRAM_ACCESS_TOKEN`: Access token of your Instagram account. [Get your access token](https://developers.facebook.com/docs/instagram-api)
|
|
117
|
+
|
|
118
|
+
### LinkedIn
|
|
119
|
+
Required:
|
|
120
|
+
- `li_at` cookie: li_at cookie of your LinkedIn account. [Get your li_at cookie](https://www.notion.so/LinkedIn-driver-Get-your-cookies)
|
|
121
|
+
- `JSESSIONID` cookie: JSESSIONID cookie of your LinkedIn account. [Get your JSESSIONID cookie](https://www.notion.so/LinkedIn-driver-Get-your-cookies)
|
|
122
|
+
|
|
123
|
+
### Mailchimp
|
|
124
|
+
Required:
|
|
125
|
+
- `MAILCHIMP_API_KEY`: API key of your Mailchimp account. [Get your API key](https://mailchimp.com/developer/api/)
|
|
126
|
+
- `MAILCHIMP_SERVER_PREFIX`: Server prefix of your Mailchimp account. [Get your server prefix](https://mailchimp.com/developer/api/)
|
|
127
|
+
|
|
128
|
+
### Mercury
|
|
129
|
+
Required:
|
|
130
|
+
- `MERCURY_API_TOKEN`: API token of your Mercury account. [Get your API token](https://app.mercury.com/settings/tokens)
|
|
131
|
+
|
|
132
|
+
### NewsAPI
|
|
133
|
+
Required:
|
|
134
|
+
- `NEWSAPI_API_KEY`: API key of your NewsAPI account. [Get your API key](https://newsapi.org/register)
|
|
135
|
+
|
|
136
|
+
### Notion
|
|
137
|
+
Required:
|
|
138
|
+
- `NOTION_API_KEY`: API key of your Notion account. [Get your API key](https://www.notion.so/my-integrations)
|
|
139
|
+
|
|
140
|
+
### OneDrive
|
|
141
|
+
Required:
|
|
142
|
+
- `ONEDRIVE_ACCESS_TOKEN`: Access token of your OneDrive account. [Get your access token](https://learn.microsoft.com/en-us/onedrive/developer/rest-api/getting-started/)
|
|
143
|
+
|
|
144
|
+
### Pennylane
|
|
145
|
+
Required:
|
|
146
|
+
- `PENNYLANE_API_TOKEN`: API token of your Pennylane account. [Get your API token](https://pennylane.readme.io/docs/get-my-api-token)
|
|
147
|
+
|
|
148
|
+
### Perplexity
|
|
149
|
+
Required:
|
|
150
|
+
- `PERPLEXITY_API_KEY`: API key of your Perplexity account. [Get your API key](https://docs.perplexity.ai/docs/getting-started)
|
|
151
|
+
|
|
152
|
+
### Pipedrive
|
|
153
|
+
Required:
|
|
154
|
+
- `PIPEDRIVE_API_KEY`: API key of your Pipedrive account. [Get your API key](https://app.pipedrive.com/settings/api)
|
|
155
|
+
|
|
156
|
+
### PostgreSQL
|
|
157
|
+
Required:
|
|
158
|
+
- `POSTGRES_HOST`: Host of your PostgreSQL database.
|
|
159
|
+
- `POSTGRES_PORT`: Port of your PostgreSQL database.
|
|
160
|
+
- `POSTGRES_DB`: Database name of your PostgreSQL database.
|
|
161
|
+
- `POSTGRES_USER`: User of your PostgreSQL database.
|
|
162
|
+
- `POSTGRES_PASSWORD`: Password of your PostgreSQL database.
|
|
163
|
+
|
|
164
|
+
### Qonto
|
|
165
|
+
Required:
|
|
166
|
+
- `QONTO_ORGANIZATION_SLUG`: Organization slug of your Qonto account. [Get your organization slug](https://support-fr.qonto.com/hc/en-us/articles/23947692362513)
|
|
167
|
+
- `QONTO_SECRET_KEY`: Secret key of your Qonto account. [Get your secret key](https://support-fr.qonto.com/hc/en-us/articles/23947692362513)
|
|
168
|
+
|
|
169
|
+
### Replicate
|
|
170
|
+
Required:
|
|
171
|
+
- `REPLICATE_API_KEY`: API key of your Replicate account. [Get your API key](https://replicate.com/account/api-tokens)
|
|
172
|
+
|
|
173
|
+
### Serper
|
|
174
|
+
Required:
|
|
175
|
+
- `SERPER_API_KEY`: API key of your Serper account. [Get your API key](https://serper.dev/api-key)
|
|
176
|
+
|
|
177
|
+
### Slack
|
|
178
|
+
Required:
|
|
179
|
+
- `SLACK_BOT_TOKEN`: Bot token of your Slack account. [Get your bot token](https://api.slack.com/apps)
|
|
180
|
+
|
|
181
|
+
### Stripe
|
|
182
|
+
Required:
|
|
183
|
+
- `STRIPE_API_KEY`: API key of your Stripe account. [Get your API key](https://dashboard.stripe.com/apikeys)
|
|
184
|
+
|
|
185
|
+
### Supabase
|
|
186
|
+
Required:
|
|
187
|
+
- `SUPABASE_URL`: URL of your Supabase account. [Get your URL](https://app.supabase.com/project/_/settings/api)
|
|
188
|
+
- `SUPABASE_KEY`: Key of your Supabase account. [Get your key](https://app.supabase.com/project/_/settings/api)
|
|
189
|
+
|
|
190
|
+
### TikTok
|
|
191
|
+
Required:
|
|
192
|
+
- `TIKTOK_ACCESS_TOKEN`: Access token of your TikTok account. [Get your access token](https://developers.tiktok.com/)
|
|
193
|
+
|
|
194
|
+
### WhatsApp
|
|
195
|
+
Required:
|
|
196
|
+
- `WHATSAPP_ACCESS_TOKEN`: Access token of your WhatsApp account. [Get your access token](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started)
|
|
197
|
+
|
|
198
|
+
### Yahoo Finance
|
|
199
|
+
Required:
|
|
200
|
+
- `YAHOO_FINANCE_API_KEY`: API key of your Yahoo Finance account. [Get your API key](https://www.yahoofinanceapi.com/)
|
|
201
|
+
|
|
202
|
+
### YouTube
|
|
203
|
+
Required:
|
|
204
|
+
- `YOUTUBE_API_KEY`: API key of your YouTube account. [Get your API key](https://console.cloud.google.com/apis/credentials)
|
|
205
|
+
|
|
206
|
+
### ZeroBounce
|
|
207
|
+
Required:
|
|
208
|
+
- `ZEROBOUNCE_API_KEY`: API key of your ZeroBounce account. [Get your API key](https://app.zerobounce.net/)
|
|
209
|
+
|
|
210
|
+
""",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"name": "Agents",
|
|
214
|
+
"description": """
|
|
215
|
+
API endpoints for interacting with ABI's agents.
|
|
216
|
+
|
|
217
|
+
### Core Agents:
|
|
218
|
+
- Abi: Manages and coordinates other agents
|
|
219
|
+
- Ontology: Manages and coordinates other agents
|
|
220
|
+
- Naas: Manages and coordinates other agents
|
|
221
|
+
- Support: Provides help and guidance for using ABI
|
|
222
|
+
|
|
223
|
+
### Marketplace Agents:
|
|
224
|
+
- Custom agents with deep expertise in specific domains
|
|
225
|
+
- Can be configured and trained for specialized tasks
|
|
226
|
+
- Extensible through custom tools and knowledge bases
|
|
227
|
+
|
|
228
|
+
Each agent can be accessed through dedicated endpoints that allow:
|
|
229
|
+
- Completion requests for generating responses
|
|
230
|
+
- Chat interactions for ongoing conversations
|
|
231
|
+
- Tool execution for specific tasks
|
|
232
|
+
- Configuration updates for customizing behavior
|
|
233
|
+
|
|
234
|
+
Agents leverage various tools including integrations, pipelines and workflows to accomplish tasks. They can be extended with custom tools and knowledge to enhance their capabilities.
|
|
235
|
+
|
|
236
|
+
""",
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"name": "Pipelines",
|
|
240
|
+
"description": """
|
|
241
|
+
API endpoints for interacting with ABI's pipelines.
|
|
242
|
+
""",
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"name": "Workflows",
|
|
246
|
+
"description": """
|
|
247
|
+
API endpoints for interacting with ABI's workflows.
|
|
248
|
+
""",
|
|
249
|
+
},
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
API_LANDING_HTML = """
|
|
253
|
+
<!DOCTYPE html>
|
|
254
|
+
<html>
|
|
255
|
+
<head>
|
|
256
|
+
<title>[TITLE]</title>
|
|
257
|
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
|
258
|
+
<style>
|
|
259
|
+
body {
|
|
260
|
+
font-family: Arial, sans-serif;
|
|
261
|
+
display: flex;
|
|
262
|
+
flex-direction: column;
|
|
263
|
+
align-items: center;
|
|
264
|
+
justify-content: center;
|
|
265
|
+
height: 100vh;
|
|
266
|
+
margin: 0;
|
|
267
|
+
background-color: #000000;
|
|
268
|
+
color: white;
|
|
269
|
+
}
|
|
270
|
+
.logo {
|
|
271
|
+
width: 200px;
|
|
272
|
+
margin-bottom: 20px;
|
|
273
|
+
}
|
|
274
|
+
h1 {
|
|
275
|
+
font-size: 48px;
|
|
276
|
+
margin-bottom: 40px;
|
|
277
|
+
}
|
|
278
|
+
.buttons {
|
|
279
|
+
display: flex;
|
|
280
|
+
gap: 20px;
|
|
281
|
+
}
|
|
282
|
+
a {
|
|
283
|
+
padding: 12px 24px;
|
|
284
|
+
font-size: 18px;
|
|
285
|
+
border: none;
|
|
286
|
+
border-radius: 4px;
|
|
287
|
+
cursor: pointer;
|
|
288
|
+
text-decoration: none;
|
|
289
|
+
color: white;
|
|
290
|
+
background-color: #007bff;
|
|
291
|
+
transition: background-color 0.2s;
|
|
292
|
+
}
|
|
293
|
+
a:hover {
|
|
294
|
+
background-color: #0056b3;
|
|
295
|
+
}
|
|
296
|
+
</style>
|
|
297
|
+
</head>
|
|
298
|
+
<body>
|
|
299
|
+
<img src="/static/[LOGO_NAME]" alt="Logo" class="logo">
|
|
300
|
+
<h1>Welcome to [TITLE]!</h1>
|
|
301
|
+
<p>[TITLE] is a tool that allows you to interact with ABI's capabilities for business process automation and intelligence.</p>
|
|
302
|
+
<div class="buttons">
|
|
303
|
+
<a href="/redoc">Go to Documentation</a>
|
|
304
|
+
</div>
|
|
305
|
+
</body>
|
|
306
|
+
</html>
|
|
307
|
+
"""
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ABI MCP Server - Lightweight HTTP-based Implementation
|
|
3
|
+
Exposes ABI agents as MCP tools with fast startup (no heavy imports)
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
|
+
|
|
11
|
+
import httpx
|
|
12
|
+
from dotenv import load_dotenv
|
|
13
|
+
from mcp.server.fastmcp import FastMCP
|
|
14
|
+
|
|
15
|
+
# Load environment variables from .env file if present
|
|
16
|
+
load_dotenv()
|
|
17
|
+
|
|
18
|
+
# Initialize FastMCP server
|
|
19
|
+
mcp = FastMCP("abi")
|
|
20
|
+
|
|
21
|
+
# Constants - Default to localhost for development, can be overridden by env var
|
|
22
|
+
ABI_API_BASE = os.environ.get("ABI_API_BASE", "http://localhost:9879")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_api_key() -> str:
|
|
26
|
+
"""Get the API key from environment variables"""
|
|
27
|
+
api_key = os.environ.get("ABI_API_KEY")
|
|
28
|
+
if not api_key:
|
|
29
|
+
print("❌ ABI_API_KEY not found in environment")
|
|
30
|
+
print("📝 Please add it to your .env file:")
|
|
31
|
+
print(" ABI_API_KEY=your_key_here")
|
|
32
|
+
exit(1)
|
|
33
|
+
return api_key
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def fetch_openapi_spec() -> Dict[str, Any]:
|
|
37
|
+
"""Fetch the OpenAPI specification to discover available agents"""
|
|
38
|
+
try:
|
|
39
|
+
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
40
|
+
response = await client.get(f"{ABI_API_BASE}/openapi.json")
|
|
41
|
+
response.raise_for_status()
|
|
42
|
+
return response.json()
|
|
43
|
+
except Exception as e:
|
|
44
|
+
print(f"❌ Failed to fetch OpenAPI spec: {e}")
|
|
45
|
+
return {}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def extract_agents_from_openapi(openapi_spec: Dict[str, Any]) -> List[Dict[str, str]]:
|
|
49
|
+
"""Extract agent information from OpenAPI specification"""
|
|
50
|
+
agents = []
|
|
51
|
+
paths = openapi_spec.get("paths", {})
|
|
52
|
+
|
|
53
|
+
for path, methods in paths.items():
|
|
54
|
+
# Look for agent completion endpoints
|
|
55
|
+
if "/agents/" in path and path.endswith("/completion"):
|
|
56
|
+
# Extract agent name from path like /agents/{agent_name}/completion
|
|
57
|
+
agent_name = path.split("/agents/")[1].split("/completion")[0]
|
|
58
|
+
|
|
59
|
+
# Get description from POST method
|
|
60
|
+
post_method = methods.get("post", {})
|
|
61
|
+
description = post_method.get("summary", f"{agent_name} agent completion")
|
|
62
|
+
|
|
63
|
+
agents.append(
|
|
64
|
+
{
|
|
65
|
+
"name": agent_name,
|
|
66
|
+
"description": description,
|
|
67
|
+
"function_name": agent_name_to_function_name(agent_name),
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
return agents
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def agent_name_to_function_name(agent_name: str) -> str:
|
|
75
|
+
"""Convert agent name to valid Python function name"""
|
|
76
|
+
# Replace spaces and special chars with underscores, convert to lowercase
|
|
77
|
+
function_name = re.sub(r"[^a-zA-Z0-9_]", "_", agent_name.lower())
|
|
78
|
+
# Remove multiple consecutive underscores
|
|
79
|
+
function_name = re.sub(r"_+", "_", function_name)
|
|
80
|
+
# Remove leading/trailing underscores
|
|
81
|
+
function_name = function_name.strip("_")
|
|
82
|
+
# Ensure it doesn't start with a number
|
|
83
|
+
if function_name and function_name[0].isdigit():
|
|
84
|
+
function_name = f"agent_{function_name}"
|
|
85
|
+
return function_name or "unknown_agent"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
async def call_abi_agent_http(agent_name: str, prompt: str, thread_id: int = 1) -> str:
|
|
89
|
+
"""Call ABI agents via HTTP to avoid heavy module imports"""
|
|
90
|
+
try:
|
|
91
|
+
headers = {
|
|
92
|
+
"Authorization": f"Bearer {get_api_key()}",
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
"User-Agent": "ABI-MCP/1.0",
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
data = {"prompt": prompt, "thread_id": thread_id}
|
|
98
|
+
|
|
99
|
+
url = f"{ABI_API_BASE}/agents/{agent_name}/completion"
|
|
100
|
+
|
|
101
|
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
102
|
+
response = await client.post(url, json=data, headers=headers)
|
|
103
|
+
response.raise_for_status()
|
|
104
|
+
return response.text.strip('"') # Remove JSON quotes
|
|
105
|
+
|
|
106
|
+
except httpx.ConnectError:
|
|
107
|
+
return f"❌ ABI API server not running at {ABI_API_BASE}. Please start it first with: uv run api"
|
|
108
|
+
except httpx.TimeoutException:
|
|
109
|
+
return f"⏱️ Timeout calling {agent_name} agent. The agent might be processing a complex request."
|
|
110
|
+
except httpx.HTTPStatusError as e:
|
|
111
|
+
if e.response.status_code == 401:
|
|
112
|
+
return (
|
|
113
|
+
"🔒 Authentication failed. Check your ABI_API_KEY environment variable."
|
|
114
|
+
)
|
|
115
|
+
elif e.response.status_code == 404:
|
|
116
|
+
return f"❓ Agent '{agent_name}' not found. Please check available agents via OpenAPI spec."
|
|
117
|
+
else:
|
|
118
|
+
return f"❌ HTTP {e.response.status_code} error calling {agent_name} agent: {e.response.text}"
|
|
119
|
+
except Exception as e:
|
|
120
|
+
return f"❌ Error calling {agent_name} agent: {str(e)}"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def create_agent_function(agent_name: str, description: str):
|
|
124
|
+
"""Create a dynamic agent function"""
|
|
125
|
+
|
|
126
|
+
async def agent_function(prompt: str, thread_id: int = 1) -> str:
|
|
127
|
+
return await call_abi_agent_http(agent_name, prompt, thread_id)
|
|
128
|
+
|
|
129
|
+
# Set function metadata
|
|
130
|
+
agent_function.__name__ = agent_name_to_function_name(agent_name)
|
|
131
|
+
agent_function.__doc__ = f"""{description}
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
prompt: Your question or request for the {agent_name} agent
|
|
135
|
+
thread_id: Thread ID for conversation context (default: 1)
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
return agent_function
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def wait_for_api():
|
|
142
|
+
"""Wait for the API to be available before starting"""
|
|
143
|
+
max_retries = 30 # Wait up to 5 minutes (30 * 10 seconds)
|
|
144
|
+
retry_delay = 10 # seconds
|
|
145
|
+
|
|
146
|
+
for attempt in range(max_retries):
|
|
147
|
+
try:
|
|
148
|
+
async with httpx.AsyncClient(timeout=5.0) as client:
|
|
149
|
+
response = await client.get(f"{ABI_API_BASE}")
|
|
150
|
+
if response.status_code == 200:
|
|
151
|
+
print("✅ API is ready!")
|
|
152
|
+
return True
|
|
153
|
+
except Exception:
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
if attempt < max_retries - 1:
|
|
157
|
+
print(
|
|
158
|
+
f"⏳ Waiting for API to be ready... (attempt {attempt + 1}/{max_retries})"
|
|
159
|
+
)
|
|
160
|
+
await asyncio.sleep(retry_delay)
|
|
161
|
+
|
|
162
|
+
print("❌ API did not become ready in time")
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
async def register_agents_dynamically():
|
|
167
|
+
"""Discover and register agents from OpenAPI specification"""
|
|
168
|
+
print("🔍 Discovering agents from OpenAPI specification...")
|
|
169
|
+
|
|
170
|
+
# Wait for API to be ready if not running locally
|
|
171
|
+
if not ABI_API_BASE.startswith("http://localhost"):
|
|
172
|
+
api_ready = await wait_for_api()
|
|
173
|
+
if not api_ready:
|
|
174
|
+
print("⚠️ API not ready, using fallback configuration")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
openapi_spec = await fetch_openapi_spec()
|
|
178
|
+
if not openapi_spec:
|
|
179
|
+
print("⚠️ Failed to fetch OpenAPI spec, falling back to basic agents")
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
agents = extract_agents_from_openapi(openapi_spec)
|
|
183
|
+
|
|
184
|
+
if not agents:
|
|
185
|
+
print("⚠️ No agents found in OpenAPI spec")
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
print(f"📡 Found {len(agents)} agents:")
|
|
189
|
+
|
|
190
|
+
for agent_info in agents:
|
|
191
|
+
agent_name = agent_info["name"]
|
|
192
|
+
description = agent_info["description"]
|
|
193
|
+
function_name = agent_info["function_name"]
|
|
194
|
+
|
|
195
|
+
print(f" • {agent_name} -> {function_name}()")
|
|
196
|
+
|
|
197
|
+
# Create and register the agent function
|
|
198
|
+
agent_function = create_agent_function(agent_name, description)
|
|
199
|
+
mcp.tool()(agent_function)
|
|
200
|
+
|
|
201
|
+
print("✅ All agents registered successfully!")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
async def setup():
|
|
205
|
+
"""Setup function to initialize the server"""
|
|
206
|
+
# Quick startup - no heavy imports!
|
|
207
|
+
print("🚀 Starting lightweight ABI MCP Server...")
|
|
208
|
+
print(f"📡 Will connect to ABI API at: {ABI_API_BASE}")
|
|
209
|
+
|
|
210
|
+
# Validate API key exists
|
|
211
|
+
get_api_key()
|
|
212
|
+
print("🔑 API key loaded successfully")
|
|
213
|
+
|
|
214
|
+
# Dynamically discover and register agents
|
|
215
|
+
await register_agents_dynamically()
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def run():
|
|
219
|
+
"""Entry point for the script"""
|
|
220
|
+
# Run setup first
|
|
221
|
+
asyncio.run(setup())
|
|
222
|
+
|
|
223
|
+
# Determine transport type from environment
|
|
224
|
+
transport = os.environ.get("MCP_TRANSPORT", "stdio")
|
|
225
|
+
|
|
226
|
+
if transport == "sse":
|
|
227
|
+
# SSE transport for web deployment
|
|
228
|
+
print(
|
|
229
|
+
"🌐 Starting MCP server with SSE (Server-Sent Events) transport on port 8000"
|
|
230
|
+
)
|
|
231
|
+
mcp.run(transport="sse")
|
|
232
|
+
elif transport == "http":
|
|
233
|
+
# HTTP transport using streamable-http
|
|
234
|
+
print("🌐 Starting MCP server with streamable HTTP transport")
|
|
235
|
+
mcp.run(transport="streamable-http")
|
|
236
|
+
else:
|
|
237
|
+
# STDIO transport for local Claude Desktop integration
|
|
238
|
+
print("📋 Starting MCP server with STDIO transport")
|
|
239
|
+
mcp.run(transport="stdio")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
run()
|