chore: commit pending gateway changes

This commit is contained in:
2026-05-10 22:34:15 +08:00
parent 53f8edfb67
commit d59756a27c
71 changed files with 15106 additions and 656 deletions
+281 -28
View File
@@ -5,19 +5,29 @@ import type {
CatalogProvider,
CatalogProviderUpsertRequest,
CreatedGatewayApiKey,
GatewayAccessRuleBatchRequest,
GatewayAccessRule,
GatewayAccessRuleUpsertRequest,
GatewayApiKey,
GatewayTenant,
GatewayTenantUpsertRequest,
GatewayTask,
GatewayUser,
GatewayUserUpsertRequest,
IntegrationPlatform,
ListResponse,
PlatformModel,
PlayableGatewayApiKey,
PricingRule,
PricingRuleSet,
PricingRuleSetUpsertRequest,
RateLimitWindow,
RuntimePolicySet,
RuntimePolicySetUpsertRequest,
UserGroup,
UserGroupUpsertRequest,
} from '@easyai-ai-gateway/contracts';
import type { PlatformCreateInput, PlatformModelBindingInput } from './types';
const API_BASE = import.meta.env.VITE_GATEWAY_API_BASE_URL ?? 'http://localhost:8088';
@@ -62,6 +72,10 @@ export async function listModels(token: string): Promise<ListResponse<PlatformMo
return request<ListResponse<PlatformModel>>('/api/v1/models', { token });
}
export async function listPlayableModels(token: string): Promise<ListResponse<PlatformModel>> {
return request<ListResponse<PlatformModel>>('/api/v1/playground/models', { token });
}
export async function listPublicCatalogProviders(): Promise<ListResponse<CatalogProvider>> {
return request<ListResponse<CatalogProvider>>('/api/v1/public/catalog/providers', { auth: false });
}
@@ -128,6 +142,20 @@ export async function updateBaseModel(
});
}
export async function resetBaseModel(token: string, baseModelId: string): Promise<BaseModelCatalogItem> {
return request<BaseModelCatalogItem>(`/api/v1/catalog/base-models/${baseModelId}/reset`, {
method: 'POST',
token,
});
}
export async function resetAllBaseModels(token: string): Promise<ListResponse<BaseModelCatalogItem>> {
return request<ListResponse<BaseModelCatalogItem>>('/api/v1/catalog/base-models/reset-all', {
method: 'POST',
token,
});
}
export async function deleteBaseModel(token: string, baseModelId: string): Promise<void> {
await request<void>(`/api/v1/catalog/base-models/${baseModelId}`, {
method: 'DELETE',
@@ -173,22 +201,168 @@ export async function deletePricingRuleSet(token: string, ruleSetId: string): Pr
});
}
export async function listRuntimePolicySets(token: string): Promise<ListResponse<RuntimePolicySet>> {
return request<ListResponse<RuntimePolicySet>>('/api/v1/runtime/policy-sets', { token });
}
export async function createRuntimePolicySet(
token: string,
input: RuntimePolicySetUpsertRequest,
): Promise<RuntimePolicySet> {
return request<RuntimePolicySet>('/api/v1/runtime/policy-sets', {
body: input,
method: 'POST',
token,
});
}
export async function updateRuntimePolicySet(
token: string,
policySetId: string,
input: RuntimePolicySetUpsertRequest,
): Promise<RuntimePolicySet> {
return request<RuntimePolicySet>(`/api/v1/runtime/policy-sets/${policySetId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deleteRuntimePolicySet(token: string, policySetId: string): Promise<void> {
await request<void>(`/api/v1/runtime/policy-sets/${policySetId}`, {
method: 'DELETE',
token,
});
}
export async function listTenants(token: string): Promise<ListResponse<GatewayTenant>> {
return request<ListResponse<GatewayTenant>>('/api/v1/tenants', { token });
}
export async function createTenant(token: string, input: GatewayTenantUpsertRequest): Promise<GatewayTenant> {
return request<GatewayTenant>('/api/v1/tenants', {
body: input,
method: 'POST',
token,
});
}
export async function updateTenant(token: string, tenantId: string, input: GatewayTenantUpsertRequest): Promise<GatewayTenant> {
return request<GatewayTenant>(`/api/v1/tenants/${tenantId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deleteTenant(token: string, tenantId: string): Promise<void> {
await request<void>(`/api/v1/tenants/${tenantId}`, {
method: 'DELETE',
token,
});
}
export async function listUsers(token: string): Promise<ListResponse<GatewayUser>> {
return request<ListResponse<GatewayUser>>('/api/v1/users', { token });
}
export async function createGatewayUser(token: string, input: GatewayUserUpsertRequest): Promise<GatewayUser> {
return request<GatewayUser>('/api/v1/users', {
body: input,
method: 'POST',
token,
});
}
export async function updateGatewayUser(token: string, userId: string, input: GatewayUserUpsertRequest): Promise<GatewayUser> {
return request<GatewayUser>(`/api/v1/users/${userId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deleteGatewayUser(token: string, userId: string): Promise<void> {
await request<void>(`/api/v1/users/${userId}`, {
method: 'DELETE',
token,
});
}
export async function listUserGroups(token: string): Promise<ListResponse<UserGroup>> {
return request<ListResponse<UserGroup>>('/api/v1/user-groups', { token });
}
export async function createUserGroup(token: string, input: UserGroupUpsertRequest): Promise<UserGroup> {
return request<UserGroup>('/api/v1/user-groups', {
body: input,
method: 'POST',
token,
});
}
export async function updateUserGroup(token: string, groupId: string, input: UserGroupUpsertRequest): Promise<UserGroup> {
return request<UserGroup>(`/api/v1/user-groups/${groupId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deleteUserGroup(token: string, groupId: string): Promise<void> {
await request<void>(`/api/v1/user-groups/${groupId}`, {
method: 'DELETE',
token,
});
}
export async function listAccessRules(token: string): Promise<ListResponse<GatewayAccessRule>> {
return request<ListResponse<GatewayAccessRule>>('/api/v1/access-rules', { token });
}
export async function createAccessRule(token: string, input: GatewayAccessRuleUpsertRequest): Promise<GatewayAccessRule> {
return request<GatewayAccessRule>('/api/v1/access-rules', {
body: input,
method: 'POST',
token,
});
}
export async function batchAccessRules(token: string, input: GatewayAccessRuleBatchRequest): Promise<ListResponse<GatewayAccessRule>> {
return request<ListResponse<GatewayAccessRule>>('/api/v1/access-rules/batch', {
body: input,
method: 'POST',
token,
});
}
export async function updateAccessRule(
token: string,
ruleId: string,
input: GatewayAccessRuleUpsertRequest,
): Promise<GatewayAccessRule> {
return request<GatewayAccessRule>(`/api/v1/access-rules/${ruleId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deleteAccessRule(token: string, ruleId: string): Promise<void> {
await request<void>(`/api/v1/access-rules/${ruleId}`, {
method: 'DELETE',
token,
});
}
export async function listApiKeys(token: string): Promise<ListResponse<GatewayApiKey>> {
return request<ListResponse<GatewayApiKey>>('/api/v1/api-keys', { token });
}
export async function listPlayableApiKeys(token: string): Promise<ListResponse<PlayableGatewayApiKey>> {
return request<ListResponse<PlayableGatewayApiKey>>('/api/playground/api-keys', { token });
}
export async function createApiKey(
token: string,
input: { name: string; scopes?: string[] },
@@ -200,22 +374,7 @@ export async function createApiKey(
});
}
export async function createPlatform(
token: string,
input: {
provider: string;
platformKey?: string;
name: string;
baseUrl?: string;
authType?: string;
credentials?: Record<string, unknown>;
config?: Record<string, unknown>;
defaultPricingMode?: string;
defaultDiscountFactor?: number;
pricingRuleSetId?: string;
priority?: number;
},
): Promise<IntegrationPlatform> {
export async function createPlatform(token: string, input: PlatformCreateInput): Promise<IntegrationPlatform> {
return request<IntegrationPlatform>('/api/v1/platforms', {
body: input,
method: 'POST',
@@ -223,21 +382,25 @@ export async function createPlatform(
});
}
export async function updatePlatform(token: string, platformId: string, input: PlatformCreateInput): Promise<IntegrationPlatform> {
return request<IntegrationPlatform>(`/api/v1/platforms/${platformId}`, {
body: input,
method: 'PATCH',
token,
});
}
export async function deletePlatform(token: string, platformId: string): Promise<void> {
await request<void>(`/api/v1/platforms/${platformId}`, {
method: 'DELETE',
token,
});
}
export async function createPlatformModel(
token: string,
platformId: string,
input: {
canonicalModelKey?: string;
baseModelId?: string;
modelName: string;
modelAlias?: string;
modelType: string;
displayName?: string;
retryPolicy?: Record<string, unknown>;
rateLimitPolicy?: Record<string, unknown>;
pricingRuleSetId?: string;
discountFactor?: number;
},
input: PlatformModelBindingInput,
): Promise<PlatformModel> {
return request<PlatformModel>(`/api/v1/platforms/${platformId}/models`, {
body: input,
@@ -246,6 +409,25 @@ export async function createPlatformModel(
});
}
export async function replacePlatformModels(
token: string,
platformId: string,
models: PlatformModelBindingInput[],
): Promise<ListResponse<PlatformModel>> {
return request<ListResponse<PlatformModel>>(`/api/v1/platforms/${platformId}/models`, {
body: { models },
method: 'PUT',
token,
});
}
export async function deletePlatformModel(token: string, modelId: string): Promise<void> {
await request<void>(`/api/v1/platform-models/${modelId}`, {
method: 'DELETE',
token,
});
}
export async function createChatTask(
token: string,
input: { model: string; messages: Array<Record<string, unknown>>; runMode?: string; simulation?: boolean },
@@ -257,6 +439,57 @@ export async function createChatTask(
});
}
export async function streamChatCompletions(
token: string,
input: { model: string; messages: Array<Record<string, unknown>>; simulation?: boolean },
onDelta: (delta: string) => void,
): Promise<void> {
for await (const delta of streamChatCompletionText(token, input)) {
onDelta(delta);
}
}
export async function* streamChatCompletionText(
token: string,
input: { model: string; messages: Array<Record<string, unknown>>; simulation?: boolean },
signal?: AbortSignal,
): AsyncGenerator<string> {
const response = await fetch(`${API_BASE}/v1/chat/completions`, {
body: JSON.stringify({ ...input, stream: true }),
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
method: 'POST',
signal,
});
if (!response.ok) {
const body = await response.text();
throw new Error(parseErrorMessage(body) || `Request failed: ${response.status}`);
}
if (!response.body) {
return;
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const events = buffer.split(/\n\n/);
buffer = events.pop() ?? '';
for (const eventBlock of events) {
const delta = parseSSEBlockDelta(eventBlock);
if (delta) yield delta;
}
}
if (buffer.trim()) {
const delta = parseSSEBlockDelta(buffer);
if (delta) yield delta;
}
}
export async function createImageGenerationTask(
token: string,
input: { model: string; prompt: string; size?: string; quality?: string; runMode?: string; simulation?: boolean },
@@ -335,3 +568,23 @@ function parseErrorMessage(body: string) {
return body;
}
}
function parseSSEBlockDelta(block: string) {
const data = block
.split(/\n/)
.filter((line) => line.startsWith('data:'))
.map((line) => line.replace(/^data:\s?/, ''))
.join('\n')
.trim();
if (!data || data === '[DONE]') return '';
try {
const parsed = JSON.parse(data) as {
choices?: Array<{ delta?: { content?: string }; message?: { content?: string } }>;
delta?: string;
output_text?: string;
};
return parsed.choices?.[0]?.delta?.content ?? parsed.delta ?? parsed.output_text ?? '';
} catch {
return data;
}
}