@astrive-ai/providers 1.0.9 → 1.0.11

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/index.d.ts CHANGED
@@ -2,4 +2,5 @@ export * from './base-provider.js';
2
2
  export * from './provider-manager.js';
3
3
  export * from './groq-provider.js';
4
4
  export * from './openai-compatible-provider.js';
5
+ export * from './overchat-provider.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ export * from './base-provider.js';
2
2
  export * from './provider-manager.js';
3
3
  export * from './groq-provider.js';
4
4
  export * from './openai-compatible-provider.js';
5
+ export * from './overchat-provider.js';
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { BaseProvider } from './base-provider.js';
2
+ import { ChatRequest, ChatResponse, ChatChunk, ILogger, IEventEmitter } from '@astrive-ai/types';
3
+ export declare class OverchatProvider extends BaseProvider {
4
+ private API;
5
+ private ua;
6
+ private models;
7
+ constructor(logger: ILogger, events: IEventEmitter);
8
+ isAvailable(): boolean;
9
+ private buildOverchatHeaders;
10
+ private mapMessages;
11
+ chat(request: ChatRequest): Promise<ChatResponse>;
12
+ chatStream(request: ChatRequest): AsyncGenerator<ChatChunk, void, unknown>;
13
+ getModels(): string[];
14
+ supportsFeature(feature: string): boolean;
15
+ }
16
+ //# sourceMappingURL=overchat-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overchat-provider.d.ts","sourceRoot":"","sources":["../src/overchat-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGjG,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,GAAG,CAAiD;IAC5D,OAAO,CAAC,EAAE,CAAqH;IAC/H,OAAO,CAAC,MAAM,CAAiC;gBAEnC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAIlC,WAAW,IAAI,OAAO;IAItC,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,WAAW;IAkBN,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA+ChD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;IA+EjF,SAAS,IAAI,MAAM,EAAE;IAIrB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;CAIjD"}
@@ -0,0 +1,170 @@
1
+ import { BaseProvider } from './base-provider.js';
2
+ import crypto from 'node:crypto';
3
+ export class OverchatProvider extends BaseProvider {
4
+ API = "https://api.overchat.ai/v1/chat/completions";
5
+ ua = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Mobile Safari/537.36";
6
+ models = ["claude-haiku-4-5-20251001"];
7
+ constructor(logger, events) {
8
+ super('overchat', 'community', logger, events);
9
+ }
10
+ isAvailable() {
11
+ return true; // No API key required
12
+ }
13
+ buildOverchatHeaders(deviceId) {
14
+ return {
15
+ "sec-ch-ua-platform": `"Android"`,
16
+ "x-device-uuid": deviceId,
17
+ "sec-ch-ua": `"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"`,
18
+ "sec-ch-ua-mobile": "?1",
19
+ "x-device-language": "id-ID",
20
+ "x-device-platform": "web",
21
+ "x-device-version": "1.0.44",
22
+ "user-agent": this.ua,
23
+ accept: "*/*",
24
+ "content-type": "application/json",
25
+ origin: "https://overchat.ai",
26
+ referer: "https://overchat.ai/",
27
+ "accept-language": "id-ID,id;q=0.9",
28
+ priority: "u=1, i",
29
+ };
30
+ }
31
+ mapMessages(request) {
32
+ return request.messages.map(msg => {
33
+ const mapped = { ...msg };
34
+ if (!mapped.id)
35
+ mapped.id = crypto.randomUUID();
36
+ if (mapped.tool_calls) {
37
+ mapped.tool_calls = mapped.tool_calls.map((tc) => ({
38
+ id: tc.id,
39
+ type: 'function',
40
+ function: {
41
+ name: tc.name || tc.function?.name,
42
+ arguments: typeof tc.arguments === 'string' ? tc.arguments : (typeof tc.function?.arguments === 'string' ? tc.function.arguments : JSON.stringify(tc.arguments || tc.function?.arguments))
43
+ }
44
+ }));
45
+ }
46
+ return mapped;
47
+ });
48
+ }
49
+ async chat(request) {
50
+ const chatId = crypto.randomUUID();
51
+ const deviceId = crypto.randomUUID();
52
+ const body = {
53
+ chatId,
54
+ model: this.models[0],
55
+ messages: this.mapMessages(request),
56
+ personaId: "claude-haiku-4-5-landing",
57
+ frequency_penalty: 0,
58
+ max_tokens: request.maxTokens || 4000,
59
+ presence_penalty: 0,
60
+ stream: false,
61
+ temperature: request.temperature || 0.5,
62
+ top_p: 0.95,
63
+ };
64
+ if (request.tools && request.tools.length > 0) {
65
+ body.tools = request.tools;
66
+ }
67
+ const response = await fetch(this.API, {
68
+ method: "POST",
69
+ headers: this.buildOverchatHeaders(deviceId),
70
+ body: JSON.stringify(body)
71
+ });
72
+ if (!response.ok) {
73
+ const text = await response.text();
74
+ throw new Error(`HTTP ${response.status}: ${text}`);
75
+ }
76
+ const data = await response.json();
77
+ return {
78
+ id: data.id || crypto.randomUUID(),
79
+ content: data.choices?.[0]?.message?.content || '',
80
+ role: 'assistant',
81
+ toolCalls: data.choices?.[0]?.message?.tool_calls?.map((tc) => ({
82
+ id: tc.id,
83
+ name: tc.function.name,
84
+ arguments: typeof tc.function.arguments === 'string' ? JSON.parse(tc.function.arguments) : tc.function.arguments
85
+ })),
86
+ model: data.model || this.models[0],
87
+ finishReason: data.choices?.[0]?.finish_reason || 'stop'
88
+ };
89
+ }
90
+ async *chatStream(request) {
91
+ const chatId = crypto.randomUUID();
92
+ const deviceId = crypto.randomUUID();
93
+ const body = {
94
+ chatId,
95
+ model: this.models[0],
96
+ messages: this.mapMessages(request),
97
+ personaId: "claude-haiku-4-5-landing",
98
+ frequency_penalty: 0,
99
+ max_tokens: request.maxTokens || 4000,
100
+ presence_penalty: 0,
101
+ stream: true,
102
+ temperature: request.temperature || 0.5,
103
+ top_p: 0.95,
104
+ };
105
+ if (request.tools && request.tools.length > 0) {
106
+ body.tools = request.tools;
107
+ }
108
+ const response = await fetch(this.API, {
109
+ method: "POST",
110
+ headers: this.buildOverchatHeaders(deviceId),
111
+ body: JSON.stringify(body),
112
+ });
113
+ if (!response.ok) {
114
+ throw new Error(`HTTP ${response.status}: ${await response.text()}`);
115
+ }
116
+ if (!response.body)
117
+ throw new Error('No response body');
118
+ const reader = response.body.getReader();
119
+ const decoder = new TextDecoder('utf-8');
120
+ let buffer = '';
121
+ while (true) {
122
+ const { done, value } = await reader.read();
123
+ if (done)
124
+ break;
125
+ buffer += decoder.decode(value, { stream: true });
126
+ const lines = buffer.split('\n');
127
+ buffer = lines.pop() || '';
128
+ for (const rawLine of lines) {
129
+ const line = rawLine.trim();
130
+ if (!line.startsWith("data:"))
131
+ continue;
132
+ const data = line.slice(5).trim();
133
+ if (!data || data === "[DONE]") {
134
+ if (data === "[DONE]")
135
+ yield { content: '', done: true };
136
+ continue;
137
+ }
138
+ try {
139
+ const json = JSON.parse(data);
140
+ const delta = json.choices?.[0]?.delta;
141
+ if (delta) {
142
+ if (delta.content) {
143
+ yield { content: delta.content, done: false };
144
+ }
145
+ if (delta.tool_calls) {
146
+ yield {
147
+ content: '',
148
+ done: false,
149
+ toolCalls: delta.tool_calls.map((tc) => ({
150
+ id: tc.id,
151
+ name: tc.function?.name,
152
+ arguments: tc.function?.arguments || ''
153
+ }))
154
+ };
155
+ }
156
+ }
157
+ }
158
+ catch { }
159
+ }
160
+ }
161
+ }
162
+ getModels() {
163
+ return [...this.models];
164
+ }
165
+ supportsFeature(feature) {
166
+ const supported = ['chat', 'streaming', 'function_calling'];
167
+ return supported.includes(feature);
168
+ }
169
+ }
170
+ //# sourceMappingURL=overchat-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overchat-provider.js","sourceRoot":"","sources":["../src/overchat-provider.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrive-ai/providers",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './base-provider.js';
2
2
  export * from './provider-manager.js';
3
3
  export * from './groq-provider.js';
4
4
  export * from './openai-compatible-provider.js';
5
+ export * from './overchat-provider.js';
@@ -0,0 +1,189 @@
1
+ import { BaseProvider } from './base-provider.js';
2
+ import { ChatRequest, ChatResponse, ChatChunk, ILogger, IEventEmitter } from '@astrive-ai/types';
3
+ import crypto from 'node:crypto';
4
+
5
+ export class OverchatProvider extends BaseProvider {
6
+ private API = "https://api.overchat.ai/v1/chat/completions";
7
+ private ua = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Mobile Safari/537.36";
8
+ private models = ["claude-haiku-4-5-20251001"];
9
+
10
+ constructor(logger: ILogger, events: IEventEmitter) {
11
+ super('overchat', 'community', logger, events);
12
+ }
13
+
14
+ public override isAvailable(): boolean {
15
+ return true; // No API key required
16
+ }
17
+
18
+ private buildOverchatHeaders(deviceId: string) {
19
+ return {
20
+ "sec-ch-ua-platform": `"Android"`,
21
+ "x-device-uuid": deviceId,
22
+ "sec-ch-ua": `"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"`,
23
+ "sec-ch-ua-mobile": "?1",
24
+ "x-device-language": "id-ID",
25
+ "x-device-platform": "web",
26
+ "x-device-version": "1.0.44",
27
+ "user-agent": this.ua,
28
+ accept: "*/*",
29
+ "content-type": "application/json",
30
+ origin: "https://overchat.ai",
31
+ referer: "https://overchat.ai/",
32
+ "accept-language": "id-ID,id;q=0.9",
33
+ priority: "u=1, i",
34
+ };
35
+ }
36
+
37
+ private mapMessages(request: ChatRequest) {
38
+ return request.messages.map(msg => {
39
+ const mapped = { ...msg } as any;
40
+ if (!mapped.id) mapped.id = crypto.randomUUID();
41
+ if (mapped.tool_calls) {
42
+ mapped.tool_calls = mapped.tool_calls.map((tc: any) => ({
43
+ id: tc.id,
44
+ type: 'function',
45
+ function: {
46
+ name: tc.name || tc.function?.name,
47
+ arguments: typeof tc.arguments === 'string' ? tc.arguments : (typeof tc.function?.arguments === 'string' ? tc.function.arguments : JSON.stringify(tc.arguments || tc.function?.arguments))
48
+ }
49
+ }));
50
+ }
51
+ return mapped;
52
+ });
53
+ }
54
+
55
+ public async chat(request: ChatRequest): Promise<ChatResponse> {
56
+ const chatId = crypto.randomUUID();
57
+ const deviceId = crypto.randomUUID();
58
+
59
+ const body: any = {
60
+ chatId,
61
+ model: this.models[0],
62
+ messages: this.mapMessages(request),
63
+ personaId: "claude-haiku-4-5-landing",
64
+ frequency_penalty: 0,
65
+ max_tokens: request.maxTokens || 4000,
66
+ presence_penalty: 0,
67
+ stream: false,
68
+ temperature: request.temperature || 0.5,
69
+ top_p: 0.95,
70
+ };
71
+
72
+ if (request.tools && request.tools.length > 0) {
73
+ body.tools = request.tools;
74
+ }
75
+
76
+ const response = await fetch(this.API, {
77
+ method: "POST",
78
+ headers: this.buildOverchatHeaders(deviceId),
79
+ body: JSON.stringify(body)
80
+ });
81
+
82
+ if (!response.ok) {
83
+ const text = await response.text();
84
+ throw new Error(`HTTP ${response.status}: ${text}`);
85
+ }
86
+
87
+ const data: any = await response.json();
88
+ return {
89
+ id: data.id || crypto.randomUUID(),
90
+ content: data.choices?.[0]?.message?.content || '',
91
+ role: 'assistant',
92
+ toolCalls: data.choices?.[0]?.message?.tool_calls?.map((tc: any) => ({
93
+ id: tc.id,
94
+ name: tc.function.name,
95
+ arguments: typeof tc.function.arguments === 'string' ? JSON.parse(tc.function.arguments) : tc.function.arguments
96
+ })),
97
+ model: data.model || this.models[0],
98
+ finishReason: data.choices?.[0]?.finish_reason || 'stop'
99
+ };
100
+ }
101
+
102
+ public async *chatStream(request: ChatRequest): AsyncGenerator<ChatChunk, void, unknown> {
103
+ const chatId = crypto.randomUUID();
104
+ const deviceId = crypto.randomUUID();
105
+
106
+ const body: any = {
107
+ chatId,
108
+ model: this.models[0],
109
+ messages: this.mapMessages(request),
110
+ personaId: "claude-haiku-4-5-landing",
111
+ frequency_penalty: 0,
112
+ max_tokens: request.maxTokens || 4000,
113
+ presence_penalty: 0,
114
+ stream: true,
115
+ temperature: request.temperature || 0.5,
116
+ top_p: 0.95,
117
+ };
118
+
119
+ if (request.tools && request.tools.length > 0) {
120
+ body.tools = request.tools;
121
+ }
122
+
123
+ const response = await fetch(this.API, {
124
+ method: "POST",
125
+ headers: this.buildOverchatHeaders(deviceId),
126
+ body: JSON.stringify(body),
127
+ });
128
+
129
+ if (!response.ok) {
130
+ throw new Error(`HTTP ${response.status}: ${await response.text()}`);
131
+ }
132
+
133
+ if (!response.body) throw new Error('No response body');
134
+
135
+ const reader = response.body.getReader();
136
+ const decoder = new TextDecoder('utf-8');
137
+ let buffer = '';
138
+
139
+ while (true) {
140
+ const { done, value } = await reader.read();
141
+ if (done) break;
142
+ buffer += decoder.decode(value, { stream: true });
143
+
144
+ const lines = buffer.split('\n');
145
+ buffer = lines.pop() || '';
146
+
147
+ for (const rawLine of lines) {
148
+ const line = rawLine.trim();
149
+ if (!line.startsWith("data:")) continue;
150
+
151
+ const data = line.slice(5).trim();
152
+ if (!data || data === "[DONE]") {
153
+ if (data === "[DONE]") yield { content: '', done: true };
154
+ continue;
155
+ }
156
+
157
+ try {
158
+ const json = JSON.parse(data);
159
+ const delta = json.choices?.[0]?.delta;
160
+ if (delta) {
161
+ if (delta.content) {
162
+ yield { content: delta.content, done: false };
163
+ }
164
+ if (delta.tool_calls) {
165
+ yield {
166
+ content: '',
167
+ done: false,
168
+ toolCalls: delta.tool_calls.map((tc: any) => ({
169
+ id: tc.id,
170
+ name: tc.function?.name,
171
+ arguments: tc.function?.arguments || ''
172
+ }))
173
+ };
174
+ }
175
+ }
176
+ } catch {}
177
+ }
178
+ }
179
+ }
180
+
181
+ public getModels(): string[] {
182
+ return [...this.models];
183
+ }
184
+
185
+ public supportsFeature(feature: string): boolean {
186
+ const supported = ['chat', 'streaming', 'function_calling'];
187
+ return supported.includes(feature);
188
+ }
189
+ }