coala-cli 0.2.4__tar.gz → 0.2.5__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.
- coala_cli-0.2.5/.gitignore +6 -0
- {coala_cli-0.2.4 → coala_cli-0.2.5}/PKG-INFO +10 -11
- {coala_cli-0.2.4 → coala_cli-0.2.5}/coala/tool_logic.py +68 -1
- coala_cli-0.2.5/pyproject.toml +42 -0
- coala_cli-0.2.4/pyproject.toml +0 -27
- {coala_cli-0.2.4 → coala_cli-0.2.5}/README.md +0 -0
- {coala_cli-0.2.4 → coala_cli-0.2.5}/coala/__init__.py +0 -0
- {coala_cli-0.2.4 → coala_cli-0.2.5}/coala/agent.py +0 -0
- {coala_cli-0.2.4 → coala_cli-0.2.5}/coala/mcp_api.py +0 -0
- {coala_cli-0.2.4 → coala_cli-0.2.5}/coala/remote_api.py +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: coala-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Command-line LLM-agent Adapter
|
|
5
|
-
License: MIT
|
|
6
5
|
Author: Qiang
|
|
7
|
-
|
|
6
|
+
License-Expression: MIT
|
|
8
7
|
Classifier: License :: OSI Approved :: MIT License
|
|
9
8
|
Classifier: Programming Language :: Python :: 3
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
-
Requires-
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
12
|
+
Requires-Python: <3.15,>=3.12
|
|
13
|
+
Requires-Dist: cwltool<4.0.0,>=3.2.20260413085819
|
|
14
|
+
Requires-Dist: fastapi>=0.115.0
|
|
15
|
+
Requires-Dist: mcp<2.0.0,>=1.12.0
|
|
16
|
+
Requires-Dist: pydantic<3.0.0,>=2.10.0
|
|
17
|
+
Requires-Dist: requests<3.0.0,>=2.33.0
|
|
18
|
+
Requires-Dist: uvicorn<0.33.0,>=0.32.0
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
|
|
21
21
|
# Coala: Command-line LLM-agent Adapter
|
|
@@ -29,4 +29,3 @@ Coala integrates the [Common Workflow Language (CWL)](https://www.commonwl.org/s
|
|
|
29
29
|
|
|
30
30
|
Please find Coala documuentations through [Coala website](https://coala.info/), including [overview](https://coala.info/guide/), [installation](https://coala.info/guide/installation.html), [quick start](https://coala.info/guide/quick-start.html), and [use cases](https://coala.info/use-cases/).
|
|
31
31
|
|
|
32
|
-
|
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from urllib.parse import urlparse, unquote
|
|
7
7
|
from urllib.request import url2pathname
|
|
8
8
|
from cwltool.context import RuntimeContext
|
|
9
|
+
from cwltool.factory import WorkflowStatus
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def _canonical_file_uri(uri: str) -> str:
|
|
@@ -57,6 +58,66 @@ def configure_container_runner(runtime_context: RuntimeContext, container_runner
|
|
|
57
58
|
or shutil.which('xcrunner') or 'xcrunner'
|
|
58
59
|
)
|
|
59
60
|
|
|
61
|
+
class ToolRunFailed(RuntimeError):
|
|
62
|
+
"""A CWL run that exited non-zero, carrying what the tool itself printed."""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Enough to hold a tool's closing error and the lines that lead to it, without flooding the
|
|
66
|
+
# caller with a long progress log.
|
|
67
|
+
_FAILED_OUTPUT_LINES = 40
|
|
68
|
+
_FAILED_OUTPUT_CHARS = 6000
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _captured_stream_outputs(tool) -> dict:
|
|
72
|
+
"""``{output id: "stdout" | "stderr"}`` for outputs that capture the tool's own streams.
|
|
73
|
+
|
|
74
|
+
cwltool rewrites ``type: stdout`` into a ``File`` whose glob is the tool's ``stdout`` value,
|
|
75
|
+
so the glob, not the type, identifies it — and still does when that value is an expression.
|
|
76
|
+
"""
|
|
77
|
+
spec = getattr(getattr(tool, "t", None), "tool", None) or {}
|
|
78
|
+
streams = {spec.get(s): s for s in ("stdout", "stderr") if spec.get(s)}
|
|
79
|
+
found = {}
|
|
80
|
+
for out in spec.get("outputs") or []:
|
|
81
|
+
glob = (out.get("outputBinding") or {}).get("glob")
|
|
82
|
+
if isinstance(glob, str) and glob in streams:
|
|
83
|
+
found[str(out.get("id", "")).rsplit("#", 1)[-1]] = streams[glob]
|
|
84
|
+
return found
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _tail(path: str) -> str:
|
|
88
|
+
try:
|
|
89
|
+
with open(path, "r", encoding="utf-8", errors="replace") as fh:
|
|
90
|
+
lines = fh.read().splitlines()
|
|
91
|
+
except OSError:
|
|
92
|
+
return ""
|
|
93
|
+
text = "\n".join(lines[-_FAILED_OUTPUT_LINES:]).strip()
|
|
94
|
+
return text[-_FAILED_OUTPUT_CHARS:]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _failed_run_output(tool, partial) -> str:
|
|
98
|
+
"""The tail of the tool's own stdout/stderr capture files from a failed run, or ``""``.
|
|
99
|
+
|
|
100
|
+
A tool that prints its error to standard output, into a file the CWL declares with
|
|
101
|
+
``stdout:``, leaves cwltool's log with nothing but "exited with status: 1": cellranger-arc
|
|
102
|
+
``mkref`` reported an unknown GTF contig that way, and the caller retried blind for three
|
|
103
|
+
hours. cwltool still collects that file when the run fails and passes it in the exception,
|
|
104
|
+
so read it back.
|
|
105
|
+
"""
|
|
106
|
+
if not isinstance(partial, dict):
|
|
107
|
+
return ""
|
|
108
|
+
parts = []
|
|
109
|
+
for out_id, stream in _captured_stream_outputs(tool).items():
|
|
110
|
+
entry = partial.get(out_id)
|
|
111
|
+
location = entry.get("location") if isinstance(entry, dict) else None
|
|
112
|
+
if not isinstance(location, str) or not location.startswith("file://"):
|
|
113
|
+
continue
|
|
114
|
+
text = _tail(url2pathname(urlparse(location).path))
|
|
115
|
+
if text:
|
|
116
|
+
name = entry.get("basename") or out_id
|
|
117
|
+
parts.append(f"The tool's {stream} ({name}), last lines:\n{text}")
|
|
118
|
+
return "\n\n".join(parts)
|
|
119
|
+
|
|
120
|
+
|
|
60
121
|
def _read_file_content(filepath):
|
|
61
122
|
"""Read file content, handling gzipped files."""
|
|
62
123
|
try:
|
|
@@ -198,7 +259,13 @@ def run_tool(tool, params, outputs, read_outs=False, container_runner=None):
|
|
|
198
259
|
configure_container_runner(original_runtime_context, container_runner)
|
|
199
260
|
|
|
200
261
|
# Execute tool (no need to pass runtime_context if we modified it in place)
|
|
201
|
-
|
|
262
|
+
try:
|
|
263
|
+
res = tool(**params)
|
|
264
|
+
except WorkflowStatus as exc:
|
|
265
|
+
detail = _failed_run_output(tool, exc.out)
|
|
266
|
+
if not detail:
|
|
267
|
+
raise
|
|
268
|
+
raise ToolRunFailed(f"Completed {exc.status}.\n\n{detail}") from exc
|
|
202
269
|
outs = {}
|
|
203
270
|
for ot in outputs:
|
|
204
271
|
out_content = res[ot['name']]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "coala-cli"
|
|
3
|
+
version = "0.2.5"
|
|
4
|
+
description = "Command-line LLM-agent Adapter"
|
|
5
|
+
authors = [{ name = "Qiang" }]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.12,<3.15"
|
|
9
|
+
classifiers = [
|
|
10
|
+
"License :: OSI Approved :: MIT License",
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Programming Language :: Python :: 3.12",
|
|
13
|
+
"Programming Language :: Python :: 3.13",
|
|
14
|
+
"Programming Language :: Python :: 3.14",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"fastapi>=0.115.0",
|
|
18
|
+
"requests>=2.33.0,<3.0.0",
|
|
19
|
+
"pydantic>=2.10.0,<3.0.0",
|
|
20
|
+
"uvicorn>=0.32.0,<0.33.0",
|
|
21
|
+
"cwltool>=3.2.20260413085819,<4.0.0",
|
|
22
|
+
"mcp>=1.12.0,<2.0.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = ["pytest>=8.0.0", "pytest-asyncio>=0.24.0"]
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["hatchling"]
|
|
30
|
+
build-backend = "hatchling.build"
|
|
31
|
+
|
|
32
|
+
# The sdist carries what the Poetry build did: the package and the README.
|
|
33
|
+
[tool.hatch.build.targets.sdist]
|
|
34
|
+
include = ["coala", "README.md"]
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["coala"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
filterwarnings = [
|
|
41
|
+
"ignore::pydantic.warnings.UnsupportedFieldAttributeWarning",
|
|
42
|
+
]
|
coala_cli-0.2.4/pyproject.toml
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "coala-cli"
|
|
3
|
-
version = "0.2.4"
|
|
4
|
-
description = "Command-line LLM-agent Adapter"
|
|
5
|
-
authors = ["Qiang"]
|
|
6
|
-
license = "MIT"
|
|
7
|
-
readme = "README.md"
|
|
8
|
-
packages = [{ include = "coala" }]
|
|
9
|
-
|
|
10
|
-
[tool.poetry.dependencies]
|
|
11
|
-
python = ">=3.12,<3.15"
|
|
12
|
-
fastapi = ">=0.115.0"
|
|
13
|
-
requests = "^2.33.0"
|
|
14
|
-
pydantic = "^2.10.0"
|
|
15
|
-
uvicorn = "^0.32.0"
|
|
16
|
-
cwltool = "^3.2.20260413085819"
|
|
17
|
-
mcp = "^1.12.0"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
[build-system]
|
|
21
|
-
requires = ["poetry-core"]
|
|
22
|
-
build-backend = "poetry.core.masonry.api"
|
|
23
|
-
|
|
24
|
-
[tool.pytest.ini_options]
|
|
25
|
-
filterwarnings = [
|
|
26
|
-
"ignore::pydantic.warnings.UnsupportedFieldAttributeWarning",
|
|
27
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|