-
Notifications
You must be signed in to change notification settings - Fork 418
Expand file tree
/
Copy pathChatEndpointTests.cs
More file actions
624 lines (557 loc) · 37.9 KB
/
Copy pathChatEndpointTests.cs
File metadata and controls
624 lines (557 loc) · 37.9 KB
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
using Newtonsoft.Json;
using NUnit.Framework;
using OpenAI_API.Chat;
using OpenAI_API.Completions;
using OpenAI_API.Models;
using OpenAI_API.Moderation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace OpenAI_Tests
{
public class ChatEndpointTests
{
[SetUp]
public void Setup()
{
OpenAI_API.APIAuthentication.Default = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY"));
}
[Test]
public void BasicCompletion()
{
var api = new OpenAI_API.OpenAIAPI();
Assert.IsNotNull(api.Chat);
var results = api.Chat.CreateChatCompletionAsync(new ChatRequest()
{
Model = Model.ChatGPTTurbo,
Temperature = 0.1,
MaxTokens = 5,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.User, "Hello!")
}
}).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Object);
Assert.NotNull(results.Choices);
Assert.NotZero(results.Choices.Count);
Assert.AreEqual(ChatMessageRole.Assistant, results.Choices[0].Message.Role);
Assert.That(results.Choices.All(c => c.Message.Role.Equals(ChatMessageRole.Assistant)));
Assert.That(results.Choices.All(c => c.Message.TextContent.Length > 1));
}
[Test]
public void BasicCompletionWithNames()
{
var api = new OpenAI_API.OpenAIAPI();
Assert.IsNotNull(api.Chat);
var results = api.Chat.CreateChatCompletionAsync(new ChatRequest()
{
Model = Model.ChatGPTTurbo,
Temperature = 0.1,
MaxTokens = 5,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.System, "You are the moderator in this workplace chat. Answer any questions asked of the participants."),
new ChatMessage(ChatMessageRole.User, "Hello everyone") { Name="John"},
new ChatMessage(ChatMessageRole.User, "Good morning all") { Name="Edward"},
new ChatMessage(ChatMessageRole.User, "Is John here? Answer yes or no.") { Name = "Cindy" }
}
}).Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Object);
Assert.NotNull(results.Choices);
Assert.NotZero(results.Choices.Count);
Assert.AreEqual(ChatMessageRole.Assistant, results.Choices[0].Message.Role);
Assert.That(results.Choices.All(c => c.Message.Role.Equals(ChatMessageRole.Assistant)));
Assert.That(results.Choices.All(c => c.Message.TextContent.Length > 1));
Assert.That(results.ToString().ToLower().Contains("yes"));
}
[Test]
public void SimpleCompletion()
{
var api = new OpenAI_API.OpenAIAPI();
Assert.IsNotNull(api.Chat);
var results = api.Chat.CreateChatCompletionAsync("Hello!").Result;
Assert.IsNotNull(results);
if (results.CreatedUnixTime.HasValue)
{
Assert.NotZero(results.CreatedUnixTime.Value);
Assert.NotNull(results.Created);
Assert.Greater(results.Created.Value, new DateTime(2018, 1, 1));
Assert.Less(results.Created.Value, DateTime.Now.AddDays(1));
}
else
{
Assert.Null(results.Created);
}
Assert.NotNull(results.Object);
Assert.NotNull(results.Choices);
Assert.NotZero(results.Choices.Count);
Assert.AreEqual(ChatMessageRole.Assistant, results.Choices[0].Message.Role);
Assert.That(results.Choices.All(c => c.Message.Role.Equals(ChatMessageRole.Assistant)));
Assert.That(results.Choices.All(c => c.Message.Role == ChatMessageRole.Assistant));
Assert.That(results.Choices.All(c => c.Message.TextContent.Length > 1));
Assert.IsNotEmpty(results.ToString());
}
[TestCase("gpt-3.5-turbo")]
[TestCase("gpt-4")]
[TestCase("gpt-4-1106-preview")]
public void ChatBackAndForth(string model)
{
var api = new OpenAI_API.OpenAIAPI();
var chat = api.Chat.CreateConversation();
chat.Model = model;
chat.RequestParameters.Temperature = 0;
chat.AppendSystemMessage("You are a teacher who helps children understand if things are animals or not. If the user tells you an animal, you say \"yes\". If the user tells you something that is not an animal, you say \"no\". You only ever respond with \"yes\" or \"no\". You do not say anything else.");
chat.AppendUserInput("Is this an animal? Cat");
chat.AppendExampleChatbotOutput("Yes");
chat.AppendUserInput("Is this an animal? House");
chat.AppendExampleChatbotOutput("No");
chat.AppendUserInput("Is this an animal? Dog");
string res = chat.GetResponseFromChatbotAsync().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.AreEqual("Yes", res.Trim());
chat.AppendUserInput("Is this an animal? Chair");
res = chat.GetResponseFromChatbotAsync().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.AreEqual("No", res.Trim());
}
[TestCase(false)]
[TestCase(true)]
[TestCase(null)]
public void ChatTooLong(bool? addTruncationHandler)
{
var api = new OpenAI_API.OpenAIAPI();
var chat = api.Chat.CreateConversation();
chat.Model = "gpt-3.5-turbo-0613";
chat.RequestParameters.Temperature = 0;
if (addTruncationHandler == true)
{
chat.OnTruncationNeeded += (sender, args) =>
{
for (int i = 0; i < args.Count; i++)
{
if (args[i].Role != ChatMessageRole.System)
{
args.RemoveAt(i);
return;
}
}
};
}
else if (addTruncationHandler == false)
{
chat.AutoTruncateOnContextLengthExceeded = false;
}
AddLongExampleToChat(chat);
if (addTruncationHandler == false)
{
// it should fail because the response is too long
Assert.Throws<AggregateException>(() => chat.GetResponseFromChatbotAsync().Wait());
}
else
{
string res = chat.GetResponseFromChatbotAsync().Result;
Assert.IsTrue(res.Contains("Rayleigh"));
Assert.AreEqual(3260,chat.MostRecentApiResult.Usage.PromptTokens);
}
}
[TestCase(false)]
[TestCase(true)]
[TestCase(null)]
public async Task ChatTooLongStreaming(bool? addTruncationHandler)
{
var api = new OpenAI_API.OpenAIAPI();
var chat = api.Chat.CreateConversation();
chat.Model = "gpt-3.5-turbo-0613";
chat.RequestParameters.Temperature = 0;
if (addTruncationHandler == true)
{
chat.OnTruncationNeeded += (sender, args) =>
{
for (int i = 0; i < args.Count; i++)
{
if (args[i].Role != ChatMessageRole.System)
{
args.RemoveAt(i);
return;
}
}
};
}
else if (addTruncationHandler == false)
{
chat.AutoTruncateOnContextLengthExceeded = false;
}
AddLongExampleToChat(chat);
if (addTruncationHandler == false)
{
// it should fail because the response is too long
Assert.Throws<AggregateException>(() => chat.StreamResponseFromChatbotAsync(s=>s.ToString()).Wait());
}
else
{
string result = "";
int streamParts = 0;
await foreach (var streamResultPart in chat.StreamResponseEnumerableFromChatbotAsync())
{
result += streamResultPart;
streamParts++;
}
Assert.NotNull(result);
Assert.IsNotEmpty(result);
Assert.That(result.Contains("Rayleigh"));
Assert.Greater(result.Length, 200);
Assert.Greater(streamParts, 5);
Assert.AreEqual(ChatMessageRole.User, chat.Messages.Last().Role);
Assert.AreEqual(result, chat.Messages.Last().TextContent);
}
}
/// <summary>
/// This adds a very long chat history that exceeds the prompt token limit
/// </summary>
/// <param name="chat">The chat to add the examples to</param>
private static void AddLongExampleToChat(Conversation chat)
{
chat.AppendSystemMessage("You are a helpful assistant who is really good at explaining things to students.");
chat.AppendUserInput("Please explain how mountains are formed in great detail");
// the following example text is taken from wikipedia
chat.AppendExampleChatbotOutput(@"Mountain formation refers to the geological processes that underlie the formation of mountains. These processes are associated with large-scale movements of the Earth's crust (tectonic plates). Folding, faulting, volcanic activity, igneous intrusion and metamorphism can all be parts of the orogenic process of mountain building. The formation of mountains is not necessarily related to the geological structures found on it.
The understanding of specific landscape features in terms of the underlying tectonic processes is called tectonic geomorphology, and the study of geologically young or ongoing processes is called neotectonics.
From the late 18th century until its replacement by plate tectonics in the 1960s, geosyncline theory was used to explain much mountain-building.
Types of mountains
See also: List of mountain types
There are five main types of mountains: volcanic, fold, plateau, fault-block and dome. A more detailed classification useful on a local scale predates plate tectonics and adds to these categories.
Volcanic mountains
Annotated view includes Ushkovsky, Tolbachik, Bezymianny, Zimina, and Udina stratovolcanoes of Kamchatka, Russia. Oblique view taken on November 12, 2013, from ISS.
Stratovolcanoes associated with a subduction zone (left) and a spreading ridge volcano (right). A hotspot volcano is center.
Movements of tectonic plates create volcanoes along the plate boundaries, which erupt and form mountains. A volcanic arc system is a series of volcanoes that form near a subduction zone where the crust of a sinking oceanic plate melts and drags water down with the subducting crust.
The Dome of Vitosha mountain next to Sofia
Most volcanoes occur in a band encircling the Pacific Ocean (the Pacific Ring of Fire), and in another that extends from the Mediterranean across Asia to join the Pacific band in the Indonesian Archipelago. The most important types of volcanic mountain are composite cones or stratovolcanoes (Vesuvius, Kilimanjaro and Mount Fuji are examples) and shield volcanoes (such as Mauna Loa on Hawaii, a hotspot volcano).
A shield volcano has a gently sloping cone due to the low viscosity of the emitted material, primarily basalt. Mauna Loa is the classic example, with a slope of 4°-6°. (The relation between slope and viscosity falls under the topic of angle of repose. Vitosha - the domed mountain next to Sofia, capital of Bulgaria, is also formed by volcanic activity.
Zard-Kuh, a fold mountain in the central Zagros range of Iran.
When plates collide or undergo subduction (that is – ride one over another), the plates tend to buckle and fold, forming mountains. Most of the major continental mountain ranges are associated with thrusting and folding or orogenesis. Examples are the Balkan Mountains, the Jura and the Zagros mountains.
Sierra Nevada Mountains (formed by delamination) as seen from the International Space Station.
When a fault block is raised or tilted, block mountains can result. Higher blocks are called horsts and troughs are called grabens. A spreading apart of the surface causes tensional forces. When the tensional forces are strong enough to cause a plate to split apart, it does so such that a center block drops down relative to its flanking blocks.
An example of this is the Sierra Nevada Range, where delamination created a block 650 km long and 80 km wide that consists of many individual portions tipped gently west, with east facing slips rising abruptly to produce the highest mountain front in the continental United States.
Another good example is the Rila - Rhodope mountain Massif in Bulgaria, Southeast Europe, including the well defined horsts of Belasitsa (linear horst), Rila mountain (vaulted domed shaped horst) and Pirin mountain - a horst forming a massive anticline situated between the complex graben valleys of Struma and that of Mesta.
Uplifted passive margins
Unlike orogenic mountains there is no widely accepted geophysical model that explains elevated passive continental margins such as the Scandinavian Mountains, Eastern Greenland, the Brazilian Highlands or Australia's Great Dividing Range.
Models
See also: Extensional tectonics, Rift valley, Rift, Prediction of volcanic activity, and Geomorphology
Hotspot volcanoes
Hotspots are supplied by a magma source in the Earth's mantle called a mantle plume. Although originally attributed to a melting of subducted oceanic crust, recent evidence belies this connection. The mechanism for plume formation remains a research topic.
Fault blocks
Several movements of the Earth's crust that lead to mountains are associated with faults. These movements actually are amenable to analysis that can predict, for example, the height of a raised block and the width of an intervening rift between blocks using the rheology of the layers and the forces of isostasy. Early bent plate models predicting fractures and fault movements have evolved into today's kinematic and flexural models.");
chat.AppendUserInput("Explain how a car engine works in great detail");
// the following example text is taken from wikipedia
chat.AppendExampleChatbotOutput(@"There are a wide variety of propulsion systems available or potentially available for automobiles and other vehicles. Options included internal combustion engines fueled by petrol, diesel, propane, or natural gas; hybrid vehicles, plug-in hybrids, fuel cell vehicles fueled by hydrogen and all electric cars. Fueled vehicles seem to have the advantage due to the limited range and high cost of batteries. Some options required construction of a network of fueling or charging stations. With no compelling advantage for any particular option, car makers pursued parallel development tracks using a variety of options. Reducing the weight of vehicles was one strategy being employed.
Recent developments
The use of high-technology (such as electronic engine control units) in advanced designs resulting from substantial investments in development research by European countries and Japan seemed to give an advantage to them over Chinese automakers and parts suppliers who, as of 2013, had low development budgets and lacked capacity to produce parts for high-tech engine and power train designs.
Characteristics
The chief characteristic of an automotive engine (compared to a stationary engine or a marine engine) is a high power-to-weight ratio. This is achieved by using a high rotational speed. However, automotive engines are sometimes modified for marine use, forming a marine automobile engine.
History
Main article: History of the automobile
In the early years, steam engines and electric motors were tried, but with limited success. In the 20th century, the internal combustion (ic) engine became dominant. In 2015, the internal combustion engine remains the most widely used but a resurgence of electricity seems likely because of increasing concern about ic engine exhaust gas emissions.
As of 2017, the majority of the cars in the United States are gasoline powered. In the early 1900s, the internal combustion engines faced competition from steam and electric engines. The internal combustion engines of the time was powered by gasoline. Internal combustion engines function with the concept of a piston being pushed by the pressure of a certain explosion. This is the predecessor to the modern diesel engine used in automobiles, but more specifically, heavy duty vehicles such as semi-trucks.
Engine types
Internal combustion engines
Main article: Internal combustion engine
Petrol engines quickly became the choice of manufacturers and consumers alike. Despite the rough start, noisy and dirty engine, and the difficult gear shifting, new technologies such as the production line and the advancement of the engine allowed the standard production of the gas automobiles. This is the start, from the invention of the gas automobile in 1876, to the beginning of mass production in the 1890s. Henry Ford's Model T drove down the price of cars to a more affordable price. At the same time, Charles Kettering invented an electric starter, allowing the car to be more efficient than the mechanical starter.
An internal combustion engine is a motor that is powered by the expansion of gas which is created by the combustion of hydrocarbon gases fuels. Gasoline engines became popular as a result of this, as internal combustion engines were commonly known as gasoline engines. Although gasoline engines became popular, they were not particularly desirable due to the dangers of fuel leaks that may cause explosions. Therefore, many inventors attempted to create a kerosene burning engine as a result. This was not a successful venture applying it for automotive usage. There are many different types of fuels for internal combustion engines. These include diesel, gasoline, and ethanol.
Steam engines
Main article: History of steam road vehicles
The steam engine was invented in the late 1700s, and the primary method of powering engines and soon, locomotives. One of the most popular steam automobile was the “Stanley Steamer,” offering low pollution, power, and speed. The downside of these steam automobiles is the unreliability, complexity, and the frequent accidents that occurred with them. The startup time for a steam car may take up to 45 minutes, defeating the purpose of faster transportation. By the time the steam automobile was improved, the complexity of manufacturing relative to the gas automobiles made steam automobiles unprofitable.
A steam engine is a device which transforms heat into mechanical motion. This is provided with the usage of boilers, which create steam by boiling water. In the early 1900s, Abner Doble introduced a steam-powered car in the United States which had capabilities that could potentially overpower Ford's Model T in efficiency.
Electric motors
Main article: Electric motor
Electric vehicles seemed to be the most viable option, similar to the steam automobiles. It was first invented in the early 1800s, and became a viable option of transportation around 1890, when William Morrison created the first electric car that traveled 14 miles per hour. The electric cars offered low pollution and a soundless ride, unlike their gasoline counterparts. The greatest downside of electric cars was the range. The typical electric car could reach around 20 miles before requiring a recharge. Manufacturers could not increase the number of batteries, due to the bulkiness of the batteries at the time. Without an incentive to purchase the electric automobiles, gas automobiles was the most viable option at the time.
Electric cars use batteries to store electricity which is used to power electric motors. The battery delivers the power to the motor, which is either AC or DC. The difference between AC and DC motors is the sort of system that is required to run it in an electric vehicle. An AC motor is generally cheaper but the components required to run it in an electric vehicle such as the controller and inverter makes it more expensive than the DC motor. A unique feature of electric vehicles compared to its gasoline counterparts, the electric vehicle is more simple than the gasoline vehicle.
In the 1970s, the electric vehicle made its reappearance because of the 1973 OPEC Oil Embargo. Previously, the abundant gasoline had become the prime source of fuel for vehicles. But after the shortage, manufacturers began looking towards electric vehicles again. Despite the improved technology from the 1800s, the electric vehicles faced similar technological flaws such as limited mileage and speed. They could only travel up to 45 miles per hour and had a range of approximately 40 miles.");
chat.AppendUserInput("Explain airplanes in great detail");
// the following example text is taken from wikipedia
chat.AppendExampleChatbotOutput(@"An airplane (American English), or aeroplane (Commonwealth English), informally plane, is a fixed-wing aircraft that is propelled forward by thrust from a jet engine, propeller, or rocket engine. Airplanes come in a variety of sizes, shapes, and wing configurations. The broad spectrum of uses for airplanes includes recreation, transportation of goods and people, military, and research. Worldwide, commercial aviation transports more than four billion passengers annually on airliners Most airplanes are flown by a pilot on board the aircraft, but some are designed to be remotely or computer-controlled such as drones.
The Wright brothers invented and flew the first airplane in 1903, recognized as ""the first sustained and controlled heavier-than-air powered flight"". Following its limited use in World War I, aircraft technology continued to develop. Airplanes had a presence in all the major battles of World War II. The first jet aircraft was the German Heinkel He 178 in 1939. The first jet airliner, the de Havilland Comet, was introduced in 1952. The Boeing 707, the first widely successful commercial jet, was in commercial service for more than 50 years, from 1958 to at least 2013.
Etymology and usage
First attested in English in the late 19th century (prior to the first sustained powered flight), the word airplane, like aeroplane, derives from the French aéroplane, which comes from the Greek ἀήρ (aēr), ""air"" In an example of synecdoche, the word for the wing came to refer to the entire aircraft.
In the United States and Canada, the term ""airplane"" is used for powered fixed-wing aircraft. In the United Kingdom and Ireland and most of the Commonwealth, the term ""aeroplane"" (/ˈɛərəpleɪn/) is usually applied to these aircraft.
History
Main articles: Aviation history and First flying machine
Le Bris and his glider, Albatros II, photographed by Nadar, 1868
Otto Lilienthal in mid-flight, c. 1895
Antecedents
Many stories from antiquity involve flight, such as the Greek legend of Icarus and Daedalus, and the Vimana in ancient Indian epics. Around 400 BC in Greece, Archytas was reputed to have designed and built the first artificial, self-propelled flying device, a bird-shaped model propelled by a jet of what was probably steam, said to have flown some 200 m (660 ft).
Some of the earliest recorded attempts with gliders were those by the 9th-century Andalusian and Arabic-language poet Abbas ibn Firnas and the 11th-century English monk Eilmer of Malmesbury; both experiments injured their pilots. Leonardo da Vinci researched the wing design of birds and designed a man-powered aircraft in his Codex on the Flight of Birds (1502), noting for the first time the distinction between the center of mass and the center of pressure of flying birds.
In 1799, George Cayley set forth the concept of the modern airplane as a fixed-wing flying machine with separate systems for lift, propulsion, and control. Other aviators who made similar flights at that time were Otto Lilienthal, Percy Pilcher, and Octave Chanute.
Sir Hiram Maxim built a craft that weighed 3.5 tons, with a 110-foot (34 m) wingspan that was powered by two 360-horsepower (270 kW) steam engines driving two propellers. In 1894, his machine was tested with overhead rails to prevent it from rising. The test showed that it had enough lift to take off. The craft was uncontrollable and it is presumed that Maxim realized this because he subsequently abandoned work on it.
In the 1890s, Lawrence Hargrave conducted research on wing structures and developed a box kite that lifted the weight of a man. His box kite designs were widely adopted. Although he also developed a type of rotary aircraft engine, he did not create and fly a powered fixed-wing aircraft.
Between 1867 and 1896, the German pioneer of human aviation Otto Lilienthal developed heavier-than-air flight. He was the first person to make well-documented, repeated, successful gliding flights. Lilienthal's work led to him developing the concept of the modern wing,
Early powered flights
Patent drawings of Clement Ader's Éole.
The Frenchman Clement Ader constructed his first of three flying machines in 1886, the Éole. It was a bat-like design run by a lightweight steam engine of his own invention, with four cylinders developing 20 horsepower (15 kW), driving a four-blade propeller. The engine weighed no more than 4 kilograms per kilowatt (6.6 lb/hp). The wings had a span of 14 m (46 ft). All-up weight was 300 kilograms (660 lb). On 9 October 1890, Ader attempted to fly the Éole. Aviation historians give credit to this effort as a powered take-off and uncontrolled hop of approximately 50 m (160 ft) at a height of approximately 200 mm (7.9 in).
The American Wright brothers flights in 1903 are recognized by the Fédération Aéronautique Internationale (FAI), the standard-setting and record-keeping body for aeronautics, as ""the first sustained and controlled heavier-than-air powered flight"". By 1905, the Wright Flyer III was capable of fully controllable, stable flight for substantial periods. The Wright brothers credited Otto Lilienthal as a major inspiration for their decision to pursue manned flight.
Santos-Dumont 14-bis, between 1906 and 1907
In 1906, the Brazilian Alberto Santos-Dumont made what was claimed to be the first airplane flight unassisted by catapult
An early aircraft design that brought together the modern monoplane tractor configuration was the Blériot VIII design of 1908. It had movable tail surfaces controlling both yaw and pitch, a form of roll control supplied either by wing warping or by ailerons and controlled by its pilot with a joystick and rudder bar. It was an important predecessor of his later Blériot XI Channel-crossing aircraft of the summer of 1909.
World War I served as a testbed for the use of the airplane as a weapon. Airplanes demonstrated their potential as mobile observation platforms, then proved themselves to be machines of war capable of causing casualties to the enemy. The earliest known aerial victory with a synchronized machine gun-armed fighter aircraft occurred in 1915, by German Luftstreitkräfte Leutnant Kurt Wintgens. Fighter aces appeared; the greatest (by number of Aerial Combat victories) was Manfred von Richthofen.
Following WWI, aircraft technology continued to develop. Alcock and Brown crossed the Atlantic non-stop for the first time in 1919. The first international commercial flights took place between the United States and Canada in 1919.
Airplanes had a presence in all the major battles of World War II. They were an essential component of the military strategies of the period, such as the German Blitzkrieg, The Battle of Britain, and the American and Japanese aircraft carrier campaigns of the Pacific War.
Development of jet aircraft
The Concorde supersonic transport aircraft
The first practical jet aircraft was the German Heinkel He 178, which was tested in 1939. In 1943, the Messerschmitt Me 262, the first operational jet fighter aircraft, went into service in the German Luftwaffe.
The first jet airliner, the de Havilland Comet, was introduced in 1952. The Boeing 707, the first widely successful commercial jet, was in commercial service for more than 50 years, from 1958 to 2010. The Boeing 747 was the world's biggest passenger aircraft from 1970 until it was surpassed by the Airbus A380 in 2005.
Supersonic airliner flights, including those of the Concorde, have been limited to over-water flight at supersonic speed because of their sonic boom, which is prohibited over most populated land areas. The high cost of operation per passenger-mile and a deadly crash in 2000 induced the operators of the Concorde to remove it from service.
Propulsion
Propeller
An Antonov An-2 biplane
An aircraft propeller, or airscrew, converts rotary motion from an engine or other power source, into a swirling slipstream which pushes the propeller forwards or backwards. It comprises a rotating power-driven hub, to which are attached two or more radial airfoil-section blades such that the whole assembly rotates about a longitudinal axis.
Reciprocating engine
Reciprocating engines in aircraft have three main variants, radial, in-line and flat or horizontally opposed engine. The radial engine is a reciprocating type internal combustion engine configuration in which the cylinders ""radiate"" outward from a central crankcase like the spokes of a wheel and was commonly used for aircraft engines before gas turbine engines became predominant. An inline engine is a reciprocating engine with banks of cylinders, one behind another, rather than rows of cylinders, with each bank having any number of cylinders, but rarely more than six, and may be water-cooled. A flat engine is an internal combustion engine with horizontally-opposed cylinders.");
chat.AppendUserInput("Explain why the sky is blue in great detail");
}
[TestCase("gpt-3.5-turbo")]
[TestCase("gpt-4")]
[TestCase("gpt-4-1106-preview")]
public void ChatWithNames(string model)
{
var api = new OpenAI_API.OpenAIAPI();
var chat = api.Chat.CreateConversation();
chat.Model = model;
chat.RequestParameters.Temperature = 0;
chat.AppendSystemMessage("You are the moderator in this workplace chat. Answer any questions asked of the participants.");
chat.AppendUserInputWithName("John", "Hello everyone");
chat.AppendUserInputWithName("Edward", "Good morning all");
chat.AppendUserInputWithName("Cindy", "Is John here? Answer yes or no.");
chat.AppendExampleChatbotOutput("Yes");
chat.AppendUserInputWithName("Cindy", "Is Monica here? Answer yes or no.");
string res = chat.GetResponseFromChatbotAsync().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.That(res.ToLower().Contains("no"));
chat.AppendUserInputWithName("Cindy", "Is Edward here? Answer yes or no.");
res = chat.GetResponseFromChatbotAsync().Result;
Assert.NotNull(res);
Assert.IsNotEmpty(res);
Assert.That(res.ToLower().Contains("yes"));
}
[TestCase("gpt-3.5-turbo")]
[TestCase("gpt-4-1106-preview")]
public async Task StreamCompletionEnumerableAsync_ShouldStreamData(string model)
{
var api = new OpenAI_API.OpenAIAPI();
Assert.IsNotNull(api.Chat);
var req = new ChatRequest()
{
Model = model,
Temperature = 0.2,
MaxTokens = 500,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.User, "Please explain how mountains are formed in great detail.")
}
};
var chatResults = new List<ChatResult>();
await foreach (var res in api.Chat.StreamChatEnumerableAsync(req))
{
chatResults.Add(res);
}
Assert.Greater(chatResults.Count, 100);
Assert.That(chatResults.Select(cr => cr.Choices[0].Delta.TextContent).Count(c => !string.IsNullOrEmpty(c)) > 50);
}
[TestCase("gpt-3.5-turbo")]
[TestCase("gpt-4-1106-preview")]
public async Task StreamingConversation(string model)
{
var api = new OpenAI_API.OpenAIAPI();
var chat = api.Chat.CreateConversation();
chat.RequestParameters.MaxTokens = 500;
chat.RequestParameters.Temperature = 0.2;
chat.Model = model;
chat.AppendSystemMessage("You are a helpful assistant who is really good at explaining things to students.");
chat.AppendUserInput("Please explain to me how mountains are formed in great detail.");
string result = "";
int streamParts = 0;
await foreach (var streamResultPart in chat.StreamResponseEnumerableFromChatbotAsync())
{
result += streamResultPart;
streamParts++;
}
Assert.NotNull(result);
Assert.IsNotEmpty(result);
Assert.That(result.ToLower().Contains("mountains"));
Assert.Greater(result.Length, 200);
Assert.Greater(streamParts, 5);
Assert.AreEqual(ChatMessageRole.User, chat.Messages.Last().Role);
Assert.AreEqual(result, chat.Messages.Last().TextContent);
}
[TestCase("gpt-4-1106-preview")]
[TestCase("gpt-3.5-turbo-1106")]
public void ChatJsonFormat(string model)
{
var api = new OpenAI_API.OpenAIAPI();
ChatRequest chatRequest = new ChatRequest()
{
Model = model,
Temperature = 0.0,
MaxTokens = 500,
ResponseFormat = ChatRequest.ResponseFormats.JsonObject,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.System, "You are a helpful assistant designed to output JSON."),
new ChatMessage(ChatMessageRole.User, "Who won the world series in 2020? Return JSON of a 'wins' dictionary with the year as the numeric key and the winning team as the string value.")
}
};
var results = api.Chat.CreateChatCompletionAsync(chatRequest).Result;
Assert.IsNotNull(results);
Assert.NotNull(results.Object);
Assert.NotNull(results.Choices);
Assert.NotZero(results.Choices.Count);
Assert.AreEqual(ChatMessageRole.Assistant, results.Choices[0].Message.Role);
Assert.That(results.Choices.All(c => c.Message.TextContent.Length > 1));
Assert.AreEqual("stop", results.Choices[0].FinishReason);
using (StringReader stringReader = new StringReader(results.Choices[0].Message.TextContent))
{
using (JsonTextReader jsonReader= new JsonTextReader(stringReader))
{
var serializer = new JsonSerializer();
var json = serializer.Deserialize<Dictionary<string, Dictionary<int, string>>>(jsonReader);
Assert.NotNull(json);
Assert.IsTrue(json.ContainsKey("wins"));
Assert.IsTrue(json["wins"].ContainsKey(2020));
Assert.AreEqual("Los Angeles Dodgers", json["wins"][2020]);
}
}
}
[Test]
public async Task SameSeedShouldBeSameOutput() {
var api = new OpenAI_API.OpenAIAPI();
ChatRequest chatRequest = new ChatRequest()
{
Model = Model.ChatGPTTurbo_1106,
Temperature = 0,
MaxTokens = 100,
Seed = 5,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.System, "You are a very creative comedian."),
new ChatMessage(ChatMessageRole.User, "Tell me a joke.")
}
};
var resultA = await api.Chat.CreateChatCompletionAsync(chatRequest);
string jokeA = resultA.ToString();
string systemFingerprintA = resultA.SystemFingerprint;
Assert.IsNotNull(systemFingerprintA);
Assert.IsNotEmpty(systemFingerprintA);
Assert.IsNotEmpty(jokeA);
var resultB = await api.Chat.CreateChatCompletionAsync(chatRequest);
string jokeB = resultB.ToString();
string systemFingerprintB = resultB.SystemFingerprint;
Assert.IsNotNull(systemFingerprintB);
Assert.IsNotEmpty(systemFingerprintB);
Assert.IsNotEmpty(jokeB);
if (systemFingerprintA == systemFingerprintB)
{
Assert.AreEqual(jokeA, jokeB);
}
}
[Test]
public async Task DifferentSeedShouldBeDifferentOutput()
{
var api = new OpenAI_API.OpenAIAPI();
ChatRequest chatRequest = new ChatRequest()
{
Model = Model.ChatGPTTurbo_1106,
Temperature = 0,
MaxTokens = 100,
Seed = 5,
Messages = new ChatMessage[] {
new ChatMessage(ChatMessageRole.System, "You are a very creative comedian."),
new ChatMessage(ChatMessageRole.User, "Tell me a joke.")
}
};
var resultA = await api.Chat.CreateChatCompletionAsync(chatRequest);
string jokeA = resultA.ToString();
string systemFingerprintA = resultA.SystemFingerprint;
Assert.IsNotNull(systemFingerprintA);
Assert.IsNotEmpty(systemFingerprintA);
Assert.IsNotEmpty(jokeA);
chatRequest.Seed = 99;
var resultB = await api.Chat.CreateChatCompletionAsync(chatRequest);
string jokeB = resultB.ToString();
string systemFingerprintB = resultB.SystemFingerprint;
Assert.IsNotNull(systemFingerprintB);
Assert.IsNotEmpty(systemFingerprintB);
Assert.IsNotEmpty(jokeB);
if (systemFingerprintA == systemFingerprintB)
{
Assert.AreNotEqual(jokeA, jokeB);
}
}
[Test]
public void ChatMessageSerializationShouldDeserialzeAsExpected()
{
var msg = new ChatMessage()
{
Role = ChatMessageRole.User,
TextContent = "This is a test"
};
var jmsg = JsonConvert.SerializeObject(msg);
var deserializedMsg = JsonConvert.DeserializeObject<ChatMessage>(jmsg);
Assert.IsNotNull(deserializedMsg);
Assert.IsTrue(msg.TextContent.Equals(deserializedMsg.TextContent));
Assert.IsTrue(deserializedMsg.Images.Count == msg.Images.Count);
}
[Test]
public void ChatMessagesContentSerializationShouldDeserialzeAsExpected()
{
var msg = new ChatMessage(ChatMessageRole.User, "What is this image about?", new ChatMessage.ImageInput[] { new ChatMessage.ImageInput("https://xyz.com/image.png") });
var jmsg = JsonConvert.SerializeObject(msg);
var deserializedMsg = JsonConvert.DeserializeObject<ChatMessage>(jmsg);
Assert.IsNotNull(deserializedMsg);
Assert.IsTrue(msg.TextContent.Equals(deserializedMsg.TextContent));
Assert.IsTrue(deserializedMsg.Images.Count == msg.Images.Count);
Assert.IsTrue(deserializedMsg.Images[0].Url.Equals(msg.Images[0].Url));
}
[Test]
public void ChatMessagesListSerializationShouldDeserialzeAsExpected()
{
var messages = new List<ChatMessage>();
var msg1 = new ChatMessage(ChatMessageRole.User, "What is this image about?", new ChatMessage.ImageInput[] { new ChatMessage.ImageInput("https://xyz.com/image.png") });
messages.Add(msg1);
var msg2 = new ChatMessage(ChatMessageRole.User, "And what is this image about?", new ChatMessage.ImageInput[] { new ChatMessage.ImageInput("https://xyz.com/image2.png") });
messages.Add(msg2);
var jmsgs = JsonConvert.SerializeObject(messages);
var deserializedMessagesList = JsonConvert.DeserializeObject<List<ChatMessage>>(jmsgs);
Assert.IsNotNull(deserializedMessagesList);
Assert.IsTrue(deserializedMessagesList.Count == messages.Count);
Assert.IsTrue(deserializedMessagesList[0].TextContent.Equals(messages[0].TextContent));
Assert.IsTrue(deserializedMessagesList[0].Images.Count == messages[0].Images.Count);
Assert.IsTrue(deserializedMessagesList[0].Images[0].Url.Equals(messages[0].Images[0].Url));
Assert.IsTrue(deserializedMessagesList[1].TextContent.Equals(messages[1].TextContent));
Assert.IsTrue(deserializedMessagesList[1].Images.Count == messages[1].Images.Count);
Assert.IsTrue(deserializedMessagesList[1].Images[0].Url.Equals(messages[1].Images[0].Url));
}
}
}