-
Notifications
You must be signed in to change notification settings - Fork 7
Sub task/setup the infrastructure and backend interfaces core 555 #515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
irumvanselme
merged 2 commits into
main
from
sub-task/setup-the-infrastructure-and-backend-interfaces-CORE-555
Jul 14, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,4 +6,5 @@ export enum Lambdas { | |
| API = "API", | ||
| IMPORT = "IMPORT", | ||
| EXPORT = "EXPORT", | ||
| EMBEDDING = "EMBEDDING", | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import { SQSEvent, SQSRecord } from "aws-lambda"; | ||
| import { initOnce as serverInitOnce } from "server/init"; | ||
| import { initializeSentry } from "initializeSentry"; | ||
| import * as Sentry from "@sentry/aws-serverless"; | ||
| import { Lambdas } from "common/lambda.types"; | ||
| import { IGenerateEmbeddingTask } from "embeddings/service/types"; | ||
| import { EmbeddingService } from "embeddings/service/service"; | ||
|
|
||
| initializeSentry(Lambdas.EMBEDDING); | ||
|
|
||
| async function initOnce() { | ||
| await serverInitOnce(); | ||
| return new EmbeddingService(); | ||
| } | ||
|
|
||
| /** | ||
| * Entry point for the embeddings lambda function. | ||
| * | ||
| * This lambda is triggered by the embeddings SQS queue via an event source mapping: when N messages | ||
| * are available on the queue, the lambda is invoked with up to N records in `event.Records`, and this | ||
| * handler generates the embeddings for each of them in the background. | ||
| * | ||
| * If a record throws, we rethrow so that AWS retries the message and, after the configured number of | ||
| * attempts, moves it to the dead-letter queue. | ||
| */ | ||
| export const handler = Sentry.wrapHandler(async (event: SQSEvent): Promise<void> => { | ||
| const records = event.Records ?? []; | ||
| console.info(`Embeddings lambda triggered with ${records.length} record(s)`); | ||
|
|
||
| // Initialize the connection to the database (and registries). If it fails, rethrow so the lambda is retried. | ||
| const embeddingService = await initOnce(); | ||
|
|
||
| for (const record of records) { | ||
| await handleRecord(embeddingService, record); | ||
| } | ||
| }); | ||
|
|
||
| async function handleRecord(embeddingService: EmbeddingService, record: SQSRecord): Promise<void> { | ||
| let task: IGenerateEmbeddingTask; | ||
| try { | ||
| task = JSON.parse(record.body) as IGenerateEmbeddingTask; | ||
| } catch (e: unknown) { | ||
| // A malformed message will never succeed on retry, so log and skip it rather than throwing. | ||
| console.error(new Error(`Embeddings lambda: skipping unparseable SQS record ${record.messageId}`, { cause: e })); | ||
| return; | ||
| } | ||
|
|
||
| console.info("Processing embedding task", { messageId: record.messageId, task }); | ||
| await embeddingService.processTask(task); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { IEmbeddingModelService } from "embeddings/models/modelsServiceTypes"; | ||
|
|
||
| /** | ||
| * Base URL of the Gemini (Generative Language) REST API. | ||
| */ | ||
| // const GEMINI_API_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; | ||
|
|
||
| /** | ||
| * GeminiService talks to the Gemini REST API directly via `fetch` | ||
| * (no SDK dependency, so it bundles cleanly with esbuild). | ||
| * | ||
| * See: | ||
| * - https://ai.google.dev/api/embeddings#method:-models.embedcontent | ||
| * - https://ai.google.dev/api/embeddings#method:-models.batchembedcontents | ||
| */ | ||
| export class GeminiService implements IEmbeddingModelService { | ||
| private readonly apiKey: string; | ||
| private readonly model: string; | ||
|
|
||
| constructor(apiKey: string, model: string) { | ||
| if (!apiKey) { | ||
| throw new Error("GeminiService: GEMINI_API_KEY is not configured"); | ||
| } | ||
| this.apiKey = apiKey; | ||
|
|
||
| if (!model) | ||
| throw new Error( | ||
| "GeminiService: GEMINI_MODEL_NAME is not configured. Please set it in the environment variables or in the config file." | ||
| ); | ||
| this.model = model; | ||
| } | ||
|
|
||
| async generateEmbeddingBatch(texts: string[]): Promise<number[][]> { | ||
| console.debug("GeminiService: generateEmbeddingBatch", { texts }); | ||
| console.warn("Not implemented yet"); | ||
| return [[]]; | ||
| } | ||
|
|
||
| async generateEmbedding(text: string): Promise<number[]> { | ||
| const [vector] = await this.generateEmbeddingBatch([text]); | ||
| return vector; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| export interface IEmbeddingModelService { | ||
| /** | ||
| * Generate an embedding vector for the given text. | ||
| * | ||
| * @param text - The text to embed. | ||
| * @returns The embedding vector as an array of numbers. | ||
| * @throws If the API key is not configured, or the API returns an error / empty response. | ||
| */ | ||
| generateEmbedding(text: string): Promise<number[]>; | ||
|
|
||
| /** | ||
| * Generate embeddings for a batch of texts. | ||
| * @param texts | ||
| */ | ||
| generateEmbeddingBatch(texts: string[]): Promise<number[][]>; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { IGenerateEmbeddingTask } from "./types"; | ||
|
|
||
| export interface IEmbeddingClient { | ||
| pushTaskToQueue(task: IGenerateEmbeddingTask): Promise<void>; | ||
| } | ||
|
|
||
| export class EmbeddingClient implements IEmbeddingClient { | ||
| pushTaskToQueue(task: IGenerateEmbeddingTask): Promise<void> { | ||
| console.debug("EmbeddingClient.pushTaskToQueue", task); | ||
| throw new Error("Method not implemented."); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { IGenerateEmbeddingTask } from "./types"; | ||
|
|
||
| export interface IEmbeddingService { | ||
| processTask(task: IGenerateEmbeddingTask): Promise<void>; | ||
| } | ||
|
|
||
| export class EmbeddingService implements IEmbeddingService { | ||
| constructor() {} | ||
|
|
||
| async processTask(task: IGenerateEmbeddingTask): Promise<void> { | ||
| console.info("Generated embedding", { | ||
| modelId: task.modelId, | ||
| entityType: task.entityType, | ||
| entityId: task.entityId, | ||
| }); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| export enum EmbeddableEntityType { | ||
| Skill = "Skill", | ||
| Occupation = "Occupation", | ||
| OccupationGroup = "OccupationGroup", | ||
| SkillGroup = "SkillGroup", | ||
| } | ||
|
|
||
| export enum EmbeddableField { | ||
| preferredLabel = "preferredLabel", | ||
| description = "description", | ||
| altLabels = "altLabels", | ||
| scopeNote = "scopeNote", | ||
| } | ||
|
|
||
| export interface IGenerateEmbeddingTask { | ||
| modelId: string; | ||
| entityId: string; | ||
| entityType: EmbeddableEntityType; | ||
| fields: EmbeddableField; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda"; | ||
|
|
||
| export class POSTModelEmbeddingProcessesHandler { | ||
| async handle(_event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> { | ||
| console.log(_event); | ||
| throw new Error("Not implemented yet"); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { APIGatewayProxyEvent } from "aws-lambda"; | ||
| import { APIGatewayProxyResult } from "aws-lambda/trigger/api-gateway-proxy"; | ||
| import { HTTP_VERBS, STD_ERRORS_RESPONSES } from "server/httpUtils"; | ||
| import { POSTModelEmbeddingProcessesHandler } from "./POST"; | ||
|
|
||
| export const handler: ( | ||
| event: APIGatewayProxyEvent /*, context: Context, callback: Callback*/ | ||
| ) => Promise<APIGatewayProxyResult> = async ( | ||
| event: APIGatewayProxyEvent /*, context: Context, callback: Callback*/ | ||
| ) => { | ||
| if (event?.httpMethod === HTTP_VERBS.POST) { | ||
| return new POSTModelEmbeddingProcessesHandler().handle(event); | ||
| } | ||
| return STD_ERRORS_RESPONSES.METHOD_NOT_ALLOWED; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The POST handler for model embedding processes is an unimplemented stub that will cause all requests to this endpoint to return a 500 error.
Severity: HIGH
Suggested Fix
Implement the logic for the
POSTModelEmbeddingProcessesHandlerto correctly handle the creation of model embedding processes. If this feature is not ready for release, either remove the route from the main router inbackend/src/index.tsor place it behind a feature flag to prevent access.Prompt for AI Agent
Did we get this right? 👍 / 👎 to inform future reviews.