adaptive-memory-multi-model-router 2.16.0 → 2.16.2
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.
- package/.github/workflows/adapters-ci.yml +142 -0
- package/.github/workflows/auto-submit-sitemap.yml +41 -0
- package/.github/workflows/ci.yml +2 -5
- package/.github/workflows/mcp-pypi-publish.yml +34 -0
- package/.github/workflows/pypi-publish.yml +146 -0
- package/.github/workflows/tmlpd-publish.yml +23 -0
- package/README.md +245 -148
- package/RELEASE_v2.16.0.md +149 -0
- package/TECHNICAL_README.md +253 -0
- package/adapters/README.md +36 -0
- package/adapters/__init__.py +25 -0
- package/adapters/a3m_adapter/__init__.py +51 -0
- package/adapters/a3m_adapter/adapter/__init__.py +22 -0
- package/adapters/a3m_adapter/adapter/autogen.py +169 -0
- package/adapters/a3m_adapter/adapter/config.py +100 -0
- package/adapters/a3m_adapter/adapter/haystack.py +197 -0
- package/adapters/a3m_adapter/adapter/langchain.py +155 -0
- package/adapters/a3m_adapter/adapter/langgraph.py +196 -0
- package/adapters/a3m_adapter/adapter/llamaindex.py +162 -0
- package/adapters/a3m_adapter/adapter/pinecone.py +217 -0
- package/adapters/a3m_adapter/adapter/vercel.py +188 -0
- package/adapters/a3m_adapter/tests/__init__.py +1 -0
- package/adapters/a3m_adapter/tests/test_adapters.py +118 -0
- package/adapters/a3m_adapter/tests/test_integration.py +80 -0
- package/adapters/requirements-dev.txt +6 -0
- package/adapters/requirements.txt +4 -0
- package/adapters/setup.py +23 -0
- package/demo.py +251 -0
- package/discoverability-diagnosis.md +280 -0
- package/dist/analytics/costAnalytics.d.ts.map +1 -1
- package/dist/benchmark/reproducible.d.ts.map +1 -1
- package/dist/cache/semanticCache.d.ts.map +1 -1
- package/dist/cli/setupWizard.d.ts +257 -50
- package/dist/cli/setupWizard.d.ts.map +1 -1
- package/dist/cli/setupWizard.js +419 -109
- package/dist/cli/setupWizard.js.map +1 -1
- package/dist/cli/tui.d.ts +6 -0
- package/dist/cli/tui.js +96 -67
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli.js +9 -0
- package/dist/cost/budgetEnforcer.d.ts.map +1 -1
- package/dist/cost/costTracker.d.ts.map +1 -1
- package/dist/ensemble/multiRoundDialog.d.ts.map +1 -1
- package/dist/ensemble/shapleyValue.d.ts.map +1 -1
- package/dist/ensemble.d.ts +1 -1
- package/dist/ensemble.js +141 -0
- package/dist/integrations/langchainAdapter.d.ts.map +1 -1
- package/dist/integrations/langchainAdapter.js +3 -3
- package/dist/integrations/langchainAdapter.js.map +1 -1
- package/dist/integrations/oauth.d.ts.map +1 -1
- package/dist/integrations/scienceAdapter.d.ts.map +1 -1
- package/dist/memory/autoFetch.d.ts.map +1 -1
- package/dist/memory/hybridMemory.d.ts.map +1 -1
- package/dist/memory/memoryTree.d.ts.map +1 -1
- package/dist/memory/obsidianVault.d.ts.map +1 -1
- package/dist/memory/reasoningBank.d.ts.map +1 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/tracer.d.ts.map +1 -1
- package/dist/providers/providerConfig.d.ts.map +1 -1
- package/dist/providers/providerConfig.js +32 -17
- package/dist/providers/providerConfig.js.map +1 -1
- package/dist/routing/advancedRouter.d.ts.map +1 -1
- package/dist/routing/advancedRouter.js +106 -14
- package/dist/routing/advancedRouter.js.map +1 -1
- package/dist/routing/providerHealth.d.ts.map +1 -1
- package/dist/routing/providerRetry.d.ts.map +1 -1
- package/dist/routing/shadowSampler.d.ts.map +1 -0
- package/dist/routing/shadowSampler.js.map +1 -1
- package/dist/security/guardrails.d.ts.map +1 -1
- package/dist/server/handlers/chatHandler.d.ts.map +1 -1
- package/dist/server/handlers/completionsHandler.d.ts.map +1 -1
- package/dist/server/handlers/embeddingsHandler.d.ts.map +1 -1
- package/dist/server/handlers/healthHandler.d.ts.map +1 -1
- package/dist/server/handlers/metricsHandler.d.ts.map +1 -1
- package/dist/server/handlers/modelsHandler.d.ts.map +1 -1
- package/dist/server/metrics.d.ts.map +1 -1
- package/dist/server/proxyServer.d.ts.map +1 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/state.d.ts.map +1 -1
- package/dist/skills/__tests__/skill_manager.test.js +5 -265
- package/dist/skills/__tests__/skill_manager.test.js.map +1 -1
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/docker-compose.yml +84 -60
- package/docs/ARTICLE_Biology_Inspired_Routing.md +208 -0
- package/docs/ARTICLE_Master.md +78 -0
- package/docs/ARTICLE_Master_CN.md +78 -0
- package/docs/ARTICLE_OpenRouter_Stripe.md +140 -0
- package/docs/DEVPTO_ARTICLE.md +84 -0
- package/docs/HUMAN_STYLE_GUIDE.md +75 -0
- package/docs/IMPRINT_PLAN.md +88 -0
- package/docs/OPENROUTER_ALTERNATIVE.md +184 -0
- package/docs/SOCIAL_CAMPAIGN.md +316 -0
- package/docs/anthropic.html +45 -0
- package/docs/best-llm-routers-2025.html +157 -0
- package/docs/cerebras.html +43 -0
- package/docs/cli-cheatsheet.md +286 -212
- package/docs/comparison.md +2 -2
- package/docs/deepseek.html +44 -0
- package/docs/google.html +47 -0
- package/docs/groq.html +44 -0
- package/docs/llms-full.txt +360 -138
- package/docs/llms.txt +70 -71
- package/docs/mistral.html +43 -0
- package/docs/ollama.html +50 -0
- package/docs/openai.html +57 -0
- package/docs/sitemap.xml +69 -57
- package/docs-site/blog/best-llm-routers-2025.html +157 -0
- package/docs-site/index.html +68 -9
- package/docs-site/providers/anthropic.html +45 -0
- package/docs-site/providers/cerebras.html +43 -0
- package/docs-site/providers/deepseek.html +44 -0
- package/docs-site/providers/google.html +47 -0
- package/docs-site/providers/groq.html +44 -0
- package/docs-site/providers/index.html +41 -0
- package/docs-site/providers/mistral.html +43 -0
- package/docs-site/providers/ollama.html +50 -0
- package/docs-site/providers/openai.html +57 -0
- package/docs-site/sitemap.xml +69 -0
- package/llms.txt +70 -62
- package/package.json +44 -182
- package/packages/agentkit-adapter/LICENSE +21 -0
- package/packages/agentkit-adapter/README.md +126 -0
- package/packages/agentkit-adapter/examples/agentkit-example.ts +139 -0
- package/packages/agentkit-adapter/package.json +57 -0
- package/packages/agentkit-adapter/src/adapter.ts +381 -0
- package/packages/agentkit-adapter/src/index.ts +36 -0
- package/packages/agentkit-adapter/src/types.ts +105 -0
- package/packages/agentkit-adapter/src/util.ts +13 -0
- package/packages/agentkit-adapter/tsconfig.json +22 -0
- package/prometheus.yml +8 -0
- package/python/README.md +35 -81
- package/python/a3m/__init__.py +32 -3
- package/python/a3m/adapters/__init__.py +21 -0
- package/python/a3m/adapters/langchain.py +190 -0
- package/python/a3m/adapters/llamaindex.py +249 -0
- package/python/a3m/adapters/qdrant.py +240 -0
- package/python/a3m/adapters/weaviate.py +263 -0
- package/python/a3m/client.py +5 -0
- package/python/build_verify.sh +32 -0
- package/python/mcp-server/README.md +172 -0
- package/python/mcp-server/a3m_mcp/__init__.py +25 -0
- package/python/mcp-server/a3m_mcp/__main__.py +15 -0
- package/python/mcp-server/a3m_mcp/server.py +205 -0
- package/python/mcp-server/pyproject.toml +24 -0
- package/python/pyproject.toml +60 -6
- package/python/setup.py +3 -28
- package/scripts/submit-sitemap.sh +52 -0
- package/src/__types__/registry.d.ts +14 -0
- package/src/cli/setupWizard.ts +443 -112
- package/src/cli/tui.ts +159 -0
- package/src/ensemble.ts +154 -1
- package/src/integrations/langchainAdapter.ts +2 -2
- package/src/providers/providerConfig.ts +32 -17
- package/src/providers/registry.js +27 -0
- package/src/routing/advancedRouter.ts +99 -14
- package/src/routing/shadowSampler.ts +1 -1
- package/test-install/package.json +12 -0
- package/tests/tsconfig.json +0 -1
- package/tmlpd-pi-extension/README.md +105 -44
- package/tmlpd-pi-extension/docs/demo.svg +33 -0
- package/tmlpd-pi-extension/package.json +35 -106
- package/tmlpd-pi-extension/src/tokenOptimization/contextStratifier.ts +163 -0
- package/tmlpd-pi-extension/src/tokenOptimization/fetchOnceLocal.ts +136 -0
- package/tmlpd-pi-extension/src/tokenOptimization/index.ts +197 -0
- package/tmlpd-pi-extension/src/tokenOptimization/interAgentCompression.ts +157 -0
- package/tmlpd-pi-extension/src/tokenOptimization/schemaContract.ts +101 -0
- package/tmlpd-pi-extension/src/tokenOptimization/semanticCache.ts +248 -0
- package/tmlpd-pi-extension/src/tokenOptimization/tokenAwareFallback.ts +192 -0
- package/tmlpd-pi-extension/test/verify.js +21 -0
- package/tsconfig.build.json +3 -2
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts +0 -12
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js +0 -289
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js.map +0 -1
- package/packages/a3m-vercel-ai/dist/index.d.ts +0 -82
- package/packages/a3m-vercel-ai/dist/index.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/index.js +0 -79
- package/packages/a3m-vercel-ai/dist/index.js.map +0 -1
- package/packages/a3m-vercel-ai/dist/types.d.ts +0 -97
- package/packages/a3m-vercel-ai/dist/types.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/types.js +0 -5
- package/packages/a3m-vercel-ai/dist/types.js.map +0 -1
- package/src/skills/__tests__/skill_manager.test.ts +0 -328
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +0 -114
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cache/prefixCache.js +0 -285
- package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +0 -1
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +0 -58
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cache/responseCache.js +0 -153
- package/tmlpd-pi-extension/dist/cache/responseCache.js.map +0 -1
- package/tmlpd-pi-extension/dist/cli.js +0 -59
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +0 -95
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cost/costTracker.js +0 -240
- package/tmlpd-pi-extension/dist/cost/costTracker.js.map +0 -1
- package/tmlpd-pi-extension/dist/index.d.ts +0 -723
- package/tmlpd-pi-extension/dist/index.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/index.js +0 -239
- package/tmlpd-pi-extension/dist/index.js.map +0 -1
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +0 -82
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js +0 -145
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +0 -102
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +0 -207
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +0 -85
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +0 -210
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +0 -1
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +0 -102
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/providers/localProvider.js +0 -338
- package/tmlpd-pi-extension/dist/providers/localProvider.js.map +0 -1
- package/tmlpd-pi-extension/dist/providers/registry.d.ts +0 -55
- package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/providers/registry.js +0 -138
- package/tmlpd-pi-extension/dist/providers/registry.js.map +0 -1
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +0 -68
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js +0 -332
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +0 -1
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +0 -101
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +0 -368
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +0 -96
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js +0 -170
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/compression.d.ts +0 -61
- package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/compression.js +0 -281
- package/tmlpd-pi-extension/dist/utils/compression.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts +0 -74
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/reliability.js +0 -177
- package/tmlpd-pi-extension/dist/utils/reliability.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +0 -117
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +0 -246
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +0 -50
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js +0 -124
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a3m/agentkit-adapter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A3M Router adapter for AgentKit - enables AI agents with intelligent multi-provider routing",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
20
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"lint": "eslint src/",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"agentkit",
|
|
27
|
+
"a3m",
|
|
28
|
+
"router",
|
|
29
|
+
"llm",
|
|
30
|
+
"multi-provider",
|
|
31
|
+
"ai",
|
|
32
|
+
"agent",
|
|
33
|
+
"openai",
|
|
34
|
+
"anthropic",
|
|
35
|
+
"routing"
|
|
36
|
+
],
|
|
37
|
+
"author": "",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@inngest/agent-kit": ">=0.0.1"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@inngest/ai": ">=0.1.0",
|
|
44
|
+
"zod": "^3.22.4"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@inngest/agent-kit": "^0.13.0",
|
|
48
|
+
"@types/node": "^20.10.0",
|
|
49
|
+
"tsup": "^8.0.0",
|
|
50
|
+
"typescript": "^5.3.0",
|
|
51
|
+
"vitest": "^1.0.0"
|
|
52
|
+
},
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/Das-rebel/adaptive-memory-multi-model-router"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A3M Router AgentKit Adapter
|
|
3
|
+
*
|
|
4
|
+
* Wraps A3M Router as an AgentKit-compatible LLM backend.
|
|
5
|
+
* Supports tool calling, streaming, and parallel ensemble mode.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type AiAdapter } from "@inngest/ai";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { stringifyError } from "./util";
|
|
11
|
+
import type {
|
|
12
|
+
A3MConfig,
|
|
13
|
+
A3MInferenceOptions,
|
|
14
|
+
A3MMessage,
|
|
15
|
+
A3MTool,
|
|
16
|
+
A3MStreamChunk,
|
|
17
|
+
A3MToolCall,
|
|
18
|
+
} from "./types";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A3M Router adapter for AgentKit
|
|
22
|
+
*/
|
|
23
|
+
export class A3MAdapter {
|
|
24
|
+
private config: Required<A3MConfig>;
|
|
25
|
+
private format: AiAdapter.Format = "openai-chat";
|
|
26
|
+
private url: string;
|
|
27
|
+
private authKey: string = "";
|
|
28
|
+
|
|
29
|
+
constructor(config: A3MConfig = {}) {
|
|
30
|
+
this.config = {
|
|
31
|
+
baseUrl: config.baseUrl || "http://localhost:8787",
|
|
32
|
+
apiKey: config.apiKey || "",
|
|
33
|
+
defaultModel: config.defaultModel || "",
|
|
34
|
+
parallel: config.parallel ?? false,
|
|
35
|
+
temperature: config.temperature ?? 0.7,
|
|
36
|
+
maxTokens: config.maxTokens ?? 4096,
|
|
37
|
+
headers: config.headers || {},
|
|
38
|
+
};
|
|
39
|
+
this.url = `${this.config.baseUrl}/v1/chat/completions`;
|
|
40
|
+
this.authKey = this.config.apiKey;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get the adapter format
|
|
45
|
+
*/
|
|
46
|
+
getFormat(): AiAdapter.Format {
|
|
47
|
+
return this.format;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get adapter options (required by AgentKit)
|
|
52
|
+
*/
|
|
53
|
+
getOptions(): AiAdapter.Any["options"] {
|
|
54
|
+
return {
|
|
55
|
+
model: this.config.defaultModel || "auto",
|
|
56
|
+
apiKey: this.config.apiKey,
|
|
57
|
+
baseUrl: this.config.baseUrl,
|
|
58
|
+
} as AiAdapter.Any["options"];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert AgentKit messages to A3M format
|
|
63
|
+
*/
|
|
64
|
+
private convertMessages(messages: Array<{
|
|
65
|
+
type: string;
|
|
66
|
+
role?: string;
|
|
67
|
+
content?: string;
|
|
68
|
+
tool?: { id?: string; name?: string };
|
|
69
|
+
tools?: unknown[];
|
|
70
|
+
}>): A3MMessage[] {
|
|
71
|
+
return messages.map((m) => {
|
|
72
|
+
if (m.type === "tool_result") {
|
|
73
|
+
return {
|
|
74
|
+
role: "tool" as const,
|
|
75
|
+
content: typeof m.content === "string" ? m.content : JSON.stringify(m.content),
|
|
76
|
+
toolCallId: m.tool?.id,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (m.type === "tool_call") {
|
|
80
|
+
// Tool calls are handled separately
|
|
81
|
+
return {
|
|
82
|
+
role: "assistant" as const,
|
|
83
|
+
content: "",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
role: (m.role as "user" | "assistant" | "system") || "user",
|
|
88
|
+
content: m.content || "",
|
|
89
|
+
};
|
|
90
|
+
}).filter((m) => m.content || m.role === "system");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Convert AgentKit tools to A3M/OpenAI format
|
|
95
|
+
*/
|
|
96
|
+
private convertTools(tools: Array<{
|
|
97
|
+
name: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
parameters?: z.ZodType<unknown>;
|
|
100
|
+
strict?: boolean;
|
|
101
|
+
}>) {
|
|
102
|
+
return tools.map((t) => ({
|
|
103
|
+
type: "function",
|
|
104
|
+
function: {
|
|
105
|
+
name: t.name,
|
|
106
|
+
description: t.description || "",
|
|
107
|
+
parameters: t.parameters ? z.toJSONSchema(t.parameters, { target: "draft-7" }) : undefined,
|
|
108
|
+
strict: t.strict ?? Boolean(t.parameters),
|
|
109
|
+
},
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Parse A3M/OpenAI response to AgentKit messages
|
|
115
|
+
*/
|
|
116
|
+
private parseResponse(input: Record<string, unknown>): Array<{
|
|
117
|
+
type: string;
|
|
118
|
+
role?: string;
|
|
119
|
+
content?: string;
|
|
120
|
+
tools?: A3MToolCall[];
|
|
121
|
+
stop_reason?: string;
|
|
122
|
+
}> {
|
|
123
|
+
const result: Array<{
|
|
124
|
+
type: string;
|
|
125
|
+
role?: string;
|
|
126
|
+
content?: string;
|
|
127
|
+
tools?: A3MToolCall[];
|
|
128
|
+
stop_reason?: string;
|
|
129
|
+
}> = [];
|
|
130
|
+
|
|
131
|
+
if (input.error) {
|
|
132
|
+
throw new Error(`A3M request failed: ${JSON.stringify(input.error)}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const choices = (input.choices as Array<Record<string, unknown>>) || [];
|
|
136
|
+
|
|
137
|
+
for (const choice of choices) {
|
|
138
|
+
const message = choice.message as Record<string, unknown> || {};
|
|
139
|
+
const finishReason = choice.finish_reason as string || "stop";
|
|
140
|
+
|
|
141
|
+
// Text content
|
|
142
|
+
if (message.content && (message.content as string).trim()) {
|
|
143
|
+
result.push({
|
|
144
|
+
type: "text",
|
|
145
|
+
role: message.role as string,
|
|
146
|
+
content: message.content as string,
|
|
147
|
+
stop_reason: finishReason,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Tool calls
|
|
152
|
+
const toolCalls = message.tool_calls as Array<Record<string, unknown>> || [];
|
|
153
|
+
if (toolCalls.length > 0) {
|
|
154
|
+
result.push({
|
|
155
|
+
type: "tool_call",
|
|
156
|
+
role: message.role as string,
|
|
157
|
+
tools: toolCalls.map((tc) => ({
|
|
158
|
+
id: tc.id as string,
|
|
159
|
+
name: (tc.function as Record<string, string>)?.name || "",
|
|
160
|
+
arguments: JSON.parse((tc.function as Record<string, string>)?.arguments || "{}"),
|
|
161
|
+
})),
|
|
162
|
+
stop_reason: "tool",
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Run inference through A3M Router
|
|
172
|
+
*/
|
|
173
|
+
async infer(
|
|
174
|
+
stepID: string,
|
|
175
|
+
messages: Array<{
|
|
176
|
+
type: string;
|
|
177
|
+
role?: string;
|
|
178
|
+
content?: string;
|
|
179
|
+
tool?: { id?: string; name?: string };
|
|
180
|
+
tools?: unknown[];
|
|
181
|
+
}>,
|
|
182
|
+
tools: Array<{
|
|
183
|
+
name: string;
|
|
184
|
+
description?: string;
|
|
185
|
+
parameters?: z.ZodType<unknown>;
|
|
186
|
+
strict?: boolean;
|
|
187
|
+
}>,
|
|
188
|
+
toolChoice: "auto" | "none" | { type: "function"; function: { name: string } } = "auto",
|
|
189
|
+
options: A3MInferenceOptions = {}
|
|
190
|
+
): Promise<{
|
|
191
|
+
output: Array<{ type: string; role?: string; content?: string; tools?: A3MToolCall[]; stop_reason?: string }>;
|
|
192
|
+
raw: Record<string, unknown>;
|
|
193
|
+
}> {
|
|
194
|
+
const body: Record<string, unknown> = {
|
|
195
|
+
model: options.model || this.config.defaultModel || "auto",
|
|
196
|
+
messages: this.convertMessages(messages),
|
|
197
|
+
temperature: options.temperature ?? this.config.temperature,
|
|
198
|
+
max_tokens: options.maxTokens ?? this.config.maxTokens,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
if (tools.length > 0) {
|
|
202
|
+
body.tools = this.convertTools(tools);
|
|
203
|
+
if (toolChoice === "auto") {
|
|
204
|
+
body.tool_choice = "auto";
|
|
205
|
+
} else if (toolChoice === "none") {
|
|
206
|
+
body.tool_choice = "none";
|
|
207
|
+
} else if (toolChoice && typeof toolChoice === "object") {
|
|
208
|
+
body.tool_choice = {
|
|
209
|
+
type: "function",
|
|
210
|
+
function: { name: toolChoice.function.name },
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (options.provider) {
|
|
216
|
+
body.provider = options.provider;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (options.stop) {
|
|
220
|
+
body.stop = options.stop;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Parallel ensemble mode
|
|
224
|
+
if (options.parallel ?? this.config.parallel) {
|
|
225
|
+
body.parallel = true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const headers: Record<string, string> = {
|
|
229
|
+
"Content-Type": "application/json",
|
|
230
|
+
...this.config.headers,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
if (this.authKey) {
|
|
234
|
+
headers["Authorization"] = `Bearer ${this.authKey}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const response = await fetch(this.url, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
headers,
|
|
241
|
+
body: JSON.stringify(body),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (!response.ok) {
|
|
245
|
+
throw new Error(`A3M request failed: ${response.status} ${response.statusText}`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const result = (await response.json()) as Record<string, unknown>;
|
|
249
|
+
return {
|
|
250
|
+
output: this.parseResponse(result),
|
|
251
|
+
raw: result,
|
|
252
|
+
};
|
|
253
|
+
} catch (err) {
|
|
254
|
+
throw new Error(`A3M inference error: ${stringifyError(err)}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Stream inference through A3M Router
|
|
260
|
+
*/
|
|
261
|
+
async *stream(
|
|
262
|
+
messages: A3MMessage[],
|
|
263
|
+
tools: A3MTool[] = [],
|
|
264
|
+
options: A3MInferenceOptions = {}
|
|
265
|
+
): AsyncGenerator<A3MStreamChunk> {
|
|
266
|
+
const body: Record<string, unknown> = {
|
|
267
|
+
model: options.model || this.config.defaultModel || "auto",
|
|
268
|
+
messages,
|
|
269
|
+
temperature: options.temperature ?? this.config.temperature,
|
|
270
|
+
max_tokens: options.maxTokens ?? this.config.maxTokens,
|
|
271
|
+
stream: true,
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
if (tools.length > 0) {
|
|
275
|
+
body.tools = this.convertTools(tools);
|
|
276
|
+
body.tool_choice = "auto";
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (options.provider) {
|
|
280
|
+
body.provider = options.provider;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const headers: Record<string, string> = {
|
|
284
|
+
"Content-Type": "application/json",
|
|
285
|
+
...this.config.headers,
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
if (this.authKey) {
|
|
289
|
+
headers["Authorization"] = `Bearer ${this.authKey}`;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const response = await fetch(this.url, {
|
|
294
|
+
method: "POST",
|
|
295
|
+
headers,
|
|
296
|
+
body: JSON.stringify(body),
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
if (!response.ok) {
|
|
300
|
+
throw new Error(`A3M stream failed: ${response.status} ${response.statusText}`);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!response.body) {
|
|
304
|
+
throw new Error("A3M stream: no response body");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const reader = response.body.getReader();
|
|
308
|
+
const decoder = new TextDecoder();
|
|
309
|
+
let buffer = "";
|
|
310
|
+
|
|
311
|
+
while (true) {
|
|
312
|
+
const { done, value } = await reader.read();
|
|
313
|
+
if (done) break;
|
|
314
|
+
|
|
315
|
+
buffer += decoder.decode(value, { stream: true });
|
|
316
|
+
const lines = buffer.split("\n");
|
|
317
|
+
buffer = lines.pop() || "";
|
|
318
|
+
|
|
319
|
+
for (const line of lines) {
|
|
320
|
+
const trimmed = line.trim();
|
|
321
|
+
if (!trimmed || !trimmed.startsWith("data: ")) continue;
|
|
322
|
+
|
|
323
|
+
const data = trimmed.slice(6);
|
|
324
|
+
if (data === "[DONE]") {
|
|
325
|
+
yield { type: "done" };
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
try {
|
|
330
|
+
const chunk = JSON.parse(data) as Record<string, unknown>;
|
|
331
|
+
const delta = chunk.choices?.[0]?.delta as Record<string, unknown>;
|
|
332
|
+
|
|
333
|
+
if (delta?.content) {
|
|
334
|
+
yield { type: "text", content: delta.content as string };
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (delta?.tool_calls) {
|
|
338
|
+
for (const tc of delta.tool_calls as Array<Record<string, unknown>>) {
|
|
339
|
+
yield {
|
|
340
|
+
type: "tool_call",
|
|
341
|
+
toolCall: {
|
|
342
|
+
id: tc.id as string,
|
|
343
|
+
name: (tc.function as Record<string, string>)?.name || "",
|
|
344
|
+
arguments: JSON.parse((tc.function as Record<string, string>)?.arguments || "{}"),
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
} catch {
|
|
350
|
+
// Skip malformed JSON
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
yield { type: "done" };
|
|
356
|
+
} catch (err) {
|
|
357
|
+
yield { type: "error", error: stringifyError(err) };
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Check if A3M Router is available
|
|
363
|
+
*/
|
|
364
|
+
async healthCheck(): Promise<boolean> {
|
|
365
|
+
try {
|
|
366
|
+
const response = await fetch(`${this.config.baseUrl}/health`, {
|
|
367
|
+
method: "GET",
|
|
368
|
+
});
|
|
369
|
+
return response.ok;
|
|
370
|
+
} catch {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Create an A3M adapter with default settings
|
|
378
|
+
*/
|
|
379
|
+
export function createA3MAdapter(config?: A3MConfig): A3MAdapter {
|
|
380
|
+
return new A3MAdapter(config);
|
|
381
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A3M Router AgentKit Adapter
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { createAgenticModelFromAiAdapter } from "@inngest/agent-kit";
|
|
7
|
+
* import { createA3MAdapter } from "@a3m/agentkit-adapter";
|
|
8
|
+
*
|
|
9
|
+
* // Create A3M adapter
|
|
10
|
+
* const a3m = createA3MAdapter({
|
|
11
|
+
* baseUrl: "http://localhost:8787",
|
|
12
|
+
* parallel: true, // Enable parallel ensemble mode
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Wrap as AgentKit model
|
|
16
|
+
* const model = createAgenticModelFromAiAdapter(a3m as unknown as AiAdapter.Any);
|
|
17
|
+
*
|
|
18
|
+
* // Use with AgentKit agent
|
|
19
|
+
* const agent = new Agent({
|
|
20
|
+
* model,
|
|
21
|
+
* tools: [/* your tools *\/],
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export { A3MAdapter, createA3MAdapter } from "./adapter";
|
|
27
|
+
export type {
|
|
28
|
+
A3MConfig,
|
|
29
|
+
A3MInferenceOptions,
|
|
30
|
+
A3MMessage,
|
|
31
|
+
A3MTool,
|
|
32
|
+
A3MToolCall,
|
|
33
|
+
A3MStreamChunk,
|
|
34
|
+
A3MResponse,
|
|
35
|
+
ToolChoice,
|
|
36
|
+
} from "./types";
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for A3M Router AgentKit Adapter
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for A3M Router
|
|
9
|
+
*/
|
|
10
|
+
export interface A3MConfig {
|
|
11
|
+
/** A3M Router base URL (default: http://localhost:8787) */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
/** API key for A3M Router (if required) */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Default model to use (optional - A3M will route automatically) */
|
|
16
|
+
defaultModel?: string;
|
|
17
|
+
/** Enable parallel ensemble mode */
|
|
18
|
+
parallel?: boolean;
|
|
19
|
+
/** Temperature for generation (0-2) */
|
|
20
|
+
temperature?: number;
|
|
21
|
+
/** Maximum tokens to generate */
|
|
22
|
+
maxTokens?: number;
|
|
23
|
+
/** Additional headers to send with each request */
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A3M-specific options for inference
|
|
29
|
+
*/
|
|
30
|
+
export interface A3MInferenceOptions {
|
|
31
|
+
/** Override the model for this call */
|
|
32
|
+
model?: string;
|
|
33
|
+
/** Enable parallel ensemble for this call */
|
|
34
|
+
parallel?: boolean;
|
|
35
|
+
/** Temperature (0-2) */
|
|
36
|
+
temperature?: number;
|
|
37
|
+
/** Maximum tokens */
|
|
38
|
+
maxTokens?: number;
|
|
39
|
+
/** Provider to use (bypass routing) */
|
|
40
|
+
provider?: string;
|
|
41
|
+
/** Stop sequences */
|
|
42
|
+
stop?: string[];
|
|
43
|
+
/** Retry on failure */
|
|
44
|
+
retry?: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Message format compatible with AgentKit
|
|
49
|
+
*/
|
|
50
|
+
export interface A3MMessage {
|
|
51
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
52
|
+
content: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
toolCallId?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Tool call format for A3M
|
|
59
|
+
*/
|
|
60
|
+
export interface A3MToolCall {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
arguments: Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Tool definition for A3M
|
|
68
|
+
*/
|
|
69
|
+
export interface A3MTool {
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
parameters?: z.ZodType<unknown>;
|
|
73
|
+
strict?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Streaming chunk from A3M
|
|
78
|
+
*/
|
|
79
|
+
export interface A3MStreamChunk {
|
|
80
|
+
type: "text" | "tool_call" | "done" | "error";
|
|
81
|
+
content?: string;
|
|
82
|
+
toolCall?: A3MToolCall;
|
|
83
|
+
error?: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Response from A3M inference
|
|
88
|
+
*/
|
|
89
|
+
export interface A3MResponse {
|
|
90
|
+
content: string;
|
|
91
|
+
toolCalls?: A3MToolCall[];
|
|
92
|
+
model?: string;
|
|
93
|
+
provider?: string;
|
|
94
|
+
usage?: {
|
|
95
|
+
promptTokens: number;
|
|
96
|
+
completionTokens: number;
|
|
97
|
+
totalTokens: number;
|
|
98
|
+
};
|
|
99
|
+
finishReason?: "stop" | "length" | "tool_calls" | "content_filter";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Tool choice options
|
|
104
|
+
*/
|
|
105
|
+
export type ToolChoice = "auto" | "none" | { type: "function"; function: { name: string } };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"declarationMap": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"rootDir": "./src",
|
|
12
|
+
"strict": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"isolatedModules": true,
|
|
18
|
+
"noEmit": false
|
|
19
|
+
},
|
|
20
|
+
"include": ["src/**/*"],
|
|
21
|
+
"exclude": ["node_modules", "dist", "examples"]
|
|
22
|
+
}
|