Skip to content

Commit

Permalink
Add openapi docs
Browse files Browse the repository at this point in the history
  • Loading branch information
eoctet committed Feb 24, 2024
1 parent ae81944 commit a27eecd
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 7 deletions.
10 changes: 5 additions & 5 deletions octet-chat-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
Expand Down Expand Up @@ -134,6 +129,11 @@
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down
101 changes: 101 additions & 0 deletions octet-chat-app/src/main/java/chat/octet/api/ChatCompletionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,19 @@
import chat.octet.utils.JsonUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.annotations.RouterOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
Expand All @@ -26,6 +37,7 @@
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Flux;
Expand All @@ -39,8 +51,13 @@

import static org.springframework.web.reactive.function.server.RequestPredicates.POST;

@OpenAPIDefinition(
info = @Info(title = "Octet.Chat", description = "Build your own private auto agent."),
externalDocs = @ExternalDocumentation(description = "Github", url = "https://github.com/eoctet/Octet.Chat")
)
@Slf4j
@Configuration
@Tag(name = "ChatCompletionService", description = "Chat completion service")
public class ChatCompletionService {

private final Semaphore semaphore = new Semaphore(1);
Expand All @@ -64,6 +81,18 @@ private Mono<ServerResponse> response(HttpStatus status, String body) {


@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_EVENT_STREAM_VALUE},
operation = @Operation(
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = RequestParameter.class))),
description = "Chat with local agent.",
operationId = "chat",
tags = "Chat & Completions",
responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ChatCompletionChunk.class)))
)
)
public RouterFunction<ServerResponse> chatCompletionsFunction() {
return handler(
POST("/v1/chat/completions"),
Expand All @@ -82,6 +111,18 @@ public RouterFunction<ServerResponse> chatCompletionsFunction() {
}

@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_EVENT_STREAM_VALUE},
operation = @Operation(
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = RequestParameter.class))),
description = "Completions with local agent.",
operationId = "completions",
tags = "Chat & Completions",
responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ChatCompletionChunk.class)))
)
)
public RouterFunction<ServerResponse> completionsFunction() {
return handler(
POST("/v1/completions"),
Expand All @@ -96,6 +137,18 @@ public RouterFunction<ServerResponse> completionsFunction() {
}

@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
operation = @Operation(
requestBody = @RequestBody(content = @Content(examples = @ExampleObject(value = "{\"content\":\"Your text\"}"), schema = @Schema(implementation = Object.class))),
description = "Tokenize text to tokens.",
operationId = "tokenize",
tags = "Tokenize",
responses = @ApiResponse(responseCode = "200", content = @Content(examples = @ExampleObject(value = "{\"tokens\":[]}")))
)
)
public RouterFunction<ServerResponse> tokenizeFunction() {
return handler(
POST("/v1/tokenize"),
Expand All @@ -114,6 +167,18 @@ public RouterFunction<ServerResponse> tokenizeFunction() {
}

@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
operation = @Operation(
requestBody = @RequestBody(content = @Content(examples = @ExampleObject(value = "{\"tokens\":[]}"), schema = @Schema(implementation = Object.class))),
description = "Detokenize tokens to text.",
operationId = "detokenize",
tags = "Tokenize",
responses = @ApiResponse(responseCode = "200", content = @Content(examples = @ExampleObject(value = "{\"content\":\"string\"}")))
)
)
public RouterFunction<ServerResponse> detokenizeFunction() {
return handler(
POST("/v1/detokenize"),
Expand All @@ -133,6 +198,18 @@ public RouterFunction<ServerResponse> detokenizeFunction() {


@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.ALL_VALUE,
operation = @Operation(
requestBody = @RequestBody(content = @Content(examples = @ExampleObject(value = "{\"user\":\"string\",\"session\":\"string\"}"), schema = @Schema(implementation = Object.class))),
description = "Reset chat session.",
operationId = "reset",
tags = "Characters",
responses = @ApiResponse(responseCode = "200", content = @Content(examples = @ExampleObject(value = "success")))
)
)
public RouterFunction<ServerResponse> resetSessionFunction() {
return handler(
POST("/v1/session/reset"),
Expand All @@ -159,6 +236,18 @@ public RouterFunction<ServerResponse> resetSessionFunction() {
}

@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
operation = @Operation(
requestBody = @RequestBody(content = @Content(examples = @ExampleObject(value = "{}"), schema = @Schema(implementation = Object.class))),
description = "Show all AI characters list.",
operationId = "characters",
tags = "Characters",
responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = CharacterModel.class)))
)
)
public RouterFunction<ServerResponse> getCharactersFunction() {
return RouterFunctions.route(
RequestPredicates.POST("/v1/characters").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
Expand All @@ -179,6 +268,18 @@ public RouterFunction<ServerResponse> getCharactersFunction() {
}

@Bean
@RouterOperation(
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.ALL_VALUE,
operation = @Operation(
requestBody = @RequestBody(content = @Content(examples = @ExampleObject(value = "{\"character\": \"string\"}"), schema = @Schema(implementation = Object.class))),
description = "Reload AI characters.",
operationId = "reload",
tags = "Characters",
responses = @ApiResponse(responseCode = "200", content = @Content(examples = @ExampleObject(value = "success")))
)
)
public RouterFunction<ServerResponse> reloadCharactersFunction() {
return handler(
POST("/v1/characters/reload"),
Expand Down
5 changes: 3 additions & 2 deletions octet-chat-app/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
server:
port: 8152
shutdown: graceful
swagger:
enabled: true
springdoc:
api-docs:
enabled: true
spring:
lifecycle:
timeout-per-shutdown-phase: 30s

0 comments on commit a27eecd

Please sign in to comment.