@zodic/shared 0.0.42 → 0.0.44

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/api/index.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import {
2
2
  BackendBindings,
3
+ BatchInputItem,
4
+ BatchProcessingResult,
5
+ BatchResponse,
6
+ ChatGPTFileUploadResponse,
3
7
  ChatMessages,
4
8
  NatalChartInterpretation,
5
9
  } from '../types';
@@ -18,39 +22,120 @@ import {
18
22
  import { makeAstrologyApiCall } from './astrology';
19
23
 
20
24
  export const Api = (env: BackendBindings) => ({
21
- callChatGPT: async (
22
- messages: ChatMessages,
23
- { model = 'gpt-4', options = {} }: ChatGPTOptions
24
- ): Promise<string> => {
25
- const endpoint = 'https://api.openai.com/v1/chat/completions';
26
- const headers = {
27
- 'Content-Type': 'application/json',
28
- Authorization: `Bearer ${env.OPENAI_API_KEY}`,
29
- };
25
+ callChatGPT: {
26
+ single: async (
27
+ messages: ChatMessages,
28
+ { model = 'gpt-4', options = {} }: ChatGPTOptions
29
+ ): Promise<string> => {
30
+ const endpoint = 'https://api.openai.com/v1/chat/completions';
31
+ const headers = {
32
+ 'Content-Type': 'application/json',
33
+ Authorization: `Bearer ${env.OPENAI_API_KEY}`,
34
+ };
30
35
 
31
- const body = JSON.stringify({
32
- model,
33
- messages,
34
- ...options,
35
- });
36
+ const body = JSON.stringify({
37
+ model,
38
+ messages,
39
+ ...options,
40
+ });
36
41
 
37
- try {
38
- const response = await fetch(endpoint, { method: 'POST', headers, body });
42
+ try {
43
+ const response = await fetch(endpoint, {
44
+ method: 'POST',
45
+ headers,
46
+ body,
47
+ });
39
48
 
40
- if (!response.ok) {
41
- const error = await response.json();
42
- console.error('Error from OpenAI API:', error);
43
- throw new Error(`OpenAI API Error: ${response.status}`);
49
+ if (!response.ok) {
50
+ const error = await response.json();
51
+ console.error('Error from OpenAI API:', error);
52
+ throw new Error(`OpenAI API Error: ${response.status}`);
53
+ }
54
+
55
+ const data = (await response.json()) as any;
56
+ return data.choices[0].message.content.trim() as string;
57
+ } catch (err: any) {
58
+ console.error('Error calling ChatGPT API:', err.message);
59
+ throw err;
60
+ }
61
+ },
62
+ batch: async (
63
+ env: BackendBindings,
64
+ batchItems: BatchInputItem[]
65
+ ): Promise<BatchProcessingResult[]> => {
66
+ console.log('Preparing to send ChatGPT batch request.');
67
+
68
+ const uploadEndpoint = 'https://api.openai.com/v1/files';
69
+ const batchEndpoint = 'https://api.openai.com/v1/batches';
70
+ const apiKey = env.OPENAI_API_KEY;
71
+
72
+ if (!apiKey) {
73
+ throw new Error('OPENAI_API_KEY is not defined in the environment.');
44
74
  }
45
75
 
46
- const data = (await response.json()) as any;
47
- return data.choices[0].message.content.trim() as string;
48
- } catch (err: any) {
49
- console.error('Error calling ChatGPT API:', err.message);
50
- throw err;
51
- }
52
- },
76
+ try {
77
+ // Step 1: Upload the input file
78
+ const inputFile = JSON.stringify(batchItems);
79
+ const uploadResponse = await fetch(uploadEndpoint, {
80
+ method: 'POST',
81
+ headers: {
82
+ Authorization: `Bearer ${apiKey}`,
83
+ },
84
+ body: new Blob([inputFile], { type: 'application/json' }),
85
+ });
86
+
87
+ if (!uploadResponse.ok) {
88
+ const uploadError = await uploadResponse.json();
89
+ console.error('Failed to upload input file:', uploadError);
90
+ throw new Error(
91
+ `File upload failed with status ${uploadResponse.status}`
92
+ );
93
+ }
53
94
 
95
+ const uploadData =
96
+ (await uploadResponse.json()) as ChatGPTFileUploadResponse;
97
+ const fileId = uploadData.id;
98
+ console.log(`File uploaded successfully. File ID: ${fileId}`);
99
+
100
+ // Step 2: Submit the batch request
101
+ const batchPayload = {
102
+ file: fileId,
103
+ purpose: 'fine-tune', // Define the correct purpose based on OpenAI's API
104
+ };
105
+
106
+ const batchResponse = await fetch(batchEndpoint, {
107
+ method: 'POST',
108
+ headers: {
109
+ 'Content-Type': 'application/json',
110
+ Authorization: `Bearer ${apiKey}`,
111
+ },
112
+ body: JSON.stringify(batchPayload),
113
+ });
114
+
115
+ if (!batchResponse.ok) {
116
+ const batchError = await batchResponse.json();
117
+ console.error('Failed to create batch:', batchError);
118
+ throw new Error(
119
+ `Batch creation failed with status ${batchResponse.status}`
120
+ );
121
+ }
122
+
123
+ const batchData = (await batchResponse.json()) as BatchResponse;
124
+ console.log(`Batch created successfully. Batch ID: ${batchData.id}`);
125
+
126
+ // Step 3: Poll for batch results (not shown here; depends on the implementation)
127
+
128
+ return batchItems.map((item) => ({
129
+ id: item.id,
130
+ status: 'completed', // Placeholder; actual status would depend on polling results
131
+ content: undefined, // Placeholder for actual response
132
+ }));
133
+ } catch (error) {
134
+ console.error('Error in callChatGPTBatch:', error);
135
+ throw error;
136
+ }
137
+ },
138
+ },
54
139
  callLeonardo: {
55
140
  generateImage: async ({
56
141
  prompt,
@@ -1,6 +1,6 @@
1
1
  import { inject } from 'inversify';
2
- import { ConceptService } from '../services/ConceptService';
3
2
  import { ConceptPhase } from '../../types/scopes/legacy';
3
+ import { ConceptService } from '../services/ConceptService';
4
4
 
5
5
  export class ConceptWorkflow {
6
6
  constructor(@inject(ConceptService) private conceptService: ConceptService) {}
@@ -16,7 +16,7 @@ export class ConceptWorkflow {
16
16
 
17
17
  try {
18
18
  switch (phase) {
19
- case 'name-description-poem':
19
+ case 'basic-info':
20
20
  await this.conceptService.generateBasicInfo(
21
21
  conceptSlug,
22
22
  combinationString
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -139,3 +139,45 @@ export type ConceptQueueMessage = {
139
139
  combinationString: string;
140
140
  phase: ConceptPhase;
141
141
  };
142
+
143
+ export type BatchInputItem = {
144
+ id: string;
145
+ messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>;
146
+ };
147
+
148
+ export type BatchResponseItem = {
149
+ id: string;
150
+ status: 'completed' | 'failed';
151
+ result?: {
152
+ choices: Array<{
153
+ message: {
154
+ role: string;
155
+ content: string;
156
+ };
157
+ }>;
158
+ };
159
+ error?: any;
160
+ };
161
+
162
+ export type BatchProcessingResult = {
163
+ id: string;
164
+ status: 'completed' | 'failed';
165
+ content?: string;
166
+ error?: any;
167
+ };
168
+
169
+ export type ChatGPTBatchResult = {
170
+ id: string;
171
+ status: 'completed' | 'failed';
172
+ content?: string;
173
+ error?: any;
174
+ };
175
+
176
+ export type ChatGPTFileUploadResponse = {
177
+ id: string; // Unique identifier for the uploaded file
178
+ object: string; // Type of the object, usually "file"
179
+ bytes: number; // File size in bytes
180
+ created_at: number; // Timestamp when the file was created
181
+ filename: string; // Name of the uploaded file
182
+ purpose: string; // Purpose of the file, e.g., "fine-tune"
183
+ };
@@ -2,7 +2,7 @@ import { BackendBindings } from './cloudflare';
2
2
  import { Gender } from './generic';
3
3
 
4
4
  export type ConceptPhase =
5
- | 'name-description-poem'
5
+ | 'basic-info'
6
6
  | 'leonardo-prompt'
7
7
  | 'content'
8
8
  | 'images';