@super_studio/ecforce-ai-agent-server 1.2.0 → 1.3.0-canary.0
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/README.md +292 -0
- package/dist/lib/constants.cjs +1 -1
- package/dist/lib/constants.mjs +1 -1
- package/dist/lib/constants.mjs.map +1 -1
- package/dist/lib/google-proxy-fetch.cjs +34 -0
- package/dist/lib/google-proxy-fetch.mjs +35 -0
- package/dist/lib/google-proxy-fetch.mjs.map +1 -0
- package/dist/provider.cjs +107 -0
- package/dist/provider.d.cts +18 -0
- package/dist/provider.d.cts.map +1 -0
- package/dist/provider.d.mts +18 -0
- package/dist/provider.d.mts.map +1 -0
- package/dist/provider.mjs +107 -0
- package/dist/provider.mjs.map +1 -0
- package/dist/sdk/__generated__/index.cjs +29 -0
- package/dist/sdk/__generated__/index.d.cts +111 -17
- package/dist/sdk/__generated__/index.d.cts.map +1 -1
- package/dist/sdk/__generated__/index.d.mts +111 -17
- package/dist/sdk/__generated__/index.d.mts.map +1 -1
- package/dist/sdk/__generated__/index.mjs +29 -0
- package/dist/sdk/__generated__/index.mjs.map +1 -1
- package/package.json +9 -1
- package/src/lib/constants.ts +1 -1
- package/src/lib/google-proxy-fetch.ts +64 -0
- package/src/provider.ts +202 -0
- package/src/sdk/__generated__/index.ts +236 -78
- package/src/sdk/generate.ts +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@super_studio/ecforce-ai-agent-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-canary.0",
|
|
4
4
|
"main": "./dist/index.cjs",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.cts",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"require": "./dist/mcp-auth.cjs",
|
|
19
19
|
"import": "./dist/mcp-auth.mjs"
|
|
20
20
|
},
|
|
21
|
+
"./provider": {
|
|
22
|
+
"require": "./dist/provider.cjs",
|
|
23
|
+
"import": "./dist/provider.mjs"
|
|
24
|
+
},
|
|
21
25
|
"./package.json": "./package.json"
|
|
22
26
|
},
|
|
23
27
|
"publishConfig": {
|
|
@@ -28,6 +32,10 @@
|
|
|
28
32
|
"swagger-typescript-api": "13.2.9"
|
|
29
33
|
},
|
|
30
34
|
"dependencies": {
|
|
35
|
+
"@ai-sdk/anthropic": "^3.0.68",
|
|
36
|
+
"@ai-sdk/google-vertex": "^4.0.106",
|
|
37
|
+
"@ai-sdk/openai": "^3.0.49",
|
|
38
|
+
"@ai-sdk/provider": "^3.0.8",
|
|
31
39
|
"@panva/hkdf": "^1.2.1",
|
|
32
40
|
"jose": "^6.0.6"
|
|
33
41
|
},
|
package/src/lib/constants.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const API_ENDPOINT = "
|
|
1
|
+
export const API_ENDPOINT = "https://agent.ec-force.com";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function createGoogleProxyFetch(apiKey: string | undefined) {
|
|
2
|
+
return async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
3
|
+
const url = typeof input === "string" ? input : input.toString();
|
|
4
|
+
const headers = new Headers(init?.headers);
|
|
5
|
+
headers.delete("x-goog-api-key");
|
|
6
|
+
headers.delete("X-Goog-Api-Key");
|
|
7
|
+
|
|
8
|
+
if (apiKey) {
|
|
9
|
+
headers.set("authorization", `Bearer ${apiKey}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const body = normalizeGoogleProxyRequestBody(url, init?.body);
|
|
13
|
+
|
|
14
|
+
return fetch(input, {
|
|
15
|
+
...init,
|
|
16
|
+
...(body ? { body } : {}),
|
|
17
|
+
headers,
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizeGoogleProxyRequestBody(
|
|
23
|
+
url: string,
|
|
24
|
+
body: RequestInit["body"],
|
|
25
|
+
): RequestInit["body"] {
|
|
26
|
+
if (!body || typeof body !== "string") {
|
|
27
|
+
return body;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (
|
|
31
|
+
!url.includes(":generateContent") &&
|
|
32
|
+
!url.includes(":streamGenerateContent")
|
|
33
|
+
) {
|
|
34
|
+
return body;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const payload = JSON.parse(body) as Record<string, unknown>;
|
|
39
|
+
const toolConfig = payload.toolConfig as
|
|
40
|
+
| Record<string, unknown>
|
|
41
|
+
| undefined;
|
|
42
|
+
const functionCallingConfig = toolConfig?.functionCallingConfig as
|
|
43
|
+
| Record<string, unknown>
|
|
44
|
+
| undefined;
|
|
45
|
+
|
|
46
|
+
if (!functionCallingConfig?.streamFunctionCallArguments) {
|
|
47
|
+
return body;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
streamFunctionCallArguments: _streamFunctionCallArguments,
|
|
52
|
+
...restFunctionCallingConfig
|
|
53
|
+
} = functionCallingConfig;
|
|
54
|
+
|
|
55
|
+
payload.toolConfig = {
|
|
56
|
+
...toolConfig,
|
|
57
|
+
functionCallingConfig: restFunctionCallingConfig,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return JSON.stringify(payload);
|
|
61
|
+
} catch {
|
|
62
|
+
return body;
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/provider.ts
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2
|
+
import { createVertex } from "@ai-sdk/google-vertex";
|
|
3
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
4
|
+
import type { LanguageModelV3 } from "@ai-sdk/provider";
|
|
5
|
+
import { API_ENDPOINT } from "@/lib/constants";
|
|
6
|
+
import { createGoogleProxyFetch } from "@/lib/google-proxy-fetch";
|
|
7
|
+
|
|
8
|
+
export type SpstProviderOptions = {
|
|
9
|
+
projectId: string;
|
|
10
|
+
email: string;
|
|
11
|
+
callerApp: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type CreateSpstProviderParams = {
|
|
15
|
+
apiKey?: string;
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
callerApp: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type SpstProviderConfig = Pick<CreateSpstProviderParams, "apiKey" | "baseUrl">;
|
|
21
|
+
type SpstProviderSet = {
|
|
22
|
+
openai: ReturnType<typeof createOpenAI>;
|
|
23
|
+
google: ReturnType<typeof createVertex>;
|
|
24
|
+
anthropic: ReturnType<typeof createAnthropic>;
|
|
25
|
+
};
|
|
26
|
+
type ParsedSpstModelId =
|
|
27
|
+
| {
|
|
28
|
+
provider: "openai";
|
|
29
|
+
proxyModelId: string;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
provider: "google";
|
|
33
|
+
proxyModelId: string;
|
|
34
|
+
}
|
|
35
|
+
| {
|
|
36
|
+
provider: "anthropic";
|
|
37
|
+
proxyModelId: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const spstProviders = createSpstProviders({});
|
|
41
|
+
|
|
42
|
+
export function spst(modelId: string): LanguageModelV3 {
|
|
43
|
+
return createSpstLanguageModel(modelId, spstProviders);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function createSpstProvider(
|
|
47
|
+
params: CreateSpstProviderParams,
|
|
48
|
+
): typeof spst {
|
|
49
|
+
const providers = createSpstProviders(params);
|
|
50
|
+
|
|
51
|
+
return (modelId: string) => {
|
|
52
|
+
return createSpstLanguageModel(modelId, providers, params.callerApp);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createSpstProviders(config: SpstProviderConfig): SpstProviderSet {
|
|
57
|
+
const apiKey = config.apiKey ?? process.env.AI_AGENT_API_KEY;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
openai: createOpenAI({
|
|
61
|
+
name: "spst",
|
|
62
|
+
baseURL: getOpenAIProxyBaseUrl(config.baseUrl),
|
|
63
|
+
apiKey,
|
|
64
|
+
}),
|
|
65
|
+
google: createVertex({
|
|
66
|
+
apiKey,
|
|
67
|
+
baseURL: getGoogleProxyBaseUrl(config.baseUrl),
|
|
68
|
+
fetch: createGoogleProxyFetch(apiKey),
|
|
69
|
+
}),
|
|
70
|
+
anthropic: createAnthropic({
|
|
71
|
+
baseURL: getAnthropicProxyBaseUrl(config.baseUrl),
|
|
72
|
+
apiKey,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getResolvedBaseUrl(baseUrl?: string) {
|
|
78
|
+
const resolvedBaseUrl =
|
|
79
|
+
baseUrl ?? process.env.AI_AGENT_API_ENDPOINT ?? API_ENDPOINT;
|
|
80
|
+
return resolvedBaseUrl.replace(/\/$/, "");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getOpenAIProxyBaseUrl(baseUrl?: string) {
|
|
84
|
+
return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/openai`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getGoogleProxyBaseUrl(baseUrl?: string) {
|
|
88
|
+
return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/google`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getAnthropicProxyBaseUrl(baseUrl?: string) {
|
|
92
|
+
return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/anthropic`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function createSpstLanguageModel(
|
|
96
|
+
modelId: string,
|
|
97
|
+
providers: SpstProviderSet,
|
|
98
|
+
defaultCallerApp?: string,
|
|
99
|
+
) {
|
|
100
|
+
const parsedModelId = parseSpstModelId(modelId);
|
|
101
|
+
|
|
102
|
+
switch (parsedModelId.provider) {
|
|
103
|
+
case "openai":
|
|
104
|
+
return wrapSpstModel(
|
|
105
|
+
providers.openai.responses(parsedModelId.proxyModelId),
|
|
106
|
+
defaultCallerApp,
|
|
107
|
+
);
|
|
108
|
+
case "google":
|
|
109
|
+
return wrapSpstModel(
|
|
110
|
+
providers.google(parsedModelId.proxyModelId),
|
|
111
|
+
defaultCallerApp,
|
|
112
|
+
);
|
|
113
|
+
case "anthropic":
|
|
114
|
+
return wrapSpstModel(
|
|
115
|
+
providers.anthropic(parsedModelId.proxyModelId),
|
|
116
|
+
defaultCallerApp,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function parseSpstModelId(modelId: string): ParsedSpstModelId {
|
|
122
|
+
if (modelId.startsWith("openai/")) {
|
|
123
|
+
return {
|
|
124
|
+
provider: "openai",
|
|
125
|
+
proxyModelId: modelId,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (modelId.startsWith("google/")) {
|
|
130
|
+
return {
|
|
131
|
+
provider: "google",
|
|
132
|
+
proxyModelId: modelId.slice("google/".length),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (modelId.startsWith("anthropic/")) {
|
|
137
|
+
return {
|
|
138
|
+
provider: "anthropic",
|
|
139
|
+
proxyModelId: modelId.slice("anthropic/".length),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (modelId.includes("/")) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
`Provider '${modelId.split("/")[0]}' is not supported by spst() yet.`,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
throw new Error(
|
|
150
|
+
"The spst() helper currently requires an 'openai/<model>', 'google/<model>', or 'anthropic/<model>' model id.",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function wrapSpstModel(
|
|
155
|
+
model: LanguageModelV3,
|
|
156
|
+
defaultCallerApp?: string,
|
|
157
|
+
): LanguageModelV3 {
|
|
158
|
+
return {
|
|
159
|
+
specificationVersion: model.specificationVersion,
|
|
160
|
+
provider: model.provider,
|
|
161
|
+
modelId: model.modelId,
|
|
162
|
+
supportedUrls: model.supportedUrls,
|
|
163
|
+
doGenerate: (options) =>
|
|
164
|
+
model.doGenerate(withSpstHeaders(options, defaultCallerApp)),
|
|
165
|
+
doStream: (options) =>
|
|
166
|
+
model.doStream(withSpstHeaders(options, defaultCallerApp)),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function withSpstHeaders(
|
|
171
|
+
options: Parameters<LanguageModelV3["doGenerate"]>[0],
|
|
172
|
+
defaultCallerApp?: string,
|
|
173
|
+
): Parameters<LanguageModelV3["doGenerate"]>[0] {
|
|
174
|
+
const spstOptions = options.providerOptions?.spst as
|
|
175
|
+
| Partial<SpstProviderOptions>
|
|
176
|
+
| undefined;
|
|
177
|
+
|
|
178
|
+
if (!spstOptions) {
|
|
179
|
+
return options;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const callerApp = spstOptions.callerApp ?? defaultCallerApp;
|
|
183
|
+
|
|
184
|
+
if (!spstOptions.projectId || !spstOptions.email || !callerApp) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
"The spst provider requires projectId, email, and callerApp in providerOptions.spst.",
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const { spst: _spst, ...providerOptions } = options.providerOptions ?? {};
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
...options,
|
|
194
|
+
headers: {
|
|
195
|
+
...options.headers,
|
|
196
|
+
"x-spst-project-id": spstOptions.projectId,
|
|
197
|
+
"x-spst-user-email": spstOptions.email,
|
|
198
|
+
"x-spst-caller-app": callerApp,
|
|
199
|
+
},
|
|
200
|
+
providerOptions,
|
|
201
|
+
};
|
|
202
|
+
}
|