diff --git a/.changeset/send-metadata-to-endpoint.md b/.changeset/send-metadata-to-endpoint.md new file mode 100644 index 000000000..e823f023e --- /dev/null +++ b/.changeset/send-metadata-to-endpoint.md @@ -0,0 +1,5 @@ +--- +"lingo.dev": patch +--- + +Send sessionId, triggerType, and file path metadata to the vNext localization endpoint diff --git a/packages/cli/src/cli/cmd/run/execute.ts b/packages/cli/src/cli/cmd/run/execute.ts index 4708ca7ba..b992a0bfc 100644 --- a/packages/cli/src/cli/cmd/run/execute.ts +++ b/packages/cli/src/cli/cmd/run/execute.ts @@ -261,6 +261,7 @@ function createWorkerTask(args: { targetData: args.ctx.flags.force ? {} : targetData, processableData, hints: relevantHints, + filePath: assignedTask.bucketPathPattern, }, async (progress, _sourceChunk, processedChunk) => { // write translated chunks as they are received from LLM diff --git a/packages/cli/src/cli/localizer/_types.ts b/packages/cli/src/cli/localizer/_types.ts index 1ee0bfe4c..7213cc948 100644 --- a/packages/cli/src/cli/localizer/_types.ts +++ b/packages/cli/src/cli/localizer/_types.ts @@ -7,6 +7,7 @@ export type LocalizerData = { targetLocale: string; targetData: Record; hints: Record; + filePath?: string; }; export type LocalizerProgressFn = ( @@ -16,7 +17,11 @@ export type LocalizerProgressFn = ( ) => void; export interface ILocalizer { - id: "Lingo.dev" | "Lingo.dev vNext" | "pseudo" | NonNullable["id"]; + id: + | "Lingo.dev" + | "Lingo.dev vNext" + | "pseudo" + | NonNullable["id"]; checkAuth: () => Promise<{ authenticated: boolean; username?: string; diff --git a/packages/cli/src/cli/localizer/lingodotdev-vnext.ts b/packages/cli/src/cli/localizer/lingodotdev-vnext.ts index ed4281d49..1a1120cde 100644 --- a/packages/cli/src/cli/localizer/lingodotdev-vnext.ts +++ b/packages/cli/src/cli/localizer/lingodotdev-vnext.ts @@ -9,7 +9,13 @@ import { createId } from "@paralleldrive/cuid2"; * Creates a custom engine for Lingo.dev vNext that sends requests to: * https://api.lingo.dev/process//localize */ -function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: string }) { +function createVNextEngine(config: { + apiKey: string; + apiUrl: string; + processId: string; + sessionId: string; + triggerType: "cli" | "ci"; +}) { const endpoint = `${config.apiUrl}/process/${config.processId}/localize`; return { @@ -21,8 +27,8 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: reference?: Record>; hints?: Record; }, - workflowId: string, fast: boolean, + filePath?: string, signal?: AbortSignal, ): Promise> { const res = await fetch(endpoint, { @@ -33,12 +39,15 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: }, body: JSON.stringify( { - params: { workflowId, fast }, + params: { fast }, sourceLocale, targetLocale, data: payload.data, reference: payload.reference, hints: payload.hints, + sessionId: config.sessionId, + triggerType: config.triggerType, + metadata: filePath ? { filePath } : undefined, }, null, 2, @@ -69,7 +78,9 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: return jsonResponse.data || {}; }, - async whoami(signal?: AbortSignal): Promise<{ email: string; id: string } | null> { + async whoami( + signal?: AbortSignal, + ): Promise<{ email: string; id: string } | null> { // vNext uses a simple response for whoami return { email: "vnext-user", id: config.processId }; }, @@ -82,6 +93,7 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: fast?: boolean; reference?: Record>; hints?: Record; + filePath?: string; }, progressCallback?: ( progress: number, @@ -93,7 +105,6 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: const chunkedPayload = extractPayloadChunks(obj); const processedPayloadChunks: Record[] = []; - const workflowId = createId(); for (let i = 0; i < chunkedPayload.length; i++) { const chunk = chunkedPayload[i]; const percentageCompleted = Math.round( @@ -104,8 +115,8 @@ function createVNextEngine(config: { apiKey: string; apiUrl: string; processId: params.sourceLocale, params.targetLocale, { data: chunk, reference: params.reference, hints: params.hints }, - workflowId, params.fast || false, + params.filePath, signal, ); @@ -158,10 +169,7 @@ function countWordsInRecord( payload: any | Record | Array, ): number { if (Array.isArray(payload)) { - return payload.reduce( - (acc, item) => acc + countWordsInRecord(item), - 0, - ); + return payload.reduce((acc, item) => acc + countWordsInRecord(item), 0); } else if (typeof payload === "object" && payload !== null) { return Object.values(payload).reduce( (acc: number, item) => acc + countWordsInRecord(item), @@ -186,8 +194,8 @@ export default function createLingoDotDevVNextLocalizer( throw new Error( dedent` You're trying to use ${chalk.hex(colors.green)( - "Lingo.dev vNext", - )} provider, however, no API key is configured. + "Lingo.dev vNext", + )} provider, however, no API key is configured. To fix this issue: 1. Set ${chalk.dim("LINGO_API_KEY")} environment variable, or @@ -199,10 +207,15 @@ export default function createLingoDotDevVNextLocalizer( // Use LINGO_API_URL from environment or default to api.lingo.dev const apiUrl = process.env.LINGO_API_URL || "https://api.lingo.dev"; + const sessionId = createId(); + const triggerType = process.env.CI ? "ci" : "cli"; + const engine = createVNextEngine({ apiKey, apiUrl, processId, + sessionId, + triggerType, }); return { @@ -236,6 +249,7 @@ export default function createLingoDotDevVNextLocalizer( [input.targetLocale]: input.targetData, }, hints: input.hints, + filePath: input.filePath, }, onProgress, );