選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

test_llm.py 11KB

Introduce Plugins (#13836) Signed-off-by: yihong0618 <zouzou0208@gmail.com> Signed-off-by: -LAN- <laipz8200@outlook.com> Signed-off-by: xhe <xw897002528@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: takatost <takatost@gmail.com> Co-authored-by: kurokobo <kuro664@gmail.com> Co-authored-by: Novice Lee <novicelee@NoviPro.local> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: AkaraChen <akarachen@outlook.com> Co-authored-by: Yi <yxiaoisme@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: Hiroshi Fujita <fujita-h@users.noreply.github.com> Co-authored-by: AkaraChen <85140972+AkaraChen@users.noreply.github.com> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Novice <857526207@qq.com> Co-authored-by: Hiroki Nagai <82458324+nagaihiroki-git@users.noreply.github.com> Co-authored-by: Gen Sato <52241300+halogen22@users.noreply.github.com> Co-authored-by: eux <euxuuu@gmail.com> Co-authored-by: huangzhuo1949 <167434202+huangzhuo1949@users.noreply.github.com> Co-authored-by: huangzhuo <huangzhuo1@xiaomi.com> Co-authored-by: lotsik <lotsik@mail.ru> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: nite-knite <nkCoding@gmail.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: gakkiyomi <gakkiyomi@aliyun.com> Co-authored-by: CN-P5 <heibai2006@gmail.com> Co-authored-by: CN-P5 <heibai2006@qq.com> Co-authored-by: Chuehnone <1897025+chuehnone@users.noreply.github.com> Co-authored-by: yihong <zouzou0208@gmail.com> Co-authored-by: Kevin9703 <51311316+Kevin9703@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Boris Feld <lothiraldan@gmail.com> Co-authored-by: mbo <himabo@gmail.com> Co-authored-by: mabo <mabo@aeyes.ai> Co-authored-by: Warren Chen <warren.chen830@gmail.com> Co-authored-by: JzoNgKVO <27049666+JzoNgKVO@users.noreply.github.com> Co-authored-by: jiandanfeng <chenjh3@wangsu.com> Co-authored-by: zhu-an <70234959+xhdd123321@users.noreply.github.com> Co-authored-by: zhaoqingyu.1075 <zhaoqingyu.1075@bytedance.com> Co-authored-by: 海狸大師 <86974027+yenslife@users.noreply.github.com> Co-authored-by: Xu Song <xusong.vip@gmail.com> Co-authored-by: rayshaw001 <396301947@163.com> Co-authored-by: Ding Jiatong <dingjiatong@gmail.com> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: JasonVV <jasonwangiii@outlook.com> Co-authored-by: le0zh <newlight@qq.com> Co-authored-by: zhuxinliang <zhuxinliang@didiglobal.com> Co-authored-by: k-zaku <zaku99@outlook.jp> Co-authored-by: luckylhb90 <luckylhb90@gmail.com> Co-authored-by: hobo.l <hobo.l@binance.com> Co-authored-by: jiangbo721 <365065261@qq.com> Co-authored-by: 刘江波 <jiangbo721@163.com> Co-authored-by: Shun Miyazawa <34241526+miya@users.noreply.github.com> Co-authored-by: EricPan <30651140+Egfly@users.noreply.github.com> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Jhvcc <37662342+Jhvcc@users.noreply.github.com> Co-authored-by: lowell <lowell.hu@zkteco.in> Co-authored-by: Boris Polonsky <BorisPolonsky@users.noreply.github.com> Co-authored-by: Ademílson Tonato <ademilsonft@outlook.com> Co-authored-by: Ademílson Tonato <ademilson.tonato@refurbed.com> Co-authored-by: IWAI, Masaharu <iwaim.sub@gmail.com> Co-authored-by: Yueh-Po Peng (Yabi) <94939112+y10ab1@users.noreply.github.com> Co-authored-by: Jason <ggbbddjm@gmail.com> Co-authored-by: Xin Zhang <sjhpzx@gmail.com> Co-authored-by: yjc980121 <3898524+yjc980121@users.noreply.github.com> Co-authored-by: heyszt <36215648+hieheihei@users.noreply.github.com> Co-authored-by: Abdullah AlOsaimi <osaimiacc@gmail.com> Co-authored-by: Abdullah AlOsaimi <189027247+osaimi@users.noreply.github.com> Co-authored-by: Yingchun Lai <laiyingchun@apache.org> Co-authored-by: Hash Brown <hi@xzd.me> Co-authored-by: zuodongxu <192560071+zuodongxu@users.noreply.github.com> Co-authored-by: Masashi Tomooka <tmokmss@users.noreply.github.com> Co-authored-by: aplio <ryo.091219@gmail.com> Co-authored-by: Obada Khalili <54270856+obadakhalili@users.noreply.github.com> Co-authored-by: Nam Vu <zuzoovn@gmail.com> Co-authored-by: Kei YAMAZAKI <1715090+kei-yamazaki@users.noreply.github.com> Co-authored-by: TechnoHouse <13776377+deephbz@users.noreply.github.com> Co-authored-by: Riddhimaan-Senapati <114703025+Riddhimaan-Senapati@users.noreply.github.com> Co-authored-by: MaFee921 <31881301+2284730142@users.noreply.github.com> Co-authored-by: te-chan <t-nakanome@sakura-is.co.jp> Co-authored-by: HQidea <HQidea@users.noreply.github.com> Co-authored-by: Joshbly <36315710+Joshbly@users.noreply.github.com> Co-authored-by: xhe <xw897002528@gmail.com> Co-authored-by: weiwenyan-dev <154779315+weiwenyan-dev@users.noreply.github.com> Co-authored-by: ex_wenyan.wei <ex_wenyan.wei@tcl.com> Co-authored-by: engchina <12236799+engchina@users.noreply.github.com> Co-authored-by: engchina <atjapan2015@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: Kemal <kemalmeler@outlook.com> Co-authored-by: Lazy_Frog <4590648+lazyFrogLOL@users.noreply.github.com> Co-authored-by: Yi Xiao <54782454+YIXIAO0@users.noreply.github.com> Co-authored-by: Steven sun <98230804+Tuyohai@users.noreply.github.com> Co-authored-by: steven <sunzwj@digitalchina.com> Co-authored-by: Kalo Chin <91766386+fdb02983rhy@users.noreply.github.com> Co-authored-by: Katy Tao <34019945+KatyTao@users.noreply.github.com> Co-authored-by: depy <42985524+h4ckdepy@users.noreply.github.com> Co-authored-by: 胡春东 <gycm520@gmail.com> Co-authored-by: Junjie.M <118170653@qq.com> Co-authored-by: MuYu <mr.muzea@gmail.com> Co-authored-by: Naoki Takashima <39912547+takatea@users.noreply.github.com> Co-authored-by: Summer-Gu <37869445+gubinjie@users.noreply.github.com> Co-authored-by: Fei He <droxer.he@gmail.com> Co-authored-by: ybalbert001 <120714773+ybalbert001@users.noreply.github.com> Co-authored-by: Yuanbo Li <ybalbert@amazon.com> Co-authored-by: douxc <7553076+douxc@users.noreply.github.com> Co-authored-by: liuzhenghua <1090179900@qq.com> Co-authored-by: Wu Jiayang <62842862+Wu-Jiayang@users.noreply.github.com> Co-authored-by: Your Name <you@example.com> Co-authored-by: kimjion <45935338+kimjion@users.noreply.github.com> Co-authored-by: AugNSo <song.tiankai@icloud.com> Co-authored-by: llinvokerl <38915183+llinvokerl@users.noreply.github.com> Co-authored-by: liusurong.lsr <liusurong.lsr@alibaba-inc.com> Co-authored-by: Vasu Negi <vasu-negi@users.noreply.github.com> Co-authored-by: Hundredwz <1808096180@qq.com> Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com>
8ヶ月前
Introduce Plugins (#13836) Signed-off-by: yihong0618 <zouzou0208@gmail.com> Signed-off-by: -LAN- <laipz8200@outlook.com> Signed-off-by: xhe <xw897002528@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: takatost <takatost@gmail.com> Co-authored-by: kurokobo <kuro664@gmail.com> Co-authored-by: Novice Lee <novicelee@NoviPro.local> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: AkaraChen <akarachen@outlook.com> Co-authored-by: Yi <yxiaoisme@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: JzoNg <jzongcode@gmail.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: Hiroshi Fujita <fujita-h@users.noreply.github.com> Co-authored-by: AkaraChen <85140972+AkaraChen@users.noreply.github.com> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Novice <857526207@qq.com> Co-authored-by: Hiroki Nagai <82458324+nagaihiroki-git@users.noreply.github.com> Co-authored-by: Gen Sato <52241300+halogen22@users.noreply.github.com> Co-authored-by: eux <euxuuu@gmail.com> Co-authored-by: huangzhuo1949 <167434202+huangzhuo1949@users.noreply.github.com> Co-authored-by: huangzhuo <huangzhuo1@xiaomi.com> Co-authored-by: lotsik <lotsik@mail.ru> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: nite-knite <nkCoding@gmail.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: gakkiyomi <gakkiyomi@aliyun.com> Co-authored-by: CN-P5 <heibai2006@gmail.com> Co-authored-by: CN-P5 <heibai2006@qq.com> Co-authored-by: Chuehnone <1897025+chuehnone@users.noreply.github.com> Co-authored-by: yihong <zouzou0208@gmail.com> Co-authored-by: Kevin9703 <51311316+Kevin9703@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Boris Feld <lothiraldan@gmail.com> Co-authored-by: mbo <himabo@gmail.com> Co-authored-by: mabo <mabo@aeyes.ai> Co-authored-by: Warren Chen <warren.chen830@gmail.com> Co-authored-by: JzoNgKVO <27049666+JzoNgKVO@users.noreply.github.com> Co-authored-by: jiandanfeng <chenjh3@wangsu.com> Co-authored-by: zhu-an <70234959+xhdd123321@users.noreply.github.com> Co-authored-by: zhaoqingyu.1075 <zhaoqingyu.1075@bytedance.com> Co-authored-by: 海狸大師 <86974027+yenslife@users.noreply.github.com> Co-authored-by: Xu Song <xusong.vip@gmail.com> Co-authored-by: rayshaw001 <396301947@163.com> Co-authored-by: Ding Jiatong <dingjiatong@gmail.com> Co-authored-by: Bowen Liang <liangbowen@gf.com.cn> Co-authored-by: JasonVV <jasonwangiii@outlook.com> Co-authored-by: le0zh <newlight@qq.com> Co-authored-by: zhuxinliang <zhuxinliang@didiglobal.com> Co-authored-by: k-zaku <zaku99@outlook.jp> Co-authored-by: luckylhb90 <luckylhb90@gmail.com> Co-authored-by: hobo.l <hobo.l@binance.com> Co-authored-by: jiangbo721 <365065261@qq.com> Co-authored-by: 刘江波 <jiangbo721@163.com> Co-authored-by: Shun Miyazawa <34241526+miya@users.noreply.github.com> Co-authored-by: EricPan <30651140+Egfly@users.noreply.github.com> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: sino <sino2322@gmail.com> Co-authored-by: Jhvcc <37662342+Jhvcc@users.noreply.github.com> Co-authored-by: lowell <lowell.hu@zkteco.in> Co-authored-by: Boris Polonsky <BorisPolonsky@users.noreply.github.com> Co-authored-by: Ademílson Tonato <ademilsonft@outlook.com> Co-authored-by: Ademílson Tonato <ademilson.tonato@refurbed.com> Co-authored-by: IWAI, Masaharu <iwaim.sub@gmail.com> Co-authored-by: Yueh-Po Peng (Yabi) <94939112+y10ab1@users.noreply.github.com> Co-authored-by: Jason <ggbbddjm@gmail.com> Co-authored-by: Xin Zhang <sjhpzx@gmail.com> Co-authored-by: yjc980121 <3898524+yjc980121@users.noreply.github.com> Co-authored-by: heyszt <36215648+hieheihei@users.noreply.github.com> Co-authored-by: Abdullah AlOsaimi <osaimiacc@gmail.com> Co-authored-by: Abdullah AlOsaimi <189027247+osaimi@users.noreply.github.com> Co-authored-by: Yingchun Lai <laiyingchun@apache.org> Co-authored-by: Hash Brown <hi@xzd.me> Co-authored-by: zuodongxu <192560071+zuodongxu@users.noreply.github.com> Co-authored-by: Masashi Tomooka <tmokmss@users.noreply.github.com> Co-authored-by: aplio <ryo.091219@gmail.com> Co-authored-by: Obada Khalili <54270856+obadakhalili@users.noreply.github.com> Co-authored-by: Nam Vu <zuzoovn@gmail.com> Co-authored-by: Kei YAMAZAKI <1715090+kei-yamazaki@users.noreply.github.com> Co-authored-by: TechnoHouse <13776377+deephbz@users.noreply.github.com> Co-authored-by: Riddhimaan-Senapati <114703025+Riddhimaan-Senapati@users.noreply.github.com> Co-authored-by: MaFee921 <31881301+2284730142@users.noreply.github.com> Co-authored-by: te-chan <t-nakanome@sakura-is.co.jp> Co-authored-by: HQidea <HQidea@users.noreply.github.com> Co-authored-by: Joshbly <36315710+Joshbly@users.noreply.github.com> Co-authored-by: xhe <xw897002528@gmail.com> Co-authored-by: weiwenyan-dev <154779315+weiwenyan-dev@users.noreply.github.com> Co-authored-by: ex_wenyan.wei <ex_wenyan.wei@tcl.com> Co-authored-by: engchina <12236799+engchina@users.noreply.github.com> Co-authored-by: engchina <atjapan2015@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 呆萌闷油瓶 <253605712@qq.com> Co-authored-by: Kemal <kemalmeler@outlook.com> Co-authored-by: Lazy_Frog <4590648+lazyFrogLOL@users.noreply.github.com> Co-authored-by: Yi Xiao <54782454+YIXIAO0@users.noreply.github.com> Co-authored-by: Steven sun <98230804+Tuyohai@users.noreply.github.com> Co-authored-by: steven <sunzwj@digitalchina.com> Co-authored-by: Kalo Chin <91766386+fdb02983rhy@users.noreply.github.com> Co-authored-by: Katy Tao <34019945+KatyTao@users.noreply.github.com> Co-authored-by: depy <42985524+h4ckdepy@users.noreply.github.com> Co-authored-by: 胡春东 <gycm520@gmail.com> Co-authored-by: Junjie.M <118170653@qq.com> Co-authored-by: MuYu <mr.muzea@gmail.com> Co-authored-by: Naoki Takashima <39912547+takatea@users.noreply.github.com> Co-authored-by: Summer-Gu <37869445+gubinjie@users.noreply.github.com> Co-authored-by: Fei He <droxer.he@gmail.com> Co-authored-by: ybalbert001 <120714773+ybalbert001@users.noreply.github.com> Co-authored-by: Yuanbo Li <ybalbert@amazon.com> Co-authored-by: douxc <7553076+douxc@users.noreply.github.com> Co-authored-by: liuzhenghua <1090179900@qq.com> Co-authored-by: Wu Jiayang <62842862+Wu-Jiayang@users.noreply.github.com> Co-authored-by: Your Name <you@example.com> Co-authored-by: kimjion <45935338+kimjion@users.noreply.github.com> Co-authored-by: AugNSo <song.tiankai@icloud.com> Co-authored-by: llinvokerl <38915183+llinvokerl@users.noreply.github.com> Co-authored-by: liusurong.lsr <liusurong.lsr@alibaba-inc.com> Co-authored-by: Vasu Negi <vasu-negi@users.noreply.github.com> Co-authored-by: Hundredwz <1808096180@qq.com> Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com>
8ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. import json
  2. import time
  3. import uuid
  4. from collections.abc import Generator
  5. from unittest.mock import MagicMock, patch
  6. from core.app.entities.app_invoke_entities import InvokeFrom
  7. from core.llm_generator.output_parser.structured_output import _parse_structured_output
  8. from core.workflow.entities.variable_pool import VariablePool
  9. from core.workflow.entities.workflow_node_execution import WorkflowNodeExecutionStatus
  10. from core.workflow.graph_engine.entities.graph import Graph
  11. from core.workflow.graph_engine.entities.graph_init_params import GraphInitParams
  12. from core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeState
  13. from core.workflow.nodes.event import RunCompletedEvent
  14. from core.workflow.nodes.llm.node import LLMNode
  15. from core.workflow.system_variable import SystemVariable
  16. from extensions.ext_database import db
  17. from models.enums import UserFrom
  18. from models.workflow import WorkflowType
  19. """FOR MOCK FIXTURES, DO NOT REMOVE"""
  20. def init_llm_node(config: dict) -> LLMNode:
  21. graph_config = {
  22. "edges": [
  23. {
  24. "id": "start-source-next-target",
  25. "source": "start",
  26. "target": "llm",
  27. },
  28. ],
  29. "nodes": [{"data": {"type": "start"}, "id": "start"}, config],
  30. }
  31. graph = Graph.init(graph_config=graph_config)
  32. # Use proper UUIDs for database compatibility
  33. tenant_id = "9d2074fc-6f86-45a9-b09d-6ecc63b9056b"
  34. app_id = "9d2074fc-6f86-45a9-b09d-6ecc63b9056c"
  35. workflow_id = "9d2074fc-6f86-45a9-b09d-6ecc63b9056d"
  36. user_id = "9d2074fc-6f86-45a9-b09d-6ecc63b9056e"
  37. init_params = GraphInitParams(
  38. tenant_id=tenant_id,
  39. app_id=app_id,
  40. workflow_type=WorkflowType.WORKFLOW,
  41. workflow_id=workflow_id,
  42. graph_config=graph_config,
  43. user_id=user_id,
  44. user_from=UserFrom.ACCOUNT,
  45. invoke_from=InvokeFrom.DEBUGGER,
  46. call_depth=0,
  47. )
  48. # construct variable pool
  49. variable_pool = VariablePool(
  50. system_variables=SystemVariable(
  51. user_id="aaa",
  52. app_id=app_id,
  53. workflow_id=workflow_id,
  54. files=[],
  55. query="what's the weather today?",
  56. conversation_id="abababa",
  57. ),
  58. user_inputs={},
  59. environment_variables=[],
  60. conversation_variables=[],
  61. )
  62. variable_pool.add(["abc", "output"], "sunny")
  63. node = LLMNode(
  64. id=str(uuid.uuid4()),
  65. graph_init_params=init_params,
  66. graph=graph,
  67. graph_runtime_state=GraphRuntimeState(variable_pool=variable_pool, start_at=time.perf_counter()),
  68. config=config,
  69. )
  70. # Initialize node data
  71. if "data" in config:
  72. node.init_node_data(config["data"])
  73. return node
  74. def test_execute_llm():
  75. node = init_llm_node(
  76. config={
  77. "id": "llm",
  78. "data": {
  79. "title": "123",
  80. "type": "llm",
  81. "model": {
  82. "provider": "openai",
  83. "name": "gpt-3.5-turbo",
  84. "mode": "chat",
  85. "completion_params": {},
  86. },
  87. "prompt_template": [
  88. {
  89. "role": "system",
  90. "text": "you are a helpful assistant.\ntoday's weather is {{#abc.output#}}.",
  91. },
  92. {"role": "user", "text": "{{#sys.query#}}"},
  93. ],
  94. "memory": None,
  95. "context": {"enabled": False},
  96. "vision": {"enabled": False},
  97. },
  98. },
  99. )
  100. db.session.close = MagicMock()
  101. # Mock the _fetch_model_config to avoid database calls
  102. def mock_fetch_model_config(**_kwargs):
  103. from decimal import Decimal
  104. from unittest.mock import MagicMock
  105. from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage
  106. from core.model_runtime.entities.message_entities import AssistantPromptMessage
  107. # Create mock model instance
  108. mock_model_instance = MagicMock()
  109. mock_usage = LLMUsage(
  110. prompt_tokens=30,
  111. prompt_unit_price=Decimal("0.001"),
  112. prompt_price_unit=Decimal(1000),
  113. prompt_price=Decimal("0.00003"),
  114. completion_tokens=20,
  115. completion_unit_price=Decimal("0.002"),
  116. completion_price_unit=Decimal(1000),
  117. completion_price=Decimal("0.00004"),
  118. total_tokens=50,
  119. total_price=Decimal("0.00007"),
  120. currency="USD",
  121. latency=0.5,
  122. )
  123. mock_message = AssistantPromptMessage(content="Test response from mock")
  124. mock_llm_result = LLMResult(
  125. model="gpt-3.5-turbo",
  126. prompt_messages=[],
  127. message=mock_message,
  128. usage=mock_usage,
  129. )
  130. mock_model_instance.invoke_llm.return_value = mock_llm_result
  131. # Create mock model config
  132. mock_model_config = MagicMock()
  133. mock_model_config.mode = "chat"
  134. mock_model_config.provider = "openai"
  135. mock_model_config.model = "gpt-3.5-turbo"
  136. mock_model_config.parameters = {}
  137. return mock_model_instance, mock_model_config
  138. # Mock fetch_prompt_messages to avoid database calls
  139. def mock_fetch_prompt_messages_1(**_kwargs):
  140. from core.model_runtime.entities.message_entities import SystemPromptMessage, UserPromptMessage
  141. return [
  142. SystemPromptMessage(content="you are a helpful assistant. today's weather is sunny."),
  143. UserPromptMessage(content="what's the weather today?"),
  144. ], []
  145. with (
  146. patch.object(LLMNode, "_fetch_model_config", mock_fetch_model_config),
  147. patch.object(LLMNode, "fetch_prompt_messages", mock_fetch_prompt_messages_1),
  148. ):
  149. # execute node
  150. result = node._run()
  151. assert isinstance(result, Generator)
  152. for item in result:
  153. if isinstance(item, RunCompletedEvent):
  154. if item.run_result.status != WorkflowNodeExecutionStatus.SUCCEEDED:
  155. print(f"Error: {item.run_result.error}")
  156. print(f"Error type: {item.run_result.error_type}")
  157. assert item.run_result.status == WorkflowNodeExecutionStatus.SUCCEEDED
  158. assert item.run_result.process_data is not None
  159. assert item.run_result.outputs is not None
  160. assert item.run_result.outputs.get("text") is not None
  161. assert item.run_result.outputs.get("usage", {})["total_tokens"] > 0
  162. def test_execute_llm_with_jinja2():
  163. """
  164. Test execute LLM node with jinja2
  165. """
  166. node = init_llm_node(
  167. config={
  168. "id": "llm",
  169. "data": {
  170. "title": "123",
  171. "type": "llm",
  172. "model": {"provider": "openai", "name": "gpt-3.5-turbo", "mode": "chat", "completion_params": {}},
  173. "prompt_config": {
  174. "jinja2_variables": [
  175. {"variable": "sys_query", "value_selector": ["sys", "query"]},
  176. {"variable": "output", "value_selector": ["abc", "output"]},
  177. ]
  178. },
  179. "prompt_template": [
  180. {
  181. "role": "system",
  182. "text": "you are a helpful assistant.\ntoday's weather is {{#abc.output#}}",
  183. "jinja2_text": "you are a helpful assistant.\ntoday's weather is {{output}}.",
  184. "edition_type": "jinja2",
  185. },
  186. {
  187. "role": "user",
  188. "text": "{{#sys.query#}}",
  189. "jinja2_text": "{{sys_query}}",
  190. "edition_type": "basic",
  191. },
  192. ],
  193. "memory": None,
  194. "context": {"enabled": False},
  195. "vision": {"enabled": False},
  196. },
  197. },
  198. )
  199. # Mock db.session.close()
  200. db.session.close = MagicMock()
  201. # Mock the _fetch_model_config method
  202. def mock_fetch_model_config(**_kwargs):
  203. from decimal import Decimal
  204. from unittest.mock import MagicMock
  205. from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage
  206. from core.model_runtime.entities.message_entities import AssistantPromptMessage
  207. # Create mock model instance
  208. mock_model_instance = MagicMock()
  209. mock_usage = LLMUsage(
  210. prompt_tokens=30,
  211. prompt_unit_price=Decimal("0.001"),
  212. prompt_price_unit=Decimal(1000),
  213. prompt_price=Decimal("0.00003"),
  214. completion_tokens=20,
  215. completion_unit_price=Decimal("0.002"),
  216. completion_price_unit=Decimal(1000),
  217. completion_price=Decimal("0.00004"),
  218. total_tokens=50,
  219. total_price=Decimal("0.00007"),
  220. currency="USD",
  221. latency=0.5,
  222. )
  223. mock_message = AssistantPromptMessage(content="Test response: sunny weather and what's the weather today?")
  224. mock_llm_result = LLMResult(
  225. model="gpt-3.5-turbo",
  226. prompt_messages=[],
  227. message=mock_message,
  228. usage=mock_usage,
  229. )
  230. mock_model_instance.invoke_llm.return_value = mock_llm_result
  231. # Create mock model config
  232. mock_model_config = MagicMock()
  233. mock_model_config.mode = "chat"
  234. mock_model_config.provider = "openai"
  235. mock_model_config.model = "gpt-3.5-turbo"
  236. mock_model_config.parameters = {}
  237. return mock_model_instance, mock_model_config
  238. # Mock fetch_prompt_messages to avoid database calls
  239. def mock_fetch_prompt_messages_2(**_kwargs):
  240. from core.model_runtime.entities.message_entities import SystemPromptMessage, UserPromptMessage
  241. return [
  242. SystemPromptMessage(content="you are a helpful assistant. today's weather is sunny."),
  243. UserPromptMessage(content="what's the weather today?"),
  244. ], []
  245. with (
  246. patch.object(LLMNode, "_fetch_model_config", mock_fetch_model_config),
  247. patch.object(LLMNode, "fetch_prompt_messages", mock_fetch_prompt_messages_2),
  248. ):
  249. # execute node
  250. result = node._run()
  251. for item in result:
  252. if isinstance(item, RunCompletedEvent):
  253. assert item.run_result.status == WorkflowNodeExecutionStatus.SUCCEEDED
  254. assert item.run_result.process_data is not None
  255. assert "sunny" in json.dumps(item.run_result.process_data)
  256. assert "what's the weather today?" in json.dumps(item.run_result.process_data)
  257. def test_extract_json():
  258. llm_texts = [
  259. '<think>\n\n</think>{"name": "test", "age": 123', # resoning model (deepseek-r1)
  260. '{"name":"test","age":123}', # json schema model (gpt-4o)
  261. '{\n "name": "test",\n "age": 123\n}', # small model (llama-3.2-1b)
  262. '```json\n{"name": "test", "age": 123}\n```', # json markdown (deepseek-chat)
  263. '{"name":"test",age:123}', # without quotes (qwen-2.5-0.5b)
  264. ]
  265. result = {"name": "test", "age": 123}
  266. assert all(_parse_structured_output(item) == result for item in llm_texts)