Skip to content

Commit

Permalink
Merge branch 'main' into fix-typo-20241008
Browse files Browse the repository at this point in the history
  • Loading branch information
psxjoy authored Oct 8, 2024
2 parents ee5315f + 4a432c9 commit 40238de
Show file tree
Hide file tree
Showing 22 changed files with 2,260 additions and 2,518 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
Expand Down Expand Up @@ -1208,21 +1209,32 @@ private void fillIngressHeaderControlStageConfig(V1ObjectMeta metadata, HeaderCo
}
if (CollectionUtils.isNotEmpty(config.getAdd())) {
setFunctionalAnnotation(metadata, addKey,
StringUtils.join(config.getAdd().stream().map(this::getHeaderConfig).toList(), Separators.NEW_LINE),
StringUtils.join(config.getAdd().stream().map(this::getHeaderConfig).filter(Objects::nonNull).toList(),
Separators.NEW_LINE),
enabled);
}
if (CollectionUtils.isNotEmpty(config.getSet())) {
setFunctionalAnnotation(metadata, setKey,
StringUtils.join(config.getSet().stream().map(this::getHeaderConfig).toList(), Separators.NEW_LINE),
StringUtils.join(config.getSet().stream().map(this::getHeaderConfig).filter(Objects::nonNull).toList(),
Separators.NEW_LINE),
enabled);
}
if (CollectionUtils.isNotEmpty(config.getRemove())) {
setFunctionalAnnotation(metadata, removeKey, StringUtils.join(config.getRemove(), Separators.COMMA),
setFunctionalAnnotation(metadata, removeKey,
StringUtils.join(
config.getRemove().stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList()),
Separators.COMMA),
enabled);
}
}

private String getHeaderConfig(Header header) {
if (StringUtils.isEmpty(header.getKey())) {
return null;
}
if (StringUtils.isEmpty(header.getValue())) {
return header.getKey() + Separators.SPACE;
}
return header.getKey() + Separators.SPACE + header.getValue();
}

Expand Down Expand Up @@ -1273,7 +1285,7 @@ private void fillIngressTls(V1ObjectMeta metadata, V1IngressSpec spec, Route rou
}

V1IngressTLS tls = new V1IngressTLS();
if (!HigressConstants.DEFAULT_DOMAIN.equals(domainName)){
if (!HigressConstants.DEFAULT_DOMAIN.equals(domainName)) {
tls.setHosts(Collections.singletonList(domainName));
}
tls.setSecretName(domain.getCertIdentifier());
Expand Down Expand Up @@ -1602,13 +1614,19 @@ private static String buildImageUrl(String imageRepository, String imageVersion)
}

private void setQueryAnnotation(V1ObjectMeta metadata, KeyedRoutePredicate keyedRoutePredicate) {
if (StringUtils.isAnyBlank(keyedRoutePredicate.getMatchType(), keyedRoutePredicate.getKey(), keyedRoutePredicate.getMatchValue())){
return;
}
RoutePredicateTypeEnum predicateType = RoutePredicateTypeEnum.valueOf(keyedRoutePredicate.getMatchType());
String annotationName = String.format(KubernetesConstants.Annotation.QUERY_MATCH_KEY_FORMAT,
predicateType.getAnnotationPrefix(), keyedRoutePredicate.getKey());
KubernetesUtil.setAnnotation(metadata, annotationName, keyedRoutePredicate.getMatchValue());
}

private void setHeaderAnnotation(V1ObjectMeta metadata, KeyedRoutePredicate keyedRoutePredicate) {
if (StringUtils.isAnyBlank(keyedRoutePredicate.getMatchType(), keyedRoutePredicate.getKey(), keyedRoutePredicate.getMatchValue())){
return;
}
RoutePredicateTypeEnum predicateType = RoutePredicateTypeEnum.valueOf(keyedRoutePredicate.getMatchType());
String key = keyedRoutePredicate.getKey();
String format = KubernetesConstants.Annotation.HEADER_MATCH_KEY_FORMAT;
Expand Down
42 changes: 28 additions & 14 deletions backend/sdk/src/main/resources/plugins/ai-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ description: AI Agent插件配置参考
---

## 功能说明
一个可定制化的 API AI Agent,支持配置 http method 类型为 GET 与 POST 的 API,目前只支持非流式模式
一个可定制化的 API AI Agent,支持配置 http method 类型为 GET 与 POST 的 API,支持多轮对话,支持流式与非流式模式
agent流程图如下:
![ai-agent](https://github.com/user-attachments/assets/b0761a0c-1afa-496c-a98e-bb9f38b340f8)
![ai-agent](https://img.alicdn.com/imgextra/i1/O1CN01PGSDW31WQfEPm173u_!!6000000002783-0-tps-2733-1473.jpg)


## 运行属性

插件执行阶段:`默认阶段`
插件执行优先级:`20`
插件执行优先级:`200`

## 配置字段

Expand Down Expand Up @@ -46,18 +47,19 @@ agent流程图如下:

`apiProvider`的配置字段说明如下:

| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-----------------|-----------|---------|--------|------------------------------------------|
| `apiKey` | object | 非必填 | - | 用于在访问外部 API 服务时进行认证的令牌。 |
| `serviceName` | string | 必填 | - | 访问外部 API 服务名 |
| `servicePort` | int | 必填 | - | 访问外部 API 服务端口 |
| `domain` | string | 必填 | - | 访访问外部 API 时域名 |
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|-----------|---------|--------|------------------------------------------|
| `apiKey` | object | 非必填 | - | 用于在访问外部 API 服务时进行认证的令牌。 |
| `maxExecutionTime`| int | 非必填 | 50000 | 每一次请求API的超时时间,单位毫秒。 |
| `serviceName` | string | 必填 | - | 访问外部 API 服务名 |
| `servicePort` | int | 必填 | - | 访问外部 API 服务端口 |
| `domain` | string | 必填 | - | 访访问外部 API 时域名 |

`apiKey`的配置字段说明如下:

| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|---------|------------|--------|-------------------------------------------------------------------------------|
| `in` | string | 非必填 | header | 在访问外部 API 服务时进行认证的令牌是放在 header 中还是放在 query 中,默认是 header
|-------------------|---------|------------|--------|-----------------------------------------------------------------------------------------|
| `in` | string | 非必填 | none | 在访问外部 API 服务时进行认证的令牌是放在 header 中还是放在 query 中,如果API没有令牌,填none
| `name` | string | 非必填 | - | 用于在访问外部 API 服务时进行认证的令牌的名称。 |
| `value` | string | 非必填 | - | 用于在访问外部 API 服务时进行认证的令牌的值。 |

Expand All @@ -75,11 +77,8 @@ agent流程图如下:
|-----------------|-----------|-----------|--------|---------------------------------------------|
| `question` | string | 非必填 | - | Agent ReAct 模板的 question 部分 |
| `thought1` | string | 非必填 | - | Agent ReAct 模板的 thought1 部分 |
| `actionInput` | string | 非必填 | - | Agent ReAct 模板的 actionInput 部分 |
| `observation` | string | 非必填 | - | Agent ReAct 模板的 observation 部分 |
| `thought2` | string | 非必填 | - | Agent ReAct 模板的 thought2 部分 |
| `finalAnswer` | string | 非必填 | - | Agent ReAct 模板的 finalAnswer 部分 |
| `begin` | string | 非必填 | - | Agent ReAct 模板的 begin 部分 |

## 用法示例

Expand Down Expand Up @@ -325,6 +324,21 @@ curl 'http://<这里换成网关公网IP>/api/openai/v1/chat/completions' \

**请求示例**

```shell
curl 'http://<这里换成网关公网IP>/api/openai/v1/chat/completions' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
--data-raw '{"model":"qwen","frequency_penalty":0,"max_tokens":800,"stream":false,"messages":[{"role": "user","content": "济南的天气如何?"},{ "role": "assistant","content": "目前,济南市的天气为多云,气温为24℃,数据更新时间为2024年9月12日21时50分14秒。"},{"role": "user","content": "北京呢?"}],"presence_penalty":0,"temperature":0,"top_p":0}'
```

**响应示例**

```json
{"id":"ebd6ea91-8e38-9e14-9a5b-90178d2edea4","choices":[{"index":0,"message":{"role":"assistant","content":"目前,北京市的天气为晴朗,气温为19℃,数据更新时间为2024年9月12日22时17分40秒。"},"finish_reason":"stop"}],"created":1723187991,"model":"qwen-max-0403","object":"chat.completion","usage":{"prompt_tokens":999,"completion_tokens":76,"total_tokens":1075}}
```

**请求示例**

```shell
curl 'http://<这里换成网关公网IP>/api/openai/v1/chat/completions' \
-H 'Accept: application/json, text/event-stream' \
Expand Down
35 changes: 22 additions & 13 deletions backend/sdk/src/main/resources/plugins/ai-agent/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ keywords: [ AI Gateway, AI Agent ]
description: AI Agent plugin configuration reference
---
## Functional Description
A customizable API AI Agent that supports configuring HTTP method types as GET and POST APIs. Currently, it only supports non-streaming mode.
A customizable API AI Agent that supports configuring HTTP method types as GET and POST APIs. Supports multiple dialogue rounds, streaming and non-streaming modes.
The agent flow chart is as follows:
![ai-agent](https://github.com/user-attachments/assets/b0761a0c-1afa-496c-a98e-bb9f38b340f8)

## Runtime Properties
Plugin execution phase: `Default Phase`
Plugin execution priority: `20`
Plugin execution phase: `Default Phase`
Plugin execution priority: `200`

## Configuration Fields

Expand Down Expand Up @@ -41,17 +41,18 @@ The configuration fields for `apis` are as follows:
| `api` | string | Required | - | OpenAPI documentation of the tool |

The configuration fields for `apiProvider` are as follows:
| Name | Data Type | Requirement | Default Value | Description |
|-----------------|-----------|-------------|---------------|--------------------------------------------------|
| `apiKey` | object | Optional | - | Token for authentication when accessing external API services. |
| `serviceName` | string | Required | - | Name of the external API service |
| `servicePort` | int | Required | - | Port of the external API service |
| `domain` | string | Required | - | Domain for accessing the external API |
| Name | Data Type | Requirement | Default Value | Description |
|-------------------|-----------|-------------|---------------|--------------------------------------------------|
| `apiKey` | object | Optional | - | Token for authentication when accessing external API services. |
| `maxExecutionTime`| int | Optional | 50000 | Timeout for each request to the API, in milliseconds|
| `serviceName` | string | Required | - | Name of the external API service |
| `servicePort` | int | Required | - | Port of the external API service |
| `domain` | string | Required | - | Domain for accessing the external API |

The configuration fields for `apiKey` are as follows:
| Name | Data Type | Requirement | Default Value | Description |
|-------------------|-----------|-------------|---------------|-------------------------------------------------------------------------------------|
| `in` | string | Optional | header | Whether the authentication token for accessing the external API service is in the header or in the query; default is header. |
| `in` | string | Optional | none | Whether the authentication token for accessing the external API service is in the header or in the query; If the API does not have a token, fill in none. |
| `name` | string | Optional | - | The name of the token for authentication when accessing the external API service. |
| `value` | string | Optional | - | The value of the token for authentication when accessing the external API service. |

Expand All @@ -67,11 +68,8 @@ The configuration fields for `chTemplate` and `enTemplate` are as follows:
|-----------------|-----------|-------------|---------------|---------------------------------------------------|
| `question` | string | Optional | - | The question part of the Agent ReAct template |
| `thought1` | string | Optional | - | The thought1 part of the Agent ReAct template |
| `actionInput` | string | Optional | - | The actionInput part of the Agent ReAct template |
| `observation` | string | Optional | - | The observation part of the Agent ReAct template |
| `thought2` | string | Optional | - | The thought2 part of the Agent ReAct template |
| `finalAnswer` | string | Optional | - | The finalAnswer part of the Agent ReAct template |
| `begin` | string | Optional | - | The begin part of the Agent ReAct template |

## Usage Example
**Configuration Information**
Expand Down Expand Up @@ -308,6 +306,17 @@ curl 'http://<replace with gateway public IP>/api/openai/v1/chat/completions' \
curl 'http://<replace with gateway public IP>/api/openai/v1/chat/completions' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
--data-raw '{"model":"qwen","frequency_penalty":0,"max_tokens":800,"stream":false,"messages":[{"role":"user","content":"What is the current weather in Jinan?"},{"role":"assistant","content":" The current weather condition in Jinan is overcast, with a temperature of 31°C. This information was last updated on August 9, 2024, at 15:12 (Beijing time)."},{"role":"user","content":"BeiJing?"}],"presence_penalty":0,"temperature":0,"top_p":0}'
```
**Response Example**
```json
{"id":"ebd6ea91-8e38-9e14-9a5b-90178d2edea4","choices":[{"index":0,"message":{"role":"assistant","content":" The current weather condition in Beijing is overcast, with a temperature of 19°C. This information was last updated on Sep 12, 2024, at 22:17 (Beijing time)."},"finish_reason":"stop"}],"created":1723187991,"model":"qwen-max-0403","object":"chat.completion","usage":{"prompt_tokens":999,"completion_tokens":76,"total_tokens":1075}}
```
**Request Example**
```shell
curl 'http://<replace with gateway public IP>/api/openai/v1/chat/completions' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
--data-raw '{"model":"qwen","frequency_penalty":0,"max_tokens":800,"stream":false,"messages":[{"role":"user","content":"What is the current weather in Jinan? Please indicate in Fahrenheit and respond in Japanese."}],"presence_penalty":0,"temperature":0,"top_p":0}'
```
**Response Example**
Expand Down
2 changes: 1 addition & 1 deletion backend/sdk/src/main/resources/plugins/ai-agent/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ info:
gatewayMinVersion: ""
spec:
phase: default
priority: 20
priority: 200
routeConfigSchema:
openAPIV3Schema:
type: object
Expand Down
Loading

0 comments on commit 40238de

Please sign in to comment.