ohlcv-ai 1.0.8 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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 N = /* @__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))(N || {});
2
+ const k = /* @__PURE__ */ new Map([
3
3
  [
4
4
  "qwen-turbo",
5
5
  {
@@ -358,21 +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
- class _ {
375
+ function D(n) {
376
+ const e = Object.values(N);
377
+ for (const t of e)
378
+ if (t === n)
379
+ return t;
380
+ return null;
381
+ }
382
+ class q {
376
383
  /**
377
384
  * Constructor - Minimal configuration
378
385
  * @param config.apiKey - API key (required)
@@ -380,67 +387,326 @@ class _ {
380
387
  * @param config.timeout - Timeout, default 30 seconds
381
388
  */
382
389
  constructor(e) {
383
- 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 || N.QWEN_TURBO, this.timeout = e.timeout || 3e4, !this.apiKey)
384
391
  throw new Error("API Key cannot be empty");
385
- if (!b.get(this.modelType))
392
+ if (!k.get(this.modelType))
386
393
  throw new Error(`Unsupported model type: ${this.modelType}`);
387
394
  }
388
395
  /**
389
- * Simplest method: single conversation
390
- * @param message - User message
391
- * @param options - Chat options
392
- * @returns AI response
393
- */
394
- async chat(e, o) {
395
- const s = [];
396
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
397
- const a = await this.chatCompletion(s, {
398
- temperature: o?.temperature,
399
- maxTokens: o?.maxTokens,
400
- 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: s?.modelType
401
415
  });
402
- return this.extractContent(a);
416
+ return this.extractContent(o);
403
417
  }
404
418
  /**
405
419
  * Multi-turn conversation
406
420
  * @param messages - Message history
421
+ * @param i18n - Language restriction for AI response
407
422
  * @param options - Chat options
408
423
  * @returns Complete API response
409
424
  */
410
- async chatCompletion(e, o) {
411
- const s = o?.modelType || this.modelType, a = b.get(s);
412
- if (!a)
413
- throw new Error(`Unsupported model type: ${s}`);
414
- 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);
415
436
  try {
416
- return await this.makeRequest(m, p, r);
417
- } catch (d) {
418
- 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}`);
419
440
  }
420
441
  }
421
442
  /**
422
443
  * Streaming conversation (only supports OpenAI format)
423
444
  * @param messages - Message history
424
445
  * @param callback - Streaming callback function
446
+ * @param i18n - Language restriction for AI response
425
447
  * @param options - Chat options
426
448
  */
427
- async chatStream(e, o, s) {
428
- const a = s?.modelType || this.modelType, i = b.get(a);
429
- if (!i)
430
- throw new Error(`Unsupported model type: ${a}`);
431
- 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")
432
454
  throw new Error("Streaming conversation only supports OpenAI format models");
433
- const n = s?.temperature ?? 0.7, r = s?.maxTokens ?? 1e3, m = this.buildOpenAIRequest(
434
- 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,
435
463
  e,
436
- n,
437
- r,
464
+ i,
465
+ d,
438
466
  !0
439
467
  );
440
468
  try {
441
- await this.makeStreamRequest(i.endpoint, m, o);
442
- } catch (c) {
443
- 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: r?.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: o?.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: r?.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)}...`);
444
710
  }
445
711
  }
446
712
  /**
@@ -448,7 +714,7 @@ class _ {
448
714
  * @param modelType - New model type
449
715
  */
450
716
  setModel(e) {
451
- if (!b.get(e))
717
+ if (!k.get(e))
452
718
  throw new Error(`Unsupported model type: ${e}`);
453
719
  this.modelType = e;
454
720
  }
@@ -456,7 +722,7 @@ class _ {
456
722
  * Get current model configuration
457
723
  */
458
724
  getCurrentModel() {
459
- const e = b.get(this.modelType);
725
+ const e = k.get(this.modelType);
460
726
  if (!e)
461
727
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
462
728
  return {
@@ -471,7 +737,7 @@ class _ {
471
737
  */
472
738
  async testConnection() {
473
739
  try {
474
- 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");
475
741
  return {
476
742
  success: !0,
477
743
  model: this.modelType,
@@ -485,19 +751,19 @@ class _ {
485
751
  };
486
752
  }
487
753
  }
488
- buildOpenAIRequest(e, o, s, a, i) {
754
+ buildOpenAIRequest(e, t, s, a, r) {
489
755
  return {
490
756
  model: e,
491
- messages: o,
757
+ messages: t,
492
758
  temperature: s,
493
759
  max_tokens: a,
494
- stream: i
760
+ stream: r
495
761
  };
496
762
  }
497
- buildDashScopeRequest(e, o, s, a) {
763
+ buildDashScopeRequest(e, t, s, a) {
498
764
  return {
499
765
  model: e,
500
- input: { messages: o },
766
+ input: { messages: t },
501
767
  parameters: {
502
768
  temperature: s,
503
769
  max_tokens: a,
@@ -505,61 +771,61 @@ class _ {
505
771
  }
506
772
  };
507
773
  }
508
- async makeRequest(e, o, s) {
509
- 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);
510
776
  try {
511
- const n = await fetch(e, {
777
+ const o = await fetch(e, {
512
778
  method: "POST",
513
779
  headers: {
514
780
  Authorization: `Bearer ${this.apiKey}`,
515
781
  "Content-Type": "application/json; charset=utf-8",
516
782
  Accept: "application/json"
517
783
  },
518
- body: JSON.stringify(o),
784
+ body: JSON.stringify(t),
519
785
  signal: a.signal
520
786
  });
521
- if (clearTimeout(i), !n.ok) {
522
- const r = await n.text();
523
- 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}`);
524
790
  }
525
- return s ? n.body : await n.json();
526
- } catch (n) {
527
- 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;
528
794
  }
529
795
  }
530
- async makeStreamRequest(e, o, s) {
531
- const a = await this.makeRequest(e, o, !0);
796
+ async makeStreamRequest(e, t, s) {
797
+ const a = await this.makeRequest(e, t, !0);
532
798
  if (!a)
533
799
  throw new Error("Failed to get streaming response");
534
- const i = a.getReader(), n = new TextDecoder("utf-8");
535
- let r = "";
800
+ const r = a.getReader(), o = new TextDecoder("utf-8");
801
+ let i = "";
536
802
  try {
537
803
  for (; ; ) {
538
- const { done: m, value: c } = await i.read();
539
- if (m) {
804
+ const { done: d, value: l } = await r.read();
805
+ if (d) {
540
806
  s("", !0);
541
807
  break;
542
808
  }
543
- r += n.decode(c, { stream: !0 });
544
- const p = r.split(`
809
+ i += o.decode(l, { stream: !0 });
810
+ const u = i.split(`
545
811
  `);
546
- r = p.pop() || "";
547
- for (const d of p)
548
- if (d.startsWith("data: ")) {
549
- const l = d.slice(6);
550
- 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]") {
551
817
  s("", !0);
552
818
  return;
553
819
  }
554
820
  try {
555
- const h = JSON.parse(l);
556
- h.choices?.[0]?.delta?.content && s(h.choices[0].delta.content, !1);
821
+ const p = JSON.parse(c);
822
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
557
823
  } catch {
558
824
  }
559
825
  }
560
826
  }
561
827
  } finally {
562
- i.releaseLock();
828
+ r.releaseLock();
563
829
  }
564
830
  }
565
831
  extractContent(e) {
@@ -571,101 +837,12 @@ class _ {
571
837
  return e.output.text;
572
838
  throw new Error("Unable to parse response content");
573
839
  }
574
- /**
575
- * Specialized method for processing OHLCV arrays
576
- * @param ohlcvArray - OHLCV data array
577
- * @param instructions - Processing instructions, supports Chinese and English (optional, default: "Based on these OHLCV data, predict the next period")
578
- * @param count - Number of OHLCV data items to return (optional, default: 1)
579
- * @param options - Chat options
580
- * @returns Predicted OHLCV array
581
- */
582
- async predictingOHLCV(e, o, s, a) {
583
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
584
- if (!Number.isInteger(n) || n <= 0)
585
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
586
- const r = 50;
587
- if (n > r)
588
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}. Please reduce the count or split your request.`);
589
- 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.
590
- Your task: ${i}
591
- CRITICAL RULES:
592
- 1. ${m}
593
- 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
594
- 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
595
- 4. All numbers must be valid numbers
596
- 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
597
- 6. Maintain consistency with historical trends and patterns
598
- 7. For technical analysis, provide reasonable values based on typical patterns
599
- 8. Do not include markdown formatting, only pure JSON
600
- ${n === 1 ? `Example of valid response for 1 period:
601
- [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${n} periods:
602
- [
603
- {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
604
- {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
605
- ${n > 2 ? `,
606
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
607
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
608
- ${p}
609
- 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 = [
610
- { role: "system", content: c },
611
- { role: "user", content: d }
612
- ];
613
- try {
614
- const h = n * 50 + 100, x = Math.max(a?.maxTokens || 1e3, h), k = await this.chatCompletion(l, {
615
- temperature: a?.temperature || 0.3,
616
- maxTokens: x,
617
- stream: !1,
618
- modelType: a?.modelType
619
- }), E = this.extractContent(k), g = this.parseOHLCVResponse(E);
620
- if (g.length !== n)
621
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
622
- return g;
623
- } catch (h) {
624
- throw new Error(`OHLCV analysis failed: ${h.message}`);
625
- }
626
- }
627
- /**
628
- * Parse AI returned OHLCV response
629
- * @private
630
- */
631
- parseOHLCVResponse(e) {
632
- try {
633
- const o = JSON.parse(e);
634
- if (!Array.isArray(o))
635
- throw new Error("Response is not in array format");
636
- return o.map((a, i) => {
637
- if (typeof a != "object" || a === null)
638
- throw new Error(`Element ${i} is not a valid object`);
639
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
640
- for (const l of d)
641
- if (typeof a[l] != "number" || isNaN(a[l]))
642
- throw new Error(`Element ${i} field ${l} is not a valid number`);
643
- if (r < m)
644
- throw new Error(`Element ${i}: high cannot be lower than low`);
645
- if (c < m || c > r)
646
- throw new Error(`Element ${i}: close must be between low and high`);
647
- return {
648
- open: Number(n),
649
- high: Number(r),
650
- low: Number(m),
651
- close: Number(c),
652
- volume: Number(p)
653
- };
654
- });
655
- } catch (o) {
656
- const s = e.match(/\[[\s\S]*\]/);
657
- if (s)
658
- return this.parseOHLCVResponse(s[0]);
659
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
660
- Original content: ${e.substring(0, 200)}...`);
661
- }
662
- }
663
840
  }
664
- function $(t, e) {
665
- return new _({ apiKey: t, modelType: e });
841
+ function B(n, e) {
842
+ return new q({ apiKey: n, modelType: e });
666
843
  }
667
- var v = /* @__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))(v || {});
668
- const y = /* @__PURE__ */ new Map([
844
+ var O = /* @__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))(O || {});
845
+ const $ = /* @__PURE__ */ new Map([
669
846
  // Chat models
670
847
  [
671
848
  "deepseek-chat",
@@ -958,21 +1135,28 @@ const y = /* @__PURE__ */ new Map([
958
1135
  }
959
1136
  ]
960
1137
  ]);
961
- function R(t) {
962
- return y.get(t);
1138
+ function K(n) {
1139
+ return $.get(n);
963
1140
  }
964
- function S() {
965
- return Array.from(y.values());
1141
+ function F() {
1142
+ return Array.from($.values());
966
1143
  }
967
- function A(t) {
968
- for (const e of y.values())
969
- if (e.name === t)
1144
+ function U(n) {
1145
+ for (const e of $.values())
1146
+ if (e.name === n)
970
1147
  return e;
971
1148
  }
972
- function D() {
973
- return Array.from(y.keys());
1149
+ function Q() {
1150
+ return Array.from($.keys());
1151
+ }
1152
+ function z(n) {
1153
+ const e = Object.values(O);
1154
+ for (const t of e)
1155
+ if (t === n)
1156
+ return t;
1157
+ return null;
974
1158
  }
975
- class C {
1159
+ class H {
976
1160
  /**
977
1161
  * Constructor - Minimal configuration
978
1162
  * @param config.apiKey - API key (required)
@@ -981,92 +1165,270 @@ class C {
981
1165
  * @param config.baseURL - Base URL for API, default official endpoint
982
1166
  */
983
1167
  constructor(e) {
984
- if (this.apiKey = e.apiKey, this.modelType = e.modelType || v.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 || O.DEEPSEEK_CHAT, this.timeout = e.timeout || 3e4, this.baseURL = e.baseURL || "https://api.deepseek.com", !this.apiKey)
985
1169
  throw new Error("API Key cannot be empty");
986
- if (!y.get(this.modelType))
1170
+ if (!$.get(this.modelType))
987
1171
  throw new Error(`Unsupported model type: ${this.modelType}`);
988
1172
  }
989
1173
  /**
990
- * Simplest method: single conversation
1174
+ * Simplest method: single conversation with i18n support
991
1175
  * @param message - User message
1176
+ * @param i18n - Language restriction for AI response
992
1177
  * @param options - Chat options
993
1178
  * @returns AI response
994
1179
  */
995
- async chat(e, o) {
996
- const s = [];
997
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
998
- const a = await this.chatCompletion(s, {
999
- temperature: o?.temperature,
1000
- 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,
1001
1191
  stream: !1,
1002
- modelType: o?.modelType,
1003
- topP: o?.topP,
1004
- frequencyPenalty: o?.frequencyPenalty,
1005
- presencePenalty: o?.presencePenalty,
1006
- stop: o?.stop,
1007
- tools: o?.tools,
1008
- toolChoice: o?.toolChoice
1192
+ modelType: s?.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
1009
1199
  });
1010
- return this.extractContent(a);
1200
+ return this.extractContent(o);
1011
1201
  }
1012
1202
  /**
1013
- * Multi-turn conversation
1203
+ * Multi-turn conversation with i18n support
1014
1204
  * @param messages - Message history
1205
+ * @param i18n - Language restriction for AI response
1015
1206
  * @param options - Chat options
1016
1207
  * @returns Complete API response
1017
1208
  */
1018
- async chatCompletion(e, o) {
1019
- const s = o?.modelType || this.modelType, a = y.get(s);
1020
- if (!a)
1021
- throw new Error(`Unsupported model type: ${s}`);
1022
- 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, h = o?.toolChoice, x = a.endpoint, k = this.buildOpenAIRequest(
1023
- 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,
1024
1221
  e,
1222
+ o,
1025
1223
  i,
1026
- n,
1027
- r,
1224
+ d,
1225
+ l,
1226
+ u,
1028
1227
  m,
1029
1228
  c,
1030
1229
  p,
1031
- d,
1032
- l,
1033
- h
1230
+ g
1034
1231
  );
1035
1232
  try {
1036
- return await this.makeRequest(x, k, r);
1037
- } catch (E) {
1038
- 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}`);
1039
1236
  }
1040
1237
  }
1041
1238
  /**
1042
- * Streaming conversation
1239
+ * Streaming conversation with i18n support
1043
1240
  * @param messages - Message history
1044
1241
  * @param callback - Streaming callback function
1242
+ * @param i18n - Language restriction for AI response
1045
1243
  * @param options - Chat options
1046
1244
  */
1047
- async chatStream(e, o, s) {
1048
- const a = s?.modelType || this.modelType, i = y.get(a);
1049
- if (!i)
1050
- throw new Error(`Unsupported model type: ${a}`);
1051
- 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(
1052
- 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,
1053
1257
  e,
1054
- n,
1055
- r,
1258
+ i,
1259
+ d,
1056
1260
  !0,
1261
+ l,
1262
+ u,
1057
1263
  m,
1058
- c,
1059
- p,
1060
- s?.stop,
1061
- s?.tools,
1062
- s?.toolChoice
1264
+ a?.stop,
1265
+ a?.tools,
1266
+ a?.toolChoice
1063
1267
  );
1064
1268
  try {
1065
- await this.makeStreamRequest(i.endpoint, d, o);
1066
- } catch (l) {
1067
- 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}`);
1272
+ }
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: r?.modelType || O.DEEPSEEK_FINANCE,
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}`);
1068
1377
  }
1069
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: o?.modelType || O.DEEPSEEK_FINANCE
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
+ }
1070
1432
  /**
1071
1433
  * Specialized method for processing OHLCV arrays
1072
1434
  * @param ohlcvArray - OHLCV data array
@@ -1075,17 +1437,17 @@ class C {
1075
1437
  * @param options - Chat options
1076
1438
  * @returns Predicted OHLCV array
1077
1439
  */
1078
- async predictingOHLCV(e, o, s, a) {
1079
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
1080
- if (!Number.isInteger(n) || n <= 0)
1081
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
1082
- const r = 50;
1083
- if (n > r)
1084
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}.`);
1085
- 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.
1086
- 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}
1087
1449
  CRITICAL RULES:
1088
- 1. ${m}
1450
+ 1. ${d}
1089
1451
  2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
1090
1452
  3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
1091
1453
  4. All numbers must be valid numbers
@@ -1094,34 +1456,34 @@ CRITICAL RULES:
1094
1456
  7. For technical analysis, provide reasonable values based on typical patterns
1095
1457
  8. Do not include markdown formatting, only pure JSON
1096
1458
 
1097
- ${n === 1 ? `Example of valid response for 1 period:
1098
- [{"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:
1099
1461
  [
1100
1462
  {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
1101
1463
  {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
1102
- ${n > 2 ? `,
1103
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
1104
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
1105
- ${p}
1106
- 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 = [
1107
- { role: "system", content: c },
1108
- { 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 }
1109
1471
  ];
1110
1472
  try {
1111
- const h = n * 50 + 100, x = Math.max(a?.maxTokens || 2e3, h), k = await this.chatCompletion(l, {
1473
+ const p = o * 50 + 100, g = Math.max(a?.maxTokens || 2e3, p), y = await this.chatCompletion(c, "en", {
1112
1474
  temperature: a?.temperature || 0.3,
1113
- maxTokens: x,
1475
+ maxTokens: g,
1114
1476
  stream: !1,
1115
- modelType: a?.modelType || v.DEEPSEEK_FINANCE,
1477
+ modelType: a?.modelType || O.DEEPSEEK_FINANCE,
1116
1478
  topP: a?.topP,
1117
1479
  frequencyPenalty: a?.frequencyPenalty,
1118
1480
  presencePenalty: a?.presencePenalty
1119
- }), E = this.extractContent(k), g = this.parseOHLCVResponse(E);
1120
- if (g.length !== n)
1121
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
1122
- return g;
1123
- } catch (h) {
1124
- throw new Error(`OHLCV analysis failed: ${h.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}`);
1125
1487
  }
1126
1488
  }
1127
1489
  /**
@@ -1129,7 +1491,7 @@ Please process this data according to the system instructions. Remember to retur
1129
1491
  * @param modelType - New model type
1130
1492
  */
1131
1493
  setModel(e) {
1132
- if (!y.get(e))
1494
+ if (!$.get(e))
1133
1495
  throw new Error(`Unsupported model type: ${e}`);
1134
1496
  this.modelType = e;
1135
1497
  }
@@ -1137,7 +1499,7 @@ Please process this data according to the system instructions. Remember to retur
1137
1499
  * Get current model configuration
1138
1500
  */
1139
1501
  getCurrentModel() {
1140
- const e = y.get(this.modelType);
1502
+ const e = $.get(this.modelType);
1141
1503
  if (!e)
1142
1504
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
1143
1505
  return {
@@ -1147,12 +1509,12 @@ Please process this data according to the system instructions. Remember to retur
1147
1509
  };
1148
1510
  }
1149
1511
  /**
1150
- * Test connection
1512
+ * Test connection with i18n support
1151
1513
  * @returns Connection test result
1152
1514
  */
1153
1515
  async testConnection() {
1154
1516
  try {
1155
- 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");
1156
1518
  return {
1157
1519
  success: !0,
1158
1520
  model: this.modelType,
@@ -1166,71 +1528,71 @@ Please process this data according to the system instructions. Remember to retur
1166
1528
  };
1167
1529
  }
1168
1530
  }
1169
- buildOpenAIRequest(e, o, s, a, i, n, r, m, c, p, d) {
1170
- const l = {
1531
+ buildOpenAIRequest(e, t, s, a, r, o, i, d, l, u, m) {
1532
+ const c = {
1171
1533
  model: e,
1172
- messages: o,
1534
+ messages: t,
1173
1535
  temperature: s,
1174
1536
  max_tokens: a,
1175
- stream: i
1537
+ stream: r
1176
1538
  };
1177
- 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;
1178
1540
  }
1179
- async makeRequest(e, o, s) {
1180
- 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);
1181
1543
  try {
1182
- const n = await fetch(e, {
1544
+ const o = await fetch(e, {
1183
1545
  method: "POST",
1184
1546
  headers: {
1185
1547
  Authorization: `Bearer ${this.apiKey}`,
1186
1548
  "Content-Type": "application/json; charset=utf-8",
1187
1549
  Accept: "application/json"
1188
1550
  },
1189
- body: JSON.stringify(o),
1551
+ body: JSON.stringify(t),
1190
1552
  signal: a.signal
1191
1553
  });
1192
- if (clearTimeout(i), !n.ok) {
1193
- const r = await n.text();
1194
- 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}`);
1195
1557
  }
1196
- return s ? n.body : await n.json();
1197
- } catch (n) {
1198
- 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;
1199
1561
  }
1200
1562
  }
1201
- async makeStreamRequest(e, o, s) {
1202
- const a = await this.makeRequest(e, o, !0);
1563
+ async makeStreamRequest(e, t, s) {
1564
+ const a = await this.makeRequest(e, t, !0);
1203
1565
  if (!a)
1204
1566
  throw new Error("Failed to get streaming response");
1205
- const i = a.getReader(), n = new TextDecoder("utf-8");
1206
- let r = "";
1567
+ const r = a.getReader(), o = new TextDecoder("utf-8");
1568
+ let i = "";
1207
1569
  try {
1208
1570
  for (; ; ) {
1209
- const { done: m, value: c } = await i.read();
1210
- if (m) {
1571
+ const { done: d, value: l } = await r.read();
1572
+ if (d) {
1211
1573
  s("", !0);
1212
1574
  break;
1213
1575
  }
1214
- r += n.decode(c, { stream: !0 });
1215
- const p = r.split(`
1576
+ i += o.decode(l, { stream: !0 });
1577
+ const u = i.split(`
1216
1578
  `);
1217
- r = p.pop() || "";
1218
- for (const d of p)
1219
- if (d.startsWith("data: ")) {
1220
- const l = d.slice(6);
1221
- 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]") {
1222
1584
  s("", !0);
1223
1585
  return;
1224
1586
  }
1225
1587
  try {
1226
- const h = JSON.parse(l);
1227
- h.choices?.[0]?.delta?.content && s(h.choices[0].delta.content, !1);
1588
+ const p = JSON.parse(c);
1589
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
1228
1590
  } catch {
1229
1591
  }
1230
1592
  }
1231
1593
  }
1232
1594
  } finally {
1233
- i.releaseLock();
1595
+ r.releaseLock();
1234
1596
  }
1235
1597
  }
1236
1598
  extractContent(e) {
@@ -1246,42 +1608,42 @@ Please process this data according to the system instructions. Remember to retur
1246
1608
  }
1247
1609
  parseOHLCVResponse(e) {
1248
1610
  try {
1249
- const o = JSON.parse(e);
1250
- if (!Array.isArray(o))
1611
+ const t = JSON.parse(e);
1612
+ if (!Array.isArray(t))
1251
1613
  throw new Error("Response is not in array format");
1252
- return o.map((a, i) => {
1614
+ return t.map((a, r) => {
1253
1615
  if (typeof a != "object" || a === null)
1254
- throw new Error(`Element ${i} is not a valid object`);
1255
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
1256
- for (const l of d)
1257
- if (typeof a[l] != "number" || isNaN(a[l]))
1258
- throw new Error(`Element ${i} field ${l} is not a valid number`);
1259
- if (r < m)
1260
- throw new Error(`Element ${i}: high cannot be lower than low`);
1261
- if (c < m || c > r)
1262
- 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`);
1263
1625
  return {
1264
- open: Number(n),
1265
- high: Number(r),
1266
- low: Number(m),
1267
- close: Number(c),
1268
- volume: Number(p)
1626
+ open: Number(o),
1627
+ high: Number(i),
1628
+ low: Number(d),
1629
+ close: Number(l),
1630
+ volume: Number(u)
1269
1631
  };
1270
1632
  });
1271
- } catch (o) {
1633
+ } catch (t) {
1272
1634
  const s = e.match(/\[[\s\S]*\]/);
1273
1635
  if (s)
1274
1636
  return this.parseOHLCVResponse(s[0]);
1275
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
1637
+ throw new Error(`Unable to parse AI returned OHLCV data: ${t}
1276
1638
  Original content: ${e.substring(0, 200)}...`);
1277
1639
  }
1278
1640
  }
1279
1641
  }
1280
- function B(t, e) {
1281
- return new C({ apiKey: t, modelType: e });
1642
+ function M(n, e) {
1643
+ return new H({ apiKey: n, modelType: e });
1282
1644
  }
1283
- 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 || {});
1284
- const u = /* @__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([
1285
1647
  // GPT-4 Series
1286
1648
  [
1287
1649
  "gpt-4",
@@ -1469,52 +1831,52 @@ const u = /* @__PURE__ */ new Map([
1469
1831
  }
1470
1832
  ]
1471
1833
  ]);
1472
- function I(t) {
1473
- return u.get(t);
1834
+ function j(n) {
1835
+ return x.get(n);
1474
1836
  }
1475
- function w() {
1476
- return Array.from(u.values());
1837
+ function L() {
1838
+ return Array.from(x.values());
1477
1839
  }
1478
- function H(t) {
1479
- for (const e of u.values())
1480
- if (e.name === t)
1840
+ function W(n) {
1841
+ for (const e of x.values())
1842
+ if (e.name === n)
1481
1843
  return e;
1482
1844
  }
1483
- function K() {
1484
- return Array.from(u.keys());
1845
+ function G() {
1846
+ return Array.from(x.keys());
1485
1847
  }
1486
- function V() {
1487
- return w().filter(
1488
- (t) => t.capabilities.includes("chat")
1848
+ function J() {
1849
+ return L().filter(
1850
+ (n) => n.capabilities.includes("chat")
1489
1851
  );
1490
1852
  }
1491
- function U() {
1492
- return w().filter(
1493
- (t) => t.capabilities.includes("text-completion")
1853
+ function X() {
1854
+ return L().filter(
1855
+ (n) => n.capabilities.includes("text-completion")
1494
1856
  );
1495
1857
  }
1496
- function Q() {
1497
- return w().filter(
1498
- (t) => t.capabilities.includes("embeddings")
1858
+ function Z() {
1859
+ return L().filter(
1860
+ (n) => n.capabilities.includes("embeddings")
1499
1861
  );
1500
1862
  }
1501
- function W() {
1502
- return w().filter(
1503
- (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")
1504
1866
  );
1505
1867
  }
1506
- function j() {
1507
- return w().filter(
1508
- (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")
1509
1871
  );
1510
1872
  }
1511
- function F() {
1512
- return w().filter(
1513
- (t) => t.capabilities.includes("multimodal")
1873
+ function te() {
1874
+ return L().filter(
1875
+ (n) => n.capabilities.includes("multimodal")
1514
1876
  );
1515
1877
  }
1516
- function G() {
1517
- const t = [
1878
+ function ne() {
1879
+ const n = [
1518
1880
  "gpt-4o",
1519
1881
  "gpt-4o-mini",
1520
1882
  "gpt-4-turbo",
@@ -1523,60 +1885,67 @@ function G() {
1523
1885
  "dall-e-3"
1524
1886
  /* DALL_E_3 */
1525
1887
  ];
1526
- return w().filter(
1527
- (e) => t.includes(e.name)
1888
+ return L().filter(
1889
+ (e) => n.includes(e.name)
1528
1890
  );
1529
1891
  }
1530
- function X() {
1531
- 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));
1532
1894
  }
1533
- function z() {
1534
- 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));
1535
1897
  }
1536
- function J(t, e, o = 0) {
1537
- 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;
1538
1900
  return {
1539
1901
  inputTokens: e,
1540
- outputTokens: o,
1902
+ outputTokens: t,
1541
1903
  inputCost: s,
1542
1904
  outputCost: a,
1543
1905
  totalCost: s + a
1544
1906
  };
1545
1907
  }
1546
- function M(t) {
1547
- let e = w();
1548
- switch (t.taskType) {
1908
+ function ie(n) {
1909
+ let e = L();
1910
+ switch (n.taskType) {
1549
1911
  case "chat":
1550
- e = e.filter((o) => o.capabilities.includes("chat"));
1912
+ e = e.filter((t) => t.capabilities.includes("chat"));
1551
1913
  break;
1552
1914
  case "completion":
1553
- e = e.filter((o) => o.capabilities.includes("text-completion"));
1915
+ e = e.filter((t) => t.capabilities.includes("text-completion"));
1554
1916
  break;
1555
1917
  case "embedding":
1556
- e = e.filter((o) => o.capabilities.includes("embeddings"));
1918
+ e = e.filter((t) => t.capabilities.includes("embeddings"));
1557
1919
  break;
1558
1920
  case "image":
1559
1921
  e = e.filter(
1560
- (o) => o.capabilities.includes("image-generation") || o.capabilities.includes("vision")
1922
+ (t) => t.capabilities.includes("image-generation") || t.capabilities.includes("vision")
1561
1923
  );
1562
1924
  break;
1563
1925
  case "audio":
1564
1926
  e = e.filter(
1565
- (o) => o.capabilities.includes("speech-recognition") || o.capabilities.includes("speech-synthesis")
1927
+ (t) => t.capabilities.includes("speech-recognition") || t.capabilities.includes("speech-synthesis")
1566
1928
  );
1567
1929
  break;
1568
1930
  }
1569
- return t.contextLength && (e = e.filter(
1570
- (o) => o.contextLength && o.contextLength >= t.contextLength
1571
- )), t.features && t.features.length > 0 && (e = e.filter(
1572
- (o) => t.features.every(
1573
- (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)
1574
1936
  )
1575
- )), t.budget && e.sort(
1576
- (o, s) => (o.inputCostPer1KTokens || 0) - (s.inputCostPer1KTokens || 0)
1937
+ )), n.budget && e.sort(
1938
+ (t, s) => (t.inputCostPer1KTokens || 0) - (s.inputCostPer1KTokens || 0)
1577
1939
  ), e.slice(0, 5);
1578
1940
  }
1579
- class L {
1941
+ function re(n) {
1942
+ const e = Object.values(T);
1943
+ for (const t of e)
1944
+ if (t === n)
1945
+ return t;
1946
+ return null;
1947
+ }
1948
+ class S {
1580
1949
  /**
1581
1950
  * Constructor - Minimal configuration
1582
1951
  * @param config.apiKey - API key (required)
@@ -1586,77 +1955,313 @@ class L {
1586
1955
  * @param config.baseURL - Custom base URL (optional)
1587
1956
  */
1588
1957
  constructor(e) {
1589
- 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)
1590
1959
  throw new Error("API Key cannot be empty");
1591
- if (!u.get(this.modelType))
1960
+ if (!x.get(this.modelType))
1592
1961
  throw new Error(`Unsupported model type: ${this.modelType}`);
1593
1962
  }
1594
1963
  /**
1595
- * Simplest method: single conversation
1964
+ * Simplest method: single conversation with i18n support
1596
1965
  * @param message - User message
1966
+ * @param i18n - Language restriction for AI response
1597
1967
  * @param options - Chat options
1598
1968
  * @returns AI response
1599
1969
  */
1600
- async chat(e, o) {
1601
- const s = [];
1602
- o?.systemPrompt && s.push({ role: "system", content: o.systemPrompt }), s.push({ role: "user", content: e });
1603
- const a = await this.chatCompletion(s, {
1604
- temperature: o?.temperature,
1605
- 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,
1606
1981
  stream: !1,
1607
- topP: o?.topP,
1608
- frequencyPenalty: o?.frequencyPenalty,
1609
- presencePenalty: o?.presencePenalty,
1610
- stop: o?.stop
1982
+ topP: s?.topP,
1983
+ frequencyPenalty: s?.frequencyPenalty,
1984
+ presencePenalty: s?.presencePenalty,
1985
+ stop: s?.stop
1611
1986
  });
1612
- return this.extractContent(a);
1987
+ return this.extractContent(o);
1613
1988
  }
1614
1989
  /**
1615
- * Multi-turn conversation
1990
+ * Multi-turn conversation with i18n support
1616
1991
  * @param messages - Message history
1992
+ * @param i18n - Language restriction for AI response
1617
1993
  * @param options - Chat options
1618
1994
  * @returns Complete API response
1619
1995
  */
1620
- async chatCompletion(e, o) {
1621
- const s = o?.modelType || this.modelType, a = u.get(s);
1622
- if (!a)
1623
- throw new Error(`Unsupported model type: ${s}`);
1624
- const i = o?.temperature ?? 0.7, n = o?.maxTokens ?? 1e3, r = o?.stream ?? !1, m = a.endpoint, c = this.buildOpenAIRequest(
1625
- 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,
1626
2008
  e,
2009
+ o,
1627
2010
  i,
1628
- n,
1629
- r,
1630
- o
2011
+ d,
2012
+ s
1631
2013
  );
1632
2014
  try {
1633
- return await this.makeRequest(m, c, r);
1634
- } catch (p) {
1635
- 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}`);
1636
2018
  }
1637
2019
  }
1638
2020
  /**
1639
- * Streaming conversation
2021
+ * Streaming conversation with i18n support
1640
2022
  * @param messages - Message history
1641
2023
  * @param callback - Streaming callback function
2024
+ * @param i18n - Language restriction for AI response
1642
2025
  * @param options - Chat options
1643
2026
  */
1644
- async chatStream(e, o, s) {
1645
- const a = s?.modelType || this.modelType, i = u.get(a);
1646
- if (!i)
1647
- throw new Error(`Unsupported model type: ${a}`);
1648
- const n = s?.temperature ?? 0.7, r = s?.maxTokens ?? 1e3, m = this.buildOpenAIRequest(
1649
- 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,
1650
2039
  e,
1651
- n,
1652
- r,
2040
+ i,
2041
+ d,
1653
2042
  !0,
1654
- s
2043
+ a
1655
2044
  );
1656
2045
  try {
1657
- await this.makeStreamRequest(i.endpoint, m, o);
1658
- } catch (c) {
1659
- 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: r?.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: o?.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: a?.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}`);
1660
2265
  }
1661
2266
  }
1662
2267
  /**
@@ -1665,31 +2270,31 @@ class L {
1665
2270
  * @param options - Image generation options
1666
2271
  * @returns Generated image URLs
1667
2272
  */
1668
- async generateImage(e, o) {
1669
- const s = o?.modelType || f.DALL_E_3;
1670
- 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)
1671
2276
  throw new Error("Image generation only supports DALL-E models");
1672
- const a = u.get(s);
2277
+ const a = x.get(s);
1673
2278
  if (!a)
1674
2279
  throw new Error(`Unsupported model type: ${s}`);
1675
- const i = {
2280
+ const r = {
1676
2281
  model: a.name,
1677
2282
  prompt: e,
1678
- n: o?.n || 1,
1679
- size: o?.size || "1024x1024",
1680
- quality: o?.quality || "standard",
1681
- style: o?.style || "vivid",
1682
- 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"
1683
2288
  };
1684
2289
  try {
1685
- const n = await this.makeRequest(a.endpoint, i, !1);
1686
- if (n.data && Array.isArray(n.data))
1687
- return n.data.map(
1688
- (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
1689
2294
  );
1690
2295
  throw new Error("Invalid response format from image generation");
1691
- } catch (n) {
1692
- throw new Error(`Image generation failed: ${n.message}`);
2296
+ } catch (o) {
2297
+ throw new Error(`Image generation failed: ${o.message}`);
1693
2298
  }
1694
2299
  }
1695
2300
  /**
@@ -1698,22 +2303,22 @@ class L {
1698
2303
  * @param options - Embedding options
1699
2304
  * @returns Embedding vectors
1700
2305
  */
1701
- async createEmbeddings(e, o) {
1702
- const s = o?.modelType || f.TEXT_EMBEDDING_ADA_002, a = u.get(s);
2306
+ async createEmbeddings(e, t) {
2307
+ const s = t?.modelType || T.TEXT_EMBEDDING_ADA_002, a = x.get(s);
1703
2308
  if (!a)
1704
2309
  throw new Error(`Unsupported model type: ${s}`);
1705
- const i = {
2310
+ const r = {
1706
2311
  model: a.name,
1707
2312
  input: e
1708
2313
  };
1709
- 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);
1710
2315
  try {
1711
- const n = await this.makeRequest(a.endpoint, i, !1);
1712
- if (n.data && Array.isArray(n.data))
1713
- 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);
1714
2319
  throw new Error("Invalid response format from embeddings");
1715
- } catch (n) {
1716
- throw new Error(`Embedding creation failed: ${n.message}`);
2320
+ } catch (o) {
2321
+ throw new Error(`Embedding creation failed: ${o.message}`);
1717
2322
  }
1718
2323
  }
1719
2324
  /**
@@ -1722,19 +2327,19 @@ class L {
1722
2327
  * @param options - Transcription options
1723
2328
  * @returns Transcribed text
1724
2329
  */
1725
- async transcribeAudio(e, o) {
1726
- const s = o?.modelType || f.WHISPER_1, a = u.get(s);
2330
+ async transcribeAudio(e, t) {
2331
+ const s = t?.modelType || T.WHISPER_1, a = x.get(s);
1727
2332
  if (!a)
1728
2333
  throw new Error(`Unsupported model type: ${s}`);
1729
- const i = new FormData();
2334
+ const r = new FormData();
1730
2335
  if (typeof e == "string")
1731
2336
  throw new Error("File path/Base64 support requires additional implementation");
1732
- 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());
1733
2338
  try {
1734
- const n = await this.makeFormDataRequest(a.endpoint, i, !1);
1735
- return n.text || n.transcription || "";
1736
- } catch (n) {
1737
- 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}`);
1738
2343
  }
1739
2344
  }
1740
2345
  /**
@@ -1743,21 +2348,21 @@ class L {
1743
2348
  * @param options - TTS options
1744
2349
  * @returns Audio data (base64 or blob)
1745
2350
  */
1746
- async textToSpeech(e, o) {
1747
- const s = o?.modelType || f.TTS_1_HD, a = u.get(s);
2351
+ async textToSpeech(e, t) {
2352
+ const s = t?.modelType || T.TTS_1_HD, a = x.get(s);
1748
2353
  if (!a)
1749
2354
  throw new Error(`Unsupported model type: ${s}`);
1750
- const i = {
2355
+ const r = {
1751
2356
  model: a.name,
1752
2357
  input: e,
1753
- voice: o?.voice || "alloy",
1754
- response_format: o?.responseFormat || "mp3",
1755
- speed: o?.speed || 1
2358
+ voice: t?.voice || "alloy",
2359
+ response_format: t?.responseFormat || "mp3",
2360
+ speed: t?.speed || 1
1756
2361
  };
1757
2362
  try {
1758
- return await this.makeRequest(a.endpoint, i, !1, !0);
1759
- } catch (n) {
1760
- 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}`);
1761
2366
  }
1762
2367
  }
1763
2368
  /**
@@ -1766,18 +2371,18 @@ class L {
1766
2371
  * @param options - Moderation options
1767
2372
  * @returns Moderation results
1768
2373
  */
1769
- async moderateContent(e, o) {
1770
- const s = o?.modelType || f.MODERATION_LATEST, a = u.get(s);
2374
+ async moderateContent(e, t) {
2375
+ const s = t?.modelType || T.MODERATION_LATEST, a = x.get(s);
1771
2376
  if (!a)
1772
2377
  throw new Error(`Unsupported model type: ${s}`);
1773
- const i = {
2378
+ const r = {
1774
2379
  model: a.name,
1775
2380
  input: e
1776
2381
  };
1777
2382
  try {
1778
- return (await this.makeRequest(a.endpoint, i, !1)).results || [];
1779
- } catch (n) {
1780
- 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}`);
1781
2386
  }
1782
2387
  }
1783
2388
  /**
@@ -1785,7 +2390,7 @@ class L {
1785
2390
  * @param modelType - New model type
1786
2391
  */
1787
2392
  setModel(e) {
1788
- if (!u.get(e))
2393
+ if (!x.get(e))
1789
2394
  throw new Error(`Unsupported model type: ${e}`);
1790
2395
  this.modelType = e;
1791
2396
  }
@@ -1793,7 +2398,7 @@ class L {
1793
2398
  * Get current model configuration
1794
2399
  */
1795
2400
  getCurrentModel() {
1796
- const e = u.get(this.modelType);
2401
+ const e = x.get(this.modelType);
1797
2402
  if (!e)
1798
2403
  throw new Error(`Model configuration does not exist: ${this.modelType}`);
1799
2404
  return {
@@ -1803,12 +2408,12 @@ class L {
1803
2408
  };
1804
2409
  }
1805
2410
  /**
1806
- * Test connection
2411
+ * Test connection with i18n support
1807
2412
  * @returns Connection test result
1808
2413
  */
1809
2414
  async testConnection() {
1810
2415
  try {
1811
- 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");
1812
2417
  return {
1813
2418
  success: !0,
1814
2419
  model: this.modelType,
@@ -1829,115 +2434,115 @@ class L {
1829
2434
  * @param modelType - Model type (optional, uses current if not provided)
1830
2435
  * @returns Cost estimate
1831
2436
  */
1832
- estimateCost(e, o = 0, s) {
1833
- const a = s || this.modelType, i = u.get(a);
1834
- if (!i)
2437
+ estimateCost(e, t = 0, s) {
2438
+ const a = s || this.modelType, r = x.get(a);
2439
+ if (!r)
1835
2440
  throw new Error(`Unsupported model type: ${a}`);
1836
- 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;
1837
2442
  return {
1838
- inputCost: n,
1839
- outputCost: r,
1840
- totalCost: n + r
2443
+ inputCost: o,
2444
+ outputCost: i,
2445
+ totalCost: o + i
1841
2446
  };
1842
2447
  }
1843
- buildOpenAIRequest(e, o, s, a, i, n) {
1844
- const r = {
2448
+ buildOpenAIRequest(e, t, s, a, r, o) {
2449
+ const i = {
1845
2450
  model: e,
1846
- messages: o,
2451
+ messages: t,
1847
2452
  temperature: s,
1848
2453
  max_tokens: a,
1849
- stream: i
2454
+ stream: r
1850
2455
  };
1851
- 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;
1852
2457
  }
1853
- async makeRequest(e, o, s, a = !1) {
1854
- 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);
1855
2460
  try {
1856
- const r = e.startsWith("http") ? e : `${this.baseURL}${e}`, m = {
2461
+ const i = e.startsWith("http") ? e : `${this.baseURL}${e}`, d = {
1857
2462
  Authorization: `Bearer ${this.apiKey}`,
1858
2463
  "Content-Type": "application/json"
1859
2464
  };
1860
- this.organization && (m["OpenAI-Organization"] = this.organization);
1861
- const c = await fetch(r, {
2465
+ this.organization && (d["OpenAI-Organization"] = this.organization);
2466
+ const l = await fetch(i, {
1862
2467
  method: "POST",
1863
- headers: m,
1864
- body: JSON.stringify(o),
1865
- signal: i.signal
2468
+ headers: d,
2469
+ body: JSON.stringify(t),
2470
+ signal: r.signal
1866
2471
  });
1867
- if (clearTimeout(n), !c.ok) {
1868
- const p = await c.text();
2472
+ if (clearTimeout(o), !l.ok) {
2473
+ const u = await l.text();
1869
2474
  try {
1870
- const d = JSON.parse(p);
1871
- 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}`);
1872
2477
  } catch {
1873
- throw new Error(`HTTP ${c.status}: ${p}`);
2478
+ throw new Error(`HTTP ${l.status}: ${u}`);
1874
2479
  }
1875
2480
  }
1876
- return a ? await c.arrayBuffer() : s ? c.body : await c.json();
1877
- } catch (r) {
1878
- 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;
1879
2484
  }
1880
2485
  }
1881
- async makeFormDataRequest(e, o, s) {
1882
- 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);
1883
2488
  try {
1884
- const n = e.startsWith("http") ? e : `${this.baseURL}${e}`, r = {
2489
+ const o = e.startsWith("http") ? e : `${this.baseURL}${e}`, i = {
1885
2490
  Authorization: `Bearer ${this.apiKey}`
1886
2491
  };
1887
- this.organization && (r["OpenAI-Organization"] = this.organization);
1888
- const m = await fetch(n, {
2492
+ this.organization && (i["OpenAI-Organization"] = this.organization);
2493
+ const d = await fetch(o, {
1889
2494
  method: "POST",
1890
- headers: r,
1891
- body: o,
2495
+ headers: i,
2496
+ body: t,
1892
2497
  signal: a.signal
1893
2498
  });
1894
- if (clearTimeout(i), !m.ok) {
1895
- const c = await m.text();
2499
+ if (clearTimeout(r), !d.ok) {
2500
+ const l = await d.text();
1896
2501
  try {
1897
- const p = JSON.parse(c);
1898
- 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}`);
1899
2504
  } catch {
1900
- throw new Error(`HTTP ${m.status}: ${c}`);
2505
+ throw new Error(`HTTP ${d.status}: ${l}`);
1901
2506
  }
1902
2507
  }
1903
- return s ? m.body : await m.json();
1904
- } catch (n) {
1905
- 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;
1906
2511
  }
1907
2512
  }
1908
- async makeStreamRequest(e, o, s) {
1909
- const a = await this.makeRequest(e, o, !0);
2513
+ async makeStreamRequest(e, t, s) {
2514
+ const a = await this.makeRequest(e, t, !0);
1910
2515
  if (!a)
1911
2516
  throw new Error("Failed to get streaming response");
1912
- const i = a.getReader(), n = new TextDecoder("utf-8");
1913
- let r = "";
2517
+ const r = a.getReader(), o = new TextDecoder("utf-8");
2518
+ let i = "";
1914
2519
  try {
1915
2520
  for (; ; ) {
1916
- const { done: m, value: c } = await i.read();
1917
- if (m) {
2521
+ const { done: d, value: l } = await r.read();
2522
+ if (d) {
1918
2523
  s("", !0);
1919
2524
  break;
1920
2525
  }
1921
- r += n.decode(c, { stream: !0 });
1922
- const p = r.split(`
2526
+ i += o.decode(l, { stream: !0 });
2527
+ const u = i.split(`
1923
2528
  `);
1924
- r = p.pop() || "";
1925
- for (const d of p)
1926
- if (d.startsWith("data: ")) {
1927
- const l = d.slice(6);
1928
- 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]") {
1929
2534
  s("", !0);
1930
2535
  return;
1931
2536
  }
1932
2537
  try {
1933
- const h = JSON.parse(l);
1934
- h.choices?.[0]?.delta?.content && s(h.choices[0].delta.content, !1);
2538
+ const p = JSON.parse(c);
2539
+ p.choices?.[0]?.delta?.content && s(p.choices[0].delta.content, !1);
1935
2540
  } catch {
1936
2541
  }
1937
2542
  }
1938
2543
  }
1939
2544
  } finally {
1940
- i.releaseLock();
2545
+ r.releaseLock();
1941
2546
  }
1942
2547
  }
1943
2548
  extractContent(e) {
@@ -1951,137 +2556,83 @@ class L {
1951
2556
  return e.text;
1952
2557
  throw new Error("Unable to parse response content");
1953
2558
  }
1954
- /**
1955
- * Specialized method for processing OHLCV arrays
1956
- * @param ohlcvArray - OHLCV data array
1957
- * @param instructions - Processing instructions (optional, default: "Based on these OHLCV data, predict the next period")
1958
- * @param count - Number of OHLCV data items to return (optional, default: 1)
1959
- * @param options - Chat options
1960
- * @returns Predicted OHLCV array
1961
- */
1962
- async analyzeOHLCV(e, o, s, a) {
1963
- const i = o || "Based on these OHLCV data, predict the next period", n = s || 1;
1964
- if (!Number.isInteger(n) || n <= 0)
1965
- throw new Error(`Invalid count parameter: ${n}. Must be a positive integer.`);
1966
- const r = 50;
1967
- if (n > r)
1968
- throw new Error(`Count parameter too large: ${n}. Maximum allowed is ${r}. Please reduce the count or split your request.`);
1969
- 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.
1970
- Your task: ${i}
1971
- CRITICAL RULES:
1972
- 1. ${m}
1973
- 2. Return ONLY a JSON array of OHLCV objects, NO explanations, comments, or other text
1974
- 3. The OHLCV array format must match: [{open, high, low, close, volume}, ...]
1975
- 4. All numbers must be valid numbers
1976
- 5. Ensure technical rationality (high >= low, high >= close >= low, volume >= 0)
1977
- 6. Maintain consistency with historical trends and patterns
1978
- 7. For technical analysis, provide reasonable values based on typical patterns
1979
- 8. Do not include markdown formatting, only pure JSON
1980
- ${n === 1 ? `Example of valid response for 1 period:
1981
- [{"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000}]` : `Example of valid response for ${n} periods:
1982
- [
1983
- {"open": 115.5, "high": 118.0, "low": 114.0, "close": 117.0, "volume": 1350000},
1984
- {"open": 117.5, "high": 120.0, "low": 116.0, "close": 119.0, "volume": 1400000}
1985
- ${n > 2 ? `,
1986
- ... ${n - 2} more OHLCV objects following the same pattern` : ""}
1987
- ]`}`, p = JSON.stringify(e, null, 2), d = `Here is the historical OHLCV data (${e.length} periods):
1988
- ${p}
1989
- 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 = [
1990
- { role: "system", content: c },
1991
- { role: "user", content: d }
1992
- ];
1993
- try {
1994
- const h = n * 50 + 100, x = Math.max(a?.maxTokens || 1e3, h), k = await this.chatCompletion(l, {
1995
- temperature: a?.temperature || 0.3,
1996
- maxTokens: x,
1997
- stream: !1,
1998
- modelType: a?.modelType,
1999
- topP: a?.topP,
2000
- frequencyPenalty: a?.frequencyPenalty,
2001
- presencePenalty: a?.presencePenalty,
2002
- stop: a?.stop
2003
- }), E = this.extractContent(k), g = this.parseOHLCVResponse(E);
2004
- if (g.length !== n)
2005
- throw new Error(`AI returned ${g.length} OHLCV objects, but expected ${n}.`);
2006
- return g;
2007
- } catch (h) {
2008
- throw new Error(`OHLCV analysis failed: ${h.message}`);
2009
- }
2010
- }
2011
2559
  /**
2012
2560
  * Parse AI returned OHLCV response
2013
2561
  * @private
2014
2562
  */
2015
2563
  parseOHLCVResponse(e) {
2016
2564
  try {
2017
- const o = JSON.parse(e);
2018
- if (!Array.isArray(o))
2565
+ const t = JSON.parse(e);
2566
+ if (!Array.isArray(t))
2019
2567
  throw new Error("Response is not in array format");
2020
- return o.map((a, i) => {
2568
+ return t.map((a, r) => {
2021
2569
  if (typeof a != "object" || a === null)
2022
- throw new Error(`Element ${i} is not a valid object`);
2023
- const { open: n, high: r, low: m, close: c, volume: p } = a, d = ["open", "high", "low", "close", "volume"];
2024
- for (const l of d)
2025
- if (typeof a[l] != "number" || isNaN(a[l]))
2026
- throw new Error(`Element ${i} field ${l} is not a valid number`);
2027
- if (r < m)
2028
- throw new Error(`Element ${i}: high cannot be lower than low`);
2029
- if (c < m || c > r)
2030
- 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`);
2031
2579
  return {
2032
- open: Number(n),
2033
- high: Number(r),
2034
- low: Number(m),
2035
- close: Number(c),
2036
- volume: Number(p)
2580
+ open: Number(o),
2581
+ high: Number(i),
2582
+ low: Number(d),
2583
+ close: Number(l),
2584
+ volume: Number(u)
2037
2585
  };
2038
2586
  });
2039
- } catch (o) {
2587
+ } catch (t) {
2040
2588
  const s = e.match(/\[[\s\S]*\]/);
2041
2589
  if (s)
2042
2590
  return this.parseOHLCVResponse(s[0]);
2043
- throw new Error(`Unable to parse AI returned OHLCV data: ${o}
2591
+ throw new Error(`Unable to parse AI returned OHLCV data: ${t}
2044
2592
  Original content: ${e.substring(0, 200)}...`);
2045
2593
  }
2046
2594
  }
2047
2595
  }
2048
- function Z(t, e) {
2049
- return new L({ apiKey: t, modelType: e });
2596
+ function ce(n, e) {
2597
+ return new S({ apiKey: n, modelType: e });
2050
2598
  }
2051
2599
  export {
2052
- b as ALIYUN_MODELS,
2053
- T as AliYunModelType,
2054
- _ as AliyunAI,
2055
- y as DEEPSEEK_MODELS,
2056
- C as DeepSeekAI,
2057
- v as DeepSeekModelType,
2058
- u as OPENAI_MODELS,
2059
- L as OpenAI,
2060
- f as OpenAIModelType,
2061
- $ as createAliyunAI,
2062
- B as createDeepSeekAI,
2063
- Z as createOpenAI,
2064
- J as estimateCost,
2065
- S as getAllDeepSeekModels,
2066
- P as getAllModels,
2067
- w as getAllOpenAIModels,
2068
- j as getAudioModelsOpenAI,
2069
- O as getAvailableAliYunModelTypes,
2070
- D as getAvailableDeepSeekModelTypes,
2071
- K as getAvailableOpenAIModelTypes,
2072
- V as getChatModels,
2073
- U as getCompletionModels,
2074
- X as getCostEfficientModels,
2075
- R as getDeepSeekModel,
2076
- A as getDeepSeekModelByName,
2077
- Q as getEmbeddingModels,
2078
- z as getHighContextModels,
2079
- G as getLatestModels,
2080
- N as getModel,
2081
- q as getModelByName,
2082
- F as getMultimodalModelsOpenAI,
2083
- I as getOpenAIModel,
2084
- H as getOpenAIModelByName,
2085
- W as getVisionModelsOpenAI,
2086
- M as suggestModel
2600
+ k as ALIYUN_MODELS,
2601
+ N as AliYunModelType,
2602
+ q as AliyunAI,
2603
+ $ as DEEPSEEK_MODELS,
2604
+ H as DeepSeekAI,
2605
+ O 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
2087
2638
  };