kestra-io / kestra-io/plugin-scaleway

Add Generative APIs tasks for Scaleway Plugin

Open
#24 1 comment 0 reactions 0 assignees View on GitHub
area/plugin
Dominant language
Java
Stars
0
Forks
0
Avg merge
7h 18m
Merged PRs (30d)
2

Description

## Summary

[Scaleway Generative APIs](https://www.scaleway.com/en/generative-apis/) is Scaleway's managed LLM inference service, exposed as an OpenAI-compatible REST API. This sub-plugin lets Kestra flows run chat completions, embeddings, and reranking against hosted open-weight models without leaving the flow, for European data-residency-aware AI pipelines.

## Motivation

Teams already using Kestra's HTTP tasks or the OpenAI plugin against OpenAI-hosted models need a first-class way to point the same kind of prompt/completion flow at Scaleway-hosted models instead — mainly for GDPR/data-residency reasons. A dedicated sub-plugin:

- Lets flow authors call chat/embeddings/rerank endpoints with typed, documented properties instead of raw HTTP tasks
- Fits naturally alongside the rest of `plugin-scaleway`'s compute and storage sub-plugins for end-to-end AI pipelines (e.g. read from Object Storage, embed, store in a managed database)
- Supports asynchronous batch inference via the `/v1/batches` endpoint for large-volume jobs

## Context

Part of the Scaleway plugin EPIC: https://github.com/kestra-io/plugin-scaleway/issues/2. Uses the shared `AbstractScalewayConnection` base class defined in that EPIC for credentials.

## API Reference

- **Official docs**: https://www.scaleway.com/en/developers/api/generative-apis/
- **Authentication**: `Authorization: Bearer ` (OpenAI-SDK convention) — same IAM secret key as the rest of the plugin.
- **Base URL pattern**: flat, non-regional — `https://api.scaleway.ai/v1/` (single region today: `fr-par`)
- **SDK / client library**: none official for Java. The API is explicitly OpenAI-compatible (https://www.scaleway.com/en/docs/generative-apis/reference-content/openai-compatibility/) — use Kestra's internal HTTP client rather than pulling in an OpenAI client library.

## Gradle Dependencies

None required. Kestra's internal HTTP client (`io.kestra.core.http.client`) and Jackson serializers are already provided by the framework.

## Plugin Structure

- **Repository**: `plugin-scaleway` (existing)
- **Namespace**: `io.kestra.plugin.scaleway.genai`
- **Sub-plugins**: none — flat sub-package
- **Categories**: AI

> **Task class naming**: task class names must not repeat the plugin or package name. Use `ChatCompletion`, `Embeddings`, `Rerank`, `ListModels` — not `GenaiChatCompletion` or `ChatCompletionGenai`.

## Suggested Tasks

1. Extend `AbstractScalewayConnection` for the `genai` sub-package (bearer-token variant)
2. `ListModels` — list available hosted models (`GET /v1/models`)
3. `ChatCompletion` — chat completions (`POST /v1/chat/completions`)
4. `Embeddings` — text embeddings (`POST /v1/embeddings`)
5. `Rerank` — document reranking (`POST /v1/rerank`)
6. `CreateBatch` / `GetBatch` — async batch inference (`POST /v1/batches`, `GET /v1/batches/{id}`), with a polling trigger on batch completion
7. Write unit + integration tests (mock the OpenAI-compatible responses)
8. Add `package-info.java` with `@PluginSubGroup(category = PluginSubGroup.PluginCategory.AI)`
9. Add `metadata/genai.yaml` and plugin icon SVG
10. Add YAML examples and plugin documentation

## YAML Examples

### Example 1 — Chat completion against a hosted model

```yaml
id: scaleway_chat_completion
namespace: company.team

inputs:
- id: prompt
type: STRING

tasks:
- id: chat
type: io.kestra.plugin.scaleway.genai.ChatCompletion
secretKey: "{{ secret('SCW_SECRET_KEY') }}"
model: "llama-3.1-8b-instruct"
messages:
- role: user
content: "{{ inputs.prompt }}"
```

### Example 2 — Embed a batch of documents and log the vector count

```yaml
id: scaleway_embeddings
namespace: company.team

tasks:
- id: embed
type: io.kestra.plugin.scaleway.genai.Embeddings
secretKey: "{{ secret('SCW_SECRET_KEY') }}"
model: "bge-multilingual-gemma2"
input:
- "First document to embed"
- "Second document to embed"

- id: log_results
type: io.kestra.plugin.core.log.Log
message: "Generated {{ outputs.embed.total }} embeddings"
```

### Example 3 — React when an async batch inference job completes

```yaml
id: scaleway_batch_completion
namespace: company.team

triggers:
- id: on_batch_done
type: io.kestra.plugin.scaleway.genai.BatchTrigger
secretKey: "{{ secret('SCW_SECRET_KEY') }}"
batchId: "{{ vars.batch_id }}"
interval: PT1M

tasks:
- id: handle_completion
type: io.kestra.plugin.core.log.Log
message: "Batch {{ trigger.batchId }} finished with status {{ trigger.status }}"
```

## Acceptance Criteria

### Functional
- [ ] `ListModels`, `ChatCompletion`, `Embeddings`, `Rerank` tasks extending `AbstractScalewayConnection`
- [ ] `CreateBatch` / `GetBatch` tasks for async batch inference
- [ ] Polling trigger on batch completion status
- [ ] Unit + integration tests pass (`./gradlew test`)
- [ ] Build passes with `./gradlew build`

### Kestra Plugin Coding Standards
- [ ] HTTP calls use Kestra's internal HTTP client (`io.kestra.core.http.client`) — no OkHttp, Apache HttpClient, or OpenAI client library
- [ ] All new properties use `Property`
- [ ] `secretKey` annotated with `@PluginProperty(secret = true)`
- [ ] Every property and output has a `@Schema` annotation
- [ ] Task classes carry the five mandatory Lombok annotations (`@SuperBuilder`, `@ToString`, `@EqualsAndHashCode`, `@Getter`, `@NoArgsConstructor`)
- [ ] Logging via `runContext.logger()` only
- [ ] JSON serialization uses Jackson mappers from `io.kestra.core.serializers`

### Documentation & Structure
- [ ] `@Plugin(examples = ...)` entries each set `full = true` with a complete runnable flow
- [ ] Sensitive values in examples use `{{ secret('SCW_SECRET_KEY') }}`
- [ ] `package-info.java` with `@PluginSubGroup(category = PluginSubGroup.PluginCategory.AI)`
- [ ] `metadata/genai.yaml` and plugin icon SVG present

---
*[View as Artifact](https://claude.ai/code/artifact/e6a18033-3d5b-4403-8ff1-d18f54f7f978)*

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by inspecting the existing plugin-scaleway structure and the shared AbstractScalewayConnection referenced in the issue, then review the Scaleway Generative APIs reference. Implement the listed model, completion, embedding, rerank, batch, and trigger entry points with tests, package-info.java, metadata/genai.yaml, and documentation. Run ./gradlew test and ./gradlew build; done means all acceptance criteria pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
ai, api, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.