ohlcv-ai 1.0.9 → 1.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/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- var T = /* @__PURE__ */ ((t) => (t.QWEN_TURBO = "qwen-turbo", t.QWEN_PLUS = "qwen-plus", t.QWEN_MAX = "qwen-max", t.QWEN_MAX_LONGCONTEXT = "qwen-max-longcontext", t.QWEN_2_5B = "qwen2.5-0.5b", t.QWEN_2_5B_INSTRUCT = "qwen2.5-0.5b-instruct", t.QWEN_2_5B_7B = "qwen2.5-7b", t.QWEN_2_5B_7B_INSTRUCT = "qwen2.5-7b-instruct", t.QWEN_2_5B_14B = "qwen2.5-14b", t.QWEN_2_5B_14B_INSTRUCT = "qwen2.5-14b-instruct", t.QWEN_2_5B_32B = "qwen2.5-32b", t.QWEN_2_5B_32B_INSTRUCT = "qwen2.5-32b-instruct", t.QWEN_2_5B_72B = "qwen2.5-72b", t.QWEN_2_5B_72B_INSTRUCT = "qwen2.5-72b-instruct", t.QWEN_2_5B_CODER = "qwen2.5-coder", t.QWEN_2_5B_CODER_7B = "qwen2.5-coder-7b", t.QWEN_2_5B_CODER_14B = "qwen2.5-coder-14b", t.QWEN_2_5B_CODER_32B = "qwen2.5-coder-32b", t.QWEN_VL_LITE = "qwen-vl-lite", t.QWEN_VL_PLUS = "qwen-vl-plus", t.QWEN_VL_MAX = "qwen-vl-max", t.QWEN_AUDIO_TURBO = "qwen-audio-turbo", t.QWEN_AUDIO_CHAT = "qwen-audio-chat", t.QWEN_MATH_7B = "qwen-math-7b", t.LLAMA2_7B_CHAT_V2 = "llama2-7b-chat-v2", t.BAICHUAN2_7B_CHAT_V1 = "baichuan2-7b-chat-v1", t.QWEN_FINANCIAL = "qwen-financial", t.QWEN_FINANCIAL_14B = "qwen-financial-14b", t.QWEN_FINANCIAL_32B = "qwen-financial-32b", t.QWEN_MEDICAL = "qwen-medical", t.QWEN_MEDICAL_14B = "qwen-medical-14b", t.QWEN_MEDICAL_32B = "qwen-medical-32b", t.QWEN_OMNI = "qwen-omni", t.QWEN_OMNI_PRO = "qwen-omni-pro", t))(T || {});
2
- const b = /* @__PURE__ */ new Map([
1
+ var O = /* @__PURE__ */ ((n) => (n.QWEN_TURBO = "qwen-turbo", n.QWEN_PLUS = "qwen-plus", n.QWEN_MAX = "qwen-max", n.QWEN_MAX_LONGCONTEXT = "qwen-max-longcontext", n.QWEN_2_5B = "qwen2.5-0.5b", n.QWEN_2_5B_INSTRUCT = "qwen2.5-0.5b-instruct", n.QWEN_2_5B_7B = "qwen2.5-7b", n.QWEN_2_5B_7B_INSTRUCT = "qwen2.5-7b-instruct", n.QWEN_2_5B_14B = "qwen2.5-14b", n.QWEN_2_5B_14B_INSTRUCT = "qwen2.5-14b-instruct", n.QWEN_2_5B_32B = "qwen2.5-32b", n.QWEN_2_5B_32B_INSTRUCT = "qwen2.5-32b-instruct", n.QWEN_2_5B_72B = "qwen2.5-72b", n.QWEN_2_5B_72B_INSTRUCT = "qwen2.5-72b-instruct", n.QWEN_2_5B_CODER = "qwen2.5-coder", n.QWEN_2_5B_CODER_7B = "qwen2.5-coder-7b", n.QWEN_2_5B_CODER_14B = "qwen2.5-coder-14b", n.QWEN_2_5B_CODER_32B = "qwen2.5-coder-32b", n.QWEN_VL_LITE = "qwen-vl-lite", n.QWEN_VL_PLUS = "qwen-vl-plus", n.QWEN_VL_MAX = "qwen-vl-max", n.QWEN_AUDIO_TURBO = "qwen-audio-turbo", n.QWEN_AUDIO_CHAT = "qwen-audio-chat", n.QWEN_MATH_7B = "qwen-math-7b", n.LLAMA2_7B_CHAT_V2 = "llama2-7b-chat-v2", n.BAICHUAN2_7B_CHAT_V1 = "baichuan2-7b-chat-v1", n.QWEN_FINANCIAL = "qwen-financial", n.QWEN_FINANCIAL_14B = "qwen-financial-14b", n.QWEN_FINANCIAL_32B = "qwen-financial-32b", n.QWEN_MEDICAL = "qwen-medical", n.QWEN_MEDICAL_14B = "qwen-medical-14b", n.QWEN_MEDICAL_32B = "qwen-medical-32b", n.QWEN_OMNI = "qwen-omni", n.QWEN_OMNI_PRO = "qwen-omni-pro", n))(O || {});
2
+ const k = /* @__PURE__ */ new Map([
3
3
  [
4
4
  "qwen-turbo",
5
5
  {
@@ -358,28 +358,28 @@ const b = /* @__PURE__ */ new Map([
358
358
  }
359
359
  ]
360
360
  ]);
361
- function N(t) {
362
- return b.get(t);
361
+ function V(n) {
362
+ return k.get(n);
363
363
  }
364
- function P() {
365
- return Array.from(b.values());
364
+ function R() {
365
+ return Array.from(k.values());
366
366
  }
367
- function q(t) {
368
- for (const e of b.values())
369
- if (e.name === t)
367
+ function A(n) {
368
+ for (const e of k.values())
369
+ if (e.name === n)
370
370
  return e;
371
371
  }
372
- function O() {
373
- return Array.from(b.keys());
372
+ function I() {
373
+ return Array.from(k.keys());
374
374
  }
375
- function $(t) {
376
- const e = Object.values(T);
377
- for (const o of e)
378
- if (o === t)
379
- return o;
375
+ function D(n) {
376
+ const e = Object.values(O);
377
+ for (const t of e)
378
+ if (t === n)
379
+ return t;
380
380
  return null;
381
381
  }
382
- class _ {
382
+ class q {
383
383
  /**
384
384
  * Constructor - Minimal configuration
385
385
  * @param config.apiKey - API key (required)
@@ -387,67 +387,326 @@ class _ {
387
387
  * @param config.timeout - Timeout, default 30 seconds
388
388
  */
389
389
  constructor(e) {
390
- if (this.apiKey = e.apiKey, this.modelType = e.modelType || T.QWEN_TURBO, this.timeout = e.timeout || 3e4, !this.apiKey)
390
+ if (this.apiKey = e.apiKey, this.modelType = e.modelType || O.QWEN_TURBO, this.timeout = e.timeout || 3e4, !this.apiKey)
391
391
  throw new Error("API Key cannot be empty");
392
- if (!b.get(this.modelType))
392
+ if (!k.get(this.modelType))
393
393
  throw new Error(`Unsupported model type: ${this.modelType}`);
394
394
  }
395
395
  /**
396
- * Simplest method: single conversation
397
- * @param message - User message
398
- * @param options - Chat options
399
- * @returns AI response
400
- */
401
- async chat(e, o) {
402
- const s = [];
403
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
404
- const a = await this.chatCompletion(s, {
405
- temperature: o?.temperature,
406
- maxTokens: o?.maxTokens,
407
- stream: !1
396
+ * Simplest method: single conversation
397
+ * @param message - User message
398
+ * @param i18n - Language restriction for AI response
399
+ * @param options - Chat options
400
+ * @returns AI response
401
+ */
402
+ async chat(e, t, s) {
403
+ const a = [], r = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
404
+ if (s?.systemPrompt || r) {
405
+ const i = [s?.systemPrompt, r].filter(Boolean).join(`
406
+ `);
407
+ a.push({ role: "system", content: i });
408
+ }
409
+ a.push({ role: "user", content: e });
410
+ const o = await this.chatCompletion(a, t, {
411
+ temperature: s?.temperature,
412
+ maxTokens: s?.maxTokens,
413
+ stream: !1,
414
+ modelType: this.modelType
408
415
  });
409
- return this.extractContent(a);
416
+ return this.extractContent(o);
410
417
  }
411
418
  /**
412
419
  * Multi-turn conversation
413
420
  * @param messages - Message history
421
+ * @param i18n - Language restriction for AI response
414
422
  * @param options - Chat options
415
423
  * @returns Complete API response
416
424
  */
417
- async chatCompletion(e, o) {
418
- const s = o?.modelType || this.modelType, a = b.get(s);
419
- if (!a)
420
- throw new Error(`Unsupported model type: ${s}`);
421
- const i = o?.temperature ?? 0.7, n = o?.maxTokens ?? 1e3, r = o?.stream ?? !1, m = a.endpoint, p = a.format === "openai" ? this.buildOpenAIRequest(a.name, e, i, n, r) : this.buildDashScopeRequest(a.name, e, i, n);
425
+ async chatCompletion(e, t, s) {
426
+ const a = s?.modelType || this.modelType, r = k.get(a);
427
+ if (!r)
428
+ throw new Error(`Unsupported model type: ${a}`);
429
+ const o = s?.temperature ?? 0.7, i = s?.maxTokens ?? 1e3, d = s?.stream ?? !1, l = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
430
+ l && (e.some((g) => g.role === "system") ? e = e.map((g) => g.role === "system" ? {
431
+ ...g,
432
+ content: `${g.content}
433
+ ${l}`
434
+ } : g) : e.unshift({ role: "system", content: l }));
435
+ const u = r.endpoint, c = r.format === "openai" ? this.buildOpenAIRequest(r.name, e, o, i, d) : this.buildDashScopeRequest(r.name, e, o, i);
422
436
  try {
423
- return await this.makeRequest(m, p, r);
424
- } catch (d) {
425
- throw new Error(`Aliyun AI request failed: ${d.message}`);
437
+ return await this.makeRequest(u, c, d);
438
+ } catch (p) {
439
+ throw new Error(`Aliyun AI request failed: ${p.message}`);
426
440
  }
427
441
  }
428
442
  /**
429
443
  * Streaming conversation (only supports OpenAI format)
430
444
  * @param messages - Message history
431
445
  * @param callback - Streaming callback function
446
+ * @param i18n - Language restriction for AI response
432
447
  * @param options - Chat options
433
448
  */
434
- async chatStream(e, o, s) {
435
- const a = s?.modelType || this.modelType, i = b.get(a);
436
- if (!i)
437
- throw new Error(`Unsupported model type: ${a}`);
438
- if (i.format !== "openai")
449
+ async chatStream(e, t, s, a) {
450
+ const r = a?.modelType || this.modelType, o = k.get(r);
451
+ if (!o)
452
+ throw new Error(`Unsupported model type: ${r}`);
453
+ if (o.format !== "openai")
439
454
  throw new Error("Streaming conversation only supports OpenAI format models");
440
- const n = s?.temperature ?? 0.7, r = s?.maxTokens ?? 1e3, m = this.buildOpenAIRequest(
441
- i.name,
455
+ const i = a?.temperature ?? 0.7, d = a?.maxTokens ?? 1e3, l = s === "en" ? "Please respond in English only." : s === "cn" ? "请使用中文回答。" : "";
456
+ l && (e.some((c) => c.role === "system") ? e = e.map((c) => c.role === "system" ? {
457
+ ...c,
458
+ content: `${c.content}
459
+ ${l}`
460
+ } : c) : e.unshift({ role: "system", content: l }));
461
+ const u = this.buildOpenAIRequest(
462
+ o.name,
442
463
  e,
443
- n,
444
- r,
464
+ i,
465
+ d,
445
466
  !0
446
467
  );
447
468
  try {
448
- await this.makeStreamRequest(i.endpoint, m, o);
449
- } catch (c) {
450
- throw new Error(`Streaming request failed: ${c.message}`);
469
+ await this.makeStreamRequest(o.endpoint, u, t);
470
+ } catch (m) {
471
+ throw new Error(`Streaming request failed: ${m.message}`);
472
+ }
473
+ }
474
+ /**
475
+ * Analyze OHLCV data and return AI analysis results
476
+ * @param ohlcvArray - OHLCV data array
477
+ * @param i18n - Language restriction for AI response
478
+ * @param analysisType - Analysis type (optional, default: "comprehensive")
479
+ * - "trend": Trend analysis
480
+ * - "volume": Volume analysis
481
+ * - "technical": Technical analysis
482
+ * - "comprehensive": Comprehensive analysis
483
+ * @param message - User's subjective request or specific question (optional)
484
+ * @param options - Chat options
485
+ * @returns AI analysis result of OHLCV data (text description)
486
+ */
487
+ async analyzeOHLCV(e, t, s, a, r) {
488
+ const o = s || "comprehensive", i = e.length, l = {
489
+ trend: t === "en" ? "Provide a detailed trend analysis of this OHLCV data, including price direction, support/resistance levels, and trend strength." : "提供详细的OHLCV数据趋势分析,包括价格方向、支撑/阻力位和趋势强度。",
490
+ volume: t === "en" ? "Analyze the volume patterns in this OHLCV data, including volume trends, unusual volume spikes, and volume-price relationships." : "分析OHLCV数据中的成交量模式,包括成交量趋势、异常成交量波动和量价关系。",
491
+ technical: t === "en" ? "Perform technical analysis on this OHLCV data, identifying potential technical indicators, patterns, and trading signals." : "对OHLCV数据进行技术分析,识别潜在的技术指标、图表形态和交易信号。",
492
+ comprehensive: t === "en" ? "Provide a comprehensive analysis of this OHLCV data, covering trends, volume, technical aspects, and potential market implications." : "提供全面的OHLCV数据分析,涵盖趋势、成交量、技术面和潜在市场影响。"
493
+ }[o], u = t === "en" ? "Please provide your analysis in English." : "请用中文进行分析。";
494
+ let m = "";
495
+ if (i > 0) {
496
+ const h = e[0], f = e[i - 1].close - h.close, w = f / h.close * 100;
497
+ let C = h.high, v = h.low, P = 0;
498
+ for (const E of e)
499
+ E.high > C && (C = E.high), E.low < v && (v = E.low), P += E.volume;
500
+ const _ = P / i;
501
+ m = t === "en" ? `This dataset contains ${i} periods of OHLCV data.
502
+ Price range: ${v.toFixed(2)} - ${C.toFixed(2)}
503
+ Overall price change: ${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
504
+ Average volume: ${_.toFixed(0)}` : `该数据集包含 ${i} 个周期的OHLCV数据。
505
+ 价格范围:${v.toFixed(2)} - ${C.toFixed(2)}
506
+ 总体价格变化:${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
507
+ 平均成交量:${_.toFixed(0)}`;
508
+ }
509
+ let c = t === "en" ? `You are a professional financial data analyst. Your task is to analyze OHLCV (Open, High, Low, Close, Volume) data and provide insights.
510
+ Analysis focus: ${l}
511
+ ${m ? `Data characteristics:
512
+ ${m}
513
+
514
+ ` : ""}
515
+ Please provide:
516
+ 1. Clear and structured analysis
517
+ 2. Key observations from the data
518
+ 3. Potential implications or insights
519
+ 4. Recommendations or considerations (if applicable)
520
+ Format your response as a well-organized text analysis.` : `您是一位专业的金融数据分析师。您的任务是分析OHLCV(开盘价、最高价、最低价、收盘价、成交量)数据并提供见解。
521
+ 分析重点:${l}
522
+ ${m ? `数据特征:
523
+ ${m}
524
+
525
+ ` : ""}
526
+ 请提供:
527
+ 1. 清晰且有结构的分析
528
+ 2. 数据的关键观察结果
529
+ 3. 潜在的启示或见解
530
+ 4. 建议或注意事项(如适用)
531
+ 请以组织良好的文本分析形式回复。`;
532
+ c += `
533
+
534
+ ${u}`;
535
+ const p = JSON.stringify(e, null, 2);
536
+ let g = "";
537
+ a ? g = t === "en" ? `Here is the OHLCV data (${i} periods):
538
+ ${p}
539
+ My specific question or request: ${a}
540
+ Please analyze this data considering my request above.` : `这是OHLCV数据(${i}个周期):
541
+ ${p}
542
+ 我的具体问题或需求:${a}
543
+ 请根据我的上述需求分析这些数据。` : g = t === "en" ? `Here is the OHLCV data (${i} periods):
544
+ ${p}
545
+ Please analyze this data as requested.` : `这是OHLCV数据(${i}个周期):
546
+ ${p}
547
+ 请按要求分析这些数据。`;
548
+ const y = [
549
+ { role: "system", content: c },
550
+ { role: "user", content: g }
551
+ ];
552
+ try {
553
+ const h = await this.chatCompletion(y, t, {
554
+ temperature: r?.temperature || 0.5,
555
+ maxTokens: r?.maxTokens || 1500,
556
+ stream: !1,
557
+ modelType: this.modelType
558
+ });
559
+ return this.extractContent(h);
560
+ } catch (h) {
561
+ throw new Error(`OHLCV analysis failed: ${h.message}`);
562
+ }
563
+ }
564
+ /**
565
+ * Enhanced version: Analyze OHLCV and return structured results (optional)
566
+ * @param ohlcvArray - OHLCV data array
567
+ * @param i18n - Language restriction for AI response
568
+ * @param analysisType - Analysis type
569
+ * @param message - User's subjective request or specific question
570
+ * @param structured - Whether to return structured results (default: false)
571
+ * @param options - Chat options
572
+ * @returns AI analysis results
573
+ */
574
+ async analyzeOHLCVEnhanced(e, t, s, a, r = !1, o) {
575
+ if (r) {
576
+ const i = t === "en" ? `You are a professional financial data analyst. Analyze the OHLCV data and provide a structured response with:
577
+ 1. Summary (brief overview)
578
+ 2. Details (key observations, 3-5 points)
579
+ 3. Recommendations (actionable insights, 2-3 points)
580
+ Format as JSON: {"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}` : `您是一位专业的金融数据分析师。分析OHLCV数据并提供结构化响应:
581
+ 1. 总结(简要概述)
582
+ 2. 详情(关键观察结果,3-5点)
583
+ 3. 建议(可操作的见解,2-3点)
584
+ 格式化为JSON:{"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}`, d = JSON.stringify(e, null, 2);
585
+ let l = t === "en" ? `Analyze this OHLCV data (${e.length} periods):
586
+ ${d}` : `分析此OHLCV数据(${e.length}个周期):
587
+ ${d}`;
588
+ a && (l += t === "en" ? `
589
+
590
+ Additional request: ${a}` : `
591
+
592
+ 附加要求:${a}`);
593
+ const u = [
594
+ { role: "system", content: i },
595
+ { role: "user", content: l }
596
+ ];
597
+ try {
598
+ const m = await this.chatCompletion(u, t, {
599
+ temperature: o?.temperature || 0.4,
600
+ maxTokens: o?.maxTokens || 1200,
601
+ stream: !1,
602
+ modelType: this.modelType
603
+ }), c = this.extractContent(m);
604
+ try {
605
+ const p = JSON.parse(c);
606
+ if (p.summary && Array.isArray(p.details) && Array.isArray(p.recommendations))
607
+ return p;
608
+ } catch {
609
+ }
610
+ return c;
611
+ } catch (m) {
612
+ throw new Error(`Structured OHLCV analysis failed: ${m.message}`);
613
+ }
614
+ }
615
+ return this.analyzeOHLCV(e, t, s, a, o);
616
+ }
617
+ /**
618
+ * Specialized method for processing OHLCV arrays
619
+ * @param ohlcvArray - OHLCV data array
620
+ * @param i18n - Language restriction for AI response
621
+ * @param instructions - Processing instructions, supports Chinese and English (optional, default: "Based on these OHLCV data, predict the next period")
622
+ * @param count - Number of OHLCV data items to return (optional, default: 1)
623
+ * @param options - Chat options
624
+ * @returns Predicted OHLCV array
625
+ */
626
+ async predictingOHLCV(e, t, s, a, r) {
627
+ const o = s || "Based on these OHLCV data, predict the next period", i = a || 1;
628
+ if (!Number.isInteger(i) || i <= 0)
629
+ throw new Error(`Invalid count parameter: ${i}. Must be a positive integer.`);
630
+ const d = 50;
631
+ if (i > d)
632
+ throw new Error(`Count parameter too large: ${i}. Maximum allowed is ${d}. Please reduce the count or split your request.`);
633
+ const l = i === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${i} consecutive OHLCV objects for the next ${i} periods.`, u = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
634
+ let m = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
635
+ Your task: ${o}
636
+ CRITICAL RULES:
637
+ 1. ${l}
638
+ 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
639
+ 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
640
+ 4. All numbers must be valid numbers
641
+ 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
642
+ 6. Maintain consistency with historical trends and patterns
643
+ 7. For technical analysis, provide reasonable values based on typical patterns
644
+ 8. Do not include markdown formatting, only pure JSON
645
+ ${i === 1 ? `Example of valid response for 1 period:
646
+ [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${i} periods:
647
+ [
648
+ {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
649
+ {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
650
+ ${i > 2 ? `,
651
+ ... ${i - 2} more OHLCV objects following the same pattern` : ""}
652
+ ]`}`;
653
+ u && (m = `${m}
654
+
655
+ ${u}`);
656
+ const c = JSON.stringify(e, null, 2), p = `Here is the historical OHLCV data (${e.length} periods):
657
+ ${c}
658
+ Please process this data according to the system instructions. Remember to return EXACTLY ${i} OHLCV object(s) in a JSON array with no additional text.`, g = [
659
+ { role: "system", content: m },
660
+ { role: "user", content: p }
661
+ ];
662
+ try {
663
+ const y = i * 50 + 100, h = Math.max(r?.maxTokens || 1e3, y), b = await this.chatCompletion(g, t, {
664
+ temperature: r?.temperature || 0.3,
665
+ maxTokens: h,
666
+ stream: !1,
667
+ modelType: this.modelType
668
+ }), f = this.extractContent(b), w = this.parseOHLCVResponse(f);
669
+ if (w.length !== i)
670
+ throw new Error(`AI returned ${w.length} OHLCV objects, but expected ${i}.`);
671
+ return w;
672
+ } catch (y) {
673
+ throw new Error(`OHLCV analysis failed: ${y.message}`);
674
+ }
675
+ }
676
+ /**
677
+ * Parse AI returned OHLCV response
678
+ * @private
679
+ */
680
+ parseOHLCVResponse(e) {
681
+ try {
682
+ const t = JSON.parse(e);
683
+ if (!Array.isArray(t))
684
+ throw new Error("Response is not in array format");
685
+ return t.map((a, r) => {
686
+ if (typeof a != "object" || a === null)
687
+ throw new Error(`Element ${r} is not a valid object`);
688
+ const { open: o, high: i, low: d, close: l, volume: u } = a, m = ["open", "high", "low", "close", "volume"];
689
+ for (const c of m)
690
+ if (typeof a[c] != "number" || isNaN(a[c]))
691
+ throw new Error(`Element ${r} field ${c} is not a valid number`);
692
+ if (i < d)
693
+ throw new Error(`Element ${r}: high cannot be lower than low`);
694
+ if (l < d || l > i)
695
+ throw new Error(`Element ${r}: close must be between low and high`);
696
+ return {
697
+ open: Number(o),
698
+ high: Number(i),
699
+ low: Number(d),
700
+ close: Number(l),
701
+ volume: Number(u)
702
+ };
703
+ });
704
+ } catch (t) {
705
+ const s = e.match(/\[[\s\S]*\]/);
706
+ if (s)
707
+ return this.parseOHLCVResponse(s[0]);
708
+ throw new Error(`Unable to parse AI returned OHLCV data: ${t}
709
+ Original content: ${e.substring(0, 200)}...`);
451
710
  }
452
711
  }
453
712
  /**
@@ -455,7 +714,7 @@ class _ {
455
714
  * @param modelType - New model type
456
715
  */
457
716
  setModel(e) {
458
- if (!b.get(e))
717
+ if (!k.get(e))
459
718
  throw new Error(`Unsupported model type: ${e}`);
460
719
  this.modelType = e;
461
720
  }
@@ -463,7 +722,7 @@ class _ {
463
722
  * Get current model configuration
464
723
  */
465
724
  getCurrentModel() {
466
- const e = b.get(this.modelType);
725
+ const e = k.get(this.modelType);
467
726
  if (!e)
468
727
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
469
728
  return {
@@ -478,7 +737,7 @@ class _ {
478
737
  */
479
738
  async testConnection() {
480
739
  try {
481
- const e = await this.chat('Hello, respond with "OK" if you can hear me.');
740
+ const e = await this.chat('Hello, respond with "OK" if you can hear me.', "en");
482
741
  return {
483
742
  success: !0,
484
743
  model: this.modelType,
@@ -492,19 +751,19 @@ class _ {
492
751
  };
493
752
  }
494
753
  }
495
- buildOpenAIRequest(e, o, s, a, i) {
754
+ buildOpenAIRequest(e, t, s, a, r) {
496
755
  return {
497
756
  model: e,
498
- messages: o,
757
+ messages: t,
499
758
  temperature: s,
500
759
  max_tokens: a,
501
- stream: i
760
+ stream: r
502
761
  };
503
762
  }
504
- buildDashScopeRequest(e, o, s, a) {
763
+ buildDashScopeRequest(e, t, s, a) {
505
764
  return {
506
765
  model: e,
507
- input: { messages: o },
766
+ input: { messages: t },
508
767
  parameters: {
509
768
  temperature: s,
510
769
  max_tokens: a,
@@ -512,61 +771,61 @@ class _ {
512
771
  }
513
772
  };
514
773
  }
515
- async makeRequest(e, o, s) {
516
- const a = new AbortController(), i = setTimeout(() => a.abort(), this.timeout);
774
+ async makeRequest(e, t, s) {
775
+ const a = new AbortController(), r = setTimeout(() => a.abort(), this.timeout);
517
776
  try {
518
- const n = await fetch(e, {
777
+ const o = await fetch(e, {
519
778
  method: "POST",
520
779
  headers: {
521
780
  Authorization: `Bearer ${this.apiKey}`,
522
781
  "Content-Type": "application/json; charset=utf-8",
523
782
  Accept: "application/json"
524
783
  },
525
- body: JSON.stringify(o),
784
+ body: JSON.stringify(t),
526
785
  signal: a.signal
527
786
  });
528
- if (clearTimeout(i), !n.ok) {
529
- const r = await n.text();
530
- throw new Error(`HTTP ${n.status}: ${r}`);
787
+ if (clearTimeout(r), !o.ok) {
788
+ const i = await o.text();
789
+ throw new Error(`HTTP ${o.status}: ${i}`);
531
790
  }
532
- return s ? n.body : await n.json();
533
- } catch (n) {
534
- throw clearTimeout(i), n.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : n;
791
+ return s ? o.body : await o.json();
792
+ } catch (o) {
793
+ throw clearTimeout(r), o.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : o;
535
794
  }
536
795
  }
537
- async makeStreamRequest(e, o, s) {
538
- const a = await this.makeRequest(e, o, !0);
796
+ async makeStreamRequest(e, t, s) {
797
+ const a = await this.makeRequest(e, t, !0);
539
798
  if (!a)
540
799
  throw new Error("Failed to get streaming response");
541
- const i = a.getReader(), n = new TextDecoder("utf-8");
542
- let r = "";
800
+ const r = a.getReader(), o = new TextDecoder("utf-8");
801
+ let i = "";
543
802
  try {
544
803
  for (; ; ) {
545
- const { done: m, value: c } = await i.read();
546
- if (m) {
804
+ const { done: d, value: l } = await r.read();
805
+ if (d) {
547
806
  s("", !0);
548
807
  break;
549
808
  }
550
- r += n.decode(c, { stream: !0 });
551
- const p = r.split(`
809
+ i += o.decode(l, { stream: !0 });
810
+ const u = i.split(`
552
811
  `);
553
- r = p.pop() || "";
554
- for (const d of p)
555
- if (d.startsWith("data: ")) {
556
- const l = d.slice(6);
557
- if (l === "[DONE]") {
812
+ i = u.pop() || "";
813
+ for (const m of u)
814
+ if (m.startsWith("data: ")) {
815
+ const c = m.slice(6);
816
+ if (c === "[DONE]") {
558
817
  s("", !0);
559
818
  return;
560
819
  }
561
820
  try {
562
- const u = JSON.parse(l);
563
- u.choices?.[0]?.delta?.content && s(u.choices[0].delta.content, !1);
821
+ const p = JSON.parse(c);
822
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
564
823
  } catch {
565
824
  }
566
825
  }
567
826
  }
568
827
  } finally {
569
- i.releaseLock();
828
+ r.releaseLock();
570
829
  }
571
830
  }
572
831
  extractContent(e) {
@@ -578,101 +837,12 @@ class _ {
578
837
  return e.output.text;
579
838
  throw new Error("Unable to parse response content");
580
839
  }
581
- /**
582
- * Specialized method for processing OHLCV arrays
583
- * @param ohlcvArray - OHLCV data array
584
- * @param instructions - Processing instructions, supports Chinese and English (optional, default: "Based on these OHLCV data, predict the next period")
585
- * @param count - Number of OHLCV data items to return (optional, default: 1)
586
- * @param options - Chat options
587
- * @returns Predicted OHLCV array
588
- */
589
- async predictingOHLCV(e, o, s, a) {
590
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
591
- if (!Number.isInteger(n) || n <= 0)
592
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
593
- const r = 50;
594
- if (n > r)
595
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}. Please reduce the count or split your request.`);
596
- const m = n === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${n} consecutive OHLCV objects for the next ${n} periods.`, c = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
597
- Your task: ${i}
598
- CRITICAL RULES:
599
- 1. ${m}
600
- 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
601
- 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
602
- 4. All numbers must be valid numbers
603
- 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
604
- 6. Maintain consistency with historical trends and patterns
605
- 7. For technical analysis, provide reasonable values based on typical patterns
606
- 8. Do not include markdown formatting, only pure JSON
607
- ${n === 1 ? `Example of valid response for 1 period:
608
- [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${n} periods:
609
- [
610
- {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
611
- {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
612
- ${n > 2 ? `,
613
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
614
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
615
- ${p}
616
- Please process this data according to the system instructions. Remember to return EXACTLY ${n} OHLCV object(s) in a JSON array with no additional text.`, l = [
617
- { role: "system", content: c },
618
- { role: "user", content: d }
619
- ];
620
- try {
621
- const u = n * 50 + 100, x = Math.max(a?.maxTokens || 1e3, u), v = await this.chatCompletion(l, {
622
- temperature: a?.temperature || 0.3,
623
- maxTokens: x,
624
- stream: !1,
625
- modelType: a?.modelType
626
- }), E = this.extractContent(v), g = this.parseOHLCVResponse(E);
627
- if (g.length !== n)
628
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
629
- return g;
630
- } catch (u) {
631
- throw new Error(`OHLCV analysis failed: ${u.message}`);
632
- }
633
- }
634
- /**
635
- * Parse AI returned OHLCV response
636
- * @private
637
- */
638
- parseOHLCVResponse(e) {
639
- try {
640
- const o = JSON.parse(e);
641
- if (!Array.isArray(o))
642
- throw new Error("Response is not in array format");
643
- return o.map((a, i) => {
644
- if (typeof a != "object" || a === null)
645
- throw new Error(`Element ${i} is not a valid object`);
646
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
647
- for (const l of d)
648
- if (typeof a[l] != "number" || isNaN(a[l]))
649
- throw new Error(`Element ${i} field ${l} is not a valid number`);
650
- if (r < m)
651
- throw new Error(`Element ${i}: high cannot be lower than low`);
652
- if (c < m || c > r)
653
- throw new Error(`Element ${i}: close must be between low and high`);
654
- return {
655
- open: Number(n),
656
- high: Number(r),
657
- low: Number(m),
658
- close: Number(c),
659
- volume: Number(p)
660
- };
661
- });
662
- } catch (o) {
663
- const s = e.match(/\[[\s\S]*\]/);
664
- if (s)
665
- return this.parseOHLCVResponse(s[0]);
666
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
667
- Original content: ${e.substring(0, 200)}...`);
668
- }
669
- }
670
840
  }
671
- function R(t, e) {
672
- return new _({ apiKey: t, modelType: e });
841
+ function B(n, e) {
842
+ return new q({ apiKey: n, modelType: e });
673
843
  }
674
- var k = /* @__PURE__ */ ((t) => (t.DEEPSEEK_CHAT = "deepseek-chat", t.DEEPSEEK_CHAT_LITE = "deepseek-chat-lite", t.DEEPSEEK_CHAT_PRO = "deepseek-chat-pro", t.DEEPSEEK_CHAT_MAX = "deepseek-chat-max", t.DEEPSEEK_CODER = "deepseek-coder", t.DEEPSEEK_CODER_LITE = "deepseek-coder-lite", t.DEEPSEEK_CODER_PRO = "deepseek-coder-pro", t.DEEPSEEK_MATH = "deepseek-math", t.DEEPSEEK_MATH_PRO = "deepseek-math-pro", t.DEEPSEEK_REASONER = "deepseek-reasoner", t.DEEPSEEK_REASONER_PRO = "deepseek-reasoner-pro", t.DEEPSEEK_VISION = "deepseek-vision", t.DEEPSEEK_VISION_PRO = "deepseek-vision-pro", t.DEEPSEEK_FINANCE = "deepseek-finance", t.DEEPSEEK_LAW = "deepseek-law", t.DEEPSEEK_MEDICAL = "deepseek-medical", t.DEEPSEEK_RESEARCH = "deepseek-research", t.DEEPSEEK_OMNI = "deepseek-omni", t.DEEPSEEK_OMNI_PRO = "deepseek-omni-pro", t.DEEPSEEK_LLM = "deepseek-llm", t.DEEPSEEK_LLM_67B = "deepseek-llm-67b", t.DEEPSEEK_LLM_131B = "deepseek-llm-131b", t))(k || {});
675
- const y = /* @__PURE__ */ new Map([
844
+ var N = /* @__PURE__ */ ((n) => (n.DEEPSEEK_CHAT = "deepseek-chat", n.DEEPSEEK_CHAT_LITE = "deepseek-chat-lite", n.DEEPSEEK_CHAT_PRO = "deepseek-chat-pro", n.DEEPSEEK_CHAT_MAX = "deepseek-chat-max", n.DEEPSEEK_CODER = "deepseek-coder", n.DEEPSEEK_CODER_LITE = "deepseek-coder-lite", n.DEEPSEEK_CODER_PRO = "deepseek-coder-pro", n.DEEPSEEK_MATH = "deepseek-math", n.DEEPSEEK_MATH_PRO = "deepseek-math-pro", n.DEEPSEEK_REASONER = "deepseek-reasoner", n.DEEPSEEK_REASONER_PRO = "deepseek-reasoner-pro", n.DEEPSEEK_VISION = "deepseek-vision", n.DEEPSEEK_VISION_PRO = "deepseek-vision-pro", n.DEEPSEEK_FINANCE = "deepseek-finance", n.DEEPSEEK_LAW = "deepseek-law", n.DEEPSEEK_MEDICAL = "deepseek-medical", n.DEEPSEEK_RESEARCH = "deepseek-research", n.DEEPSEEK_OMNI = "deepseek-omni", n.DEEPSEEK_OMNI_PRO = "deepseek-omni-pro", n.DEEPSEEK_LLM = "deepseek-llm", n.DEEPSEEK_LLM_67B = "deepseek-llm-67b", n.DEEPSEEK_LLM_131B = "deepseek-llm-131b", n))(N || {});
845
+ const $ = /* @__PURE__ */ new Map([
676
846
  // Chat models
677
847
  [
678
848
  "deepseek-chat",
@@ -965,28 +1135,28 @@ const y = /* @__PURE__ */ new Map([
965
1135
  }
966
1136
  ]
967
1137
  ]);
968
- function S(t) {
969
- return y.get(t);
1138
+ function K(n) {
1139
+ return $.get(n);
970
1140
  }
971
- function A() {
972
- return Array.from(y.values());
1141
+ function F() {
1142
+ return Array.from($.values());
973
1143
  }
974
- function D(t) {
975
- for (const e of y.values())
976
- if (e.name === t)
1144
+ function U(n) {
1145
+ for (const e of $.values())
1146
+ if (e.name === n)
977
1147
  return e;
978
1148
  }
979
- function B() {
980
- return Array.from(y.keys());
1149
+ function Q() {
1150
+ return Array.from($.keys());
981
1151
  }
982
- function I(t) {
983
- const e = Object.values(k);
984
- for (const o of e)
985
- if (o === t)
986
- return o;
1152
+ function z(n) {
1153
+ const e = Object.values(N);
1154
+ for (const t of e)
1155
+ if (t === n)
1156
+ return t;
987
1157
  return null;
988
1158
  }
989
- class C {
1159
+ class H {
990
1160
  /**
991
1161
  * Constructor - Minimal configuration
992
1162
  * @param config.apiKey - API key (required)
@@ -995,92 +1165,270 @@ class C {
995
1165
  * @param config.baseURL - Base URL for API, default official endpoint
996
1166
  */
997
1167
  constructor(e) {
998
- if (this.apiKey = e.apiKey, this.modelType = e.modelType || k.DEEPSEEK_CHAT, this.timeout = e.timeout || 3e4, this.baseURL = e.baseURL || "https://api.deepseek.com", !this.apiKey)
1168
+ if (this.apiKey = e.apiKey, this.modelType = e.modelType || N.DEEPSEEK_CHAT, this.timeout = e.timeout || 3e4, this.baseURL = e.baseURL || "https://api.deepseek.com", !this.apiKey)
999
1169
  throw new Error("API Key cannot be empty");
1000
- if (!y.get(this.modelType))
1170
+ if (!$.get(this.modelType))
1001
1171
  throw new Error(`Unsupported model type: ${this.modelType}`);
1002
1172
  }
1003
1173
  /**
1004
- * Simplest method: single conversation
1174
+ * Simplest method: single conversation with i18n support
1005
1175
  * @param message - User message
1176
+ * @param i18n - Language restriction for AI response
1006
1177
  * @param options - Chat options
1007
1178
  * @returns AI response
1008
1179
  */
1009
- async chat(e, o) {
1010
- const s = [];
1011
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
1012
- const a = await this.chatCompletion(s, {
1013
- temperature: o?.temperature,
1014
- maxTokens: o?.maxTokens,
1180
+ async chat(e, t, s) {
1181
+ const a = [], r = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
1182
+ if (s?.systemPrompt || r) {
1183
+ const i = [s?.systemPrompt, r].filter(Boolean).join(`
1184
+ `);
1185
+ a.push({ role: "system", content: i });
1186
+ }
1187
+ a.push({ role: "user", content: e });
1188
+ const o = await this.chatCompletion(a, t, {
1189
+ temperature: s?.temperature,
1190
+ maxTokens: s?.maxTokens,
1015
1191
  stream: !1,
1016
- modelType: o?.modelType,
1017
- topP: o?.topP,
1018
- frequencyPenalty: o?.frequencyPenalty,
1019
- presencePenalty: o?.presencePenalty,
1020
- stop: o?.stop,
1021
- tools: o?.tools,
1022
- toolChoice: o?.toolChoice
1192
+ modelType: this.modelType,
1193
+ topP: s?.topP,
1194
+ frequencyPenalty: s?.frequencyPenalty,
1195
+ presencePenalty: s?.presencePenalty,
1196
+ stop: s?.stop,
1197
+ tools: s?.tools,
1198
+ toolChoice: s?.toolChoice
1023
1199
  });
1024
- return this.extractContent(a);
1200
+ return this.extractContent(o);
1025
1201
  }
1026
1202
  /**
1027
- * Multi-turn conversation
1203
+ * Multi-turn conversation with i18n support
1028
1204
  * @param messages - Message history
1205
+ * @param i18n - Language restriction for AI response
1029
1206
  * @param options - Chat options
1030
1207
  * @returns Complete API response
1031
1208
  */
1032
- async chatCompletion(e, o) {
1033
- const s = o?.modelType || this.modelType, a = y.get(s);
1034
- if (!a)
1035
- throw new Error(`Unsupported model type: ${s}`);
1036
- const i = o?.temperature ?? 0.7, n = o?.maxTokens ?? 2e3, r = o?.stream ?? !1, m = o?.topP ?? 1, c = o?.frequencyPenalty ?? 0, p = o?.presencePenalty ?? 0, d = o?.stop, l = o?.tools, u = o?.toolChoice, x = a.endpoint, v = this.buildOpenAIRequest(
1037
- a.name,
1209
+ async chatCompletion(e, t, s) {
1210
+ const a = s?.modelType || this.modelType, r = $.get(a);
1211
+ if (!r)
1212
+ throw new Error(`Unsupported model type: ${a}`);
1213
+ const o = s?.temperature ?? 0.7, i = s?.maxTokens ?? 2e3, d = s?.stream ?? !1, l = s?.topP ?? 1, u = s?.frequencyPenalty ?? 0, m = s?.presencePenalty ?? 0, c = s?.stop, p = s?.tools, g = s?.toolChoice, y = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
1214
+ y && (e.some((w) => w.role === "system") ? e = e.map((w) => w.role === "system" ? {
1215
+ ...w,
1216
+ content: `${w.content}
1217
+ ${y}`
1218
+ } : w) : e.unshift({ role: "system", content: y }));
1219
+ const h = r.endpoint, b = this.buildOpenAIRequest(
1220
+ r.name,
1038
1221
  e,
1222
+ o,
1039
1223
  i,
1040
- n,
1041
- r,
1224
+ d,
1225
+ l,
1226
+ u,
1042
1227
  m,
1043
1228
  c,
1044
1229
  p,
1045
- d,
1046
- l,
1047
- u
1230
+ g
1048
1231
  );
1049
1232
  try {
1050
- return await this.makeRequest(x, v, r);
1051
- } catch (E) {
1052
- throw new Error(`DeepSeek AI request failed: ${E.message}`);
1233
+ return await this.makeRequest(h, b, d);
1234
+ } catch (f) {
1235
+ throw new Error(`DeepSeek AI request failed: ${f.message}`);
1053
1236
  }
1054
1237
  }
1055
1238
  /**
1056
- * Streaming conversation
1239
+ * Streaming conversation with i18n support
1057
1240
  * @param messages - Message history
1058
1241
  * @param callback - Streaming callback function
1242
+ * @param i18n - Language restriction for AI response
1059
1243
  * @param options - Chat options
1060
1244
  */
1061
- async chatStream(e, o, s) {
1062
- const a = s?.modelType || this.modelType, i = y.get(a);
1063
- if (!i)
1064
- throw new Error(`Unsupported model type: ${a}`);
1065
- const n = s?.temperature ?? 0.7, r = s?.maxTokens ?? 2e3, m = s?.topP ?? 1, c = s?.frequencyPenalty ?? 0, p = s?.presencePenalty ?? 0, d = this.buildOpenAIRequest(
1066
- i.name,
1245
+ async chatStream(e, t, s, a) {
1246
+ const r = a?.modelType || this.modelType, o = $.get(r);
1247
+ if (!o)
1248
+ throw new Error(`Unsupported model type: ${r}`);
1249
+ const i = a?.temperature ?? 0.7, d = a?.maxTokens ?? 2e3, l = a?.topP ?? 1, u = a?.frequencyPenalty ?? 0, m = a?.presencePenalty ?? 0, c = s === "en" ? "Please respond in English only." : s === "cn" ? "请使用中文回答。" : "";
1250
+ c && (e.some((y) => y.role === "system") ? e = e.map((y) => y.role === "system" ? {
1251
+ ...y,
1252
+ content: `${y.content}
1253
+ ${c}`
1254
+ } : y) : e.unshift({ role: "system", content: c }));
1255
+ const p = this.buildOpenAIRequest(
1256
+ o.name,
1067
1257
  e,
1068
- n,
1069
- r,
1258
+ i,
1259
+ d,
1070
1260
  !0,
1261
+ l,
1262
+ u,
1071
1263
  m,
1072
- c,
1073
- p,
1074
- s?.stop,
1075
- s?.tools,
1076
- s?.toolChoice
1264
+ a?.stop,
1265
+ a?.tools,
1266
+ a?.toolChoice
1077
1267
  );
1078
1268
  try {
1079
- await this.makeStreamRequest(i.endpoint, d, o);
1080
- } catch (l) {
1081
- throw new Error(`Streaming request failed: ${l.message}`);
1269
+ await this.makeStreamRequest(o.endpoint, p, t);
1270
+ } catch (g) {
1271
+ throw new Error(`Streaming request failed: ${g.message}`);
1082
1272
  }
1083
1273
  }
1274
+ /**
1275
+ * Analyze OHLCV data and return AI analysis results (text description)
1276
+ * @param ohlcvArray - OHLCV data array
1277
+ * @param i18n - Language restriction for AI response
1278
+ * @param analysisType - Analysis type (optional, default: "comprehensive")
1279
+ * - "trend": Trend analysis
1280
+ * - "volume": Volume analysis
1281
+ * - "technical": Technical analysis
1282
+ * - "comprehensive": Comprehensive analysis
1283
+ * @param message - User's subjective request or specific question (optional)
1284
+ * @param options - Chat options
1285
+ * @returns AI analysis result of OHLCV data (text description)
1286
+ */
1287
+ async analyzeOHLCV(e, t, s, a, r) {
1288
+ const o = s || "comprehensive", i = e.length, l = {
1289
+ trend: {
1290
+ en: "Provide a detailed trend analysis of this OHLCV data, including price direction, support/resistance levels, and trend strength.",
1291
+ cn: "提供详细的OHLCV数据趋势分析,包括价格方向、支撑/阻力位和趋势强度。"
1292
+ },
1293
+ volume: {
1294
+ en: "Analyze the volume patterns in this OHLCV data, including volume trends, unusual volume spikes, and volume-price relationships.",
1295
+ cn: "分析OHLCV数据中的成交量模式,包括成交量趋势、异常成交量波动和量价关系。"
1296
+ },
1297
+ technical: {
1298
+ en: "Perform technical analysis on this OHLCV data, identifying potential technical indicators, patterns, and trading signals.",
1299
+ cn: "对OHLCV数据进行技术分析,识别潜在的技术指标、图表形态和交易信号。"
1300
+ },
1301
+ comprehensive: {
1302
+ en: "Provide a comprehensive analysis of this OHLCV data, covering trends, volume, technical aspects, and potential market implications.",
1303
+ cn: "提供全面的OHLCV数据分析,涵盖趋势、成交量、技术面和潜在市场影响。"
1304
+ }
1305
+ }[o][t], u = t === "en" ? "Please provide your analysis in English." : "请用中文进行分析。";
1306
+ let m = "";
1307
+ if (i > 0) {
1308
+ const h = e[0], f = e[i - 1].close - h.close, w = f / h.close * 100;
1309
+ let C = h.high, v = h.low, P = 0;
1310
+ for (const E of e)
1311
+ E.high > C && (C = E.high), E.low < v && (v = E.low), P += E.volume;
1312
+ const _ = P / i;
1313
+ m = t === "en" ? `This dataset contains ${i} periods of OHLCV data.
1314
+ Price range: ${v.toFixed(2)} - ${C.toFixed(2)}
1315
+ Overall price change: ${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
1316
+ Average volume: ${_.toFixed(0)}` : `该数据集包含 ${i} 个周期的OHLCV数据。
1317
+ 价格范围:${v.toFixed(2)} - ${C.toFixed(2)}
1318
+ 总体价格变化:${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
1319
+ 平均成交量:${_.toFixed(0)}`;
1320
+ }
1321
+ let c = t === "en" ? `You are a professional financial data analyst. Your task is to analyze OHLCV (Open, High, Low, Close, Volume) data and provide insights.
1322
+ Analysis focus: ${l}
1323
+ ${m ? `Data characteristics:
1324
+ ${m}
1325
+
1326
+ ` : ""}
1327
+ Please provide:
1328
+ 1. Clear and structured analysis
1329
+ 2. Key observations from the data
1330
+ 3. Potential implications or insights
1331
+ 4. Recommendations or considerations (if applicable)
1332
+ Format your response as a well-organized text analysis.` : `您是一位专业的金融数据分析师。您的任务是分析OHLCV(开盘价、最高价、最低价、收盘价、成交量)数据并提供见解。
1333
+ 分析重点:${l}
1334
+ ${m ? `数据特征:
1335
+ ${m}
1336
+
1337
+ ` : ""}
1338
+ 请提供:
1339
+ 1. 清晰且有结构的分析
1340
+ 2. 数据的关键观察结果
1341
+ 3. 潜在的启示或见解
1342
+ 4. 建议或注意事项(如适用)
1343
+ 请以组织良好的文本分析形式回复。`;
1344
+ c += `
1345
+
1346
+ ${u}`;
1347
+ const p = JSON.stringify(e, null, 2);
1348
+ let g = "";
1349
+ a ? g = t === "en" ? `Here is the OHLCV data (${i} periods):
1350
+ ${p}
1351
+ My specific question or request: ${a}
1352
+ Please analyze this data considering my request above.` : `这是OHLCV数据(${i}个周期):
1353
+ ${p}
1354
+ 我的具体问题或需求:${a}
1355
+ 请根据我的上述需求分析这些数据。` : g = t === "en" ? `Here is the OHLCV data (${i} periods):
1356
+ ${p}
1357
+ Please analyze this data as requested.` : `这是OHLCV数据(${i}个周期):
1358
+ ${p}
1359
+ 请按要求分析这些数据。`;
1360
+ const y = [
1361
+ { role: "system", content: c },
1362
+ { role: "user", content: g }
1363
+ ];
1364
+ try {
1365
+ const h = await this.chatCompletion(y, t, {
1366
+ temperature: r?.temperature || 0.5,
1367
+ maxTokens: r?.maxTokens || 1500,
1368
+ stream: !1,
1369
+ modelType: this.modelType,
1370
+ topP: r?.topP,
1371
+ frequencyPenalty: r?.frequencyPenalty,
1372
+ presencePenalty: r?.presencePenalty
1373
+ });
1374
+ return this.extractContent(h);
1375
+ } catch (h) {
1376
+ throw new Error(`OHLCV analysis failed: ${h.message}`);
1377
+ }
1378
+ }
1379
+ /**
1380
+ * Enhanced version: Analyze OHLCV and return structured results (optional)
1381
+ * @param ohlcvArray - OHLCV data array
1382
+ * @param i18n - Language restriction for AI response
1383
+ * @param analysisType - Analysis type
1384
+ * @param message - User's subjective request or specific question
1385
+ * @param structured - Whether to return structured results (default: false)
1386
+ * @param options - Chat options
1387
+ * @returns AI analysis results
1388
+ */
1389
+ async analyzeOHLCVEnhanced(e, t, s, a, r = !1, o) {
1390
+ if (r) {
1391
+ const i = t === "en" ? `You are a professional financial data analyst. Analyze the OHLCV data and provide a structured response with:
1392
+ 1. Summary (brief overview)
1393
+ 2. Details (key observations, 3-5 points)
1394
+ 3. Recommendations (actionable insights, 2-3 points)
1395
+ Format as JSON: {"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}` : `您是一位专业的金融数据分析师。分析OHLCV数据并提供结构化响应:
1396
+ 1. 总结(简要概述)
1397
+ 2. 详情(关键观察结果,3-5点)
1398
+ 3. 建议(可操作的见解,2-3点)
1399
+ 格式化为JSON:{"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}`, d = JSON.stringify(e, null, 2);
1400
+ let l = t === "en" ? `Analyze this OHLCV data (${e.length} periods):
1401
+ ${d}` : `分析此OHLCV数据(${e.length}个周期):
1402
+ ${d}`;
1403
+ a && (l += t === "en" ? `
1404
+
1405
+ Additional request: ${a}` : `
1406
+
1407
+ 附加要求:${a}`);
1408
+ const u = [
1409
+ { role: "system", content: i },
1410
+ { role: "user", content: l }
1411
+ ];
1412
+ try {
1413
+ const m = await this.chatCompletion(u, t, {
1414
+ temperature: o?.temperature || 0.4,
1415
+ maxTokens: o?.maxTokens || 1200,
1416
+ stream: !1,
1417
+ modelType: this.modelType
1418
+ }), c = this.extractContent(m);
1419
+ try {
1420
+ const p = JSON.parse(c);
1421
+ if (p.summary && Array.isArray(p.details) && Array.isArray(p.recommendations))
1422
+ return p;
1423
+ } catch {
1424
+ }
1425
+ return c;
1426
+ } catch (m) {
1427
+ throw new Error(`Structured OHLCV analysis failed: ${m.message}`);
1428
+ }
1429
+ }
1430
+ return this.analyzeOHLCV(e, t, s, a, o);
1431
+ }
1084
1432
  /**
1085
1433
  * Specialized method for processing OHLCV arrays
1086
1434
  * @param ohlcvArray - OHLCV data array
@@ -1089,17 +1437,17 @@ class C {
1089
1437
  * @param options - Chat options
1090
1438
  * @returns Predicted OHLCV array
1091
1439
  */
1092
- async predictingOHLCV(e, o, s, a) {
1093
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
1094
- if (!Number.isInteger(n) || n <= 0)
1095
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
1096
- const r = 50;
1097
- if (n > r)
1098
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}.`);
1099
- const m = n === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${n} consecutive OHLCV objects for the next ${n} periods.`, c = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
1100
- Your task: ${i}
1440
+ async predictingOHLCV(e, t, s, a) {
1441
+ const r = t || "Based on these OHLCV data, predict the next period", o = s || 1;
1442
+ if (!Number.isInteger(o) || o <= 0)
1443
+ throw new Error(`Invalid count parameter: ${o}. Must be a positive integer.`);
1444
+ const i = 50;
1445
+ if (o > i)
1446
+ throw new Error(`Count parameter too large: ${o}. Maximum allowed is ${i}.`);
1447
+ const d = o === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${o} consecutive OHLCV objects for the next ${o} periods.`, l = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
1448
+ Your task: ${r}
1101
1449
  CRITICAL RULES:
1102
- 1. ${m}
1450
+ 1. ${d}
1103
1451
  2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
1104
1452
  3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
1105
1453
  4. All numbers must be valid numbers
@@ -1108,34 +1456,34 @@ CRITICAL RULES:
1108
1456
  7. For technical analysis, provide reasonable values based on typical patterns
1109
1457
  8. Do not include markdown formatting, only pure JSON
1110
1458
 
1111
- ${n === 1 ? `Example of valid response for 1 period:
1112
- [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${n} periods:
1459
+ ${o === 1 ? `Example of valid response for 1 period:
1460
+ [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${o} periods:
1113
1461
  [
1114
1462
  {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
1115
1463
  {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
1116
- ${n > 2 ? `,
1117
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
1118
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
1119
- ${p}
1120
- Please process this data according to the system instructions. Remember to return EXACTLY ${n} OHLCV object(s) in a JSON array with no additional text.`, l = [
1121
- { role: "system", content: c },
1122
- { role: "user", content: d }
1464
+ ${o > 2 ? `,
1465
+ ... ${o - 2} more OHLCV objects following the same pattern` : ""}
1466
+ ]`}`, u = JSON.stringify(e, null, 2), m = `Here is the historical OHLCV data (${e.length} periods):
1467
+ ${u}
1468
+ Please process this data according to the system instructions. Remember to return EXACTLY ${o} OHLCV object(s) in a JSON array with no additional text.`, c = [
1469
+ { role: "system", content: l },
1470
+ { role: "user", content: m }
1123
1471
  ];
1124
1472
  try {
1125
- const u = n * 50 + 100, x = Math.max(a?.maxTokens || 2e3, u), v = await this.chatCompletion(l, {
1473
+ const p = o * 50 + 100, g = Math.max(a?.maxTokens || 2e3, p), y = await this.chatCompletion(c, "en", {
1126
1474
  temperature: a?.temperature || 0.3,
1127
- maxTokens: x,
1475
+ maxTokens: g,
1128
1476
  stream: !1,
1129
- modelType: a?.modelType || k.DEEPSEEK_FINANCE,
1477
+ modelType: this.modelType,
1130
1478
  topP: a?.topP,
1131
1479
  frequencyPenalty: a?.frequencyPenalty,
1132
1480
  presencePenalty: a?.presencePenalty
1133
- }), E = this.extractContent(v), g = this.parseOHLCVResponse(E);
1134
- if (g.length !== n)
1135
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
1136
- return g;
1137
- } catch (u) {
1138
- throw new Error(`OHLCV analysis failed: ${u.message}`);
1481
+ }), h = this.extractContent(y), b = this.parseOHLCVResponse(h);
1482
+ if (b.length !== o)
1483
+ throw new Error(`AI returned ${b.length} OHLCV objects, but expected ${o}.`);
1484
+ return b;
1485
+ } catch (p) {
1486
+ throw new Error(`OHLCV analysis failed: ${p.message}`);
1139
1487
  }
1140
1488
  }
1141
1489
  /**
@@ -1143,7 +1491,7 @@ Please process this data according to the system instructions. Remember to retur
1143
1491
  * @param modelType - New model type
1144
1492
  */
1145
1493
  setModel(e) {
1146
- if (!y.get(e))
1494
+ if (!$.get(e))
1147
1495
  throw new Error(`Unsupported model type: ${e}`);
1148
1496
  this.modelType = e;
1149
1497
  }
@@ -1151,7 +1499,7 @@ Please process this data according to the system instructions. Remember to retur
1151
1499
  * Get current model configuration
1152
1500
  */
1153
1501
  getCurrentModel() {
1154
- const e = y.get(this.modelType);
1502
+ const e = $.get(this.modelType);
1155
1503
  if (!e)
1156
1504
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
1157
1505
  return {
@@ -1161,12 +1509,12 @@ Please process this data according to the system instructions. Remember to retur
1161
1509
  };
1162
1510
  }
1163
1511
  /**
1164
- * Test connection
1512
+ * Test connection with i18n support
1165
1513
  * @returns Connection test result
1166
1514
  */
1167
1515
  async testConnection() {
1168
1516
  try {
1169
- const e = await this.chat('Hello, respond with "OK" if you can hear me.');
1517
+ const e = await this.chat('Hello, respond with "OK" if you can hear me.', "en");
1170
1518
  return {
1171
1519
  success: !0,
1172
1520
  model: this.modelType,
@@ -1180,71 +1528,71 @@ Please process this data according to the system instructions. Remember to retur
1180
1528
  };
1181
1529
  }
1182
1530
  }
1183
- buildOpenAIRequest(e, o, s, a, i, n, r, m, c, p, d) {
1184
- const l = {
1531
+ buildOpenAIRequest(e, t, s, a, r, o, i, d, l, u, m) {
1532
+ const c = {
1185
1533
  model: e,
1186
- messages: o,
1534
+ messages: t,
1187
1535
  temperature: s,
1188
1536
  max_tokens: a,
1189
- stream: i
1537
+ stream: r
1190
1538
  };
1191
- return n !== void 0 && (l.top_p = n), r !== void 0 && (l.frequency_penalty = r), m !== void 0 && (l.presence_penalty = m), c && (l.stop = c), p && (l.tools = p), d && (l.tool_choice = d), l;
1539
+ return o !== void 0 && (c.top_p = o), i !== void 0 && (c.frequency_penalty = i), d !== void 0 && (c.presence_penalty = d), l && (c.stop = l), u && (c.tools = u), m && (c.tool_choice = m), c;
1192
1540
  }
1193
- async makeRequest(e, o, s) {
1194
- const a = new AbortController(), i = setTimeout(() => a.abort(), this.timeout);
1541
+ async makeRequest(e, t, s) {
1542
+ const a = new AbortController(), r = setTimeout(() => a.abort(), this.timeout);
1195
1543
  try {
1196
- const n = await fetch(e, {
1544
+ const o = await fetch(e, {
1197
1545
  method: "POST",
1198
1546
  headers: {
1199
1547
  Authorization: `Bearer ${this.apiKey}`,
1200
1548
  "Content-Type": "application/json; charset=utf-8",
1201
1549
  Accept: "application/json"
1202
1550
  },
1203
- body: JSON.stringify(o),
1551
+ body: JSON.stringify(t),
1204
1552
  signal: a.signal
1205
1553
  });
1206
- if (clearTimeout(i), !n.ok) {
1207
- const r = await n.text();
1208
- throw new Error(`HTTP ${n.status}: ${r}`);
1554
+ if (clearTimeout(r), !o.ok) {
1555
+ const i = await o.text();
1556
+ throw new Error(`HTTP ${o.status}: ${i}`);
1209
1557
  }
1210
- return s ? n.body : await n.json();
1211
- } catch (n) {
1212
- throw clearTimeout(i), n.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : n;
1558
+ return s ? o.body : await o.json();
1559
+ } catch (o) {
1560
+ throw clearTimeout(r), o.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : o;
1213
1561
  }
1214
1562
  }
1215
- async makeStreamRequest(e, o, s) {
1216
- const a = await this.makeRequest(e, o, !0);
1563
+ async makeStreamRequest(e, t, s) {
1564
+ const a = await this.makeRequest(e, t, !0);
1217
1565
  if (!a)
1218
1566
  throw new Error("Failed to get streaming response");
1219
- const i = a.getReader(), n = new TextDecoder("utf-8");
1220
- let r = "";
1567
+ const r = a.getReader(), o = new TextDecoder("utf-8");
1568
+ let i = "";
1221
1569
  try {
1222
1570
  for (; ; ) {
1223
- const { done: m, value: c } = await i.read();
1224
- if (m) {
1571
+ const { done: d, value: l } = await r.read();
1572
+ if (d) {
1225
1573
  s("", !0);
1226
1574
  break;
1227
1575
  }
1228
- r += n.decode(c, { stream: !0 });
1229
- const p = r.split(`
1576
+ i += o.decode(l, { stream: !0 });
1577
+ const u = i.split(`
1230
1578
  `);
1231
- r = p.pop() || "";
1232
- for (const d of p)
1233
- if (d.startsWith("data: ")) {
1234
- const l = d.slice(6);
1235
- if (l === "[DONE]") {
1579
+ i = u.pop() || "";
1580
+ for (const m of u)
1581
+ if (m.startsWith("data: ")) {
1582
+ const c = m.slice(6);
1583
+ if (c === "[DONE]") {
1236
1584
  s("", !0);
1237
1585
  return;
1238
1586
  }
1239
1587
  try {
1240
- const u = JSON.parse(l);
1241
- u.choices?.[0]?.delta?.content && s(u.choices[0].delta.content, !1);
1588
+ const p = JSON.parse(c);
1589
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
1242
1590
  } catch {
1243
1591
  }
1244
1592
  }
1245
1593
  }
1246
1594
  } finally {
1247
- i.releaseLock();
1595
+ r.releaseLock();
1248
1596
  }
1249
1597
  }
1250
1598
  extractContent(e) {
@@ -1260,42 +1608,42 @@ Please process this data according to the system instructions. Remember to retur
1260
1608
  }
1261
1609
  parseOHLCVResponse(e) {
1262
1610
  try {
1263
- const o = JSON.parse(e);
1264
- if (!Array.isArray(o))
1611
+ const t = JSON.parse(e);
1612
+ if (!Array.isArray(t))
1265
1613
  throw new Error("Response is not in array format");
1266
- return o.map((a, i) => {
1614
+ return t.map((a, r) => {
1267
1615
  if (typeof a != "object" || a === null)
1268
- throw new Error(`Element ${i} is not a valid object`);
1269
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
1270
- for (const l of d)
1271
- if (typeof a[l] != "number" || isNaN(a[l]))
1272
- throw new Error(`Element ${i} field ${l} is not a valid number`);
1273
- if (r < m)
1274
- throw new Error(`Element ${i}: high cannot be lower than low`);
1275
- if (c < m || c > r)
1276
- throw new Error(`Element ${i}: close must be between low and high`);
1616
+ throw new Error(`Element ${r} is not a valid object`);
1617
+ const { open: o, high: i, low: d, close: l, volume: u } = a, m = ["open", "high", "low", "close", "volume"];
1618
+ for (const c of m)
1619
+ if (typeof a[c] != "number" || isNaN(a[c]))
1620
+ throw new Error(`Element ${r} field ${c} is not a valid number`);
1621
+ if (i < d)
1622
+ throw new Error(`Element ${r}: high cannot be lower than low`);
1623
+ if (l < d || l > i)
1624
+ throw new Error(`Element ${r}: close must be between low and high`);
1277
1625
  return {
1278
- open: Number(n),
1279
- high: Number(r),
1280
- low: Number(m),
1281
- close: Number(c),
1282
- volume: Number(p)
1626
+ open: Number(o),
1627
+ high: Number(i),
1628
+ low: Number(d),
1629
+ close: Number(l),
1630
+ volume: Number(u)
1283
1631
  };
1284
1632
  });
1285
- } catch (o) {
1633
+ } catch (t) {
1286
1634
  const s = e.match(/\[[\s\S]*\]/);
1287
1635
  if (s)
1288
1636
  return this.parseOHLCVResponse(s[0]);
1289
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
1637
+ throw new Error(`Unable to parse AI returned OHLCV data: ${t}
1290
1638
  Original content: ${e.substring(0, 200)}...`);
1291
1639
  }
1292
1640
  }
1293
1641
  }
1294
- function H(t, e) {
1295
- return new C({ apiKey: t, modelType: e });
1642
+ function M(n, e) {
1643
+ return new H({ apiKey: n, modelType: e });
1296
1644
  }
1297
- var f = /* @__PURE__ */ ((t) => (t.GPT4 = "gpt-4", t.GPT4_0314 = "gpt-4-0314", t.GPT4_0613 = "gpt-4-0613", t.GPT4_32K = "gpt-4-32k", t.GPT4_32K_0314 = "gpt-4-32k-0314", t.GPT4_32K_0613 = "gpt-4-32k-0613", t.GPT4_TURBO = "gpt-4-turbo", t.GPT4_TURBO_PREVIEW = "gpt-4-turbo-preview", t.GPT4_TURBO_2024_04_09 = "gpt-4-turbo-2024-04-09", t.GPT4_OMNI = "gpt-4o", t.GPT4_OMNI_2024_05_13 = "gpt-4o-2024-05-13", t.GPT4_OMNI_MINI = "gpt-4o-mini", t.GPT4_OMNI_MINI_2024_07_18 = "gpt-4o-mini-2024-07-18", t.GPT3_5_TURBO = "gpt-3.5-turbo", t.GPT3_5_TURBO_0125 = "gpt-3.5-turbo-0125", t.GPT3_5_TURBO_1106 = "gpt-3.5-turbo-1106", t.GPT3_5_TURBO_INSTRUCT = "gpt-3.5-turbo-instruct", t.GPT3_5_TURBO_16K = "gpt-3.5-turbo-16k", t.GPT3_5_TURBO_16K_0613 = "gpt-3.5-turbo-16k-0613", t.DAVINCI_002 = "davinci-002", t.BABBAGE_002 = "babbage-002", t.TEXT_DAVINCI_003 = "text-davinci-003", t.TEXT_DAVINCI_002 = "text-davinci-002", t.TEXT_DAVINCI_001 = "text-davinci-001", t.TEXT_CURIE_001 = "text-curie-001", t.TEXT_BABBAGE_001 = "text-babbage-001", t.TEXT_ADA_001 = "text-ada-001", t.TEXT_EMBEDDING_ADA_002 = "text-embedding-ada-002", t.TEXT_EMBEDDING_3_SMALL = "text-embedding-3-small", t.TEXT_EMBEDDING_3_LARGE = "text-embedding-3-large", t.DALL_E_2 = "dall-e-2", t.DALL_E_3 = "dall-e-3", t.WHISPER_1 = "whisper-1", t.TTS_1 = "tts-1", t.TTS_1_HD = "tts-1-hd", t.MODERATION_LATEST = "text-moderation-latest", t.MODERATION_STABLE = "text-moderation-stable", t.GPT3_5_TURBO_FINETUNED = "ft:gpt-3.5-turbo-0125:personal:", t.GPT4_FINETUNED = "ft:gpt-4-0125-preview:personal:", t.GPT4_VISION_PREVIEW = "gpt-4-vision-preview", t))(f || {});
1298
- const h = /* @__PURE__ */ new Map([
1645
+ var T = /* @__PURE__ */ ((n) => (n.GPT4 = "gpt-4", n.GPT4_0314 = "gpt-4-0314", n.GPT4_0613 = "gpt-4-0613", n.GPT4_32K = "gpt-4-32k", n.GPT4_32K_0314 = "gpt-4-32k-0314", n.GPT4_32K_0613 = "gpt-4-32k-0613", n.GPT4_TURBO = "gpt-4-turbo", n.GPT4_TURBO_PREVIEW = "gpt-4-turbo-preview", n.GPT4_TURBO_2024_04_09 = "gpt-4-turbo-2024-04-09", n.GPT4_OMNI = "gpt-4o", n.GPT4_OMNI_2024_05_13 = "gpt-4o-2024-05-13", n.GPT4_OMNI_MINI = "gpt-4o-mini", n.GPT4_OMNI_MINI_2024_07_18 = "gpt-4o-mini-2024-07-18", n.GPT3_5_TURBO = "gpt-3.5-turbo", n.GPT3_5_TURBO_0125 = "gpt-3.5-turbo-0125", n.GPT3_5_TURBO_1106 = "gpt-3.5-turbo-1106", n.GPT3_5_TURBO_INSTRUCT = "gpt-3.5-turbo-instruct", n.GPT3_5_TURBO_16K = "gpt-3.5-turbo-16k", n.GPT3_5_TURBO_16K_0613 = "gpt-3.5-turbo-16k-0613", n.DAVINCI_002 = "davinci-002", n.BABBAGE_002 = "babbage-002", n.TEXT_DAVINCI_003 = "text-davinci-003", n.TEXT_DAVINCI_002 = "text-davinci-002", n.TEXT_DAVINCI_001 = "text-davinci-001", n.TEXT_CURIE_001 = "text-curie-001", n.TEXT_BABBAGE_001 = "text-babbage-001", n.TEXT_ADA_001 = "text-ada-001", n.TEXT_EMBEDDING_ADA_002 = "text-embedding-ada-002", n.TEXT_EMBEDDING_3_SMALL = "text-embedding-3-small", n.TEXT_EMBEDDING_3_LARGE = "text-embedding-3-large", n.DALL_E_2 = "dall-e-2", n.DALL_E_3 = "dall-e-3", n.WHISPER_1 = "whisper-1", n.TTS_1 = "tts-1", n.TTS_1_HD = "tts-1-hd", n.MODERATION_LATEST = "text-moderation-latest", n.MODERATION_STABLE = "text-moderation-stable", n.GPT3_5_TURBO_FINETUNED = "ft:gpt-3.5-turbo-0125:personal:", n.GPT4_FINETUNED = "ft:gpt-4-0125-preview:personal:", n.GPT4_VISION_PREVIEW = "gpt-4-vision-preview", n))(T || {});
1646
+ const x = /* @__PURE__ */ new Map([
1299
1647
  // GPT-4 Series
1300
1648
  [
1301
1649
  "gpt-4",
@@ -1483,52 +1831,52 @@ const h = /* @__PURE__ */ new Map([
1483
1831
  }
1484
1832
  ]
1485
1833
  ]);
1486
- function K(t) {
1487
- return h.get(t);
1834
+ function j(n) {
1835
+ return x.get(n);
1488
1836
  }
1489
- function w() {
1490
- return Array.from(h.values());
1837
+ function L() {
1838
+ return Array.from(x.values());
1491
1839
  }
1492
- function V(t) {
1493
- for (const e of h.values())
1494
- if (e.name === t)
1840
+ function W(n) {
1841
+ for (const e of x.values())
1842
+ if (e.name === n)
1495
1843
  return e;
1496
1844
  }
1497
- function U() {
1498
- return Array.from(h.keys());
1845
+ function G() {
1846
+ return Array.from(x.keys());
1499
1847
  }
1500
- function Q() {
1501
- return w().filter(
1502
- (t) => t.capabilities.includes("chat")
1848
+ function J() {
1849
+ return L().filter(
1850
+ (n) => n.capabilities.includes("chat")
1503
1851
  );
1504
1852
  }
1505
- function j() {
1506
- return w().filter(
1507
- (t) => t.capabilities.includes("text-completion")
1853
+ function X() {
1854
+ return L().filter(
1855
+ (n) => n.capabilities.includes("text-completion")
1508
1856
  );
1509
1857
  }
1510
- function W() {
1511
- return w().filter(
1512
- (t) => t.capabilities.includes("embeddings")
1858
+ function Z() {
1859
+ return L().filter(
1860
+ (n) => n.capabilities.includes("embeddings")
1513
1861
  );
1514
1862
  }
1515
- function F() {
1516
- return w().filter(
1517
- (t) => t.capabilities.includes("vision") || t.capabilities.includes("image-generation")
1863
+ function Y() {
1864
+ return L().filter(
1865
+ (n) => n.capabilities.includes("vision") || n.capabilities.includes("image-generation")
1518
1866
  );
1519
1867
  }
1520
- function G() {
1521
- return w().filter(
1522
- (t) => t.capabilities.includes("audio-processing") || t.capabilities.includes("speech-recognition") || t.capabilities.includes("speech-synthesis")
1868
+ function ee() {
1869
+ return L().filter(
1870
+ (n) => n.capabilities.includes("audio-processing") || n.capabilities.includes("speech-recognition") || n.capabilities.includes("speech-synthesis")
1523
1871
  );
1524
1872
  }
1525
- function X() {
1526
- return w().filter(
1527
- (t) => t.capabilities.includes("multimodal")
1873
+ function te() {
1874
+ return L().filter(
1875
+ (n) => n.capabilities.includes("multimodal")
1528
1876
  );
1529
1877
  }
1530
- function z() {
1531
- const t = [
1878
+ function ne() {
1879
+ const n = [
1532
1880
  "gpt-4o",
1533
1881
  "gpt-4o-mini",
1534
1882
  "gpt-4-turbo",
@@ -1537,67 +1885,67 @@ function z() {
1537
1885
  "dall-e-3"
1538
1886
  /* DALL_E_3 */
1539
1887
  ];
1540
- return w().filter(
1541
- (e) => t.includes(e.name)
1888
+ return L().filter(
1889
+ (e) => n.includes(e.name)
1542
1890
  );
1543
1891
  }
1544
- function M() {
1545
- return w().filter((t) => t.inputCostPer1KTokens && t.inputCostPer1KTokens < 1e-3).sort((t, e) => (t.inputCostPer1KTokens || 0) - (e.inputCostPer1KTokens || 0));
1892
+ function oe() {
1893
+ return L().filter((n) => n.inputCostPer1KTokens && n.inputCostPer1KTokens < 1e-3).sort((n, e) => (n.inputCostPer1KTokens || 0) - (e.inputCostPer1KTokens || 0));
1546
1894
  }
1547
- function J() {
1548
- return w().filter((t) => t.contextLength && t.contextLength >= 128e3).sort((t, e) => (e.contextLength || 0) - (t.contextLength || 0));
1895
+ function ae() {
1896
+ return L().filter((n) => n.contextLength && n.contextLength >= 128e3).sort((n, e) => (e.contextLength || 0) - (n.contextLength || 0));
1549
1897
  }
1550
- function Z(t, e, o = 0) {
1551
- const s = (t.inputCostPer1KTokens || 0) / 1e3 * e, a = (t.outputCostPer1KTokens || 0) / 1e3 * o;
1898
+ function se(n, e, t = 0) {
1899
+ const s = (n.inputCostPer1KTokens || 0) / 1e3 * e, a = (n.outputCostPer1KTokens || 0) / 1e3 * t;
1552
1900
  return {
1553
1901
  inputTokens: e,
1554
- outputTokens: o,
1902
+ outputTokens: t,
1555
1903
  inputCost: s,
1556
1904
  outputCost: a,
1557
1905
  totalCost: s + a
1558
1906
  };
1559
1907
  }
1560
- function Y(t) {
1561
- let e = w();
1562
- switch (t.taskType) {
1908
+ function ie(n) {
1909
+ let e = L();
1910
+ switch (n.taskType) {
1563
1911
  case "chat":
1564
- e = e.filter((o) => o.capabilities.includes("chat"));
1912
+ e = e.filter((t) => t.capabilities.includes("chat"));
1565
1913
  break;
1566
1914
  case "completion":
1567
- e = e.filter((o) => o.capabilities.includes("text-completion"));
1915
+ e = e.filter((t) => t.capabilities.includes("text-completion"));
1568
1916
  break;
1569
1917
  case "embedding":
1570
- e = e.filter((o) => o.capabilities.includes("embeddings"));
1918
+ e = e.filter((t) => t.capabilities.includes("embeddings"));
1571
1919
  break;
1572
1920
  case "image":
1573
1921
  e = e.filter(
1574
- (o) => o.capabilities.includes("image-generation") || o.capabilities.includes("vision")
1922
+ (t) => t.capabilities.includes("image-generation") || t.capabilities.includes("vision")
1575
1923
  );
1576
1924
  break;
1577
1925
  case "audio":
1578
1926
  e = e.filter(
1579
- (o) => o.capabilities.includes("speech-recognition") || o.capabilities.includes("speech-synthesis")
1927
+ (t) => t.capabilities.includes("speech-recognition") || t.capabilities.includes("speech-synthesis")
1580
1928
  );
1581
1929
  break;
1582
1930
  }
1583
- return t.contextLength && (e = e.filter(
1584
- (o) => o.contextLength && o.contextLength >= t.contextLength
1585
- )), t.features && t.features.length > 0 && (e = e.filter(
1586
- (o) => t.features.every(
1587
- (s) => o.supportedFeatures?.includes(s) || o.capabilities.includes(s)
1931
+ return n.contextLength && (e = e.filter(
1932
+ (t) => t.contextLength && t.contextLength >= n.contextLength
1933
+ )), n.features && n.features.length > 0 && (e = e.filter(
1934
+ (t) => n.features.every(
1935
+ (s) => t.supportedFeatures?.includes(s) || t.capabilities.includes(s)
1588
1936
  )
1589
- )), t.budget && e.sort(
1590
- (o, s) => (o.inputCostPer1KTokens || 0) - (s.inputCostPer1KTokens || 0)
1937
+ )), n.budget && e.sort(
1938
+ (t, s) => (t.inputCostPer1KTokens || 0) - (s.inputCostPer1KTokens || 0)
1591
1939
  ), e.slice(0, 5);
1592
1940
  }
1593
- function ee(t) {
1594
- const e = Object.values(f);
1595
- for (const o of e)
1596
- if (o === t)
1597
- return o;
1941
+ function re(n) {
1942
+ const e = Object.values(T);
1943
+ for (const t of e)
1944
+ if (t === n)
1945
+ return t;
1598
1946
  return null;
1599
1947
  }
1600
- class L {
1948
+ class S {
1601
1949
  /**
1602
1950
  * Constructor - Minimal configuration
1603
1951
  * @param config.apiKey - API key (required)
@@ -1607,77 +1955,313 @@ class L {
1607
1955
  * @param config.baseURL - Custom base URL (optional)
1608
1956
  */
1609
1957
  constructor(e) {
1610
- if (this.apiKey = e.apiKey, this.modelType = e.modelType || f.GPT3_5_TURBO, this.timeout = e.timeout || 3e4, this.organization = e.organization, this.baseURL = e.baseURL || "https://api.openai.com/v1", !this.apiKey)
1958
+ if (this.apiKey = e.apiKey, this.modelType = e.modelType || T.GPT3_5_TURBO, this.timeout = e.timeout || 3e4, this.organization = e.organization, this.baseURL = e.baseURL || "https://api.openai.com/v1", !this.apiKey)
1611
1959
  throw new Error("API Key cannot be empty");
1612
- if (!h.get(this.modelType))
1960
+ if (!x.get(this.modelType))
1613
1961
  throw new Error(`Unsupported model type: ${this.modelType}`);
1614
1962
  }
1615
1963
  /**
1616
- * Simplest method: single conversation
1964
+ * Simplest method: single conversation with i18n support
1617
1965
  * @param message - User message
1966
+ * @param i18n - Language restriction for AI response
1618
1967
  * @param options - Chat options
1619
1968
  * @returns AI response
1620
1969
  */
1621
- async chat(e, o) {
1622
- const s = [];
1623
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
1624
- const a = await this.chatCompletion(s, {
1625
- temperature: o?.temperature,
1626
- maxTokens: o?.maxTokens,
1970
+ async chat(e, t, s) {
1971
+ const a = [], r = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
1972
+ if (s?.systemPrompt || r) {
1973
+ const i = [s?.systemPrompt, r].filter(Boolean).join(`
1974
+ `);
1975
+ a.push({ role: "system", content: i });
1976
+ }
1977
+ a.push({ role: "user", content: e });
1978
+ const o = await this.chatCompletion(a, t, {
1979
+ temperature: s?.temperature,
1980
+ maxTokens: s?.maxTokens,
1627
1981
  stream: !1,
1628
- topP: o?.topP,
1629
- frequencyPenalty: o?.frequencyPenalty,
1630
- presencePenalty: o?.presencePenalty,
1631
- stop: o?.stop
1982
+ topP: s?.topP,
1983
+ frequencyPenalty: s?.frequencyPenalty,
1984
+ presencePenalty: s?.presencePenalty,
1985
+ stop: s?.stop
1632
1986
  });
1633
- return this.extractContent(a);
1987
+ return this.extractContent(o);
1634
1988
  }
1635
1989
  /**
1636
- * Multi-turn conversation
1990
+ * Multi-turn conversation with i18n support
1637
1991
  * @param messages - Message history
1992
+ * @param i18n - Language restriction for AI response
1638
1993
  * @param options - Chat options
1639
1994
  * @returns Complete API response
1640
1995
  */
1641
- async chatCompletion(e, o) {
1642
- const s = o?.modelType || this.modelType, a = h.get(s);
1643
- if (!a)
1644
- throw new Error(`Unsupported model type: ${s}`);
1645
- const i = o?.temperature ?? 0.7, n = o?.maxTokens ?? 1e3, r = o?.stream ?? !1, m = a.endpoint, c = this.buildOpenAIRequest(
1646
- a.name,
1996
+ async chatCompletion(e, t, s) {
1997
+ const a = s?.modelType || this.modelType, r = x.get(a);
1998
+ if (!r)
1999
+ throw new Error(`Unsupported model type: ${a}`);
2000
+ const o = s?.temperature ?? 0.7, i = s?.maxTokens ?? 1e3, d = s?.stream ?? !1, l = r.endpoint, u = t === "en" ? "Please respond in English only." : t === "cn" ? "请使用中文回答。" : "";
2001
+ u && (e.some((p) => p.role === "system") ? e = e.map((p) => p.role === "system" ? {
2002
+ ...p,
2003
+ content: `${p.content}
2004
+ ${u}`
2005
+ } : p) : e.unshift({ role: "system", content: u }));
2006
+ const m = this.buildOpenAIRequest(
2007
+ r.name,
1647
2008
  e,
2009
+ o,
1648
2010
  i,
1649
- n,
1650
- r,
1651
- o
2011
+ d,
2012
+ s
1652
2013
  );
1653
2014
  try {
1654
- return await this.makeRequest(m, c, r);
1655
- } catch (p) {
1656
- throw new Error(`OpenAI request failed: ${p.message}`);
2015
+ return await this.makeRequest(l, m, d);
2016
+ } catch (c) {
2017
+ throw new Error(`OpenAI request failed: ${c.message}`);
1657
2018
  }
1658
2019
  }
1659
2020
  /**
1660
- * Streaming conversation
2021
+ * Streaming conversation with i18n support
1661
2022
  * @param messages - Message history
1662
2023
  * @param callback - Streaming callback function
2024
+ * @param i18n - Language restriction for AI response
1663
2025
  * @param options - Chat options
1664
2026
  */
1665
- async chatStream(e, o, s) {
1666
- const a = s?.modelType || this.modelType, i = h.get(a);
1667
- if (!i)
1668
- throw new Error(`Unsupported model type: ${a}`);
1669
- const n = s?.temperature ?? 0.7, r = s?.maxTokens ?? 1e3, m = this.buildOpenAIRequest(
1670
- i.name,
2027
+ async chatStream(e, t, s, a) {
2028
+ const r = a?.modelType || this.modelType, o = x.get(r);
2029
+ if (!o)
2030
+ throw new Error(`Unsupported model type: ${r}`);
2031
+ const i = a?.temperature ?? 0.7, d = a?.maxTokens ?? 1e3, l = s === "en" ? "Please respond in English only." : s === "cn" ? "请使用中文回答。" : "";
2032
+ l && (e.some((c) => c.role === "system") ? e = e.map((c) => c.role === "system" ? {
2033
+ ...c,
2034
+ content: `${c.content}
2035
+ ${l}`
2036
+ } : c) : e.unshift({ role: "system", content: l }));
2037
+ const u = this.buildOpenAIRequest(
2038
+ o.name,
1671
2039
  e,
1672
- n,
1673
- r,
2040
+ i,
2041
+ d,
1674
2042
  !0,
1675
- s
2043
+ a
1676
2044
  );
1677
2045
  try {
1678
- await this.makeStreamRequest(i.endpoint, m, o);
1679
- } catch (c) {
1680
- throw new Error(`Streaming request failed: ${c.message}`);
2046
+ await this.makeStreamRequest(o.endpoint, u, t);
2047
+ } catch (m) {
2048
+ throw new Error(`Streaming request failed: ${m.message}`);
2049
+ }
2050
+ }
2051
+ /**
2052
+ * Analyze OHLCV data and return AI analysis results (text description)
2053
+ * @param ohlcvArray - OHLCV data array
2054
+ * @param i18n - Language restriction for AI response
2055
+ * @param analysisType - Analysis type (optional, default: "comprehensive")
2056
+ * - "trend": Trend analysis
2057
+ * - "volume": Volume analysis
2058
+ * - "technical": Technical analysis
2059
+ * - "comprehensive": Comprehensive analysis
2060
+ * @param message - User's subjective request or specific question (optional)
2061
+ * @param options - Chat options
2062
+ * @returns AI analysis result of OHLCV data (text description)
2063
+ */
2064
+ async analyzeOHLCV(e, t, s, a, r) {
2065
+ const o = s || "comprehensive", i = e.length, l = {
2066
+ trend: {
2067
+ en: "Provide a detailed trend analysis of this OHLCV data, including price direction, support/resistance levels, and trend strength.",
2068
+ cn: "提供详细的OHLCV数据趋势分析,包括价格方向、支撑/阻力位和趋势强度。"
2069
+ },
2070
+ volume: {
2071
+ en: "Analyze the volume patterns in this OHLCV data, including volume trends, unusual volume spikes, and volume-price relationships.",
2072
+ cn: "分析OHLCV数据中的成交量模式,包括成交量趋势、异常成交量波动和量价关系。"
2073
+ },
2074
+ technical: {
2075
+ en: "Perform technical analysis on this OHLCV data, identifying potential technical indicators, patterns, and trading signals.",
2076
+ cn: "对OHLCV数据进行技术分析,识别潜在的技术指标、图表形态和交易信号。"
2077
+ },
2078
+ comprehensive: {
2079
+ en: "Provide a comprehensive analysis of this OHLCV data, covering trends, volume, technical aspects, and potential market implications.",
2080
+ cn: "提供全面的OHLCV数据分析,涵盖趋势、成交量、技术面和潜在市场影响。"
2081
+ }
2082
+ }[o][t], u = t === "en" ? "Please provide your analysis in English." : "请用中文进行分析。";
2083
+ let m = "";
2084
+ if (i > 0) {
2085
+ const h = e[0], f = e[i - 1].close - h.close, w = f / h.close * 100;
2086
+ let C = h.high, v = h.low, P = 0;
2087
+ for (const E of e)
2088
+ E.high > C && (C = E.high), E.low < v && (v = E.low), P += E.volume;
2089
+ const _ = P / i;
2090
+ m = t === "en" ? `This dataset contains ${i} periods of OHLCV data.
2091
+ Price range: ${v.toFixed(2)} - ${C.toFixed(2)}
2092
+ Overall price change: ${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
2093
+ Average volume: ${_.toFixed(0)}` : `该数据集包含 ${i} 个周期的OHLCV数据。
2094
+ 价格范围:${v.toFixed(2)} - ${C.toFixed(2)}
2095
+ 总体价格变化:${f >= 0 ? "+" : ""}${f.toFixed(2)} (${f >= 0 ? "+" : ""}${w.toFixed(2)}%)
2096
+ 平均成交量:${_.toFixed(0)}`;
2097
+ }
2098
+ let c = t === "en" ? `You are a professional financial data analyst. Your task is to analyze OHLCV (Open, High, Low, Close, Volume) data and provide insights.
2099
+ Analysis focus: ${l}
2100
+ ${m ? `Data characteristics:
2101
+ ${m}
2102
+
2103
+ ` : ""}
2104
+ Please provide:
2105
+ 1. Clear and structured analysis
2106
+ 2. Key observations from the data
2107
+ 3. Potential implications or insights
2108
+ 4. Recommendations or considerations (if applicable)
2109
+ Format your response as a well-organized text analysis.` : `您是一位专业的金融数据分析师。您的任务是分析OHLCV(开盘价、最高价、最低价、收盘价、成交量)数据并提供见解。
2110
+ 分析重点:${l}
2111
+ ${m ? `数据特征:
2112
+ ${m}
2113
+
2114
+ ` : ""}
2115
+ 请提供:
2116
+ 1. 清晰且有结构的分析
2117
+ 2. 数据的关键观察结果
2118
+ 3. 潜在的启示或见解
2119
+ 4. 建议或注意事项(如适用)
2120
+ 请以组织良好的文本分析形式回复。`;
2121
+ c += `
2122
+
2123
+ ${u}`;
2124
+ const p = JSON.stringify(e, null, 2);
2125
+ let g = "";
2126
+ a ? g = t === "en" ? `Here is the OHLCV data (${i} periods):
2127
+ ${p}
2128
+ My specific question or request: ${a}
2129
+ Please analyze this data considering my request above.` : `这是OHLCV数据(${i}个周期):
2130
+ ${p}
2131
+ 我的具体问题或需求:${a}
2132
+ 请根据我的上述需求分析这些数据。` : g = t === "en" ? `Here is the OHLCV data (${i} periods):
2133
+ ${p}
2134
+ Please analyze this data as requested.` : `这是OHLCV数据(${i}个周期):
2135
+ ${p}
2136
+ 请按要求分析这些数据。`;
2137
+ const y = [
2138
+ { role: "system", content: c },
2139
+ { role: "user", content: g }
2140
+ ];
2141
+ try {
2142
+ const h = await this.chatCompletion(y, t, {
2143
+ temperature: r?.temperature || 0.5,
2144
+ maxTokens: r?.maxTokens || 1500,
2145
+ stream: !1,
2146
+ modelType: this.modelType,
2147
+ topP: r?.topP,
2148
+ frequencyPenalty: r?.frequencyPenalty,
2149
+ presencePenalty: r?.presencePenalty,
2150
+ stop: r?.stop
2151
+ });
2152
+ return this.extractContent(h);
2153
+ } catch (h) {
2154
+ throw new Error(`OHLCV analysis failed: ${h.message}`);
2155
+ }
2156
+ }
2157
+ /**
2158
+ * Enhanced version: Analyze OHLCV and return structured results (optional)
2159
+ * @param ohlcvArray - OHLCV data array
2160
+ * @param i18n - Language restriction for AI response
2161
+ * @param analysisType - Analysis type
2162
+ * @param message - User's subjective request or specific question
2163
+ * @param structured - Whether to return structured results (default: false)
2164
+ * @param options - Chat options
2165
+ * @returns AI analysis results
2166
+ */
2167
+ async analyzeOHLCVEnhanced(e, t, s, a, r = !1, o) {
2168
+ if (r) {
2169
+ const i = t === "en" ? `You are a professional financial data analyst. Analyze the OHLCV data and provide a structured response with:
2170
+ 1. Summary (brief overview)
2171
+ 2. Details (key observations, 3-5 points)
2172
+ 3. Recommendations (actionable insights, 2-3 points)
2173
+ Format as JSON: {"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}` : `您是一位专业的金融数据分析师。分析OHLCV数据并提供结构化响应:
2174
+ 1. 总结(简要概述)
2175
+ 2. 详情(关键观察结果,3-5点)
2176
+ 3. 建议(可操作的见解,2-3点)
2177
+ 格式化为JSON:{"summary": "...", "details": ["...", "..."], "recommendations": ["...", "..."]}`, d = JSON.stringify(e, null, 2);
2178
+ let l = t === "en" ? `Analyze this OHLCV data (${e.length} periods):
2179
+ ${d}` : `分析此OHLCV数据(${e.length}个周期):
2180
+ ${d}`;
2181
+ a && (l += t === "en" ? `
2182
+
2183
+ Additional request: ${a}` : `
2184
+
2185
+ 附加要求:${a}`);
2186
+ const u = [
2187
+ { role: "system", content: i },
2188
+ { role: "user", content: l }
2189
+ ];
2190
+ try {
2191
+ const m = await this.chatCompletion(u, t, {
2192
+ temperature: o?.temperature || 0.4,
2193
+ maxTokens: o?.maxTokens || 1200,
2194
+ stream: !1,
2195
+ modelType: this.modelType
2196
+ }), c = this.extractContent(m);
2197
+ try {
2198
+ const p = JSON.parse(c);
2199
+ if (p.summary && Array.isArray(p.details) && Array.isArray(p.recommendations))
2200
+ return p;
2201
+ } catch {
2202
+ }
2203
+ return c;
2204
+ } catch (m) {
2205
+ throw new Error(`Structured OHLCV analysis failed: ${m.message}`);
2206
+ }
2207
+ }
2208
+ return this.analyzeOHLCV(e, t, s, a, o);
2209
+ }
2210
+ /**
2211
+ * Specialized method for processing OHLCV arrays (predict future values)
2212
+ * @param ohlcvArray - OHLCV data array
2213
+ * @param instructions - Processing instructions, supports Chinese and English (optional, default: "Based on these OHLCV data, predict the next period")
2214
+ * @param count - Number of OHLCV data items to return (optional, default: 1)
2215
+ * @param options - Chat options
2216
+ * @returns Predicted OHLCV array
2217
+ */
2218
+ async predictingOHLCV(e, t, s, a) {
2219
+ const r = t || "Based on these OHLCV data, predict the next period", o = s || 1;
2220
+ if (!Number.isInteger(o) || o <= 0)
2221
+ throw new Error(`Invalid count parameter: ${o}. Must be a positive integer.`);
2222
+ const i = 50;
2223
+ if (o > i)
2224
+ throw new Error(`Count parameter too large: ${o}. Maximum allowed is ${i}. Please reduce the count or split your request.`);
2225
+ const d = o === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${o} consecutive OHLCV objects for the next ${o} periods.`, l = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
2226
+ Your task: ${r}
2227
+ CRITICAL RULES:
2228
+ 1. ${d}
2229
+ 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
2230
+ 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
2231
+ 4. All numbers must be valid numbers
2232
+ 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
2233
+ 6. Maintain consistency with historical trends and patterns
2234
+ 7. For technical analysis, provide reasonable values based on typical patterns
2235
+ 8. Do not include markdown formatting, only pure JSON
2236
+ ${o === 1 ? `Example of valid response for 1 period:
2237
+ [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${o} periods:
2238
+ [
2239
+ {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
2240
+ {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
2241
+ ${o > 2 ? `,
2242
+ ... ${o - 2} more OHLCV objects following the same pattern` : ""}
2243
+ ]`}`, u = JSON.stringify(e, null, 2), m = `Here is the historical OHLCV data (${e.length} periods):
2244
+ ${u}
2245
+ Please process this data according to the system instructions. Remember to return EXACTLY ${o} OHLCV object(s) in a JSON array with no additional text.`, c = [
2246
+ { role: "system", content: l },
2247
+ { role: "user", content: m }
2248
+ ];
2249
+ try {
2250
+ const p = o * 50 + 100, g = Math.max(a?.maxTokens || 1e3, p), y = await this.chatCompletion(c, "en", {
2251
+ temperature: a?.temperature || 0.3,
2252
+ maxTokens: g,
2253
+ stream: !1,
2254
+ modelType: this.modelType,
2255
+ topP: a?.topP,
2256
+ frequencyPenalty: a?.frequencyPenalty,
2257
+ presencePenalty: a?.presencePenalty,
2258
+ stop: a?.stop
2259
+ }), h = this.extractContent(y), b = this.parseOHLCVResponse(h);
2260
+ if (b.length !== o)
2261
+ throw new Error(`AI returned ${b.length} OHLCV objects, but expected ${o}.`);
2262
+ return b;
2263
+ } catch (p) {
2264
+ throw new Error(`OHLCV analysis failed: ${p.message}`);
1681
2265
  }
1682
2266
  }
1683
2267
  /**
@@ -1686,31 +2270,31 @@ class L {
1686
2270
  * @param options - Image generation options
1687
2271
  * @returns Generated image URLs
1688
2272
  */
1689
- async generateImage(e, o) {
1690
- const s = o?.modelType || f.DALL_E_3;
1691
- if (s !== f.DALL_E_2 && s !== f.DALL_E_3)
2273
+ async generateImage(e, t) {
2274
+ const s = t?.modelType || T.DALL_E_3;
2275
+ if (s !== T.DALL_E_2 && s !== T.DALL_E_3)
1692
2276
  throw new Error("Image generation only supports DALL-E models");
1693
- const a = h.get(s);
2277
+ const a = x.get(s);
1694
2278
  if (!a)
1695
2279
  throw new Error(`Unsupported model type: ${s}`);
1696
- const i = {
2280
+ const r = {
1697
2281
  model: a.name,
1698
2282
  prompt: e,
1699
- n: o?.n || 1,
1700
- size: o?.size || "1024x1024",
1701
- quality: o?.quality || "standard",
1702
- style: o?.style || "vivid",
1703
- response_format: o?.responseFormat || "url"
2283
+ n: t?.n || 1,
2284
+ size: t?.size || "1024x1024",
2285
+ quality: t?.quality || "standard",
2286
+ style: t?.style || "vivid",
2287
+ response_format: t?.responseFormat || "url"
1704
2288
  };
1705
2289
  try {
1706
- const n = await this.makeRequest(a.endpoint, i, !1);
1707
- if (n.data && Array.isArray(n.data))
1708
- return n.data.map(
1709
- (r) => o?.responseFormat === "b64_json" ? r.b64_json : r.url
2290
+ const o = await this.makeRequest(a.endpoint, r, !1);
2291
+ if (o.data && Array.isArray(o.data))
2292
+ return o.data.map(
2293
+ (i) => t?.responseFormat === "b64_json" ? i.b64_json : i.url
1710
2294
  );
1711
2295
  throw new Error("Invalid response format from image generation");
1712
- } catch (n) {
1713
- throw new Error(`Image generation failed: ${n.message}`);
2296
+ } catch (o) {
2297
+ throw new Error(`Image generation failed: ${o.message}`);
1714
2298
  }
1715
2299
  }
1716
2300
  /**
@@ -1719,22 +2303,22 @@ class L {
1719
2303
  * @param options - Embedding options
1720
2304
  * @returns Embedding vectors
1721
2305
  */
1722
- async createEmbeddings(e, o) {
1723
- const s = o?.modelType || f.TEXT_EMBEDDING_ADA_002, a = h.get(s);
2306
+ async createEmbeddings(e, t) {
2307
+ const s = t?.modelType || T.TEXT_EMBEDDING_ADA_002, a = x.get(s);
1724
2308
  if (!a)
1725
2309
  throw new Error(`Unsupported model type: ${s}`);
1726
- const i = {
2310
+ const r = {
1727
2311
  model: a.name,
1728
2312
  input: e
1729
2313
  };
1730
- o?.dimensions && a.name === f.TEXT_EMBEDDING_3_SMALL && (i.dimensions = o.dimensions);
2314
+ t?.dimensions && a.name === T.TEXT_EMBEDDING_3_SMALL && (r.dimensions = t.dimensions);
1731
2315
  try {
1732
- const n = await this.makeRequest(a.endpoint, i, !1);
1733
- if (n.data && Array.isArray(n.data))
1734
- return n.data.map((r) => r.embedding);
2316
+ const o = await this.makeRequest(a.endpoint, r, !1);
2317
+ if (o.data && Array.isArray(o.data))
2318
+ return o.data.map((i) => i.embedding);
1735
2319
  throw new Error("Invalid response format from embeddings");
1736
- } catch (n) {
1737
- throw new Error(`Embedding creation failed: ${n.message}`);
2320
+ } catch (o) {
2321
+ throw new Error(`Embedding creation failed: ${o.message}`);
1738
2322
  }
1739
2323
  }
1740
2324
  /**
@@ -1743,19 +2327,19 @@ class L {
1743
2327
  * @param options - Transcription options
1744
2328
  * @returns Transcribed text
1745
2329
  */
1746
- async transcribeAudio(e, o) {
1747
- const s = o?.modelType || f.WHISPER_1, a = h.get(s);
2330
+ async transcribeAudio(e, t) {
2331
+ const s = t?.modelType || T.WHISPER_1, a = x.get(s);
1748
2332
  if (!a)
1749
2333
  throw new Error(`Unsupported model type: ${s}`);
1750
- const i = new FormData();
2334
+ const r = new FormData();
1751
2335
  if (typeof e == "string")
1752
2336
  throw new Error("File path/Base64 support requires additional implementation");
1753
- i.append("file", e), i.append("model", a.name), o?.language && i.append("language", o.language), o?.prompt && i.append("prompt", o.prompt), o?.responseFormat && i.append("response_format", o.responseFormat), o?.temperature !== void 0 && i.append("temperature", o.temperature.toString());
2337
+ r.append("file", e), r.append("model", a.name), t?.language && r.append("language", t.language), t?.prompt && r.append("prompt", t.prompt), t?.responseFormat && r.append("response_format", t.responseFormat), t?.temperature !== void 0 && r.append("temperature", t.temperature.toString());
1754
2338
  try {
1755
- const n = await this.makeFormDataRequest(a.endpoint, i, !1);
1756
- return n.text || n.transcription || "";
1757
- } catch (n) {
1758
- throw new Error(`Audio transcription failed: ${n.message}`);
2339
+ const o = await this.makeFormDataRequest(a.endpoint, r, !1);
2340
+ return o.text || o.transcription || "";
2341
+ } catch (o) {
2342
+ throw new Error(`Audio transcription failed: ${o.message}`);
1759
2343
  }
1760
2344
  }
1761
2345
  /**
@@ -1764,21 +2348,21 @@ class L {
1764
2348
  * @param options - TTS options
1765
2349
  * @returns Audio data (base64 or blob)
1766
2350
  */
1767
- async textToSpeech(e, o) {
1768
- const s = o?.modelType || f.TTS_1_HD, a = h.get(s);
2351
+ async textToSpeech(e, t) {
2352
+ const s = t?.modelType || T.TTS_1_HD, a = x.get(s);
1769
2353
  if (!a)
1770
2354
  throw new Error(`Unsupported model type: ${s}`);
1771
- const i = {
2355
+ const r = {
1772
2356
  model: a.name,
1773
2357
  input: e,
1774
- voice: o?.voice || "alloy",
1775
- response_format: o?.responseFormat || "mp3",
1776
- speed: o?.speed || 1
2358
+ voice: t?.voice || "alloy",
2359
+ response_format: t?.responseFormat || "mp3",
2360
+ speed: t?.speed || 1
1777
2361
  };
1778
2362
  try {
1779
- return await this.makeRequest(a.endpoint, i, !1, !0);
1780
- } catch (n) {
1781
- throw new Error(`Text-to-speech conversion failed: ${n.message}`);
2363
+ return await this.makeRequest(a.endpoint, r, !1, !0);
2364
+ } catch (o) {
2365
+ throw new Error(`Text-to-speech conversion failed: ${o.message}`);
1782
2366
  }
1783
2367
  }
1784
2368
  /**
@@ -1787,18 +2371,18 @@ class L {
1787
2371
  * @param options - Moderation options
1788
2372
  * @returns Moderation results
1789
2373
  */
1790
- async moderateContent(e, o) {
1791
- const s = o?.modelType || f.MODERATION_LATEST, a = h.get(s);
2374
+ async moderateContent(e, t) {
2375
+ const s = t?.modelType || T.MODERATION_LATEST, a = x.get(s);
1792
2376
  if (!a)
1793
2377
  throw new Error(`Unsupported model type: ${s}`);
1794
- const i = {
2378
+ const r = {
1795
2379
  model: a.name,
1796
2380
  input: e
1797
2381
  };
1798
2382
  try {
1799
- return (await this.makeRequest(a.endpoint, i, !1)).results || [];
1800
- } catch (n) {
1801
- throw new Error(`Content moderation failed: ${n.message}`);
2383
+ return (await this.makeRequest(a.endpoint, r, !1)).results || [];
2384
+ } catch (o) {
2385
+ throw new Error(`Content moderation failed: ${o.message}`);
1802
2386
  }
1803
2387
  }
1804
2388
  /**
@@ -1806,7 +2390,7 @@ class L {
1806
2390
  * @param modelType - New model type
1807
2391
  */
1808
2392
  setModel(e) {
1809
- if (!h.get(e))
2393
+ if (!x.get(e))
1810
2394
  throw new Error(`Unsupported model type: ${e}`);
1811
2395
  this.modelType = e;
1812
2396
  }
@@ -1814,7 +2398,7 @@ class L {
1814
2398
  * Get current model configuration
1815
2399
  */
1816
2400
  getCurrentModel() {
1817
- const e = h.get(this.modelType);
2401
+ const e = x.get(this.modelType);
1818
2402
  if (!e)
1819
2403
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
1820
2404
  return {
@@ -1824,12 +2408,12 @@ class L {
1824
2408
  };
1825
2409
  }
1826
2410
  /**
1827
- * Test connection
2411
+ * Test connection with i18n support
1828
2412
  * @returns Connection test result
1829
2413
  */
1830
2414
  async testConnection() {
1831
2415
  try {
1832
- const e = await this.chat('Hello, respond with "OK" if you can hear me.');
2416
+ const e = await this.chat('Hello, respond with "OK" if you can hear me.', "en");
1833
2417
  return {
1834
2418
  success: !0,
1835
2419
  model: this.modelType,
@@ -1850,115 +2434,115 @@ class L {
1850
2434
  * @param modelType - Model type (optional, uses current if not provided)
1851
2435
  * @returns Cost estimate
1852
2436
  */
1853
- estimateCost(e, o = 0, s) {
1854
- const a = s || this.modelType, i = h.get(a);
1855
- if (!i)
2437
+ estimateCost(e, t = 0, s) {
2438
+ const a = s || this.modelType, r = x.get(a);
2439
+ if (!r)
1856
2440
  throw new Error(`Unsupported model type: ${a}`);
1857
- const n = (i.inputCostPer1KTokens || 0) / 1e3 * e, r = (i.outputCostPer1KTokens || 0) / 1e3 * o;
2441
+ const o = (r.inputCostPer1KTokens || 0) / 1e3 * e, i = (r.outputCostPer1KTokens || 0) / 1e3 * t;
1858
2442
  return {
1859
- inputCost: n,
1860
- outputCost: r,
1861
- totalCost: n + r
2443
+ inputCost: o,
2444
+ outputCost: i,
2445
+ totalCost: o + i
1862
2446
  };
1863
2447
  }
1864
- buildOpenAIRequest(e, o, s, a, i, n) {
1865
- const r = {
2448
+ buildOpenAIRequest(e, t, s, a, r, o) {
2449
+ const i = {
1866
2450
  model: e,
1867
- messages: o,
2451
+ messages: t,
1868
2452
  temperature: s,
1869
2453
  max_tokens: a,
1870
- stream: i
2454
+ stream: r
1871
2455
  };
1872
- return n?.topP !== void 0 && (r.top_p = n.topP), n?.frequencyPenalty !== void 0 && (r.frequency_penalty = n.frequencyPenalty), n?.presencePenalty !== void 0 && (r.presence_penalty = n.presencePenalty), n?.stop !== void 0 && (r.stop = n.stop), r;
2456
+ return o?.topP !== void 0 && (i.top_p = o.topP), o?.frequencyPenalty !== void 0 && (i.frequency_penalty = o.frequencyPenalty), o?.presencePenalty !== void 0 && (i.presence_penalty = o.presencePenalty), o?.stop !== void 0 && (i.stop = o.stop), i;
1873
2457
  }
1874
- async makeRequest(e, o, s, a = !1) {
1875
- const i = new AbortController(), n = setTimeout(() => i.abort(), this.timeout);
2458
+ async makeRequest(e, t, s, a = !1) {
2459
+ const r = new AbortController(), o = setTimeout(() => r.abort(), this.timeout);
1876
2460
  try {
1877
- const r = e.startsWith("http") ? e : `${this.baseURL}${e}`, m = {
2461
+ const i = e.startsWith("http") ? e : `${this.baseURL}${e}`, d = {
1878
2462
  Authorization: `Bearer ${this.apiKey}`,
1879
2463
  "Content-Type": "application/json"
1880
2464
  };
1881
- this.organization && (m["OpenAI-Organization"] = this.organization);
1882
- const c = await fetch(r, {
2465
+ this.organization && (d["OpenAI-Organization"] = this.organization);
2466
+ const l = await fetch(i, {
1883
2467
  method: "POST",
1884
- headers: m,
1885
- body: JSON.stringify(o),
1886
- signal: i.signal
2468
+ headers: d,
2469
+ body: JSON.stringify(t),
2470
+ signal: r.signal
1887
2471
  });
1888
- if (clearTimeout(n), !c.ok) {
1889
- const p = await c.text();
2472
+ if (clearTimeout(o), !l.ok) {
2473
+ const u = await l.text();
1890
2474
  try {
1891
- const d = JSON.parse(p);
1892
- throw new Error(`HTTP ${c.status}: ${d.error?.message || p}`);
2475
+ const m = JSON.parse(u);
2476
+ throw new Error(`HTTP ${l.status}: ${m.error?.message || u}`);
1893
2477
  } catch {
1894
- throw new Error(`HTTP ${c.status}: ${p}`);
2478
+ throw new Error(`HTTP ${l.status}: ${u}`);
1895
2479
  }
1896
2480
  }
1897
- return a ? await c.arrayBuffer() : s ? c.body : await c.json();
1898
- } catch (r) {
1899
- throw clearTimeout(n), r.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : r;
2481
+ return a ? await l.arrayBuffer() : s ? l.body : await l.json();
2482
+ } catch (i) {
2483
+ throw clearTimeout(o), i.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : i;
1900
2484
  }
1901
2485
  }
1902
- async makeFormDataRequest(e, o, s) {
1903
- const a = new AbortController(), i = setTimeout(() => a.abort(), this.timeout);
2486
+ async makeFormDataRequest(e, t, s) {
2487
+ const a = new AbortController(), r = setTimeout(() => a.abort(), this.timeout);
1904
2488
  try {
1905
- const n = e.startsWith("http") ? e : `${this.baseURL}${e}`, r = {
2489
+ const o = e.startsWith("http") ? e : `${this.baseURL}${e}`, i = {
1906
2490
  Authorization: `Bearer ${this.apiKey}`
1907
2491
  };
1908
- this.organization && (r["OpenAI-Organization"] = this.organization);
1909
- const m = await fetch(n, {
2492
+ this.organization && (i["OpenAI-Organization"] = this.organization);
2493
+ const d = await fetch(o, {
1910
2494
  method: "POST",
1911
- headers: r,
1912
- body: o,
2495
+ headers: i,
2496
+ body: t,
1913
2497
  signal: a.signal
1914
2498
  });
1915
- if (clearTimeout(i), !m.ok) {
1916
- const c = await m.text();
2499
+ if (clearTimeout(r), !d.ok) {
2500
+ const l = await d.text();
1917
2501
  try {
1918
- const p = JSON.parse(c);
1919
- throw new Error(`HTTP ${m.status}: ${p.error?.message || c}`);
2502
+ const u = JSON.parse(l);
2503
+ throw new Error(`HTTP ${d.status}: ${u.error?.message || l}`);
1920
2504
  } catch {
1921
- throw new Error(`HTTP ${m.status}: ${c}`);
2505
+ throw new Error(`HTTP ${d.status}: ${l}`);
1922
2506
  }
1923
2507
  }
1924
- return s ? m.body : await m.json();
1925
- } catch (n) {
1926
- throw clearTimeout(i), n.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : n;
2508
+ return s ? d.body : await d.json();
2509
+ } catch (o) {
2510
+ throw clearTimeout(r), o.name === "AbortError" ? new Error(`Request timeout (${this.timeout}ms)`) : o;
1927
2511
  }
1928
2512
  }
1929
- async makeStreamRequest(e, o, s) {
1930
- const a = await this.makeRequest(e, o, !0);
2513
+ async makeStreamRequest(e, t, s) {
2514
+ const a = await this.makeRequest(e, t, !0);
1931
2515
  if (!a)
1932
2516
  throw new Error("Failed to get streaming response");
1933
- const i = a.getReader(), n = new TextDecoder("utf-8");
1934
- let r = "";
2517
+ const r = a.getReader(), o = new TextDecoder("utf-8");
2518
+ let i = "";
1935
2519
  try {
1936
2520
  for (; ; ) {
1937
- const { done: m, value: c } = await i.read();
1938
- if (m) {
2521
+ const { done: d, value: l } = await r.read();
2522
+ if (d) {
1939
2523
  s("", !0);
1940
2524
  break;
1941
2525
  }
1942
- r += n.decode(c, { stream: !0 });
1943
- const p = r.split(`
2526
+ i += o.decode(l, { stream: !0 });
2527
+ const u = i.split(`
1944
2528
  `);
1945
- r = p.pop() || "";
1946
- for (const d of p)
1947
- if (d.startsWith("data: ")) {
1948
- const l = d.slice(6);
1949
- if (l === "[DONE]") {
2529
+ i = u.pop() || "";
2530
+ for (const m of u)
2531
+ if (m.startsWith("data: ")) {
2532
+ const c = m.slice(6);
2533
+ if (c === "[DONE]") {
1950
2534
  s("", !0);
1951
2535
  return;
1952
2536
  }
1953
2537
  try {
1954
- const u = JSON.parse(l);
1955
- u.choices?.[0]?.delta?.content && s(u.choices[0].delta.content, !1);
2538
+ const p = JSON.parse(c);
2539
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
1956
2540
  } catch {
1957
2541
  }
1958
2542
  }
1959
2543
  }
1960
2544
  } finally {
1961
- i.releaseLock();
2545
+ r.releaseLock();
1962
2546
  }
1963
2547
  }
1964
2548
  extractContent(e) {
@@ -1972,140 +2556,83 @@ class L {
1972
2556
  return e.text;
1973
2557
  throw new Error("Unable to parse response content");
1974
2558
  }
1975
- /**
1976
- * Specialized method for processing OHLCV arrays
1977
- * @param ohlcvArray - OHLCV data array
1978
- * @param instructions - Processing instructions (optional, default: "Based on these OHLCV data, predict the next period")
1979
- * @param count - Number of OHLCV data items to return (optional, default: 1)
1980
- * @param options - Chat options
1981
- * @returns Predicted OHLCV array
1982
- */
1983
- async analyzeOHLCV(e, o, s, a) {
1984
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
1985
- if (!Number.isInteger(n) || n <= 0)
1986
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
1987
- const r = 50;
1988
- if (n > r)
1989
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}. Please reduce the count or split your request.`);
1990
- const m = n === 1 ? "Return EXACTLY 1 OHLCV object for the next period." : `Return EXACTLY ${n} consecutive OHLCV objects for the next ${n} periods.`, c = `You are a professional financial data analysis AI. The user will give you an array of OHLCV (Open, High, Low, Close, Volume) data.
1991
- Your task: ${i}
1992
- CRITICAL RULES:
1993
- 1. ${m}
1994
- 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
1995
- 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
1996
- 4. All numbers must be valid numbers
1997
- 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
1998
- 6. Maintain consistency with historical trends and patterns
1999
- 7. For technical analysis, provide reasonable values based on typical patterns
2000
- 8. Do not include markdown formatting, only pure JSON
2001
- ${n === 1 ? `Example of valid response for 1 period:
2002
- [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${n} periods:
2003
- [
2004
- {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
2005
- {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
2006
- ${n > 2 ? `,
2007
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
2008
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
2009
- ${p}
2010
- Please process this data according to the system instructions. Remember to return EXACTLY ${n} OHLCV object(s) in a JSON array with no additional text.`, l = [
2011
- { role: "system", content: c },
2012
- { role: "user", content: d }
2013
- ];
2014
- try {
2015
- const u = n * 50 + 100, x = Math.max(a?.maxTokens || 1e3, u), v = await this.chatCompletion(l, {
2016
- temperature: a?.temperature || 0.3,
2017
- maxTokens: x,
2018
- stream: !1,
2019
- modelType: a?.modelType,
2020
- topP: a?.topP,
2021
- frequencyPenalty: a?.frequencyPenalty,
2022
- presencePenalty: a?.presencePenalty,
2023
- stop: a?.stop
2024
- }), E = this.extractContent(v), g = this.parseOHLCVResponse(E);
2025
- if (g.length !== n)
2026
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
2027
- return g;
2028
- } catch (u) {
2029
- throw new Error(`OHLCV analysis failed: ${u.message}`);
2030
- }
2031
- }
2032
2559
  /**
2033
2560
  * Parse AI returned OHLCV response
2034
2561
  * @private
2035
2562
  */
2036
2563
  parseOHLCVResponse(e) {
2037
2564
  try {
2038
- const o = JSON.parse(e);
2039
- if (!Array.isArray(o))
2565
+ const t = JSON.parse(e);
2566
+ if (!Array.isArray(t))
2040
2567
  throw new Error("Response is not in array format");
2041
- return o.map((a, i) => {
2568
+ return t.map((a, r) => {
2042
2569
  if (typeof a != "object" || a === null)
2043
- throw new Error(`Element ${i} is not a valid object`);
2044
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
2045
- for (const l of d)
2046
- if (typeof a[l] != "number" || isNaN(a[l]))
2047
- throw new Error(`Element ${i} field ${l} is not a valid number`);
2048
- if (r < m)
2049
- throw new Error(`Element ${i}: high cannot be lower than low`);
2050
- if (c < m || c > r)
2051
- throw new Error(`Element ${i}: close must be between low and high`);
2570
+ throw new Error(`Element ${r} is not a valid object`);
2571
+ const { open: o, high: i, low: d, close: l, volume: u } = a, m = ["open", "high", "low", "close", "volume"];
2572
+ for (const c of m)
2573
+ if (typeof a[c] != "number" || isNaN(a[c]))
2574
+ throw new Error(`Element ${r} field ${c} is not a valid number`);
2575
+ if (i < d)
2576
+ throw new Error(`Element ${r}: high cannot be lower than low`);
2577
+ if (l < d || l > i)
2578
+ throw new Error(`Element ${r}: close must be between low and high`);
2052
2579
  return {
2053
- open: Number(n),
2054
- high: Number(r),
2055
- low: Number(m),
2056
- close: Number(c),
2057
- volume: Number(p)
2580
+ open: Number(o),
2581
+ high: Number(i),
2582
+ low: Number(d),
2583
+ close: Number(l),
2584
+ volume: Number(u)
2058
2585
  };
2059
2586
  });
2060
- } catch (o) {
2587
+ } catch (t) {
2061
2588
  const s = e.match(/\[[\s\S]*\]/);
2062
2589
  if (s)
2063
2590
  return this.parseOHLCVResponse(s[0]);
2064
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
2591
+ throw new Error(`Unable to parse AI returned OHLCV data: ${t}
2065
2592
  Original content: ${e.substring(0, 200)}...`);
2066
2593
  }
2067
2594
  }
2068
2595
  }
2069
- function te(t, e) {
2070
- return new L({ apiKey: t, modelType: e });
2596
+ function ce(n, e) {
2597
+ return new S({ apiKey: n, modelType: e });
2071
2598
  }
2072
2599
  export {
2073
- b as ALIYUN_MODELS,
2074
- T as AliYunModelType,
2075
- _ as AliyunAI,
2076
- y as DEEPSEEK_MODELS,
2077
- C as DeepSeekAI,
2078
- k as DeepSeekModelType,
2079
- h as OPENAI_MODELS,
2080
- L as OpenAI,
2081
- f as OpenAIModelType,
2082
- R as createAliyunAI,
2083
- H as createDeepSeekAI,
2084
- te as createOpenAI,
2085
- Z as estimateCost,
2086
- A as getAllDeepSeekModels,
2087
- P as getAllModels,
2088
- w as getAllOpenAIModels,
2089
- G as getAudioModelsOpenAI,
2090
- O as getAvailableAliYunModelTypes,
2091
- B as getAvailableDeepSeekModelTypes,
2092
- U as getAvailableOpenAIModelTypes,
2093
- Q as getChatModels,
2094
- j as getCompletionModels,
2095
- M as getCostEfficientModels,
2096
- S as getDeepSeekModel,
2097
- D as getDeepSeekModelByName,
2098
- W as getEmbeddingModels,
2099
- J as getHighContextModels,
2100
- z as getLatestModels,
2101
- N as getModel,
2102
- q as getModelByName,
2103
- X as getMultimodalModelsOpenAI,
2104
- K as getOpenAIModel,
2105
- V as getOpenAIModelByName,
2106
- F as getVisionModelsOpenAI,
2107
- $ as stringToAliYunModelType,
2108
- I as stringToDeepSeekModelType,
2109
- ee as stringToOpenAIModelType,
2110
- Y as suggestModel
2600
+ k as ALIYUN_MODELS,
2601
+ O as AliYunModelType,
2602
+ q as AliyunAI,
2603
+ $ as DEEPSEEK_MODELS,
2604
+ H as DeepSeekAI,
2605
+ N as DeepSeekModelType,
2606
+ x as OPENAI_MODELS,
2607
+ S as OpenAI,
2608
+ T as OpenAIModelType,
2609
+ B as createAliyunAI,
2610
+ M as createDeepSeekAI,
2611
+ ce as createOpenAI,
2612
+ se as estimateCost,
2613
+ F as getAllDeepSeekModels,
2614
+ R as getAllModels,
2615
+ L as getAllOpenAIModels,
2616
+ ee as getAudioModelsOpenAI,
2617
+ I as getAvailableAliYunModelTypes,
2618
+ Q as getAvailableDeepSeekModelTypes,
2619
+ G as getAvailableOpenAIModelTypes,
2620
+ J as getChatModels,
2621
+ X as getCompletionModels,
2622
+ oe as getCostEfficientModels,
2623
+ K as getDeepSeekModel,
2624
+ U as getDeepSeekModelByName,
2625
+ Z as getEmbeddingModels,
2626
+ ae as getHighContextModels,
2627
+ ne as getLatestModels,
2628
+ V as getModel,
2629
+ A as getModelByName,
2630
+ te as getMultimodalModelsOpenAI,
2631
+ j as getOpenAIModel,
2632
+ W as getOpenAIModelByName,
2633
+ Y as getVisionModelsOpenAI,
2634
+ D as stringToAliYunModelType,
2635
+ z as stringToDeepSeekModelType,
2636
+ re as stringToOpenAIModelType,
2637
+ ie as suggestModel
2111
2638
  };