Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .github/README.jp.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ AIゲートウェイは、すべての他のプロバイダーとモデルに対
| <img src="https://files.readme.io/d38a23e-small-studio-favicon.png" width=35> | [AI21](https://portkey.ai/docs/welcome/integration-guides) | ✅ | ✅ |
| <img src="https://platform.stability.ai/small-logo-purple.svg" width=35> | [Stability AI](https://portkey.ai/docs/welcome/integration-guides/stability-ai) | ✅ | ✅ |
| <img src="https://deepinfra.com/_next/static/media/logo.4a03fd3d.svg" width=35> | [DeepInfra](https://portkey.ai/docs/welcome/integration-guides) | ✅ | ✅ |
| <img src="https://company.hpc-ai.com/hubfs/logos/colossal-ai_logo_vertical.svg" width=35 height=35 style="object-fit:contain" alt="HPC-AI"> | [HPC-AI](https://www.hpc-ai.com/) | ✅ | ✅ |
| <img src="https://ollama.com/public/ollama.png" width=35> | [Ollama](https://portkey.ai/docs/welcome/integration-guides/ollama) | ✅ | ✅ |
| <img src="https://novita.ai/favicon.ico" width=35> | Novita AI | ✅ | ✅ | `/chat/completions`, `/completions` |

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,15 @@ Explore Gateway integrations with [45+ providers](https://portkey.wiki/gh-59) an
| <img src="https://files.readme.io/d38a23e-small-studio-favicon.png" width=35> | [AI21](https://portkey.wiki/gh-91) | ✅ | ✅ |
| <img src="https://platform.stability.ai/small-logo-purple.svg" width=35> | [Stability AI](https://portkey.wiki/gh-71) | ✅ | ✅ |
| <img src="https://deepinfra.com/_next/static/media/logo.4a03fd3d.svg" width=35> | [DeepInfra](https://portkey.sh/gh-92) | ✅ | ✅ |
| <img src="https://company.hpc-ai.com/hubfs/logos/colossal-ai_logo_vertical.svg" width=35 height=35 style="object-fit:contain" alt="HPC-AI"> | [HPC-AI](https://www.hpc-ai.com/) | ✅ | ✅ |
| <img src="https://ollama.com/public/ollama.png" width=35> | [Ollama](https://portkey.wiki/gh-72) | ✅ | ✅ |
| <img src="https://novita.ai/favicon.ico" width=35> | [Novita AI](https://portkey.wiki/gh-73) | ✅ | ✅ | `/chat/completions`, `/completions` |


> [View the complete list of 200+ supported models here](https://portkey.wiki/gh-74)

**HPC-AI:** Use `provider: "hpc-ai"` with your HPC-AI API key. The gateway targets `https://api.hpc-ai.com/inference/v1` (OpenAI-compatible chat completions). Override the base URL with `x-portkey-custom-host` or `custom_host` in config if required. Example models: `minimax/minimax-m2.5`, `moonshotai/kimi-k2.5`. For local integration tests, optional env vars: `HPC_AI_API_KEY`, `HPC_AI_BASE_URL` (see `.env.example`).
Comment thread
lioZ129 marked this conversation as resolved.
Outdated

<br>

<br>
Expand Down
16 changes: 16 additions & 0 deletions src/data/models.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@
},
"name": "Axon Code"
},
{
"id": "minimax/minimax-m2.5",
"object": "model",
"provider": {
"id": "hpc-ai"
},
"name": "MiniMax M2.5"
},
{
"id": "moonshotai/kimi-k2.5",
"object": "model",
"provider": {
"id": "hpc-ai"
},
"name": "Kimi K2.5"
},
{
"id": "meta-llama/llama-3.1-70b-instruct/fp-8",
"object": "model",
Expand Down
2 changes: 2 additions & 0 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export const LEPTON: string = 'lepton';
export const KLUSTER_AI: string = 'kluster-ai';
export const NSCALE: string = 'nscale';
export const HYPERBOLIC: string = 'hyperbolic';
export const HPC_AI: string = 'hpc-ai';
export const BYTEZ: string = 'bytez';
export const FEATHERLESS_AI: string = 'featherless-ai';
export const KRUTRIM: string = 'krutrim';
Expand Down Expand Up @@ -173,6 +174,7 @@ export const VALID_PROVIDERS = [
KLUSTER_AI,
NSCALE,
HYPERBOLIC,
HPC_AI,
BYTEZ,
FEATHERLESS_AI,
KRUTRIM,
Expand Down
29 changes: 29 additions & 0 deletions src/providers/hpc-ai/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ProviderAPIConfig } from '../types';

const DEFAULT_HPC_AI_BASE_URL = 'https://api.hpc-ai.com/inference/v1';

const HpcAiApiConfig: ProviderAPIConfig = {
getBaseURL: ({ providerOptions }) => {
const fromEnv =
typeof process !== 'undefined' && process.env?.HPC_AI_BASE_URL
? process.env.HPC_AI_BASE_URL
: '';
return providerOptions.customHost || fromEnv || DEFAULT_HPC_AI_BASE_URL;
},
headers: ({ providerOptions }) => {
return {
Authorization: `Bearer ${providerOptions.apiKey}`,
};
},
getEndpoint: ({ fn }) => {
switch (fn) {
case 'chatComplete':
case 'stream-chatComplete':
return '/chat/completions';
default:
return '';
}
},
};

export default HpcAiApiConfig;
230 changes: 230 additions & 0 deletions src/providers/hpc-ai/chatComplete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
import { HPC_AI } from '../../globals';
import { Params } from '../../types/requestBody';
import {
ChatCompletionResponse,
ErrorResponse,
ProviderConfig,
} from '../types';
import {
generateErrorResponse,
generateInvalidProviderResponseError,
} from '../utils';

export const HpcAiChatCompleteConfig: ProviderConfig = {
model: {
param: 'model',
required: true,
default: 'minimax/minimax-m2.5',
},
messages: {
param: 'messages',
required: true,
default: [],
transform: (params: Params) => {
return params.messages?.map((message) => {
if (message.role === 'developer') return { ...message, role: 'system' };
return message;
});
},
},
frequency_penalty: {
param: 'frequency_penalty',
default: 0,
min: -2,
max: 2,
},
max_tokens: {
param: 'max_tokens',
default: 100,
min: 1,
},
max_completion_tokens: {
param: 'max_tokens',
default: 100,
min: 1,
},
n: {
param: 'n',
default: 1,
min: 1,
max: 1,
},
presence_penalty: {
param: 'presence_penalty',
min: -2,
max: 2,
default: 0,
},
temperature: {
param: 'temperature',
default: 1,
min: 0,
max: 2,
},
top_p: {
param: 'top_p',
default: 1,
min: 0,
max: 1,
},
stop: {
param: 'stop',
default: null,
},
stream: {
param: 'stream',
default: false,
},
};

interface HpcAiChatCompleteResponse extends ChatCompletionResponse {
id: string;
object: string;
created: number;
model: string;
usage: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
}

export interface HpcAiDetailErrorResponse {
detail: {
loc: string[];
msg: string;
type: string;
}[];
}

interface HpcAiStreamChunk {
id: string;
object: string;
created: number;
model: string;
choices: {
delta: {
role?: string | null;
content?: string;
};
index: number;
finish_reason: string | null;
}[];
usage?: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
}

export const HpcAiChatCompleteResponseTransform: (
response:
| HpcAiChatCompleteResponse
| HpcAiDetailErrorResponse
| ErrorResponse,
responseStatus: number
) => ChatCompletionResponse | ErrorResponse = (response, responseStatus) => {
if (responseStatus !== 200 && 'error' in response && response.error) {
return generateErrorResponse(
{
...response.error,
},
HPC_AI
);
}

if (
'detail' in response &&
responseStatus !== 200 &&
Array.isArray(response.detail) &&
response.detail.length
) {
let firstError: Record<string, any> | undefined;
let errorField: string | null = null;
let errorMessage: string | undefined;
let errorType: string | null = null;

[firstError] = response.detail;
errorField = firstError?.loc?.join('.') ?? '';
errorMessage = firstError.msg;
errorType = firstError.type;

return generateErrorResponse(
{
message: `${errorField ? `${errorField}: ` : ''}${errorMessage}`,
type: errorType,
param: null,
code: null,
},
HPC_AI
);
}

if ('choices' in response) {
return {
id: response.id,
object: response.object,
created: response.created,
model: response.model,
provider: HPC_AI,
choices: response.choices.map((c) => ({
index: c.index,
message: {
role: c.message.role,
content: c.message.content,
},
finish_reason: c.finish_reason,
})),
usage: {
prompt_tokens: response.usage?.prompt_tokens,
completion_tokens: response.usage?.completion_tokens,
total_tokens: response.usage?.total_tokens,
},
};
}

return generateInvalidProviderResponseError(response, HPC_AI);
};

export const HpcAiChatCompleteStreamChunkTransform: (
response: string
) => string = (responseChunk) => {
if (
responseChunk.match(
/^:\s*ping\s*-\s*\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{6}\+\d{2}:\d{2}$/
)
) {
return '';
}

let chunk = responseChunk.trim();
chunk = chunk.replace(/^data: /, '');
chunk = chunk.trim();
if (chunk === '[DONE]') {
return `data: ${chunk}\n\n`;
}
const parsedChunk: HpcAiStreamChunk = JSON.parse(chunk);
return (
`data: ${JSON.stringify({
id: parsedChunk.id,
object: parsedChunk.object,
created: parsedChunk.created,
model: parsedChunk.model,
provider: HPC_AI,
choices: [
{
index: parsedChunk.choices[0].index,
delta: parsedChunk.choices[0].delta,
finish_reason: parsedChunk.choices[0].finish_reason,
},
],
usage: parsedChunk.usage
? {
prompt_tokens: parsedChunk.usage.prompt_tokens,
completion_tokens: parsedChunk.usage.completion_tokens,
total_tokens: parsedChunk.usage.total_tokens,
}
: undefined,
})}` + '\n\n'
);
};
18 changes: 18 additions & 0 deletions src/providers/hpc-ai/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ProviderConfigs } from '../types';
import HpcAiApiConfig from './api';
import {
HpcAiChatCompleteConfig,
HpcAiChatCompleteResponseTransform,
HpcAiChatCompleteStreamChunkTransform,
} from './chatComplete';

const HpcAiConfig: ProviderConfigs = {
chatComplete: HpcAiChatCompleteConfig,
api: HpcAiApiConfig,
responseTransforms: {
chatComplete: HpcAiChatCompleteResponseTransform,
'stream-chatComplete': HpcAiChatCompleteStreamChunkTransform,
},
};

export default HpcAiConfig;
2 changes: 2 additions & 0 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import LeptonConfig from './lepton';
import KlusterAIConfig from './kluster-ai';
import NscaleConfig from './nscale';
import HyperbolicConfig from './hyperbolic';
import HpcAiConfig from './hpc-ai';
import { FeatherlessAIConfig } from './featherless-ai';
import KrutrimConfig from './krutrim';
import AI302Config from './302ai';
Expand Down Expand Up @@ -133,6 +134,7 @@ const Providers: { [key: string]: ProviderConfigs } = {
'kluster-ai': KlusterAIConfig,
nscale: NscaleConfig,
hyperbolic: HyperbolicConfig,
'hpc-ai': HpcAiConfig,
bytez: BytezConfig,
'featherless-ai': FeatherlessAIConfig,
krutrim: KrutrimConfig,
Expand Down
3 changes: 3 additions & 0 deletions src/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ <h3>Select Provider</h3>
<option value="openai">OpenAI</option>
<option value="anthropic">Anthropic</option>
<option value="groq">Groq</option>
<option value="hpc-ai">HPC-AI</option>
<option value="bedrock">Bedrock</option>
<option value="azure-openai">Azure OpenAI</option>
<option value="cohere">Cohere</option>
Expand Down Expand Up @@ -1460,6 +1461,7 @@ <h3>Enter API Key</h3>
"openai": "gpt-4o-mini",
"anthropic": "claude-3-5-sonnet-20240620",
"groq": "llama3-70b-8192",
"hpc-ai": "minimax/minimax-m2.5",
"bedrock": "anthropic.claude-3-sonnet-20240229-v1:0",
"azure-openai": "gpt-4o-mini",
"cohere": "command-r-plus",
Expand All @@ -1474,6 +1476,7 @@ <h3>Enter API Key</h3>
"openai": "https://portkey.ai/docs/integrations/llms/openai",
"anthropic": "https://portkey.ai/docs/integrations/llms/anthropic",
"groq": "https://portkey.ai/docs/integrations/llms/groq",
"hpc-ai": "https://portkey.ai/docs/integrations/llms/hpc-ai",
"bedrock": "https://portkey.ai/docs/integrations/llms/aws-bedrock",
"azure-openai": "https://portkey.ai/docs/integrations/llms/azure-openai",
"cohere": "https://portkey.ai/docs/integrations/llms/cohere",
Expand Down
4 changes: 4 additions & 0 deletions src/tests/resources/testVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ const testVariables: TestVariables = {
apiKey: process.env.DEEPINFRA_API_KEY,
chatCompletions: { model: 'meta-llama/Meta-Llama-3-8B-Instruct' },
},
'hpc-ai': {
apiKey: process.env.HPC_AI_API_KEY,
chatCompletions: { model: 'minimax/minimax-m2.5' },
},
'stability-ai': {
apiKey: process.env.STABILITY_AI_API_KEY,
chatCompletions: { model: '' },
Expand Down
Loading