graphsight-langgraph 0.1.2__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (16) hide show
  1. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/PKG-INFO +11 -5
  2. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/README.md +10 -4
  3. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph/github_ingest.py +37 -14
  4. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph/mapper.py +1 -0
  5. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/PKG-INFO +11 -5
  6. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/pyproject.toml +1 -1
  7. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/LICENSE +0 -0
  8. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph/__init__.py +0 -0
  9. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph/schema.py +0 -0
  10. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph/tracer.py +0 -0
  11. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/SOURCES.txt +0 -0
  12. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/dependency_links.txt +0 -0
  13. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/entry_points.txt +0 -0
  14. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/requires.txt +0 -0
  15. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/graphsight_langgraph.egg-info/top_level.txt +0 -0
  16. {graphsight_langgraph-0.1.2 → graphsight_langgraph-0.1.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphsight-langgraph
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: X-ray for LangGraph retrieval: one callback handler captures every retriever call, score, and relational path — rendered as an interactive graph.
5
5
  Author: Arush Karnatak
6
6
  License: MIT
@@ -94,14 +94,20 @@ graphsight-github-trace REPO [QUESTION] [options]
94
94
  | `--token` | `$GITHUB_TOKEN` | GitHub token. Required for private repositories; raises the rate limit on public ones. |
95
95
  | `--prs` | `25` | Recent pull requests to fetch. |
96
96
  | `--issues` | `25` | Recent issues to fetch. |
97
+ | `--commits` | `25` | Recent commits to fetch — solo repos with no PRs/issues still produce a full graph. |
97
98
  | `--top` | `10` | Items the retrieval keeps. |
98
99
  | `--out` | `graphsight_out/` | Output directory for `agent_trace.json` and `trace_state.json`. |
99
100
 
100
101
  Method note: the CLI builds a corpus with relational edges
101
- (`person AUTHORED pr`, `pr RESOLVES issue`, `pr TOUCHES repo`) and ranks by
102
- **lexical overlap with 1-hop graph expansion** — deliberately simple, and
103
- reported as such. The scores you see are exactly the scores computed;
104
- nothing is presented as semantic similarity.
102
+ (`person AUTHORED pr/commit`, `pr RESOLVES issue`, `pr TOUCHES repo`) and
103
+ ranks by **lexical overlap with 1-hop graph expansion** — deliberately
104
+ simple, and reported as such. The scores you see are exactly the scores
105
+ computed; nothing is presented as semantic similarity.
106
+
107
+ Ask it *who / what / when* questions ("who touched auth recently?", "which
108
+ issue needed two attempts?") — that's what commit and PR history can answer.
109
+ *How-does-it-work* questions need semantic retrieval over code and docs,
110
+ which this deliberately simple demo does not pretend to do.
105
111
 
106
112
  ## Tracing your own agent
107
113
 
@@ -67,14 +67,20 @@ graphsight-github-trace REPO [QUESTION] [options]
67
67
  | `--token` | `$GITHUB_TOKEN` | GitHub token. Required for private repositories; raises the rate limit on public ones. |
68
68
  | `--prs` | `25` | Recent pull requests to fetch. |
69
69
  | `--issues` | `25` | Recent issues to fetch. |
70
+ | `--commits` | `25` | Recent commits to fetch — solo repos with no PRs/issues still produce a full graph. |
70
71
  | `--top` | `10` | Items the retrieval keeps. |
71
72
  | `--out` | `graphsight_out/` | Output directory for `agent_trace.json` and `trace_state.json`. |
72
73
 
73
74
  Method note: the CLI builds a corpus with relational edges
74
- (`person AUTHORED pr`, `pr RESOLVES issue`, `pr TOUCHES repo`) and ranks by
75
- **lexical overlap with 1-hop graph expansion** — deliberately simple, and
76
- reported as such. The scores you see are exactly the scores computed;
77
- nothing is presented as semantic similarity.
75
+ (`person AUTHORED pr/commit`, `pr RESOLVES issue`, `pr TOUCHES repo`) and
76
+ ranks by **lexical overlap with 1-hop graph expansion** — deliberately
77
+ simple, and reported as such. The scores you see are exactly the scores
78
+ computed; nothing is presented as semantic similarity.
79
+
80
+ Ask it *who / what / when* questions ("who touched auth recently?", "which
81
+ issue needed two attempts?") — that's what commit and PR history can answer.
82
+ *How-does-it-work* questions need semantic retrieval over code and docs,
83
+ which this deliberately simple demo does not pretend to do.
78
84
 
79
85
  ## Tracing your own agent
80
86
 
@@ -33,7 +33,7 @@ _STOP = {
33
33
  }
34
34
 
35
35
  # tie-break on equal lexical score: substantive artifacts over boilerplate
36
- _KIND_PRIORITY = {"pull_request": 3, "ticket": 2, "repo": 1, "person": 0}
36
+ _KIND_PRIORITY = {"pull_request": 4, "commit": 3, "ticket": 2, "repo": 1, "person": 0}
37
37
 
38
38
 
39
39
  # github fetch, stdlib only
@@ -65,7 +65,9 @@ def _excerpt(text: Optional[str], limit: int = 400) -> str:
65
65
 
66
66
 
67
67
  # corpus
68
- def build_corpus(repo: str, token: Optional[str], n_prs: int, n_issues: int) -> list[Document]:
68
+ def build_corpus(
69
+ repo: str, token: Optional[str], n_prs: int, n_issues: int, n_commits: int
70
+ ) -> list[Document]:
69
71
  owner_name = repo.split("/")[-1]
70
72
  meta = _get(f"/repos/{repo}", token)
71
73
  repo_id = f"repo_{owner_name}"
@@ -119,15 +121,34 @@ def build_corpus(repo: str, token: Optional[str], n_prs: int, n_issues: int) ->
119
121
  ))
120
122
  authored.setdefault(login, [])
121
123
 
122
- for login, pr_ids in authored.items():
124
+ # solo repos often have no PRs/issues at all — commits carry the history
125
+ commits = _get(f"/repos/{repo}/commits?per_page={n_commits}", token) if n_commits else []
126
+ for c in commits:
127
+ sha = c["sha"][:7]
128
+ login = (c.get("author") or {}).get("login") or (c.get("commit", {}).get("author") or {}).get("name") or "unknown"
129
+ commit_id = f"commit_{sha}"
130
+ message = c.get("commit", {}).get("message") or ""
131
+ edges = [{"source": commit_id, "target": repo_id, "relation": "TOUCHES", "weight": 0.6},
132
+ {"source": f"person_{login}", "target": commit_id, "relation": "AUTHORED", "weight": 0.9}]
133
+ for ref in _RESOLVE_RE.findall(message):
134
+ edges.append({"source": commit_id, "target": f"tkt_{ref}", "relation": "RESOLVES", "weight": 0.8})
135
+ summary = _excerpt(message.splitlines()[0] if message else sha, 48)
123
136
  docs.append(Document(
124
- page_content=f"GitHub user {login} — authored {len(pr_ids)} of the "
125
- f"last {len(prs)} pull requests in {repo}.",
137
+ page_content=_excerpt(f"Commit {sha} by {login}: {message}"),
138
+ metadata={"id": commit_id, "label": summary, "kind": "commit",
139
+ "source": c.get("html_url"), "edges": edges},
140
+ ))
141
+ authored.setdefault(login, []).append(commit_id)
142
+
143
+ for login, work_ids in authored.items():
144
+ docs.append(Document(
145
+ page_content=f"GitHub user {login} — authored {len(work_ids)} of the "
146
+ f"recent changes (PRs/commits) in {repo}.",
126
147
  metadata={"id": f"person_{login}", "label": login, "kind": "person",
127
148
  "source": f"https://github.com/{login}",
128
149
  # carried on both endpoints; the tracer dedups per retrieval
129
- "edges": [{"source": f"person_{login}", "target": pid,
130
- "relation": "AUTHORED", "weight": 0.9} for pid in pr_ids]},
150
+ "edges": [{"source": f"person_{login}", "target": wid,
151
+ "relation": "AUTHORED", "weight": 0.9} for wid in work_ids]},
131
152
  ))
132
153
  return docs
133
154
 
@@ -180,11 +201,12 @@ class LexicalGraphRetriever(BaseRetriever):
180
201
  for score, doc in sorted(kept.values(), key=lambda pair: pair[0], reverse=True):
181
202
  edges = [e for e in doc.metadata.get("edges", [])
182
203
  if e["source"] in kept and e["target"] in kept]
183
- out.append(Document(
184
- page_content=doc.page_content,
185
- metadata={**{k: v for k, v in doc.metadata.items() if k != "edges"},
186
- "score": score, "edges": edges},
187
- ))
204
+ meta = {k: v for k, v in doc.metadata.items() if k != "edges"}
205
+ # zero overlap means "here because of its edges, not the query" —
206
+ # no score is more honest than a 0.00 chip
207
+ if score > 0:
208
+ meta["score"] = score
209
+ out.append(Document(page_content=doc.page_content, metadata={**meta, "edges": edges}))
188
210
  return out
189
211
 
190
212
 
@@ -253,6 +275,7 @@ def main(argv: Optional[list[str]] = None) -> None:
253
275
  help="GitHub token (or set GITHUB_TOKEN); needed for private repos")
254
276
  parser.add_argument("--prs", type=int, default=25, help="recent PRs to fetch (default 25)")
255
277
  parser.add_argument("--issues", type=int, default=25, help="recent issues to fetch (default 25)")
278
+ parser.add_argument("--commits", type=int, default=25, help="recent commits to fetch (default 25)")
256
279
  parser.add_argument("--top", type=int, default=10, help="items to retrieve (default 10)")
257
280
  parser.add_argument("--out", type=Path, default=Path("graphsight_out"), help="output directory")
258
281
  args = parser.parse_args(argv)
@@ -261,8 +284,8 @@ def main(argv: Optional[list[str]] = None) -> None:
261
284
  parser.error("repo must be owner/name")
262
285
  question = args.question or f"What changed recently in {args.repo}, and who drove it?"
263
286
 
264
- print(f"fetching {args.repo} (last {args.prs} PRs, {args.issues} issues)…", file=sys.stderr)
265
- corpus = build_corpus(args.repo, args.token, args.prs, args.issues)
287
+ print(f"fetching {args.repo} (last {args.prs} PRs, {args.issues} issues, {args.commits} commits)…", file=sys.stderr)
288
+ corpus = build_corpus(args.repo, args.token, args.prs, args.issues, args.commits)
266
289
  print(f"corpus : {len(corpus)} documents", file=sys.stderr)
267
290
 
268
291
  trace = run_traced(corpus, question, args.repo, args.top)
@@ -20,6 +20,7 @@ _KIND_TO_ENTITY = {
20
20
  "document": "Document",
21
21
  "doc": "Document",
22
22
  "chunk": "Document",
23
+ "commit": "Commit",
23
24
  "repo": "Repo",
24
25
  "repository": "Repo",
25
26
  "branch": "Repo",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphsight-langgraph
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: X-ray for LangGraph retrieval: one callback handler captures every retriever call, score, and relational path — rendered as an interactive graph.
5
5
  Author: Arush Karnatak
6
6
  License: MIT
@@ -94,14 +94,20 @@ graphsight-github-trace REPO [QUESTION] [options]
94
94
  | `--token` | `$GITHUB_TOKEN` | GitHub token. Required for private repositories; raises the rate limit on public ones. |
95
95
  | `--prs` | `25` | Recent pull requests to fetch. |
96
96
  | `--issues` | `25` | Recent issues to fetch. |
97
+ | `--commits` | `25` | Recent commits to fetch — solo repos with no PRs/issues still produce a full graph. |
97
98
  | `--top` | `10` | Items the retrieval keeps. |
98
99
  | `--out` | `graphsight_out/` | Output directory for `agent_trace.json` and `trace_state.json`. |
99
100
 
100
101
  Method note: the CLI builds a corpus with relational edges
101
- (`person AUTHORED pr`, `pr RESOLVES issue`, `pr TOUCHES repo`) and ranks by
102
- **lexical overlap with 1-hop graph expansion** — deliberately simple, and
103
- reported as such. The scores you see are exactly the scores computed;
104
- nothing is presented as semantic similarity.
102
+ (`person AUTHORED pr/commit`, `pr RESOLVES issue`, `pr TOUCHES repo`) and
103
+ ranks by **lexical overlap with 1-hop graph expansion** — deliberately
104
+ simple, and reported as such. The scores you see are exactly the scores
105
+ computed; nothing is presented as semantic similarity.
106
+
107
+ Ask it *who / what / when* questions ("who touched auth recently?", "which
108
+ issue needed two attempts?") — that's what commit and PR history can answer.
109
+ *How-does-it-work* questions need semantic retrieval over code and docs,
110
+ which this deliberately simple demo does not pretend to do.
105
111
 
106
112
  ## Tracing your own agent
107
113
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "graphsight-langgraph"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "X-ray for LangGraph retrieval: one callback handler captures every retriever call, score, and relational path — rendered as an interactive graph."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"