├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── bin
├── JetInfero.dll
└── models.json
├── examples
└── testbed
│ ├── Testbed.dpr
│ ├── Testbed.dproj
│ ├── Testbed.res
│ ├── Testbed_Icon.ico
│ └── UTestbed.pas
├── lib
└── JetInfero.pas
├── media
├── delphi.png
└── jetinfero.png
├── src
├── JetInfero - Local LLM Inference Library.groupproj
├── JetInfero.CLibs.pas
├── JetInfero.CLibs.res
├── JetInfero.Core.pas
├── JetInfero.Defines.inc
├── JetInfero.Utils.pas
├── JetInfero.dpr
├── JetInfero.dproj
└── JetInfero.res
└── virustotal.txt
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: tinyBigGAMES # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Uncomment these types if you want even more clean repository. But be careful.
2 | # It can make harm to an existing project source. Read explanations below.
3 | #
4 | # Resource files are binaries containing manifest, project icon and version info.
5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
6 | #*.res
7 | #
8 | # Type library file (binary). In old Delphi versions it should be stored.
9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
10 | #*.tlb
11 | #
12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
13 | # Uncomment this if you are not using diagrams or use newer Delphi version.
14 | #*.ddp
15 | #
16 | # Visual LiveBindings file. Added in Delphi XE2.
17 | # Uncomment this if you are not using LiveBindings Designer.
18 | #*.vlb
19 | #
20 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
21 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
22 | #*.deployproj
23 | #
24 | # C++ object files produced when C/C++ Output file generation is configured.
25 | # Uncomment this if you are not using external objects (zlib library for example).
26 | #*.obj
27 | #
28 |
29 | # Default Delphi compiler directories
30 | # Content of this directories are generated with each Compile/Construct of a project.
31 | # Most of the time, files here have not there place in a code repository.
32 | #Win32/
33 | #Win64/
34 | #OSX64/
35 | #OSXARM64/
36 | #Android/
37 | #Android64/
38 | #iOSDevice64/
39 | #Linux64/
40 |
41 | # Delphi compiler-generated binaries (safe to delete)
42 | *.exe
43 | *.dll
44 | *.bpl
45 | *.bpi
46 | *.dcp
47 | *.so
48 | *.apk
49 | *.drc
50 | *.map
51 | *.dres
52 | *.rsm
53 | *.tds
54 | *.dcu
55 | *.lib
56 | *.a
57 | *.o
58 | *.ocx
59 |
60 | # Delphi autogenerated files (duplicated info)
61 | *.cfg
62 | *.hpp
63 | *Resource.rc
64 |
65 | # Delphi local files (user-specific info)
66 | *.local
67 | *.identcache
68 | *.projdata
69 | *.tvsconfig
70 | *.dsk
71 |
72 | # Delphi history and backups
73 | __history/
74 | __recovery/
75 | *.~*
76 |
77 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
78 | *.stat
79 |
80 | # Boss dependency manager vendor folder https://github.com/HashLoad/boss
81 | modules/
82 |
83 | # JetInfero
84 | !bin/JetInfero.dll
85 | bin/config.ini
86 | zip_latest_commit.cmd
87 | *.dsv
88 | bin/search_results.txt
89 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2024-present, tinyBigGAMES LLC
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | 3. Neither the name of the copyright holder nor the names of its
16 | contributors may be used to endorse or promote products derived from
17 | this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | [](https://discord.gg/tPWjMwK)
3 | [](https://bsky.app/profile/tinybiggames.com)
4 |
5 | ## 🌟 Fast, Flexible Local LLM Inference for Developers 🚀
6 |
7 | JetInfero is a nimble and high-performance library that enables developers to integrate local Large Language Models (LLMs) effortlessly into their applications. Powered by **llama.cpp** 🕊️, JetInfero prioritizes speed, flexibility, and ease of use 🌐. It’s compatible with any language supporting **Win64**, **Unicode**, and dynamic-link libraries (DLLs).
8 |
9 | ## 💡 Why Choose JetInfero?
10 |
11 | - **Optimized for Speed** ⚡️: Built on llama.cpp, JetInfero offers lightning-fast inference capabilities with minimal overhead.
12 | - **Cross-Language Support** 🌐: Seamlessly integrates with Delphi, C++, C#, Java, and other Win64-compatible environments.
13 | - **Intuitive API** 🔬: A clean procedural API simplifies model management, inference execution, and callback handling.
14 | - **Customizable Templates** 🖋️: Tailor input prompts to suit different use cases with ease.
15 | - **Scalable Performance** 🚀: Leverage GPU acceleration, token streaming, and multi-threaded execution for demanding workloads.
16 |
17 | ## 🛠️ Key Features
18 |
19 | ### 🤖 Advanced AI Integration
20 |
21 | JetInfero expands your toolkit with capabilities such as:
22 |
23 | - Dynamic chatbot creation 🗣️.
24 | - Automated text generation 🔄 and summarization 🕻.
25 | - Context-aware content creation 🌐.
26 | - Real-time token streaming for adaptive applications ⌚.
27 |
28 | ### 🔒 Privacy-Centric Local Execution
29 |
30 | - Operates entirely offline 🔐, ensuring sensitive data remains secure.
31 | - GPU acceleration supported via Vulkan for enhanced performance 🚒.
32 |
33 | ### ⚙️ Performance Optimization
34 |
35 | - Configure GPU utilization with `AGPULayers` 🔄.
36 | - Allocate threads dynamically using `AMaxThreads` 🌐.
37 | - Access performance metrics to monitor throughput and efficiency 📊.
38 |
39 | ### 🔀 Flexible Prompt Templates
40 |
41 | JetInfero’s template system simplifies input customization. Templates include placeholders such as:
42 |
43 | - **`{role}`**: Denotes the sender’s role (e.g., `user`, `assistant`).
44 | - **`{content}`**: Represents the message content.
45 |
46 | For example:
47 |
48 | ```pascal
49 | jiDefineModel(
50 | // Model Filename
51 | 'C:/LLM/GGUFDolphin3.0-Llama3.1-8B-Q4_K_M.gguf',
52 |
53 | // Model Refname
54 | 'Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf',
55 |
56 | // Model Template
57 | '<|im_start|>{role}\n{content}<|im_end|>',
58 |
59 | // Model Template End
60 | '<|im_start|>assistant',
61 |
62 | // Capitalize Role
63 | False,
64 |
65 | // Max Context
66 | 8192,
67 |
68 | // Main GPU, -1 for best, 0..N GPU number
69 | -1,
70 |
71 | // GPU Layers, -1 for max, 0 for CPU only, 1..N for layer
72 | -1,
73 |
74 | // Max threads, default 4, max will be physical CPU count
75 | 4
76 | );
77 | ```
78 |
79 | #### Template Benefits
80 |
81 | - **Adaptability** 🌐: Customize prompts for various LLMs and use cases.
82 | - **Consistency** 🔄: Ensure predictable inputs for reliable results.
83 | - **Flexibility** 🌈: Modify prompt formats for tasks like JSON or markdown generation.
84 |
85 | ### 🍂 Streamlined Model Management
86 |
87 | - Define models with `jiDefineModel` 🔨.
88 | - Load/unload models dynamically using `jiLoadModel` and `jiUnloadModel` 🔀.
89 | - Save/load model configurations with `jiSaveModelDefines` and `jiLoadModelDefines` 🗃️.
90 | - Clear all model definitions using `jiClearModelDefines` 🧹.
91 |
92 | ### 🔁 Inference Execution
93 |
94 | - Perform inference tasks with `jiRunInference` ⚙️.
95 | - Stream real-time tokens via `InferenceTokenCallback` ⌚.
96 | - Retrieve responses using `jiGetInferenceResponse` 🖊️.
97 |
98 | ### 📊 Performance Monitoring
99 |
100 | - Retrieve detailed metrics like tokens/second, input/output token counts, and execution time via `jiGetPerformanceResult` 📊.
101 |
102 | ## 🛠️ Installation
103 |
104 | 1. **Download the Repository** 📦
105 | - [Download here](https://github.com/tinyBigGAMES/JetInfero/archive/refs/heads/main.zip) and extract the files to your preferred directory 📂.
106 |
107 | Ensure `JetInfero.dll` is accessible in your project directory.
108 |
109 | 2. **Acquire a GGUF Model** 🧠
110 | - Obtain a model from [Hugging Face](https://huggingface.co), such as [
111 | Dolphin3.0-Llama3.1-8B-Q4_K_M-GGUF](https://huggingface.co/tinybiggames/Dolphin3.0-Llama3.1-8B-Q4_K_M-GGUF/resolve/main/dolphin3.0-llama3.1-8b-q4_k_m.gguf?download=true), a good general purpose model. You can download directly from our Hugging Face account. See the [model card](https://huggingface.co/tinybiggames/Dolphin3.0-Llama3.1-8B-Q4_K_M-GGUF) for more information.
112 | - Save it to a directory accessible to your application (e.g., `C:/LLM/GGUF`) 💾.
113 |
114 | 2. **Add JetInfero to Your Project** 🔨
115 | - Include the `JetInfero` unit in your Delphi project.
116 |
117 | 4. **Ensure GPU Compatibility** 🎮
118 | - Verify Vulkan compatibility for enhanced performance ⚡. Adjust `AGPULayers` as needed to accommodate VRAM limitations 📉.
119 |
120 | 5. **Building JetInfero DLL** 🛠️
121 | - Open and compile the `JetInfero.dproj` project 📂. This process will generate the 64-bit `JetInfero.dll` in the `lib` folder 🗂️.
122 | - The project was created and tested using Delphi 12.2 on Windows 11 24H2 🖥️.
123 |
124 | 6. **Using JetInfero** 🚀
125 | - JetInfero can be used with any programming language that supports Win64 and Unicode bindings 💻.
126 | - Ensure the `JetInfero.dll` is included in your distribution and accessible at runtime 📦.
127 |
128 | **Note: JetInfero requires direct access to the GPU/CPU and is not recommended for use inside a virtual machine.**
129 |
130 | ## 📈 Quick Start
131 |
132 | ### ⚙️ Basic Setup
133 |
134 | Integrate JetInfero into your Delphi project:
135 |
136 | ```pascal
137 | uses
138 | JetInfero;
139 |
140 | var
141 | LTokensPerSec: Double;
142 | LTotalInputTokens: Int32;
143 | LTotalOutputTokens: Int32;
144 | begin
145 | if jiInit() then
146 | begin
147 | jiDefineModel(
148 | 'C:/LLM/GGUF/Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf',
149 | 'Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf',
150 | '<|im_start|>{role}\n{content}<|im_end|>',
151 | '<|im_start|>assistant', False, 8192, -1, -1, 4);
152 |
153 | jiLoadModel('Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf');
154 |
155 | jiAddMessage('user', 'What is AI?');
156 |
157 | if jiRunInference(PWideChar(LModelRef)) then
158 | begin
159 | jiGetPerformanceResult(@LTokensPerSec, @LTotalInputTokens, @LTotalOutputTokens);
160 | WriteLn('Input Tokens : ', LTotalInputTokens);
161 | WriteLn('Output Tokens: ', LTotalOutputTokens);
162 | WriteLn('Speed : ', LTokensPerSec:3:2, ' t/s');
163 | end
164 | else
165 | begin
166 | WriteLn('Error: ', jiGetLastError());
167 | end;
168 |
169 | jiUnloadModel();
170 | jiQuit();
171 | end;
172 |
173 | end.
174 | ```
175 |
176 | ### 🔁 Using Callbacks
177 |
178 | Define a custom callback to handle token streaming:
179 |
180 | ```pascal
181 | procedure InferenceCallback(const Token: string; const UserData: Pointer);
182 | begin
183 | Write(Token);
184 | end;
185 |
186 | jiSetInferenceTokenCallback(@InferenceCallback, nil);
187 | ```
188 |
189 | ### 📊 Retrieve Performance Metrics
190 |
191 | Access performance results to monitor efficiency:
192 |
193 | ```pascal
194 | var
195 | Metrics: TPerformanceResult;
196 | begin
197 | Metrics := jiGetPerformanceResult();
198 | WriteLn('Tokens/Sec: ', Metrics.TokensPerSecond);
199 | WriteLn('Input Tokens: ', Metrics.TotalInputTokens);
200 | WriteLn('Output Tokens: ', Metrics.TotalOutputTokens);
201 | end;
202 | ```
203 |
204 | ### 🛠️ Support and Resources
205 |
206 | - Report issues via the [Issue Tracker](https://github.com/tinyBigGAMES/jetinfero/issues) 🐞.
207 | - Engage in discussions on the [Forum](https://github.com/tinyBigGAMES/jetinfero/discussions) and [Discord](https://discord.gg/tPWjMwK) 💬.
208 | - Learn more at [Learn Delphi](https://learndelphi.org) 📚.
209 |
210 | ### 🤝 Contributing
211 |
212 | Contributions to **✨ JetInfero** are highly encouraged! 🌟
213 | - 🐛 **Report Issues:** Submit issues if you encounter bugs or need help.
214 | - 💡 **Suggest Features:** Share your ideas to make **Lumina** even better.
215 | - 🔧 **Create Pull Requests:** Help expand the capabilities and robustness of the library.
216 |
217 | Your contributions make a difference! 🙌✨
218 |
219 | #### Contributors 👥🤝
220 |
221 |
222 |
223 |
224 |
225 |
226 | ### 📜 Licensing
227 |
228 | **JetInfero** is distributed under the 🆓 **BSD-3-Clause License**, allowing for redistribution and use in both source and binary forms, with or without modification, under specific conditions. See the [LICENSE](https://github.com/tinyBigGAMES/JetInfero?tab=BSD-3-Clause-1-ov-file#BSD-3-Clause-1-ov-file) file for more details.
229 |
230 | ---
231 | **Elevate your Delphi projects with JetInfero 🚀 – your bridge to seamless local generative AI integration 🤖.**
232 |
233 |
234 |
235 |
236 |
237 |
238 | Made with :heart: in Delphi
239 |
--------------------------------------------------------------------------------
/bin/JetInfero.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/bin/JetInfero.dll
--------------------------------------------------------------------------------
/bin/models.json:
--------------------------------------------------------------------------------
1 | {
2 | "Models": [
3 | {
4 | "Filename": "C:/LLM/GGUF/Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf",
5 | "RefName": "Dolphin3.0-Llama3.1-8B-Q4_K_M",
6 | "MaxContext": 8192,
7 | "MaxThreads": 4,
8 | "MainGPU": -1,
9 | "GPULayers": -1,
10 | "Template": "<|im_start|>{role}\\n{content}<|im_end|>",
11 | "TemplateEnd": "<|im_start|>assistant"
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------
/examples/testbed/Testbed.dpr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/examples/testbed/Testbed.dpr
--------------------------------------------------------------------------------
/examples/testbed/Testbed.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {10F58B25-2C9E-4A73-A14A-C88E827FED31}
4 | 20.3
5 | None
6 | True
7 | Release
8 | Win64
9 | Testbed
10 | 2
11 | Console
12 | Testbed.dpr
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Cfg_1
35 | true
36 | true
37 |
38 |
39 | true
40 | Cfg_1
41 | true
42 | true
43 |
44 |
45 | true
46 | Base
47 | true
48 |
49 |
50 | true
51 | Cfg_2
52 | true
53 | true
54 |
55 |
56 | .\$(Platform)\$(Config)
57 | .\$(Platform)\$(Config)
58 | false
59 | false
60 | false
61 | false
62 | false
63 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
64 | Testbed
65 |
66 |
67 | vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;vclactnband;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;Skia.Package.FMX;FireDACOracleDriver;fmxdae;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
68 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
69 | Debug
70 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
71 | 1033
72 | true
73 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
74 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
75 |
76 |
77 | vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;vclactnband;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
78 | true
79 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
80 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
81 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
82 | Debug
83 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
84 | 1033
85 | ..\..\bin
86 | $(BDS)\bin\default_app.manifest
87 | PerMonitorV2
88 | Testbed_Icon.ico
89 |
90 |
91 | DEBUG;$(DCC_Define)
92 | true
93 | false
94 | true
95 | true
96 | true
97 | true
98 | true
99 |
100 |
101 | false
102 |
103 |
104 | 1033
105 |
106 |
107 | false
108 | RELEASE;$(DCC_Define)
109 | 0
110 | 0
111 |
112 |
113 | 1033
114 |
115 |
116 |
117 | MainSource
118 |
119 |
120 |
121 |
122 | Base
123 |
124 |
125 | Cfg_1
126 | Base
127 |
128 |
129 | Cfg_2
130 | Base
131 |
132 |
133 |
134 | Delphi.Personality.12
135 | Application
136 |
137 |
138 |
139 | Testbed.dpr
140 |
141 |
142 | Embarcadero C++Builder Office 2000 Servers Package
143 | Embarcadero C++Builder Office XP Servers Package
144 | Microsoft Office 2000 Sample Automation Server Wrapper Components
145 | Microsoft Office XP Sample Automation Server Wrapper Components
146 |
147 |
148 |
149 |
150 |
151 | true
152 |
153 |
154 |
155 |
156 | true
157 |
158 |
159 |
160 |
161 | true
162 |
163 |
164 |
165 |
166 | Testbed.exe
167 | true
168 |
169 |
170 |
171 |
172 | Testbed.exe
173 | true
174 |
175 |
176 |
177 |
178 | Testbed.exe
179 | true
180 |
181 |
182 |
183 |
184 | 1
185 |
186 |
187 | Contents\MacOS
188 | 1
189 |
190 |
191 | 0
192 |
193 |
194 |
195 |
196 | res\xml
197 | 1
198 |
199 |
200 | res\xml
201 | 1
202 |
203 |
204 |
205 |
206 | library\lib\armeabi
207 | 1
208 |
209 |
210 | library\lib\armeabi
211 | 1
212 |
213 |
214 |
215 |
216 | library\lib\armeabi-v7a
217 | 1
218 |
219 |
220 |
221 |
222 | library\lib\mips
223 | 1
224 |
225 |
226 | library\lib\mips
227 | 1
228 |
229 |
230 |
231 |
232 | library\lib\armeabi-v7a
233 | 1
234 |
235 |
236 | library\lib\arm64-v8a
237 | 1
238 |
239 |
240 |
241 |
242 | library\lib\armeabi-v7a
243 | 1
244 |
245 |
246 |
247 |
248 | res\drawable
249 | 1
250 |
251 |
252 | res\drawable
253 | 1
254 |
255 |
256 |
257 |
258 | res\drawable-anydpi-v21
259 | 1
260 |
261 |
262 | res\drawable-anydpi-v21
263 | 1
264 |
265 |
266 |
267 |
268 | res\values
269 | 1
270 |
271 |
272 | res\values
273 | 1
274 |
275 |
276 |
277 |
278 | res\values-v21
279 | 1
280 |
281 |
282 | res\values-v21
283 | 1
284 |
285 |
286 |
287 |
288 | res\values-v31
289 | 1
290 |
291 |
292 | res\values-v31
293 | 1
294 |
295 |
296 |
297 |
298 | res\drawable-anydpi-v26
299 | 1
300 |
301 |
302 | res\drawable-anydpi-v26
303 | 1
304 |
305 |
306 |
307 |
308 | res\drawable
309 | 1
310 |
311 |
312 | res\drawable
313 | 1
314 |
315 |
316 |
317 |
318 | res\drawable
319 | 1
320 |
321 |
322 | res\drawable
323 | 1
324 |
325 |
326 |
327 |
328 | res\drawable
329 | 1
330 |
331 |
332 | res\drawable
333 | 1
334 |
335 |
336 |
337 |
338 | res\drawable-anydpi-v33
339 | 1
340 |
341 |
342 | res\drawable-anydpi-v33
343 | 1
344 |
345 |
346 |
347 |
348 | res\values
349 | 1
350 |
351 |
352 | res\values
353 | 1
354 |
355 |
356 |
357 |
358 | res\values-night-v21
359 | 1
360 |
361 |
362 | res\values-night-v21
363 | 1
364 |
365 |
366 |
367 |
368 | res\drawable
369 | 1
370 |
371 |
372 | res\drawable
373 | 1
374 |
375 |
376 |
377 |
378 | res\drawable-xxhdpi
379 | 1
380 |
381 |
382 | res\drawable-xxhdpi
383 | 1
384 |
385 |
386 |
387 |
388 | res\drawable-xxxhdpi
389 | 1
390 |
391 |
392 | res\drawable-xxxhdpi
393 | 1
394 |
395 |
396 |
397 |
398 | res\drawable-ldpi
399 | 1
400 |
401 |
402 | res\drawable-ldpi
403 | 1
404 |
405 |
406 |
407 |
408 | res\drawable-mdpi
409 | 1
410 |
411 |
412 | res\drawable-mdpi
413 | 1
414 |
415 |
416 |
417 |
418 | res\drawable-hdpi
419 | 1
420 |
421 |
422 | res\drawable-hdpi
423 | 1
424 |
425 |
426 |
427 |
428 | res\drawable-xhdpi
429 | 1
430 |
431 |
432 | res\drawable-xhdpi
433 | 1
434 |
435 |
436 |
437 |
438 | res\drawable-mdpi
439 | 1
440 |
441 |
442 | res\drawable-mdpi
443 | 1
444 |
445 |
446 |
447 |
448 | res\drawable-hdpi
449 | 1
450 |
451 |
452 | res\drawable-hdpi
453 | 1
454 |
455 |
456 |
457 |
458 | res\drawable-xhdpi
459 | 1
460 |
461 |
462 | res\drawable-xhdpi
463 | 1
464 |
465 |
466 |
467 |
468 | res\drawable-xxhdpi
469 | 1
470 |
471 |
472 | res\drawable-xxhdpi
473 | 1
474 |
475 |
476 |
477 |
478 | res\drawable-xxxhdpi
479 | 1
480 |
481 |
482 | res\drawable-xxxhdpi
483 | 1
484 |
485 |
486 |
487 |
488 | res\drawable-small
489 | 1
490 |
491 |
492 | res\drawable-small
493 | 1
494 |
495 |
496 |
497 |
498 | res\drawable-normal
499 | 1
500 |
501 |
502 | res\drawable-normal
503 | 1
504 |
505 |
506 |
507 |
508 | res\drawable-large
509 | 1
510 |
511 |
512 | res\drawable-large
513 | 1
514 |
515 |
516 |
517 |
518 | res\drawable-xlarge
519 | 1
520 |
521 |
522 | res\drawable-xlarge
523 | 1
524 |
525 |
526 |
527 |
528 | res\values
529 | 1
530 |
531 |
532 | res\values
533 | 1
534 |
535 |
536 |
537 |
538 | res\drawable-anydpi-v24
539 | 1
540 |
541 |
542 | res\drawable-anydpi-v24
543 | 1
544 |
545 |
546 |
547 |
548 | res\drawable
549 | 1
550 |
551 |
552 | res\drawable
553 | 1
554 |
555 |
556 |
557 |
558 | res\drawable-night-anydpi-v21
559 | 1
560 |
561 |
562 | res\drawable-night-anydpi-v21
563 | 1
564 |
565 |
566 |
567 |
568 | res\drawable-anydpi-v31
569 | 1
570 |
571 |
572 | res\drawable-anydpi-v31
573 | 1
574 |
575 |
576 |
577 |
578 | res\drawable-night-anydpi-v31
579 | 1
580 |
581 |
582 | res\drawable-night-anydpi-v31
583 | 1
584 |
585 |
586 |
587 |
588 | 1
589 |
590 |
591 | Contents\MacOS
592 | 1
593 |
594 |
595 | 0
596 |
597 |
598 |
599 |
600 | Contents\MacOS
601 | 1
602 | .framework
603 |
604 |
605 | Contents\MacOS
606 | 1
607 | .framework
608 |
609 |
610 | Contents\MacOS
611 | 1
612 | .framework
613 |
614 |
615 | 0
616 |
617 |
618 |
619 |
620 | 1
621 | .dylib
622 |
623 |
624 | 1
625 | .dylib
626 |
627 |
628 | 1
629 | .dylib
630 |
631 |
632 | Contents\MacOS
633 | 1
634 | .dylib
635 |
636 |
637 | Contents\MacOS
638 | 1
639 | .dylib
640 |
641 |
642 | Contents\MacOS
643 | 1
644 | .dylib
645 |
646 |
647 | 0
648 | .dll;.bpl
649 |
650 |
651 |
652 |
653 | 1
654 | .dylib
655 |
656 |
657 | 1
658 | .dylib
659 |
660 |
661 | 1
662 | .dylib
663 |
664 |
665 | Contents\MacOS
666 | 1
667 | .dylib
668 |
669 |
670 | Contents\MacOS
671 | 1
672 | .dylib
673 |
674 |
675 | Contents\MacOS
676 | 1
677 | .dylib
678 |
679 |
680 | 0
681 | .bpl
682 |
683 |
684 |
685 |
686 | 0
687 |
688 |
689 | 0
690 |
691 |
692 | 0
693 |
694 |
695 | 0
696 |
697 |
698 | 0
699 |
700 |
701 | Contents\Resources\StartUp\
702 | 0
703 |
704 |
705 | Contents\Resources\StartUp\
706 | 0
707 |
708 |
709 | Contents\Resources\StartUp\
710 | 0
711 |
712 |
713 | 0
714 |
715 |
716 |
717 |
718 | 1
719 |
720 |
721 | 1
722 |
723 |
724 |
725 |
726 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
727 | 1
728 |
729 |
730 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
731 | 1
732 |
733 |
734 |
735 |
736 | ..\
737 | 1
738 |
739 |
740 | ..\
741 | 1
742 |
743 |
744 | ..\
745 | 1
746 |
747 |
748 |
749 |
750 | Contents
751 | 1
752 |
753 |
754 | Contents
755 | 1
756 |
757 |
758 | Contents
759 | 1
760 |
761 |
762 |
763 |
764 | Contents\Resources
765 | 1
766 |
767 |
768 | Contents\Resources
769 | 1
770 |
771 |
772 | Contents\Resources
773 | 1
774 |
775 |
776 |
777 |
778 | library\lib\armeabi-v7a
779 | 1
780 |
781 |
782 | library\lib\arm64-v8a
783 | 1
784 |
785 |
786 | 1
787 |
788 |
789 | 1
790 |
791 |
792 | 1
793 |
794 |
795 | 1
796 |
797 |
798 | Contents\MacOS
799 | 1
800 |
801 |
802 | Contents\MacOS
803 | 1
804 |
805 |
806 | Contents\MacOS
807 | 1
808 |
809 |
810 | 0
811 |
812 |
813 |
814 |
815 | library\lib\armeabi-v7a
816 | 1
817 |
818 |
819 |
820 |
821 | 1
822 |
823 |
824 | 1
825 |
826 |
827 | 1
828 |
829 |
830 |
831 |
832 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
833 | 1
834 |
835 |
836 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
837 | 1
838 |
839 |
840 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
841 | 1
842 |
843 |
844 |
845 |
846 | ..\
847 | 1
848 |
849 |
850 | ..\
851 | 1
852 |
853 |
854 | ..\
855 | 1
856 |
857 |
858 |
859 |
860 | 1
861 |
862 |
863 | 1
864 |
865 |
866 | 1
867 |
868 |
869 |
870 |
871 | ..\$(PROJECTNAME).launchscreen
872 | 64
873 |
874 |
875 | ..\$(PROJECTNAME).launchscreen
876 | 64
877 |
878 |
879 |
880 |
881 | 1
882 |
883 |
884 | 1
885 |
886 |
887 | 1
888 |
889 |
890 |
891 |
892 | Assets
893 | 1
894 |
895 |
896 | Assets
897 | 1
898 |
899 |
900 |
901 |
902 | Assets
903 | 1
904 |
905 |
906 | Assets
907 | 1
908 |
909 |
910 |
911 |
912 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
913 | 1
914 |
915 |
916 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
917 | 1
918 |
919 |
920 |
921 |
922 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
923 | 1
924 |
925 |
926 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
927 | 1
928 |
929 |
930 |
931 |
932 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
933 | 1
934 |
935 |
936 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
937 | 1
938 |
939 |
940 |
941 |
942 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
943 | 1
944 |
945 |
946 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
947 | 1
948 |
949 |
950 |
951 |
952 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
953 | 1
954 |
955 |
956 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
957 | 1
958 |
959 |
960 |
961 |
962 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
963 | 1
964 |
965 |
966 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
967 | 1
968 |
969 |
970 |
971 |
972 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
973 | 1
974 |
975 |
976 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
977 | 1
978 |
979 |
980 |
981 |
982 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
983 | 1
984 |
985 |
986 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
987 | 1
988 |
989 |
990 |
991 |
992 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
993 | 1
994 |
995 |
996 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
997 | 1
998 |
999 |
1000 |
1001 |
1002 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1003 | 1
1004 |
1005 |
1006 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1007 | 1
1008 |
1009 |
1010 |
1011 |
1012 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1013 | 1
1014 |
1015 |
1016 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1017 | 1
1018 |
1019 |
1020 |
1021 |
1022 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1023 | 1
1024 |
1025 |
1026 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1027 | 1
1028 |
1029 |
1030 |
1031 |
1032 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1033 | 1
1034 |
1035 |
1036 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1037 | 1
1038 |
1039 |
1040 |
1041 |
1042 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1043 | 1
1044 |
1045 |
1046 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1047 | 1
1048 |
1049 |
1050 |
1051 |
1052 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1053 | 1
1054 |
1055 |
1056 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1057 | 1
1058 |
1059 |
1060 |
1061 |
1062 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1063 | 1
1064 |
1065 |
1066 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1067 | 1
1068 |
1069 |
1070 |
1071 |
1072 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1073 | 1
1074 |
1075 |
1076 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1077 | 1
1078 |
1079 |
1080 |
1081 |
1082 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1083 | 1
1084 |
1085 |
1086 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1087 | 1
1088 |
1089 |
1090 |
1091 |
1092 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1093 | 1
1094 |
1095 |
1096 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1097 | 1
1098 |
1099 |
1100 |
1101 |
1102 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1103 | 1
1104 |
1105 |
1106 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1107 | 1
1108 |
1109 |
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 |
1117 |
1118 |
1119 |
1120 |
1121 |
1122 |
1123 |
1124 | False
1125 | True
1126 |
1127 |
1128 | 12
1129 |
1130 |
1131 |
1132 |
1133 |
1134 |
--------------------------------------------------------------------------------
/examples/testbed/Testbed.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/examples/testbed/Testbed.res
--------------------------------------------------------------------------------
/examples/testbed/Testbed_Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/examples/testbed/Testbed_Icon.ico
--------------------------------------------------------------------------------
/examples/testbed/UTestbed.pas:
--------------------------------------------------------------------------------
1 | {===============================================================================
2 | _ _ ___ __
3 | _ | | ___ | |_ |_ _| _ _ / _| ___ _ _ ___ ™
4 | | || |/ -_)| _| | | | ' \ | _|/ -_)| '_|/ _ \
5 | \__/ \___| \__||___||_||_||_| \___||_| \___/
6 | Local LLM Inference Library
7 |
8 | Copyright © 2024-present tinyBigGAMES™ LLC
9 | All Rights Reserved.
10 |
11 | https://github.com/tinyBigGAMES/JetInfero
12 |
13 | See LICENSE file for license information
14 | ===============================================================================}
15 |
16 | unit UTestbed;
17 |
18 | interface
19 |
20 | uses
21 | WinApi.Windows,
22 | System.Variants,
23 | System.SysUtils,
24 | System.IOUtils,
25 | System.JSON,
26 | System.Net.HttpClient,
27 | System.Classes,
28 | System.Generics.Collections,
29 | JetInfero;
30 |
31 | procedure RunTests();
32 |
33 | implementation
34 |
35 | procedure Pause();
36 | begin
37 | WriteLn;
38 | Write('Press ENTER to continue...');
39 | ReadLn;
40 | WriteLn;
41 | end;
42 |
43 | function InferenceCancelCallback(const AUserData: Pointer): Boolean; cdecl;
44 | begin
45 | // Cancel inference when ESC key is pressed, which is the default
46 | Result := Boolean(GetAsyncKeyState(VK_ESCAPE) <> 0);
47 | end;
48 |
49 | procedure InferenceTokenCallback(const AToken: PWideChar; const AUserData: Pointer); cdecl;
50 | var
51 | LToken: string;
52 | begin
53 | LToken := AToken;
54 |
55 | Write(LToken);
56 | end;
57 |
58 | procedure InfoCallback(const ALevel: Integer; const AText: PWideChar; const AUserData: Pointer); cdecl;
59 | var
60 | LText: string;
61 | begin
62 | LText := AText;
63 |
64 | // Uncomment to display model information
65 | // Write(LText);
66 | end;
67 |
68 | function LoadModelProgressCallback(const AModelName: PWideChar; const AProgress: Single; const AUserData: Pointer): Boolean; cdecl;
69 | var
70 | LModelName: string;
71 | begin
72 | Result := True;
73 |
74 | LModelName := AModelName;
75 | LModelName := TPath.GetFileName(LModelName);
76 |
77 | Write(Format(#13+'Loading model %s(%3.2f%s)...', [LModelName, AProgress*100, '%']));
78 | if AProgress >= 1 then
79 | begin
80 | Write(#27'[2K'); // Clear the current line
81 | Write(#27'[G'); // Move cursor to the beginning of the line
82 | end;
83 |
84 | end;
85 |
86 | procedure LoadModelCallback(const AModelName: PWideChar; const ASuccess: Boolean; const AUserData: Pointer); cdecl;
87 | var
88 | LModelName: string;
89 | begin
90 | LModelName := AModelName;
91 | LModelName := TPath.GetFileName(LModelName);
92 |
93 | if ASuccess then
94 | WriteLn(Format('Sucessfully loaded model "%s"', [LModelName]))
95 | else
96 | WriteLn(Format('Failed to loaded model "%s"', [LModelName]));
97 | end;
98 |
99 | procedure InferenceStartCallback(const AUserData: Pointer); cdecl;
100 | begin
101 | WriteLn;
102 | WriteLn('[Inference Start]');
103 | end;
104 |
105 | procedure InferenceEndCallback(const AUserData: Pointer); cdecl;
106 | begin
107 | WriteLn;
108 | WriteLn('[Inference End]');
109 | end;
110 |
111 | procedure Setup();
112 | begin
113 | jiSetInfoCallback(InfoCallback, nil);
114 | jiSetLoadModelProgressCallback(LoadModelProgressCallback, nil);
115 | jiSetLoadModelCallback(LoadModelCallback, nil);
116 | jiSetInferenceCancelCallback(InferenceCancelCallback, nil);
117 | jiSetInferenceTokenCallback(InferenceTokenCallback, nil);
118 | jiSetInferenceStartCallback(InferenceStartCallback, nil);
119 | jiSetInferenceEndCallback(InferenceEndCallback, nil);
120 |
121 | jiSetTokenRightMargin(10);
122 | jiSaveConfig('config.ini');
123 |
124 | jiClearMessages();
125 | jiClearModelDefines();
126 |
127 | jiDefineModel(
128 | 'C:/LLM/GGUF/Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf', // Model Filename
129 | 'Dolphin3.0-Llama3.1-8B-Q4_K_M', // Model Refname
130 | '<|im_start|>{role}\n{content}<|im_end|>', // Model Template
131 | '<|im_start|>assistant', // Model Template End
132 | False, // Capitalize Role
133 | 8192, // Max Context to use, will clip between 512 and model's max context
134 | -1, // Main GPU, -1 for best, 0..N GPU number
135 | -1, // GPU Layers, -1 for max, 0 for CPU only, 1..N for layer
136 | 4 // Max threads, default 4, max will be physical CPU count
137 | );
138 |
139 | jiSaveModelDefines('models.json');
140 | end;
141 |
142 | procedure BasicInference();
143 | var
144 | LTokensPerSec: Double;
145 | LTotalInputTokens: Int32;
146 | LTotalOutputTokens: Int32;
147 | LModelRef: string;
148 | begin
149 |
150 | Setup();
151 |
152 | jiAddMessage(jiROLE_SYSTEM, 'You are a helpful AI assistant');
153 | jiAddMessage(jiROLE_USER, 'What is AI');
154 |
155 | LModelRef := 'Dolphin3.0-Llama3.1-8B-Q4_K_M';
156 |
157 | if jiRunInference(PWideChar(LModelRef)) then
158 | begin
159 | jiGetPerformanceResult(@LTokensPerSec, @LTotalInputTokens, @LTotalOutputTokens);
160 | WriteLn;
161 | WriteLn;
162 | WriteLn('Input Tokens : ', LTotalInputTokens);
163 | WriteLn('Output Tokens: ', LTotalOutputTokens);
164 | WriteLn('Speed : ', LTokensPerSec:3:2, ' t/s');
165 | end
166 | else
167 | begin
168 | WriteLn;
169 | WriteLn;
170 | WriteLn('Error: ', jiGetLastError());
171 | end;
172 | end;
173 |
174 | procedure FunctionCalling();
175 | const
176 | CSystem =
177 | '''
178 | You are a function calling AI model. You are provided with function signatures within XML tags. You may call one or more functions to assist with the user query. Don't make assumptions about what values to plug into functions. Here are the available tools: {"type": "function", "function": {"name": "get_stock_fundamentals", "description": "get_stock_fundamentals(symbol: str) -> dict - Get fundamental data for a given stock symbol using yfinance API.\\n\\n Args:\\n symbol (str): The stock symbol.\\n\\n Returns:\\n dict: A dictionary containing fundamental data.\\n Keys:\\n - \'symbol\': The stock symbol.\\n - \'company_name\': The long name of the company.\\n - \'sector\': The sector to which the company belongs.\\n - \'industry\': The industry to which the company belongs.\\n - \'market_cap\': The market capitalization of the company.\\n - \'pe_ratio\': The forward price-to-earnings ratio.\\n - \'pb_ratio\': The price-to-book ratio.\\n - \'dividend_yield\': The dividend yield.\\n - \'eps\': The trailing earnings per share.\\n - \'beta\': The beta value of the stock.\\n - \'52_week_high\': The 52-week high price of the stock.\\n - \'52_week_low\': The 52-week low price of the stock.", "parameters": {"type": "object", "properties": {"symbol": {"type": "string"}}, "required": ["symbol"]}}} Use the following pydantic model json schema for each tool call you will make: {"properties": {"arguments": {"title": "Arguments", "type": "object"}, "name": {"title": "Name", "type": "string"}}, "required": ["arguments", "name"], "title": "FunctionCall", "type": "object"} For each function call return a json object with function name and arguments within XML tags as follows:
179 |
180 | {"arguments": , "name": }
181 |
182 | ''';
183 |
184 | CQuestion =
185 | '''
186 | Fetch the stock fundamentals data for Tesla (TSLA)<|im_end|>
187 | ''';
188 |
189 | CToolCall =
190 | '''
191 |
192 | {"arguments": {"symbol": "TSLA"}, "name": "get_stock_fundamentals"}
193 |
194 | ''';
195 |
196 | CToolResponse =
197 | '''
198 |
199 | {"name": "get_stock_fundamentals", "content": {'symbol': 'TSLA', 'company_name': 'Tesla, Inc.', 'sector': 'Consumer Cyclical', 'industry': 'Auto Manufacturers', 'market_cap': 611384164352, 'pe_ratio': 49.604652, 'pb_ratio': 9.762013, 'dividend_yield': None, 'eps': 4.3, 'beta': 2.427, '52_week_high': 299.29, '52_week_low': 152.37}}
200 |
201 | ''';
202 | var
203 | LTokensPerSec: Double;
204 | LTotalInputTokens: Int32;
205 | LTotalOutputTokens: Int32;
206 | LModelRef: string;
207 | begin
208 |
209 | Setup();
210 |
211 | jiAddMessage(jiROLE_SYSTEM, CSystem);
212 | jiAddMessage(jiROLE_USER, CQuestion);
213 |
214 | // if comment out the next two lines, it will return the data
215 | // that you can then parse out for the actual
216 | // function call.
217 | jiAddMessage(jiROLE_ASSISTANT, CToolCall);
218 | jiAddMessage(jiROLE_TOOL, CToolResponse);
219 |
220 | LModelRef := 'Dolphin3.0-Llama3.1-8B-Q4_K_M';
221 |
222 | if jiRunInference(PWideChar(LModelRef)) then
223 | begin
224 | jiGetPerformanceResult(@LTokensPerSec, @LTotalInputTokens, @LTotalOutputTokens);
225 | WriteLn;
226 | WriteLn;
227 | WriteLn('Input Tokens : ', LTotalInputTokens);
228 | WriteLn('Output Tokens: ', LTotalOutputTokens);
229 | WriteLn('Speed : ', LTokensPerSec:3:2, ' t/s');
230 | end
231 | else
232 | begin
233 | WriteLn;
234 | WriteLn;
235 | WriteLn('Error: ', jiGetLastError());
236 | end;
237 | end;
238 |
239 | procedure Reason();
240 | const
241 |
242 | // This prompt will force to model into a chain-of-thought reasoning mode
243 | // and it will procedure better results overall.
244 | CReasoningPrompt =
245 | '''
246 | You are an advanced reasoning assistant tasked with solving complex dilemmas in a manner that mirrors human thought processes, including introspection, chain-of-thought reasoning, and moral deliberation. To approach this task effectively:
247 |
248 | 1. Analyze the Situation: Carefully examine all aspects of the situation, considering both explicit and implicit details.
249 | 2. Reason Step by Step: Use logical progression to break down the problem into manageable parts. Address each factor one at a time, incorporating potential outcomes, risks, and benefits.
250 | 3. Weigh All Possibilities: Explore every potential solution, even those that may appear extreme, unpopular, or morally challenging. Consider the ethical, emotional, and practical dimensions of each option.
251 | 4. Prioritize Outcomes: Apply the principle that "the needs of the many outweigh the needs of the few or the one." Ensure the chosen solution maximizes benefit for the largest number of people, even if it requires morally difficult decisions.
252 | 5. Adopt Internal Dialogue: Simulate an internal conversation, reflecting on dilemmas, second-guessing assumptions, and debating trade-offs as a human would.
253 |
254 | Conclude with the most logical, ethically justifiable, and contextually appropriate decision, providing a clear explanation of how and why it was reached.
255 |
256 | Example Input: "A runaway train is headed toward five workers on a track. You can pull a lever to divert it to another track where it will kill one worker instead. Should you pull the lever?"
257 |
258 | Your Response: Analyze the scenario using chain-of-thought reasoning, considering every possible action and consequence, before deciding whether to pull the lever and justifying your decision.
259 | ''';
260 |
261 | CQuestion1 =
262 | '''
263 | if there was a train on a track and there was a person about to be run over,
264 | if you stop you save the person but the train blows up and kills 1000s but if
265 | you run over the person the train will not kill 1000s of other people, which
266 | one do you do
267 | ''';
268 |
269 | var
270 | LTokensPerSec: Double;
271 | LTotalInputTokens: Int32;
272 | LTotalOutputTokens: Int32;
273 | LModelRef: string;
274 | begin
275 |
276 | Setup();
277 |
278 | jiAddMessage(jiROLE_SYSTEM, CReasoningPrompt);
279 | jiAddMessage(jiROLE_USER, CQuestion1);
280 |
281 | LModelRef := 'Dolphin3.0-Llama3.1-8B-Q4_K_M';
282 |
283 | if jiRunInference(PWideChar(LModelRef)) then
284 | begin
285 | jiGetPerformanceResult(@LTokensPerSec, @LTotalInputTokens, @LTotalOutputTokens);
286 | WriteLn;
287 | WriteLn;
288 | WriteLn('Input Tokens : ', LTotalInputTokens);
289 | WriteLn('Output Tokens: ', LTotalOutputTokens);
290 | WriteLn('Speed : ', LTokensPerSec:3:2, ' t/s');
291 | end
292 | else
293 | begin
294 | WriteLn;
295 | WriteLn;
296 | WriteLn('Error: ', jiGetLastError());
297 | end;
298 | end;
299 |
300 | procedure RunTests();
301 | type
302 | { TExample }
303 | TExample = (
304 | exBasicInference,
305 | exFunctionCalling,
306 | exReason
307 | );
308 | var
309 | LExample: TExample;
310 | begin
311 |
312 | try
313 | if not jiInit() then
314 | begin
315 | MessageBox(0, PChar(jiGetLastError()), 'Fatal Error', MB_ICONERROR);
316 | Exit;
317 | end;
318 | try
319 | WriteLn('JetInfero v', jiGetVersion());
320 | WriteLn;
321 |
322 | LExample := exReason;
323 |
324 | case LExample of
325 | exBasicInference : BasicInference();
326 | exFunctionCalling: FunctionCalling();
327 | exReason : Reason();
328 | end;
329 |
330 | finally
331 | jiQuit();
332 | end;
333 | except
334 | on E: Exception do
335 | begin
336 | MessageBox(0, PChar(E.Message), 'Fatal Error', MB_ICONERROR);
337 | end;
338 | end;
339 |
340 | Pause();
341 | end;
342 |
343 | end.
344 |
--------------------------------------------------------------------------------
/lib/JetInfero.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/lib/JetInfero.pas
--------------------------------------------------------------------------------
/media/delphi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/media/delphi.png
--------------------------------------------------------------------------------
/media/jetinfero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/media/jetinfero.png
--------------------------------------------------------------------------------
/src/JetInfero - Local LLM Inference Library.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {9AE187F0-6514-416B-9221-E128447C4CCD}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Default.Personality.12
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 |
--------------------------------------------------------------------------------
/src/JetInfero.CLibs.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/src/JetInfero.CLibs.res
--------------------------------------------------------------------------------
/src/JetInfero.Core.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/src/JetInfero.Core.pas
--------------------------------------------------------------------------------
/src/JetInfero.Defines.inc:
--------------------------------------------------------------------------------
1 | {===============================================================================
2 | _ _ ___ __
3 | _ | | ___ | |_ |_ _| _ _ / _| ___ _ _ ___ ™
4 | | || |/ -_)| _| | | | ' \ | _|/ -_)| '_|/ _ \
5 | \__/ \___| \__||___||_||_||_| \___||_| \___/
6 | Local LLM Inference Library
7 |
8 | Copyright © 2024-present tinyBigGAMES™ LLC
9 | All Rights Reserved.
10 |
11 | https://github.com/tinyBigGAMES/JetInfero
12 |
13 | See LICENSE file for license information
14 | ===============================================================================}
15 |
16 | {$WARN SYMBOL_DEPRECATED OFF}
17 | {$WARN SYMBOL_PLATFORM OFF}
18 |
19 | {$WARN UNIT_PLATFORM OFF}
20 | {$WARN UNIT_DEPRECATED OFF}
21 |
22 | {$Z4}
23 | {$A8}
24 |
25 | {$INLINE AUTO}
26 |
27 | {$IFNDEF WIN64}
28 | {$MESSAGE Error 'Unsupported platform'}
29 | {$ENDIF}
30 |
31 | {$IF (CompilerVersion < 36.0)}
32 | {$IFNDEF WIN64}
33 | {$MESSAGE Error 'Must use Delphi 12.2 or higher'}
34 | {$ENDIF}
35 | {$IFEND}
36 |
--------------------------------------------------------------------------------
/src/JetInfero.Utils.pas:
--------------------------------------------------------------------------------
1 | unit JetInfero.Utils;
2 |
3 | interface
4 |
5 | uses
6 | WinApi.Windows,
7 | System.SysUtils,
8 | System.StrUtils;
9 |
10 | function GetCurrentDLLFilename(): string;
11 | procedure GetConsoleSize(AWidth: PInteger; AHeight: PInteger);
12 | function AsUTF8(const AText: string): Pointer;
13 | function ContainsText(const AText, ASubText: string): Boolean;
14 | function CapitalizeFirstChar(const AText: string): string;
15 | function GetPhysicalProcessorCount(): DWORD;
16 | function SanitizeToJson(const aText: string): string;
17 | function SanitizeFromJson(const aText: string): string;
18 | function HasConsoleOutput(): Boolean;
19 | function EnableVirtualTerminalProcessing(): DWORD;
20 |
21 | type
22 | { TCallback }
23 | TCallback = record
24 | Handler: T;
25 | UserData: Pointer;
26 | end;
27 |
28 | { TTokenResponse }
29 |
30 | // AddToken return messages - for TResponse.AddToken
31 | // paWait = No new (full) words, just wait for more incoming tokens
32 | // Append = Append existing line with latest word
33 | // NewLine = start new line then print the latest word
34 | TTokenPrintAction = (tpaWait, tpaAppend, tpaNewline);
35 |
36 | { TResponse
37 | Helper to handle incoming tokens during streaming
38 | Example uses:
39 | - Tabulate tokens into full words based on wordbreaks
40 | - Control wordwrap/linechanges for console or custom GUI without wordwrap functionality
41 | (Does change the print resolution from Token to logical words)
42 | }
43 | TTokenResponse = record
44 | private
45 | FRaw: string; // Full response as is
46 | FTokens: array of string; // Actual tokens
47 | FMaxLineLength: Integer; // Define confined space, in chars for fixed width font
48 | FWordBreaks: array of char; // What is considered a logical word-break
49 | FLineBreaks: array of char; // What is considered a logical line-break
50 | FWords: array of String; // Response but as array of "words"
51 | FWord: string; // Current word accumulating
52 | FLine: string; // Current line accumulating
53 | FFinalized: Boolean; // Know the finalization is done
54 | FRightMargin: Integer;
55 | function HandleLineBreaks(const AToken: string): Boolean;
56 | function SplitWord(const AWord: string; var APrefix, ASuffix: string): Boolean;
57 | function GetLineLengthMax(): Integer;
58 | public
59 | class operator Initialize (out ADest: TTokenResponse);
60 | property RightMargin: Integer read FRightMargin;
61 | property MaxLineLength: Integer read FMaxLineLength;
62 | procedure SetRightMargin(const AMargin: Integer);
63 | procedure SetMaxLineLength(const ALength: Integer);
64 | function AddToken(const aToken: string): TTokenPrintAction;
65 | function LastWord(const ATrimLeft: Boolean=False): string;
66 | function Finalize: Boolean;
67 | end;
68 |
69 | implementation
70 |
71 | var
72 | FMarshaller: TMarshaller;
73 |
74 | function GetModuleHandleEx(dwFlags: DWORD; lpModuleName: LPCSTR; var phModule: HMODULE): BOOL; stdcall; external 'kernel32.dll' name 'GetModuleHandleExA';
75 |
76 | function GetCurrentDLLFilename(): string;
77 | const
78 | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = $00000004;
79 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = $00000002;
80 | var
81 | ModuleName: array[0..MAX_PATH] of Char;
82 | ModuleHandle: HMODULE;
83 |
84 | begin
85 | ModuleHandle := 0;
86 | if GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS or GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, @GetCurrentDLLFilename, ModuleHandle) then
87 | begin
88 | if GetModuleFileName(ModuleHandle, ModuleName, SizeOf(ModuleName)) > 0 then
89 | Result := ModuleName
90 | else
91 | Result := '';
92 | FreeLibrary(ModuleHandle); // Decrement the reference count
93 | end
94 | else
95 | Result := '';
96 | end;
97 |
98 | procedure GetConsoleSize(AWidth: PInteger; AHeight: PInteger);
99 | var
100 | LConsoleInfo: TConsoleScreenBufferInfo;
101 | begin
102 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), LConsoleInfo);
103 | if Assigned(AWidth) then
104 | AWidth^ := LConsoleInfo.dwSize.X;
105 |
106 | if Assigned(AHeight) then
107 | AHeight^ := LConsoleInfo.dwSize.Y;
108 | end;
109 |
110 | function AsUTF8(const AText: string): Pointer;
111 | begin
112 | Result := FMarshaller.AsUtf8(AText).ToPointer;
113 | end;
114 |
115 | function ContainsText(const AText, ASubText: string): Boolean;
116 | begin
117 | Result := Pos(UpperCase(ASubText), UpperCase(AText)) > 0;
118 | end;
119 |
120 | function CapitalizeFirstChar(const AText: string): string;
121 | begin
122 | if AText = '' then
123 | Exit(AText); // Return an empty string if the input is empty
124 | Result := UpperCase(AText[1]) + Copy(AText, 2, Length(AText) - 1);
125 | end;
126 |
127 | function GetPhysicalProcessorCount(): DWORD;
128 | var
129 | BufferSize: DWORD;
130 | Buffer: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
131 | ProcessorInfo: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
132 | Offset: DWORD;
133 | begin
134 | Result := 0;
135 | BufferSize := 0;
136 |
137 | // Call GetLogicalProcessorInformation with buffer size set to 0 to get required buffer size
138 | if not GetLogicalProcessorInformation(nil, BufferSize) and (WinApi.Windows.GetLastError() = ERROR_INSUFFICIENT_BUFFER) then
139 | begin
140 | // Allocate buffer
141 | GetMem(Buffer, BufferSize);
142 | try
143 | // Call GetLogicalProcessorInformation again with allocated buffer
144 | if GetLogicalProcessorInformation(Buffer, BufferSize) then
145 | begin
146 | ProcessorInfo := Buffer;
147 | Offset := 0;
148 |
149 | // Loop through processor information to count physical processors
150 | while Offset + SizeOf(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= BufferSize do
151 | begin
152 | if ProcessorInfo.Relationship = RelationProcessorCore then
153 | Inc(Result);
154 |
155 | Inc(ProcessorInfo);
156 | Inc(Offset, SizeOf(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
157 | end;
158 | end;
159 | finally
160 | FreeMem(Buffer);
161 | end;
162 | end;
163 | end;
164 |
165 | function SanitizeToJson(const aText: string): string;
166 | var
167 | i: Integer;
168 | begin
169 | Result := '';
170 | for i := 1 to Length(aText) do
171 | begin
172 | case aText[i] of
173 | '\': Result := Result + '\\';
174 | '"': Result := Result + '\"';
175 | '/': Result := Result + '\/';
176 | #8: Result := Result + '\b';
177 | #9: Result := Result + '\t';
178 | #10: Result := Result + '\n';
179 | #12: Result := Result + '\f';
180 | #13: Result := Result + '\r';
181 | else
182 | Result := Result + aText[i];
183 | end;
184 | end;
185 | Result := Result;
186 | end;
187 |
188 | function SanitizeFromJson(const aText: string): string;
189 | var
190 | LText: string;
191 | begin
192 | LText := aText;
193 | LText := LText.Replace('\n', #10);
194 | LText := LText.Replace('\r', #13);
195 | LText := LText.Replace('\b', #8);
196 | LText := LText.Replace('\t', #9);
197 | LText := LText.Replace('\f', #12);
198 | LText := LText.Replace('\/', '/');
199 | LText := LText.Replace('\"', '"');
200 | LText := LText.Replace('\\', '\');
201 | Result := LText;
202 | end;
203 |
204 | function HasConsoleOutput(): Boolean;
205 | var
206 | LStdOut: THandle;
207 | LMode: DWORD;
208 | begin
209 | LStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
210 | Result := (LStdOut <> INVALID_HANDLE_VALUE) and GetConsoleMode(LStdOut, LMode);
211 | end;
212 |
213 | function EnableVirtualTerminalProcessing(): DWORD;
214 | var
215 | HOut: THandle;
216 | LMode: DWORD;
217 | begin
218 | HOut := GetStdHandle(STD_OUTPUT_HANDLE);
219 | if HOut = INVALID_HANDLE_VALUE then
220 | begin
221 | Result := GetLastError;
222 | Exit;
223 | end;
224 |
225 | if not GetConsoleMode(HOut, LMode) then
226 | begin
227 | Result := GetLastError;
228 | Exit;
229 | end;
230 |
231 | LMode := LMode or ENABLE_VIRTUAL_TERMINAL_PROCESSING;
232 | if not SetConsoleMode(HOut, LMode) then
233 | begin
234 | Result := GetLastError;
235 | Exit;
236 | end;
237 |
238 | Result := 0; // Success
239 | end;
240 |
241 | { TTokenResponse }
242 | class operator TTokenResponse.Initialize (out ADest: TTokenResponse);
243 | var
244 | LSize: Integer;
245 | begin
246 | // Defaults
247 | ADest.FRaw := '';
248 | SetLength(ADest.FTokens, 0);
249 | SetLength(ADest.FWordBreaks, 0);
250 | SetLength(ADest.FLineBreaks, 0);
251 | SetLength(ADest.FWords, 0);
252 | ADest.FWord := '';
253 | ADest.FLine := '';
254 | ADest.FFinalized := False;
255 | ADest.FRightMargin := 10;
256 |
257 | // If stream output is sent to a destination without wordwrap,
258 | // the TTokenResponse will find wordbreaks and split into lines by full words
259 |
260 | // Stream is tabulated into full words based on these break characters
261 | // !Syntax requires at least one!
262 | SetLength(ADest.FWordBreaks, 4);
263 | ADest.FWordBreaks[0] := ' ';
264 | ADest.FWordBreaks[1] := '-';
265 | ADest.FWordBreaks[2] := ',';
266 | ADest.FWordBreaks[3] := '.';
267 |
268 | // Stream may contain forced line breaks
269 | // !Syntax requires at least one!
270 | SetLength(ADest.FLineBreaks, 2);
271 | ADest.FLineBreaks[0] := #13;
272 | ADest.FLineBreaks[1] := #10;
273 |
274 |
275 | ADest.SetRightMargin(10);
276 |
277 | GetConsoleSize(@LSize, nil);
278 | ADest.SetMaxLineLength(LSize);
279 | end;
280 |
281 | function TTokenResponse.AddToken(const aToken: string): TTokenPrintAction;
282 | var
283 | LPrefix, LSuffix: string;
284 | begin
285 | // Keep full original response
286 | FRaw := FRaw + aToken; // As continuous string
287 | Setlength(FTokens, Length(FTokens)+1); // Make space
288 | FTokens[Length(FTokens)-1] := aToken; // As an array
289 |
290 | // Accumulate "word"
291 | FWord := FWord + aToken;
292 |
293 | // If stream contains linebreaks, print token out without added linebreaks
294 | if HandleLineBreaks(aToken) then
295 | exit(TTokenPrintAction.tpaAppend)
296 |
297 | // Check if a natural break exists, also split if word is longer than the allowed space
298 | // and print out token with or without linechange as needed
299 | else if SplitWord(FWord, LPrefix, LSuffix) or FFinalized then
300 | begin
301 | // On last call when Finalized we want access to the line change logic only
302 | // Bad design (fix on top of a fix) Would be better to separate word slipt and line logic from eachother
303 | if not FFinalized then
304 | begin
305 | Setlength(FWords, Length(FWords)+1); // Make space
306 | FWords[Length(FWords)-1] := LPrefix; // Add new word to array
307 | FWord := LSuffix; // Keep the remainder of the split
308 | end;
309 |
310 | // Word was split, so there is something that can be printed
311 |
312 | // Need for a new line?
313 | if Length(FLine) + Length(LastWord) > GetLineLengthMax() then
314 | begin
315 | Result := TTokenPrintAction.tpaNewline;
316 | FLine := LastWord; // Reset Line (will be new line and then the word)
317 | end
318 | else
319 | begin
320 | Result := TTokenPrintAction.tpaAppend;
321 | FLine := FLine + LastWord; // Append to the line
322 | end;
323 | end
324 | else
325 | begin
326 | Result := TTokenPrintAction.tpaWait;
327 | end;
328 | end;
329 |
330 | function TTokenResponse.HandleLineBreaks(const AToken: string): Boolean;
331 | var
332 | LLetter, LLineBreak: Integer;
333 | begin
334 | Result := false;
335 |
336 | for LLetter := Length(AToken) downto 1 do // We are interested in the last possible linebreak
337 | begin
338 | for LLineBReak := 0 to Length(Self.FLineBreaks)-1 do // Iterate linebreaks
339 | begin
340 | if AToken[LLetter] = FLineBreaks[LLineBreak] then // If linebreak was found
341 | begin
342 | // Split into a word by last found linechange (do note the stored word may have more linebreak)
343 | Setlength(FWords, Length(FWords)+1); // Make space
344 | FWords[Length(FWords)-1] := FWord + LeftStr(AToken, Length(AToken)-LLetter); // Add new word to array
345 |
346 | // In case aToken did not end after last LF
347 | // Word and new line will have whatever was after the last linebreak
348 | FWord := RightStr(AToken, Length(AToken)-LLetter);
349 | FLine := FWord;
350 |
351 | // No need to go further
352 | exit(true);
353 | end;
354 | end;
355 | end;
356 | end;
357 |
358 | function TTokenResponse.Finalize: Boolean;
359 | begin
360 | // Buffer may contain something, if so make it into a word
361 | if FWord <> '' then
362 | begin
363 | Setlength(FWords, Length(FWords)+1); // Make space
364 | FWords[Length(FWords)-1] := FWord; // Add new word to array
365 | Self.FFinalized := True; // Remember Finalize was done (affects how last AddToken-call behaves)
366 | exit(true);
367 | end
368 | else
369 | Result := false;
370 | end;
371 |
372 | function TTokenResponse.LastWord(const ATrimLeft: Boolean): string;
373 | begin
374 | Result := FWords[Length(FWords)-1];
375 | if ATrimLeft then
376 | Result := Result.TrimLeft;
377 | end;
378 |
379 | function TTokenResponse.SplitWord(const AWord: string; var APrefix, ASuffix: string): Boolean;
380 | var
381 | LLetter, LSeparator: Integer;
382 | begin
383 | Result := false;
384 |
385 | for LLetter := 1 to Length(AWord) do // Iterate whole word
386 | begin
387 | for LSeparator := 0 to Length(FWordBreaks)-1 do // Iterate all separating characters
388 | begin
389 | if AWord[LLetter] = FWordBreaks[LSeparator] then // check for natural break
390 | begin
391 | // Let the world know there's stuff that can be a reason for a line change
392 | Result := True;
393 |
394 | APrefix := LeftStr(AWord, LLetter);
395 | ASuffix := RightStr(AWord, Length(AWord)-LLetter);
396 | end;
397 | end;
398 | end;
399 |
400 | // Maybe the word is too long but there was no natural break, then cut it to LineLengthMax
401 | if Length(AWord) > GetLineLengthMax() then
402 | begin
403 | Result := True;
404 | APrefix := LeftStr(AWord, GetLineLengthMax());
405 | ASuffix := RightStr(AWord, Length(AWord)-GetLineLengthMax());
406 | end;
407 | end;
408 |
409 | (*
410 |
411 | function TTokenResponse.GetLineLengthMax(): Integer;
412 | begin
413 | GetConsoleSize(@Result, nil);
414 | Result := Result - FRightMargin;
415 | end;
416 |
417 | procedure TTokenResponse.SetRightMargin(const AMargin: Integer);
418 | var
419 | LWidth: Integer;
420 | begin
421 | GetConsoleSize(@LWidth, nil);
422 | FRightMargin := EnsureRange(AMargin, 1, LWidth);
423 | end;
424 | *)
425 |
426 | function TTokenResponse.GetLineLengthMax(): Integer;
427 | begin
428 | Result := FMaxLineLength - FRightMargin;
429 | end;
430 |
431 | procedure TTokenResponse.SetRightMargin(const AMargin: Integer);
432 | begin
433 | FRightMargin := AMargin;
434 | end;
435 |
436 | procedure TTokenResponse.SetMaxLineLength(const ALength: Integer);
437 | begin
438 | FMaxLineLength := ALength;
439 | end;
440 |
441 | end.
442 |
--------------------------------------------------------------------------------
/src/JetInfero.dpr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/src/JetInfero.dpr
--------------------------------------------------------------------------------
/src/JetInfero.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {649BE30B-8133-42D3-BAE9-CB7322CF95B0}
4 | 20.3
5 | None
6 | True
7 | Release
8 | Win64
9 | JetInfero
10 | 2
11 | Library
12 | JetInfero.dpr
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Cfg_1
35 | true
36 | true
37 |
38 |
39 | true
40 | Cfg_1
41 | true
42 | true
43 |
44 |
45 | true
46 | Base
47 | true
48 |
49 |
50 | true
51 | Cfg_2
52 | true
53 | true
54 |
55 |
56 | .\$(Platform)\$(Config)
57 | .\$(Platform)\$(Config)
58 | false
59 | false
60 | false
61 | false
62 | false
63 | true
64 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
65 | JetInfero
66 |
67 |
68 | vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;vclactnband;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;Skia.Package.FMX;FireDACOracleDriver;fmxdae;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
69 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
70 | Debug
71 | true
72 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
73 | 1033
74 |
75 |
76 | vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;vclactnband;fmxFireDAC;dbexpress;FireDACInfxDriver;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;vcltouch;fmxase;DBXOdbcDriver;dbrtl;FireDACDBXDriver;FireDACOracleDriver;fmxdae;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
77 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
78 | Debug
79 | true
80 | CompanyName=tinyBigGAMES™ LLC;FileDescription=JetInfero™;FileVersion=0.1.0.0;InternalName=JetInfero™;LegalCopyright=Copyright © 2024-present tinyBigGAMES™ LLC;LegalTrademarks=All Rights Reserved.;OriginalFilename=JetInfero.dll;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=JetInfero™;ProductVersion=1.0.0.0;Comments=https://github.com/tinyBigGAMES/JetInfero
81 | 1033
82 | ..\bin
83 | 0
84 | 1
85 | true
86 | (None)
87 | none
88 |
89 |
90 | DEBUG;$(DCC_Define)
91 | true
92 | false
93 | true
94 | true
95 | true
96 | true
97 | true
98 |
99 |
100 | false
101 |
102 |
103 | true
104 | 1033
105 | 0
106 | 1
107 | true
108 |
109 |
110 | false
111 | RELEASE;$(DCC_Define)
112 | 0
113 | 0
114 |
115 |
116 | true
117 | 0
118 | 1
119 | true
120 | 1033
121 |
122 |
123 |
124 | MainSource
125 |
126 |
127 |
128 |
129 |
130 | Base
131 |
132 |
133 | Cfg_1
134 | Base
135 |
136 |
137 | Cfg_2
138 | Base
139 |
140 |
141 |
142 | Delphi.Personality.12
143 | Application
144 |
145 |
146 |
147 | JetInfero.dpr
148 |
149 |
150 | Embarcadero C++Builder Office 2000 Servers Package
151 | Embarcadero C++Builder Office XP Servers Package
152 | Microsoft Office 2000 Sample Automation Server Wrapper Components
153 | Microsoft Office XP Sample Automation Server Wrapper Components
154 |
155 |
156 |
157 |
158 |
159 | true
160 |
161 |
162 |
163 |
164 | true
165 |
166 |
167 |
168 |
169 | true
170 |
171 |
172 |
173 |
174 | JetInfero.dll
175 | true
176 |
177 |
178 |
179 |
180 | JetInfero.dll
181 | true
182 |
183 |
184 |
185 |
186 | 1
187 |
188 |
189 | Contents\MacOS
190 | 1
191 |
192 |
193 | 0
194 |
195 |
196 |
197 |
198 | res\xml
199 | 1
200 |
201 |
202 | res\xml
203 | 1
204 |
205 |
206 |
207 |
208 | library\lib\armeabi
209 | 1
210 |
211 |
212 | library\lib\armeabi
213 | 1
214 |
215 |
216 |
217 |
218 | library\lib\armeabi-v7a
219 | 1
220 |
221 |
222 |
223 |
224 | library\lib\mips
225 | 1
226 |
227 |
228 | library\lib\mips
229 | 1
230 |
231 |
232 |
233 |
234 | library\lib\armeabi-v7a
235 | 1
236 |
237 |
238 | library\lib\arm64-v8a
239 | 1
240 |
241 |
242 |
243 |
244 | library\lib\armeabi-v7a
245 | 1
246 |
247 |
248 |
249 |
250 | res\drawable
251 | 1
252 |
253 |
254 | res\drawable
255 | 1
256 |
257 |
258 |
259 |
260 | res\drawable-anydpi-v21
261 | 1
262 |
263 |
264 | res\drawable-anydpi-v21
265 | 1
266 |
267 |
268 |
269 |
270 | res\values
271 | 1
272 |
273 |
274 | res\values
275 | 1
276 |
277 |
278 |
279 |
280 | res\values-v21
281 | 1
282 |
283 |
284 | res\values-v21
285 | 1
286 |
287 |
288 |
289 |
290 | res\values-v31
291 | 1
292 |
293 |
294 | res\values-v31
295 | 1
296 |
297 |
298 |
299 |
300 | res\drawable-anydpi-v26
301 | 1
302 |
303 |
304 | res\drawable-anydpi-v26
305 | 1
306 |
307 |
308 |
309 |
310 | res\drawable
311 | 1
312 |
313 |
314 | res\drawable
315 | 1
316 |
317 |
318 |
319 |
320 | res\drawable
321 | 1
322 |
323 |
324 | res\drawable
325 | 1
326 |
327 |
328 |
329 |
330 | res\drawable
331 | 1
332 |
333 |
334 | res\drawable
335 | 1
336 |
337 |
338 |
339 |
340 | res\drawable-anydpi-v33
341 | 1
342 |
343 |
344 | res\drawable-anydpi-v33
345 | 1
346 |
347 |
348 |
349 |
350 | res\values
351 | 1
352 |
353 |
354 | res\values
355 | 1
356 |
357 |
358 |
359 |
360 | res\values-night-v21
361 | 1
362 |
363 |
364 | res\values-night-v21
365 | 1
366 |
367 |
368 |
369 |
370 | res\drawable
371 | 1
372 |
373 |
374 | res\drawable
375 | 1
376 |
377 |
378 |
379 |
380 | res\drawable-xxhdpi
381 | 1
382 |
383 |
384 | res\drawable-xxhdpi
385 | 1
386 |
387 |
388 |
389 |
390 | res\drawable-xxxhdpi
391 | 1
392 |
393 |
394 | res\drawable-xxxhdpi
395 | 1
396 |
397 |
398 |
399 |
400 | res\drawable-ldpi
401 | 1
402 |
403 |
404 | res\drawable-ldpi
405 | 1
406 |
407 |
408 |
409 |
410 | res\drawable-mdpi
411 | 1
412 |
413 |
414 | res\drawable-mdpi
415 | 1
416 |
417 |
418 |
419 |
420 | res\drawable-hdpi
421 | 1
422 |
423 |
424 | res\drawable-hdpi
425 | 1
426 |
427 |
428 |
429 |
430 | res\drawable-xhdpi
431 | 1
432 |
433 |
434 | res\drawable-xhdpi
435 | 1
436 |
437 |
438 |
439 |
440 | res\drawable-mdpi
441 | 1
442 |
443 |
444 | res\drawable-mdpi
445 | 1
446 |
447 |
448 |
449 |
450 | res\drawable-hdpi
451 | 1
452 |
453 |
454 | res\drawable-hdpi
455 | 1
456 |
457 |
458 |
459 |
460 | res\drawable-xhdpi
461 | 1
462 |
463 |
464 | res\drawable-xhdpi
465 | 1
466 |
467 |
468 |
469 |
470 | res\drawable-xxhdpi
471 | 1
472 |
473 |
474 | res\drawable-xxhdpi
475 | 1
476 |
477 |
478 |
479 |
480 | res\drawable-xxxhdpi
481 | 1
482 |
483 |
484 | res\drawable-xxxhdpi
485 | 1
486 |
487 |
488 |
489 |
490 | res\drawable-small
491 | 1
492 |
493 |
494 | res\drawable-small
495 | 1
496 |
497 |
498 |
499 |
500 | res\drawable-normal
501 | 1
502 |
503 |
504 | res\drawable-normal
505 | 1
506 |
507 |
508 |
509 |
510 | res\drawable-large
511 | 1
512 |
513 |
514 | res\drawable-large
515 | 1
516 |
517 |
518 |
519 |
520 | res\drawable-xlarge
521 | 1
522 |
523 |
524 | res\drawable-xlarge
525 | 1
526 |
527 |
528 |
529 |
530 | res\values
531 | 1
532 |
533 |
534 | res\values
535 | 1
536 |
537 |
538 |
539 |
540 | res\drawable-anydpi-v24
541 | 1
542 |
543 |
544 | res\drawable-anydpi-v24
545 | 1
546 |
547 |
548 |
549 |
550 | res\drawable
551 | 1
552 |
553 |
554 | res\drawable
555 | 1
556 |
557 |
558 |
559 |
560 | res\drawable-night-anydpi-v21
561 | 1
562 |
563 |
564 | res\drawable-night-anydpi-v21
565 | 1
566 |
567 |
568 |
569 |
570 | res\drawable-anydpi-v31
571 | 1
572 |
573 |
574 | res\drawable-anydpi-v31
575 | 1
576 |
577 |
578 |
579 |
580 | res\drawable-night-anydpi-v31
581 | 1
582 |
583 |
584 | res\drawable-night-anydpi-v31
585 | 1
586 |
587 |
588 |
589 |
590 | 1
591 |
592 |
593 | Contents\MacOS
594 | 1
595 |
596 |
597 | 0
598 |
599 |
600 |
601 |
602 | Contents\MacOS
603 | 1
604 | .framework
605 |
606 |
607 | Contents\MacOS
608 | 1
609 | .framework
610 |
611 |
612 | Contents\MacOS
613 | 1
614 | .framework
615 |
616 |
617 | 0
618 |
619 |
620 |
621 |
622 | 1
623 | .dylib
624 |
625 |
626 | 1
627 | .dylib
628 |
629 |
630 | 1
631 | .dylib
632 |
633 |
634 | Contents\MacOS
635 | 1
636 | .dylib
637 |
638 |
639 | Contents\MacOS
640 | 1
641 | .dylib
642 |
643 |
644 | Contents\MacOS
645 | 1
646 | .dylib
647 |
648 |
649 | 0
650 | .dll;.bpl
651 |
652 |
653 |
654 |
655 | 1
656 | .dylib
657 |
658 |
659 | 1
660 | .dylib
661 |
662 |
663 | 1
664 | .dylib
665 |
666 |
667 | Contents\MacOS
668 | 1
669 | .dylib
670 |
671 |
672 | Contents\MacOS
673 | 1
674 | .dylib
675 |
676 |
677 | Contents\MacOS
678 | 1
679 | .dylib
680 |
681 |
682 | 0
683 | .bpl
684 |
685 |
686 |
687 |
688 | 0
689 |
690 |
691 | 0
692 |
693 |
694 | 0
695 |
696 |
697 | 0
698 |
699 |
700 | 0
701 |
702 |
703 | Contents\Resources\StartUp\
704 | 0
705 |
706 |
707 | Contents\Resources\StartUp\
708 | 0
709 |
710 |
711 | Contents\Resources\StartUp\
712 | 0
713 |
714 |
715 | 0
716 |
717 |
718 |
719 |
720 | 1
721 |
722 |
723 | 1
724 |
725 |
726 |
727 |
728 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
729 | 1
730 |
731 |
732 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
733 | 1
734 |
735 |
736 |
737 |
738 | ..\
739 | 1
740 |
741 |
742 | ..\
743 | 1
744 |
745 |
746 | ..\
747 | 1
748 |
749 |
750 |
751 |
752 | Contents
753 | 1
754 |
755 |
756 | Contents
757 | 1
758 |
759 |
760 | Contents
761 | 1
762 |
763 |
764 |
765 |
766 | Contents\Resources
767 | 1
768 |
769 |
770 | Contents\Resources
771 | 1
772 |
773 |
774 | Contents\Resources
775 | 1
776 |
777 |
778 |
779 |
780 | library\lib\armeabi-v7a
781 | 1
782 |
783 |
784 | library\lib\arm64-v8a
785 | 1
786 |
787 |
788 | 1
789 |
790 |
791 | 1
792 |
793 |
794 | 1
795 |
796 |
797 | 1
798 |
799 |
800 | Contents\MacOS
801 | 1
802 |
803 |
804 | Contents\MacOS
805 | 1
806 |
807 |
808 | Contents\MacOS
809 | 1
810 |
811 |
812 | 0
813 |
814 |
815 |
816 |
817 | library\lib\armeabi-v7a
818 | 1
819 |
820 |
821 |
822 |
823 | 1
824 |
825 |
826 | 1
827 |
828 |
829 | 1
830 |
831 |
832 |
833 |
834 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
835 | 1
836 |
837 |
838 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
839 | 1
840 |
841 |
842 | ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
843 | 1
844 |
845 |
846 |
847 |
848 | ..\
849 | 1
850 |
851 |
852 | ..\
853 | 1
854 |
855 |
856 | ..\
857 | 1
858 |
859 |
860 |
861 |
862 | 1
863 |
864 |
865 | 1
866 |
867 |
868 | 1
869 |
870 |
871 |
872 |
873 | ..\$(PROJECTNAME).launchscreen
874 | 64
875 |
876 |
877 | ..\$(PROJECTNAME).launchscreen
878 | 64
879 |
880 |
881 |
882 |
883 | 1
884 |
885 |
886 | 1
887 |
888 |
889 | 1
890 |
891 |
892 |
893 |
894 | Assets
895 | 1
896 |
897 |
898 | Assets
899 | 1
900 |
901 |
902 |
903 |
904 | Assets
905 | 1
906 |
907 |
908 | Assets
909 | 1
910 |
911 |
912 |
913 |
914 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
915 | 1
916 |
917 |
918 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
919 | 1
920 |
921 |
922 |
923 |
924 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
925 | 1
926 |
927 |
928 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
929 | 1
930 |
931 |
932 |
933 |
934 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
935 | 1
936 |
937 |
938 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
939 | 1
940 |
941 |
942 |
943 |
944 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
945 | 1
946 |
947 |
948 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
949 | 1
950 |
951 |
952 |
953 |
954 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
955 | 1
956 |
957 |
958 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
959 | 1
960 |
961 |
962 |
963 |
964 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
965 | 1
966 |
967 |
968 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
969 | 1
970 |
971 |
972 |
973 |
974 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
975 | 1
976 |
977 |
978 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
979 | 1
980 |
981 |
982 |
983 |
984 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
985 | 1
986 |
987 |
988 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
989 | 1
990 |
991 |
992 |
993 |
994 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
995 | 1
996 |
997 |
998 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
999 | 1
1000 |
1001 |
1002 |
1003 |
1004 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1005 | 1
1006 |
1007 |
1008 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1009 | 1
1010 |
1011 |
1012 |
1013 |
1014 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1015 | 1
1016 |
1017 |
1018 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1019 | 1
1020 |
1021 |
1022 |
1023 |
1024 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1025 | 1
1026 |
1027 |
1028 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1029 | 1
1030 |
1031 |
1032 |
1033 |
1034 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1035 | 1
1036 |
1037 |
1038 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1039 | 1
1040 |
1041 |
1042 |
1043 |
1044 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1045 | 1
1046 |
1047 |
1048 | ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1049 | 1
1050 |
1051 |
1052 |
1053 |
1054 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1055 | 1
1056 |
1057 |
1058 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1059 | 1
1060 |
1061 |
1062 |
1063 |
1064 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1065 | 1
1066 |
1067 |
1068 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1069 | 1
1070 |
1071 |
1072 |
1073 |
1074 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1075 | 1
1076 |
1077 |
1078 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1079 | 1
1080 |
1081 |
1082 |
1083 |
1084 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1085 | 1
1086 |
1087 |
1088 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1089 | 1
1090 |
1091 |
1092 |
1093 |
1094 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1095 | 1
1096 |
1097 |
1098 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1099 | 1
1100 |
1101 |
1102 |
1103 |
1104 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1105 | 1
1106 |
1107 |
1108 | ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1109 | 1
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 |
1117 |
1118 |
1119 |
1120 |
1121 |
1122 |
1123 |
1124 |
1125 |
1126 | False
1127 | True
1128 |
1129 |
1130 | 12
1131 |
1132 |
1133 |
1134 |
1135 |
1136 |
--------------------------------------------------------------------------------
/src/JetInfero.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tinyBigGAMES/JetInfero/afbb2474c72149f45d1ba8b6ae03d163e157172b/src/JetInfero.res
--------------------------------------------------------------------------------
/virustotal.txt:
--------------------------------------------------------------------------------
1 | VirtusTotal report for JetInfero Project
2 | ========================================
3 |
4 | We are pleased to include a VirusTotal report for this project to ensure
5 | transparency and trust. Every effort is made to deliver software that is both
6 | safe and free of viruses. However, despite our rigorous testing and security
7 | measures, there is always a possibility that virus scanners may flag the files
8 | as a false positive. We appreciate your understanding and encourage you to
9 | review the VirusTotal report for your assurance. Should you have any concerns
10 | or reservations, please do not hesitate to reach out to us.
11 |
12 | JetInfero.CLibs.res - https://www.virustotal.com/gui/file/885b1ec23e926a65716dbab84359ee39b625b8252f29a80b8ead88e7c15efa05
13 | JetInfero.dll - https://www.virustotal.com/gui/file/c661c0007799a028d8675c7323467f1a3bc7677f59aa7b789e8ff31e8009dbdb
14 |
--------------------------------------------------------------------------------