@@ -24,7 +24,7 @@ defmodule MockInvestmentProvider do
2424 - Client risk preferences
2525 - Previous tool execution outcomes
2626
27- Unlike static DAG workflows, it dynamically chooses the next steps based on
27+ Unlike static DAG workflows, it dynamically chooses the next steps based on
2828 the evolving context and state.
2929 """
3030
@@ -261,20 +261,6 @@ defmodule MockInvestmentProvider do
261261 ]
262262 } }
263263
264- "portfolio_backtester" ->
265- { :ok ,
266- % {
267- "choices" => [
268- % {
269- "message" => % {
270- "content" =>
271- "I couldn't complete the detailed backtest. Let me provide a simplified analysis instead." ,
272- "content_only" => true
273- }
274- }
275- ]
276- } }
277-
278264 _ ->
279265 { :ok ,
280266 % {
@@ -476,7 +462,7 @@ defmodule MockInvestmentProvider do
476462 end
477463 end
478464
479- defp determine_risk_preference ( question , current_profile ) do
465+ defp determine_risk_preference ( question , _current_profile ) do
480466 question = String . downcase ( question )
481467
482468 cond do
@@ -543,7 +529,7 @@ defmodule MockInvestmentProvider do
543529 # Response generation functions
544530 #
545531
546- defp generate_contextual_response ( context , question ) do
532+ defp generate_contextual_response ( context , _question ) do
547533 cond do
548534 context . has_portfolio and context . has_backtest ->
549535 portfolio = context . portfolio
@@ -808,7 +794,7 @@ defmodule LLMAgent.Examples.InvestmentTools do
808794 fallback = Map . get ( params , "fallback" , false )
809795
810796 # Use ETFs provided in request or default set
811- provided_etfs = Map . get ( params , "etfs" , nil )
797+ _provided_etfs = Map . get ( params , "etfs" , nil )
812798
813799 allocations =
814800 case { risk_profile , fallback } do
@@ -1029,16 +1015,16 @@ defmodule LLMAgent.Examples.InvestmentDemo do
10291015 5. Simulate performance in different market scenarios
10301016
10311017 When providing recommendations, consider:
1032- - Current market conditions: #{ Store . get ( store_name , :market_volatility ) }
1033- - Interest rate environment: #{ Store . get ( store_name , :interest_rate_trend ) }
1034- - Economic outlook: #{ Store . get ( store_name , :economic_outlook ) }
1018+ - Current market conditions: #{ elem ( Store . get ( store_name , :market_volatility ) , 1 ) }
1019+ - Interest rate environment: #{ elem ( Store . get ( store_name , :interest_rate_trend ) , 1 ) }
1020+ - Economic outlook: #{ elem ( Store . get ( store_name , :economic_outlook ) , 1 ) }
10351021
10361022 Tailor your analysis approach to the client's knowledge level and goals.
10371023 Present your findings clearly with both technical detail and plain language explanations.
10381024 """
10391025
10401026 # 5. Create conversation flow with investment tools
1041- { flow , state } =
1027+ { flow , _fresh_state } =
10421028 Flows . tool_agent (
10431029 system_prompt ,
10441030 LLMAgent.Examples.InvestmentTools . get_tools ( ) ,
@@ -1103,13 +1089,20 @@ defmodule LLMAgent.Examples.InvestmentDemo do
11031089 signal = Signals . user_message ( input )
11041090
11051091 # Process through the investment flow
1106- case Flow . process ( flow , signal , current_state ) do
1107- { result , new_state } ->
1108- display_response ( result )
1092+ case flow . ( signal , current_state ) do
1093+ { :emit , % { type: :response } = response_signal , new_state } ->
1094+ display_response ( { :emit , response_signal } )
11091095
11101096 # Store conversation progress in the store for stateful decisions
11111097 Store . put ( store_name , :last_client_message , input )
1112- store_result_data ( store_name , result )
1098+
1099+ new_state
1100+
1101+ { :emit , % { type: :tool_result } = tool_signal , new_state } ->
1102+ display_response ( { :emit , tool_signal } )
1103+
1104+ # Store tool result data
1105+ store_result_data ( store_name , { :emit , tool_signal } )
11131106
11141107 new_state
11151108
@@ -1120,6 +1113,10 @@ defmodule LLMAgent.Examples.InvestmentDemo do
11201113 Store . put ( store_name , :last_error , error )
11211114
11221115 current_state
1116+
1117+ unexpected ->
1118+ IO . puts ( "Unexpected result: #{ inspect ( unexpected ) } " )
1119+ current_state
11231120 end
11241121 end )
11251122 end )
@@ -1128,19 +1125,18 @@ defmodule LLMAgent.Examples.InvestmentDemo do
11281125 IO . puts ( "\n === Investment Agent Architecture ===" )
11291126
11301127 IO . puts ( """
1131-
11321128 This example demonstrates how LLMAgent builds dynamic workflows:
11331129
11341130 1. Signal-Based Decision Making:
1135- The agent doesn't follow a predefined DAG, but instead makes decisions
1131+ The agent doesn't follow a predefined DAG, but instead makes decisions
11361132 based on evolving context and conversation state.
11371133
11381134 2. Tool Chaining with LLM Intelligence:
11391135 Unlike rule-based systems, the agent intelligently chains tools based on:
11401136 - Results of previous tool executions
11411137 - Client request analysis
11421138 - Contextual state information
1143-
1139+
11441140 3. Dynamic Path Selection:
11451141 The agent dynamically determines:
11461142 - Which tool to use next
@@ -1150,7 +1146,7 @@ defmodule LLMAgent.Examples.InvestmentDemo do
11501146
11511147 4. State Management:
11521148 The Store component maintains state across interactions:
1153- - #{ inspect ( Store . get_all ( store_name ) |> Enum . count ( ) ) } state keys tracked
1149+ - #{ length ( elem ( Store . get_all ( store_name ) , 1 ) ) } state keys tracked
11541150 - Analysis history preserved
11551151 - Tool results maintained for context
11561152 """ )
@@ -1159,44 +1155,45 @@ defmodule LLMAgent.Examples.InvestmentDemo do
11591155 IO . puts ( "\n To implement similar agents in your application, follow this pattern:" )
11601156
11611157 IO . puts ( """
1162-
11631158 1. Define domain-specific tools:
1164- ```elixir
1165- tools = [
1166- %{
1167- name: "etf_screener",
1168- description: "Screen ETFs based on criteria",
1169- parameters: %{...},
1170- execute: &screen_etfs/1
1171- }
1172- ]
1173- ```
1174-
1159+ ```elixir
1160+ tools = [
1161+ %{
1162+ name: "portfolio_analyzer",
1163+ description: "Analyze investment portfolios based on risk profile and goals",
1164+ parameters: %{
1165+ type: "object",
1166+ properties: %{
1167+ risk_profile: %{type: "string", enum: ["Conservative", "Moderate", "Aggressive"]}
1168+ }
1169+ }
1170+ }
1171+ ]
1172+ ```
1173+
11751174 2. Initialize store and create the agent:
1176- ```elixir
1177- store_name = MyApp.InvestmentStore
1178- {:ok, _} = LLMAgent.Store.start_link(name: store_name)
1179- {flow, state} = LLMAgent.Flows.tool_agent(system_prompt, tools, store_name: store_name)
1180- ```
1181-
1175+ ```elixir
1176+ store_name = MyApp.InvestmentStore
1177+ {flow, state} = LLMAgent.Flows.tool_agent(system_prompt, tools, store_name: store_name)
1178+ ```
1179+
11821180 3. Process client requests:
1183- ```elixir
1184- {result, new_state} = AgentForge.Flow.process(flow, Signals.user_message(request), state)
1185- ```
1186-
1181+ ```elixir
1182+ {result, new_state} = AgentForge.Flow.process(flow, Signals.user_message(request), state)
1183+ ```
1184+
11871185 4. Access stateful information:
1188- ```elixir
1189- portfolio = AgentForge.Store.get(store_name, :current_portfolio)
1190- history = LLMAgent.Store.get_llm_history(store_name)
1191- ```
1186+ ```elixir
1187+ portfolio = AgentForge.Store.get(store_name, :current_portfolio)
1188+ history = LLMAgent.Store.get_llm_history(store_name)
11921189 """ )
11931190 end
11941191
11951192 # Helper functions for demo
11961193
11971194 # Reset store between scenarios
11981195 defp reset_store ( store_name ) do
1199- # Preserve system settings but clear scenario- specific data
1196+ # Reset store but preserve specific keys
12001197 preserved_keys = [
12011198 :market_volatility ,
12021199 :interest_rate_trend ,
@@ -1207,13 +1204,12 @@ defmodule LLMAgent.Examples.InvestmentDemo do
12071204 # Save values we want to keep
12081205 preserved_values =
12091206 preserved_keys
1210- |> Enum . map ( fn key -> { key , Store . get ( store_name , key ) } end )
1207+ |> Enum . map ( fn key -> { key , elem ( Store . get ( store_name , key ) , 1 ) } end )
12111208 |> Map . new ( )
12121209
1213- # Clear everything
1214- Store . clear ( store_name )
1210+ IO . puts ( "\n --- Resetting conversation state ---\n " )
12151211
1216- # Restore preserved values
1212+ # We will simply reset the values we want to keep
12171213 Enum . each ( preserved_values , fn { key , value } ->
12181214 Store . put ( store_name , key , value )
12191215 end )
@@ -1239,7 +1235,7 @@ defmodule LLMAgent.Examples.InvestmentDemo do
12391235
12401236 "market_simulator" ->
12411237 Store . put ( store_name , :market_scenarios , [
1242- result | Store . get ( store_name , :market_scenarios ) || [ ]
1238+ result | elem ( Store . get ( store_name , :market_scenarios ) , 1 ) || [ ]
12431239 ] )
12441240
12451241 _ ->
0 commit comments