kotharcomputing 0.87.0__tar.gz → 0.89.0__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 (35) hide show
  1. {kotharcomputing-0.87.0/src/kotharcomputing.egg-info → kotharcomputing-0.89.0}/PKG-INFO +1 -1
  2. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/pyproject.toml +1 -1
  3. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/__init__.py +12 -0
  4. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/ai.py +6 -2
  5. kotharcomputing-0.89.0/src/kotharcomputing/aleph_language_server.py +297 -0
  6. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0/src/kotharcomputing.egg-info}/PKG-INFO +1 -1
  7. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/tests/test_public_api.py +6 -0
  8. kotharcomputing-0.87.0/src/kotharcomputing/aleph_language_server.py +0 -162
  9. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/LICENSE +0 -0
  10. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/README.md +0 -0
  11. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/setup.cfg +0 -0
  12. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/agents.py +0 -0
  13. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/api_tokens.py +0 -0
  14. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/client.py +0 -0
  15. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/common.py +0 -0
  16. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/credits.py +0 -0
  17. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/errors.py +0 -0
  18. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/executions.py +0 -0
  19. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/fetch.py +0 -0
  20. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/files.py +0 -0
  21. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/jobs.py +0 -0
  22. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/py.typed +0 -0
  23. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/runtimes.py +0 -0
  24. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/service_prices.py +0 -0
  25. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/subscribe_user.py +0 -0
  26. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/subscribe_workspace.py +0 -0
  27. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/subscriptions.py +0 -0
  28. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/users.py +0 -0
  29. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing/workspaces.py +0 -0
  30. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing.egg-info/SOURCES.txt +0 -0
  31. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing.egg-info/dependency_links.txt +0 -0
  32. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing.egg-info/requires.txt +0 -0
  33. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/src/kotharcomputing.egg-info/top_level.txt +0 -0
  34. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/tests/test_fetch_auth_headers.py +0 -0
  35. {kotharcomputing-0.87.0 → kotharcomputing-0.89.0}/tests/test_fetch_url_building.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kotharcomputing
3
- Version: 0.87.0
3
+ Version: 0.89.0
4
4
  Summary: Python SDK for the Kothar API
5
5
  Author: Kothar Computing
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kotharcomputing"
7
- version = "0.87.0"
7
+ version = "0.89.0"
8
8
  description = "Python SDK for the Kothar API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -3,9 +3,14 @@ from .aleph_language_server import (
3
3
  AlephLanguageServerClientOptions,
4
4
  AnalyzeResult,
5
5
  AnalyzeResultWithAst,
6
+ AnalyzeResultWithAstAndFormat,
7
+ AnalyzeResultWithFormat,
8
+ AstFilter,
9
+ AstFilterClause,
6
10
  AstNode,
7
11
  AstNodeLocation,
8
12
  AstNodeType,
13
+ AstTextFilter,
9
14
  Diagnostic,
10
15
  DiagnosticSeverity,
11
16
  Position,
@@ -41,6 +46,7 @@ from .ai import (
41
46
  AIChatMessageAssistantDelta,
42
47
  AIChatMessageError,
43
48
  AIChatMessageTool,
49
+ AIChatMessageToolResult,
44
50
  AIChatMessageUser,
45
51
  AIChatMessageUserAppend,
46
52
  AIChatMessageUserContent,
@@ -131,9 +137,14 @@ __all__ = [
131
137
  "AlephLanguageServerClientOptions",
132
138
  "AnalyzeResult",
133
139
  "AnalyzeResultWithAst",
140
+ "AnalyzeResultWithAstAndFormat",
141
+ "AnalyzeResultWithFormat",
142
+ "AstFilter",
143
+ "AstFilterClause",
134
144
  "AstNode",
135
145
  "AstNodeLocation",
136
146
  "AstNodeType",
147
+ "AstTextFilter",
137
148
  "Diagnostic",
138
149
  "DiagnosticSeverity",
139
150
  "Position",
@@ -167,6 +178,7 @@ __all__ = [
167
178
  "AIChatMessageAssistantDelta",
168
179
  "AIChatMessageError",
169
180
  "AIChatMessageTool",
181
+ "AIChatMessageToolResult",
170
182
  "AIChatMessageUser",
171
183
  "AIChatMessageUserAppend",
172
184
  "AIChatMessageUserContent",
@@ -112,13 +112,17 @@ class AIChatMessageError(TypedDict):
112
112
  error: ProblemDetails
113
113
 
114
114
 
115
- class AIChatMessageTool(TypedDict):
116
- role: Literal["tool"]
115
+ class AIChatMessageToolResult(TypedDict):
117
116
  toolCallId: str
118
117
  content: str
119
118
  status: NotRequired[Literal["success", "error"]]
120
119
 
121
120
 
121
+ class AIChatMessageTool(TypedDict):
122
+ role: Literal["tool"]
123
+ results: list[AIChatMessageToolResult]
124
+
125
+
122
126
  AIChatMessage: TypeAlias = AIChatMessageApi | AIChatMessageUser | AIChatMessageAssistant
123
127
  AIChatMessageWithStreaming: TypeAlias = (
124
128
  AIChatMessage | AIChatMessageAssistantDelta | AIChatMessageError
@@ -0,0 +1,297 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from enum import IntEnum
5
+ import json
6
+ from typing import Literal, NotRequired, Required, TypedDict, cast, overload
7
+
8
+ from .fetch import ApiTransport
9
+
10
+ DEFAULT_BASE_URL = "https://aleph.kotharcomputing.com"
11
+
12
+
13
+ @dataclass(slots=True)
14
+ class AlephLanguageServerClientOptions:
15
+ base_url: str = DEFAULT_BASE_URL
16
+ timeout: float = 30.0
17
+
18
+
19
+ class AlephLanguageServerClient:
20
+ def __init__(
21
+ self,
22
+ options: AlephLanguageServerClientOptions | None = None,
23
+ *,
24
+ base_url: str = DEFAULT_BASE_URL,
25
+ timeout: float = 30.0,
26
+ ) -> None:
27
+ if options is None:
28
+ options = AlephLanguageServerClientOptions(
29
+ base_url=base_url,
30
+ timeout=timeout,
31
+ )
32
+
33
+ self._transport = ApiTransport(
34
+ base_url=options.base_url,
35
+ access_token=None,
36
+ timeout=options.timeout,
37
+ )
38
+
39
+ def version(self) -> dict[str, str]:
40
+ return self._transport.get_json("version")
41
+
42
+ def format(
43
+ self,
44
+ code: str,
45
+ *,
46
+ tab_size: int | None = None,
47
+ insert_spaces: bool | None = None,
48
+ trim_trailing_whitespace: bool | None = None,
49
+ insert_final_newline: bool | None = None,
50
+ trim_final_newlines: bool | None = None,
51
+ ) -> str:
52
+ response = self._transport.raw(
53
+ "post",
54
+ "format",
55
+ headers={"Content-Type": "application/x-aleph"},
56
+ search_params={
57
+ "tab_size": tab_size,
58
+ "insert_spaces": insert_spaces,
59
+ "trim_trailing_whitespace": trim_trailing_whitespace,
60
+ "insert_final_newline": insert_final_newline,
61
+ "trim_final_newlines": trim_final_newlines,
62
+ },
63
+ body=code,
64
+ )
65
+ return response.text()
66
+
67
+ @overload
68
+ def analyze(
69
+ self,
70
+ code: str,
71
+ *,
72
+ include_ast: Literal[True],
73
+ filter_ast: AstFilter | None = ...,
74
+ format: Literal[True],
75
+ ) -> AnalyzeResultWithAstAndFormat: ...
76
+ @overload
77
+ def analyze(
78
+ self,
79
+ code: str,
80
+ *,
81
+ include_ast: Literal[True],
82
+ filter_ast: AstFilter | None = ...,
83
+ format: bool = ...,
84
+ ) -> AnalyzeResultWithAst: ...
85
+ @overload
86
+ def analyze(
87
+ self,
88
+ code: str,
89
+ *,
90
+ include_ast: bool = ...,
91
+ filter_ast: AstFilter,
92
+ format: Literal[True],
93
+ ) -> AnalyzeResultWithAstAndFormat: ...
94
+ @overload
95
+ def analyze(
96
+ self,
97
+ code: str,
98
+ *,
99
+ include_ast: bool = ...,
100
+ filter_ast: AstFilter,
101
+ format: bool = ...,
102
+ ) -> AnalyzeResultWithAst: ...
103
+ @overload
104
+ def analyze(
105
+ self,
106
+ code: str,
107
+ *,
108
+ include_ast: bool = ...,
109
+ filter_ast: None = ...,
110
+ format: Literal[True],
111
+ ) -> AnalyzeResultWithFormat: ...
112
+ @overload
113
+ def analyze(
114
+ self,
115
+ code: str,
116
+ *,
117
+ include_ast: bool = ...,
118
+ filter_ast: AstFilter | None = ...,
119
+ format: bool = ...,
120
+ ) -> AnalyzeResult: ...
121
+
122
+ def analyze(
123
+ self,
124
+ code: str,
125
+ *,
126
+ include_ast: bool = False,
127
+ filter_ast: AstFilter | None = None,
128
+ format: bool = False,
129
+ ) -> (
130
+ AnalyzeResult
131
+ | AnalyzeResultWithAst
132
+ | AnalyzeResultWithFormat
133
+ | AnalyzeResultWithAstAndFormat
134
+ ):
135
+ response = self._transport.raw(
136
+ "post",
137
+ "analyze",
138
+ headers={"Content-Type": "application/x-aleph"},
139
+ search_params={
140
+ "include_ast": include_ast or None,
141
+ "filter_ast": json.dumps(filter_ast, separators=(",", ":"))
142
+ if filter_ast is not None
143
+ else None,
144
+ "format": format or None,
145
+ },
146
+ body=code,
147
+ )
148
+ return cast(AnalyzeResult, response.json())
149
+
150
+
151
+ # -- Aleph Diagnostic types (based on LSP 3.17 specification) --
152
+
153
+
154
+ class DiagnosticSeverity(IntEnum):
155
+ Error = 1
156
+ Warning = 2
157
+ Information = 3
158
+ Hint = 4
159
+
160
+
161
+ class Position(TypedDict):
162
+ line: int
163
+ character: int
164
+
165
+
166
+ class Range(TypedDict):
167
+ start: Position
168
+ end: Position
169
+
170
+
171
+ class Diagnostic(TypedDict):
172
+ range: Range
173
+ message: str
174
+ severity: NotRequired[DiagnosticSeverity]
175
+ code: NotRequired[str | int]
176
+ source: NotRequired[str]
177
+
178
+
179
+ class AnalyzeResult(TypedDict):
180
+ diagnostics: list[Diagnostic]
181
+ ast: NotRequired[list[AstNode]]
182
+ format: NotRequired[list[str]]
183
+ error: NotRequired[str]
184
+
185
+
186
+ class AnalyzeResultWithAst(AnalyzeResult):
187
+ ast: list[AstNode]
188
+
189
+
190
+ class AnalyzeResultWithFormat(AnalyzeResult):
191
+ format: list[str]
192
+
193
+
194
+ class AnalyzeResultWithAstAndFormat(AnalyzeResultWithAst, AnalyzeResultWithFormat):
195
+ pass
196
+
197
+
198
+ class AstFilter(TypedDict):
199
+ any: list[AstFilterClause]
200
+
201
+
202
+ class _AstFilterClauseBase(TypedDict, total=False):
203
+ descendants: int
204
+
205
+
206
+ class _AstFilterClauseWithTypes(_AstFilterClauseBase, total=False):
207
+ types: Required[list[AstNodeType]]
208
+ text: AstTextFilter
209
+ children: AstFilter
210
+
211
+
212
+ class _AstFilterClauseWithText(_AstFilterClauseBase, total=False):
213
+ types: list[AstNodeType]
214
+ text: Required[AstTextFilter]
215
+ children: AstFilter
216
+
217
+
218
+ class _AstFilterClauseWithChildren(_AstFilterClauseBase, total=False):
219
+ types: list[AstNodeType]
220
+ text: AstTextFilter
221
+ children: Required[AstFilter]
222
+
223
+
224
+ AstFilterClause = (
225
+ _AstFilterClauseWithTypes | _AstFilterClauseWithText | _AstFilterClauseWithChildren
226
+ )
227
+
228
+
229
+ class AstTextFilter(TypedDict):
230
+ pattern: str
231
+ mode: NotRequired[Literal["regex"]]
232
+
233
+
234
+ class AstNode(TypedDict):
235
+ type: AstNodeType
236
+ text: NotRequired[str]
237
+ isSynthetic: NotRequired[Literal[True]]
238
+ location: AstNodeLocation
239
+ children: NotRequired[list[AstNode]]
240
+
241
+
242
+ class AstNodeLocation(TypedDict):
243
+ uri: NotRequired[str]
244
+ range: Range
245
+
246
+
247
+ AstNodeType = Literal[
248
+ "Id",
249
+ "Fun_Call",
250
+ "Unused_Return_Fun_Call",
251
+ "Arg_List",
252
+ "Slice_List",
253
+ "Slice",
254
+ "Equation",
255
+ "Var_Decl",
256
+ "Assign_Decl",
257
+ "Array_Call",
258
+ "Dot_Access",
259
+ "Lambda",
260
+ "Block",
261
+ "Scopeless_Block",
262
+ "Include",
263
+ "Def",
264
+ "While",
265
+ "If",
266
+ "For",
267
+ "Ranged_For",
268
+ "Inline_Array",
269
+ "Inline_Map",
270
+ "Return",
271
+ "File",
272
+ "Prefix",
273
+ "Break",
274
+ "Continue",
275
+ "Map_Pair",
276
+ "Value_Range",
277
+ "Inline_Range",
278
+ "Try",
279
+ "Catch",
280
+ "Finally",
281
+ "Method",
282
+ "Attr_Decl",
283
+ "Logical_And",
284
+ "Logical_Or",
285
+ "Reference",
286
+ "Switch",
287
+ "Case",
288
+ "Default",
289
+ "Noop",
290
+ "Class",
291
+ "Binary",
292
+ "Arg",
293
+ "Global_Decl",
294
+ "Constant",
295
+ "Compiled",
296
+ "Error",
297
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kotharcomputing
3
- Version: 0.87.0
3
+ Version: 0.89.0
4
4
  Summary: Python SDK for the Kothar API
5
5
  Author: Kothar Computing
6
6
  License-Expression: Apache-2.0
@@ -19,9 +19,14 @@ def test_package_import_and_public_exports() -> None:
19
19
  "AlephLanguageServerClientOptions",
20
20
  "AnalyzeResult",
21
21
  "AnalyzeResultWithAst",
22
+ "AnalyzeResultWithAstAndFormat",
23
+ "AnalyzeResultWithFormat",
24
+ "AstFilter",
25
+ "AstFilterClause",
22
26
  "AstNode",
23
27
  "AstNodeLocation",
24
28
  "AstNodeType",
29
+ "AstTextFilter",
25
30
  "Diagnostic",
26
31
  "DiagnosticSeverity",
27
32
  "Position",
@@ -55,6 +60,7 @@ def test_package_import_and_public_exports() -> None:
55
60
  "AIChatMessageAssistantDelta",
56
61
  "AIChatMessageError",
57
62
  "AIChatMessageTool",
63
+ "AIChatMessageToolResult",
58
64
  "AIChatMessageUser",
59
65
  "AIChatMessageUserAppend",
60
66
  "AIChatMessageUserContent",
@@ -1,162 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from enum import IntEnum
5
- from typing import Literal, NotRequired, TypedDict, cast, overload
6
-
7
- from .fetch import ApiTransport
8
-
9
- DEFAULT_BASE_URL = "https://aleph.kotharcomputing.com"
10
-
11
-
12
- @dataclass(slots=True)
13
- class AlephLanguageServerClientOptions:
14
- base_url: str = DEFAULT_BASE_URL
15
- timeout: float = 30.0
16
-
17
-
18
- class AlephLanguageServerClient:
19
- def __init__(
20
- self,
21
- options: AlephLanguageServerClientOptions | None = None,
22
- *,
23
- base_url: str = DEFAULT_BASE_URL,
24
- timeout: float = 30.0,
25
- ) -> None:
26
- if options is None:
27
- options = AlephLanguageServerClientOptions(
28
- base_url=base_url,
29
- timeout=timeout,
30
- )
31
-
32
- self._transport = ApiTransport(
33
- base_url=options.base_url,
34
- access_token=None,
35
- timeout=options.timeout,
36
- )
37
-
38
- def version(self) -> dict[str, str]:
39
- return self._transport.get_json("version")
40
-
41
- @overload
42
- def analyze(
43
- self, code: str, *, include_ast: Literal[True]
44
- ) -> AnalyzeResultWithAst: ...
45
- @overload
46
- def analyze(self, code: str, *, include_ast: bool = ...) -> AnalyzeResult: ...
47
-
48
- def analyze(
49
- self, code: str, *, include_ast: bool = False
50
- ) -> AnalyzeResult | AnalyzeResultWithAst:
51
- response = self._transport.raw(
52
- "post",
53
- "analyze",
54
- headers={"Content-Type": "application/x-aleph"},
55
- search_params={"include_ast": "true"} if include_ast else None,
56
- body=code,
57
- )
58
- return cast(
59
- AnalyzeResultWithAst if include_ast else AnalyzeResult, response.json()
60
- )
61
-
62
-
63
- # -- Aleph Diagnostic types (based on LSP 3.17 specification) --
64
-
65
-
66
- class DiagnosticSeverity(IntEnum):
67
- Error = 1
68
- Warning = 2
69
- Information = 3
70
- Hint = 4
71
-
72
-
73
- class Position(TypedDict):
74
- line: int
75
- character: int
76
-
77
-
78
- class Range(TypedDict):
79
- start: Position
80
- end: Position
81
-
82
-
83
- class Diagnostic(TypedDict):
84
- range: Range
85
- message: str
86
- severity: NotRequired[DiagnosticSeverity]
87
- code: NotRequired[str | int]
88
- source: NotRequired[str]
89
-
90
-
91
- class AnalyzeResult(TypedDict):
92
- diagnostics: list[Diagnostic]
93
-
94
-
95
- class AnalyzeResultWithAst(AnalyzeResult):
96
- ast: list[AstNode]
97
-
98
-
99
- class AstNode(TypedDict):
100
- type: AstNodeType
101
- text: NotRequired[str]
102
- isSynthetic: NotRequired[Literal[True]]
103
- location: NotRequired[AstNodeLocation]
104
- children: NotRequired[list[AstNode]]
105
-
106
-
107
- class AstNodeLocation(TypedDict):
108
- uri: NotRequired[str]
109
- range: Range
110
-
111
-
112
- AstNodeType = Literal[
113
- "Id",
114
- "Fun_Call",
115
- "Unused_Return_Fun_Call",
116
- "Arg_List",
117
- "Slice_List",
118
- "Slice",
119
- "Equation",
120
- "Var_Decl",
121
- "Assign_Decl",
122
- "Array_Call",
123
- "Dot_Access",
124
- "Lambda",
125
- "Block",
126
- "Scopeless_Block",
127
- "Include",
128
- "Def",
129
- "While",
130
- "If",
131
- "For",
132
- "Ranged_For",
133
- "Inline_Array",
134
- "Inline_Map",
135
- "Return",
136
- "File",
137
- "Prefix",
138
- "Break",
139
- "Continue",
140
- "Map_Pair",
141
- "Value_Range",
142
- "Inline_Range",
143
- "Try",
144
- "Catch",
145
- "Finally",
146
- "Method",
147
- "Attr_Decl",
148
- "Logical_And",
149
- "Logical_Or",
150
- "Reference",
151
- "Switch",
152
- "Case",
153
- "Default",
154
- "Noop",
155
- "Class",
156
- "Binary",
157
- "Arg",
158
- "Global_Decl",
159
- "Constant",
160
- "Compiled",
161
- "Error",
162
- ]