AdithyaVardan commited on
Commit
ed33951
Β·
1 Parent(s): 2d6f17a

Fix lazy token loading in tools, add github_list_commits tool, load_dotenv in main

Browse files
main.py CHANGED
@@ -1,4 +1,6 @@
1
  import logging
 
 
2
 
3
  from contextlib import asynccontextmanager
4
 
 
1
  import logging
2
+ from dotenv import load_dotenv
3
+ load_dotenv()
4
 
5
  from contextlib import asynccontextmanager
6
 
toolsforgitnotionslack/tools/github_tools.py CHANGED
@@ -4,21 +4,19 @@ GitHub tools β€” discovery-first, markdown-only reads, paginated, rate-limit awa
4
  import os
5
  import httpx
6
 
7
- GH = "https://api.github.com"
8
- GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "")
9
- GITHUB_REPO = os.environ.get("GITHUB_REPO", "")
10
 
11
 
12
  def _headers() -> dict:
13
  return {
14
- "Authorization": f"Bearer {GITHUB_TOKEN}",
15
  "Accept": "application/vnd.github+json",
16
  "X-GitHub-Api-Version": "2022-11-28",
17
  }
18
 
19
 
20
  def _target(repo: str) -> str:
21
- return repo or GITHUB_REPO
22
 
23
 
24
  def _rate_warn(resp: httpx.Response) -> str | None:
@@ -170,6 +168,31 @@ async def github_list_markdown_files(repo: str = "", folder: str = "") -> str:
170
  return f"[{t}] {len(items)} markdown file(s):\n" + "\n".join(f"β€’ {i['path']}" for i in items)
171
 
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  # ── Registry ───────────────────────────────────────────────────────────────────
174
 
175
  GITHUB_TOOL_FNS = {
@@ -179,6 +202,7 @@ GITHUB_TOOL_FNS = {
179
  "github_read_file": github_read_file,
180
  "github_search_code": github_search_code,
181
  "github_list_markdown_files": github_list_markdown_files,
 
182
  }
183
 
184
  GITHUB_TOOLS = [
@@ -253,4 +277,17 @@ GITHUB_TOOLS = [
253
  "repo": {"type": "string"}, "folder": {"type": "string"},
254
  }},
255
  }},
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  ]
 
4
  import os
5
  import httpx
6
 
7
+ GH = "https://api.github.com"
 
 
8
 
9
 
10
  def _headers() -> dict:
11
  return {
12
+ "Authorization": f"Bearer {os.environ.get('GITHUB_TOKEN', '')}",
13
  "Accept": "application/vnd.github+json",
14
  "X-GitHub-Api-Version": "2022-11-28",
15
  }
16
 
17
 
18
  def _target(repo: str) -> str:
19
+ return repo or os.environ.get("GITHUB_REPO", "")
20
 
21
 
22
  def _rate_warn(resp: httpx.Response) -> str | None:
 
168
  return f"[{t}] {len(items)} markdown file(s):\n" + "\n".join(f"β€’ {i['path']}" for i in items)
169
 
170
 
171
+ async def github_list_commits(repo: str = "", branch: str = "", page: int = 1) -> str:
172
+ t = _target(repo)
173
+ if not t: return "Provide repo as 'owner/repo' or set GITHUB_REPO."
174
+ params = {"per_page": 20, "page": page}
175
+ if branch:
176
+ params["sha"] = branch
177
+ async with httpx.AsyncClient(timeout=15) as h:
178
+ r = await h.get(f"{GH}/repos/{t}/commits", headers=_headers(), params=params)
179
+ if w := _rate_warn(r): return w
180
+ if r.status_code == 404: return f"Repo not found: {t}"
181
+ if r.status_code != 200: return f"GitHub error {r.status_code}: {r.text[:200]}"
182
+ commits = r.json()
183
+ if not commits: return "No commits found."
184
+ lines = []
185
+ for c in commits:
186
+ sha = c["sha"][:7]
187
+ msg = c["commit"]["message"].split("\n")[0][:80]
188
+ author = c["commit"]["author"]["name"]
189
+ date = c["commit"]["author"]["date"][:10]
190
+ lines.append(f"β€’ {sha} {date} {author}: {msg}")
191
+ if len(commits) == 20:
192
+ lines.append(f"[Page {page} β€” call with page={page+1} for more]")
193
+ return "\n".join(lines)
194
+
195
+
196
  # ── Registry ───────────────────────────────────────────────────────────────────
197
 
198
  GITHUB_TOOL_FNS = {
 
202
  "github_read_file": github_read_file,
203
  "github_search_code": github_search_code,
204
  "github_list_markdown_files": github_list_markdown_files,
205
+ "github_list_commits": github_list_commits,
206
  }
207
 
208
  GITHUB_TOOLS = [
 
277
  "repo": {"type": "string"}, "folder": {"type": "string"},
278
  }},
279
  }},
280
+ {"type": "function", "function": {
281
+ "name": "github_list_commits",
282
+ "description": (
283
+ "List recent commits in a GitHub repo. "
284
+ "Use this when asked about recent changes, commit history, or who changed what. "
285
+ "Returns SHA, date, author, and commit message for each commit."
286
+ ),
287
+ "parameters": {"type": "object", "properties": {
288
+ "repo": {"type": "string", "description": "owner/repo"},
289
+ "branch": {"type": "string", "description": "Branch name, default is the repo default branch"},
290
+ "page": {"type": "integer", "description": "Page number, default 1"},
291
+ }},
292
+ }},
293
  ]
toolsforgitnotionslack/tools/notion_tools.py CHANGED
@@ -3,15 +3,12 @@ Notion tools β€” search, read pages, list and query databases.
3
  """
4
  import os
5
  import httpx
6
- from dotenv import load_dotenv
7
- load_dotenv()
8
- NOTION_TOKEN = os.environ.get("NOTION_API_TOKEN", "")
9
-
10
- NOTION_HEADERS = {
11
- "Authorization": f"Bearer {NOTION_TOKEN}",
12
- "Notion-Version": "2022-06-28",
13
- "Content-Type": "application/json",
14
- }
15
 
16
 
17
  def _extract_rich_text(rt: list) -> str:
@@ -24,7 +21,7 @@ async def notion_search(query: str, filter_type: str = "") -> str:
24
  body["filter"] = {"value": filter_type, "property": "object"}
25
  async with httpx.AsyncClient(timeout=15) as h:
26
  r = await h.post("https://api.notion.com/v1/search",
27
- headers=NOTION_HEADERS, json=body)
28
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
29
  results = r.json().get("results", [])
30
  if not results: return "No Notion pages or databases found."
@@ -49,7 +46,7 @@ async def notion_read_page(page_id: str, max_blocks: int = 80) -> str:
49
  async with httpx.AsyncClient(timeout=15) as h:
50
  r = await h.get(
51
  f"https://api.notion.com/v1/blocks/{page_id}/children",
52
- headers=NOTION_HEADERS,
53
  params={"page_size": max_blocks},
54
  )
55
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
@@ -91,7 +88,7 @@ async def notion_list_databases(query: str = "") -> str:
91
  if query: body["query"] = query
92
  async with httpx.AsyncClient(timeout=15) as h:
93
  r = await h.post("https://api.notion.com/v1/search",
94
- headers=NOTION_HEADERS, json=body)
95
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
96
  results = r.json().get("results", [])
97
  if not results: return "No databases found."
@@ -112,7 +109,7 @@ async def notion_query_database(database_id: str, filter_property: str = "",
112
  async with httpx.AsyncClient(timeout=15) as h:
113
  r = await h.post(
114
  f"https://api.notion.com/v1/databases/{database_id}/query",
115
- headers=NOTION_HEADERS, json=body,
116
  )
117
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
118
  results = r.json().get("results", [])
 
3
  """
4
  import os
5
  import httpx
6
+ def _notion_headers() -> dict:
7
+ return {
8
+ "Authorization": f"Bearer {os.environ.get('NOTION_API_TOKEN', '')}",
9
+ "Notion-Version": "2022-06-28",
10
+ "Content-Type": "application/json",
11
+ }
 
 
 
12
 
13
 
14
  def _extract_rich_text(rt: list) -> str:
 
21
  body["filter"] = {"value": filter_type, "property": "object"}
22
  async with httpx.AsyncClient(timeout=15) as h:
23
  r = await h.post("https://api.notion.com/v1/search",
24
+ headers=_notion_headers(), json=body)
25
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
26
  results = r.json().get("results", [])
27
  if not results: return "No Notion pages or databases found."
 
46
  async with httpx.AsyncClient(timeout=15) as h:
47
  r = await h.get(
48
  f"https://api.notion.com/v1/blocks/{page_id}/children",
49
+ headers=_notion_headers(),
50
  params={"page_size": max_blocks},
51
  )
52
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
 
88
  if query: body["query"] = query
89
  async with httpx.AsyncClient(timeout=15) as h:
90
  r = await h.post("https://api.notion.com/v1/search",
91
+ headers=_notion_headers(), json=body)
92
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
93
  results = r.json().get("results", [])
94
  if not results: return "No databases found."
 
109
  async with httpx.AsyncClient(timeout=15) as h:
110
  r = await h.post(
111
  f"https://api.notion.com/v1/databases/{database_id}/query",
112
+ headers=_notion_headers(), json=body,
113
  )
114
  if r.status_code != 200: return f"Notion error {r.status_code}: {r.text[:300]}"
115
  results = r.json().get("results", [])
toolsforgitnotionslack/tools/slack_tools.py CHANGED
@@ -4,11 +4,8 @@ Slack tools β€” search, history, threads, channel metadata.
4
  import os
5
  import httpx
6
 
7
- SLACK_TOKEN = os.environ.get("SLACK_BOT_TOKEN", "")
8
-
9
-
10
  def _headers() -> dict:
11
- return {"Authorization": f"Bearer {SLACK_TOKEN}"}
12
 
13
 
14
  async def slack_list_channels(filter_name: str = "") -> str:
 
4
  import os
5
  import httpx
6
 
 
 
 
7
  def _headers() -> dict:
8
+ return {"Authorization": f"Bearer {os.environ.get('SLACK_BOT_TOKEN', '')}"}
9
 
10
 
11
  async def slack_list_channels(filter_name: str = "") -> str: