@super_studio/ecforce-ai-agent-server 1.2.0-canary.1 → 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 ADDED
@@ -0,0 +1,292 @@
1
+ # `@super_studio/ecforce-ai-agent-server`
2
+
3
+ ecforce AI Agent のサーバー向け SDK です。
4
+
5
+ 主に次の 2 つを提供します。
6
+
7
+ - API SDK: `createClient()` で AI Agent の内部 API を呼ぶ
8
+ - Proxy provider: `spst()` で Vercel AI SDK から内部プロキシ経由でモデルを使う
9
+
10
+ ## インストール
11
+
12
+ ```bash
13
+ pnpm add @super_studio/ecforce-ai-agent-server
14
+ ```
15
+
16
+ `spst()` は Vercel AI SDK と一緒に使います。
17
+
18
+ ```bash
19
+ pnpm add ai
20
+ ```
21
+
22
+ Google Search などで `@ai-sdk/google-vertex` のツールも使う場合は追加で入れてください。
23
+
24
+ ```bash
25
+ pnpm add @ai-sdk/google-vertex
26
+ ```
27
+
28
+ ## 環境変数
29
+
30
+ 通常は `AI_AGENT_API_KEY` だけ設定すれば動きます。
31
+
32
+ ```env
33
+ AI_AGENT_API_KEY=your-api-key
34
+ ```
35
+
36
+ dev / preview 環境へ向けたい場合だけ、接続先を上書きします。
37
+
38
+ ```env
39
+ AI_AGENT_API_ENDPOINT=https://dev-agent.ec-force.com
40
+ ```
41
+
42
+ - `AI_AGENT_API_KEY`: 必須。管理画面で発行した API キー
43
+ - `AI_AGENT_API_ENDPOINT`: 任意。省略時は本番 `https://agent.ec-force.com`
44
+
45
+ ## 使い分け
46
+
47
+ ### `createClient()`
48
+
49
+ 内部 API を直接呼びたいときに使います。
50
+
51
+ 用途:
52
+
53
+ - AI Agent セッション発行
54
+ - 管理用の内部 API 呼び出し
55
+ - 利用量サマリー取得
56
+
57
+ ### `spst()`
58
+
59
+ Vercel AI SDK の `generateText()` / `streamText()` などから、ecforce AI Agent の proxy provider を使いたいときに使います。
60
+
61
+ 用途:
62
+
63
+ - OpenAI / Google / Anthropic を内部プロキシ経由で呼ぶ
64
+ - `projectId` / `email` / `callerApp` をヘッダーに載せて課金・利用元を紐付ける
65
+ - アプリ側から AI SDK のままテキスト生成やストリームを実行する
66
+
67
+ ## API SDK
68
+
69
+ ### `createClient()` の基本
70
+
71
+ ```ts
72
+ import { createClient } from "@super_studio/ecforce-ai-agent-server";
73
+
74
+ const client = createClient();
75
+ ```
76
+
77
+ 必要なら API キーや接続先を明示できます。
78
+
79
+ ```ts
80
+ import { createClient } from "@super_studio/ecforce-ai-agent-server";
81
+
82
+ const client = createClient({
83
+ apiKey: process.env.AI_AGENT_API_KEY,
84
+ baseUrl: process.env.AI_AGENT_API_ENDPOINT,
85
+ });
86
+ ```
87
+
88
+ ### AI Agent セッションを発行する
89
+
90
+ React パッケージの `ChatbotSheet` / `ChatbotFrame` に渡すセッションは、通常この SDK で発行します。
91
+
92
+ ```ts
93
+ import { NextResponse } from "next/server";
94
+ import { createClient } from "@super_studio/ecforce-ai-agent-server";
95
+
96
+ const client = createClient();
97
+
98
+ export async function POST() {
99
+ const currentUser = {
100
+ email: "user@example.com",
101
+ projectId: "project_123",
102
+ };
103
+
104
+ const session = await client.internalChat.createSession({
105
+ email: currentUser.email,
106
+ projectId: currentUser.projectId,
107
+ });
108
+
109
+ return NextResponse.json(session);
110
+ }
111
+ ```
112
+
113
+ 返り値は次の形です。
114
+
115
+ ```ts
116
+ type AgentSession = {
117
+ token: string;
118
+ expiresAt: string;
119
+ };
120
+ ```
121
+
122
+ ### 内部 usage summary を取得する
123
+
124
+ 内部 API の利用例として、`/v1/internal/usage/summary` に対応する usage summary 取得は次のように呼べます。
125
+
126
+ ```ts
127
+ import { createClient } from "@super_studio/ecforce-ai-agent-server";
128
+
129
+ const client = createClient();
130
+
131
+ const summary = await client.internalUsage.getUsageSummary({
132
+ projectId: "project_123",
133
+ period: "2026-04",
134
+ });
135
+
136
+ console.log(summary);
137
+ /*
138
+ {
139
+ plan: "pro",
140
+ totalUsedCredits: 12345,
141
+ creditLimit: 50000,
142
+ remainingCredits: 37655,
143
+ billingPeriod: "2026-04"
144
+ }
145
+ */
146
+ ```
147
+
148
+ `period` を省略すると、サーバー側の現在 billing period が使われます。
149
+
150
+ 想定用途:
151
+
152
+ - 自社管理画面で利用量サマリーを表示する
153
+ - `spst()` 経由の利用量を含めた残クレジットを確認する
154
+ - 定期ジョブや監視でプロジェクトごとの消費量を取る
155
+
156
+ ## Proxy Provider
157
+
158
+ `spst()` は `@super_studio/ecforce-ai-agent-server/provider` から import します。
159
+
160
+ ```ts
161
+ import { spst } from "@super_studio/ecforce-ai-agent-server/provider";
162
+ ```
163
+
164
+ ### 最小例
165
+
166
+ ```ts
167
+ import { generateText } from "ai";
168
+ import { spst } from "@super_studio/ecforce-ai-agent-server/provider";
169
+
170
+ const result = await generateText({
171
+ model: spst("openai/gpt-5.4"),
172
+ prompt: "売上の改善案を3つ提案して",
173
+ providerOptions: {
174
+ spst: {
175
+ projectId: "project_123",
176
+ email: "user@example.com",
177
+ callerApp: "admin-dashboard",
178
+ },
179
+ },
180
+ });
181
+
182
+ console.log(result.text);
183
+ console.log(result.usage);
184
+ ```
185
+
186
+ `providerOptions.spst` は内部利用時の識別情報です。
187
+
188
+ - `projectId`: どのプロジェクトの利用か
189
+ - `email`: 誰の利用か
190
+ - `callerApp`: どのアプリからの利用か
191
+
192
+ 通常の内部利用では、この 3 つを毎回渡してください。
193
+
194
+ ### モデル ID の形式
195
+
196
+ `spst()` は provider 付きの model id を受け取ります。
197
+
198
+ ```ts
199
+ spst("openai/gpt-5.4");
200
+ spst("google/gemini-2.5-flash");
201
+ spst("anthropic/claude-sonnet-4-6");
202
+ ```
203
+
204
+ 現状サポートしている prefix は次です。
205
+
206
+ - `openai/`
207
+ - `google/`
208
+ - `anthropic/`
209
+
210
+ ### `callerApp` を固定した provider を作る
211
+
212
+ 同じアプリから何度も呼ぶなら `createSpstProvider()` が便利です。
213
+
214
+ ```ts
215
+ import { generateText } from "ai";
216
+ import { createSpstProvider } from "@super_studio/ecforce-ai-agent-server/provider";
217
+
218
+ const provider = createSpstProvider({
219
+ callerApp: "admin-dashboard",
220
+ });
221
+
222
+ const result = await generateText({
223
+ model: provider("google/gemini-2.5-flash"),
224
+ prompt: "今月の広告成果を要約して",
225
+ providerOptions: {
226
+ spst: {
227
+ projectId: "project_123",
228
+ email: "user@example.com",
229
+ },
230
+ },
231
+ });
232
+ ```
233
+
234
+ この場合、`callerApp` は `createSpstProvider()` 側の値が使われます。
235
+
236
+ 必要なら API キーや接続先もここで上書きできます。
237
+
238
+ ```ts
239
+ import { createSpstProvider } from "@super_studio/ecforce-ai-agent-server/provider";
240
+
241
+ const provider = createSpstProvider({
242
+ apiKey: process.env.AI_AGENT_API_KEY,
243
+ baseUrl: process.env.AI_AGENT_API_ENDPOINT,
244
+ callerApp: "admin-dashboard",
245
+ });
246
+ ```
247
+
248
+ ### ストリーミング
249
+
250
+ `streamText()` でも同じです。
251
+
252
+ ```ts
253
+ import { streamText } from "ai";
254
+ import { spst } from "@super_studio/ecforce-ai-agent-server/provider";
255
+
256
+ const result = streamText({
257
+ model: spst("openai/gpt-5.4-mini"),
258
+ prompt: "FAQ の草案を作成して",
259
+ providerOptions: {
260
+ spst: {
261
+ projectId: "project_123",
262
+ email: "user@example.com",
263
+ callerApp: "admin-dashboard",
264
+ },
265
+ },
266
+ });
267
+ ```
268
+
269
+ ### Google Search tool を併用する
270
+
271
+ Google 系モデルでは、AI SDK 側のツールを組み合わせて使えます。
272
+
273
+ ```ts
274
+ import { vertex } from "@ai-sdk/google-vertex";
275
+ import { generateText } from "ai";
276
+ import { spst } from "@super_studio/ecforce-ai-agent-server/provider";
277
+
278
+ const result = await generateText({
279
+ model: spst("google/gemini-3.1-pro-preview-customtools"),
280
+ prompt: "今日の生成AI関連ニュースを3件まとめて",
281
+ tools: {
282
+ google_search: vertex.tools.googleSearch({}),
283
+ },
284
+ providerOptions: {
285
+ spst: {
286
+ projectId: "project_123",
287
+ email: "user@example.com",
288
+ callerApp: "admin-dashboard",
289
+ },
290
+ },
291
+ });
292
+ ```
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region src/lib/constants.ts
3
- const API_ENDPOINT = "http://localhost:4043";
3
+ const API_ENDPOINT = "https://agent.ec-force.com";
4
4
 
5
5
  //#endregion
6
6
  exports.API_ENDPOINT = API_ENDPOINT;
@@ -1,5 +1,5 @@
1
1
  //#region src/lib/constants.ts
2
- const API_ENDPOINT = "http://localhost:4043";
2
+ const API_ENDPOINT = "https://agent.ec-force.com";
3
3
 
4
4
  //#endregion
5
5
  export { API_ENDPOINT };
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/lib/constants.ts"],"sourcesContent":["export const API_ENDPOINT = \"http://localhost:4043\";\n"],"mappings":";AAAA,MAAa,eAAe"}
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../../src/lib/constants.ts"],"sourcesContent":["export const API_ENDPOINT = \"https://agent.ec-force.com\";\n"],"mappings":";AAAA,MAAa,eAAe"}
@@ -0,0 +1,34 @@
1
+ const require_objectWithoutProperties = require('../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectWithoutProperties.cjs');
2
+ const require_objectSpread2 = require('../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs');
3
+
4
+ //#region src/lib/google-proxy-fetch.ts
5
+ const _excluded = ["streamFunctionCallArguments"];
6
+ function createGoogleProxyFetch(apiKey) {
7
+ return async (input, init) => {
8
+ const url = typeof input === "string" ? input : input.toString();
9
+ const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);
10
+ headers.delete("x-goog-api-key");
11
+ headers.delete("X-Goog-Api-Key");
12
+ if (apiKey) headers.set("authorization", `Bearer ${apiKey}`);
13
+ const body = normalizeGoogleProxyRequestBody(url, init === null || init === void 0 ? void 0 : init.body);
14
+ return fetch(input, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, init), body ? { body } : {}), {}, { headers }));
15
+ };
16
+ }
17
+ function normalizeGoogleProxyRequestBody(url, body) {
18
+ if (!body || typeof body !== "string") return body;
19
+ if (!url.includes(":generateContent") && !url.includes(":streamGenerateContent")) return body;
20
+ try {
21
+ const payload = JSON.parse(body);
22
+ const toolConfig = payload.toolConfig;
23
+ const functionCallingConfig = toolConfig === null || toolConfig === void 0 ? void 0 : toolConfig.functionCallingConfig;
24
+ if (!(functionCallingConfig === null || functionCallingConfig === void 0 ? void 0 : functionCallingConfig.streamFunctionCallArguments)) return body;
25
+ const { streamFunctionCallArguments: _streamFunctionCallArguments } = functionCallingConfig, restFunctionCallingConfig = require_objectWithoutProperties._objectWithoutProperties(functionCallingConfig, _excluded);
26
+ payload.toolConfig = require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, toolConfig), {}, { functionCallingConfig: restFunctionCallingConfig });
27
+ return JSON.stringify(payload);
28
+ } catch (_unused) {
29
+ return body;
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ exports.createGoogleProxyFetch = createGoogleProxyFetch;
@@ -0,0 +1,35 @@
1
+ import { _objectWithoutProperties } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectWithoutProperties.mjs";
2
+ import { _objectSpread2 } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.mjs";
3
+
4
+ //#region src/lib/google-proxy-fetch.ts
5
+ const _excluded = ["streamFunctionCallArguments"];
6
+ function createGoogleProxyFetch(apiKey) {
7
+ return async (input, init) => {
8
+ const url = typeof input === "string" ? input : input.toString();
9
+ const headers = new Headers(init === null || init === void 0 ? void 0 : init.headers);
10
+ headers.delete("x-goog-api-key");
11
+ headers.delete("X-Goog-Api-Key");
12
+ if (apiKey) headers.set("authorization", `Bearer ${apiKey}`);
13
+ const body = normalizeGoogleProxyRequestBody(url, init === null || init === void 0 ? void 0 : init.body);
14
+ return fetch(input, _objectSpread2(_objectSpread2(_objectSpread2({}, init), body ? { body } : {}), {}, { headers }));
15
+ };
16
+ }
17
+ function normalizeGoogleProxyRequestBody(url, body) {
18
+ if (!body || typeof body !== "string") return body;
19
+ if (!url.includes(":generateContent") && !url.includes(":streamGenerateContent")) return body;
20
+ try {
21
+ const payload = JSON.parse(body);
22
+ const toolConfig = payload.toolConfig;
23
+ const functionCallingConfig = toolConfig === null || toolConfig === void 0 ? void 0 : toolConfig.functionCallingConfig;
24
+ if (!(functionCallingConfig === null || functionCallingConfig === void 0 ? void 0 : functionCallingConfig.streamFunctionCallArguments)) return body;
25
+ const { streamFunctionCallArguments: _streamFunctionCallArguments } = functionCallingConfig, restFunctionCallingConfig = _objectWithoutProperties(functionCallingConfig, _excluded);
26
+ payload.toolConfig = _objectSpread2(_objectSpread2({}, toolConfig), {}, { functionCallingConfig: restFunctionCallingConfig });
27
+ return JSON.stringify(payload);
28
+ } catch (_unused) {
29
+ return body;
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ export { createGoogleProxyFetch };
35
+ //# sourceMappingURL=google-proxy-fetch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-proxy-fetch.mjs","names":[],"sources":["../../src/lib/google-proxy-fetch.ts"],"sourcesContent":["export function createGoogleProxyFetch(apiKey: string | undefined) {\n return async (input: RequestInfo | URL, init?: RequestInit) => {\n const url = typeof input === \"string\" ? input : input.toString();\n const headers = new Headers(init?.headers);\n headers.delete(\"x-goog-api-key\");\n headers.delete(\"X-Goog-Api-Key\");\n\n if (apiKey) {\n headers.set(\"authorization\", `Bearer ${apiKey}`);\n }\n\n const body = normalizeGoogleProxyRequestBody(url, init?.body);\n\n return fetch(input, {\n ...init,\n ...(body ? { body } : {}),\n headers,\n });\n };\n}\n\nfunction normalizeGoogleProxyRequestBody(\n url: string,\n body: RequestInit[\"body\"],\n): RequestInit[\"body\"] {\n if (!body || typeof body !== \"string\") {\n return body;\n }\n\n if (\n !url.includes(\":generateContent\") &&\n !url.includes(\":streamGenerateContent\")\n ) {\n return body;\n }\n\n try {\n const payload = JSON.parse(body) as Record<string, unknown>;\n const toolConfig = payload.toolConfig as\n | Record<string, unknown>\n | undefined;\n const functionCallingConfig = toolConfig?.functionCallingConfig as\n | Record<string, unknown>\n | undefined;\n\n if (!functionCallingConfig?.streamFunctionCallArguments) {\n return body;\n }\n\n const {\n streamFunctionCallArguments: _streamFunctionCallArguments,\n ...restFunctionCallingConfig\n } = functionCallingConfig;\n\n payload.toolConfig = {\n ...toolConfig,\n functionCallingConfig: restFunctionCallingConfig,\n };\n\n return JSON.stringify(payload);\n } catch {\n return body;\n }\n}\n"],"mappings":";;;;mBAkDM;AAlDN,SAAgB,uBAAuB,QAA4B;AACjE,QAAO,OAAO,OAA0B,SAAuB;EAC7D,MAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,UAAU;EAChE,MAAM,UAAU,IAAI,oDAAQ,KAAM,QAAQ;AAC1C,UAAQ,OAAO,iBAAiB;AAChC,UAAQ,OAAO,iBAAiB;AAEhC,MAAI,OACF,SAAQ,IAAI,iBAAiB,UAAU,SAAS;EAGlD,MAAM,OAAO,gCAAgC,iDAAK,KAAM,KAAK;AAE7D,SAAO,MAAM,wDACR,OACC,OAAO,EAAE,MAAM,GAAG,EAAE,SACxB,WACA;;;AAIN,SAAS,gCACP,KACA,MACqB;AACrB,KAAI,CAAC,QAAQ,OAAO,SAAS,SAC3B,QAAO;AAGT,KACE,CAAC,IAAI,SAAS,mBAAmB,IACjC,CAAC,IAAI,SAAS,yBAAyB,CAEvC,QAAO;AAGT,KAAI;EACF,MAAM,UAAU,KAAK,MAAM,KAAK;EAChC,MAAM,aAAa,QAAQ;EAG3B,MAAM,gFAAwB,WAAY;AAI1C,MAAI,gFAAC,sBAAuB,6BAC1B,QAAO;EAGT,MAAM,EACJ,6BAA6B,wDAC1B,qDACD;AAEJ,UAAQ,+CACH,mBACH,uBAAuB;AAGzB,SAAO,KAAK,UAAU,QAAQ;mBACxB;AACN,SAAO"}
@@ -0,0 +1,107 @@
1
+ const require_constants = require('./lib/constants.cjs');
2
+ const require_objectWithoutProperties = require('./_virtual/_@oxc-project_runtime@0.103.0/helpers/objectWithoutProperties.cjs');
3
+ const require_objectSpread2 = require('./_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.cjs');
4
+ const require_google_proxy_fetch = require('./lib/google-proxy-fetch.cjs');
5
+ let _ai_sdk_anthropic = require("@ai-sdk/anthropic");
6
+ let _ai_sdk_google_vertex = require("@ai-sdk/google-vertex");
7
+ let _ai_sdk_openai = require("@ai-sdk/openai");
8
+
9
+ //#region src/provider.ts
10
+ const _excluded = ["spst"];
11
+ const spstProviders = createSpstProviders({});
12
+ function spst(modelId) {
13
+ return createSpstLanguageModel(modelId, spstProviders);
14
+ }
15
+ function createSpstProvider(params) {
16
+ const providers = createSpstProviders(params);
17
+ return (modelId) => {
18
+ return createSpstLanguageModel(modelId, providers, params.callerApp);
19
+ };
20
+ }
21
+ function createSpstProviders(config) {
22
+ var _config$apiKey;
23
+ const apiKey = (_config$apiKey = config.apiKey) !== null && _config$apiKey !== void 0 ? _config$apiKey : process.env.AI_AGENT_API_KEY;
24
+ return {
25
+ openai: (0, _ai_sdk_openai.createOpenAI)({
26
+ name: "spst",
27
+ baseURL: getOpenAIProxyBaseUrl(config.baseUrl),
28
+ apiKey
29
+ }),
30
+ google: (0, _ai_sdk_google_vertex.createVertex)({
31
+ apiKey,
32
+ baseURL: getGoogleProxyBaseUrl(config.baseUrl),
33
+ fetch: require_google_proxy_fetch.createGoogleProxyFetch(apiKey)
34
+ }),
35
+ anthropic: (0, _ai_sdk_anthropic.createAnthropic)({
36
+ baseURL: getAnthropicProxyBaseUrl(config.baseUrl),
37
+ apiKey
38
+ })
39
+ };
40
+ }
41
+ function getResolvedBaseUrl(baseUrl) {
42
+ var _ref;
43
+ return ((_ref = baseUrl !== null && baseUrl !== void 0 ? baseUrl : process.env.AI_AGENT_API_ENDPOINT) !== null && _ref !== void 0 ? _ref : require_constants.API_ENDPOINT).replace(/\/$/, "");
44
+ }
45
+ function getOpenAIProxyBaseUrl(baseUrl) {
46
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/openai`;
47
+ }
48
+ function getGoogleProxyBaseUrl(baseUrl) {
49
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/google`;
50
+ }
51
+ function getAnthropicProxyBaseUrl(baseUrl) {
52
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/anthropic`;
53
+ }
54
+ function createSpstLanguageModel(modelId, providers, defaultCallerApp) {
55
+ const parsedModelId = parseSpstModelId(modelId);
56
+ switch (parsedModelId.provider) {
57
+ case "openai": return wrapSpstModel(providers.openai.responses(parsedModelId.proxyModelId), defaultCallerApp);
58
+ case "google": return wrapSpstModel(providers.google(parsedModelId.proxyModelId), defaultCallerApp);
59
+ case "anthropic": return wrapSpstModel(providers.anthropic(parsedModelId.proxyModelId), defaultCallerApp);
60
+ }
61
+ }
62
+ function parseSpstModelId(modelId) {
63
+ if (modelId.startsWith("openai/")) return {
64
+ provider: "openai",
65
+ proxyModelId: modelId
66
+ };
67
+ if (modelId.startsWith("google/")) return {
68
+ provider: "google",
69
+ proxyModelId: modelId.slice(7)
70
+ };
71
+ if (modelId.startsWith("anthropic/")) return {
72
+ provider: "anthropic",
73
+ proxyModelId: modelId.slice(10)
74
+ };
75
+ if (modelId.includes("/")) throw new Error(`Provider '${modelId.split("/")[0]}' is not supported by spst() yet.`);
76
+ throw new Error("The spst() helper currently requires an 'openai/<model>', 'google/<model>', or 'anthropic/<model>' model id.");
77
+ }
78
+ function wrapSpstModel(model, defaultCallerApp) {
79
+ return {
80
+ specificationVersion: model.specificationVersion,
81
+ provider: model.provider,
82
+ modelId: model.modelId,
83
+ supportedUrls: model.supportedUrls,
84
+ doGenerate: (options) => model.doGenerate(withSpstHeaders(options, defaultCallerApp)),
85
+ doStream: (options) => model.doStream(withSpstHeaders(options, defaultCallerApp))
86
+ };
87
+ }
88
+ function withSpstHeaders(options, defaultCallerApp) {
89
+ var _options$providerOpti, _spstOptions$callerAp, _options$providerOpti2;
90
+ const spstOptions = (_options$providerOpti = options.providerOptions) === null || _options$providerOpti === void 0 ? void 0 : _options$providerOpti.spst;
91
+ if (!spstOptions) return options;
92
+ const callerApp = (_spstOptions$callerAp = spstOptions.callerApp) !== null && _spstOptions$callerAp !== void 0 ? _spstOptions$callerAp : defaultCallerApp;
93
+ if (!spstOptions.projectId || !spstOptions.email || !callerApp) throw new Error("The spst provider requires projectId, email, and callerApp in providerOptions.spst.");
94
+ const _ref2 = (_options$providerOpti2 = options.providerOptions) !== null && _options$providerOpti2 !== void 0 ? _options$providerOpti2 : {}, { spst: _spst } = _ref2, providerOptions = require_objectWithoutProperties._objectWithoutProperties(_ref2, _excluded);
95
+ return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, options), {}, {
96
+ headers: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, options.headers), {}, {
97
+ "x-spst-project-id": spstOptions.projectId,
98
+ "x-spst-user-email": spstOptions.email,
99
+ "x-spst-caller-app": callerApp
100
+ }),
101
+ providerOptions
102
+ });
103
+ }
104
+
105
+ //#endregion
106
+ exports.createSpstProvider = createSpstProvider;
107
+ exports.spst = spst;
@@ -0,0 +1,18 @@
1
+ import { LanguageModelV3 } from "@ai-sdk/provider";
2
+
3
+ //#region src/provider.d.ts
4
+ type SpstProviderOptions = {
5
+ projectId: string;
6
+ email: string;
7
+ callerApp: string;
8
+ };
9
+ type CreateSpstProviderParams = {
10
+ apiKey?: string;
11
+ baseUrl?: string;
12
+ callerApp: string;
13
+ };
14
+ declare function spst(modelId: string): LanguageModelV3;
15
+ declare function createSpstProvider(params: CreateSpstProviderParams): typeof spst;
16
+ //#endregion
17
+ export { CreateSpstProviderParams, SpstProviderOptions, createSpstProvider, spst };
18
+ //# sourceMappingURL=provider.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.cts","names":[],"sources":["../src/provider.ts"],"sourcesContent":[],"mappings":";;;KAOY,mBAAA;;EAAA,KAAA,EAAA,MAAA;EAMA,SAAA,EAAA,MAAA;AA4BZ,CAAA;AAIgB,KAhCJ,wBAAA,GAiCF;;;;;iBALM,IAAA,mBAAuB;iBAIvB,kBAAA,SACN,kCACA"}
@@ -0,0 +1,18 @@
1
+ import { LanguageModelV3 } from "@ai-sdk/provider";
2
+
3
+ //#region src/provider.d.ts
4
+ type SpstProviderOptions = {
5
+ projectId: string;
6
+ email: string;
7
+ callerApp: string;
8
+ };
9
+ type CreateSpstProviderParams = {
10
+ apiKey?: string;
11
+ baseUrl?: string;
12
+ callerApp: string;
13
+ };
14
+ declare function spst(modelId: string): LanguageModelV3;
15
+ declare function createSpstProvider(params: CreateSpstProviderParams): typeof spst;
16
+ //#endregion
17
+ export { CreateSpstProviderParams, SpstProviderOptions, createSpstProvider, spst };
18
+ //# sourceMappingURL=provider.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../src/provider.ts"],"sourcesContent":[],"mappings":";;;KAOY,mBAAA;;EAAA,KAAA,EAAA,MAAA;EAMA,SAAA,EAAA,MAAA;AA4BZ,CAAA;AAIgB,KAhCJ,wBAAA,GAiCF;;;;;iBALM,IAAA,mBAAuB;iBAIvB,kBAAA,SACN,kCACA"}
@@ -0,0 +1,107 @@
1
+ import { API_ENDPOINT } from "./lib/constants.mjs";
2
+ import { _objectWithoutProperties } from "./_virtual/_@oxc-project_runtime@0.103.0/helpers/objectWithoutProperties.mjs";
3
+ import { _objectSpread2 } from "./_virtual/_@oxc-project_runtime@0.103.0/helpers/objectSpread2.mjs";
4
+ import { createGoogleProxyFetch } from "./lib/google-proxy-fetch.mjs";
5
+ import { createAnthropic } from "@ai-sdk/anthropic";
6
+ import { createVertex } from "@ai-sdk/google-vertex";
7
+ import { createOpenAI } from "@ai-sdk/openai";
8
+
9
+ //#region src/provider.ts
10
+ const _excluded = ["spst"];
11
+ const spstProviders = createSpstProviders({});
12
+ function spst(modelId) {
13
+ return createSpstLanguageModel(modelId, spstProviders);
14
+ }
15
+ function createSpstProvider(params) {
16
+ const providers = createSpstProviders(params);
17
+ return (modelId) => {
18
+ return createSpstLanguageModel(modelId, providers, params.callerApp);
19
+ };
20
+ }
21
+ function createSpstProviders(config) {
22
+ var _config$apiKey;
23
+ const apiKey = (_config$apiKey = config.apiKey) !== null && _config$apiKey !== void 0 ? _config$apiKey : process.env.AI_AGENT_API_KEY;
24
+ return {
25
+ openai: createOpenAI({
26
+ name: "spst",
27
+ baseURL: getOpenAIProxyBaseUrl(config.baseUrl),
28
+ apiKey
29
+ }),
30
+ google: createVertex({
31
+ apiKey,
32
+ baseURL: getGoogleProxyBaseUrl(config.baseUrl),
33
+ fetch: createGoogleProxyFetch(apiKey)
34
+ }),
35
+ anthropic: createAnthropic({
36
+ baseURL: getAnthropicProxyBaseUrl(config.baseUrl),
37
+ apiKey
38
+ })
39
+ };
40
+ }
41
+ function getResolvedBaseUrl(baseUrl) {
42
+ var _ref;
43
+ return ((_ref = baseUrl !== null && baseUrl !== void 0 ? baseUrl : process.env.AI_AGENT_API_ENDPOINT) !== null && _ref !== void 0 ? _ref : API_ENDPOINT).replace(/\/$/, "");
44
+ }
45
+ function getOpenAIProxyBaseUrl(baseUrl) {
46
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/openai`;
47
+ }
48
+ function getGoogleProxyBaseUrl(baseUrl) {
49
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/google`;
50
+ }
51
+ function getAnthropicProxyBaseUrl(baseUrl) {
52
+ return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/anthropic`;
53
+ }
54
+ function createSpstLanguageModel(modelId, providers, defaultCallerApp) {
55
+ const parsedModelId = parseSpstModelId(modelId);
56
+ switch (parsedModelId.provider) {
57
+ case "openai": return wrapSpstModel(providers.openai.responses(parsedModelId.proxyModelId), defaultCallerApp);
58
+ case "google": return wrapSpstModel(providers.google(parsedModelId.proxyModelId), defaultCallerApp);
59
+ case "anthropic": return wrapSpstModel(providers.anthropic(parsedModelId.proxyModelId), defaultCallerApp);
60
+ }
61
+ }
62
+ function parseSpstModelId(modelId) {
63
+ if (modelId.startsWith("openai/")) return {
64
+ provider: "openai",
65
+ proxyModelId: modelId
66
+ };
67
+ if (modelId.startsWith("google/")) return {
68
+ provider: "google",
69
+ proxyModelId: modelId.slice(7)
70
+ };
71
+ if (modelId.startsWith("anthropic/")) return {
72
+ provider: "anthropic",
73
+ proxyModelId: modelId.slice(10)
74
+ };
75
+ if (modelId.includes("/")) throw new Error(`Provider '${modelId.split("/")[0]}' is not supported by spst() yet.`);
76
+ throw new Error("The spst() helper currently requires an 'openai/<model>', 'google/<model>', or 'anthropic/<model>' model id.");
77
+ }
78
+ function wrapSpstModel(model, defaultCallerApp) {
79
+ return {
80
+ specificationVersion: model.specificationVersion,
81
+ provider: model.provider,
82
+ modelId: model.modelId,
83
+ supportedUrls: model.supportedUrls,
84
+ doGenerate: (options) => model.doGenerate(withSpstHeaders(options, defaultCallerApp)),
85
+ doStream: (options) => model.doStream(withSpstHeaders(options, defaultCallerApp))
86
+ };
87
+ }
88
+ function withSpstHeaders(options, defaultCallerApp) {
89
+ var _options$providerOpti, _spstOptions$callerAp, _options$providerOpti2;
90
+ const spstOptions = (_options$providerOpti = options.providerOptions) === null || _options$providerOpti === void 0 ? void 0 : _options$providerOpti.spst;
91
+ if (!spstOptions) return options;
92
+ const callerApp = (_spstOptions$callerAp = spstOptions.callerApp) !== null && _spstOptions$callerAp !== void 0 ? _spstOptions$callerAp : defaultCallerApp;
93
+ if (!spstOptions.projectId || !spstOptions.email || !callerApp) throw new Error("The spst provider requires projectId, email, and callerApp in providerOptions.spst.");
94
+ const _ref2 = (_options$providerOpti2 = options.providerOptions) !== null && _options$providerOpti2 !== void 0 ? _options$providerOpti2 : {}, { spst: _spst } = _ref2, providerOptions = _objectWithoutProperties(_ref2, _excluded);
95
+ return _objectSpread2(_objectSpread2({}, options), {}, {
96
+ headers: _objectSpread2(_objectSpread2({}, options.headers), {}, {
97
+ "x-spst-project-id": spstOptions.projectId,
98
+ "x-spst-user-email": spstOptions.email,
99
+ "x-spst-caller-app": callerApp
100
+ }),
101
+ providerOptions
102
+ });
103
+ }
104
+
105
+ //#endregion
106
+ export { createSpstProvider, spst };
107
+ //# sourceMappingURL=provider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.mjs","names":[],"sources":["../src/provider.ts"],"sourcesContent":["import { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createVertex } from \"@ai-sdk/google-vertex\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type { LanguageModelV3 } from \"@ai-sdk/provider\";\nimport { API_ENDPOINT } from \"@/lib/constants\";\nimport { createGoogleProxyFetch } from \"@/lib/google-proxy-fetch\";\n\nexport type SpstProviderOptions = {\n projectId: string;\n email: string;\n callerApp: string;\n};\n\nexport type CreateSpstProviderParams = {\n apiKey?: string;\n baseUrl?: string;\n callerApp: string;\n};\n\ntype SpstProviderConfig = Pick<CreateSpstProviderParams, \"apiKey\" | \"baseUrl\">;\ntype SpstProviderSet = {\n openai: ReturnType<typeof createOpenAI>;\n google: ReturnType<typeof createVertex>;\n anthropic: ReturnType<typeof createAnthropic>;\n};\ntype ParsedSpstModelId =\n | {\n provider: \"openai\";\n proxyModelId: string;\n }\n | {\n provider: \"google\";\n proxyModelId: string;\n }\n | {\n provider: \"anthropic\";\n proxyModelId: string;\n };\n\nconst spstProviders = createSpstProviders({});\n\nexport function spst(modelId: string): LanguageModelV3 {\n return createSpstLanguageModel(modelId, spstProviders);\n}\n\nexport function createSpstProvider(\n params: CreateSpstProviderParams,\n): typeof spst {\n const providers = createSpstProviders(params);\n\n return (modelId: string) => {\n return createSpstLanguageModel(modelId, providers, params.callerApp);\n };\n}\n\nfunction createSpstProviders(config: SpstProviderConfig): SpstProviderSet {\n const apiKey = config.apiKey ?? process.env.AI_AGENT_API_KEY;\n\n return {\n openai: createOpenAI({\n name: \"spst\",\n baseURL: getOpenAIProxyBaseUrl(config.baseUrl),\n apiKey,\n }),\n google: createVertex({\n apiKey,\n baseURL: getGoogleProxyBaseUrl(config.baseUrl),\n fetch: createGoogleProxyFetch(apiKey),\n }),\n anthropic: createAnthropic({\n baseURL: getAnthropicProxyBaseUrl(config.baseUrl),\n apiKey,\n }),\n };\n}\n\nfunction getResolvedBaseUrl(baseUrl?: string) {\n const resolvedBaseUrl =\n baseUrl ?? process.env.AI_AGENT_API_ENDPOINT ?? API_ENDPOINT;\n return resolvedBaseUrl.replace(/\\/$/, \"\");\n}\n\nfunction getOpenAIProxyBaseUrl(baseUrl?: string) {\n return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/openai`;\n}\n\nfunction getGoogleProxyBaseUrl(baseUrl?: string) {\n return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/google`;\n}\n\nfunction getAnthropicProxyBaseUrl(baseUrl?: string) {\n return `${getResolvedBaseUrl(baseUrl)}/api/proxy/v1/anthropic`;\n}\n\nfunction createSpstLanguageModel(\n modelId: string,\n providers: SpstProviderSet,\n defaultCallerApp?: string,\n) {\n const parsedModelId = parseSpstModelId(modelId);\n\n switch (parsedModelId.provider) {\n case \"openai\":\n return wrapSpstModel(\n providers.openai.responses(parsedModelId.proxyModelId),\n defaultCallerApp,\n );\n case \"google\":\n return wrapSpstModel(\n providers.google(parsedModelId.proxyModelId),\n defaultCallerApp,\n );\n case \"anthropic\":\n return wrapSpstModel(\n providers.anthropic(parsedModelId.proxyModelId),\n defaultCallerApp,\n );\n }\n}\n\nfunction parseSpstModelId(modelId: string): ParsedSpstModelId {\n if (modelId.startsWith(\"openai/\")) {\n return {\n provider: \"openai\",\n proxyModelId: modelId,\n };\n }\n\n if (modelId.startsWith(\"google/\")) {\n return {\n provider: \"google\",\n proxyModelId: modelId.slice(\"google/\".length),\n };\n }\n\n if (modelId.startsWith(\"anthropic/\")) {\n return {\n provider: \"anthropic\",\n proxyModelId: modelId.slice(\"anthropic/\".length),\n };\n }\n\n if (modelId.includes(\"/\")) {\n throw new Error(\n `Provider '${modelId.split(\"/\")[0]}' is not supported by spst() yet.`,\n );\n }\n\n throw new Error(\n \"The spst() helper currently requires an 'openai/<model>', 'google/<model>', or 'anthropic/<model>' model id.\",\n );\n}\n\nfunction wrapSpstModel(\n model: LanguageModelV3,\n defaultCallerApp?: string,\n): LanguageModelV3 {\n return {\n specificationVersion: model.specificationVersion,\n provider: model.provider,\n modelId: model.modelId,\n supportedUrls: model.supportedUrls,\n doGenerate: (options) =>\n model.doGenerate(withSpstHeaders(options, defaultCallerApp)),\n doStream: (options) =>\n model.doStream(withSpstHeaders(options, defaultCallerApp)),\n };\n}\n\nfunction withSpstHeaders(\n options: Parameters<LanguageModelV3[\"doGenerate\"]>[0],\n defaultCallerApp?: string,\n): Parameters<LanguageModelV3[\"doGenerate\"]>[0] {\n const spstOptions = options.providerOptions?.spst as\n | Partial<SpstProviderOptions>\n | undefined;\n\n if (!spstOptions) {\n return options;\n }\n\n const callerApp = spstOptions.callerApp ?? defaultCallerApp;\n\n if (!spstOptions.projectId || !spstOptions.email || !callerApp) {\n throw new Error(\n \"The spst provider requires projectId, email, and callerApp in providerOptions.spst.\",\n );\n }\n\n const { spst: _spst, ...providerOptions } = options.providerOptions ?? {};\n\n return {\n ...options,\n headers: {\n ...options.headers,\n \"x-spst-project-id\": spstOptions.projectId,\n \"x-spst-user-email\": spstOptions.email,\n \"x-spst-caller-app\": callerApp,\n },\n providerOptions,\n };\n}\n"],"mappings":";;;;;;;;;mBA6LU;AAtJV,MAAM,gBAAgB,oBAAoB,EAAE,CAAC;AAE7C,SAAgB,KAAK,SAAkC;AACrD,QAAO,wBAAwB,SAAS,cAAc;;AAGxD,SAAgB,mBACd,QACa;CACb,MAAM,YAAY,oBAAoB,OAAO;AAE7C,SAAQ,YAAoB;AAC1B,SAAO,wBAAwB,SAAS,WAAW,OAAO,UAAU;;;AAIxE,SAAS,oBAAoB,QAA6C;;CACxE,MAAM,2BAAS,OAAO,iEAAU,QAAQ,IAAI;AAE5C,QAAO;EACL,QAAQ,aAAa;GACnB,MAAM;GACN,SAAS,sBAAsB,OAAO,QAAQ;GAC9C;GACD,CAAC;EACF,QAAQ,aAAa;GACnB;GACA,SAAS,sBAAsB,OAAO,QAAQ;GAC9C,OAAO,uBAAuB,OAAO;GACtC,CAAC;EACF,WAAW,gBAAgB;GACzB,SAAS,yBAAyB,OAAO,QAAQ;GACjD;GACD,CAAC;EACH;;AAGH,SAAS,mBAAmB,SAAkB;;AAG5C,iBADE,mDAAW,QAAQ,IAAI,4DAAyB,cAC3B,QAAQ,OAAO,GAAG;;AAG3C,SAAS,sBAAsB,SAAkB;AAC/C,QAAO,GAAG,mBAAmB,QAAQ,CAAC;;AAGxC,SAAS,sBAAsB,SAAkB;AAC/C,QAAO,GAAG,mBAAmB,QAAQ,CAAC;;AAGxC,SAAS,yBAAyB,SAAkB;AAClD,QAAO,GAAG,mBAAmB,QAAQ,CAAC;;AAGxC,SAAS,wBACP,SACA,WACA,kBACA;CACA,MAAM,gBAAgB,iBAAiB,QAAQ;AAE/C,SAAQ,cAAc,UAAtB;EACE,KAAK,SACH,QAAO,cACL,UAAU,OAAO,UAAU,cAAc,aAAa,EACtD,iBACD;EACH,KAAK,SACH,QAAO,cACL,UAAU,OAAO,cAAc,aAAa,EAC5C,iBACD;EACH,KAAK,YACH,QAAO,cACL,UAAU,UAAU,cAAc,aAAa,EAC/C,iBACD;;;AAIP,SAAS,iBAAiB,SAAoC;AAC5D,KAAI,QAAQ,WAAW,UAAU,CAC/B,QAAO;EACL,UAAU;EACV,cAAc;EACf;AAGH,KAAI,QAAQ,WAAW,UAAU,CAC/B,QAAO;EACL,UAAU;EACV,cAAc,QAAQ,MAAM,EAAiB;EAC9C;AAGH,KAAI,QAAQ,WAAW,aAAa,CAClC,QAAO;EACL,UAAU;EACV,cAAc,QAAQ,MAAM,GAAoB;EACjD;AAGH,KAAI,QAAQ,SAAS,IAAI,CACvB,OAAM,IAAI,MACR,aAAa,QAAQ,MAAM,IAAI,CAAC,GAAG,mCACpC;AAGH,OAAM,IAAI,MACR,+GACD;;AAGH,SAAS,cACP,OACA,kBACiB;AACjB,QAAO;EACL,sBAAsB,MAAM;EAC5B,UAAU,MAAM;EAChB,SAAS,MAAM;EACf,eAAe,MAAM;EACrB,aAAa,YACX,MAAM,WAAW,gBAAgB,SAAS,iBAAiB,CAAC;EAC9D,WAAW,YACT,MAAM,SAAS,gBAAgB,SAAS,iBAAiB,CAAC;EAC7D;;AAGH,SAAS,gBACP,SACA,kBAC8C;;CAC9C,MAAM,uCAAc,QAAQ,+FAAiB;AAI7C,KAAI,CAAC,YACH,QAAO;CAGT,MAAM,qCAAY,YAAY,kFAAa;AAE3C,KAAI,CAAC,YAAY,aAAa,CAAC,YAAY,SAAS,CAAC,UACnD,OAAM,IAAI,MACR,sFACD;CAGH,wCAA4C,QAAQ,0FAAmB,EAAE,EAAnE,EAAE,MAAM,iBAAU;AAExB,0CACK;EACH,2CACK,QAAQ;GACX,qBAAqB,YAAY;GACjC,qBAAqB,YAAY;GACjC,qBAAqB;;EAEvB"}