@node-llm/core 0.2.2 → 0.3.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.
Files changed (65) hide show
  1. package/README.md +125 -4
  2. package/dist/chat/Chat.d.ts +32 -16
  3. package/dist/chat/Chat.d.ts.map +1 -1
  4. package/dist/chat/Chat.js +102 -32
  5. package/dist/chat/ChatOptions.d.ts +5 -0
  6. package/dist/chat/ChatOptions.d.ts.map +1 -1
  7. package/dist/chat/ChatResponse.d.ts +18 -0
  8. package/dist/chat/ChatResponse.d.ts.map +1 -0
  9. package/dist/chat/ChatResponse.js +26 -0
  10. package/dist/chat/Stream.d.ts.map +1 -1
  11. package/dist/chat/Stream.js +10 -0
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/llm.d.ts +25 -3
  16. package/dist/llm.d.ts.map +1 -1
  17. package/dist/llm.js +48 -1
  18. package/dist/models/ModelRegistry.d.ts +23 -0
  19. package/dist/models/ModelRegistry.d.ts.map +1 -0
  20. package/dist/models/ModelRegistry.js +54 -0
  21. package/dist/moderation/Moderation.d.ts +56 -0
  22. package/dist/moderation/Moderation.d.ts.map +1 -0
  23. package/dist/moderation/Moderation.js +92 -0
  24. package/dist/providers/Provider.d.ts +39 -0
  25. package/dist/providers/Provider.d.ts.map +1 -1
  26. package/dist/providers/openai/Chat.d.ts.map +1 -1
  27. package/dist/providers/openai/Chat.js +1 -0
  28. package/dist/providers/openai/Moderation.d.ts +8 -0
  29. package/dist/providers/openai/Moderation.d.ts.map +1 -0
  30. package/dist/providers/openai/Moderation.js +26 -0
  31. package/dist/providers/openai/OpenAIProvider.d.ts +6 -1
  32. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
  33. package/dist/providers/openai/OpenAIProvider.js +12 -0
  34. package/dist/providers/openai/Streaming.d.ts.map +1 -1
  35. package/dist/providers/openai/Streaming.js +19 -8
  36. package/dist/providers/openai/Transcription.d.ts +10 -0
  37. package/dist/providers/openai/Transcription.d.ts.map +1 -0
  38. package/dist/providers/openai/Transcription.js +161 -0
  39. package/dist/providers/openai/index.d.ts +8 -0
  40. package/dist/providers/openai/index.d.ts.map +1 -1
  41. package/dist/providers/openai/index.js +12 -0
  42. package/dist/transcription/Transcription.d.ts +11 -0
  43. package/dist/transcription/Transcription.d.ts.map +1 -0
  44. package/dist/transcription/Transcription.js +21 -0
  45. package/dist/utils/FileLoader.d.ts.map +1 -1
  46. package/dist/utils/FileLoader.js +12 -1
  47. package/dist/utils/audio.d.ts +10 -0
  48. package/dist/utils/audio.d.ts.map +1 -0
  49. package/dist/utils/audio.js +46 -0
  50. package/package.json +17 -7
  51. package/dist/providers/openai/register.d.ts +0 -2
  52. package/dist/providers/openai/register.d.ts.map +0 -1
  53. package/dist/providers/openai/register.js +0 -15
  54. package/dist/tools/Tool.d.ts +0 -8
  55. package/dist/tools/Tool.d.ts.map +0 -1
  56. package/dist/tools/Tool.js +0 -1
  57. package/dist/tools/ToolSet.d.ts +0 -15
  58. package/dist/tools/ToolSet.d.ts.map +0 -1
  59. package/dist/tools/ToolSet.js +0 -29
  60. package/dist/tools/index.d.ts +0 -2
  61. package/dist/tools/index.d.ts.map +0 -1
  62. package/dist/tools/index.js +0 -1
  63. package/dist/tools/runCommandTool.d.ts +0 -8
  64. package/dist/tools/runCommandTool.d.ts.map +0 -1
  65. package/dist/tools/runCommandTool.js +0 -19
package/dist/llm.js CHANGED
@@ -1,14 +1,26 @@
1
1
  import { Chat } from "./chat/Chat.js";
2
2
  import { providerRegistry } from "./providers/registry.js";
3
- import { ensureOpenAIRegistered } from "./providers/openai/register.js";
3
+ import { ensureOpenAIRegistered } from "./providers/openai/index.js";
4
4
  import { GeneratedImage } from "./image/GeneratedImage.js";
5
+ import { models } from "./models/ModelRegistry.js";
6
+ import { Transcription } from "./transcription/Transcription.js";
7
+ import { Moderation } from "./moderation/Moderation.js";
5
8
  class LLMCore {
9
+ models = models;
6
10
  provider;
11
+ defaultTranscriptionModelId;
12
+ defaultModerationModelId;
7
13
  retry = {
8
14
  attempts: 1,
9
15
  delayMs: 0,
10
16
  };
11
17
  configure(config) {
18
+ if (config.defaultTranscriptionModel) {
19
+ this.defaultTranscriptionModelId = config.defaultTranscriptionModel;
20
+ }
21
+ if (config.defaultModerationModel) {
22
+ this.defaultModerationModelId = config.defaultModerationModel;
23
+ }
12
24
  if (config.retry) {
13
25
  this.retry = {
14
26
  attempts: config.retry.attempts ?? 1,
@@ -53,8 +65,43 @@ class LLMCore {
53
65
  });
54
66
  return new GeneratedImage(response);
55
67
  }
68
+ async transcribe(file, options) {
69
+ if (!this.provider) {
70
+ throw new Error("LLM provider not configured");
71
+ }
72
+ if (!this.provider.transcribe) {
73
+ throw new Error(`Provider does not support transcribe`);
74
+ }
75
+ const response = await this.provider.transcribe({
76
+ file,
77
+ model: options?.model || this.defaultTranscriptionModelId,
78
+ ...options,
79
+ });
80
+ return new Transcription(response);
81
+ }
82
+ get defaultTranscriptionModel() {
83
+ return this.defaultTranscriptionModelId;
84
+ }
85
+ get defaultModerationModel() {
86
+ return this.defaultModerationModelId;
87
+ }
56
88
  getRetryConfig() {
57
89
  return this.retry;
58
90
  }
91
+ async moderate(input, options) {
92
+ if (!this.provider) {
93
+ throw new Error("LLM provider not configured");
94
+ }
95
+ if (!this.provider.moderate) {
96
+ throw new Error(`Provider does not support moderate`);
97
+ }
98
+ const response = await this.provider.moderate({
99
+ input,
100
+ model: options?.model || this.defaultModerationModelId,
101
+ ...options,
102
+ });
103
+ return new Moderation(response);
104
+ }
59
105
  }
106
+ export { Transcription, Moderation };
60
107
  export const LLM = new LLMCore();
@@ -0,0 +1,23 @@
1
+ import { ModelInfo } from "../providers/Provider.js";
2
+ export declare class ModelRegistry {
3
+ private models;
4
+ private static readonly API_URL;
5
+ /**
6
+ * Refresh model information from the Parsera API
7
+ */
8
+ refresh(): Promise<void>;
9
+ /**
10
+ * Find a model by ID
11
+ */
12
+ find(id: string): ModelInfo | undefined;
13
+ /**
14
+ * List all known models
15
+ */
16
+ all(): ModelInfo[];
17
+ /**
18
+ * Filter models by provider
19
+ */
20
+ byProvider(provider: string): ModelInfo[];
21
+ }
22
+ export declare const models: ModelRegistry;
23
+ //# sourceMappingURL=ModelRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAA0C;IAEzE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8B9B;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIvC;;OAEG;IACH,GAAG,IAAI,SAAS,EAAE;IAIlB;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE;CAG1C;AAED,eAAO,MAAM,MAAM,eAAsB,CAAC"}
@@ -0,0 +1,54 @@
1
+ export class ModelRegistry {
2
+ models = new Map();
3
+ static API_URL = "https://api.parsera.org/v1/llm-specs";
4
+ /**
5
+ * Refresh model information from the Parsera API
6
+ */
7
+ async refresh() {
8
+ try {
9
+ const response = await fetch(ModelRegistry.API_URL);
10
+ if (!response.ok) {
11
+ throw new Error(`Failed to refresh models: ${response.statusText}`);
12
+ }
13
+ const specs = await response.json();
14
+ this.models.clear();
15
+ for (const spec of specs) {
16
+ this.models.set(spec.id, {
17
+ id: spec.id,
18
+ name: spec.name || spec.id,
19
+ provider: spec.provider,
20
+ family: spec.family || spec.provider,
21
+ context_window: spec.context_window,
22
+ max_output_tokens: spec.max_output_tokens,
23
+ modalities: spec.modalities || { input: ["text"], output: ["text"] },
24
+ capabilities: spec.capabilities || [],
25
+ pricing: spec.pricing || {},
26
+ metadata: spec.metadata || {}
27
+ });
28
+ }
29
+ }
30
+ catch (error) {
31
+ console.error("Error refreshing model registry:", error);
32
+ throw error;
33
+ }
34
+ }
35
+ /**
36
+ * Find a model by ID
37
+ */
38
+ find(id) {
39
+ return this.models.get(id);
40
+ }
41
+ /**
42
+ * List all known models
43
+ */
44
+ all() {
45
+ return Array.from(this.models.values());
46
+ }
47
+ /**
48
+ * Filter models by provider
49
+ */
50
+ byProvider(provider) {
51
+ return this.all().filter(m => m.provider === provider);
52
+ }
53
+ }
54
+ export const models = new ModelRegistry();
@@ -0,0 +1,56 @@
1
+ import { ModerationResponse, ModerationResult } from "../providers/Provider.js";
2
+ /**
3
+ * Represents the results of a moderation request.
4
+ * Can contain one or multiple results if multiple inputs were provided.
5
+ */
6
+ export declare class Moderation implements Iterable<ModerationItem> {
7
+ private readonly response;
8
+ constructor(response: ModerationResponse);
9
+ get id(): string;
10
+ get model(): string;
11
+ /**
12
+ * Returns all results as ModerationItem instances
13
+ */
14
+ get results(): ModerationItem[];
15
+ /**
16
+ * Returns the number of results
17
+ */
18
+ get length(): number;
19
+ /**
20
+ * Returns true if any of the results are flagged
21
+ */
22
+ get flagged(): boolean;
23
+ /**
24
+ * Aggregates all flagged categories across all results
25
+ */
26
+ get flaggedCategories(): string[];
27
+ /**
28
+ * Returns categories for the first result (most common case)
29
+ */
30
+ get categories(): Record<string, boolean>;
31
+ /**
32
+ * Returns category scores for the first result
33
+ */
34
+ get categoryScores(): Record<string, number>;
35
+ get flagged_categories(): string[];
36
+ get category_scores(): Record<string, number>;
37
+ isFlagged(): boolean;
38
+ /**
39
+ * Makes the Moderation object iterable (yields results)
40
+ */
41
+ [Symbol.iterator](): Iterator<ModerationItem>;
42
+ }
43
+ /**
44
+ * Represents a single result within a moderation request
45
+ */
46
+ export declare class ModerationItem {
47
+ readonly raw: ModerationResult;
48
+ constructor(raw: ModerationResult);
49
+ get flagged(): boolean;
50
+ get categories(): Record<string, boolean>;
51
+ get categoryScores(): Record<string, number>;
52
+ get flaggedCategories(): string[];
53
+ get flagged_categories(): string[];
54
+ get category_scores(): Record<string, number>;
55
+ }
56
+ //# sourceMappingURL=Moderation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Moderation.d.ts","sourceRoot":"","sources":["../../src/moderation/Moderation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEhF;;;GAGG;AACH,qBAAa,UAAW,YAAW,QAAQ,CAAC,cAAc,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,kBAAkB;IAEzD,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,cAAc,EAAE,CAE9B;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAMhC;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAExC;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE3C;IAGD,IAAI,kBAAkB,IAAI,MAAM,EAAE,CAAmC;IACrE,IAAI,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAgC;IAC7E,SAAS,IAAI,OAAO;IAEpB;;OAEG;IACF,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,cAAc,CAAC;CAK/C;AAED;;GAEG;AACH,qBAAa,cAAc;aACG,GAAG,EAAE,gBAAgB;gBAArB,GAAG,EAAE,gBAAgB;IAEjD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAExC;IAED,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE3C;IAED,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAEhC;IAGD,IAAI,kBAAkB,IAAI,MAAM,EAAE,CAAmC;IACrE,IAAI,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAgC;CAC9E"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Represents the results of a moderation request.
3
+ * Can contain one or multiple results if multiple inputs were provided.
4
+ */
5
+ export class Moderation {
6
+ response;
7
+ constructor(response) {
8
+ this.response = response;
9
+ }
10
+ get id() {
11
+ return this.response.id;
12
+ }
13
+ get model() {
14
+ return this.response.model;
15
+ }
16
+ /**
17
+ * Returns all results as ModerationItem instances
18
+ */
19
+ get results() {
20
+ return this.response.results.map((r) => new ModerationItem(r));
21
+ }
22
+ /**
23
+ * Returns the number of results
24
+ */
25
+ get length() {
26
+ return this.response.results.length;
27
+ }
28
+ /**
29
+ * Returns true if any of the results are flagged
30
+ */
31
+ get flagged() {
32
+ return this.response.results.some((r) => r.flagged);
33
+ }
34
+ /**
35
+ * Aggregates all flagged categories across all results
36
+ */
37
+ get flaggedCategories() {
38
+ const all = new Set();
39
+ for (const item of this.results) {
40
+ item.flaggedCategories.forEach((cat) => all.add(cat));
41
+ }
42
+ return Array.from(all);
43
+ }
44
+ /**
45
+ * Returns categories for the first result (most common case)
46
+ */
47
+ get categories() {
48
+ return this.results[0]?.categories || {};
49
+ }
50
+ /**
51
+ * Returns category scores for the first result
52
+ */
53
+ get categoryScores() {
54
+ return this.results[0]?.categoryScores || {};
55
+ }
56
+ // --- Ruby-compatible aliases ---
57
+ get flagged_categories() { return this.flaggedCategories; }
58
+ get category_scores() { return this.categoryScores; }
59
+ isFlagged() { return this.flagged; }
60
+ /**
61
+ * Makes the Moderation object iterable (yields results)
62
+ */
63
+ *[Symbol.iterator]() {
64
+ for (const item of this.results) {
65
+ yield item;
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Represents a single result within a moderation request
71
+ */
72
+ export class ModerationItem {
73
+ raw;
74
+ constructor(raw) {
75
+ this.raw = raw;
76
+ }
77
+ get flagged() {
78
+ return this.raw.flagged;
79
+ }
80
+ get categories() {
81
+ return this.raw.categories;
82
+ }
83
+ get categoryScores() {
84
+ return this.raw.category_scores;
85
+ }
86
+ get flaggedCategories() {
87
+ return Object.keys(this.categories).filter((cat) => this.categories[cat]);
88
+ }
89
+ // --- Ruby-compatible aliases ---
90
+ get flagged_categories() { return this.flaggedCategories; }
91
+ get category_scores() { return this.categoryScores; }
92
+ }
@@ -6,6 +6,7 @@ export interface ChatRequest {
6
6
  tools?: Tool[];
7
7
  temperature?: number;
8
8
  max_tokens?: number;
9
+ headers?: Record<string, string>;
9
10
  }
10
11
  export interface ChatChunk {
11
12
  content: string;
@@ -56,11 +57,49 @@ export interface ImageResponse {
56
57
  mime_type?: string;
57
58
  revised_prompt?: string;
58
59
  }
60
+ export interface TranscriptionRequest {
61
+ model?: string;
62
+ file: string;
63
+ prompt?: string;
64
+ language?: string;
65
+ speakerNames?: string[];
66
+ speakerReferences?: string[];
67
+ }
68
+ export interface TranscriptionSegment {
69
+ id: number;
70
+ start: number;
71
+ end: number;
72
+ text: string;
73
+ speaker?: string;
74
+ [key: string]: any;
75
+ }
76
+ export interface TranscriptionResponse {
77
+ text: string;
78
+ model: string;
79
+ duration?: number;
80
+ segments?: TranscriptionSegment[];
81
+ }
82
+ export interface ModerationRequest {
83
+ input: string | string[];
84
+ model?: string;
85
+ }
86
+ export interface ModerationResult {
87
+ flagged: boolean;
88
+ categories: Record<string, boolean>;
89
+ category_scores: Record<string, number>;
90
+ }
91
+ export interface ModerationResponse {
92
+ id: string;
93
+ model: string;
94
+ results: ModerationResult[];
95
+ }
59
96
  export interface Provider {
60
97
  chat(request: ChatRequest): Promise<ChatResponse>;
61
98
  stream?(request: ChatRequest): AsyncIterable<ChatChunk>;
62
99
  listModels?(): Promise<ModelInfo[]>;
63
100
  paint?(request: ImageRequest): Promise<ImageResponse>;
101
+ transcribe?(request: TranscriptionRequest): Promise<TranscriptionResponse>;
102
+ moderate?(request: ModerationRequest): Promise<ModerationResponse>;
64
103
  capabilities?: ProviderCapabilities;
65
104
  }
66
105
  //# sourceMappingURL=Provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Provider.d.ts","sourceRoot":"","sources":["../../src/providers/Provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACxD,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACtD,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC"}
1
+ {"version":3,"file":"Provider.d.ts","sourceRoot":"","sources":["../../src/providers/Provider.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK3D,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAqD3D"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK3D,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAsD3D"}
@@ -29,6 +29,7 @@ export class OpenAIChat {
29
29
  headers: {
30
30
  "Authorization": `Bearer ${this.apiKey}`,
31
31
  "Content-Type": "application/json",
32
+ ...request.headers,
32
33
  },
33
34
  body: JSON.stringify(body),
34
35
  });
@@ -0,0 +1,8 @@
1
+ import { ModerationRequest, ModerationResponse } from "../Provider.js";
2
+ export declare class OpenAIModeration {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(request: ModerationRequest): Promise<ModerationResponse>;
7
+ }
8
+ //# sourceMappingURL=Moderation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Moderation.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Moderation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGvE,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAmBvE"}
@@ -0,0 +1,26 @@
1
+ import { handleOpenAIError } from "./Errors.js";
2
+ export class OpenAIModeration {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl;
7
+ this.apiKey = apiKey;
8
+ }
9
+ async execute(request) {
10
+ const response = await fetch(`${this.baseUrl}/moderations`, {
11
+ method: "POST",
12
+ headers: {
13
+ "Authorization": `Bearer ${this.apiKey}`,
14
+ "Content-Type": "application/json",
15
+ },
16
+ body: JSON.stringify({
17
+ input: request.input,
18
+ model: request.model || "omni-moderation-latest",
19
+ }),
20
+ });
21
+ if (!response.ok) {
22
+ await handleOpenAIError(response, request.model || "omni-moderation-latest");
23
+ }
24
+ return (await response.json());
25
+ }
26
+ }
@@ -1,4 +1,5 @@
1
- import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk, ImageRequest, ImageResponse } from "../Provider.js";
1
+ import { Provider, ChatRequest, ChatResponse, ModelInfo, ChatChunk, ImageRequest, ImageResponse, ModerationRequest, ModerationResponse } from "../Provider.js";
2
+ import { TranscriptionRequest, TranscriptionResponse } from "../Provider.js";
2
3
  export interface OpenAIProviderOptions {
3
4
  apiKey: string;
4
5
  baseUrl?: string;
@@ -10,6 +11,8 @@ export declare class OpenAIProvider implements Provider {
10
11
  private readonly streamingHandler;
11
12
  private readonly modelsHandler;
12
13
  private readonly imageHandler;
14
+ private readonly transcriptionHandler;
15
+ private readonly moderationHandler;
13
16
  capabilities: {
14
17
  supportsVision: (model: string) => boolean;
15
18
  supportsTools: (model: string) => boolean;
@@ -21,5 +24,7 @@ export declare class OpenAIProvider implements Provider {
21
24
  stream(request: ChatRequest): AsyncGenerator<ChatChunk>;
22
25
  listModels(): Promise<ModelInfo[]>;
23
26
  paint(request: ImageRequest): Promise<ImageResponse>;
27
+ transcribe(request: TranscriptionRequest): Promise<TranscriptionResponse>;
28
+ moderate(request: ModerationRequest): Promise<ModerationResponse>;
24
29
  }
25
30
  //# sourceMappingURL=OpenAIProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAOxH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,QAAQ;IAcjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAbpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAEpC,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;kCACd,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAQrD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAG3D"}
1
+ {"version":3,"file":"OpenAIProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/OpenAIProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAQ/J,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,QAAQ;IAgBjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAfpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IAE9C,YAAY;gCACO,MAAM;+BACP,MAAM;0CACK,MAAM;kCACd,MAAM;MAChC;gBAE2B,OAAO,EAAE,qBAAqB;IAUrD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;IAIxD,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIlC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpD,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAIzE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAGxE"}
@@ -3,6 +3,8 @@ import { OpenAIChat } from "./Chat.js";
3
3
  import { OpenAIStreaming } from "./Streaming.js";
4
4
  import { OpenAIModels } from "./Models.js";
5
5
  import { OpenAIImage } from "./Image.js";
6
+ import { OpenAITranscription } from "./Transcription.js";
7
+ import { OpenAIModeration } from "./Moderation.js";
6
8
  export class OpenAIProvider {
7
9
  options;
8
10
  baseUrl;
@@ -10,6 +12,8 @@ export class OpenAIProvider {
10
12
  streamingHandler;
11
13
  modelsHandler;
12
14
  imageHandler;
15
+ transcriptionHandler;
16
+ moderationHandler;
13
17
  capabilities = {
14
18
  supportsVision: (model) => Capabilities.supportsVision(model),
15
19
  supportsTools: (model) => Capabilities.supportsTools(model),
@@ -23,6 +27,8 @@ export class OpenAIProvider {
23
27
  this.streamingHandler = new OpenAIStreaming(this.baseUrl, options.apiKey);
24
28
  this.modelsHandler = new OpenAIModels(this.baseUrl, options.apiKey);
25
29
  this.imageHandler = new OpenAIImage(this.baseUrl, options.apiKey);
30
+ this.transcriptionHandler = new OpenAITranscription(this.baseUrl, options.apiKey);
31
+ this.moderationHandler = new OpenAIModeration(this.baseUrl, options.apiKey);
26
32
  }
27
33
  async chat(request) {
28
34
  return this.chatHandler.execute(request);
@@ -36,4 +42,10 @@ export class OpenAIProvider {
36
42
  async paint(request) {
37
43
  return this.imageHandler.execute(request);
38
44
  }
45
+ async transcribe(request) {
46
+ return this.transcriptionHandler.execute(request);
47
+ }
48
+ async moderate(request) {
49
+ return this.moderationHandler.execute(request);
50
+ }
39
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;CA0DhE"}
1
+ {"version":3,"file":"Streaming.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIxD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEtE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC;CAqEhE"}
@@ -25,6 +25,7 @@ export class OpenAIStreaming {
25
25
  headers: {
26
26
  "Authorization": `Bearer ${this.apiKey}`,
27
27
  "Content-Type": "application/json",
28
+ ...request.headers,
28
29
  },
29
30
  body: JSON.stringify(body),
30
31
  });
@@ -36,22 +37,32 @@ export class OpenAIStreaming {
36
37
  }
37
38
  const reader = response.body.getReader();
38
39
  const decoder = new TextDecoder();
40
+ let buffer = "";
39
41
  while (true) {
40
42
  const { value, done } = await reader.read();
41
43
  if (done)
42
44
  break;
43
- const chunk = decoder.decode(value);
44
- const lines = chunk.split("\n");
45
+ const chunk = decoder.decode(value, { stream: true });
46
+ buffer += chunk;
47
+ const lines = buffer.split("\n\n");
48
+ buffer = lines.pop() || ""; // Keep the last incomplete part in the buffer
45
49
  for (const line of lines) {
46
- if (!line.startsWith("data: "))
50
+ const trimmed = line.trim();
51
+ if (!trimmed.startsWith("data: "))
47
52
  continue;
48
- const data = line.replace("data: ", "").trim();
53
+ const data = trimmed.replace("data: ", "").trim();
49
54
  if (data === "[DONE]")
50
55
  return;
51
- const json = JSON.parse(data);
52
- const delta = json.choices?.[0]?.delta?.content;
53
- if (delta) {
54
- yield { content: delta };
56
+ try {
57
+ const json = JSON.parse(data);
58
+ const delta = json.choices?.[0]?.delta?.content;
59
+ if (delta) {
60
+ yield { content: delta };
61
+ }
62
+ }
63
+ catch (e) {
64
+ // Ignore parse errors for now, or log them
65
+ // console.warn("JSON parse error in stream:", e);
55
66
  }
56
67
  }
57
68
  }
@@ -0,0 +1,10 @@
1
+ import { TranscriptionRequest, TranscriptionResponse } from "../Provider.js";
2
+ export declare class OpenAITranscription {
3
+ private readonly baseUrl;
4
+ private readonly apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ execute(request: TranscriptionRequest): Promise<TranscriptionResponse>;
7
+ private transcribeViaWhisper;
8
+ private transcribeViaChat;
9
+ }
10
+ //# sourceMappingURL=Transcription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transcription.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Transcription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI7E,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAU9D,oBAAoB;YA4CpB,iBAAiB;CAwHhC"}