@ebowwa/ai 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/client.d.ts → client.d.ts} +3 -2
- package/client.d.ts.map +1 -0
- package/client.js +736 -0
- package/client.js.map +1 -0
- package/client.ts +688 -0
- package/index.js +34 -0
- package/{dist/index.d.ts → index.ts} +10 -2
- package/package.json +16 -50
- package/prompts.js +550 -0
- package/prompts.ts +551 -0
- package/types.js +22 -0
- package/{dist/types.js → types.ts} +12 -1
- package/LICENSE +0 -21
- package/README.md +0 -106
- package/dist/client.js +0 -492
- package/dist/index.js +0 -18
- package/dist/prompts.d.ts +0 -222
- package/dist/prompts.js +0 -462
- package/dist/schemas/ai.d.ts +0 -1335
- package/dist/schemas/ai.js +0 -416
- package/dist/schemas/glm.d.ts +0 -16
- package/dist/schemas/glm.js +0 -25
- package/dist/schemas/index.d.ts +0 -5
- package/dist/schemas/index.js +0 -5
- package/dist/types.d.ts +0 -13
package/prompts.ts
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable prompt architecture for scalable AI interactions
|
|
3
|
+
*
|
|
4
|
+
* Core concepts:
|
|
5
|
+
* - PromptPart: Composable building blocks
|
|
6
|
+
* - PromptBuilder: Fluent API for assembling prompts
|
|
7
|
+
* - PromptTemplate: Reusable templates with interpolation
|
|
8
|
+
* - PromptChain: Multi-step workflows
|
|
9
|
+
* - PromptStrategy: Different reasoning approaches
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Import and re-export ChatMessage for type compatibility
|
|
13
|
+
import type { ChatMessage } from "./types.js";
|
|
14
|
+
|
|
15
|
+
export type { ChatMessage };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Base interface for all composable prompt parts
|
|
19
|
+
*/
|
|
20
|
+
export interface PromptPart {
|
|
21
|
+
toPrompt(): string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* System instruction - sets AI role and behavior
|
|
26
|
+
*/
|
|
27
|
+
export class SystemInstruction implements PromptPart {
|
|
28
|
+
constructor(
|
|
29
|
+
public role: string,
|
|
30
|
+
public guidelines?: string[],
|
|
31
|
+
) {}
|
|
32
|
+
|
|
33
|
+
toPrompt(): string {
|
|
34
|
+
const base = `You are a ${this.role}.`;
|
|
35
|
+
if (this.guidelines?.length) {
|
|
36
|
+
return `${base}\n\nGuidelines:\n${this.guidelines.map((g) => `- ${g}`).join("\n")}`;
|
|
37
|
+
}
|
|
38
|
+
return base;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Context - provides data/background information
|
|
44
|
+
*/
|
|
45
|
+
export class Context implements PromptPart {
|
|
46
|
+
constructor(public data: Record<string, unknown>) {}
|
|
47
|
+
|
|
48
|
+
toPrompt(): string {
|
|
49
|
+
const entries = Object.entries(this.data)
|
|
50
|
+
.filter(([_, v]) => v !== undefined && v !== null && v !== "")
|
|
51
|
+
.map(
|
|
52
|
+
([k, v]) => `- ${k}: ${typeof v === "object" ? JSON.stringify(v) : v}`,
|
|
53
|
+
)
|
|
54
|
+
.join("\n");
|
|
55
|
+
return entries ? `Context:\n${entries}` : "";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Examples - few-shot learning samples
|
|
61
|
+
*/
|
|
62
|
+
export class Examples implements PromptPart {
|
|
63
|
+
constructor(public examples: Array<{ input: string; output: string }>) {}
|
|
64
|
+
|
|
65
|
+
toPrompt(): string {
|
|
66
|
+
if (this.examples.length === 0) return "";
|
|
67
|
+
return this.examples
|
|
68
|
+
.map(
|
|
69
|
+
(ex, i) =>
|
|
70
|
+
`Example ${i + 1}:\nInput: ${ex.input}\nOutput: ${ex.output}`,
|
|
71
|
+
)
|
|
72
|
+
.join("\n\n");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Output format specification
|
|
78
|
+
*/
|
|
79
|
+
export class OutputFormat implements PromptPart {
|
|
80
|
+
constructor(
|
|
81
|
+
public type: "json" | "text" | "code" | "markdown",
|
|
82
|
+
public schema?: Record<string, unknown>,
|
|
83
|
+
) {}
|
|
84
|
+
|
|
85
|
+
toPrompt(): string {
|
|
86
|
+
if (this.type === "json" && this.schema) {
|
|
87
|
+
return `Respond in JSON format with this schema:\n${JSON.stringify(this.schema, null, 2)}`;
|
|
88
|
+
}
|
|
89
|
+
return `Respond in ${this.type} format.`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Constraints - rules and limitations
|
|
95
|
+
*/
|
|
96
|
+
export class Constraints implements PromptPart {
|
|
97
|
+
constructor(public rules: string[]) {}
|
|
98
|
+
|
|
99
|
+
toPrompt(): string {
|
|
100
|
+
if (this.rules.length === 0) return "";
|
|
101
|
+
return `Constraints:\n${this.rules.map((r) => `- ${r}`).join("\n")}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Task - the main instruction/question
|
|
107
|
+
*/
|
|
108
|
+
export class Task implements PromptPart {
|
|
109
|
+
constructor(public instruction: string) {}
|
|
110
|
+
|
|
111
|
+
toPrompt(): string {
|
|
112
|
+
return `Task:\n${this.instruction}`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Fluent builder for composable prompts
|
|
118
|
+
*/
|
|
119
|
+
export class PromptBuilder {
|
|
120
|
+
private parts: PromptPart[] = [];
|
|
121
|
+
private systemPart?: SystemInstruction;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Set system role and guidelines
|
|
125
|
+
*/
|
|
126
|
+
system(role: string, guidelines?: string[]): this {
|
|
127
|
+
this.systemPart = new SystemInstruction(role, guidelines);
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Add context data
|
|
133
|
+
*/
|
|
134
|
+
context(data: Record<string, unknown>): this {
|
|
135
|
+
this.parts.push(new Context(data));
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Add few-shot examples
|
|
141
|
+
*/
|
|
142
|
+
examples(examples: Array<{ input: string; output: string }>): this {
|
|
143
|
+
this.parts.push(new Examples(examples));
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Specify output format
|
|
149
|
+
*/
|
|
150
|
+
output(
|
|
151
|
+
type: "json" | "text" | "code" | "markdown",
|
|
152
|
+
schema?: Record<string, unknown>,
|
|
153
|
+
): this {
|
|
154
|
+
this.parts.push(new OutputFormat(type, schema));
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Add constraints/rules
|
|
160
|
+
*/
|
|
161
|
+
constraints(...rules: string[]): this {
|
|
162
|
+
this.parts.push(new Constraints(rules));
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Add the main task/instruction
|
|
168
|
+
*/
|
|
169
|
+
task(instruction: string): this {
|
|
170
|
+
this.parts.push(new Task(instruction));
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Add custom prompt part
|
|
176
|
+
*/
|
|
177
|
+
custom(part: PromptPart): this {
|
|
178
|
+
this.parts.push(part);
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Build final prompt string (for simple generate)
|
|
184
|
+
*/
|
|
185
|
+
build(): string {
|
|
186
|
+
const allParts = [
|
|
187
|
+
...(this.systemPart ? [this.systemPart] : []),
|
|
188
|
+
...this.parts,
|
|
189
|
+
];
|
|
190
|
+
return allParts
|
|
191
|
+
.map((p) => p.toPrompt())
|
|
192
|
+
.filter(Boolean)
|
|
193
|
+
.join("\n\n");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Build for chat completion (returns messages array)
|
|
198
|
+
*/
|
|
199
|
+
buildChat(): ChatMessage[] {
|
|
200
|
+
const messages: ChatMessage[] = [];
|
|
201
|
+
|
|
202
|
+
if (this.systemPart) {
|
|
203
|
+
messages.push({ role: "system", content: this.systemPart.toPrompt() });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const userContent = this.parts
|
|
207
|
+
.map((p) => p.toPrompt())
|
|
208
|
+
.filter(Boolean)
|
|
209
|
+
.join("\n\n");
|
|
210
|
+
if (userContent) {
|
|
211
|
+
messages.push({ role: "user", content: userContent });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return messages;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Build as system + user prompt pair
|
|
219
|
+
*/
|
|
220
|
+
buildPair(): { system: string; user: string } {
|
|
221
|
+
return {
|
|
222
|
+
system: this.systemPart?.toPrompt() || "",
|
|
223
|
+
user: this.parts
|
|
224
|
+
.map((p) => p.toPrompt())
|
|
225
|
+
.filter(Boolean)
|
|
226
|
+
.join("\n\n"),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Reusable prompt template with variable interpolation
|
|
233
|
+
*/
|
|
234
|
+
export class PromptTemplate {
|
|
235
|
+
constructor(private template: string) {}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Render template with variables
|
|
239
|
+
* Supports {{variable}} syntax
|
|
240
|
+
*/
|
|
241
|
+
render(vars: Record<string, unknown>): string {
|
|
242
|
+
let result = this.template;
|
|
243
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
244
|
+
const placeholder = `{{${key}}}`;
|
|
245
|
+
result = result.replaceAll(placeholder, String(value ?? ""));
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Create template from string
|
|
252
|
+
*/
|
|
253
|
+
static from(template: string): PromptTemplate {
|
|
254
|
+
return new PromptTemplate(template);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Create typed template with compile-time safety
|
|
259
|
+
*/
|
|
260
|
+
static typed<T extends Record<string, unknown>>(
|
|
261
|
+
template: string,
|
|
262
|
+
): TypedPromptTemplate<T> {
|
|
263
|
+
return new TypedPromptTemplate(template);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Type-safe prompt template
|
|
269
|
+
*/
|
|
270
|
+
export class TypedPromptTemplate<T extends Record<string, unknown>> {
|
|
271
|
+
constructor(private template: string) {}
|
|
272
|
+
|
|
273
|
+
render(vars: T): string {
|
|
274
|
+
return new PromptTemplate(this.template).render(vars);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Prompt strategies for different reasoning approaches
|
|
280
|
+
*/
|
|
281
|
+
export class PromptStrategy {
|
|
282
|
+
/**
|
|
283
|
+
* Zero-shot: direct instruction without examples
|
|
284
|
+
*/
|
|
285
|
+
static zeroShot(instruction: string): string {
|
|
286
|
+
return instruction;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Few-shot: instruction with examples
|
|
291
|
+
*/
|
|
292
|
+
static fewShot(
|
|
293
|
+
instruction: string,
|
|
294
|
+
examples: Array<{ input: string; output: string }>,
|
|
295
|
+
): string {
|
|
296
|
+
return new PromptBuilder().examples(examples).task(instruction).build();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Chain-of-thought: step-by-step reasoning
|
|
301
|
+
*/
|
|
302
|
+
static chainOfThought(question: string): string {
|
|
303
|
+
return `${question}\n\nThink step by step. Show your work and reasoning process.`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* ReAct: Reasoning + Acting (for tool use)
|
|
308
|
+
*/
|
|
309
|
+
static reAct(task: string): string {
|
|
310
|
+
return `Task: ${task}
|
|
311
|
+
|
|
312
|
+
Think: [your reasoning about the current state]
|
|
313
|
+
Act: [action to take]
|
|
314
|
+
Observation: [result of action]
|
|
315
|
+
|
|
316
|
+
Repeat Think/Act/Observation until the task is complete.`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Chain prompts where output feeds into next input
|
|
322
|
+
*/
|
|
323
|
+
export class PromptChain {
|
|
324
|
+
private steps: Array<(input: string, client: any) => Promise<string>> = [];
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Add a step to the chain
|
|
328
|
+
*/
|
|
329
|
+
add(step: (input: string, client: any) => Promise<string>): this {
|
|
330
|
+
this.steps.push(step);
|
|
331
|
+
return this;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Execute the entire chain
|
|
336
|
+
*/
|
|
337
|
+
async execute(initialInput: string, client: any): Promise<string[]> {
|
|
338
|
+
const results: string[] = [];
|
|
339
|
+
let current = initialInput;
|
|
340
|
+
|
|
341
|
+
for (const step of this.steps) {
|
|
342
|
+
current = await step(current, client);
|
|
343
|
+
results.push(current);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return results;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ============================================================================
|
|
351
|
+
// PRE-BUILT PROMPTS (Refactored using composable architecture)
|
|
352
|
+
// ============================================================================
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Pre-built prompt templates for common AI tasks
|
|
356
|
+
*/
|
|
357
|
+
export const PROMPTS = {
|
|
358
|
+
/**
|
|
359
|
+
* Generate a server name based on project context
|
|
360
|
+
*/
|
|
361
|
+
generateServerName: (project?: string, description?: string) => {
|
|
362
|
+
return new PromptBuilder()
|
|
363
|
+
.system("server naming specialist", [
|
|
364
|
+
"Create memorable, technical names",
|
|
365
|
+
"Use lowercase letters and hyphens only",
|
|
366
|
+
])
|
|
367
|
+
.context({ project, description })
|
|
368
|
+
.constraints(
|
|
369
|
+
"8-15 characters maximum",
|
|
370
|
+
"lowercase letters only",
|
|
371
|
+
"hyphens allowed but no consecutive hyphens",
|
|
372
|
+
"Return ONLY the name, no explanation",
|
|
373
|
+
)
|
|
374
|
+
.task("Generate a short, memorable server name.")
|
|
375
|
+
.build();
|
|
376
|
+
},
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Suggest optimal server type based on workload
|
|
380
|
+
*/
|
|
381
|
+
suggestServerType: (workload: string) => {
|
|
382
|
+
return new PromptBuilder()
|
|
383
|
+
.system("Hetzner cloud infrastructure expert", [
|
|
384
|
+
"Know all Hetzner server types and their capabilities",
|
|
385
|
+
"Consider cost-effectiveness",
|
|
386
|
+
])
|
|
387
|
+
.context({ workload })
|
|
388
|
+
.examples([
|
|
389
|
+
{
|
|
390
|
+
input: "High-traffic web server with moderate CPU needs",
|
|
391
|
+
output:
|
|
392
|
+
"cpx21 - Good balance of performance and cost for web workloads",
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
input: "Development/testing server",
|
|
396
|
+
output: "cpx11 - Lowest cost option, sufficient for development",
|
|
397
|
+
},
|
|
398
|
+
])
|
|
399
|
+
.constraints(
|
|
400
|
+
"Respond with just the server type name",
|
|
401
|
+
"Follow with one brief sentence explaining why",
|
|
402
|
+
"Suggest any appropriate Hetzner server type based on the workload needs",
|
|
403
|
+
)
|
|
404
|
+
.task("Suggest the best Hetzner server type for this workload.")
|
|
405
|
+
.build();
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Analyze resource usage and provide recommendations
|
|
410
|
+
*/
|
|
411
|
+
analyzeResources: (
|
|
412
|
+
cpu: number,
|
|
413
|
+
memory: number,
|
|
414
|
+
disk: number,
|
|
415
|
+
activePorts?: string[],
|
|
416
|
+
) => {
|
|
417
|
+
const contextData: Record<string, unknown> = {
|
|
418
|
+
cpu: `${cpu}%`,
|
|
419
|
+
memory: `${memory}%`,
|
|
420
|
+
disk: `${disk}%`,
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
if (activePorts && activePorts.length > 0) {
|
|
424
|
+
contextData.activePorts =
|
|
425
|
+
activePorts.slice(0, 10).join(", ") +
|
|
426
|
+
(activePorts.length > 10 ? ` (+${activePorts.length - 10} more)` : "");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return new PromptBuilder()
|
|
430
|
+
.system("DevOps monitoring specialist", [
|
|
431
|
+
"Assess server health holistically",
|
|
432
|
+
"Prioritize actionable advice",
|
|
433
|
+
])
|
|
434
|
+
.context(contextData)
|
|
435
|
+
.examples([
|
|
436
|
+
{
|
|
437
|
+
input: "CPU: 95%, Memory: 90%, Disk: 50%",
|
|
438
|
+
output:
|
|
439
|
+
"CRITICAL: Immediate scale-up required. CPU and memory are at dangerous levels.",
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
input: "CPU: 15%, Memory: 25%, Disk: 30%",
|
|
443
|
+
output: "HEALTHY: All metrics within normal range. No action needed.",
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
input: "CPU: 45%, Memory: 85%, Disk: 20%",
|
|
447
|
+
output:
|
|
448
|
+
"WARNING: Memory usage high. Consider optimizing applications or upgrading memory.",
|
|
449
|
+
},
|
|
450
|
+
])
|
|
451
|
+
.constraints(
|
|
452
|
+
"Assessment must be one of: HEALTHY, WARNING, CRITICAL",
|
|
453
|
+
"Provide exactly one sentence for assessment",
|
|
454
|
+
"Provide exactly one actionable recommendation if not HEALTHY",
|
|
455
|
+
"Keep total response under 100 words",
|
|
456
|
+
)
|
|
457
|
+
.task("Analyze the server resource usage and provide health assessment.")
|
|
458
|
+
.build();
|
|
459
|
+
},
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Generate SSH troubleshooting tips
|
|
463
|
+
*/
|
|
464
|
+
sshTroubleshoot: (error: string) => {
|
|
465
|
+
return new PromptBuilder()
|
|
466
|
+
.system("SSH troubleshooting expert", [
|
|
467
|
+
"Know common SSH issues and solutions",
|
|
468
|
+
"Provide practical, step-by-step solutions",
|
|
469
|
+
])
|
|
470
|
+
.context({ error })
|
|
471
|
+
.examples([
|
|
472
|
+
{
|
|
473
|
+
input: "Connection refused",
|
|
474
|
+
output:
|
|
475
|
+
"1. Verify SSH service is running: systemctl status sshd\n2. Check firewall rules\n3. Confirm correct port (usually 22)",
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
input: "Permission denied (publickey)",
|
|
479
|
+
output:
|
|
480
|
+
"1. Verify public key is added to server's ~/.ssh/authorized_keys\n2. Check file permissions: chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys\n3. Ensure you're using the correct private key",
|
|
481
|
+
},
|
|
482
|
+
])
|
|
483
|
+
.constraints(
|
|
484
|
+
"Provide 2-3 specific troubleshooting steps",
|
|
485
|
+
"Each step should be actionable",
|
|
486
|
+
"Keep responses concise",
|
|
487
|
+
)
|
|
488
|
+
.task("Provide SSH troubleshooting steps for this error.")
|
|
489
|
+
.build();
|
|
490
|
+
},
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Suggest server actions based on state
|
|
494
|
+
*/
|
|
495
|
+
suggestActions: (status: string, age?: string) => {
|
|
496
|
+
return new PromptBuilder()
|
|
497
|
+
.system("Server operations specialist", [
|
|
498
|
+
"Understand server lifecycle management",
|
|
499
|
+
"Consider cost implications",
|
|
500
|
+
])
|
|
501
|
+
.context({ status, age })
|
|
502
|
+
.examples([
|
|
503
|
+
{
|
|
504
|
+
input: "Status: stopped, Age: 2 hours",
|
|
505
|
+
output:
|
|
506
|
+
"Actions: start (to resume service), delete (if no longer needed)",
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
input: "Status: running, Age: 30 days",
|
|
510
|
+
output:
|
|
511
|
+
"Actions: reboot (for maintenance), resize (if performance issues)",
|
|
512
|
+
},
|
|
513
|
+
])
|
|
514
|
+
.constraints(
|
|
515
|
+
"Suggest 1-2 appropriate actions",
|
|
516
|
+
"Include very brief explanation for each",
|
|
517
|
+
"Consider actions: start, stop, restart, delete, resize",
|
|
518
|
+
)
|
|
519
|
+
.task("Suggest appropriate server management actions.")
|
|
520
|
+
.build();
|
|
521
|
+
},
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Generate a witty server status message
|
|
525
|
+
*/
|
|
526
|
+
statusMessage: (status: string, name: string) => {
|
|
527
|
+
return new PromptBuilder()
|
|
528
|
+
.system("Playful status message generator", [
|
|
529
|
+
"Be lighthearted but professional",
|
|
530
|
+
"Use puns and wordplay when appropriate",
|
|
531
|
+
])
|
|
532
|
+
.context({ status, name })
|
|
533
|
+
.examples([
|
|
534
|
+
{
|
|
535
|
+
input: "Status: running, Name: prod-db-01",
|
|
536
|
+
output: "🟢 prod-db-01 is alive and kicking!",
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
input: "Status: stopped, Name: dev-server",
|
|
540
|
+
output: "💤 dev-server is taking a nap",
|
|
541
|
+
},
|
|
542
|
+
])
|
|
543
|
+
.constraints(
|
|
544
|
+
"Keep under 50 characters",
|
|
545
|
+
"Use appropriate emoji for status",
|
|
546
|
+
"Be creative and memorable",
|
|
547
|
+
)
|
|
548
|
+
.task("Generate a brief, witty status message.")
|
|
549
|
+
.build();
|
|
550
|
+
},
|
|
551
|
+
} as const;
|
package/types.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI protocol related types for the application
|
|
4
|
+
*
|
|
5
|
+
* This file now re-exports types from schema.ts for backward compatibility.
|
|
6
|
+
* New code should import directly from schema.ts.
|
|
7
|
+
*
|
|
8
|
+
* Schema provides:
|
|
9
|
+
* - Runtime validation with Zod
|
|
10
|
+
* - Type inference for TypeScript
|
|
11
|
+
* - Helper functions for validation
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.categorizeError = exports.convertUsage = exports.validateRawResponse = exports.validateChatCompletionOptions = exports.validateChatMessages = exports.validateChatMessage = void 0;
|
|
15
|
+
// Re-export validation helpers for convenience
|
|
16
|
+
var ai_1 = require("@ebowwa/codespaces-types/runtime/ai");
|
|
17
|
+
Object.defineProperty(exports, "validateChatMessage", { enumerable: true, get: function () { return ai_1.validateChatMessage; } });
|
|
18
|
+
Object.defineProperty(exports, "validateChatMessages", { enumerable: true, get: function () { return ai_1.validateChatMessages; } });
|
|
19
|
+
Object.defineProperty(exports, "validateChatCompletionOptions", { enumerable: true, get: function () { return ai_1.validateChatCompletionOptions; } });
|
|
20
|
+
Object.defineProperty(exports, "validateRawResponse", { enumerable: true, get: function () { return ai_1.validateRawResponse; } });
|
|
21
|
+
Object.defineProperty(exports, "convertUsage", { enumerable: true, get: function () { return ai_1.convertUsage; } });
|
|
22
|
+
Object.defineProperty(exports, "categorizeError", { enumerable: true, get: function () { return ai_1.categorizeError; } });
|
|
@@ -9,5 +9,16 @@
|
|
|
9
9
|
* - Type inference for TypeScript
|
|
10
10
|
* - Helper functions for validation
|
|
11
11
|
*/
|
|
12
|
+
|
|
13
|
+
// Re-export all types from schema
|
|
14
|
+
export type * from "@ebowwa/codespaces-types/runtime/ai";
|
|
15
|
+
|
|
12
16
|
// Re-export validation helpers for convenience
|
|
13
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
validateChatMessage,
|
|
19
|
+
validateChatMessages,
|
|
20
|
+
validateChatCompletionOptions,
|
|
21
|
+
validateRawResponse,
|
|
22
|
+
convertUsage,
|
|
23
|
+
categorizeError,
|
|
24
|
+
} from "@ebowwa/codespaces-types/runtime/ai";
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Ebowwa Labs
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|