@evolinkai/mcp 0.0.0-stage → 1.3.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.
Files changed (103) hide show
  1. package/LICENSE +178 -0
  2. package/README.md +67 -2
  3. package/dist/core/src/config.d.ts +19 -0
  4. package/dist/core/src/config.d.ts.map +1 -0
  5. package/dist/core/src/config.js +88 -0
  6. package/dist/core/src/config.js.map +1 -0
  7. package/dist/core/src/data/model-params.d.ts +49 -0
  8. package/dist/core/src/data/model-params.d.ts.map +1 -0
  9. package/dist/core/src/data/model-params.generated.d.ts +2 -0
  10. package/dist/core/src/data/model-params.generated.d.ts.map +1 -0
  11. package/dist/core/src/data/model-params.generated.js +3 -0
  12. package/dist/core/src/data/model-params.generated.js.map +1 -0
  13. package/dist/core/src/data/model-params.js +22 -0
  14. package/dist/core/src/data/model-params.js.map +1 -0
  15. package/dist/core/src/request-context.d.ts +60 -0
  16. package/dist/core/src/request-context.d.ts.map +1 -0
  17. package/dist/core/src/request-context.js +39 -0
  18. package/dist/core/src/request-context.js.map +1 -0
  19. package/dist/core/src/server.d.ts +18 -0
  20. package/dist/core/src/server.d.ts.map +1 -0
  21. package/dist/core/src/server.js +84 -0
  22. package/dist/core/src/server.js.map +1 -0
  23. package/dist/core/src/services/api-client.d.ts +129 -0
  24. package/dist/core/src/services/api-client.d.ts.map +1 -0
  25. package/dist/core/src/services/api-client.js +163 -0
  26. package/dist/core/src/services/api-client.js.map +1 -0
  27. package/dist/core/src/services/error-handler.d.ts +51 -0
  28. package/dist/core/src/services/error-handler.d.ts.map +1 -0
  29. package/dist/core/src/services/error-handler.js +390 -0
  30. package/dist/core/src/services/error-handler.js.map +1 -0
  31. package/dist/core/src/services/file-client.d.ts +24 -0
  32. package/dist/core/src/services/file-client.d.ts.map +1 -0
  33. package/dist/core/src/services/file-client.js +100 -0
  34. package/dist/core/src/services/file-client.js.map +1 -0
  35. package/dist/core/src/services/http-policy.d.ts +40 -0
  36. package/dist/core/src/services/http-policy.d.ts.map +1 -0
  37. package/dist/core/src/services/http-policy.js +120 -0
  38. package/dist/core/src/services/http-policy.js.map +1 -0
  39. package/dist/core/src/services/model-catalog.d.ts +24 -0
  40. package/dist/core/src/services/model-catalog.d.ts.map +1 -0
  41. package/dist/core/src/services/model-catalog.js +45 -0
  42. package/dist/core/src/services/model-catalog.js.map +1 -0
  43. package/dist/core/src/services/param-validator.d.ts +21 -0
  44. package/dist/core/src/services/param-validator.d.ts.map +1 -0
  45. package/dist/core/src/services/param-validator.js +164 -0
  46. package/dist/core/src/services/param-validator.js.map +1 -0
  47. package/dist/core/src/services/pricing-client.d.ts +77 -0
  48. package/dist/core/src/services/pricing-client.d.ts.map +1 -0
  49. package/dist/core/src/services/pricing-client.js +332 -0
  50. package/dist/core/src/services/pricing-client.js.map +1 -0
  51. package/dist/core/src/services/upload-policy.d.ts +17 -0
  52. package/dist/core/src/services/upload-policy.d.ts.map +1 -0
  53. package/dist/core/src/services/upload-policy.js +160 -0
  54. package/dist/core/src/services/upload-policy.js.map +1 -0
  55. package/dist/core/src/tools/check-balance.d.ts +4 -0
  56. package/dist/core/src/tools/check-balance.d.ts.map +1 -0
  57. package/dist/core/src/tools/check-balance.js +78 -0
  58. package/dist/core/src/tools/check-balance.js.map +1 -0
  59. package/dist/core/src/tools/estimate-cost.d.ts +4 -0
  60. package/dist/core/src/tools/estimate-cost.d.ts.map +1 -0
  61. package/dist/core/src/tools/estimate-cost.js +127 -0
  62. package/dist/core/src/tools/estimate-cost.js.map +1 -0
  63. package/dist/core/src/tools/generate.d.ts +4 -0
  64. package/dist/core/src/tools/generate.d.ts.map +1 -0
  65. package/dist/core/src/tools/generate.js +178 -0
  66. package/dist/core/src/tools/generate.js.map +1 -0
  67. package/dist/core/src/tools/get-model.d.ts +5 -0
  68. package/dist/core/src/tools/get-model.d.ts.map +1 -0
  69. package/dist/core/src/tools/get-model.js +109 -0
  70. package/dist/core/src/tools/get-model.js.map +1 -0
  71. package/dist/core/src/tools/get-task.d.ts +7 -0
  72. package/dist/core/src/tools/get-task.d.ts.map +1 -0
  73. package/dist/core/src/tools/get-task.js +55 -0
  74. package/dist/core/src/tools/get-task.js.map +1 -0
  75. package/dist/core/src/tools/list-tasks.d.ts +6 -0
  76. package/dist/core/src/tools/list-tasks.d.ts.map +1 -0
  77. package/dist/core/src/tools/list-tasks.js +142 -0
  78. package/dist/core/src/tools/list-tasks.js.map +1 -0
  79. package/dist/core/src/tools/search-models.d.ts +5 -0
  80. package/dist/core/src/tools/search-models.d.ts.map +1 -0
  81. package/dist/core/src/tools/search-models.js +96 -0
  82. package/dist/core/src/tools/search-models.js.map +1 -0
  83. package/dist/core/src/tools/shared.d.ts +50 -0
  84. package/dist/core/src/tools/shared.d.ts.map +1 -0
  85. package/dist/core/src/tools/shared.js +129 -0
  86. package/dist/core/src/tools/shared.js.map +1 -0
  87. package/dist/core/src/tools/task-format.d.ts +32 -0
  88. package/dist/core/src/tools/task-format.d.ts.map +1 -0
  89. package/dist/core/src/tools/task-format.js +138 -0
  90. package/dist/core/src/tools/task-format.js.map +1 -0
  91. package/dist/core/src/tools/upload-file.d.ts +7 -0
  92. package/dist/core/src/tools/upload-file.d.ts.map +1 -0
  93. package/dist/core/src/tools/upload-file.js +104 -0
  94. package/dist/core/src/tools/upload-file.js.map +1 -0
  95. package/dist/core/src/version.d.ts +3 -0
  96. package/dist/core/src/version.d.ts.map +1 -0
  97. package/dist/core/src/version.js +3 -0
  98. package/dist/core/src/version.js.map +1 -0
  99. package/dist/evolink-media/src/index.d.ts +3 -0
  100. package/dist/evolink-media/src/index.d.ts.map +1 -0
  101. package/dist/evolink-media/src/index.js +16 -0
  102. package/dist/evolink-media/src/index.js.map +1 -0
  103. package/package.json +46 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-params.generated.js","sourceRoot":"","sources":["../../../../../core/src/data/model-params.generated.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,MAAM,CAAC,MAAM,iBAAiB,GAAW,47idAA47id,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { MODEL_PARAMS_JSON } from './model-params.generated.js';
2
+ let index;
3
+ function load() {
4
+ index ??= JSON.parse(MODEL_PARAMS_JSON);
5
+ return index;
6
+ }
7
+ export function modelParamsMeta() {
8
+ return load().meta;
9
+ }
10
+ export function allModelParams() {
11
+ return Object.values(load().models);
12
+ }
13
+ /** Exact model ID first, then a case-insensitive match. */
14
+ export function findModelParams(model) {
15
+ const models = load().models;
16
+ const trimmed = model.trim();
17
+ if (models[trimmed])
18
+ return models[trimmed];
19
+ const lower = trimmed.toLowerCase();
20
+ return Object.values(models).find(entry => entry.model.toLowerCase() === lower);
21
+ }
22
+ //# sourceMappingURL=model-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-params.js","sourceRoot":"","sources":["../../../../../core/src/data/model-params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAuDhE,IAAI,KAAmC,CAAC;AAExC,SAAS,IAAI;IACX,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAqB,CAAC;IAC5D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,MAAM,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Per-request EvoLink credentials for the hosted (remote) MCP service.
3
+ *
4
+ * The stdio packages never enter a scope, so getApiKey() keeps reading
5
+ * EVOLINK_API_KEY or the CLI credential helper there. Inside a scope the
6
+ * request's own credential is the only one used: there is no fallback to
7
+ * process-wide credentials.
8
+ */
9
+ export interface RequestCredentials {
10
+ /** Caller's own API key (hosted api-key mode); absent for signed-in connections. */
11
+ apiKey?: string;
12
+ /** Signed-in connections (key custody A): the gateway finds the connection's key itself. */
13
+ serviceChannel?: ServiceChannelCredentials;
14
+ /** Agent-readable reason surfaced by tools that need an API key when there is none. */
15
+ unavailableReason?: string;
16
+ /** Assistant name sent as X-Evo-Client-Name; the hosted service takes it from the HTTP User-Agent. */
17
+ clientName?: string;
18
+ /** Hosted service: told about every tool call of this request, for usage records. */
19
+ onToolCall?: (call: ToolCallRecord) => void;
20
+ }
21
+ /** One tool call as usage records see it: no arguments except the model name. */
22
+ export interface ToolCallRecord {
23
+ tool: string;
24
+ ok: boolean;
25
+ /** Error category of a failed call (`exception` when the tool threw). */
26
+ category?: string;
27
+ model?: string;
28
+ durationMs: number;
29
+ }
30
+ /**
31
+ * Key custody A: this service never holds a user's key. A signed-in call
32
+ * forwards the connection's Passport access token, which this service has
33
+ * already verified; the gateway verifies it again, takes the session, account
34
+ * and client from it, checks the session with Passport and bills the account's
35
+ * EvoLink MCP key.
36
+ */
37
+ export interface ServiceChannelCredentials {
38
+ /** The connection's Passport access token (audience: this MCP server, scope mcp). */
39
+ accessToken: string;
40
+ }
41
+ export declare function runWithRequestCredentials<T>(credentials: RequestCredentials, fn: () => T): T;
42
+ export declare function currentRequestCredentials(): RequestCredentials | undefined;
43
+ /** Hosted mode: never fall back to EVOLINK_API_KEY or the local credential helper. */
44
+ export declare function disableProcessCredentials(): void;
45
+ export declare function processCredentialsAllowed(): boolean;
46
+ /**
47
+ * How this request is billed: `signed_in` spends the account's internal MCP key
48
+ * through the service channel (its limit is the user's "EvoLink MCP limit");
49
+ * `api_key` is the hosted service with the caller's own API key; `local` is a
50
+ * stdio server with EVOLINK_API_KEY or the CLI login.
51
+ */
52
+ export type CredentialMode = 'local' | 'api_key' | 'signed_in';
53
+ export declare function currentCredentialMode(): CredentialMode;
54
+ /** stdio: remember the assistant name from the MCP initialize handshake. */
55
+ export declare function setProcessClientName(name: string | undefined): void;
56
+ /** The request's assistant name inside a hosted scope, otherwise the stdio client's. */
57
+ export declare function currentClientName(): string | undefined;
58
+ /** Printable ASCII only, at most 64 characters, so it is safe in a header and a log line. */
59
+ export declare function sanitizeClientName(value: string | undefined): string | undefined;
60
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../../../core/src/request-context.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,yBAAyB,CAAC;IAC3C,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sGAAsG;IACtG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CAC7C;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5F;AAED,wBAAgB,yBAAyB,IAAI,kBAAkB,GAAG,SAAS,CAE1E;AAED,sFAAsF;AACtF,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAE/D,wBAAgB,qBAAqB,IAAI,cAAc,CAGtD;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEnE;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAItD;AAED,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGhF"}
@@ -0,0 +1,39 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ const storage = new AsyncLocalStorage();
3
+ let processCredentialsDisabled = false;
4
+ let processClientName;
5
+ export function runWithRequestCredentials(credentials, fn) {
6
+ return storage.run(credentials, fn);
7
+ }
8
+ export function currentRequestCredentials() {
9
+ return storage.getStore();
10
+ }
11
+ /** Hosted mode: never fall back to EVOLINK_API_KEY or the local credential helper. */
12
+ export function disableProcessCredentials() {
13
+ processCredentialsDisabled = true;
14
+ }
15
+ export function processCredentialsAllowed() {
16
+ return !processCredentialsDisabled;
17
+ }
18
+ export function currentCredentialMode() {
19
+ if (storage.getStore()?.serviceChannel)
20
+ return 'signed_in';
21
+ return processCredentialsDisabled ? 'api_key' : 'local';
22
+ }
23
+ /** stdio: remember the assistant name from the MCP initialize handshake. */
24
+ export function setProcessClientName(name) {
25
+ processClientName = sanitizeClientName(name);
26
+ }
27
+ /** The request's assistant name inside a hosted scope, otherwise the stdio client's. */
28
+ export function currentClientName() {
29
+ const scoped = storage.getStore();
30
+ if (scoped)
31
+ return sanitizeClientName(scoped.clientName);
32
+ return processClientName;
33
+ }
34
+ /** Printable ASCII only, at most 64 characters, so it is safe in a header and a log line. */
35
+ export function sanitizeClientName(value) {
36
+ const cleaned = (value ?? '').replace(/[^\x20-\x7e]/g, '').trim().slice(0, 64);
37
+ return cleaned || undefined;
38
+ }
39
+ //# sourceMappingURL=request-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../../../core/src/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA6CrD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAsB,CAAC;AAC5D,IAAI,0BAA0B,GAAG,KAAK,CAAC;AACvC,IAAI,iBAAqC,CAAC;AAE1C,MAAM,UAAU,yBAAyB,CAAI,WAA+B,EAAE,EAAW;IACvF,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,yBAAyB;IACvC,0BAA0B,GAAG,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO,CAAC,0BAA0B,CAAC;AACrC,CAAC;AAUD,MAAM,UAAU,qBAAqB;IACnC,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,cAAc;QAAE,OAAO,WAAW,CAAC;IAC3D,OAAO,0BAA0B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1D,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,iBAAiB,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAClC,IAAI,MAAM;QAAE,OAAO,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACzD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/E,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ServerConfig } from './config.js';
3
+ export { type ServerConfig, createConfig, getApiKey } from './config.js';
4
+ export interface ServerOptions {
5
+ /** Allow upload_file to read local paths (stdio only); the hosted service sets false. */
6
+ localFileUploads?: boolean;
7
+ /**
8
+ * Offer upload_file at all. Signed-in hosted connections set false: files-api
9
+ * accepts only the user's own API key, which key custody A never hands out.
10
+ */
11
+ uploads?: boolean;
12
+ /** Remember the client's name from initialize for X-Evo-Client-Name (stdio only; hosted requests carry their own). */
13
+ trackClientName?: boolean;
14
+ }
15
+ /** Sent to the client at initialize; most assistants add it to their instructions. */
16
+ export declare const SERVER_INSTRUCTIONS: string;
17
+ export declare function createServer(config: ServerConfig, options?: ServerOptions): McpServer;
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../core/src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAYhD,OAAO,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,WAAW,aAAa;IAC5B,yFAAyF;IACzF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sHAAsH;IACtH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,sFAAsF;AACtF,eAAO,MAAM,mBAAmB,QASpB,CAAC;AAEb,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,aAAkB,GAAG,SAAS,CAyBzF"}
@@ -0,0 +1,84 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { currentRequestCredentials, setProcessClientName } from './request-context.js';
3
+ import { registerCheckBalance } from './tools/check-balance.js';
4
+ import { registerEstimateCost } from './tools/estimate-cost.js';
5
+ import { registerGenerateTools } from './tools/generate.js';
6
+ import { registerGetModel } from './tools/get-model.js';
7
+ import { registerGetTask } from './tools/get-task.js';
8
+ import { registerListTasks } from './tools/list-tasks.js';
9
+ import { registerSearchModels } from './tools/search-models.js';
10
+ import { registerUploadFile } from './tools/upload-file.js';
11
+ import { MCP_VERSION } from './version.js';
12
+ export { createConfig, getApiKey } from './config.js';
13
+ /** Sent to the client at initialize; most assistants add it to their instructions. */
14
+ export const SERVER_INSTRUCTIONS = [
15
+ 'EvoLink creates images, videos, music and speech with 150+ models, billed to the user\'s EvoLink balance (68 credits ≈ $1).',
16
+ '- Find a model with search_models; read its parameters and prices with get_model.',
17
+ '- Before a paid generate_image, generate_video or generate_audio call, get the price with estimate_cost and tell the user; go ahead once they agree, or if they already approved this spend.',
18
+ '- generate_video and generate_audio return a task_id; wait for it with get_task (up to 45 s per call). Never call a generate tool again to check progress: that charges again.',
19
+ '- Result links expire after 24 hours; give them to the user right away.',
20
+ '- Reference images, audio and video are passed as public http(s) links. If upload_file is listed, use it for a file on the user\'s computer; if it is not, ask the user for a public link, because this connection cannot read local files or chat attachments.',
21
+ '- Errors include a next step (for example a top-up link); follow it instead of retrying blindly.',
22
+ '- When a call is refused for money, tell the user which reason the error names: the EvoLink MCP limit (or daily limit) they set, EvoLink MCP being paused, or the account balance. They need different fixes, so never call an MCP limit a low balance; give the link from the error and do not retry until the user has acted.',
23
+ ].join('\n');
24
+ export function createServer(config, options = {}) {
25
+ const server = new McpServer({
26
+ name: config.channel === 'beta' ? 'evolink-mcp-beta' : 'evolink-mcp',
27
+ title: 'EvoLink',
28
+ version: MCP_VERSION,
29
+ websiteUrl: 'https://evolink.ai/mcp',
30
+ }, { instructions: SERVER_INSTRUCTIONS });
31
+ if (options.trackClientName ?? true) {
32
+ server.server.oninitialized = () => setProcessClientName(server.server.getClientVersion()?.name);
33
+ }
34
+ observeToolCalls(server);
35
+ registerSearchModels(server);
36
+ registerGetModel(server);
37
+ registerEstimateCost(server, config);
38
+ registerGenerateTools(server, config);
39
+ registerGetTask(server, config);
40
+ registerListTasks(server, config);
41
+ if (options.uploads ?? true)
42
+ registerUploadFile(server, { localFiles: options.localFileUploads ?? true });
43
+ registerCheckBalance(server, config);
44
+ return server;
45
+ }
46
+ /** The model a call asked for, when its arguments name one. */
47
+ function modelOf(args) {
48
+ const input = args[0];
49
+ if (!input || typeof input !== 'object')
50
+ return undefined;
51
+ const model = input.model;
52
+ return typeof model === 'string' && model.length > 0 && model.length <= 100 ? model : undefined;
53
+ }
54
+ function callRecord(tool, args, result, durationMs) {
55
+ const outcome = result;
56
+ const model = modelOf(args);
57
+ const record = { tool, ok: outcome?.isError !== true, durationMs };
58
+ if (!record.ok) {
59
+ const category = outcome?.structuredContent?.error?.category;
60
+ record.category = typeof category === 'string' ? category : 'error';
61
+ }
62
+ if (model)
63
+ record.model = model;
64
+ return record;
65
+ }
66
+ /** Tells the request's observer (hosted service usage records) about every tool call; stdio has none. */
67
+ function observeToolCalls(server) {
68
+ const register = server.registerTool.bind(server);
69
+ const observed = (name, config, handler) => register(name, config, async (...args) => {
70
+ const report = currentRequestCredentials()?.onToolCall;
71
+ const started = Date.now();
72
+ try {
73
+ const result = await handler(...args);
74
+ report?.(callRecord(name, args, result, Date.now() - started));
75
+ return result;
76
+ }
77
+ catch (error) {
78
+ report?.({ tool: name, ok: false, category: 'exception', durationMs: Date.now() - started, ...(modelOf(args) ? { model: modelOf(args) } : {}) });
79
+ throw error;
80
+ }
81
+ });
82
+ server.registerTool = observed;
83
+ }
84
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../core/src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import { type ServerConfig } from '../config.js';
2
+ import { type GatewayErrorInfo } from './error-handler.js';
3
+ export type TaskStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
4
+ export interface TaskResponse {
5
+ created: number;
6
+ id: string;
7
+ model: string;
8
+ object: string;
9
+ progress: number;
10
+ status: TaskStatus;
11
+ type: string;
12
+ duration?: number;
13
+ video_duration?: number;
14
+ results?: string[];
15
+ result_data?: ResultDataItem[] | Record<string, unknown>;
16
+ task_info?: {
17
+ can_cancel?: boolean;
18
+ estimated_time?: number;
19
+ video_duration?: number;
20
+ };
21
+ usage?: {
22
+ billing_rule?: string;
23
+ credits_reserved?: number;
24
+ credits_used?: number;
25
+ cost?: {
26
+ credits?: number;
27
+ usd?: number;
28
+ cny?: number;
29
+ };
30
+ user_group?: string;
31
+ };
32
+ error?: {
33
+ code?: string;
34
+ message?: string;
35
+ type?: string;
36
+ suggestion?: string;
37
+ };
38
+ request_id?: string;
39
+ /** Set by the MCP client when the gateway answered a repeated Idempotency-Key with the original response. */
40
+ idempotency_replayed?: boolean;
41
+ }
42
+ export interface ResultDataItem {
43
+ result_id?: string;
44
+ duration?: number;
45
+ tags?: string;
46
+ title?: string;
47
+ image_url?: string;
48
+ audio_url?: string;
49
+ stream_audio_url?: string;
50
+ video_url?: string;
51
+ }
52
+ export interface TaskListItem {
53
+ id: string;
54
+ model: string;
55
+ type: string;
56
+ status: TaskStatus;
57
+ progress: number;
58
+ created_at: number;
59
+ duration?: number;
60
+ has_results?: boolean;
61
+ result_count?: number;
62
+ has_error?: boolean;
63
+ credits_used?: number;
64
+ }
65
+ export interface TaskListResponse {
66
+ data: TaskListItem[];
67
+ total: number;
68
+ page: number;
69
+ page_size: number;
70
+ }
71
+ export interface CreditsResponse {
72
+ user: {
73
+ remaining_credits: number;
74
+ used_credits: number;
75
+ };
76
+ token: {
77
+ remaining_credits: number;
78
+ used_credits: number;
79
+ unlimited_credits: boolean;
80
+ /** Daily limit of the calling key, when one is set (newer gateways). */
81
+ daily_limit_credits?: number;
82
+ daily_used_credits?: number;
83
+ reset_timezone?: string;
84
+ };
85
+ }
86
+ export declare class ApiHttpError extends Error {
87
+ readonly status: number;
88
+ readonly retryAfterMs?: number | undefined;
89
+ readonly requestId?: string | undefined;
90
+ readonly info?: GatewayErrorInfo | undefined;
91
+ constructor(status: number, message: string, retryAfterMs?: number | undefined, requestId?: string | undefined, info?: GatewayErrorInfo | undefined);
92
+ }
93
+ export declare function withRetry<T>(fn: () => Promise<T>, retries: number, baseDelayMs: number): Promise<T>;
94
+ export interface SubmitOptions {
95
+ path: string;
96
+ body: Record<string, unknown>;
97
+ tool: string;
98
+ /** Reused on a retry of the same intent; a fresh one is generated when absent. */
99
+ idempotencyKey?: string;
100
+ }
101
+ /**
102
+ * Submit one paid intent. At most one transport retry, always with the same
103
+ * idempotency key, so the gateway ledger (Idempotency-Key) can return the
104
+ * original task instead of creating a second one.
105
+ */
106
+ export declare function submitTask(config: ServerConfig, options: SubmitOptions): Promise<TaskResponse>;
107
+ /** @deprecated kept for callers outside the tools; use submitTask. */
108
+ export declare function apiRequest(config: ServerConfig, options: {
109
+ method: 'GET' | 'POST';
110
+ path: string;
111
+ body?: Record<string, unknown>;
112
+ tool?: string;
113
+ }): Promise<TaskResponse>;
114
+ /** One task (GET /v1/tasks/{id}). Unfinished tasks sync with the provider on every read, so callers pace themselves. */
115
+ export declare function queryTask(config: ServerConfig, taskId: string, tool?: string): Promise<TaskResponse>;
116
+ /** Up to 50 tasks in one call (POST /v1/tasks/batch); unknown or foreign IDs are simply absent. */
117
+ export declare function queryTasks(config: ServerConfig, taskIds: string[], tool?: string): Promise<TaskResponse[]>;
118
+ export interface ListTasksQuery {
119
+ status?: string;
120
+ type?: string;
121
+ model?: string;
122
+ page?: number;
123
+ pageSize?: number;
124
+ }
125
+ /** The account's recent tasks, newest first (GET /v1/tasks). Items carry no result links. */
126
+ export declare function listTasks(config: ServerConfig, query: ListTasksQuery, tool?: string): Promise<TaskListResponse>;
127
+ /** Account balance and this key's usage (GET /v1/credits). */
128
+ export declare function getCredits(config: ServerConfig, tool?: string): Promise<CreditsResponse>;
129
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../../../../core/src/services/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,163 @@
1
+ import { gatewayAuthHeaders } from '../config.js';
2
+ import { classifyGatewayError, formatGatewayError } from './error-handler.js';
3
+ import { DEFAULT_READ_TIMEOUT_MS, DEFAULT_SUBMIT_TIMEOUT_MS, MAX_RETRY_DELAY_MS, PaidRequestOutcomeUnknownError, RequestTimeoutError, evoHeaders, fetchWithTimeout, newRunId, parseRetryAfter, readJsonBody, responseRequestId, timeoutFromEnv, } from './http-policy.js';
4
+ // --- Error class for HTTP-level failures ---
5
+ export class ApiHttpError extends Error {
6
+ status;
7
+ retryAfterMs;
8
+ requestId;
9
+ info;
10
+ constructor(status, message, retryAfterMs, requestId, info) {
11
+ super(message);
12
+ this.status = status;
13
+ this.retryAfterMs = retryAfterMs;
14
+ this.requestId = requestId;
15
+ this.info = info;
16
+ this.name = 'ApiHttpError';
17
+ }
18
+ }
19
+ // --- Retry logic ---
20
+ const RETRYABLE_STATUS_CODES = new Set([429, 502, 503]);
21
+ function sleep(ms) {
22
+ return new Promise(resolve => setTimeout(resolve, ms));
23
+ }
24
+ function isRetryable(error) {
25
+ // Key and balance rejections are always HTTP 402, so they are never retried here.
26
+ if (error instanceof ApiHttpError)
27
+ return RETRYABLE_STATUS_CODES.has(error.status);
28
+ if (error instanceof PaidRequestOutcomeUnknownError)
29
+ return true;
30
+ if (error instanceof RequestTimeoutError)
31
+ return true;
32
+ if (error instanceof TypeError)
33
+ return true; // network errors (DNS, reset, …)
34
+ return false;
35
+ }
36
+ export async function withRetry(fn, retries, baseDelayMs) {
37
+ let lastError;
38
+ for (let attempt = 0; attempt <= retries; attempt++) {
39
+ try {
40
+ return await fn();
41
+ }
42
+ catch (error) {
43
+ lastError = error;
44
+ if (attempt < retries && isRetryable(error)) {
45
+ const retryAfterMs = error instanceof ApiHttpError ? error.retryAfterMs : undefined;
46
+ await sleep(Math.min(retryAfterMs ?? baseDelayMs * (attempt + 1), MAX_RETRY_DELAY_MS));
47
+ continue;
48
+ }
49
+ throw error;
50
+ }
51
+ }
52
+ throw lastError;
53
+ }
54
+ // --- Core request (no retry) ---
55
+ async function rawRequest(config, options) {
56
+ const url = `${config.baseUrl}${options.path}`;
57
+ const headers = {
58
+ ...gatewayAuthHeaders(),
59
+ 'Accept': 'application/json',
60
+ ...evoHeaders(options.tool ?? 'unknown'),
61
+ };
62
+ if (options.body)
63
+ headers['Content-Type'] = 'application/json';
64
+ if (options.idempotencyKey) {
65
+ headers['Idempotency-Key'] = options.idempotencyKey;
66
+ headers['X-Evo-Run-Id'] = options.idempotencyKey;
67
+ }
68
+ const isRead = options.method === 'GET' || !options.idempotencyKey;
69
+ let response;
70
+ try {
71
+ response = await fetchWithTimeout(url, {
72
+ method: options.method,
73
+ headers,
74
+ body: options.body ? JSON.stringify(options.body) : undefined,
75
+ }, options.timeoutMs ?? timeoutFromEnv(isRead ? 'EVOLINK_MCP_READ_TIMEOUT_MS' : 'EVOLINK_MCP_WRITE_TIMEOUT_MS', isRead ? DEFAULT_READ_TIMEOUT_MS : DEFAULT_SUBMIT_TIMEOUT_MS));
76
+ }
77
+ catch (error) {
78
+ if (!isRead)
79
+ throw new PaidRequestOutcomeUnknownError(error, options.idempotencyKey);
80
+ throw error;
81
+ }
82
+ const data = await readJsonBody(response);
83
+ const requestId = responseRequestId(response.headers);
84
+ if (!response.ok) {
85
+ const retryAfterMs = parseRetryAfter(response.headers.get('retry-after'));
86
+ const info = classifyGatewayError(response.status, data, retryAfterMs, requestId);
87
+ throw new ApiHttpError(response.status, formatGatewayError(info), retryAfterMs, info.request_id, info);
88
+ }
89
+ return { data: data, requestId, headers: response.headers };
90
+ }
91
+ /**
92
+ * Submit one paid intent. At most one transport retry, always with the same
93
+ * idempotency key, so the gateway ledger (Idempotency-Key) can return the
94
+ * original task instead of creating a second one.
95
+ */
96
+ export async function submitTask(config, options) {
97
+ const idempotencyKey = options.idempotencyKey ?? newRunId();
98
+ const { data, requestId, headers } = await withRetry(() => rawRequest(config, {
99
+ method: 'POST',
100
+ path: options.path,
101
+ body: options.body,
102
+ tool: options.tool,
103
+ idempotencyKey,
104
+ }), 1, 500);
105
+ if (!data.request_id && requestId)
106
+ data.request_id = requestId;
107
+ if (headers.get('idempotency-replayed') === 'true')
108
+ data.idempotency_replayed = true;
109
+ return data;
110
+ }
111
+ /** @deprecated kept for callers outside the tools; use submitTask. */
112
+ export async function apiRequest(config, options) {
113
+ if (options.method !== 'POST' || !options.body) {
114
+ throw new Error('apiRequest only accepts generation POST operations');
115
+ }
116
+ return submitTask(config, { path: options.path, body: options.body, tool: options.tool ?? 'unknown' });
117
+ }
118
+ /** One task (GET /v1/tasks/{id}). Unfinished tasks sync with the provider on every read, so callers pace themselves. */
119
+ export async function queryTask(config, taskId, tool = 'get_task') {
120
+ const { data, requestId } = await withRetry(() => rawRequest(config, { method: 'GET', path: `/v1/tasks/${encodeURIComponent(taskId)}`, tool }), 2, 1500);
121
+ if (!data.request_id && requestId)
122
+ data.request_id = requestId;
123
+ return data;
124
+ }
125
+ /** Up to 50 tasks in one call (POST /v1/tasks/batch); unknown or foreign IDs are simply absent. */
126
+ export async function queryTasks(config, taskIds, tool = 'list_tasks') {
127
+ const { data } = await withRetry(() => rawRequest(config, {
128
+ method: 'POST',
129
+ path: '/v1/tasks/batch',
130
+ body: { task_ids: taskIds },
131
+ tool,
132
+ }), 2, 1500);
133
+ return Array.isArray(data.data) ? data.data : [];
134
+ }
135
+ /** The account's recent tasks, newest first (GET /v1/tasks). Items carry no result links. */
136
+ export async function listTasks(config, query, tool = 'list_tasks') {
137
+ const params = new URLSearchParams();
138
+ if (query.status)
139
+ params.set('status', query.status);
140
+ if (query.type)
141
+ params.set('type', query.type);
142
+ if (query.model)
143
+ params.set('model', query.model);
144
+ params.set('page', String(query.page ?? 1));
145
+ params.set('page_size', String(query.pageSize ?? 20));
146
+ const { data } = await withRetry(() => rawRequest(config, { method: 'GET', path: `/v1/tasks?${params}`, tool }), 2, 1500);
147
+ return {
148
+ data: Array.isArray(data.data) ? data.data : [],
149
+ total: typeof data.total === 'number' ? data.total : 0,
150
+ page: typeof data.page === 'number' ? data.page : query.page ?? 1,
151
+ page_size: typeof data.page_size === 'number' ? data.page_size : query.pageSize ?? 20,
152
+ };
153
+ }
154
+ /** Account balance and this key's usage (GET /v1/credits). */
155
+ export async function getCredits(config, tool = 'check_balance') {
156
+ const { data, requestId } = await withRetry(() => rawRequest(config, { method: 'GET', path: '/v1/credits', tool }), 2, 1000);
157
+ if (data.success === false || !data.data?.user || !data.data?.token) {
158
+ const info = classifyGatewayError(500, { error: { message: data.message || 'The balance could not be read.' } }, undefined, requestId);
159
+ throw new ApiHttpError(500, formatGatewayError(info), undefined, requestId, info);
160
+ }
161
+ return data.data;
162
+ }
163
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../../../core/src/services/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * What the assistant should do about a rejection. The gateway already tells
3
+ * the three quota cases apart by error.code (all are HTTP 402 with the same
4
+ * error.type), so classification goes by code first and status second.
5
+ *
6
+ * A signed-in connection spends the account's internal MCP key, so its key
7
+ * limits are the user's "EvoLink MCP limit" (mcp_*), never an API key's.
8
+ */
9
+ export type ErrorCategory = 'account_balance_insufficient' | 'mcp_limit_reached' | 'mcp_daily_limit_reached' | 'mcp_paused' | 'mcp_key_expired' | 'key_quota_exhausted' | 'key_daily_quota_exhausted' | 'key_disabled' | 'key_expired' | 'model_not_allowed' | 'unauthorized' | 'forbidden' | 'rate_limited' | 'invalid_request' | 'not_found' | 'content_policy' | 'model_unavailable' | 'idempotency_conflict' | 'outcome_unknown' | 'request_too_large' | 'server_error' | 'connection_ended' | 'session_check_unavailable' | 'connection_setup_failed' | 'service_misconfigured' | 'sign_in_token_rejected' | 'mcp_channel_disabled' | 'account_disabled';
10
+ export interface GatewayErrorInfo {
11
+ status: number;
12
+ category: ErrorCategory;
13
+ /**
14
+ * First sentence for the user when a limit, the balance or the connection
15
+ * stopped the request. It names which one, so every client can tell an
16
+ * EvoLink MCP limit from an empty account.
17
+ */
18
+ headline?: string;
19
+ code?: string;
20
+ message: string;
21
+ next_step: string;
22
+ retryable: boolean;
23
+ retry_after_seconds?: number;
24
+ action_url?: string;
25
+ request_id?: string;
26
+ /** Key name, balance and limit figures the gateway attaches to quota rejections (credits). */
27
+ details?: Record<string, unknown>;
28
+ }
29
+ /** Gateway display rate: 1 USD = 6.8 CNY and 1 CNY = 10 credits. */
30
+ export declare const CREDITS_PER_USD = 68;
31
+ export declare function formatCredits(value: number): string;
32
+ export declare function formatUsd(value: number): string;
33
+ /** Classifies one non-2xx gateway or files-api response. */
34
+ export declare function classifyGatewayError(status: number, body: unknown, retryAfterMs?: number, headerRequestId?: string): GatewayErrorInfo;
35
+ /**
36
+ * With a headline the first line says which limit it is; the gateway's own
37
+ * sentence is left out because it speaks of "API key …" even for the MCP key.
38
+ */
39
+ export declare function formatGatewayError(info: GatewayErrorInfo): string;
40
+ export declare function formatApiError(status: number, body: unknown): string;
41
+ export type TaskErrorCode = 'content_policy_violation' | 'invalid_parameters' | 'image_dimension_mismatch' | 'image_processing_error' | 'request_cancelled' | 'resource_not_found' | 'generation_timeout' | 'quota_exceeded' | 'resource_exhausted' | 'generation_failed_no_content' | 'service_error' | 'service_unavailable' | 'unknown_error';
42
+ export interface TaskErrorInfo {
43
+ suggestion: string;
44
+ retryable: boolean;
45
+ }
46
+ export declare function getTaskErrorInfo(code: string): TaskErrorInfo;
47
+ export declare function formatTaskError(error: {
48
+ code?: string;
49
+ message?: string;
50
+ }): string;
51
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../../../core/src/services/error-handler.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GACrB,8BAA8B,GAC9B,mBAAmB,GACnB,yBAAyB,GACzB,YAAY,GACZ,iBAAiB,GACjB,qBAAqB,GACrB,2BAA2B,GAC3B,cAAc,GACd,aAAa,GACb,mBAAmB,GACnB,cAAc,GACd,WAAW,GACX,cAAc,GACd,iBAAiB,GACjB,WAAW,GACX,gBAAgB,GAChB,mBAAmB,GACnB,sBAAsB,GACtB,iBAAiB,GACjB,mBAAmB,GACnB,cAAc,GACd,kBAAkB,GAClB,2BAA2B,GAC3B,yBAAyB,GACzB,uBAAuB,GACvB,wBAAwB,GACxB,sBAAsB,GACtB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,aAAa,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,oEAAoE;AACpE,eAAO,MAAM,eAAe,KAAK,CAAC;AAqHlC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK/C;AA0JD,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,eAAe,CAAC,EAAE,MAAM,GACvB,gBAAgB,CAuClB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAOjE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAEpE;AAID,MAAM,MAAM,aAAa,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,0BAA0B,GAC1B,wBAAwB,GACxB,mBAAmB,GACnB,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,oBAAoB,GACpB,8BAA8B,GAC9B,eAAe,GACf,qBAAqB,GACrB,eAAe,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAyDD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAE5D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAUlF"}