@sync.so/mcp-server 0.1.4 → 0.2.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 +261 -86
- package/deploy/generation-status/app.html.gz +0 -0
- package/deploy/generation-status/release.json +6 -0
- package/dist/abort-signals.d.ts +6 -0
- package/dist/abort-signals.d.ts.map +1 -0
- package/dist/abort-signals.js +23 -0
- package/dist/account-features.d.ts +7 -0
- package/dist/account-features.d.ts.map +1 -0
- package/dist/account-features.js +48 -0
- package/dist/app-upload-relay.d.ts +13 -0
- package/dist/app-upload-relay.d.ts.map +1 -0
- package/dist/app-upload-relay.js +136 -0
- package/dist/asset-thumbnail.d.ts +3 -0
- package/dist/asset-thumbnail.d.ts.map +1 -0
- package/dist/asset-thumbnail.js +2 -0
- package/dist/auth/async-context.d.ts +5 -0
- package/dist/auth/async-context.d.ts.map +1 -0
- package/dist/auth/async-context.js +14 -0
- package/dist/auth/bearer-auth.d.ts +16 -0
- package/dist/auth/bearer-auth.d.ts.map +1 -0
- package/dist/auth/bearer-auth.js +55 -0
- package/dist/auth/client-credentials.d.ts +13 -0
- package/dist/auth/client-credentials.d.ts.map +1 -0
- package/dist/auth/client-credentials.js +67 -0
- package/dist/auth/device-auth.d.ts.map +1 -1
- package/dist/auth/device-auth.js +3 -2
- package/dist/auth/fixture-cleanup.d.ts +4 -0
- package/dist/auth/fixture-cleanup.d.ts.map +1 -0
- package/dist/auth/fixture-cleanup.js +9 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -0
- package/dist/auth/oauth-diagnostics.d.ts +11 -0
- package/dist/auth/oauth-diagnostics.d.ts.map +1 -0
- package/dist/auth/oauth-diagnostics.js +78 -0
- package/dist/auth/oauth-provider.d.ts +16 -0
- package/dist/auth/oauth-provider.d.ts.map +1 -0
- package/dist/auth/oauth-provider.js +107 -0
- package/dist/auth/resource-metadata.d.ts +2 -0
- package/dist/auth/resource-metadata.d.ts.map +1 -0
- package/dist/auth/resource-metadata.js +3 -0
- package/dist/auth/token-verification.d.ts +11 -0
- package/dist/auth/token-verification.d.ts.map +1 -0
- package/dist/auth/token-verification.js +99 -0
- package/dist/auth/verification-cache.d.ts +8 -0
- package/dist/auth/verification-cache.d.ts.map +1 -0
- package/dist/auth/verification-cache.js +111 -0
- package/dist/chatgpt-analytics.d.ts +22 -0
- package/dist/chatgpt-analytics.d.ts.map +1 -0
- package/dist/chatgpt-analytics.js +172 -0
- package/dist/chatgpt-app.d.ts +15 -0
- package/dist/chatgpt-app.d.ts.map +1 -0
- package/dist/chatgpt-app.js +133 -0
- package/dist/chatgpt-release.d.ts +12 -0
- package/dist/chatgpt-release.d.ts.map +1 -0
- package/dist/chatgpt-release.js +30 -0
- package/dist/cli.js +30 -16
- package/dist/client-profile.d.ts +10 -0
- package/dist/client-profile.d.ts.map +1 -0
- package/dist/client-profile.js +45 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +52 -0
- package/dist/generation-status-html.d.ts +2 -0
- package/dist/generation-status-html.d.ts.map +1 -0
- package/dist/generation-status-html.js +26 -0
- package/dist/generation-status.d.ts +6 -0
- package/dist/generation-status.d.ts.map +1 -0
- package/dist/generation-status.js +37 -0
- package/dist/http-client.d.ts +45 -1
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +171 -34
- package/dist/http-server.d.ts +53 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +753 -0
- package/dist/http-session.d.ts +18 -0
- package/dist/http-session.d.ts.map +1 -0
- package/dist/http-session.js +189 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/oauth-response.d.ts +3 -0
- package/dist/oauth-response.d.ts.map +1 -0
- package/dist/oauth-response.js +30 -0
- package/dist/openapi/index.d.ts +2 -2
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/parser.d.ts +2 -0
- package/dist/openapi/parser.d.ts.map +1 -1
- package/dist/openapi/parser.js +41 -1
- package/dist/openapi/types.d.ts +3 -0
- package/dist/openapi/types.d.ts.map +1 -1
- package/dist/organization-selection.d.ts +61 -0
- package/dist/organization-selection.d.ts.map +1 -0
- package/dist/organization-selection.js +142 -0
- package/dist/rate-limits.d.ts +13 -0
- package/dist/rate-limits.d.ts.map +1 -0
- package/dist/rate-limits.js +67 -0
- package/dist/revision.d.ts +6 -0
- package/dist/revision.d.ts.map +1 -0
- package/dist/revision.js +17 -0
- package/dist/runtime-diagnostics.d.ts +32 -0
- package/dist/runtime-diagnostics.d.ts.map +1 -0
- package/dist/runtime-diagnostics.js +58 -0
- package/dist/server.d.ts +23 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +893 -32
- package/dist/session-registry.d.ts +54 -0
- package/dist/session-registry.d.ts.map +1 -0
- package/dist/session-registry.js +202 -0
- package/dist/session-telemetry.d.ts +13 -0
- package/dist/session-telemetry.d.ts.map +1 -0
- package/dist/session-telemetry.js +87 -0
- package/dist/spend-confirmation.d.ts +21 -0
- package/dist/spend-confirmation.d.ts.map +1 -0
- package/dist/spend-confirmation.js +105 -0
- package/dist/tool-analytics-context.d.ts +11 -0
- package/dist/tool-analytics-context.d.ts.map +1 -0
- package/dist/tool-analytics-context.js +8 -0
- package/dist/tool-names.d.ts +35 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tool-names.js +133 -0
- package/dist/tools/account-context.d.ts +5 -0
- package/dist/tools/account-context.d.ts.map +1 -0
- package/dist/tools/account-context.js +131 -0
- package/dist/tools/account-management.d.ts +4 -0
- package/dist/tools/account-management.d.ts.map +1 -0
- package/dist/tools/account-management.js +111 -0
- package/dist/tools/app-tools.d.ts +31 -0
- package/dist/tools/app-tools.d.ts.map +1 -0
- package/dist/tools/app-tools.js +350 -0
- package/dist/tools/asset-analysis.d.ts +4 -0
- package/dist/tools/asset-analysis.d.ts.map +1 -0
- package/dist/tools/asset-analysis.js +172 -0
- package/dist/tools/asset-creators.d.ts +4 -0
- package/dist/tools/asset-creators.d.ts.map +1 -0
- package/dist/tools/asset-creators.js +38 -0
- package/dist/tools/audio-trim.d.ts +6 -0
- package/dist/tools/audio-trim.d.ts.map +1 -0
- package/dist/tools/audio-trim.js +79 -0
- package/dist/tools/batch-results.d.ts +16 -0
- package/dist/tools/batch-results.d.ts.map +1 -0
- package/dist/tools/batch-results.js +103 -0
- package/dist/tools/batches.d.ts +28 -0
- package/dist/tools/batches.d.ts.map +1 -0
- package/dist/tools/batches.js +293 -0
- package/dist/tools/dialogue.d.ts +6 -0
- package/dist/tools/dialogue.d.ts.map +1 -0
- package/dist/tools/dialogue.js +309 -0
- package/dist/tools/estimate-duration.d.ts +35 -0
- package/dist/tools/estimate-duration.d.ts.map +1 -0
- package/dist/tools/estimate-duration.js +66 -0
- package/dist/tools/feedback.d.ts +14 -0
- package/dist/tools/feedback.d.ts.map +1 -0
- package/dist/tools/feedback.js +72 -0
- package/dist/tools/generated-adapters.d.ts +25 -0
- package/dist/tools/generated-adapters.d.ts.map +1 -0
- package/dist/tools/generated-adapters.js +143 -0
- package/dist/tools/generation-context.d.ts +14 -0
- package/dist/tools/generation-context.d.ts.map +1 -0
- package/dist/tools/generation-context.js +39 -0
- package/dist/tools/generation-continuation.d.ts +4 -0
- package/dist/tools/generation-continuation.d.ts.map +1 -0
- package/dist/tools/generation-continuation.js +124 -0
- package/dist/tools/generation-costs.d.ts +6 -0
- package/dist/tools/generation-costs.d.ts.map +1 -0
- package/dist/tools/generation-costs.js +67 -0
- package/dist/tools/generation-output.d.ts +3 -0
- package/dist/tools/generation-output.d.ts.map +1 -0
- package/dist/tools/generation-output.js +39 -0
- package/dist/tools/generator.d.ts +35 -2
- package/dist/tools/generator.d.ts.map +1 -1
- package/dist/tools/generator.js +127 -9
- package/dist/tools/job-status.d.ts +35 -0
- package/dist/tools/job-status.d.ts.map +1 -0
- package/dist/tools/job-status.js +92 -0
- package/dist/tools/job-wait.d.ts +41 -0
- package/dist/tools/job-wait.d.ts.map +1 -0
- package/dist/tools/job-wait.js +84 -0
- package/dist/tools/jobs.d.ts +3 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +210 -0
- package/dist/tools/media-upload.d.ts +27 -0
- package/dist/tools/media-upload.d.ts.map +1 -0
- package/dist/tools/media-upload.js +247 -0
- package/dist/tools/model-options.d.ts +36 -0
- package/dist/tools/model-options.d.ts.map +1 -0
- package/dist/tools/model-options.js +48 -0
- package/dist/tools/organization-choice.d.ts +9 -0
- package/dist/tools/organization-choice.d.ts.map +1 -0
- package/dist/tools/organization-choice.js +136 -0
- package/dist/tools/organizations.d.ts +56 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +235 -0
- package/dist/tools/output-schemas.d.ts +54 -0
- package/dist/tools/output-schemas.d.ts.map +1 -0
- package/dist/tools/output-schemas.js +58 -0
- package/dist/tools/overrides.d.ts +3 -0
- package/dist/tools/overrides.d.ts.map +1 -1
- package/dist/tools/overrides.js +113 -15
- package/dist/tools/playback-metadata.d.ts +4 -0
- package/dist/tools/playback-metadata.d.ts.map +1 -0
- package/dist/tools/playback-metadata.js +51 -0
- package/dist/tools/project-destination.d.ts +13 -0
- package/dist/tools/project-destination.d.ts.map +1 -0
- package/dist/tools/project-destination.js +45 -0
- package/dist/tools/project-history.d.ts +6 -0
- package/dist/tools/project-history.d.ts.map +1 -0
- package/dist/tools/project-history.js +45 -0
- package/dist/tools/project-intent.d.ts +8 -0
- package/dist/tools/project-intent.d.ts.map +1 -0
- package/dist/tools/project-intent.js +87 -0
- package/dist/tools/running-submissions.d.ts +7 -0
- package/dist/tools/running-submissions.d.ts.map +1 -0
- package/dist/tools/running-submissions.js +91 -0
- package/dist/tools/speech.d.ts +6 -0
- package/dist/tools/speech.d.ts.map +1 -0
- package/dist/tools/speech.js +116 -0
- package/dist/tools/studio-draft.d.ts +7 -0
- package/dist/tools/studio-draft.d.ts.map +1 -0
- package/dist/tools/studio-draft.js +195 -0
- package/dist/tools/studio-view-contract.d.ts +184 -0
- package/dist/tools/studio-view-contract.d.ts.map +1 -0
- package/dist/tools/studio-view-contract.js +67 -0
- package/dist/tools/studio-view.d.ts +6 -0
- package/dist/tools/studio-view.d.ts.map +1 -0
- package/dist/tools/studio-view.js +126 -0
- package/dist/tools/timeline-lipsync.d.ts +316 -0
- package/dist/tools/timeline-lipsync.d.ts.map +1 -0
- package/dist/tools/timeline-lipsync.js +304 -0
- package/dist/tools/translation-preview.d.ts +8 -0
- package/dist/tools/translation-preview.d.ts.map +1 -0
- package/dist/tools/translation-preview.js +146 -0
- package/dist/tools/translation.d.ts +6 -0
- package/dist/tools/translation.d.ts.map +1 -0
- package/dist/tools/translation.js +131 -0
- package/dist/tools/upload-widget.d.ts +13 -0
- package/dist/tools/upload-widget.d.ts.map +1 -0
- package/dist/tools/upload-widget.js +788 -0
- package/dist/toolsets.d.ts +18 -0
- package/dist/toolsets.d.ts.map +1 -0
- package/dist/toolsets.js +157 -0
- package/dist/update-check.d.ts +38 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +150 -0
- package/dist/upload-runtime.d.ts +45 -0
- package/dist/upload-runtime.d.ts.map +1 -0
- package/dist/upload-runtime.js +156 -0
- package/dist/upload-source.d.ts +4 -0
- package/dist/upload-source.d.ts.map +1 -0
- package/dist/upload-source.js +46 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/package.json +77 -31
- package/dist/openapi/parser.test.d.ts +0 -2
- package/dist/openapi/parser.test.d.ts.map +0 -1
- package/dist/openapi/parser.test.js +0 -188
- package/dist/tools/generator.test.d.ts +0 -2
- package/dist/tools/generator.test.d.ts.map +0 -1
- package/dist/tools/generator.test.js +0 -178
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { isImportInProgress, jobSettled, rawStatus } from './job-status.js';
|
|
3
|
+
import { pollUntil, waitInput } from './job-wait.js';
|
|
4
|
+
/**
|
|
5
|
+
* Agent-facing fixes for tools generated straight from the public OpenAPI spec. Each one
|
|
6
|
+
* keeps accepting the generated input, so callers holding the old tool list still work.
|
|
7
|
+
*/
|
|
8
|
+
// Tools whose project is the target itself: the caller names the project to read or
|
|
9
|
+
// change, so the new-project intent guard (project-intent.ts) does not apply to them.
|
|
10
|
+
export const projectTargetTools = new WeakSet();
|
|
11
|
+
const PROJECT_PATH = /^\/v2\/projects\/\{id\}(?:\/|$)/;
|
|
12
|
+
const IMPORT_RETRY_MS = 15_000;
|
|
13
|
+
/** Every other tool calls the project `projectId`; generated project routes said `id`. */
|
|
14
|
+
function withProjectIdAlias(tool) {
|
|
15
|
+
const { id, ...rest } = tool.inputSchema;
|
|
16
|
+
if (!id)
|
|
17
|
+
return tool;
|
|
18
|
+
const handler = tool.handler;
|
|
19
|
+
const adapted = {
|
|
20
|
+
...tool,
|
|
21
|
+
inputSchema: {
|
|
22
|
+
projectId: z.string().optional().describe('Project ID (UUID).'),
|
|
23
|
+
...rest,
|
|
24
|
+
id: z.string().optional().describe('Deprecated alias of projectId.'),
|
|
25
|
+
},
|
|
26
|
+
handler: async (args, context) => {
|
|
27
|
+
const { projectId, id: alias, ...fields } = args;
|
|
28
|
+
const project = projectId ?? alias;
|
|
29
|
+
if (project === undefined)
|
|
30
|
+
throw new Error('Pass projectId.');
|
|
31
|
+
if (alias !== undefined && projectId !== undefined && alias !== projectId)
|
|
32
|
+
throw new Error('projectId and id name different projects; pass projectId only.');
|
|
33
|
+
const result = await handler({ ...fields, id: project }, context);
|
|
34
|
+
if (result !== '')
|
|
35
|
+
return result;
|
|
36
|
+
// 204 responses: say what happened instead of an empty string.
|
|
37
|
+
return tool.name === 'projects_attach-asset'
|
|
38
|
+
? { projectId: project, assetId: fields.assetId, attached: true }
|
|
39
|
+
: { projectId: project, ok: true };
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
projectTargetTools.add(adapted);
|
|
43
|
+
return adapted;
|
|
44
|
+
}
|
|
45
|
+
/** Transcription takes source URLs; every other workflow passes saved assets by id. */
|
|
46
|
+
function withTranscriptionAsset(tool, http) {
|
|
47
|
+
const handler = tool.handler;
|
|
48
|
+
return {
|
|
49
|
+
...tool,
|
|
50
|
+
description: `${tool.description} Pass assetId to transcribe a saved VIDEO or AUDIO asset instead of a source URL.`,
|
|
51
|
+
inputSchema: {
|
|
52
|
+
...tool.inputSchema,
|
|
53
|
+
// An assetId replaces the source URL, so neither can stay required.
|
|
54
|
+
...Object.fromEntries(['sourceVideoUrl', 'sourceAudioUrl']
|
|
55
|
+
.filter((key) => tool.inputSchema[key])
|
|
56
|
+
.map((key) => [key, tool.inputSchema[key].optional()])),
|
|
57
|
+
assetId: z
|
|
58
|
+
.uuid()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe('Saved VIDEO or AUDIO asset to transcribe; replaces sourceVideoUrl/sourceAudioUrl.'),
|
|
61
|
+
},
|
|
62
|
+
handler: async (args, context) => {
|
|
63
|
+
const { assetId: rawAssetId, ...fields } = args;
|
|
64
|
+
const assetId = z.uuid().optional().parse(rawAssetId);
|
|
65
|
+
if (assetId === undefined)
|
|
66
|
+
return handler(fields, context);
|
|
67
|
+
if (fields.sourceVideoUrl !== undefined || fields.sourceAudioUrl !== undefined)
|
|
68
|
+
throw new Error('Pass assetId or a source URL, not both.');
|
|
69
|
+
const asset = z.object({ type: z.string(), url: z.string().min(1) }).parse(await http.request('get', `/v2/assets/${assetId}`, {
|
|
70
|
+
signal: context?.signal,
|
|
71
|
+
}));
|
|
72
|
+
if (asset.type !== 'VIDEO' && asset.type !== 'AUDIO')
|
|
73
|
+
throw new Error(`Asset ${assetId} is ${asset.type}; transcribe a VIDEO or AUDIO asset.`);
|
|
74
|
+
const source = asset.type === 'VIDEO' ? 'sourceVideoUrl' : 'sourceAudioUrl';
|
|
75
|
+
return handler({ ...fields, [source]: asset.url }, context);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function withJobWait(tool, label) {
|
|
80
|
+
const handler = tool.handler;
|
|
81
|
+
return {
|
|
82
|
+
...tool,
|
|
83
|
+
description: `${tool.description} Pass wait: true to wait for the job on the server.`,
|
|
84
|
+
inputSchema: { ...tool.inputSchema, wait: waitInput },
|
|
85
|
+
handler: async ({ wait, ...args }, context) => {
|
|
86
|
+
const read = (signal = context?.signal) => handler(args, { ...context, signal });
|
|
87
|
+
if (wait !== true)
|
|
88
|
+
return read();
|
|
89
|
+
return pollUntil(read, jobSettled, context, {
|
|
90
|
+
describe: (job) => `${label} ${String(rawStatus(job) ?? 'pending').toLowerCase()}`,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export async function attemptImport(handler, args, context, signal = context?.signal) {
|
|
96
|
+
try {
|
|
97
|
+
return { asset: await handler(args, { ...context, signal }) };
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (isImportInProgress(error))
|
|
101
|
+
return { pending: error };
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export const importWaitOptions = {
|
|
106
|
+
describe: (attempt) => {
|
|
107
|
+
const progress = 'pending' in attempt ? attempt.pending.importDetails?.progress : undefined;
|
|
108
|
+
return `importing${progress === undefined ? '' : ` ${progress}%`}`;
|
|
109
|
+
},
|
|
110
|
+
delayMs: (attempt) => 'pending' in attempt ? (attempt.pending.retryAfterMs ?? IMPORT_RETRY_MS) : undefined,
|
|
111
|
+
};
|
|
112
|
+
/** A social import answers 409 import_in_progress until the asset is saved. */
|
|
113
|
+
function withImportWait(tool) {
|
|
114
|
+
const handler = tool.handler;
|
|
115
|
+
return {
|
|
116
|
+
...tool,
|
|
117
|
+
description: `${tool.description} For a social link, pass wait: true to wait for the import on the server; a 409 import_in_progress then only means it is still downloading after about 50 seconds, so call again with the same input.`,
|
|
118
|
+
inputSchema: { ...tool.inputSchema, wait: waitInput },
|
|
119
|
+
handler: async ({ wait, ...args }, context) => {
|
|
120
|
+
if (wait !== true)
|
|
121
|
+
return handler(args, context);
|
|
122
|
+
const last = await pollUntil((signal) => attemptImport(handler, args, context, signal), (attempt) => 'asset' in attempt, context, importWaitOptions);
|
|
123
|
+
if ('pending' in last)
|
|
124
|
+
throw last.pending;
|
|
125
|
+
return last.asset;
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export function adaptGeneratedTool(tool, operation, http) {
|
|
130
|
+
if (tool.resultFormat === 'mcp' || !operation)
|
|
131
|
+
return tool;
|
|
132
|
+
if (PROJECT_PATH.test(operation.path))
|
|
133
|
+
return withProjectIdAlias(tool);
|
|
134
|
+
if (operation.method === 'post' && operation.path === '/v2/transcriptions')
|
|
135
|
+
return withTranscriptionAsset(tool, http);
|
|
136
|
+
if (operation.method === 'get' && operation.path === '/v2/transcriptions/{id}')
|
|
137
|
+
return withJobWait(tool, 'transcription');
|
|
138
|
+
if (operation.method === 'get' && operation.path === '/v2/transcriptions/{id}/speaker-analysis')
|
|
139
|
+
return withJobWait(tool, 'speaker analysis');
|
|
140
|
+
if (operation.method === 'post' && operation.path === '/v2/assets')
|
|
141
|
+
return withImportWait(tool);
|
|
142
|
+
return tool;
|
|
143
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { HttpClient } from '../http-client.js';
|
|
3
|
+
/** Optional for released clients: absence must preserve the original fingerprint. */
|
|
4
|
+
export declare const generationContextSchema: z.ZodObject<{
|
|
5
|
+
workflow: z.ZodEnum<{
|
|
6
|
+
edit_dialogue: "edit_dialogue";
|
|
7
|
+
image_to_video: "image_to_video";
|
|
8
|
+
lipsync: "lipsync";
|
|
9
|
+
translate_and_dub: "translate_and_dub";
|
|
10
|
+
}>;
|
|
11
|
+
parentGenerationId: z.ZodUUID;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
export declare function generationContextHeaders(http: HttpClient, args: Record<string, unknown>, workflows: readonly z.infer<typeof generationContextSchema>['workflow'][], signal?: AbortSignal): Promise<Record<string, string>>;
|
|
14
|
+
//# sourceMappingURL=generation-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-context.d.ts","sourceRoot":"","sources":["../../src/tools/generation-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qFAAqF;AACrF,eAAO,MAAM,uBAAuB;;;;;;;;kBAKzB,CAAC;AAEZ,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC,UAAU,CAAC,EAAE,EACzE,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA8BjC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Optional for released clients: absence must preserve the original fingerprint. */
|
|
3
|
+
export const generationContextSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
workflow: z.enum(['lipsync', 'translate_and_dub', 'image_to_video', 'edit_dialogue']),
|
|
6
|
+
parentGenerationId: z.uuid(),
|
|
7
|
+
})
|
|
8
|
+
.strict();
|
|
9
|
+
export async function generationContextHeaders(http, args, workflows, signal) {
|
|
10
|
+
if (args.continuation === undefined)
|
|
11
|
+
return {};
|
|
12
|
+
const context = generationContextSchema.parse(args.continuation);
|
|
13
|
+
const projectId = z.uuid().parse(args.projectId);
|
|
14
|
+
if (!workflows.includes(context.workflow))
|
|
15
|
+
throw new Error('The continuation workflow does not match this action.');
|
|
16
|
+
// Authorize the lineage headers without reading the parent's media/settings.
|
|
17
|
+
// Unrelated deleted sources must not block the API's same-key replay. The API
|
|
18
|
+
// authorizes the submitted inputs on new admission; continuation reads still
|
|
19
|
+
// check source access before returning media to the embedded view.
|
|
20
|
+
const project = z
|
|
21
|
+
.object({ id: z.uuid() })
|
|
22
|
+
.parse(await http.request('get', `/v2/projects/${projectId}`, { signal }));
|
|
23
|
+
if (project.id !== projectId)
|
|
24
|
+
throw new Error('Could not verify project access.');
|
|
25
|
+
const page = z
|
|
26
|
+
.object({ items: z.array(z.object({ id: z.uuid(), projectId: z.uuid() })).length(1) })
|
|
27
|
+
.parse(await http.request('get', '/v2/generations/list', {
|
|
28
|
+
query: { projectId, ids: context.parentGenerationId, limit: '1' },
|
|
29
|
+
signal,
|
|
30
|
+
}));
|
|
31
|
+
const parent = page.items[0];
|
|
32
|
+
if (parent.id !== context.parentGenerationId || parent.projectId !== projectId)
|
|
33
|
+
throw new Error('The generation does not belong to this project.');
|
|
34
|
+
signal?.throwIfAborted();
|
|
35
|
+
return {
|
|
36
|
+
'x-sync-workflow': context.workflow,
|
|
37
|
+
'x-sync-parent-generation-id': context.parentGenerationId,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-continuation.d.ts","sourceRoot":"","sources":["../../src/tools/generation-continuation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwFxD,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CA4CpF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { modelOptionsSchema } from './model-options.js';
|
|
3
|
+
// Narrow projection of Studio's InternalGenerationSchema. Provider state and
|
|
4
|
+
// arbitrary generation metadata never cross the embedded-app boundary.
|
|
5
|
+
const mediaUrl = z.url({ protocol: /^https?$/ });
|
|
6
|
+
const face = modelOptionsSchema.shape.active_speaker_detection
|
|
7
|
+
.unwrap()
|
|
8
|
+
.options[1].strip()
|
|
9
|
+
.extend({
|
|
10
|
+
frame_number: z.number().finite().optional(),
|
|
11
|
+
bounding_boxes: z.array(z.array(z.number().finite()).nullable()).optional(),
|
|
12
|
+
bounding_boxes_url: mediaUrl.optional(),
|
|
13
|
+
});
|
|
14
|
+
const options = modelOptionsSchema.strip().extend({
|
|
15
|
+
active_speaker_detection: z.union([z.boolean(), face]).optional(),
|
|
16
|
+
model_mode: z.string().optional(),
|
|
17
|
+
});
|
|
18
|
+
const audioRange = z.object({
|
|
19
|
+
refId: z.string(),
|
|
20
|
+
startTime: z.number().finite().optional(),
|
|
21
|
+
endTime: z.number().finite().optional(),
|
|
22
|
+
});
|
|
23
|
+
const generation = z.object({
|
|
24
|
+
id: z.uuid(),
|
|
25
|
+
projectId: z.uuid(),
|
|
26
|
+
status: z.enum(['PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'REJECTED']),
|
|
27
|
+
workflow: z
|
|
28
|
+
.enum([
|
|
29
|
+
'lipsync',
|
|
30
|
+
'translate_and_dub',
|
|
31
|
+
'image_to_video',
|
|
32
|
+
'edit_dialogue',
|
|
33
|
+
'change_appearance',
|
|
34
|
+
'timeline',
|
|
35
|
+
'assistant',
|
|
36
|
+
])
|
|
37
|
+
.nullish(),
|
|
38
|
+
modelName: z.string().min(1),
|
|
39
|
+
options,
|
|
40
|
+
inputs: z.array(z.object({
|
|
41
|
+
type: z.enum(['video', 'image', 'audio', 'text']),
|
|
42
|
+
assetId: z.uuid().optional(),
|
|
43
|
+
url: mediaUrl.optional(),
|
|
44
|
+
refId: z.string().optional(),
|
|
45
|
+
generatedBy: z.literal('tts').optional(),
|
|
46
|
+
provider: z
|
|
47
|
+
.object({
|
|
48
|
+
name: z.string(),
|
|
49
|
+
script: z.string(),
|
|
50
|
+
voiceId: z.string(),
|
|
51
|
+
stability: z.number().min(0).max(1).optional(),
|
|
52
|
+
similarityBoost: z.number().min(0).max(1).optional(),
|
|
53
|
+
})
|
|
54
|
+
.optional(),
|
|
55
|
+
trim_secs: z.array(z.number().finite()).optional(),
|
|
56
|
+
segments_secs: z.array(z.array(z.number().finite())).optional(),
|
|
57
|
+
segments_frames: z.array(z.array(z.number().finite())).optional(),
|
|
58
|
+
})),
|
|
59
|
+
segments: z
|
|
60
|
+
.array(z.object({
|
|
61
|
+
startTime: z.number().finite().optional(),
|
|
62
|
+
endTime: z.number().finite().optional(),
|
|
63
|
+
startFrame: z.number().finite().optional(),
|
|
64
|
+
endFrame: z.number().finite().optional(),
|
|
65
|
+
audioInput: audioRange.optional(),
|
|
66
|
+
optionsOverride: options.optional(),
|
|
67
|
+
}))
|
|
68
|
+
.nullish(),
|
|
69
|
+
speakers: z
|
|
70
|
+
.array(z.object({
|
|
71
|
+
id: z.string(),
|
|
72
|
+
audio: audioRange,
|
|
73
|
+
face: face.omit({ auto_detect: true }),
|
|
74
|
+
}))
|
|
75
|
+
.nullish(),
|
|
76
|
+
outputMediaUrl: mediaUrl.nullish(),
|
|
77
|
+
parentGenerationId: z.uuid().nullish(),
|
|
78
|
+
dialogueEditJobId: z.uuid().nullish(),
|
|
79
|
+
renderedFromAssetId: z.uuid().nullish(),
|
|
80
|
+
});
|
|
81
|
+
export function createGenerationContinuationTool(http) {
|
|
82
|
+
const input = z.object({ projectId: z.uuid(), id: z.uuid() }).strict();
|
|
83
|
+
return {
|
|
84
|
+
name: 'generations_get-continuation',
|
|
85
|
+
title: 'Read generation continuation inputs',
|
|
86
|
+
description: 'Read one accessible generation and its original inputs through the same Studio API. Rechecks project and referenced asset access. Does not create a draft, asset, transcription, preview or generation. Use the shared Studio continuation policy to choose source versus completed output.',
|
|
87
|
+
inputSchema: input.shape,
|
|
88
|
+
outputSchema: { submissionContextVersion: z.literal(1), generation },
|
|
89
|
+
annotations: {
|
|
90
|
+
readOnlyHint: true,
|
|
91
|
+
destructiveHint: false,
|
|
92
|
+
idempotentHint: true,
|
|
93
|
+
openWorldHint: false,
|
|
94
|
+
},
|
|
95
|
+
handler: async (args, context) => {
|
|
96
|
+
const { projectId, id } = input.parse(args);
|
|
97
|
+
const signal = context?.signal;
|
|
98
|
+
const project = z
|
|
99
|
+
.object({ id: z.uuid() })
|
|
100
|
+
.parse(await http.request('get', `/v2/projects/${projectId}`, { signal }));
|
|
101
|
+
if (project.id !== projectId)
|
|
102
|
+
throw new Error('Could not verify project access.');
|
|
103
|
+
const page = z.object({ items: generation.array().length(1) }).parse(await http.request('get', '/v2/generations/list', {
|
|
104
|
+
query: { projectId, ids: id, limit: '1' },
|
|
105
|
+
signal,
|
|
106
|
+
}));
|
|
107
|
+
const selected = page.items[0];
|
|
108
|
+
if (selected.id !== id || selected.projectId !== projectId)
|
|
109
|
+
throw new Error('The generation does not belong to this project.');
|
|
110
|
+
for (const assetId of new Set([
|
|
111
|
+
...selected.inputs.flatMap((item) => (item.assetId ? [item.assetId] : [])),
|
|
112
|
+
...(selected.renderedFromAssetId ? [selected.renderedFromAssetId] : []),
|
|
113
|
+
])) {
|
|
114
|
+
signal?.throwIfAborted();
|
|
115
|
+
const asset = z
|
|
116
|
+
.object({ id: z.uuid() })
|
|
117
|
+
.parse(await http.request('get', `/v2/assets/${assetId}`, { signal }));
|
|
118
|
+
if (asset.id !== assetId)
|
|
119
|
+
throw new Error('Could not verify source asset access.');
|
|
120
|
+
}
|
|
121
|
+
return { submissionContextVersion: 1, generation: selected };
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HttpClient } from '../http-client.js';
|
|
2
|
+
import type { ParsedOperation } from '../openapi/types.js';
|
|
3
|
+
import type { McpToolDefinition } from './generator.js';
|
|
4
|
+
export declare function generationCostsOperation(operation: ParsedOperation): boolean;
|
|
5
|
+
export declare function createGenerationCostsTools(operations: ParsedOperation[], http: HttpClient): McpToolDefinition[];
|
|
6
|
+
//# sourceMappingURL=generation-costs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-costs.d.ts","sourceRoot":"","sources":["../../src/tools/generation-costs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAmCxD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAM5E;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,eAAe,EAAE,EAC7B,IAAI,EAAE,UAAU,GACf,iBAAiB,EAAE,CA8BrB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const money = z.string().regex(/^\d+\.\d{5}$/);
|
|
3
|
+
const component = z.object({
|
|
4
|
+
type: z.enum(['lipsync', 'dubbing', 'speech_synthesis']),
|
|
5
|
+
operationId: z.uuid().nullable(),
|
|
6
|
+
status: z.enum(['recorded', 'pending', 'unavailable', 'not_charged']),
|
|
7
|
+
amountUsd: money.nullable(),
|
|
8
|
+
credits: z.string().regex(/^\d+$/).nullable(),
|
|
9
|
+
valueBasis: z.enum(['credit_face_value', 'metered_usage', 'none']).nullable(),
|
|
10
|
+
quantity: z.number().nonnegative().nullable(),
|
|
11
|
+
unit: z.enum(['frames', 'seconds']),
|
|
12
|
+
unitRateUsd: money.nullable(),
|
|
13
|
+
source: z.enum(['credit_ledger', 'recorded_usage', 'billing_context']).nullable(),
|
|
14
|
+
reason: z.string().nullable(),
|
|
15
|
+
});
|
|
16
|
+
const receipt = z.object({
|
|
17
|
+
generationId: z.uuid(),
|
|
18
|
+
generationStatus: z.string(),
|
|
19
|
+
currency: z.literal('USD'),
|
|
20
|
+
availability: z.enum(['complete', 'pending', 'partial', 'unavailable']),
|
|
21
|
+
totalCostUsd: money.nullable(),
|
|
22
|
+
knownSubtotalUsd: money,
|
|
23
|
+
retryAfterSeconds: z.number().int().positive().nullable(),
|
|
24
|
+
components: z.array(component),
|
|
25
|
+
excludedCosts: z.array(z.string()),
|
|
26
|
+
});
|
|
27
|
+
const input = z
|
|
28
|
+
.object({
|
|
29
|
+
generationId: z
|
|
30
|
+
.uuid()
|
|
31
|
+
.describe('Existing Sync generation ID returned by generation creation or history tools.'),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
export function generationCostsOperation(operation) {
|
|
35
|
+
return (operation.operationId === 'GenerateController_getGenerationCosts' &&
|
|
36
|
+
operation.method === 'get' &&
|
|
37
|
+
operation.path === '/v2/generate/{id}/costs');
|
|
38
|
+
}
|
|
39
|
+
export function createGenerationCostsTools(operations, http) {
|
|
40
|
+
if (!operations.some(generationCostsOperation))
|
|
41
|
+
return [];
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
name: 'generations_get-costs',
|
|
45
|
+
title: 'View actual generation costs',
|
|
46
|
+
description: 'Read recorded costs for a past Sync generation, with dubbing and lip sync listed separately. Use for what a generation actually cost, not a preflight estimate. Credit amounts express credit face value, not a card payment. Pending or unavailable components have no known total. Does not generate media or change billing.',
|
|
47
|
+
inputSchema: input.shape,
|
|
48
|
+
outputSchema: receipt.shape,
|
|
49
|
+
annotations: {
|
|
50
|
+
readOnlyHint: true,
|
|
51
|
+
destructiveHint: false,
|
|
52
|
+
idempotentHint: true,
|
|
53
|
+
openWorldHint: false,
|
|
54
|
+
},
|
|
55
|
+
meta: { ui: { visibility: ['model', 'app'] }, 'openai/widgetAccessible': true },
|
|
56
|
+
handler: async (args, context) => {
|
|
57
|
+
const { generationId } = input.parse(args);
|
|
58
|
+
const result = receipt.parse(await http.request('get', `/v2/generate/${generationId}/costs`, {
|
|
59
|
+
signal: context?.signal,
|
|
60
|
+
}));
|
|
61
|
+
if (result.generationId.toLowerCase() !== generationId.toLowerCase())
|
|
62
|
+
throw new Error('Sync returned costs for a different generation.');
|
|
63
|
+
return result;
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-output.d.ts","sourceRoot":"","sources":["../../src/tools/generation-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA8BxD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CAgBtF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const RESULT_URL = ['outputMediaUrl', 'outputUrl'];
|
|
2
|
+
const DURATION = ['outputMediaLength', 'outputDuration'];
|
|
3
|
+
// Raw generation lists from GET /v2/generations, without an output schema.
|
|
4
|
+
const GENERATION_LIST_TOOLS = new Set(['generations_list', 'projects_list-generations']);
|
|
5
|
+
function isRecord(value) {
|
|
6
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
function withAliases(value, aliases = [RESULT_URL]) {
|
|
9
|
+
if (!isRecord(value))
|
|
10
|
+
return value;
|
|
11
|
+
const result = { ...value };
|
|
12
|
+
for (const [apiName, legacyName] of aliases) {
|
|
13
|
+
if (!(apiName in value) && !(legacyName in value))
|
|
14
|
+
continue;
|
|
15
|
+
const field = apiName in value ? value[apiName] : value[legacyName];
|
|
16
|
+
result[apiName] = field;
|
|
17
|
+
result[legacyName] = field;
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
export function withGenerationOutputAliases(tool) {
|
|
22
|
+
if (tool.resultFormat === 'mcp')
|
|
23
|
+
return tool;
|
|
24
|
+
const schema = tool.outputSchema;
|
|
25
|
+
const list = GENERATION_LIST_TOOLS.has(tool.name);
|
|
26
|
+
if (!list && !(schema && 'outputMediaUrl' in schema && 'outputUrl' in schema))
|
|
27
|
+
return tool;
|
|
28
|
+
const aliases = schema && 'outputMediaLength' in schema ? [RESULT_URL, DURATION] : [RESULT_URL];
|
|
29
|
+
const handler = tool.handler;
|
|
30
|
+
return {
|
|
31
|
+
...tool,
|
|
32
|
+
handler: async (args, context) => {
|
|
33
|
+
const result = await handler(args, context);
|
|
34
|
+
return list && Array.isArray(result)
|
|
35
|
+
? result.map((item) => withAliases(item))
|
|
36
|
+
: withAliases(result, aliases);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -1,12 +1,45 @@
|
|
|
1
|
+
import type { CallToolResult, ToolAnnotations } from '@modelcontextprotocol/server';
|
|
1
2
|
import { z } from 'zod';
|
|
3
|
+
import type { ClientProfile } from '../client-profile.js';
|
|
2
4
|
import type { HttpClient } from '../http-client.js';
|
|
3
5
|
import type { ParsedOperation } from '../openapi/types.js';
|
|
4
|
-
|
|
6
|
+
type McpToolBaseDefinition = {
|
|
5
7
|
name: string;
|
|
8
|
+
title?: string;
|
|
6
9
|
description: string;
|
|
7
10
|
inputSchema: Record<string, z.ZodType>;
|
|
8
|
-
|
|
11
|
+
outputSchema?: Record<string, z.ZodType>;
|
|
12
|
+
annotations?: ToolAnnotations;
|
|
13
|
+
meta?: Record<string, unknown>;
|
|
9
14
|
};
|
|
15
|
+
export type ToolRequestContext = {
|
|
16
|
+
_meta?: Record<string, unknown>;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
clientProfile?: ClientProfile;
|
|
19
|
+
clientName?: string;
|
|
20
|
+
progress?: (progress: number, message?: string) => Promise<void>;
|
|
21
|
+
toolListChanged?: () => void;
|
|
22
|
+
};
|
|
23
|
+
type JsonMcpToolDefinition = McpToolBaseDefinition & {
|
|
24
|
+
resultFormat?: 'json';
|
|
25
|
+
handler: (args: Record<string, unknown>, context?: ToolRequestContext) => Promise<unknown>;
|
|
26
|
+
};
|
|
27
|
+
type RawMcpToolDefinition = McpToolBaseDefinition & {
|
|
28
|
+
resultFormat: 'mcp';
|
|
29
|
+
handler: (args: Record<string, unknown>, context?: ToolRequestContext) => Promise<CallToolResult>;
|
|
30
|
+
};
|
|
31
|
+
export type McpToolDefinition = JsonMcpToolDefinition | RawMcpToolDefinition;
|
|
10
32
|
export declare function generateTools(operations: ParsedOperation[], httpClient: HttpClient): McpToolDefinition[];
|
|
33
|
+
/**
|
|
34
|
+
* Behaviour hints required by the ChatGPT and Claude app/connector directories
|
|
35
|
+
* (missing/incorrect annotations are a top review-rejection cause). Derived
|
|
36
|
+
* from the HTTP verb: reads are read-only; writes modify external Sync state,
|
|
37
|
+
* so they are destructive and open-world.
|
|
38
|
+
*/
|
|
39
|
+
export declare function deriveAnnotations(method: string, toolName?: string): ToolAnnotations;
|
|
40
|
+
/** "AssetsController_getAll" → "assets_get-all", the name before tool-names.ts renames it. */
|
|
41
|
+
export declare function derivedToolName(operationId: string): string;
|
|
42
|
+
/** "AssetsController_getAll" → "assets_list". */
|
|
11
43
|
export declare function operationIdToToolName(operationId: string): string;
|
|
44
|
+
export {};
|
|
12
45
|
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/tools/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/tools/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAKvE,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,eAAe,CAAC;IAG9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,KAAK,qBAAqB,GAAG,qBAAqB,GAAG;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F,CAAC;AAEF,KAAK,oBAAoB,GAAG,qBAAqB,GAAG;IAClD,YAAY,EAAE,KAAK,CAAC;IACpB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACnG,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,oBAAoB,CAAC;AA4B7E,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,EAAE,EAC7B,UAAU,EAAE,UAAU,GACrB,iBAAiB,EAAE,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAYpF;AA6FD,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|