Skip to content

Commit 16398ca

Browse files
authored
Merge pull request #144 from lch24/dev
api_key
2 parents cfe5885 + 4e46067 commit 16398ca

10 files changed

Lines changed: 95 additions & 22 deletions

File tree

CAPI/cpp/API/include/API.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class IAPI
9393
// 等待下一帧
9494
virtual bool Wait() = 0;
9595
virtual std::future<bool> EndAllAction() = 0;
96+
virtual std::future<std::string> AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey = "") = 0;
9697
[[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI9::Character>> GetCharacters() const = 0;
9798
[[nodiscard]] virtual std::vector<std::shared_ptr<const THUAI9::Character>> GetEnemyCharacters() const = 0;
9899
[[nodiscard]] virtual std::vector<std::vector<THUAI9::PlaceType>> GetFullMap() const = 0;
@@ -190,6 +191,7 @@ class CharacterAPI : public ICharacterAPI, public IGameTimer
190191
[[nodiscard]] int32_t GetFrameCount() const override;
191192
bool Wait() override;
192193
std::future<bool> EndAllAction() override;
194+
std::future<std::string> AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey = "") override;
193195

194196
std::future<bool> Move(int64_t moveTimeInMilliseconds, double angle) override;
195197
std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
@@ -258,6 +260,7 @@ class TeamAPI : public ITeamAPI, public IGameTimer
258260
[[nodiscard]] int32_t GetFrameCount() const override;
259261
bool Wait() override;
260262
std::future<bool> EndAllAction() override;
263+
std::future<std::string> AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey = "") override;
261264

262265
[[nodiscard]] std::vector<std::shared_ptr<const THUAI9::Character>> GetCharacters() const override;
263266
[[nodiscard]] std::vector<std::shared_ptr<const THUAI9::Character>> GetEnemyCharacters() const override;
@@ -307,6 +310,7 @@ class CharacterDebugAPI : public ICharacterAPI, public IGameTimer
307310
bool Wait() override;
308311
[[nodiscard]] int32_t GetFrameCount() const override;
309312
std::future<bool> EndAllAction() override;
313+
std::future<std::string> AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey = "") override;
310314

311315
std::future<bool> Move(int64_t moveTimeInMilliseconds, double angle) override;
312316
std::future<bool> MoveRight(int64_t timeInMilliseconds) override;
@@ -366,6 +370,7 @@ class TeamDebugAPI : public ITeamAPI, public IGameTimer
366370
[[nodiscard]] int32_t GetFrameCount() const override;
367371
bool Wait() override;
368372
std::future<bool> EndAllAction() override;
373+
std::future<std::string> AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey = "") override;
369374

370375
[[nodiscard]] std::vector<std::shared_ptr<const THUAI9::Character>> GetCharacters() const override;
371376
[[nodiscard]] std::vector<std::shared_ptr<const THUAI9::Character>> GetEnemyCharacters() const override;

CAPI/cpp/API/include/Communication.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class Communication
5050
bool ProduceGoods(int64_t teamID, THUAI9::GoodsType goodsType, int32_t maxProduceNum);
5151
bool UplevelTech(int64_t teamID, THUAI9::TechType techType);
5252

53+
std::string AskAI(int64_t teamID, int64_t currentGameTime, const std::string& prompt, const std::string& apiKey);
54+
5355
private:
5456
std::unique_ptr<protobuf::AvailableService::Stub> THUAI9Stub;
5557
bool haveNewMessage = false;

CAPI/cpp/API/include/logic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class Logic : public ILogic
136136
bool BuildCharacter(THUAI9::CharacterType CharacterType, int32_t playerID);
137137
bool ProduceGoods(THUAI9::GoodsType goodsType, int32_t maxProduceNum);
138138
bool UplevelTech(THUAI9::TechType techType);
139+
std::string AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey);
139140

140141
bool TryConnection();
141142
void ProcessMessage();

CAPI/cpp/API/src/AI.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ void AI::play(ICharacterAPI& api)
1818
void AI::play(ITeamAPI& api)
1919
{
2020
(void)api;
21+
// auto answer = api.AskAI(/*currentGameTime*/, "your prompt", "<your uuid you can copy from eesast>").get();
2122
// TODO: implement team strategy.
2223
}

CAPI/cpp/API/src/API.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,24 @@ std::future<bool> CharacterAPI::EndAllAction()
8181
{ return logic.EndAllAction(); });
8282
}
8383

84+
std::future<std::string> CharacterAPI::AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey)
85+
{
86+
return std::async(std::launch::async, [this, currentGameTime, prompt = std::move(prompt), apiKey = std::move(apiKey)]() mutable
87+
{ return logic.AskAI(currentGameTime, std::move(prompt), std::move(apiKey)); });
88+
}
89+
8490
std::future<bool> TeamAPI::EndAllAction()
8591
{
8692
return std::async(std::launch::async, [this]()
8793
{ return logic.EndAllAction(); });
8894
}
8995

96+
std::future<std::string> TeamAPI::AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey)
97+
{
98+
return std::async(std::launch::async, [this, currentGameTime, prompt = std::move(prompt), apiKey = std::move(apiKey)]() mutable
99+
{ return logic.AskAI(currentGameTime, std::move(prompt), std::move(apiKey)); });
100+
}
101+
90102
std::vector<std::shared_ptr<const THUAI9::Character>> CharacterAPI::GetCharacters() const
91103
{
92104
return logic.GetCharacters();

CAPI/cpp/API/src/Communication.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,23 @@ bool Communication::UplevelTech(int64_t teamID, THUAI9::TechType techType)
187187
return status.ok() && result.act_success();
188188
}
189189

190+
std::string Communication::AskAI(int64_t teamID, int64_t currentGameTime, const std::string& prompt, const std::string& apiKey)
191+
{
192+
if (!ConsumeQuota(mtxLimit, counter, limit))
193+
return {};
194+
195+
protobuf::StrategicAIResponse reply;
196+
ClientContext context;
197+
protobuf::StrategicAIRequest request;
198+
request.set_team_id(teamID);
199+
request.set_current_game_time(currentGameTime);
200+
request.set_prompt(apiKey + "||" + prompt);
201+
auto status = THUAI9Stub->AskAI(&context, request, &reply);
202+
if (status.ok() && reply.act_success())
203+
return reply.answer();
204+
return {};
205+
}
206+
190207
bool Communication::TryConnection(int32_t playerID, int32_t teamID)
191208
{
192209
protobuf::BoolRes reply;

CAPI/cpp/API/src/DebugAPI.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ std::future<bool> CharacterDebugAPI::EndAllAction()
9999
{ return logic.EndAllAction(); });
100100
}
101101

102+
std::future<std::string> CharacterDebugAPI::AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey)
103+
{
104+
return std::async(std::launch::async, [this, currentGameTime, prompt = std::move(prompt), apiKey = std::move(apiKey)]() mutable
105+
{ return logic.AskAI(currentGameTime, std::move(prompt), std::move(apiKey)); });
106+
}
107+
102108
std::future<bool> CharacterDebugAPI::Move(int64_t moveTimeInMilliseconds, double angle)
103109
{
104110
logger->info("Move {} ms", moveTimeInMilliseconds);
@@ -352,6 +358,12 @@ std::future<bool> TeamDebugAPI::EndAllAction()
352358
{ return logic.EndAllAction(); });
353359
}
354360

361+
std::future<std::string> TeamDebugAPI::AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey)
362+
{
363+
return std::async(std::launch::async, [this, currentGameTime, prompt = std::move(prompt), apiKey = std::move(apiKey)]() mutable
364+
{ return logic.AskAI(currentGameTime, std::move(prompt), std::move(apiKey)); });
365+
}
366+
355367
std::vector<std::shared_ptr<const THUAI9::Character>> TeamDebugAPI::GetCharacters() const
356368
{
357369
return logic.GetCharacters();

CAPI/cpp/API/src/logic.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ bool Logic::UplevelTech(THUAI9::TechType techType)
280280
return pComm->UplevelTech(teamID, techType);
281281
}
282282

283+
std::string Logic::AskAI(int64_t currentGameTime, std::string prompt, std::string apiKey)
284+
{
285+
return pComm->AskAI(teamID, currentGameTime, prompt, apiKey);
286+
}
287+
283288
bool Logic::TryConnection()
284289
{
285290
return pComm->TryConnection(playerID, teamID);

logic/Gaming/Event.cs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ public async Task<bool> InitializeFromLLMAsync(int startTimeMs, int endTimeMs, C
5656
public bool InitializeFromLLM(int startTimeMs, int endTimeMs)
5757
=> InitializeFromLLMAsync(startTimeMs, endTimeMs).GetAwaiter().GetResult();
5858

59-
public async Task<string?> AskWithPromptAsync(string prompt, CancellationToken cancellationToken = default)
59+
public async Task<string?> AskWithPromptAsync(string prompt, string apiKey = "", CancellationToken cancellationToken = default)
6060
{
6161
try
6262
{
63-
return await RequestTextFromLLMAsync(prompt, cancellationToken);
63+
return await RequestTextFromLLMAsync(prompt, apiKey, cancellationToken);
6464
}
6565
catch (Exception ex)
6666
{
@@ -69,10 +69,10 @@ public bool InitializeFromLLM(int startTimeMs, int endTimeMs)
6969
}
7070
}
7171

72-
public string? AskWithPrompt(string prompt)
72+
public string? AskWithPrompt(string prompt, string apiKey = "")
7373
{
7474
using var cts = new CancellationTokenSource(GameData.AskAITimeoutMs);
75-
return AskWithPromptAsync(prompt, cts.Token).GetAwaiter().GetResult();
75+
return AskWithPromptAsync(prompt, apiKey, cts.Token).GetAwaiter().GetResult();
7676
}
7777

7878
public void InitDefault()
@@ -180,6 +180,16 @@ private sealed class GeneratedEvent
180180

181181
private static readonly HttpClient httpClient = new();
182182

183+
private static HttpRequestMessage BuildLLMRequest(string jsonBody, string apiKey)
184+
{
185+
var msg = new HttpRequestMessage(HttpMethod.Post, GameData.API_url)
186+
{
187+
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json")
188+
};
189+
msg.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
190+
return msg;
191+
}
192+
183193
private static async Task<GeneratedEvent?> RequestEventFromLLMAsync(CancellationToken cancellationToken)
184194
{
185195
if (string.IsNullOrWhiteSpace(GameData.API_key) ||
@@ -190,10 +200,7 @@ private sealed class GeneratedEvent
190200
return null;
191201
}
192202

193-
if (httpClient.DefaultRequestHeaders.Authorization == null)
194-
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GameData.API_key);
195-
196-
var req = new ChatRequest
203+
var chatReq = new ChatRequest
197204
{
198205
Model = GameData.ModelName,
199206
Messages =
@@ -211,9 +218,9 @@ private sealed class GeneratedEvent
211218
]
212219
};
213220

214-
var json = JsonSerializer.Serialize(req);
215-
using var content = new StringContent(json, Encoding.UTF8, "application/json");
216-
using var resp = await httpClient.PostAsync(GameData.API_url, content, cancellationToken);
221+
var json = JsonSerializer.Serialize(chatReq);
222+
using var request = BuildLLMRequest(json, GameData.API_key);
223+
using var resp = await httpClient.SendAsync(request, cancellationToken);
217224
if (!resp.IsSuccessStatusCode)
218225
{
219226
LogicLogging.logger.LogError($"Event LLM HTTP failed: {(int)resp.StatusCode}");
@@ -237,20 +244,22 @@ private sealed class GeneratedEvent
237244
return generated;
238245
}
239246

240-
private static async Task<string?> RequestTextFromLLMAsync(string prompt, CancellationToken cancellationToken)
247+
private static async Task<string?> RequestTextFromLLMAsync(string prompt, string apiKey, CancellationToken cancellationToken = default)
241248
{
242-
if (string.IsNullOrWhiteSpace(GameData.API_key) ||
243-
string.IsNullOrWhiteSpace(GameData.API_url) ||
249+
if (string.IsNullOrWhiteSpace(apiKey))
250+
{
251+
LogicLogging.logger.LogError("AskAI failed: team API key not configured.");
252+
return null;
253+
}
254+
255+
if (string.IsNullOrWhiteSpace(GameData.API_url) ||
244256
string.IsNullOrWhiteSpace(GameData.ModelName))
245257
{
246258
LogicLogging.logger.LogError("AskAI config missing in GameData.");
247259
return null;
248260
}
249261

250-
if (httpClient.DefaultRequestHeaders.Authorization == null)
251-
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GameData.API_key);
252-
253-
var req = new ChatRequest
262+
var chatReq = new ChatRequest
254263
{
255264
Model = GameData.ModelName,
256265
MaxTokens = 512,
@@ -269,9 +278,9 @@ private sealed class GeneratedEvent
269278
]
270279
};
271280

272-
var json = JsonSerializer.Serialize(req);
273-
using var content = new StringContent(json, Encoding.UTF8, "application/json");
274-
using var resp = await httpClient.PostAsync(GameData.API_url, content, cancellationToken);
281+
var json = JsonSerializer.Serialize(chatReq);
282+
using var request = BuildLLMRequest(json, apiKey);
283+
using var resp = await httpClient.SendAsync(request, cancellationToken);
275284
if (!resp.IsSuccessStatusCode)
276285
{
277286
LogicLogging.logger.LogError($"AskAI HTTP failed: {(int)resp.StatusCode}");

logic/Gaming/Game.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,15 @@ public bool Trade(long teamId, long playerId, Preparation.Utility.GoodsType type
315315
if (!EnsureGameStarted(nameof(AskAI)))
316316
return null;
317317

318+
// Prompt format: "apiKey||actualPrompt"
319+
string apiKey = string.Empty;
320+
var sepIndex = prompt.IndexOf("||", StringComparison.Ordinal);
321+
if (sepIndex >= 0)
322+
{
323+
apiKey = prompt.Substring(0, sepIndex);
324+
prompt = prompt.Substring(sepIndex + 2);
325+
}
326+
318327
if (string.IsNullOrWhiteSpace(prompt) || prompt.Length > GameData.AskAIPromptMaxLength)
319328
{
320329
LogicLogging.logger.LogWarning($"AskAI failed: invalid prompt length for team {teamId}.");
@@ -340,7 +349,7 @@ public bool Trade(long teamId, long playerId, Preparation.Utility.GoodsType type
340349
if (fac.ComputingPower.CompareExROri(cur - cost, cur) == cur) break;
341350
}
342351

343-
var answer = marketEvent.AskWithPrompt(prompt);
352+
var answer = marketEvent.AskWithPrompt(prompt, apiKey);
344353
if (string.IsNullOrWhiteSpace(answer))
345354
{
346355
fac.AddComputingPower(cost);

0 commit comments

Comments
 (0)