From 40a72e620bbf78d03beb764c1e75b3fff7dd20ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E6=88=90?= Date: Wed, 25 Feb 2026 12:59:30 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=B0=86=E5=8E=9F=E6=9C=89?= =?UTF-8?q?=E7=9A=84=E2=80=98human=20demo=E2=80=99=E8=AF=97=E6=AD=8C?= =?UTF-8?q?=E5=88=9B=E4=BD=9C=E5=B7=A5=E4=BD=9C=E6=B5=81=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=92=8C=E8=A1=A5=E5=85=85=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 4 +- frontend/package-lock.json | 127 +---------------- yaml_instance/demo_human.yaml | 257 +++++++++++++++++++++++++++------- 3 files changed, 217 insertions(+), 171 deletions(-) diff --git a/.env b/.env index b18fc6bfb..5bbb28ea4 100755 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -BASE_URL= -API_KEY= +BASE_URL=https://yeysai.com/v1 +API_KEY=sk-2n8YTsDFQ9d2PYJTFQ5AC3H2arX5pGXkW6nw6zURliznI0dm SERPER_DEV_API_KEY= JINA_API_KEY= \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a69edb863..07a52cb49 100755 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,10 +16,8 @@ "js-yaml": "^4.1.0", "markdown-it": "^14.1.0", "markdown-it-anchor": "^9.2.0", - "papaparse": "^5.4.1", "vue": "^3.5.22", - "vue-router": "^4.6.0", - "xlsx": "^0.18.5" + "vue-router": "^4.6.0" }, "devDependencies": { "@eslint/js": "^9.39.1", @@ -1108,7 +1106,8 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/markdown-it": { "version": "14.1.2", @@ -1125,7 +1124,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/web-bluetooth": { "version": "0.0.20", @@ -1175,7 +1175,6 @@ "resolved": "https://registry.npmjs.org/@vue-flow/core/-/core-1.48.1.tgz", "integrity": "sha512-3IxaMBLvWRbznZ4CuK0kVhp4Y4lCDQx9nhi48Swp6PwPw29KNhmiKd2kaBogYeWjGLb/tLjlE9V0s3jEmKCYWw==", "license": "MIT", - "peer": true, "dependencies": { "@vueuse/core": "^10.5.0", "d3-drag": "^3.0.0", @@ -1413,7 +1412,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1431,15 +1429,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1514,19 +1503,6 @@ "node": ">=6" } }, - "node_modules/cfb": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", - "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", - "license": "Apache-2.0", - "dependencies": { - "adler-32": "~1.3.0", - "crc-32": "~1.2.0" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1544,15 +1520,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/codepage": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", - "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1580,18 +1547,6 @@ "dev": true, "license": "MIT" }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "license": "Apache-2.0", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -1683,7 +1638,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -1830,7 +1784,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2107,15 +2060,6 @@ "dev": true, "license": "ISC" }, - "node_modules/frac": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", - "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8" - } - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2337,7 +2281,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -2474,12 +2417,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/papaparse": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.3.tgz", - "integrity": "sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==", - "license": "MIT" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2525,7 +2462,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2704,18 +2640,6 @@ "node": ">=0.10.0" } }, - "node_modules/ssf": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", - "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", - "license": "Apache-2.0", - "dependencies": { - "frac": "~1.1.2" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2801,7 +2725,6 @@ "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -2876,7 +2799,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.26", "@vue/compiler-sfc": "3.5.26", @@ -2949,24 +2871,6 @@ "node": ">= 8" } }, - "node_modules/wmf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", - "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/word": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", - "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -2977,27 +2881,6 @@ "node": ">=0.10.0" } }, - "node_modules/xlsx": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", - "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", - "license": "Apache-2.0", - "dependencies": { - "adler-32": "~1.3.0", - "cfb": "~1.2.1", - "codepage": "~1.15.0", - "crc-32": "~1.2.1", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - }, - "bin": { - "xlsx": "bin/xlsx.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", diff --git a/yaml_instance/demo_human.yaml b/yaml_instance/demo_human.yaml index 19a25e489..0c49bbc87 100755 --- a/yaml_instance/demo_human.yaml +++ b/yaml_instance/demo_human.yaml @@ -5,52 +5,215 @@ graph: description: Article generation with human feedback and editorial expansion. is_majority_voting: false start: - - A + - Inspiration Poet Agent + + end: + - User Decider + nodes: - - id: A - type: agent - config: - base_url: ${BASE_URL} - api_key: ${API_KEY} - name: gpt-4o - role: 'You are a writer, skilled at generating a full article based on a word or phrase input by the user. - - The user will input a word or a short sentence, and you need to generate an article of no less than 2000 words based on it, requiring multiple paragraphs. - - ' - thinking: - type: reflection - config: - reflection_prompt: 'Extract the first sentence of each paragraph, do not output any other content. - - ' - params: - temperature: 0.1 - max_tokens: 4000 - - id: B - type: human - config: - description: 'Please provide revision suggestions for the article. - - ' - - id: C - type: agent - config: - base_url: ${BASE_URL} - api_key: ${API_KEY} - name: gpt-4o - role: 'You are an editor, skilled at polishing and expanding articles based on feedback from users and humans. - - The user will input an article and human feedback, and you need to polish the article accordingly. - - ' - params: - temperature: 0.1 - max_tokens: 4000 + - id: Inspiration Poet Agent + type: agent + config: + name: gpt-4o + provider: openai + role: |- + You are the Inspiration Poet, a creative and free-spirited writer specializing in vernacular (everyday language) poetry. Your task is to compose the initial draft of a poem based on the given theme and emotional color. Write in a natural, conversational style, avoiding rigid classical forms. Focus on capturing the essence of the theme and evoking the specified emotion. + + Input: + - theme: The subject or topic of the poem (e.g., "after the rain," "homesickness"). + - emotion: The emotional tone to convey (e.g., "joyful," "melancholic," "peaceful"). + - (Optional, in later iterations) previous_poem: The latest revised version of the poem, if you are reworking based on feedback. + + Output: + Your output must be a plain text poem (without any additional commentary or markup). The poem should be original, coherent, and aligned with the theme and emotion. + + Guidelines: + - Use vivid, concrete imagery and simple language. + - Do not worry about perfect rhyme or meter; focus on flow and emotional resonance. + - If a previous_poem is provided, you may use it as a starting point and creatively revise it, but do not simply copy it—infuse new ideas where appropriate. + - Keep the poem concise (typically 8–20 lines, but adjust as needed). + base_url: ${BASE_URL} + api_key: ${API_KEY} + params: {} + tooling: [] + thinking: null + memories: [] + retry: null + description: Based on the theme and emotional tone, draft the first version of the vernacular poem, with a free and colloquial style. + context_window: 1 + + - id: Rhythm Consultant Agent + type: agent + config: + name: gpt-4o + provider: openai + role: |- + You are the Rhythm Consultant, an expert in the musicality of vernacular speech. Your role is to analyze the given poem and offer constructive feedback on its rhythm, line breaks, and overall flow. You do not require formal rhyme or meter; instead, focus on how the words sound when read aloud and how the pacing supports the emotional tone. + + Input: + - poem_current: The latest version of the poem to be evaluated. + + Output: + Provide your suggestions as a clear, concise text. You may include specific line references and propose alternative phrasings. Do not rewrite the entire poem; only highlight areas for improvement and suggest tweaks. + + Guidelines: + - Read the poem aloud mentally and identify any awkward rhythms, abrupt line breaks, or areas where the flow stumbles. + - Consider whether the poem's pacing matches the intended emotion (e.g., short, quick lines for excitement; longer, flowing lines for tranquility). + - Suggest small adjustments like word substitutions, line breaks, or punctuation changes. + - If the poem already flows well, you may simply state "Rhythm is smooth" and offer no major changes. + - Keep your feedback actionable and supportive. + base_url: ${BASE_URL} + api_key: ${API_KEY} + params: + temperature: 0.1 + max_tokens: 4000 + tooling: [] + thinking: null + memories: [] + retry: null + description: Specialist who evaluates the poem's rhythm, pacing, and natural cadence, providing suggestions for improvement without enforcing strict meter. + context_window: 1 + + - id: Imagery Enhancer Agent + type: agent + config: + name: gpt-4o + provider: openai + role: |- + You are the Imagery Enhancer, a poet with a gift for vivid, evocative language. Your task is to enrich the given poem by suggesting more powerful images, metaphors, and sensory details that amplify the intended emotion. You work closely with the emotional tone to ensure every image resonates. + + Input: + - poem_current: The latest version of the poem. + - emotion: The emotional tone that should permeate the poem. + + Output: + Provide specific suggestions for enhancing imagery. You may propose new lines, alternative word choices, or additional metaphors. Do not rewrite the entire poem; instead, offer targeted recommendations. + + Guidelines: + - Identify places where the imagery could be stronger, more original, or more emotionally charged. + - Suggest concrete sensory details (sight, sound, smell, touch, taste) that align with the emotion. + - If the poem already has strong imagery, you may suggest subtle refinements or simply acknowledge its effectiveness. + - Ensure your suggestions do not clash with the poem's existing rhythm or style; aim for seamless integration. + - Keep feedback focused and constructive. + base_url: ${BASE_URL} + api_key: ${API_KEY} + params: {} + tooling: [] + thinking: null + memories: [] + retry: null + description: Creative editor who strengthens the poem's imagery, metaphor, and sensory details to deepen emotional impact, ensuring alignment with the specified emotion. + context_window: 1 + + - id: Editor-in-Chief Agent + type: agent + config: + name: gpt-4o + provider: openai + role: |- + You are the Editor-in-Chief of the poetry workshop. Your role is to review the current poem, consider the suggestions from the Rhythm Consultant and Imagery Enhancer, and produce a revised version that best captures the theme and emotion. You also evaluate the quality of the revised poem by assigning a satisfaction score (1–10) to determine if further iteration is needed. + + Input: + - poem_current: The latest version of the poem before revision. + - rhyme_suggestions: Feedback from the Rhythm Consultant. + - imagery_suggestions: Feedback from the Imagery Enhancer. + - emotion: The intended emotional tone. + - (Optional) user_feedback: Any additional instructions from the human user (in later stages). + + Output: + You must output two items: + 1. revised_poem: The updated poem after incorporating relevant suggestions. + 2. satisfaction_score: An integer from 1 to 10 indicating how well the poem meets the quality standards (10 = perfect, 1 = needs major work). + + Guidelines for revision: + - Carefully weigh the suggestions: adopt those that improve the poem while maintaining coherence and emotional alignment. + - You may reject suggestions that conflict with the poem's core spirit or your own judgment. + - Ensure the revised poem flows naturally and integrates changes seamlessly. + - Keep the poem's length and style consistent with the original intent. + + Guidelines for scoring: + - Base the score on criteria such as: emotional resonance, imagery strength, rhythmic flow, and overall impact. + - A score of 8 or above indicates the poem is ready for human review; lower scores signal a need for further iteration. + - Be honest and critical—scoring too high may halt iteration prematurely, while too low may waste cycles. + + Output format: + Provide the revised poem as plain text, followed by a line with "Satisfaction Score: X" (where X is the number). + base_url: ${BASE_URL} + api_key: ${API_KEY} + params: {} + tooling: [] + thinking: null + memories: [] + retry: null + description: The final decision-maker who synthesizes feedback from the Rhythm Consultant and Imagery Enhancer, produces a revised poem, and assigns a satisfaction score to guide the iterative process. + context_window: 1 + + - id: User Review + type: human + config: + provider: "human" + description: "A stage where the user reviews the revised poem and provides feedback. The user can either approve the poem or request further modifications, which will be sent back to the Inspiration Poet for another iteration." + context_window: 1 + + - id: Iteration Counter + type: loop_counter + config: + description: "A counter that tracks the number of iterations. It increments each time the Editor-in-Chief produces a revised poem and resets when the user requests modifications." + context_window: 1 + # 可选的计数器参数,如初始值、最大值等,根据实际需要添加 + # initial_value: 0 + # max_iterations: 5 + + - id: Iteration Controller + type: python + config: + description: "A controller that decides whether to continue iterating or to proceed to human review based on the satisfaction score and iteration count. If the score is below a certain threshold and the iteration count is below the maximum, it loops back to the Inspiration Poet; otherwise, it moves to User Review." + context_window: 1 + code: | + # 在此处实现迭代控制逻辑 + # 输入变量:satisfaction_score, iteration_count, max_iterations, threshold + # 输出:next_node (例如 "Inspiration Poet" 或 "User Review") + if satisfaction_score < threshold and iteration_count < max_iterations: + next_node = "Inspiration Poet" + else: + next_node = "User Review" + + - id: User Decider + type: python + config: + description: "After the user reviews the poem, they decide whether to approve it (ending the process) or request further modifications (which resets the iteration counter and sends feedback back to the Inspiration Poet)." + context_window: 1 + code: | + # 在此处实现用户决策逻辑 + # 输入变量:user_decision (例如 "approve" 或 "modify") + # 输出:next_node 和可能的反馈数据 + if user_decision == "approve": + next_node = "END" # 或指定结束节点 + else: + # 重置计数器并传递反馈 + next_node = "Inspiration Poet" + # 可能需要输出 feedback 供后续节点使用 + edges: - - from: A - to: B - - from: B - to: C - - from: A - to: C + - from: Inspiration Poet Agent + to: Rhythm Consultant Agent + - from: Rhythm Consultant Agent + to: Imagery Enhancer Agent + - from: Imagery Enhancer Agent + to: Editor-in-Chief Agent + - from: Editor-in-Chief Agent + to: Iteration Counter + - from: Iteration Counter + to: Iteration Controller + - from: Iteration Controller + to: Inspiration Poet Agent # 继续迭代(满意度低且次数未达上限) + - from: Iteration Controller + to: User Review # 退出迭代(满意度高或已达上限) + - from: User Review + to: User Decider + - from: User Decider + to: Inspiration Poet Agent # 用户要求修改,重新开始循环(同时重置计数器) + - from: User Decider + to: Iteration Counter # 重置循环计数器 + + From cfb642b6f1a2660d8fa0cdd6eddef52df308f2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E6=88=90?= Date: Wed, 25 Feb 2026 20:48:44 +0800 Subject: [PATCH 2/2] fix: remove exposed token, use environment variable --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 5bbb28ea4..b18fc6bfb 100755 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -BASE_URL=https://yeysai.com/v1 -API_KEY=sk-2n8YTsDFQ9d2PYJTFQ5AC3H2arX5pGXkW6nw6zURliznI0dm +BASE_URL= +API_KEY= SERPER_DEV_API_KEY= JINA_API_KEY= \ No newline at end of file