@ebowwa/ai 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
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.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # @ebowwa/ai
2
+
3
+ AI/LLM client utilities and GLM API integration with OpenAI-compatible protocol support.
4
+
5
+ ## Features
6
+
7
+ - **OpenAI-Compatible Protocol**: Full support for OpenAI-compatible APIs
8
+ - **GLM-4.7 Integration**: Optimized for Z.AI GLM models (GLM-4.7, GLM-4.6, GLM-4.5, GLM-4.5-air)
9
+ - **Streaming Support**: Server-Sent Events (SSE) streaming for real-time responses
10
+ - **Type-Safe**: Built with TypeScript and Zod for runtime validation
11
+ - **Retry Logic**: Exponential backoff with configurable retries
12
+ - **Timeout Handling**: Configurable timeouts with AbortController
13
+ - **Error Handling**: Specific error types (Timeout, Auth, RateLimit, Network)
14
+ - **Prompt Architecture**: Composable prompt building utilities
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @ebowwa/ai
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Chat Completion
25
+
26
+ ```typescript
27
+ import { GLMClient } from '@ebowwa/ai/client';
28
+
29
+ const client = new GLMClient('your-api-key');
30
+
31
+ const response = await client.chatCompletion([
32
+ { role: 'user', content: 'Hello, how are you?' }
33
+ ]);
34
+
35
+ console.log(response.choices[0].message.content);
36
+ ```
37
+
38
+ ### Streaming
39
+
40
+ ```typescript
41
+ import { GLMClient } from '@ebowwa/ai/client';
42
+
43
+ const client = new GLMClient('your-api-key');
44
+
45
+ for await (const chunk of client.streamGenerate('Tell me a story')) {
46
+ if (chunk.type === 'text') {
47
+ process.stdout.write(chunk.content);
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Prompt Building
53
+
54
+ ```typescript
55
+ import { PromptBuilder } from '@ebowwa/ai/prompts';
56
+
57
+ const prompt = new PromptBuilder()
58
+ .system('helpful assistant', ['Be concise', 'Use examples'])
59
+ .context({ topic: 'programming' })
60
+ .task('Explain async/await in JavaScript')
61
+ .build();
62
+
63
+ const response = await client.generate(prompt);
64
+ ```
65
+
66
+ ## API Reference
67
+
68
+ ### GLMClient
69
+
70
+ Main client for AI chat completions.
71
+
72
+ - `chatCompletion(messages, options)` - Non-streaming chat completion
73
+ - `generate(prompt, options)` - Simple prompt generation
74
+ - `generateWithSystem(systemPrompt, userPrompt, options)` - Generate with system prompt
75
+ - `streamChatCompletion(messages, options)` - Streaming chat completion
76
+ - `streamGenerate(prompt, options)` - Streaming simple prompt
77
+ - `streamGenerateWithSystem(systemPrompt, userPrompt, options)` - Streaming with system prompt
78
+
79
+ ### PromptBuilder
80
+
81
+ Composable prompt architecture for scalable AI interactions.
82
+
83
+ - `system(role, guidelines)` - Set AI role and behavior
84
+ - `context(data)` - Add context data
85
+ - `examples(examples)` - Add few-shot examples
86
+ - `output(type, schema)` - Specify output format
87
+ - `constraints(...rules)` - Add constraints/rules
88
+ - `task(instruction)` - Add main task/instruction
89
+ - `build()` - Build final prompt string
90
+ - `buildChat()` - Build for chat completion (returns messages array)
91
+
92
+ ## Environment Variables
93
+
94
+ Set your API key via environment variables:
95
+
96
+ - `Z_AI_API_KEY` - Primary API key
97
+ - `ZAI_API_KEY` - Alternative API key
98
+ - `GLM_API_KEY` - GLM-specific API key
99
+
100
+ ## License
101
+
102
+ MIT
103
+
104
+ ## Author
105
+
106
+ Ebowwa Labs <labs@ebowwa.com>
@@ -0,0 +1,179 @@
1
+ /**
2
+ * GLM-4.7 AI Client using Z.AI OpenAI-compatible endpoint
3
+ *
4
+ * Based on documentation from: https://api.z.ai/api/coding/paas/v4
5
+ *
6
+ * Usage with any OpenAI-compatible client library:
7
+ * - Base URL: https://api.z.ai/api/coding/paas/v4
8
+ * - Models: GLM-4.7, GLM-4.6, GLM-4.5, GLM-4.5-air
9
+ *
10
+ * === LAYER 1: OpenAI Protocol Implementation ===
11
+ *
12
+ * This client implements the OpenAI-compatible protocol with:
13
+ * - 30s default timeout (configurable)
14
+ * - 3 retries with exponential backoff (1s → 2s → 4s, max 10s)
15
+ * - Specific error types: GLMTimeoutError, GLMAuthError, GLMRateLimitError, GLMNetworkError
16
+ * - AbortController for cancellation
17
+ * - Runtime validation with Zod schemas
18
+ * - SSE streaming support (NOW IMPLEMENTED)
19
+ *
20
+ * LAYER 2 (CLI Wrapper) concerns:
21
+ * - MCP plugin system → See docs/CLI-ARCHITECTURE.md
22
+ * - Session persistence → See docs/CLI-ARCHITECTURE.md
23
+ * - TUI/Ink rendering → See docs/CLI-ARCHITECTURE.md
24
+ *
25
+ * === STREAMING (Layer 1 - OpenAI Protocol) ===
26
+ *
27
+ * Streaming is now fully implemented with SSE (Server-Sent Events) parsing:
28
+ * - streamChatCompletion() - full chat streaming with StreamChunk objects
29
+ * - streamGenerate() - simple prompt streaming
30
+ * - streamGenerateWithSystem() - streaming with system prompt
31
+ *
32
+ * Each method returns an AsyncGenerator that yields StreamChunk objects:
33
+ * - type: "text" - contains incremental content in `content` field
34
+ * - type: "done" - stream complete
35
+ * - type: "error" - error occurred (check `error` field)
36
+ *
37
+ * Final chunk includes usage information (prompt_tokens, completion_tokens, total_tokens)
38
+ */
39
+ declare const fetch: typeof globalThis.fetch;
40
+ import { type ChatCompletionOptions, type ChatMessage, type ChatCompletionResponse, type StreamChunk } from "./schemas/ai.js";
41
+ /**
42
+ * Custom error types for better error handling
43
+ */
44
+ export declare class GLMTimeoutError extends Error {
45
+ constructor(message: string);
46
+ }
47
+ export declare class GLMAuthError extends Error {
48
+ constructor(message: string);
49
+ }
50
+ export declare class GLMRateLimitError extends Error {
51
+ constructor(message: string);
52
+ }
53
+ export declare class GLMNetworkError extends Error {
54
+ readonly cause?: unknown | undefined;
55
+ constructor(message: string, cause?: unknown | undefined);
56
+ }
57
+ /**
58
+ * GLM-4.7 Client for OpenAI-compatible API
59
+ * Includes timeout handling, retry logic, and detailed error reporting
60
+ */
61
+ export declare class GLMClient {
62
+ private apiKey;
63
+ private baseURL;
64
+ private fetchImpl;
65
+ constructor(apiKey?: string, baseURL?: string, fetchImpl?: typeof fetch);
66
+ /**
67
+ * Make a request to the GLM API with timeout and retry logic (for non-streaming)
68
+ */
69
+ private requestWithRetry;
70
+ /**
71
+ * Make a streaming request to the GLM API with timeout and retry logic
72
+ * Returns the raw Response object for SSE parsing
73
+ */
74
+ private requestStream;
75
+ /**
76
+ * Public request method (backward compatibility)
77
+ */
78
+ request<T>(endpoint: string, options?: RequestInit): Promise<{
79
+ data: T;
80
+ latencyMs: number;
81
+ }>;
82
+ /**
83
+ * Validate and parse chat messages using Zod schema
84
+ */
85
+ private validateMessages;
86
+ /**
87
+ * Validate and parse chat completion options using Zod schema
88
+ */
89
+ private parseOptions;
90
+ /**
91
+ * Convert raw API response to internal format with Zod validation
92
+ */
93
+ private convertResponse;
94
+ /**
95
+ * Create a chat completion (non-streaming)
96
+ * Maps API response (snake_case) to internal types (camelCase)
97
+ * Includes latency tracking and configurable timeout
98
+ */
99
+ chatCompletion(messages: ChatMessage[], options?: Partial<ChatCompletionOptions>): Promise<ChatCompletionResponse>;
100
+ /**
101
+ * Simple generate method for quick prompts (non-streaming)
102
+ */
103
+ generate(prompt: string, options?: Partial<Omit<ChatCompletionOptions, "stream">>): Promise<string>;
104
+ /**
105
+ * Generate with system prompt (non-streaming)
106
+ */
107
+ generateWithSystem(systemPrompt: string, userPrompt: string, options?: Partial<Omit<ChatCompletionOptions, "stream">>): Promise<string>;
108
+ /**
109
+ * Stream a chat completion
110
+ *
111
+ * Returns an async generator that yields StreamChunk objects as they arrive.
112
+ * Each chunk contains incremental text content, and the final chunk includes
113
+ * usage information.
114
+ *
115
+ * @param messages - The chat messages to send
116
+ * @param options - Chat completion options (timeout, maxRetries, etc.)
117
+ * @returns Async generator of StreamChunk objects
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * const chunks = [];
122
+ * for await (const chunk of client.streamChatCompletion(messages)) {
123
+ * if (chunk.type === 'text') {
124
+ * chunks.push(chunk.content);
125
+ * process.stdout.write(chunk.content);
126
+ * } else if (chunk.type === 'done') {
127
+ * console.log('\nStream complete!');
128
+ * }
129
+ * }
130
+ * ```
131
+ */
132
+ streamChatCompletion(messages: ChatMessage[], options?: Partial<ChatCompletionOptions>): AsyncGenerator<StreamChunk, void, unknown>;
133
+ /**
134
+ * Stream a simple prompt
135
+ *
136
+ * Returns an async generator that yields chunks of text as they arrive.
137
+ * Simplified interface for single-prompt streaming.
138
+ *
139
+ * @param prompt - The prompt to send
140
+ * @param options - Chat completion options (timeout, maxRetries, etc.)
141
+ * @returns Async generator of StreamChunk objects
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * for await (const chunk of client.streamGenerate("Tell me a story")) {
146
+ * if (chunk.type === 'text') {
147
+ * process.stdout.write(chunk.content);
148
+ * }
149
+ * }
150
+ * ```
151
+ */
152
+ streamGenerate(prompt: string, options?: Partial<ChatCompletionOptions>): AsyncGenerator<StreamChunk, void, unknown>;
153
+ /**
154
+ * Stream with system prompt
155
+ *
156
+ * Returns an async generator that yields chunks of text as they arrive.
157
+ * Includes both system and user prompts.
158
+ *
159
+ * @param systemPrompt - The system prompt
160
+ * @param userPrompt - The user prompt
161
+ * @param options - Chat completion options (timeout, maxRetries, etc.)
162
+ * @returns Async generator of StreamChunk objects
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * for await (const chunk of client.streamGenerateWithSystem(
167
+ * "You are a helpful assistant",
168
+ * "Explain quantum computing"
169
+ * )) {
170
+ * if (chunk.type === 'text') {
171
+ * process.stdout.write(chunk.content);
172
+ * }
173
+ * }
174
+ * ```
175
+ */
176
+ streamGenerateWithSystem(systemPrompt: string, userPrompt: string, options?: Partial<ChatCompletionOptions>): AsyncGenerator<StreamChunk, void, unknown>;
177
+ }
178
+ export declare function getGLMClient(): GLMClient | null;
179
+ export type * from "./schemas/ai.js";