-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUTest01.pas
249 lines (209 loc) · 7.62 KB
/
UTest01.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
{===============================================================================
_ ___ _____ _ _ _ _ ™
/_\ |_ _||_ _| ___ ___ | || |__(_)| |_
/ _ \ | | | | / _ \/ _ \| || / /| || _|
/_/ \_\|___| |_| \___/\___/|_||_\_\|_| \__|
AI Construction Set
Copyright © 2025-present tinyBigGAMES™ LLC
All Rights Reserved.
https://github.com/tinyBigGAMES/AIToolkit
See LICENSE file for license information
===============================================================================}
unit UTest01;
interface
uses
System.SysUtils,
System.Generics.Collections,
System.JSON,
System.RegularExpressions,
AIToolkit.Utils,
AIToolkit.Common,
AIToolkit.Messages,
AIToolkit.Inference,
AIToolkit.Tools,
AIToolkit.Console;
procedure Test();
implementation
const
// Toggle show thinking on/off
CShowThinking: Boolean = True;
// Max inference context used
CMaxContext = 1024*4;
type
// Tools static class
{$M+}
MyTools = class
published
// Document the tool method
[atSchemaDescription('Provides access to the internet to perform a web search and return the answer as a string. Only call when you can not answer the query and for real-time, time sensitive information')]
class function web_search(
// Document the tool method params
[atSchemaDescription('A string containing the result of the search query')]
query: string
): string; static;
end;
{$M-}
// Websearch tool function
class function MyTools.web_search(query: string): string;
begin
Result := atWebSearch(query.Trim()).Trim();
end;
// Get random "think" end messages
function GetRandomThinkingResult: string;
const
Messages: array[0..9] of string = (
'Here’s what I came up with:',
'This is what I found:',
'Here’s my answer:',
'Done! Here’s the result:',
'Here’s my response:',
'I’ve worked it out:',
'Processing complete. Here’s my output:',
'Here’s what I think:',
'After thinking it through, here’s my take:',
'Solution ready! Check this out:'
);
begin
Result := Messages[Random(Length(Messages))];
end;
// Custom next token event
procedure NextTokenEvent(const AToken: string);
begin
atConsole.Print(atCSIFGGreen+atCSIBold+atUtils.SanitizeFromJson(AToken));
end;
// Customize "think" start event
procedure ThinkStartEvent();
begin
atConsole.Print(atCSIFGBrightWhite+'Thinking...');
end;
// Customize "think" end event
procedure ThinkEndEvent();
begin
atConsole.ClearLine();
atConsole.PrintLn();
atConsole.PrintLn(atCSIFGCyan+GetRandomThinkingResult());
end;
procedure Test();
var
LTools: TatTools;
LMessages: TatMessagesDeepSeekR1;
LInference: TatInferenceDeepSeekR1;
LQuestion: string;
LTokenSpeed: Single;
LInputTokens: Integer;
LOutputTokens: Integer;
begin
try
LTools := TatTools.Create();
try
LMessages := TatMessagesDeepSeekR1.Create();
try
LInference := TatInferenceDeepSeekR1.Create;
try
// Add tool - called when need to do a web search for real-time, up todate inforamtion
LTools.Add(
// Class with published static tool methods
MyTools,
// Tool name
'web_search',
// Tool native function
procedure(const AMessages: TatMessages; const AInference: TatInference; const AToolCall: TatToolCall)
var
LArgs: TatParamArg;
LResponse: string;
begin
// Exit if function_call is nil
if not Assigned(AToolCall) then Exit;
// Display the name of this function_call to console
atConsole.PrintLn();
atConsole.PrintLn();
atConsole.PrintLn(atCSIFGYellow+'tool_call: "web_search"...');
// Loop over the function_call params
for LArgs in AToolCall.Params do
begin
// Do web search on Arg value (query)
LResponse := atUtils.CallStaticMethod(AToolCall.GetClass(), AToolCall.FuncName, [LArgs.Value]).AsString;
// Clear current messages
AMessages.Clear();
// Add search result as a user message - its formatted to
// instruct the LLM to display a promper response based on
// the query
AMessages.Add(atUser, LResponse);
end;
// Let reasoner LLM do inference on question
//RunInference(LMsgReason, AInference, True, CMaxContext, -1);
if not AInference.Run(AMessages, CMaxContext) then
begin
// Failed - display error
atConsole.PrintLn();
atConsole.PrintLn();
atConsole.PrintLn(atCSIFGRed+'Error: %s', [AInference.GetError()])
end;
end
);
//atConsole.PrintLn(LTools.CallPrompt());
//atConsole.PrintLn();
// Set the "think" start event handler
LInference.ThinkStartEvent := ThinkStartEvent;
// Set the "think" end event handler
LInference.ThinkEndEvent := ThinkEndEvent;
// Set show thinking tokens on/off
LInference.ShowThinking := CShowThinking;
// Set the next token event handler
LInference.NextTokenEvent := NextTokenEvent;
// Try to load the reasoning mode
if not LInference.LoadModel(CAIToolkit_Reasoning, -1, -1) then Exit;
//
LMessages.Add(atUser, LTools.CallPrompt());
// default question is nothing else is defined
LQuestion := 'what is AI?';
//LQuestion := 'what is bill gates current net worth as of 2025';
//LQuestion := 'who is bill gates?';
//LQuestion := 'what is the current U.S. national debt as of 2025?';
//LQuestion := 'what is KNO3?';
LQuestion := 'how many r''s are there in the word starawberry';
//LQuestion := 'what is the latest status on the forest fires in california in 2025?';
//LQuestion := 'detail steps how to make KNO3.';
//LQuestion := 'what is the current date and time?';
// Add question as a "user" message
LMessages.Add(atUser, LQuestion);
// Display user question
atConsole.PrintLn(atCSIFGYellow+'Question: %s', [LMessages.LastUser()]);
atConsole.PrintLn();
// Do inference
if LInference.Run(LMessages, CMaxContext) then
begin
LTools.Call(LMessages, LInference, LInference.Response());
// Success - display performance
LInference.Performance(@LInputTokens, @LOutputTokens, @LTokenSpeed);
atConsole.PrintLn();
atConsole.PrintLn();
atConsole.PrintLn(atCSIFGYellow+atCSIBold+'Tokens :: Input: %d, Output: %d, Speed: %3.2f', [LInputTokens, LOutputTokens, LTokenSpeed]);
end
else
begin
// Failed - display error
atConsole.PrintLn();
atConsole.PrintLn();
atConsole.PrintLn(atCSIFGRed+'Error: %s', [LInference.GetError()])
end;
finally
LInference.Free();
end;
finally
LMessages.Free();
end;
finally
LTools.Free();
end;
except
// Display any unhandled exceptions
on E: Exception do
begin
atConsole.PrintLn();
atConsole.PrintLn();
atConsole.PrintLn('Error: %s', [E.Message]);
end;
end;
end;
end.