Humanlearning commited on
Commit
f6fc677
·
1 Parent(s): 81917a3

llamaindex agent

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ env*
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.13
__pycache__/tools.cpython-313.pyc ADDED
Binary file (4.46 kB). View file
 
__pycache__/tools.cpython-38.pyc ADDED
Binary file (3.38 kB). View file
 
agents.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import random
3
+ import asyncio
4
+ from dotenv import load_dotenv
5
+ from llama_index.core.agent.workflow import AgentWorkflow
6
+ from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
7
+ from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
8
+ # from opentelemetry.sdk import trace as trace_sdk
9
+ from opentelemetry.sdk.trace.export import SimpleSpanProcessor
10
+ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
11
+ from opentelemetry import trace
12
+ from opentelemetry.sdk.trace import TracerProvider
13
+ from langfuse import get_client
14
+ from rich.pretty import pprint
15
+
16
+
17
+
18
+
19
+ import base64
20
+
21
+
22
+
23
+ # Import tool functions and initializers from tools.py
24
+ from tools import (
25
+ get_tavily_tool,
26
+ get_arxiv_reader,
27
+ get_wikipedia_reader,
28
+ get_wikipedia_tool,
29
+ get_arxiv_tool,
30
+ get_search_tool,
31
+ get_calculator_tool,
32
+ get_hub_stats_tool,
33
+ get_hub_stats,
34
+ )
35
+
36
+ load_dotenv("env.local")
37
+
38
+ class AlfredAgent:
39
+ def __init__(self):
40
+ # Tool initializations using imported functions
41
+ self.tavily_tool = get_tavily_tool()
42
+ self.arxiv_reader = get_arxiv_reader()
43
+ self.wikipedia_reader = get_wikipedia_reader()
44
+ self.wikipedia_tool = get_wikipedia_tool(self.wikipedia_reader)
45
+ self.arxiv_tool = get_arxiv_tool(self.arxiv_reader)
46
+ self.search_tool = get_search_tool()
47
+ self.calculator_tool = get_calculator_tool()
48
+ self.hub_stats_tool = get_hub_stats_tool()
49
+ # LLM and agent workflow
50
+ self.llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
51
+ self.alfred = AgentWorkflow.from_tools_or_functions(
52
+ [*self.search_tool, *self.calculator_tool, self.wikipedia_tool, self.arxiv_tool, self.hub_stats_tool],
53
+ llm=self.llm
54
+ )
55
+
56
+ LANGFUSE_AUTH=base64.b64encode(f"{os.getenv('LANGFUSE_PUBLIC_KEY')}:{os.getenv('LANGFUSE_SECRET_KEY')}".encode()).decode()
57
+ os.environ['OTEL_EXPORTER_OTLP_ENDPOINT'] = os.environ.get("LANGFUSE_HOST") + "/api/public/otel"
58
+ os.environ['OTEL_EXPORTER_OTLP_HEADERS'] = f"Authorization=Basic {LANGFUSE_AUTH}"
59
+
60
+ # Set up OpenTelemetry tracing
61
+ self.tracer_provider = TracerProvider()
62
+ self.tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
63
+ trace.set_tracer_provider(self.tracer_provider)
64
+
65
+
66
+ self.instrumentor = LlamaIndexInstrumentor(
67
+ public_key=os.getenv("LANGFUSE_PUBLIC_KEY"),
68
+ secret_key=os.getenv("LANGFUSE_SECRET_KEY"),
69
+ host=os.environ.get("LANGFUSE_HOST")
70
+ )
71
+
72
+
73
+ async def run_query(self, query: str):
74
+ # Instrument LlamaIndex with OpenTelemetry
75
+ self.instrumentor.instrument()
76
+
77
+ langfuse = get_client() # This picks up your LANGFUSE_PUBLIC_KEY, etc.
78
+
79
+ # Now, wrap your LlamaIndex calls in a Langfuse span for trace context
80
+ with langfuse.start_as_current_span(name="llamaindex-query") as span:
81
+ # Optionally set trace attributes
82
+ span.update_trace(user_id="user_123", input={"query": query})
83
+
84
+ response = await self.alfred.run(query)
85
+
86
+ # Optionally set trace output
87
+ span.update_trace(output={"response": str(response)})
88
+
89
+ # For short-lived scripts, flush before exit
90
+ langfuse.flush()
91
+ self.tracer_provider.shutdown()
92
+ return response
93
+
94
+ def main():
95
+
96
+ agent = AlfredAgent()
97
+ query = "who is the capital of France?"
98
+ print(f"Running query: {query}")
99
+ response = asyncio.run(agent.run_query(query))
100
+ print("\n🎩 Agents's Response:")
101
+ pprint(response)
102
+
103
+ if __name__ == "__main__":
104
+ main()
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from final-assignment-template!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
pyproject.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "final-assignment-template"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ dependencies = [
8
+ "dotenv>=0.9.9",
9
+ "huggingface-hub>=0.32.4",
10
+ "langfuse>=3.0.0",
11
+ "llama-index>=0.12.40",
12
+ "llama-index-core>=0.12.40",
13
+ "llama-index-llms-huggingface-api>=0.5.0",
14
+ "llama-index-readers-papers>=0.3.2",
15
+ "llama-index-readers-wikipedia>=0.3.0",
16
+ "llama-index-tools-duckduckgo>=0.3.0",
17
+ "llama-index-tools-tavily-research>=0.3.0",
18
+ "rich>=14.0.0",
19
+ "wikipedia>=1.4.0",
20
+ ]
tools.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from llama_index.core.tools import FunctionTool
3
+ from llama_index.tools.tavily_research import TavilyToolSpec
4
+ from llama_index.readers.wikipedia import WikipediaReader
5
+ from llama_index.readers.papers import ArxivReader
6
+ from llama_index.core.tools.ondemand_loader_tool import OnDemandLoaderTool
7
+ from huggingface_hub import list_models
8
+
9
+ # Math functions
10
+
11
+ def multiply(a: int, b: int) -> int:
12
+ """Multiply two numbers."""
13
+ return a * b
14
+
15
+ def add(a: int, b: int) -> int:
16
+ """Add two numbers."""
17
+ return a + b
18
+
19
+ def subtract(a: int, b: int) -> int:
20
+ """Subtract two numbers."""
21
+ return a - b
22
+
23
+ def divide(a: int, b: int) -> int:
24
+ """Divide two numbers."""
25
+ if b == 0:
26
+ raise ValueError("Cannot divide by zero.")
27
+ return a / b
28
+
29
+ def modulus(a: int, b: int) -> int:
30
+ """Get the modulus of two numbers."""
31
+ return a % b
32
+
33
+ # Hugging Face Hub stats tool
34
+
35
+ def get_hub_stats(author: str) -> str:
36
+ """Fetches the most downloaded model from a specific author on the Hugging Face Hub."""
37
+ try:
38
+ models = list(list_models(author=author, sort="downloads", direction=-1, limit=1))
39
+ if models:
40
+ model = models[0]
41
+ return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads."
42
+ else:
43
+ return f"No models found for author {author}."
44
+ except Exception as e:
45
+ return f"Error fetching models for {author}: {str(e)}"
46
+
47
+ # Tool initializations (as functions to be called in agent)
48
+
49
+ def get_tavily_tool():
50
+ return TavilyToolSpec(api_key=os.getenv("TAVILY_API_KEY"))
51
+
52
+ def get_arxiv_reader():
53
+ return ArxivReader()
54
+
55
+ def get_wikipedia_reader():
56
+ return WikipediaReader()
57
+
58
+ def get_wikipedia_tool(wikipedia_reader=None):
59
+ if wikipedia_reader is None:
60
+ wikipedia_reader = get_wikipedia_reader()
61
+ return OnDemandLoaderTool.from_defaults(
62
+ wikipedia_reader,
63
+ name="Wikipedia Tool",
64
+ description="A tool for loading data and querying articles from Wikipedia",
65
+ )
66
+
67
+ def get_arxiv_tool(arxiv_reader=None):
68
+ if arxiv_reader is None:
69
+ arxiv_reader = get_arxiv_reader()
70
+ return OnDemandLoaderTool.from_defaults(
71
+ arxiv_reader,
72
+ name="Arxiv Tool",
73
+ description="A tool for loading data and querying articles from Arxiv",
74
+ )
75
+
76
+ def get_search_tool():
77
+ return get_tavily_tool().to_tool_list()
78
+
79
+ def get_calculator_tool():
80
+ return [
81
+ FunctionTool.from_defaults(multiply),
82
+ FunctionTool.from_defaults(add),
83
+ FunctionTool.from_defaults(subtract),
84
+ FunctionTool.from_defaults(divide),
85
+ FunctionTool.from_defaults(modulus),
86
+ ]
87
+
88
+ def get_hub_stats_tool():
89
+ return FunctionTool.from_defaults(get_hub_stats)
uv.lock ADDED
The diff for this file is too large to render. See raw diff