nsarrazin HF Staff commited on
Commit
53a5ddc
·
1 Parent(s): 9af277e

feat(scripts): add reasoning & code samples to populate script

Browse files
Files changed (2) hide show
  1. scripts/populate.ts +48 -10
  2. scripts/samples.txt +194 -0
scripts/populate.ts CHANGED
@@ -21,6 +21,10 @@ import { Message } from "../src/lib/types/Message.ts";
21
  import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
22
  import { generateSearchTokens } from "../src/lib/utils/searchTokens.ts";
23
  import { ReviewStatus } from "../src/lib/types/Review.ts";
 
 
 
 
24
 
25
  const rl = readline.createInterface({
26
  input: process.stdin,
@@ -31,6 +35,8 @@ rl.on("close", function () {
31
  process.exit(0);
32
  });
33
 
 
 
34
  const possibleFlags = ["reset", "all", "users", "settings", "assistants", "conversations", "tools"];
35
  const argv = minimist(process.argv.slice(2));
36
  const flags = argv["_"].filter((flag) => possibleFlags.includes(flag));
@@ -55,6 +61,7 @@ async function generateMessages(preprompt?: string): Promise<Message[]> {
55
  const convLength = faker.number.int({ min: 1, max: 25 }) * 2; // must always be even
56
 
57
  for (let i = 0; i < convLength; i++) {
 
58
  lastId = addChildren(
59
  {
60
  messages,
@@ -62,13 +69,28 @@ async function generateMessages(preprompt?: string): Promise<Message[]> {
62
  },
63
  {
64
  from: isUser ? "user" : "assistant",
65
- content: faker.lorem.sentence({
66
- min: 10,
67
- max: isUser ? 50 : 200,
68
- }),
 
 
 
 
69
  createdAt: faker.date.recent({ days: 30 }),
70
  updatedAt: faker.date.recent({ days: 30 }),
71
- interrupted: i === convLength - 1 && isInterrupted,
 
 
 
 
 
 
 
 
 
 
 
72
  },
73
  lastId
74
  );
@@ -78,6 +100,7 @@ async function generateMessages(preprompt?: string): Promise<Message[]> {
78
  const convLength = faker.number.int({ min: 2, max: 200 });
79
 
80
  for (let i = 0; i < convLength; i++) {
 
81
  addChildren(
82
  {
83
  messages,
@@ -85,13 +108,28 @@ async function generateMessages(preprompt?: string): Promise<Message[]> {
85
  },
86
  {
87
  from: isUser ? "user" : "assistant",
88
- content: faker.lorem.sentence({
89
- min: 10,
90
- max: isUser ? 50 : 200,
91
- }),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  createdAt: faker.date.recent({ days: 30 }),
93
  updatedAt: faker.date.recent({ days: 30 }),
94
- interrupted: i === convLength - 1 && isInterrupted,
95
  },
96
  faker.helpers.arrayElement([
97
  messages[0].id,
 
21
  import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
22
  import { generateSearchTokens } from "../src/lib/utils/searchTokens.ts";
23
  import { ReviewStatus } from "../src/lib/types/Review.ts";
24
+ import fs from "fs";
25
+ import path from "path";
26
+ import { MessageUpdateType } from "../src/lib/types/MessageUpdate.ts";
27
+ import { MessageReasoningUpdateType } from "../src/lib/types/MessageUpdate.ts";
28
 
29
  const rl = readline.createInterface({
30
  input: process.stdin,
 
35
  process.exit(0);
36
  });
37
 
38
+ const samples = fs.readFileSync(path.join(__dirname, "samples.txt"), "utf8").split("\n---\n");
39
+
40
  const possibleFlags = ["reset", "all", "users", "settings", "assistants", "conversations", "tools"];
41
  const argv = minimist(process.argv.slice(2));
42
  const flags = argv["_"].filter((flag) => possibleFlags.includes(flag));
 
61
  const convLength = faker.number.int({ min: 1, max: 25 }) * 2; // must always be even
62
 
63
  for (let i = 0; i < convLength; i++) {
64
+ const hasReasoning = Math.random() < 0.2;
65
  lastId = addChildren(
66
  {
67
  messages,
 
69
  },
70
  {
71
  from: isUser ? "user" : "assistant",
72
+ content:
73
+ faker.lorem.sentence({
74
+ min: 10,
75
+ max: isUser ? 50 : 200,
76
+ }) +
77
+ (!isUser && Math.random() < 0.1
78
+ ? "\n```\n" + faker.helpers.arrayElement(samples) + "\n```\n"
79
+ : ""),
80
  createdAt: faker.date.recent({ days: 30 }),
81
  updatedAt: faker.date.recent({ days: 30 }),
82
+ reasoning: hasReasoning ? faker.lorem.paragraphs(2) : undefined,
83
+ updates: hasReasoning
84
+ ? [
85
+ {
86
+ type: MessageUpdateType.Reasoning,
87
+ subtype: MessageReasoningUpdateType.Status,
88
+ uuid: crypto.randomUUID(),
89
+ status: "thinking",
90
+ },
91
+ ]
92
+ : [],
93
+ interrupted: !isUser && i === convLength - 1 && isInterrupted,
94
  },
95
  lastId
96
  );
 
100
  const convLength = faker.number.int({ min: 2, max: 200 });
101
 
102
  for (let i = 0; i < convLength; i++) {
103
+ const hasReasoning = Math.random() < 0.2;
104
  addChildren(
105
  {
106
  messages,
 
108
  },
109
  {
110
  from: isUser ? "user" : "assistant",
111
+ content:
112
+ faker.lorem.sentence({
113
+ min: 10,
114
+ max: isUser ? 50 : 200,
115
+ }) +
116
+ (!isUser && Math.random() < 0.1
117
+ ? "\n```\n" + faker.helpers.arrayElement(samples) + "\n```\n"
118
+ : ""),
119
+ reasoning: hasReasoning ? faker.lorem.paragraphs(2) : undefined,
120
+ updates: hasReasoning
121
+ ? [
122
+ {
123
+ type: MessageUpdateType.Reasoning,
124
+ subtype: MessageReasoningUpdateType.Status,
125
+ uuid: crypto.randomUUID(),
126
+ status: "thinking",
127
+ },
128
+ ]
129
+ : [],
130
  createdAt: faker.date.recent({ days: 30 }),
131
  updatedAt: faker.date.recent({ days: 30 }),
132
+ interrupted: !isUser && i === convLength - 1 && isInterrupted,
133
  },
134
  faker.helpers.arrayElement([
135
  messages[0].id,
scripts/samples.txt ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Observable, of, from, interval, throwError } from 'rxjs';
2
+ import { map, filter, catchError, switchMap, take, tap } from 'rxjs/operators';
3
+
4
+ // Mock function to fetch stock prices (simulates API call)
5
+ const fetchStockPrice = (ticker: string): Observable<number> => {
6
+ return new Observable<number>((observer) => {
7
+ const intervalId = setInterval(() => {
8
+ if (Math.random() < 0.1) { // Simulating an error 10% of the time
9
+ observer.error(`Error fetching stock price for ${ticker}`);
10
+ } else {
11
+ const price = parseFloat((Math.random() * 1000).toFixed(2));
12
+ observer.next(price);
13
+ }
14
+ }, 1000);
15
+
16
+ return () => {
17
+ clearInterval(intervalId);
18
+ console.log(`Stopped fetching prices for ${ticker}`);
19
+ };
20
+ });
21
+ };
22
+
23
+ // Example usage: Tracking stock price updates
24
+ const stockTicker = 'AAPL';
25
+ const stockPrice$ = fetchStockPrice(stockTicker).pipe(
26
+ map(price => ({ ticker: stockTicker, price })), // Transform data
27
+ filter(data => data.price > 500), // Only keep prices above 500
28
+ tap(data => console.log(`Price update:`, data)), // Side effect: Logging
29
+ catchError(err => {
30
+ console.error(err);
31
+ return of({ ticker: stockTicker, price: null }); // Fallback observable
32
+ })
33
+ );
34
+
35
+ // Subscribe to the stock price updates
36
+ const subscription = stockPrice$.subscribe({
37
+ next: data => console.log(`Subscriber received:`, data),
38
+ error: err => console.error(`Subscription error:`, err),
39
+ complete: () => console.log('Stream complete'),
40
+ });
41
+
42
+ // Automatically unsubscribe after 10 seconds
43
+ setTimeout(() => {
44
+ subscription.unsubscribe();
45
+ console.log('Unsubscribed from stock price updates.');
46
+ }, 10000);
47
+ ---
48
+ class EnforceAttrsMeta(type):
49
+ """
50
+ Metaclass that enforces the presence of specific attributes in a class
51
+ and automatically decorates methods with a logging wrapper.
52
+ """
53
+
54
+ required_attributes = ['name', 'version']
55
+
56
+ def __new__(cls, name, bases, class_dict):
57
+ """
58
+ Create a new class with enforced attributes and method logging.
59
+
60
+ :param name: Name of the class being created.
61
+ :param bases: Tuple of base classes.
62
+ :param class_dict: Dictionary of attributes and methods of the class.
63
+ :return: Newly created class object.
64
+ """
65
+ # Ensure required attributes exist
66
+ for attr in cls.required_attributes:
67
+ if attr not in class_dict:
68
+ raise TypeError(f"Class '{name}' is missing required attribute '{attr}'")
69
+
70
+ # Wrap all methods in a logging decorator
71
+ for key, value in class_dict.items():
72
+ if callable(value): # Check if it's a method
73
+ class_dict[key] = cls.log_calls(value)
74
+
75
+ return super().__new__(cls, name, bases, class_dict)
76
+
77
+ @staticmethod
78
+ def log_calls(func):
79
+ """
80
+ Decorator that logs method calls and arguments.
81
+
82
+ :param func: Function to be wrapped.
83
+ :return: Wrapped function with logging.
84
+ """
85
+ def wrapper(*args, **kwargs):
86
+ print(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
87
+ result = func(*args, **kwargs)
88
+ print(f"{func.__name__} returned {result}")
89
+ return result
90
+ return wrapper
91
+
92
+
93
+ class PluginBase(metaclass=EnforceAttrsMeta):
94
+ """
95
+ Base class for plugins that enforces required attributes and logging.
96
+ """
97
+ name = "BasePlugin"
98
+ version = "1.0"
99
+
100
+ def run(self, data):
101
+ """
102
+ Process the input data.
103
+
104
+ :param data: The data to be processed.
105
+ :return: Processed result.
106
+ """
107
+ return f"Processed {data}"
108
+
109
+
110
+ class CustomPlugin(PluginBase):
111
+ """
112
+ Custom plugin that extends PluginBase and adheres to enforced rules.
113
+ """
114
+ name = "CustomPlugin"
115
+ version = "2.0"
116
+
117
+ def run(self, data):
118
+ """
119
+ Custom processing logic.
120
+
121
+ :param data: The data to process.
122
+ :return: Modified data.
123
+ """
124
+ return f"Custom processing of {data}"
125
+
126
+
127
+ # Uncommenting the following class definition will raise a TypeError
128
+ # because 'version' attribute is missing.
129
+ # class InvalidPlugin(PluginBase):
130
+ # name = "InvalidPlugin"
131
+
132
+
133
+ if __name__ == "__main__":
134
+ # Instantiate and use the plugin
135
+ plugin = CustomPlugin()
136
+ print(plugin.run("example data"))
137
+ ---
138
+ <!DOCTYPE html>
139
+ <html lang="en">
140
+ <head>
141
+ <meta charset="UTF-8">
142
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
143
+ <title>Click the Box Game</title>
144
+ <style>
145
+ body {
146
+ text-align: center;
147
+ font-family: Arial, sans-serif;
148
+ }
149
+ #game-container {
150
+ position: relative;
151
+ width: 300px;
152
+ height: 300px;
153
+ margin: 20px auto;
154
+ border: 2px solid black;
155
+ overflow: hidden;
156
+ }
157
+ #target {
158
+ width: 50px;
159
+ height: 50px;
160
+ background-color: red;
161
+ position: absolute;
162
+ cursor: pointer;
163
+ }
164
+ </style>
165
+ </head>
166
+ <body>
167
+ <h1>Click the Box!</h1>
168
+ <p>Score: <span id="score">0</span></p>
169
+ <div id="game-container">
170
+ <div id="target"></div>
171
+ </div>
172
+ <script>
173
+ let score = 0;
174
+ const target = document.getElementById("target");
175
+ const scoreDisplay = document.getElementById("score");
176
+ const container = document.getElementById("game-container");
177
+
178
+ function moveTarget() {
179
+ const maxX = container.clientWidth - target.clientWidth;
180
+ const maxY = container.clientHeight - target.clientHeight;
181
+ target.style.left = Math.random() * maxX + "px";
182
+ target.style.top = Math.random() * maxY + "px";
183
+ }
184
+
185
+ target.addEventListener("click", function() {
186
+ score++;
187
+ scoreDisplay.textContent = score;
188
+ moveTarget();
189
+ });
190
+
191
+ moveTarget();
192
+ </script>
193
+ </body>
194
+ </html>