Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
astappiev committed Nov 11, 2024
1 parent 9f7c6fc commit 7ae8019
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public Uni<Void> delete(@QueryParam("id") Long id, @QueryParam("apikey") String
public Uni<UsageSummary> chat() {
ApiKey apikey = securityIdentity.getCredential(ApiKey.class);

return ChatUsage.findByApikey(apikey).map(UsageSummary::new);
Uni<UsageChat> usageChat = UsageChat.findByApikey(apikey);
Uni<UsageSearch> usageSearch = UsageSearch.findByApikey(apikey);
return Uni.combine().all().unis(usageChat, usageSearch).asTuple().map(tuple -> new UsageSummary(tuple.getItem1(), tuple.getItem2()));
}

public record CreateToken(@NotNull @NotEmpty @Size(max = 255) String name, @Size(max = 512) String url, @Size(max = 1024) String description) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.l3s.interweb.server.features.api;

import java.time.Instant;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;

import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import org.hibernate.annotations.CreationTimestamp;

import com.fasterxml.jackson.annotation.JsonIgnore;

import de.l3s.interweb.server.features.user.User;

@Entity
@Cacheable
@Table(name = "api_request")
public class ApiRequest extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;

@JsonIgnore
@ManyToOne(optional = false, fetch = FetchType.EAGER)
public User user;

@JsonIgnore
@ManyToOne(optional = false, fetch = FetchType.LAZY)
public ApiKey apikey;

@NotNull
public String action;

@CreationTimestamp
public Instant created;

public static ApiRequest of(String action, ApiKey apikey) {
ApiRequest request = new ApiRequest();
request.user = apikey.user;
request.apikey = apikey;
request.action = action;
return request;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,20 @@
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;

import io.quarkus.hibernate.reactive.panache.PanacheEntityBase;
import org.hibernate.annotations.CreationTimestamp;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

import de.l3s.interweb.core.chat.CompletionsResults;
import de.l3s.interweb.server.features.user.User;

@Entity
@Cacheable
@Table(name = "api_request_chat")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiChatRequest extends PanacheEntityBase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;
public class ApiRequestChat extends ApiRequest {

@JsonIgnore
@ManyToOne(optional = false, fetch = FetchType.EAGER)
public User user;

@JsonIgnore
@ManyToOne(optional = false, fetch = FetchType.LAZY)
public ApiKey apikey;
@Transient
public String action = "chat";

@NotNull
public String model;
Expand All @@ -49,8 +38,8 @@ public class ApiChatRequest extends PanacheEntityBase {
@CreationTimestamp
public Instant created;

public static ApiChatRequest of(CompletionsResults results, ApiKey apikey) {
ApiChatRequest request = new ApiChatRequest();
public static ApiRequestChat of(CompletionsResults results, ApiKey apikey) {
ApiRequestChat request = new ApiRequestChat();
request.user = apikey.user;
request.apikey = apikey;
request.model = results.getModel();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.l3s.interweb.server.features.api;

import java.time.Instant;

import de.l3s.interweb.core.search.ContentType;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;

import org.hibernate.annotations.CreationTimestamp;

import com.fasterxml.jackson.annotation.JsonInclude;

import de.l3s.interweb.core.search.SearchQuery;

@Entity
@Cacheable
@Table(name = "api_request_search")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiRequestSearch extends ApiRequest {

@Transient
public String action = "search";

@NotNull
public String engine;

@NotNull
public String contentType;

@NotNull
public String query;

@NotNull
@Column(name = "est_cost")
public Double estimatedCost = 0d;

@CreationTimestamp
public Instant created;

public static ApiRequestSearch of(String engine, ContentType contentType, String query, Double estimatedCost, ApiKey apikey) {
ApiRequestSearch request = new ApiRequestSearch();
request.user = apikey.user;
request.apikey = apikey;
request.engine = engine;
request.contentType = contentType.name();
request.query = query;
request.estimatedCost = estimatedCost;
return request;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import de.l3s.interweb.server.features.user.User;

@RegisterForReflection
public class ChatUsage {
public class UsageChat {
@JsonProperty("input_tokens")
public Long inputTokens;
@JsonProperty("output_tokens")
Expand All @@ -18,30 +18,30 @@ public class ChatUsage {
@JsonProperty("total_requests")
public Long totalRequests;

public ChatUsage(Long inputTokens, Long outputTokens, Double estimatedCost, Long totalRequests) {
public UsageChat(Long inputTokens, Long outputTokens, Double estimatedCost, Long totalRequests) {
this.inputTokens = inputTokens;
this.outputTokens = outputTokens;
this.estimatedCost = estimatedCost;
this.totalRequests = totalRequests;
}

public static Uni<ChatUsage> findByApikey(ApiKey apikey) {
return ApiChatRequest.find("""
public static Uni<UsageChat> findByApikey(ApiKey apikey) {
return ApiRequestChat.find("""
select sum(inputTokens) as inputTokens, sum(outputTokens) as outputTokens, sum(estimatedCost) as estimatedCost, count(*) as totalRequests
from ApiChatRequest
from ApiRequestChat
where apikey.id = ?1
""", apikey.id)
.project(ChatUsage.class)
.project(UsageChat.class)
.singleResult();
}

public static Uni<ChatUsage> findByUser(User user) {
return ApiChatRequest.find("""
public static Uni<UsageChat> findByUser(User user) {
return ApiRequestChat.find("""
select sum(inputTokens) as inputTokens, sum(outputTokens) as outputTokens, sum(estimatedCost) as estimatedCost, count(*) as totalRequests
from ApiChatRequest
from ApiRequestChat
where user.id = ?1
""", user.id)
.project(ChatUsage.class)
.project(UsageChat.class)
.singleResult();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package de.l3s.interweb.server.features.api;

import com.fasterxml.jackson.annotation.JsonProperty;

import de.l3s.interweb.server.features.user.User;

import io.quarkus.runtime.annotations.RegisterForReflection;
import io.smallrye.mutiny.Uni;

@RegisterForReflection
public class UsageSearch {
@JsonProperty("estimated_cost")
public Double estimatedCost;
@JsonProperty("total_requests")
public Long totalRequests;

public UsageSearch(Long inputTokens, Long outputTokens, Double estimatedCost, Long totalRequests) {
this.estimatedCost = estimatedCost;
this.totalRequests = totalRequests;
}

public static Uni<UsageSearch> findByApikey(ApiKey apikey) {
return ApiRequestChat.find("""
select sum(estimatedCost) as estimatedCost, count(*) as totalRequests
from ApiRequestSearch
where apikey.id = ?1
""", apikey.id)
.project(UsageSearch.class)
.singleResult();
}

public static Uni<UsageSearch> findByUser(User user) {
return ApiRequestChat.find("""
select sum(estimatedCost) as estimatedCost, count(*) as totalRequests
from ApiRequestSearch
where user.id = ?1
""", user.id)
.project(UsageSearch.class)
.singleResult();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package de.l3s.interweb.server.features.api;

import de.l3s.interweb.server.features.user.User;

import io.quarkus.cache.Cache;
import io.quarkus.cache.CacheName;

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.quarkus.vertx.ConsumeEvent;
import io.smallrye.mutiny.Uni;

import jakarta.inject.Inject;

@ApplicationScoped
public class UsageService {

@Inject
@CacheName("my-cache")
Cache cache;

public Uni<String> getNonBlockingExpensiveValue(Object key) {
return cache.get(key, k -> {
/*
* Put an expensive call here.
* It will be executed only if the key is not already associated with a value in the cache.
*/
});
}

public boolean isExceeded(User user) {
return false;
}

@WithSession
@ConsumeEvent("api-request")
public Uni<Void> consumeRequest(ApiRequest request) {
return request.persistAndFlush().replaceWithVoid();
}

@WithSession
@ConsumeEvent("api-request-chat")
public Uni<Void> consumeChatRequest(ApiRequestChat request) {
return request.persistAndFlush().replaceWithVoid();
}

@WithSession
@ConsumeEvent("api-request-search")
public Uni<Void> consumeSearchRequest(ApiRequestSearch request) {
return request.persistAndFlush().replaceWithVoid();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public record UsageSummary(ChatUsage chat) {
public record UsageSummary(UsageChat chat, UsageSearch search) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import de.l3s.interweb.core.chat.Message;
import de.l3s.interweb.core.util.StringUtils;
import de.l3s.interweb.server.Roles;
import de.l3s.interweb.server.features.api.ApiChatRequest;
import de.l3s.interweb.server.features.api.ApiRequestChat;
import de.l3s.interweb.server.features.api.ApiKey;

@Tag(name = "Chat", description = "OpenAI compatible chat completions")
Expand All @@ -44,7 +44,7 @@ public Uni<CompletionsResults> completions(@Valid CompletionsQuery query) {
ApiKey apikey = securityIdentity.getCredential(ApiKey.class);
return chatService.completions(query).chain(results -> {
results.setChatId(null); // reset chatId if it was set
bus.send("api-request-chat", ApiChatRequest.of(results, apikey));
bus.send("api-request-chat", ApiRequestChat.of(results, apikey));

if (!query.isSave()) {
return Uni.createFrom().item(results);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import de.l3s.interweb.core.chat.CompletionsResults;
import de.l3s.interweb.core.models.Model;
import de.l3s.interweb.server.Roles;
import de.l3s.interweb.server.features.api.ApiChatRequest;
import de.l3s.interweb.server.features.api.ApiRequestChat;
import de.l3s.interweb.server.features.api.ApiKey;
import de.l3s.interweb.server.features.chat.ChatService;
import de.l3s.interweb.server.features.models.ModelsService;
Expand Down Expand Up @@ -55,7 +55,7 @@ public Uni<CompletionsResults> chatCompletions(@Valid CompletionsQuery query) {
ApiKey apikey = securityIdentity.getCredential(ApiKey.class);
return chatService.completions(query).chain(results -> {
results.setChatId(null); // reset chatId if it was set
bus.send("api-request-chat", ApiChatRequest.of(results, apikey));
bus.send("api-request-chat", ApiRequestChat.of(results, apikey));
return Uni.createFrom().item(results);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.net.URI;
import java.util.Optional;

import de.l3s.interweb.server.features.api.UsageSearch;

import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
Expand All @@ -26,7 +28,7 @@
import org.jboss.logging.Logger;

import de.l3s.interweb.server.Roles;
import de.l3s.interweb.server.features.api.ChatUsage;
import de.l3s.interweb.server.features.api.UsageChat;
import de.l3s.interweb.server.features.api.UsageSummary;

@Tag(name = "Auth & Identity", description = "User management")
Expand Down Expand Up @@ -142,7 +144,10 @@ public User me() {
@Operation(summary = "Return the usage of the current user")
public Uni<UsageSummary> chat() {
User user = (User) securityIdentity.getPrincipal();
return ChatUsage.findByUser(user).map(UsageSummary::new);

Uni<UsageChat> usageChat = UsageChat.findByUser(user);
Uni<UsageSearch> usageSearch = UsageSearch.findByUser(user);
return Uni.combine().all().unis(usageChat, usageSearch).asTuple().map(tuple -> new UsageSummary(tuple.getItem1(), tuple.getItem2()));
}

public record LoginBody(@NotNull @NotEmpty @Email @Size(max = 255) String email) {
Expand Down

0 comments on commit 7ae8019

Please sign in to comment.