Gulzat commited on
Commit
fbc1aef
·
verified ·
1 Parent(s): f6be06c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -65
app.py CHANGED
@@ -1,83 +1,181 @@
1
- # ───────────────────────────── app.py ─────────────────────────────────────
2
- # NOTE: just push this one file to your HF Space repo. The bootstrap section
3
- # installs the needed packages inside the container at first launch.
4
-
5
- # ╭──────────────────────── 0. Bootstrap helper ─────────────────────────────╮
6
- import importlib, subprocess, sys, os, datetime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  from typing import List
8
 
9
- def ensure(pkg: str, ver: str | None = None):
10
- """Import a package or pip-install it into the current env, then import."""
11
- try:
12
- return importlib.import_module(pkg)
13
- except ModuleNotFoundError:
14
- target = f"{pkg}=={ver}" if ver else pkg
15
- print(f"[bootstrap] installing {target} …", flush=True)
16
- subprocess.check_call([sys.executable, "-m", "pip", "install", target])
17
- return importlib.import_module(pkg)
18
-
19
- # minimal deps: pytz + *monolithic* langchain (0.1.x) + openai
20
- pytz = ensure("pytz")
21
- langchain = ensure("langchain", "0.1.16") # stable, includes tool decorator
22
- openai_pkg = ensure("openai") # backend used by ChatOpenAI
23
-
24
- # ╰───────────────────────────────────────────────────────────────────────────╯
25
 
26
 
27
- # ╭──────────────────────── 1. Imports after install ────────────────────────╮
28
- from langchain.tools import tool, Tool
29
- from langchain.chat_models import ChatOpenAI
30
- from langchain.agents import create_openai_functions_agent, AgentExecutor
31
- # ╰───────────────────────────────────────────────────────────────────────────╯
32
-
33
-
34
- # ╭──────────────────────── 2. Tool definitions ─────────────────────────────╮
35
- @tool
36
  def my_custom_tool(arg1: str, arg2: int) -> str:
37
- """A placeholder tool you can extend later.
38
  Args:
39
- arg1: any string
40
- arg2: any integer
41
  """
42
- return f"Received arg1='{arg1}', arg2={arg2}. Build your magic here!"
 
43
 
 
44
  @tool
45
  def get_current_time_in_timezone(timezone: str) -> str:
46
- """Return the current local time in the given IANA timezone."""
 
 
 
47
  try:
48
  tz = pytz.timezone(timezone)
49
- return datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
50
- except Exception as e:
51
- return f"Error: {e}"
52
- # ╰───────────────────────────────────────────────────────────────────────────╯
53
 
54
 
55
- # ╭──────────────────────── 3. Build agent once ─────────────────────────────╮
56
- tools: List[Tool] = [
57
- Tool.from_function(my_custom_tool, name="my_custom_tool"),
58
- Tool.from_function(get_current_time_in_timezone, name="get_current_time_in_timezone"),
59
- ]
 
 
 
60
 
61
- llm = ChatOpenAI( # uses env var OPENAI_API_KEY
62
- model = "gpt-3.5-turbo",
63
- temperature = 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  )
65
 
66
- agent = create_openai_functions_agent(llm, tools)
67
- agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
68
- # ╰───────────────────────────────────────────────────────────────────────────╯
69
-
70
-
71
- # ╭──────────────────────── 4. CLI test loop (optional) ─────────────────────╮
72
- if __name__ == "__main__":
73
- if not os.getenv("OPENAI_API_KEY"):
74
- print("⚠️ Please set OPENAI_API_KEY as an env-var (HF Space → Secrets).")
75
- print("🔮 Agent ready. Type a question or 'q' to quit.")
76
- while True:
77
- user = input("🗣 ")
78
- if user.lower().strip() in {"q", "quit", "exit"}:
79
- break
80
- result = agent_executor.invoke({"input": user})
81
- print("🤖", result["output"])
82
- # ╰───────────────────────────────────────────────────────────────────────────╯
 
 
 
 
 
 
 
 
83
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Extended smolagents template
4
+ Adds a tool that finds the overlap in normal office-hours
5
+ (09:00-17:00 local time by default) for a list of time-zones,
6
+ so a distributed team can quickly see when they’re all online.
7
+
8
+ Teams: Kyrgyzstan (Asia/Bishkek), USA (pick any valid TZ,
9
+ e.g. America/New_York), Uzbekistan (Asia/Tashkent).
10
+
11
+ Usage inside the chat UI, for example:
12
+ find_overlapping_work_hours(
13
+ ["Asia/Bishkek", "America/New_York", "Asia/Tashkent"],
14
+ start_local="09:00",
15
+ end_local="17:00"
16
+ )
17
+ """
18
+
19
+ from smolagents import (
20
+ CodeAgent,
21
+ DuckDuckGoSearchTool,
22
+ InferenceClientModel,
23
+ load_tool,
24
+ tool,
25
+ )
26
+ import datetime
27
+ import pytz
28
+ import yaml
29
  from typing import List
30
 
31
+ from tools.final_answer import FinalAnswerTool
32
+ from Gradio_UI import GradioUI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
 
35
+ # --------------------------------------------------------------------------- #
36
+ # Example placeholder tool (left intact)
 
 
 
 
 
 
 
37
  def my_custom_tool(arg1: str, arg2: int) -> str:
38
+ """A tool that does nothing yet
39
  Args:
40
+ arg1: the first argument
41
+ arg2: the second argument
42
  """
43
+ return "What magic will you build ?"
44
+
45
 
46
+ # --------------------------------------------------------------------------- #
47
  @tool
48
  def get_current_time_in_timezone(timezone: str) -> str:
49
+ """Return the current wall-clock time for a given timezone.
50
+ Args:
51
+ timezone: IANA tz database string, e.g. 'America/New_York'.
52
+ """
53
  try:
54
  tz = pytz.timezone(timezone)
55
+ now_local = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
56
+ return f"Local time in {timezone}: {now_local}"
57
+ except Exception as exc:
58
+ return f"Error: {exc}"
59
 
60
 
61
+ # --------------------------------------------------------------------------- #
62
+ @tool
63
+ def find_overlapping_work_hours(
64
+ timezones: List[str],
65
+ start_local: str = "09:00",
66
+ end_local: str = "17:00",
67
+ ) -> str:
68
+ """Given several IANA time-zones, return the daily overlap of office hours.
69
 
70
+ Args:
71
+ timezones: List of tz names (e.g. ['Asia/Bishkek','America/New_York'])
72
+ start_local: Start of work day in HH:MM (24 h) for *each* zone
73
+ end_local: End of work day in HH:MM (24 h) for *each* zone
74
+ """
75
+ try:
76
+ # Parse the local start/end once
77
+ start_h, start_m = map(int, start_local.split(":"))
78
+ end_h, end_m = map(int, end_local.split(":"))
79
+ if (end_h, end_m) <= (start_h, start_m):
80
+ return "End time must be after start time."
81
+
82
+ # For today’s date we’ll convert each zone’s window to UTC
83
+ today = datetime.date.today()
84
+ utc = pytz.utc
85
+ earliest_end_utc = datetime.datetime.min.replace(tzinfo=utc)
86
+ latest_start_utc = datetime.datetime.max.replace(tzinfo=utc)
87
+
88
+ details = []
89
+ for tz_name in timezones:
90
+ tz = pytz.timezone(tz_name)
91
+
92
+ local_start = tz.localize(
93
+ datetime.datetime(today.year, today.month, today.day, start_h, start_m)
94
+ )
95
+ local_end = tz.localize(
96
+ datetime.datetime(today.year, today.month, today.day, end_h, end_m)
97
+ )
98
+
99
+ start_utc = local_start.astimezone(utc)
100
+ end_utc = local_end.astimezone(utc)
101
+
102
+ # track overlap
103
+ if start_utc > latest_start_utc:
104
+ latest_start_utc = start_utc
105
+ if end_utc < earliest_end_utc or earliest_end_utc == datetime.datetime.min.replace(
106
+ tzinfo=utc
107
+ ):
108
+ earliest_end_utc = end_utc
109
+
110
+ details.append(
111
+ f"{tz_name}: {local_start.strftime('%H:%M')}–{local_end.strftime('%H:%M')} "
112
+ f"(UTC {start_utc.strftime('%H:%M')}–{end_utc.strftime('%H:%M')})"
113
+ )
114
+
115
+ if earliest_end_utc <= latest_start_utc:
116
+ overlap_msg = "No common working window today."
117
+ else:
118
+ # Present the intersection in UTC and in each local zone for clarity
119
+ overlap_local = []
120
+ for tz_name in timezones:
121
+ tz = pytz.timezone(tz_name)
122
+ overlap_start_local = latest_start_utc.astimezone(tz).strftime("%H:%M")
123
+ overlap_end_local = earliest_end_utc.astimezone(tz).strftime("%H:%M")
124
+ overlap_local.append(f"{tz_name}: {overlap_start_local}–{overlap_end_local}")
125
+
126
+ overlap_msg = (
127
+ f"✅ Overlap (UTC): {latest_start_utc.strftime('%H:%M')}–"
128
+ f"{earliest_end_utc.strftime('%H:%M')}\n"
129
+ + "\n".join(overlap_local)
130
+ )
131
+
132
+ return (
133
+ "Daily office hours\n"
134
+ + "\n".join(details)
135
+ + "\n\n"
136
+ + overlap_msg
137
+ )
138
+ except Exception as exc:
139
+ return f"Error computing overlap: {exc}"
140
+
141
+
142
+ # --------------------------------------------------------------------------- #
143
+ # Required final-answer tool
144
+ final_answer = FinalAnswerTool()
145
+
146
+ # Inference model
147
+ model = InferenceClientModel(
148
+ max_tokens=2096,
149
+ temperature=0.5,
150
+ model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
151
+ custom_role_conversions=None,
152
  )
153
 
154
+ # Optional extra tool from the Hugging Face Hub
155
+ image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
156
+
157
+ # System prompt templates
158
+ with open("prompts.yaml", "r") as stream:
159
+ prompt_templates = yaml.safe_load(stream)
160
+
161
+ # Assemble the agent
162
+ agent = CodeAgent(
163
+ model=model,
164
+ tools=[
165
+ final_answer,
166
+ get_current_time_in_timezone,
167
+ find_overlapping_work_hours,
168
+ # my_custom_tool, # uncomment if you actually need it
169
+ # image_generation_tool, # idem
170
+ ],
171
+ max_steps=6,
172
+ verbosity_level=1,
173
+ grammar=None,
174
+ planning_interval=None,
175
+ name=None,
176
+ description=None,
177
+ prompt_templates=prompt_templates,
178
+ )
179
 
180
+ # Launch a small Gradio front-end
181
+ GradioUI(agent).launch()