risenlab-agentlogs 0.2__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.
@@ -0,0 +1,4 @@
1
+ __pycache__/
2
+ dist/
3
+ *.egg-info/
4
+ .venv
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RISEN Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.5
2
+ Name: risenlab-agentlogs
3
+ Version: 0.2
4
+ Summary: Schema definitions and utilities for the AgentLogs dataset
5
+ Project-URL: Homepage, https://github.com/risenlab/agentlogs
6
+ Project-URL: Documentation, https://github.com/risenlab/agentlogs/tree/main/docs/schema
7
+ Project-URL: Dataset, https://huggingface.co/datasets/risenlab/agentlogs
8
+ Author: RISEN Lab
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agentlogs,copilot,dataset,github,schema
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.12
16
+ Description-Content-Type: text/markdown
17
+
18
+ # AgentLogs
19
+
20
+ [![version 0.2](https://img.shields.io/badge/version-0.2-blue)](https://huggingface.co/datasets/risenlab/agentlogs/tree/v0.2)
21
+ [![Hugging Face](https://img.shields.io/badge/Hugging%20Face-dataset-ffd21e?logo=huggingface&logoColor=ffd21e)](https://huggingface.co/datasets/risenlab/agentlogs)
22
+ [![GitHub](https://img.shields.io/badge/GitHub-code-black?logo=github)](https://github.com/risenlab/agentlogs)
23
+
24
+ TypedDict schema and helpers for the [AgentLogs](https://huggingface.co/datasets/risenlab/agentlogs) dataset. Field-level documentation: [schema reference](https://github.com/risenlab/agentlogs/tree/v0.2/docs/schema).
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install risenlab-agentlogs huggingface_hub pyarrow
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```python
35
+ from pathlib import Path
36
+
37
+ import pyarrow.parquet as pq
38
+ from huggingface_hub import snapshot_download
39
+ from agentlogs.schema import AgentSession, assert_dataset_version, cast_record
40
+
41
+ # Full dataset into data/dataset/; existing files are skipped
42
+ dataset_path = Path("data") / "dataset"
43
+ snapshot_download(
44
+ repo_id="risenlab/agentlogs",
45
+ repo_type="dataset",
46
+ revision="v0.2",
47
+ local_dir=dataset_path,
48
+ )
49
+ # Fail if the snapshot tag does not match this package version
50
+ assert_dataset_version(dataset_path)
51
+
52
+ # First session row, typed as AgentSession (nested fields included)
53
+ session_file = next((dataset_path / "agent_sessions").glob("*.parquet"))
54
+ session = cast_record(
55
+ AgentSession,
56
+ pq.read_table(session_file, memory_map=False).slice(0, 1).to_pylist()[0],
57
+ )
58
+ print(session["id"], session["name"])
59
+ ```
@@ -0,0 +1,42 @@
1
+ # AgentLogs
2
+
3
+ [![version 0.2](https://img.shields.io/badge/version-0.2-blue)](https://huggingface.co/datasets/risenlab/agentlogs/tree/v0.2)
4
+ [![Hugging Face](https://img.shields.io/badge/Hugging%20Face-dataset-ffd21e?logo=huggingface&logoColor=ffd21e)](https://huggingface.co/datasets/risenlab/agentlogs)
5
+ [![GitHub](https://img.shields.io/badge/GitHub-code-black?logo=github)](https://github.com/risenlab/agentlogs)
6
+
7
+ TypedDict schema and helpers for the [AgentLogs](https://huggingface.co/datasets/risenlab/agentlogs) dataset. Field-level documentation: [schema reference](https://github.com/risenlab/agentlogs/tree/v0.2/docs/schema).
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install risenlab-agentlogs huggingface_hub pyarrow
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```python
18
+ from pathlib import Path
19
+
20
+ import pyarrow.parquet as pq
21
+ from huggingface_hub import snapshot_download
22
+ from agentlogs.schema import AgentSession, assert_dataset_version, cast_record
23
+
24
+ # Full dataset into data/dataset/; existing files are skipped
25
+ dataset_path = Path("data") / "dataset"
26
+ snapshot_download(
27
+ repo_id="risenlab/agentlogs",
28
+ repo_type="dataset",
29
+ revision="v0.2",
30
+ local_dir=dataset_path,
31
+ )
32
+ # Fail if the snapshot tag does not match this package version
33
+ assert_dataset_version(dataset_path)
34
+
35
+ # First session row, typed as AgentSession (nested fields included)
36
+ session_file = next((dataset_path / "agent_sessions").glob("*.parquet"))
37
+ session = cast_record(
38
+ AgentSession,
39
+ pq.read_table(session_file, memory_map=False).slice(0, 1).to_pylist()[0],
40
+ )
41
+ print(session["id"], session["name"])
42
+ ```
@@ -0,0 +1,31 @@
1
+ [project]
2
+ name = "risenlab-agentlogs"
3
+ dynamic = ["version"]
4
+ description = "Schema definitions and utilities for the AgentLogs dataset"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.12"
9
+ authors = [{ name = "RISEN Lab" }]
10
+ keywords = ["agentlogs", "github", "copilot", "dataset", "schema"]
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.12",
14
+ "Typing :: Typed",
15
+ ]
16
+ dependencies = []
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/risenlab/agentlogs"
20
+ Documentation = "https://github.com/risenlab/agentlogs/tree/main/docs/schema"
21
+ Dataset = "https://huggingface.co/datasets/risenlab/agentlogs"
22
+
23
+ [build-system]
24
+ requires = ["hatchling>=1.27"]
25
+ build-backend = "hatchling.build"
26
+
27
+ [tool.hatch.version]
28
+ path = "src/agentlogs/schema/__init__.py"
29
+
30
+ [tool.hatch.build.targets.wheel]
31
+ packages = ["src/agentlogs"]
@@ -0,0 +1,91 @@
1
+ __version__ = "0.2"
2
+
3
+ from pathlib import Path
4
+
5
+ from .types.agent_session import (
6
+ AgentSession,
7
+ AgentSessionUsage,
8
+ AgentSessionEvent,
9
+ )
10
+ from .types.agent_task import (
11
+ AgentArtifactReference,
12
+ AgentTask,
13
+ AgentTaskData,
14
+ CustomAgentReference,
15
+ )
16
+ from .types.repository import (
17
+ Repository,
18
+ RepositoryMetric,
19
+ )
20
+ from .types.user import (
21
+ User,
22
+ )
23
+ from .types.references import (
24
+ AgentSessionReference,
25
+ AgentTaskReference,
26
+ RepositoryReference,
27
+ UserReference,
28
+ AgentReference,
29
+ PullRequestIDReference,
30
+ PullRequestReference,
31
+ BranchReference,
32
+ )
33
+ from .types.agent_session_log import (
34
+ AgentSessionLogEntry,
35
+ AgentSessionLogEntryData,
36
+ )
37
+ from .cast import cast_record
38
+
39
+
40
+ class DatasetVersionError(ValueError):
41
+ pass
42
+
43
+
44
+ def assert_version(version: str) -> None:
45
+ version = version.removeprefix("v")
46
+ if version != __version__:
47
+ raise DatasetVersionError(
48
+ f"Dataset version {version} does not match schema {__version__}. "
49
+ f"Install risenlab-agentlogs {version} or snapshot revision v{__version__}."
50
+ )
51
+
52
+
53
+ def assert_dataset_version(dataset_path: str | Path) -> None:
54
+ assert_version(Path(dataset_path).joinpath("VERSION").read_text().strip())
55
+
56
+
57
+ __all__ = [
58
+ "AgentSession",
59
+ "AgentSessionUsage",
60
+ "AgentSessionEvent",
61
+
62
+ "AgentSessionLogEntry",
63
+ "AgentSessionLogEntryData",
64
+
65
+ "AgentArtifactReference",
66
+ "PullRequestReference",
67
+ "BranchReference",
68
+ "AgentTask",
69
+ "AgentTaskData",
70
+ "CustomAgentReference",
71
+ "PullRequestIDReference",
72
+ "PullRequestReference",
73
+ "BranchReference",
74
+
75
+ "Repository",
76
+ "RepositoryMetric",
77
+
78
+ "User",
79
+
80
+ "AgentSessionReference",
81
+ "AgentTaskReference",
82
+ "RepositoryReference",
83
+ "UserReference",
84
+ "AgentReference",
85
+
86
+ "cast_record",
87
+ "DatasetVersionError",
88
+ "assert_dataset_version",
89
+ "assert_version",
90
+ "__version__",
91
+ ]
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as dt
4
+ from typing import Any, Mapping, TypeVar, cast
5
+
6
+ from .types.agent_session import AgentSession
7
+ from .types.agent_session_log import AgentSessionLogEntry
8
+ from .types.agent_task import AgentTask
9
+ from .types.repository import Repository
10
+ from .types.user import User
11
+
12
+ T = TypeVar("T", bound=Mapping[str, Any])
13
+
14
+ TABLE_TYPES = frozenset(
15
+ {
16
+ Repository,
17
+ AgentTask,
18
+ AgentSession,
19
+ AgentSessionLogEntry,
20
+ User,
21
+ }
22
+ )
23
+
24
+ def cast_record(cls: type[T], row: Mapping[str, Any]) -> T:
25
+ if cls not in TABLE_TYPES:
26
+ raise TypeError("cast_record only supports Repository, AgentTask, AgentSession, AgentSessionLogEntry, and User")
27
+
28
+ record = cast(dict[str, Any], row)
29
+
30
+ if cls is Repository:
31
+ for key in ("created_at", "pushed_at", "updated_at", "last_commit_at"):
32
+ value = record.get(key)
33
+ if isinstance(value, dt.datetime) and value.tzinfo is None:
34
+ record[key] = value.replace(tzinfo=dt.timezone.utc)
35
+
36
+ languages = record.get("languages")
37
+ if isinstance(languages, list):
38
+ if not languages:
39
+ record["languages"] = {}
40
+ elif isinstance(languages[0], dict):
41
+ record["languages"] = {entry["key"]: entry["value"] for entry in languages}
42
+ else:
43
+ record["languages"] = dict(languages)
44
+
45
+ elif cls is AgentTask:
46
+ data = record.get("data")
47
+ if isinstance(data, dict):
48
+ for key in ("created_at", "updated_at", "archived_at"):
49
+ value = data.get(key)
50
+ if isinstance(value, dt.datetime) and value.tzinfo is None:
51
+ data[key] = value.replace(tzinfo=dt.timezone.utc)
52
+
53
+ elif cls is AgentSession:
54
+ for key in ("created_at", "updated_at", "completed_at"):
55
+ value = record.get(key)
56
+ if isinstance(value, dt.datetime) and value.tzinfo is None:
57
+ record[key] = value.replace(tzinfo=dt.timezone.utc)
58
+
59
+ elif cls is AgentSessionLogEntry:
60
+ data = record.get("data")
61
+ if isinstance(data, dict):
62
+ created = data.get("created")
63
+ if isinstance(created, dt.datetime) and created.tzinfo is None:
64
+ data["created"] = created.replace(tzinfo=dt.timezone.utc)
65
+
66
+ return cast(T, record)
File without changes
@@ -0,0 +1,50 @@
1
+ import datetime as dt
2
+ from typing import Annotated, TypedDict
3
+
4
+ from .annotation import GitHubField, Relation
5
+ from .references import (
6
+ AgentTaskReference,
7
+ BranchReference,
8
+ PullRequestReference,
9
+ UserReference,
10
+ )
11
+
12
+ class AgentSessionUsage(TypedDict):
13
+ type: Annotated[str, GitHubField("type")]
14
+ amount: Annotated[float | None, GitHubField("amount")]
15
+ credits: Annotated[float | None, GitHubField("credits")]
16
+
17
+ class AgentSessionEvent(TypedDict):
18
+ type: Annotated[str | None, GitHubField("event_type")]
19
+ url: Annotated[str | None, GitHubField("event_url")]
20
+ ids: Annotated[list[str] | None, GitHubField("event_identifiers")]
21
+ content: Annotated[str | None, GitHubField("event_content")]
22
+
23
+ class AgentSession(TypedDict):
24
+ id: Annotated[str, GitHubField("id")]
25
+
26
+ task: Annotated[AgentTaskReference, Relation()]
27
+ log_found: bool
28
+
29
+ user: Annotated[
30
+ UserReference,
31
+ GitHubField("user", leaves={"id": "id", "login": "login"}),
32
+ ]
33
+
34
+ name: Annotated[str, GitHubField("name")]
35
+ model: Annotated[str | None, GitHubField("model")]
36
+ prompt: Annotated[str | None, GitHubField("prompt")]
37
+ state: Annotated[str, GitHubField("state")]
38
+ usage: Annotated[AgentSessionUsage | None, GitHubField("usage")]
39
+ premium_requests: Annotated[float, GitHubField("premium_requests")]
40
+ error: Annotated[str | None, GitHubField("error.message")]
41
+ remote_steerable: Annotated[bool | None, GitHubField("remote_steerable")]
42
+ workflow_run_id: Annotated[int | None, GitHubField("workflow_run_id")]
43
+
44
+ event: AgentSessionEvent
45
+ pull_request: PullRequestReference | None
46
+ branch: BranchReference | None
47
+
48
+ created_at: Annotated[dt.datetime, GitHubField("created_at")]
49
+ updated_at: Annotated[dt.datetime, GitHubField("updated_at")]
50
+ completed_at: Annotated[dt.datetime | None, GitHubField("completed_at")]
@@ -0,0 +1,225 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as dt
4
+ from typing import Annotated, TypedDict
5
+
6
+ from .annotation import GitHubField, Note, Relation
7
+ from .references import AgentSessionReference
8
+
9
+ class AgentSessionLogEntry(TypedDict):
10
+ session: Annotated[AgentSessionReference, Relation()]
11
+ entry_index: int
12
+
13
+ parsed: bool
14
+ raw: Annotated[
15
+ str | None,
16
+ Note("Not set when `parsed` is true"),
17
+ ]
18
+ data: Annotated[
19
+ AgentSessionLogEntryData | None,
20
+ GitHubField(""),
21
+ Note("Not set when `parsed` is false. Refer to `raw` instead"),
22
+ ]
23
+
24
+ class AgentSessionLogEntryData(TypedDict):
25
+ id: Annotated[str | None, GitHubField("id")]
26
+ agentId: Annotated[str | None, GitHubField("agentId")]
27
+ arguments: ToolArguments | None
28
+ callId: Annotated[str | None, GitHubField("callId")]
29
+ choices: list[Choice] | None
30
+ content: list[ContentPart] | None
31
+ copilotBillingMetadata: CopilotBillingMetadata | None
32
+ copilot_info_messages: Annotated[list[CopilotInfoMessage] | None, GitHubField("copilot_info_messages")]
33
+ copilot_model_warning_message: Annotated[str | None, GitHubField("copilot_model_warning_message")]
34
+ copilot_usage: CopilotUsage | None
35
+ copilot_warning_messages: Annotated[list[CopilotWarningMessage] | None, GitHubField("copilot_warning_messages")]
36
+ created: Annotated[dt.datetime | None, GitHubField("created")]
37
+ data: EventData | None
38
+ ephemeral: Annotated[bool | None, GitHubField("ephemeral")]
39
+ error: ErrorInfo | None
40
+ kind: Annotated[str | None, GitHubField("kind")]
41
+ model: Annotated[str | None, GitHubField("model")]
42
+ modelCall_error: Annotated[str | None, GitHubField("modelCall.error")]
43
+ modelCallDurationMs: Annotated[int | None, GitHubField("modelCallDurationMs")]
44
+ object: Annotated[str | None, GitHubField("object")]
45
+ output: Annotated[str | None, GitHubField("output")]
46
+ parentId: Annotated[str | None, GitHubField("parentId")]
47
+ performedBy: Annotated[str | None, GitHubField("performedBy")]
48
+ prompt_filter_results: list[PromptFilterResult] | None
49
+ role: Annotated[str | None, GitHubField("role")]
50
+ source: Annotated[str | None, GitHubField("source")]
51
+ system_fingerprint: Annotated[str | None, GitHubField("system_fingerprint")]
52
+ timestamp: Annotated[str | None, GitHubField("timestamp")]
53
+ toolCallId: Annotated[str | None, GitHubField("toolCallId")]
54
+ toolName: Annotated[str | None, GitHubField("toolName")]
55
+ tool_call_id: Annotated[str | None, GitHubField("tool_call_id")]
56
+ truncateResult: TruncateResult | None
57
+ turn: Annotated[int | None, GitHubField("turn")]
58
+ type: Annotated[str | None, GitHubField("type")]
59
+ usage: Usage | None
60
+
61
+ class ContentFilterCategory(TypedDict):
62
+ filtered: bool
63
+ severity: str
64
+
65
+ class ContentFilterResults(TypedDict):
66
+ hate: ContentFilterCategory | None
67
+ self_harm: ContentFilterCategory | None
68
+ sexual: ContentFilterCategory | None
69
+ violence: ContentFilterCategory | None
70
+
71
+ class PromptFilterResult(TypedDict):
72
+ prompt_index: int
73
+ content_filter_results: ContentFilterResults
74
+
75
+ class IPCitation(TypedDict):
76
+ citation_type: str | None
77
+ ip_type: str
78
+ license: str
79
+ snippet: str
80
+ url: str
81
+
82
+ class IPCitationEntry(TypedDict):
83
+ citations: IPCitation
84
+ end_offset: int
85
+ id: int
86
+ start_offset: int | None
87
+
88
+ class CopilotAnnotations(TypedDict):
89
+ IPCodeCitations: list[IPCitationEntry] | None
90
+ raw: str | None
91
+
92
+ class DeltaToolCall(TypedDict):
93
+ function_name: str | None
94
+ function_arguments: str | None
95
+ custom_name: str | None
96
+ custom_input: str | None
97
+ id: str | None
98
+ index: int | None
99
+ type: str | None
100
+
101
+ class MessageToolCall(TypedDict):
102
+ function_name: str | None
103
+ function_arguments: str | None
104
+ id: str | None
105
+ type: str | None
106
+
107
+ class Delta(TypedDict):
108
+ content: str | None
109
+ copilot_annotations: CopilotAnnotations | None
110
+ encrypted_content: str | None
111
+ padding: str | None
112
+ phase: str | None
113
+ reasoning_opaque: str | None
114
+ reasoning_text: str | None
115
+ role: str | None
116
+ tool_calls: list[DeltaToolCall] | None
117
+
118
+ class Message(TypedDict):
119
+ content: str | None
120
+ role: str | None
121
+ tool_calls: list[MessageToolCall] | None
122
+
123
+ class Choice(TypedDict):
124
+ content_filter_results: ContentFilterResults | None
125
+ delta: Delta
126
+ finish_reason: str | None
127
+ index: int | None
128
+ message: Message | None
129
+
130
+
131
+ class ToolArguments(TypedDict):
132
+ canOfferSessionApproval: bool | None
133
+ command: str | None
134
+ description: str | None
135
+ diff: str | None
136
+ filePath: str | None
137
+ kind: str | None
138
+ toolName: str | None
139
+
140
+ class ContentPart(TypedDict):
141
+ type: str
142
+ text: str | None
143
+ image_url: str | None
144
+
145
+ class CopilotBillingMetadata(TypedDict):
146
+ billable: bool
147
+
148
+ class CopilotInfoMessage(TypedDict):
149
+ code: Annotated[str, GitHubField("code")]
150
+ message: Annotated[str, GitHubField("message")]
151
+
152
+ class CopilotWarningMessage(TypedDict):
153
+ code: Annotated[str, GitHubField("code")]
154
+ message: Annotated[str, GitHubField("message")]
155
+
156
+ class TokenDetail(TypedDict):
157
+ batch_size: int
158
+ cost_per_batch: int
159
+ token_count: int
160
+ token_type: str
161
+
162
+ class CopilotUsage(TypedDict):
163
+ token_details: list[TokenDetail]
164
+ total_nano_aiu: int
165
+
166
+ class EventData(TypedDict):
167
+ actions: list[str] | None
168
+ alreadyInUse: bool | None
169
+ approved: bool | None
170
+ autoApproveEdits: bool | None
171
+ eventCount: int | None
172
+ eventsFileSizeBytes: int | None
173
+ feedback: str | None
174
+ intent: str | None
175
+ newMode: str | None
176
+ planContent: str | None
177
+ previousMode: str | None
178
+ reason: str | None
179
+ reasoningEffort: str | None
180
+ recommendedAction: str | None
181
+ remoteSteerable: bool | None
182
+ requestId: str | None
183
+ selectedAction: str | None
184
+ selectedModel: str | None
185
+ summary: str | None
186
+ toolCallId: str | None
187
+ turnId: str | None
188
+
189
+ class ErrorInfo(TypedDict):
190
+ code: str
191
+ message: str
192
+
193
+ class CompletionTokensDetails(TypedDict):
194
+ accepted_prediction_tokens: int | None
195
+ reasoning_tokens: int | None
196
+ rejected_prediction_tokens: int | None
197
+
198
+ class PromptTokensDetails(TypedDict):
199
+ cache_creation_tokens: int | None
200
+ cached_tokens: int
201
+ input_tokens: int | None
202
+ output_tokens: int | None
203
+
204
+ class UsageCopilotUsage(TypedDict):
205
+ token_details: list[TokenDetail]
206
+ total_nano_aiu: int
207
+
208
+ class Usage(TypedDict):
209
+ completion_tokens: int
210
+ completion_tokens_details: CompletionTokensDetails | None
211
+ copilot_usage: UsageCopilotUsage | None
212
+ prompt_tokens: int
213
+ prompt_tokens_details: PromptTokensDetails | None
214
+ reasoning_tokens: int | None
215
+ time_in_ms: int | None
216
+ total_tokens: int
217
+
218
+ class TruncateResult(TypedDict):
219
+ messagesRemovedDuringTruncation: int
220
+ postTruncationMessagesLength: int
221
+ postTruncationTokensInMessages: int
222
+ preTruncationMessagesLength: int
223
+ preTruncationTokensInMessages: int
224
+ tokenLimit: int
225
+ tokensRemovedDuringTruncation: int
@@ -0,0 +1,60 @@
1
+ import datetime as dt
2
+ from typing import Annotated, TypedDict
3
+
4
+ from .annotation import GitHubField, Note, Relation
5
+ from .references import (
6
+ AgentReference,
7
+ AgentSessionReference,
8
+ BranchReference,
9
+ PullRequestIDReference,
10
+ RepositoryReference,
11
+ UserReference,
12
+ )
13
+
14
+ class CustomAgentReference(TypedDict):
15
+ id: Annotated[str | None, GitHubField("id")]
16
+ name: Annotated[str | None, GitHubField("name")]
17
+ is_automation: Annotated[bool | None, GitHubField("is_automation")]
18
+
19
+ class AgentArtifactReference(TypedDict):
20
+ type: str
21
+ pull_request: Annotated[PullRequestIDReference | None, GitHubField("data")]
22
+ branch: Annotated[BranchReference | None, GitHubField("data")]
23
+
24
+ class AgentTaskData(TypedDict):
25
+ name: Annotated[str | None, GitHubField("name")]
26
+ state: Annotated[str, GitHubField("state")]
27
+ archived: bool
28
+ remote_steerable: Annotated[bool, GitHubField("remote_steerable")]
29
+ sharing_status: Annotated[str, GitHubField("sharing_status")]
30
+
31
+ created_at: Annotated[dt.datetime, GitHubField("created_at")]
32
+ updated_at: Annotated[dt.datetime, GitHubField("updated_at")]
33
+ archived_at: Annotated[dt.datetime | None, GitHubField("archived_at")]
34
+
35
+ custom_agent: Annotated[CustomAgentReference | None, GitHubField("custom_agent")]
36
+ agent_collaborators: Annotated[list[AgentReference], GitHubField("agent_collaborators[]")]
37
+ artifacts: Annotated[list[AgentArtifactReference], GitHubField("artifacts[]")]
38
+
39
+ class AgentTask(TypedDict):
40
+ id: Annotated[str, GitHubField("id")]
41
+
42
+ repository: Annotated[RepositoryReference, Relation()]
43
+ sessions: Annotated[list[AgentSessionReference], GitHubField("sessions[]")]
44
+
45
+ creator: Annotated[
46
+ UserReference | None,
47
+ GitHubField("creator", leaves={"id": "id", "login": "login"}),
48
+ Note("Not set when `found` is false"),
49
+ ]
50
+ collaborators: Annotated[
51
+ list[UserReference] | None,
52
+ GitHubField("user_collaborators[]", leaves={"id": ""}),
53
+ Note("Not set when `found` is false"),
54
+ ]
55
+
56
+ found: bool
57
+ data: Annotated[
58
+ AgentTaskData | None,
59
+ Note("Not set when `found` is false"),
60
+ ]
@@ -0,0 +1,18 @@
1
+ from dataclasses import dataclass
2
+
3
+ @dataclass(frozen=True)
4
+ class Description:
5
+ text: str
6
+
7
+ @dataclass(frozen=True)
8
+ class Note:
9
+ text: str
10
+
11
+ @dataclass(frozen=True)
12
+ class Relation:
13
+ pass
14
+
15
+ @dataclass(frozen=True)
16
+ class GitHubField:
17
+ field: str
18
+ leaves: dict[str, str] | None = None
@@ -0,0 +1,45 @@
1
+ from typing import Annotated, TypedDict
2
+
3
+ from .annotation import GitHubField
4
+
5
+ class AgentSessionReference(TypedDict):
6
+ id: Annotated[str, GitHubField("id")]
7
+
8
+ class AgentTaskReference(TypedDict):
9
+ id: Annotated[str, GitHubField("id")]
10
+
11
+ class RepositoryReference(TypedDict):
12
+ full_name: str
13
+
14
+ class UserReference(TypedDict):
15
+ id: Annotated[int, GitHubField("id")]
16
+ login: Annotated[str | None, GitHubField("login")]
17
+
18
+ class AgentReference(TypedDict):
19
+ id: Annotated[int, GitHubField("agent_id")]
20
+
21
+ # "copilot-developer" | "copilot-developer-cli" | "copilot-pr-reviews" | "vscode-chat"
22
+ slug: Annotated[str, GitHubField("slug")]
23
+
24
+ # Seems to be combination of the following three IDs:
25
+ # - Owner ID (internal, not queryable)
26
+ # - Repository ID (internal, not queryable)
27
+ # - PR GraphQL ID (queryable) / some uuid (not clear what resource)
28
+ task_id: Annotated[str | None, GitHubField("agent_task_id")]
29
+
30
+ # "Integration" | "UserToServerToken" | "OauthApplication" | "IntegrationInstallation" | None
31
+ type: Annotated[str | None, GitHubField("agent_type")]
32
+
33
+ class PullRequestIDReference(TypedDict):
34
+ id: Annotated[int | None, GitHubField("id")]
35
+ global_id: Annotated[str | None, GitHubField("global_id")]
36
+
37
+ class PullRequestReference(TypedDict):
38
+ id: Annotated[int | None, GitHubField("resource_id")]
39
+ global_id: Annotated[str | None, GitHubField("resource_global_id")]
40
+ number: Annotated[int | None, GitHubField("resource_number")]
41
+ state: Annotated[str | None, GitHubField("resource_state")]
42
+
43
+ class BranchReference(TypedDict):
44
+ base_ref: Annotated[str, GitHubField("base_ref")]
45
+ head_ref: Annotated[str | None, GitHubField("head_ref")]
@@ -0,0 +1,55 @@
1
+ import datetime as dt
2
+ from typing import Annotated, TypedDict
3
+
4
+ from .annotation import GitHubField, Relation
5
+ from .references import AgentTaskReference
6
+
7
+ class RepositoryMetric(TypedDict):
8
+ language: str
9
+ blank_lines: int
10
+ code_lines: int
11
+ comment_lines: int
12
+
13
+ class Repository(TypedDict):
14
+ full_name: str
15
+
16
+ agent_tasks: Annotated[list[AgentTaskReference], GitHubField("tasks[]")]
17
+
18
+ archived: Annotated[bool, GitHubField("isArchived")]
19
+ disabled: Annotated[bool, GitHubField("isDisabled")]
20
+ locked: Annotated[bool, GitHubField("isLocked")]
21
+ fork: Annotated[bool, GitHubField("isFork")]
22
+
23
+ homepage: Annotated[str | None, GitHubField("homepageUrl")]
24
+ has_wiki: Annotated[bool, GitHubField("hasWikiEnabled")]
25
+ license: Annotated[str | None, GitHubField("licenseInfo.name")]
26
+ main_language: str
27
+ default_branch: Annotated[str | None, GitHubField("defaultBranchRef.name")]
28
+ size: Annotated[int, GitHubField("diskUsage")]
29
+
30
+ created_at: Annotated[dt.datetime, GitHubField("created_at")]
31
+ pushed_at: Annotated[dt.datetime, GitHubField("pushed_at")]
32
+ updated_at: Annotated[dt.datetime, GitHubField("updated_at")]
33
+ last_commit_at: Annotated[dt.datetime | None, GitHubField("defaultBranchRef.target.committedDate")]
34
+ last_commit_SHA: Annotated[str | None, GitHubField("defaultBranchRef.target.oid")]
35
+
36
+ forks_count: Annotated[int, GitHubField("forkCount")]
37
+ stargazers_count: Annotated[int, GitHubField("stargazers.totalCount")]
38
+ watchers_count: Annotated[int | None, GitHubField("watchers.totalCount")]
39
+ commits_count: Annotated[int | None, GitHubField("defaultBranchRef.target.history.totalCount")]
40
+ branches_count: Annotated[int | None, GitHubField("refs.totalCount")]
41
+ releases_count: Annotated[int | None, GitHubField("releases.totalCount")]
42
+ contributors_count: int | None
43
+ total_issues_count: Annotated[int | None, GitHubField("issues.totalCount")]
44
+ open_issues_count: Annotated[int | None, GitHubField("issues(states: OPEN).totalCount")]
45
+ total_pull_requests_count: Annotated[int | None, GitHubField("pullRequests.totalCount")]
46
+ open_pull_requests_count: Annotated[int | None, GitHubField("pullRequests(states: OPEN).totalCount")]
47
+
48
+ labels: Annotated[list[str], GitHubField("labels.nodes[].name")]
49
+ topics: Annotated[list[str], GitHubField("repositoryTopics.nodes[].topic.name")]
50
+ languages: Annotated[dict[str, int], GitHubField("languages")]
51
+
52
+ blank_lines: int | None
53
+ code_lines: int | None
54
+ comment_lines: int | None
55
+ metrics: list[RepositoryMetric]
@@ -0,0 +1,28 @@
1
+ from typing import Annotated, TypedDict
2
+
3
+ from .annotation import Note, Relation
4
+ from .references import AgentSessionReference, AgentTaskReference
5
+
6
+ class User(TypedDict):
7
+ """
8
+ A GitHub user or organization
9
+ """
10
+
11
+ id: int
12
+ found: bool
13
+ found_using: Annotated[
14
+ str | None,
15
+ Note("`'id' | 'login'`. Not set when `found` is false"),
16
+ ]
17
+ login: Annotated[
18
+ str | None,
19
+ Note("Not set when `found` is false"),
20
+ ]
21
+
22
+ created_tasks: Annotated[list[AgentTaskReference], Relation()]
23
+ collaborated_tasks: Annotated[
24
+ list[AgentTaskReference],
25
+ Relation(),
26
+ Note("Taken from GitHub's API and may not be complete. Use together with created_tasks and sessions."),
27
+ ]
28
+ sessions: Annotated[list[AgentSessionReference], Relation()]