Skip to content

Commit eea02bc

Browse files
Merge pull request #328 from selfdocumentingcode/feature/gpt5
Feature/gpt5
2 parents 2e40ec8 + c094fa6 commit eea02bc

File tree

7 files changed

+64
-83
lines changed

7 files changed

+64
-83
lines changed

.github/workflows/release-v2.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ jobs:
249249
env:
250250
COMMIT_SHA: ${{ env.COMMIT_SHA }}
251251

252+
# Generate a token with "create release" permission (the default token has no such permission)
252253
- uses: actions/create-github-app-token@v1
253254
id: app-token
254255
with:
@@ -260,7 +261,6 @@ jobs:
260261
gh release create $SEMVER_TAG \
261262
--target $COMMIT_SHA \
262263
--title $SEMVER_TAG \
263-
--draft \
264264
--repo $REPOSITORY
265265
env:
266266
GH_TOKEN: ${{ steps.app-token.outputs.token }}

src/Kattbot.Common/Models/KattGpt/ChatCompletionCreateRequest.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,22 @@ public record ChatCompletionCreateRequest
103103
public bool? Stream { get; set; }
104104

105105
/// <summary>
106-
/// Gets or sets the maximum number of tokens to generate in the chat completion.
107-
/// The total length of input tokens and generated tokens is limited by the model's context length.
106+
/// An upper bound for the number of tokens that can be generated for a completion,
107+
/// including visible output tokens and reasoning tokens.
108108
/// Defaults to inf.
109-
/// https://platform.openai.com/docs/api-reference/chat/create#chat/create-max_tokens.
109+
/// https://platform.openai.com/docs/api-reference/chat/create#chat_create-max_completion_tokens
110110
/// </summary>
111-
[JsonPropertyName("max_tokens")]
112-
public int? MaxTokens { get; set; }
111+
[JsonPropertyName("max_completion_tokens")]
112+
public int? MaxCompletionTokens { get; set; }
113+
114+
/// <summary>
115+
/// Constrains effort on reasoning for reasoning models.
116+
/// Currently supported values are minimal, low, medium, and high
117+
/// Defaults to medium.
118+
/// https://platform.openai.com/docs/api-reference/chat/create#chat_create-reasoning_effort
119+
/// </summary>
120+
[JsonPropertyName("reasoning_effort")]
121+
public string? ReasoningEffort { get; set; }
113122

114123
/// <summary>
115124
/// Gets or sets number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the
@@ -130,9 +139,10 @@ public record ChatCompletionCreateRequest
130139
public float? FrequencyPenalty { get; set; }
131140

132141
/// <summary>
133-
/// Gets or sets a unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
134-
/// https://platform.openai.com/docs/api-reference/chat/create#chat/create-user.
142+
/// A stable identifier used to help detect users of your application that may be violating OpenAI's
143+
/// usage policies. The IDs should be a string that uniquely identifies each user.
144+
/// https://platform.openai.com/docs/api-reference/chat/create#chat_create-safety_identifier
135145
/// </summary>
136-
[JsonPropertyName("user")]
137-
public string? User { get; set; }
146+
[JsonPropertyName("safety_identifier")]
147+
public string? SafetyIdentifier { get; set; }
138148
}

src/Kattbot/Helpers/DiscordExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Linq;
34
using System.Threading;
45
using System.Threading.Tasks;
@@ -69,8 +70,12 @@ public static string SubstituteMentions(this DiscordMessage message)
6970
newMessageContent = newMessageContent.Replace(role.Mention, role.Name);
7071
}
7172

73+
ArgumentNullException.ThrowIfNull(message);
74+
ArgumentNullException.ThrowIfNull(message.MentionedChannels);
7275
foreach (DiscordChannel channel in message.MentionedChannels)
7376
{
77+
ArgumentNullException.ThrowIfNull(channel.Mention);
78+
ArgumentNullException.ThrowIfNull(channel.Name);
7479
newMessageContent = newMessageContent.Replace(channel.Mention, $"#{channel.Name}");
7580
}
7681

src/Kattbot/Kattbot.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="9.0.9" />
2222
<PackageReference Include="TiktokenSharp" Version="1.1.8" />
2323
<PackageReference Include="CommandLineArgumentsParser" Version="3.0.23" />
24-
<PackageReference Include="DSharpPlus" Version="5.0.0-nightly-02538" />
25-
<PackageReference Include="DSharpPlus.CommandsNext" Version="5.0.0-nightly-02538" />
26-
<PackageReference Include="DSharpPlus.Interactivity" Version="5.0.0-nightly-02538" />
27-
<PackageReference Include="MediatR" Version="13.0.0" />
28-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.9" />
29-
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.9" />
30-
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.9" />
24+
<PackageReference Include="DSharpPlus" Version="5.0.0-nightly-02542" />
25+
<PackageReference Include="DSharpPlus.CommandsNext" Version="5.0.0-nightly-02542" />
26+
<PackageReference Include="DSharpPlus.Interactivity" Version="5.0.0-nightly-02542" />
27+
<PackageReference Include="MediatR" Version="[12.5.0, 13)" />
28+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
29+
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="9.0.8" />
30+
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.8" />
3131
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
3232
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
3333
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />

src/Kattbot/NotificationHandlers/KattGptMessageHandler.cs

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ namespace Kattbot.NotificationHandlers;
2323
public class KattGptMessageHandler : BaseNotificationHandler,
2424
INotificationHandler<MessageCreatedNotification>
2525
{
26-
private const string ChatGptModel = "gpt-4o";
27-
private const string TokenizerModel = "gpt-4o";
26+
private const string ChatGptModel = "gpt-5";
27+
private const string TokenizerModel = "gpt-5";
28+
private const string DefaultReasoningEffort = "minimal";
2829

29-
private const float DefaultTemperature = 1.1f;
3030
private const int MaxTotalTokens = 24_576;
3131
private const int MaxTokensToGenerate = 960; // Roughly the limit of 2 Discord messages
32+
3233
private const string MessageSplitToken = "[cont.] ";
33-
private const string RecipientMarkerToYou = "[to you]";
34-
private const string RecipientMarkerToOthers = "[to others]";
34+
3535
private const string MessageToolUseTemplate = "`Kattbot used: {0}`";
3636

3737
private const string GptImageModel = "gpt-image-1";
@@ -85,26 +85,16 @@ public async Task Handle(MessageCreatedNotification notification, CancellationTo
8585
systemPromptsMessages,
8686
chatCompletionFunction);
8787

88-
bool shouldReplyToMessage = ShouldReplyToMessage(message);
89-
90-
string recipientMarker = shouldReplyToMessage
91-
? RecipientMarkerToYou
92-
: RecipientMarkerToOthers;
93-
9488
// Add the new message from notification
9589
string newMessageUser = author.GetDisplayName();
9690
string newMessageContent = message.SubstituteMentions();
9791

9892
ChatCompletionMessage newUserMessage =
99-
ChatCompletionMessage.AsUser($"{newMessageUser}{recipientMarker}: {newMessageContent}");
93+
ChatCompletionMessage.AsUser($"{newMessageUser}: {newMessageContent}");
10094

10195
newContextMessages.Add(newUserMessage);
10296

103-
if (!shouldReplyToMessage)
104-
{
105-
channelContext.AddMessages(newContextMessages);
106-
return;
107-
}
97+
channelContext.AddMessages(newContextMessages);
10898

10999
await channel.TriggerTypingAsync();
110100

@@ -142,8 +132,12 @@ public async Task Handle(MessageCreatedNotification notification, CancellationTo
142132
}
143133
catch (Exception ex)
144134
{
145-
await SendTextReply($"Something went wrong: {ex.Message}", message);
146-
_discordErrorLogger.LogError(ex.Message);
135+
if (ex is not NullReferenceException)
136+
{
137+
await SendTextReply($"Something went wrong: {ex.Message}", message);
138+
}
139+
140+
_discordErrorLogger.LogError(ex, ex.Message);
147141
}
148142
}
149143

@@ -172,8 +166,8 @@ private static ChatCompletionCreateRequest BuildRequest(
172166
{
173167
Model = ChatGptModel,
174168
Messages = requestMessages.ToArray(),
175-
Temperature = DefaultTemperature,
176-
MaxTokens = MaxTokensToGenerate,
169+
MaxCompletionTokens = MaxTokensToGenerate,
170+
ReasoningEffort = DefaultReasoningEffort,
177171
Tools = chatCompletionTools,
178172
ParallelToolCalls = parallelToolCalls,
179173
};
@@ -343,7 +337,7 @@ private KattGptChannelContext GetOrCreateCachedContext(
343337

344338
int remainingTokensForContextMessages = MaxTotalTokens - MaxTokensToGenerate - reservedTokenCount;
345339

346-
var tokenizer = new KattGptTokenizer(ChatGptModel);
340+
var tokenizer = new KattGptTokenizer(TokenizerModel);
347341

348342
channelContext = new KattGptChannelContext(remainingTokensForContextMessages, tokenizer);
349343

@@ -375,31 +369,7 @@ private bool ShouldHandleMessage(DiscordMessage message)
375369

376370
if (channelOptions == null) return false;
377371

378-
// if the channel is not always on, handle the message
379-
if (!channelOptions.AlwaysOn) return true;
380-
381-
// otherwise check if the message does not start with the MetaMessagePrefix
382-
string[] metaMessagePrefixes = _kattGptOptions.AlwaysOnIgnoreMessagePrefixes;
383-
bool messageStartsWithMetaMessagePrefix = metaMessagePrefixes.Any(messageContent.StartsWith);
384-
385-
// if it does, return false
386-
return !messageStartsWithMetaMessagePrefix;
387-
}
388-
389-
/// <summary>
390-
/// Checks if KattGpt should reply to the message.
391-
/// </summary>
392-
/// <param name="message">The message.</param>
393-
/// <returns>True if KattGpt should reply.</returns>
394-
private bool ShouldReplyToMessage(DiscordMessage message)
395-
{
396-
DiscordChannel channel = message.Channel!;
397-
398-
ChannelOptions? channelOptions = _kattGptService.GetChannelOptions(channel);
399-
400-
if (channelOptions == null) return false;
401-
402-
// if the channel is not always on
372+
// if the channel is not always on i.e. requires @mention or Reply
403373
if (!channelOptions.AlwaysOn)
404374
{
405375
// check if the current message is a reply to kattbot
@@ -415,7 +385,7 @@ private bool ShouldReplyToMessage(DiscordMessage message)
415385

416386
// otherwise check if the message does not start with the MetaMessagePrefix
417387
string[] metaMessagePrefixes = _kattGptOptions.AlwaysOnIgnoreMessagePrefixes;
418-
bool messageStartsWithMetaMessagePrefix = metaMessagePrefixes.Any(message.Content.TrimStart().StartsWith);
388+
bool messageStartsWithMetaMessagePrefix = metaMessagePrefixes.Any(messageContent.StartsWith);
419389

420390
// if it does, return false
421391
return !messageStartsWithMetaMessagePrefix;

src/Kattbot/appsettings.Development.json

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,25 @@
1111
"ConnectionString": "Server=host.docker.internal:5433;Database=kattbot-dev;User Id=kattbot;Password=hunter2",
1212
"CommandPrefix": "!",
1313
"AlternateCommandPrefix": "kd",
14-
"ErrorLogGuildId": "753161640496857149",
15-
"ErrorLogChannelId": "821763830577102848"
14+
"ErrorLogGuildId": "1411437458062835809",
15+
"ErrorLogChannelId": "1411441087997808750"
1616
},
1717
"KattGpt": {
1818
"GuildOptions": [
1919
{
2020
"Name": "The Cozy Climber Cat Tower",
21-
"Id": "753161640496857149",
21+
"Id": "1411437458062835809",
2222
"CategoryOptions": [
2323
{
2424
"_name": "KattGpt-dev",
25-
"Id": "1124778131753025636",
26-
"FallbackToChannelTopic": true
27-
},
28-
{
29-
"_name": "Hobbies-Dev",
30-
"Id": "1124778516991463464",
25+
"Id": "1411440609046171728",
3126
"FallbackToChannelTopic": true
3227
}
3328
],
3429
"ChannelOptions": [
3530
{
3631
"_name": "gpt-always-on",
37-
"Id": "1080612733222920332",
32+
"Id": "1411440430817742888",
3833
"Topic": "lolcat or lolspeak",
3934
"SystemPrompts": [
4035
"- In this channel all the users, including you, must write in lolcat.",
@@ -45,7 +40,7 @@
4540
},
4641
{
4742
"_name": "norsk-test",
48-
"Id": "1158017236070576210",
43+
"Id": "1411440848918548541",
4944
"Topic": "Norwegian culture and the Norwegian language",
5045
"SystemPrompts": [
5146
"- In this channel all the users, including you, must write in Norwegian.",

src/Kattbot/appsettings.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"OpenAiApiKey": "secret",
1414
"CommandPrefix": ";",
1515
"AlternateCommandPrefix": "kattpls",
16-
"ErrorLogGuildId": "753161640496857149",
17-
"ErrorLogChannelId": "821763787845402715"
16+
"ErrorLogGuildId": "1411437458062835809",
17+
"ErrorLogChannelId": "1411441021992042501"
1818
},
1919
"KattGpt": {
2020
"AlwaysOnIgnoreMessagePrefixes": [
@@ -30,25 +30,26 @@
3030
"- Identity: You are Kattbot, a talking robot-cat. Refrain from identifying as an AI Assistant or a Language Model unless necessary.",
3131
"- Tone: Maintain an informal, friendly, and engaging tone in interactions. Be approachable, interesting, and entertaining.",
3232
"- Image Generation: You can visually illustrate ideas through your AI Image Generator function, only using generated images, not sourced from elsewhere.",
33+
"- Emojis: You make conversations more fun by using emojis. Use emojis however sparingly.",
3334
"",
3435
"**Communication in Discord Channels:**",
3536
"- Interaction: Only engage in conversations when directly addressed by users.",
36-
"- Addressing: Messages from users will be prefixed with their name and the recipient marker ([to others] or [to you]).",
37-
" - Example: \"Alice[to others]: Hello, everyone! What’s up?\".",
38-
" - Example: \"Bob[to you]: Hello, how are you?\".",
39-
"- Response: Respond without prefixing your message with your name or a recipient marker. Use the name of the person addressing you to make the interaction more personal.",
37+
"- Addressing: Messages from users will be prefixed with their name.",
38+
" - Example: \"Bob: Hello, how are you?\".",
39+
"- Response: Respond using the name of the person addressing you to make the interaction more personal. Subsequent messages may omit the person's name.",
4040
" - Example: \"Hey, Bob! I’m doing quite well. How about you?\"",
4141
"",
4242
"**General Communication Guidelines:**",
4343
"- Engage: Aim to be active and reactive, keeping conversations flowing and enjoyable.",
4444
"- Clarification: If a message seems ambiguous or unclear, seek clarification politely.",
4545
"- Informative: Share engaging and fascinating tidbits, facts, or anecdotes when appropriate.",
46+
"- Style: Prefer writing paragraphs over bullet point lists, unless the response really fits a list format.",
4647
"",
4748
"**Image Generation Guidelines:**",
4849
"- Image Requests: Generate images only when requested by users.",
4950
"- When sharing an image that you generate, do not include textual indicators like \"[Attaches image]\" or \"[Generated image]\" within the message. The generated image is automatically added to your reply.",
5051
" - Example: ",
51-
" - User: \"John[to you]: Can you draw a cat sitting on a moon?\"",
52+
" - User: \"John: Can you draw a cat sitting on a moon?\"",
5253
" - Kattbot: \"Sure thing, John! Here’s your cat lounging on a moon!\" [This message contains the generated image]"
5354
],
5455
"Templates": [

0 commit comments

Comments
 (0)