Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Or have a look at the general catalog below:
|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <a id="aws-lambda">AWS Lambda + CDK</a> | [<img src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white">](typescript/integrations/deployment-lambda-cdk) [<img src="https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white">](go/integrations/go-lambda-cdk) [<img src="https://img.shields.io/badge/Java-ED8B00?logo=openjdk&logoColor=white">](java/integrations/java-gradle-lambda-cdk) [<img src="https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin&logoColor=white">](kotlin/integrations/kotlin-gradle-lambda-cdk) |
| <a id="xstate">XState</a> | [<img src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white">](typescript/integrations/xstate) |
| <a id="tuning-engines">Tuning Engines AI Gateway</a> | [<img src="https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white">](typescript/integrations/tuning-engines-governed-ai) |
| <a id="knative">Knative</a> | [<img src="https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white">](go/integrations/knative-go) |

#### End-to-End Applications
Expand Down Expand Up @@ -172,4 +173,4 @@ git push origin v0.9.1

This triggers a workflow that [creates a draft release](https://github.com/restatedev/examples/releases) on GitHub, which you need to approve to finalize it.

Please update the version tag referenced on the [Tour of Restate](https://github.com/restatedev/documentation) documentation page.
Please update the version tag referenced on the [Tour of Restate](https://github.com/restatedev/documentation) documentation page.
44 changes: 44 additions & 0 deletions typescript/integrations/tuning-engines-governed-ai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Tuning Engines governed AI with Restate

This example shows a Restate service handler calling the Tuning Engines
OpenAI-compatible endpoint. Restate owns durable execution and retries; Tuning
Engines owns model routing, policy checks, budgets, approvals, traces, and
runtime state references.

## Setup

```bash
npm install
export TE_INFERENCE_KEY=sk-te-your-inference-key
export TE_MODEL=auto
```

## Run

Start Restate locally:

```bash
npx @restatedev/restate-server
```

Start the service:

```bash
npm run service
```

Register the service:

```bash
npx @restatedev/restate deployments register http://localhost:9080
```

Invoke the handler using the normal Restate CLI or SDK flow. The handler passes
`run_id` and `request_id` metadata so Tuning Engines can correlate model usage,
policy decisions, approvals, and traces back to the Restate invocation.

## Files

- `src/app.ts` - Restate service with a governed model call.
- `package.json` - Minimal TypeScript project setup.
- `tsconfig.json` - TypeScript compiler settings.
17 changes: 17 additions & 0 deletions typescript/integrations/tuning-engines-governed-ai/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "restate-tuning-engines-governed-ai",
"private": true,
"type": "module",
"scripts": {
"service": "tsx src/app.ts",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@restatedev/restate-sdk": "^1.14.4",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
},
"devDependencies": {
"@types/node": "^24.10.1"
}
}
61 changes: 61 additions & 0 deletions typescript/integrations/tuning-engines-governed-ai/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as restate from "@restatedev/restate-sdk";

type Input = {
prompt?: string;
run_id?: string;
};

function newId(prefix: string): string {
return `${prefix}_${crypto.randomUUID().replaceAll("-", "")}`;
}

async function callTuningEngines(input: {
prompt: string;
run_id: string;
request_id: string;
}): Promise<unknown> {
const key = process.env.TE_INFERENCE_KEY;
if (!key) {
throw new Error("Set TE_INFERENCE_KEY before invoking this service.");
}

const response = await fetch("https://api.tuningengines.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
"X-TE-Run-ID": input.run_id,
"X-TE-Request-ID": input.request_id,
},
body: JSON.stringify({
model: process.env.TE_MODEL || "auto",
messages: [{ role: "user", content: input.prompt }],
metadata: {
run_id: input.run_id,
request_id: input.request_id,
runtime: "restate",
event_type: "model.call",
},
}),
});

if (!response.ok) {
throw new Error(`Tuning Engines request failed: ${response.status} ${await response.text()}`);
}

return response.json();
}

export default restate.service({
name: "TuningEnginesService",
handlers: {
async governedAi(_ctx: restate.Context, input: Input) {
const run_id = input.run_id || newId("restate");
const request_id = newId("req");
const prompt = input.prompt || "Say hello from a governed Restate handler.";

const result = await callTuningEngines({ prompt, run_id, request_id });
return { run_id, request_id, result };
},
},
});
11 changes: 11 additions & 0 deletions typescript/integrations/tuning-engines-governed-ai/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}
Loading