rossum-agent 1.0.0rc0__py3-none-any.whl
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.
- rossum_agent/__init__.py +9 -0
- rossum_agent/agent/__init__.py +32 -0
- rossum_agent/agent/core.py +932 -0
- rossum_agent/agent/memory.py +176 -0
- rossum_agent/agent/models.py +160 -0
- rossum_agent/agent/request_classifier.py +152 -0
- rossum_agent/agent/skills.py +132 -0
- rossum_agent/agent/types.py +5 -0
- rossum_agent/agent_logging.py +56 -0
- rossum_agent/api/__init__.py +1 -0
- rossum_agent/api/cli.py +51 -0
- rossum_agent/api/dependencies.py +190 -0
- rossum_agent/api/main.py +180 -0
- rossum_agent/api/models/__init__.py +1 -0
- rossum_agent/api/models/schemas.py +301 -0
- rossum_agent/api/routes/__init__.py +1 -0
- rossum_agent/api/routes/chats.py +95 -0
- rossum_agent/api/routes/files.py +113 -0
- rossum_agent/api/routes/health.py +44 -0
- rossum_agent/api/routes/messages.py +218 -0
- rossum_agent/api/services/__init__.py +1 -0
- rossum_agent/api/services/agent_service.py +451 -0
- rossum_agent/api/services/chat_service.py +197 -0
- rossum_agent/api/services/file_service.py +65 -0
- rossum_agent/assets/Primary_light_logo.png +0 -0
- rossum_agent/bedrock_client.py +64 -0
- rossum_agent/prompts/__init__.py +27 -0
- rossum_agent/prompts/base_prompt.py +80 -0
- rossum_agent/prompts/system_prompt.py +24 -0
- rossum_agent/py.typed +0 -0
- rossum_agent/redis_storage.py +482 -0
- rossum_agent/rossum_mcp_integration.py +123 -0
- rossum_agent/skills/hook-debugging.md +31 -0
- rossum_agent/skills/organization-setup.md +60 -0
- rossum_agent/skills/rossum-deployment.md +102 -0
- rossum_agent/skills/schema-patching.md +61 -0
- rossum_agent/skills/schema-pruning.md +23 -0
- rossum_agent/skills/ui-settings.md +45 -0
- rossum_agent/streamlit_app/__init__.py +1 -0
- rossum_agent/streamlit_app/app.py +646 -0
- rossum_agent/streamlit_app/beep_sound.py +36 -0
- rossum_agent/streamlit_app/cli.py +17 -0
- rossum_agent/streamlit_app/render_modules.py +123 -0
- rossum_agent/streamlit_app/response_formatting.py +305 -0
- rossum_agent/tools/__init__.py +214 -0
- rossum_agent/tools/core.py +173 -0
- rossum_agent/tools/deploy.py +404 -0
- rossum_agent/tools/dynamic_tools.py +365 -0
- rossum_agent/tools/file_tools.py +62 -0
- rossum_agent/tools/formula.py +187 -0
- rossum_agent/tools/skills.py +31 -0
- rossum_agent/tools/spawn_mcp.py +227 -0
- rossum_agent/tools/subagents/__init__.py +31 -0
- rossum_agent/tools/subagents/base.py +303 -0
- rossum_agent/tools/subagents/hook_debug.py +591 -0
- rossum_agent/tools/subagents/knowledge_base.py +305 -0
- rossum_agent/tools/subagents/mcp_helpers.py +47 -0
- rossum_agent/tools/subagents/schema_patching.py +471 -0
- rossum_agent/url_context.py +167 -0
- rossum_agent/user_detection.py +100 -0
- rossum_agent/utils.py +128 -0
- rossum_agent-1.0.0rc0.dist-info/METADATA +311 -0
- rossum_agent-1.0.0rc0.dist-info/RECORD +67 -0
- rossum_agent-1.0.0rc0.dist-info/WHEEL +5 -0
- rossum_agent-1.0.0rc0.dist-info/entry_points.txt +3 -0
- rossum_agent-1.0.0rc0.dist-info/licenses/LICENSE +21 -0
- rossum_agent-1.0.0rc0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""User detection utilities for Teleport-based authentication."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
import jwt
|
|
11
|
+
import jwt.algorithms
|
|
12
|
+
import requests
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def fetch_jwt_public_key(jwks_url: str) -> rsa.RSAPublicKey:
|
|
21
|
+
"""Fetch public key from internal Teleport JWK endpoint.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
jwks_url: URL to the JWKS endpoint
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
RSA public key for JWT verification
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
ValueError: If no JWT key found in response
|
|
31
|
+
"""
|
|
32
|
+
response = requests.get(jwks_url)
|
|
33
|
+
response.raise_for_status()
|
|
34
|
+
|
|
35
|
+
response_json = response.json()
|
|
36
|
+
if "keys" not in response_json:
|
|
37
|
+
raise ValueError("No JWT key found in Teleport JWK endpoint response")
|
|
38
|
+
|
|
39
|
+
return jwt.algorithms.RSAAlgorithm.from_jwk(response_json["keys"][0]) # type: ignore[return-value,attr-defined]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def decode_jwt_username(public_key: rsa.RSAPublicKey, token: str) -> str:
|
|
43
|
+
"""Validate and decode the JWT to extract username.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
public_key: RSA public key for verification
|
|
47
|
+
token: JWT token string
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Username from the JWT token
|
|
51
|
+
"""
|
|
52
|
+
decoded_token = jwt.decode(token, public_key, algorithms=["RS256"], options={"verify_aud": False})
|
|
53
|
+
username: str = decoded_token["username"]
|
|
54
|
+
return username
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_user_from_jwt(jwt_token: str | None) -> str | None:
|
|
58
|
+
"""Extract username from JWT token using Teleport JWKS verification.
|
|
59
|
+
|
|
60
|
+
Requires TELEPORT_JWT_JWKS_URL environment variable.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
jwt_token: The JWT token string
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Username string or None if authentication fails
|
|
67
|
+
"""
|
|
68
|
+
if not jwt_token:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
if not (jwks_url := os.environ.get("TELEPORT_JWT_JWKS_URL")):
|
|
72
|
+
logger.warning("TELEPORT_JWT_JWKS_URL not set, cannot verify JWT")
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
public_key = fetch_jwt_public_key(jwks_url)
|
|
77
|
+
username = decode_jwt_username(public_key=public_key, token=jwt_token)
|
|
78
|
+
logger.info(f"User {username} authenticated using Teleport JWT")
|
|
79
|
+
return username
|
|
80
|
+
except requests.RequestException as e:
|
|
81
|
+
logger.error(f"Failed to fetch JWKS: {e}")
|
|
82
|
+
return None
|
|
83
|
+
except jwt.InvalidTokenError as e:
|
|
84
|
+
logger.error(f"Invalid JWT token: {e}")
|
|
85
|
+
return None
|
|
86
|
+
except (KeyError, ValueError) as e:
|
|
87
|
+
logger.error(f"Failed to decode JWT claims: {e}")
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def normalize_user_id(user_id: str | None) -> str:
|
|
92
|
+
"""Normalize user ID for use in Redis keys.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
user_id: Raw user ID
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Normalized user ID suitable for Redis keys
|
|
99
|
+
"""
|
|
100
|
+
return re.sub(r"[^a-zA-Z0-9_-]", "_", user_id).lower() if user_id else "default"
|
rossum_agent/utils.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import datetime as dt
|
|
4
|
+
import shutil
|
|
5
|
+
import tempfile
|
|
6
|
+
import uuid
|
|
7
|
+
from contextvars import ContextVar
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# Context variable for session-specific output directory
|
|
11
|
+
# This allows thread-safe per-session output directories
|
|
12
|
+
_session_output_dir: ContextVar[Path | None] = ContextVar("session_output_dir", default=None)
|
|
13
|
+
|
|
14
|
+
# Base directory for all session outputs
|
|
15
|
+
BASE_OUTPUT_DIR = Path(tempfile.gettempdir()) / "rossum_agent_outputs"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def create_session_output_dir() -> Path:
|
|
19
|
+
"""Create a new session-specific output directory.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Path to the newly created session directory
|
|
23
|
+
"""
|
|
24
|
+
session_id = str(uuid.uuid4())
|
|
25
|
+
session_dir = BASE_OUTPUT_DIR / session_id
|
|
26
|
+
session_dir.mkdir(parents=True, exist_ok=True)
|
|
27
|
+
return session_dir
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def set_session_output_dir(output_dir: Path) -> None:
|
|
31
|
+
"""Set the output directory for the current session context.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
output_dir: Path to the session-specific output directory
|
|
35
|
+
"""
|
|
36
|
+
_session_output_dir.set(output_dir)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_session_output_dir() -> Path:
|
|
40
|
+
"""Get the output directory for the current session.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Path to session output directory, or creates a default one if not set
|
|
44
|
+
"""
|
|
45
|
+
output_dir = _session_output_dir.get()
|
|
46
|
+
if output_dir is None:
|
|
47
|
+
# Fallback for non-session contexts (e.g., CLI usage)
|
|
48
|
+
output_dir = Path("./outputs")
|
|
49
|
+
output_dir.mkdir(exist_ok=True)
|
|
50
|
+
return output_dir
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_generated_files(output_dir: Path | None = None) -> list[str]:
|
|
54
|
+
"""Get list of files in the outputs directory (recursively).
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
output_dir: Optional explicit output directory. If not provided,
|
|
58
|
+
uses the session context output directory.
|
|
59
|
+
"""
|
|
60
|
+
if output_dir is None:
|
|
61
|
+
output_dir = get_session_output_dir()
|
|
62
|
+
|
|
63
|
+
if not output_dir.exists():
|
|
64
|
+
return []
|
|
65
|
+
|
|
66
|
+
return [str(f.resolve()) for f in output_dir.rglob("*") if f.is_file()]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_generated_files_with_metadata(output_dir: Path | None = None) -> dict[str, float]:
|
|
70
|
+
"""Get files in the outputs directory with their modification times (recursively).
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
output_dir: Optional explicit output directory. If not provided,
|
|
74
|
+
uses the session context output directory.
|
|
75
|
+
"""
|
|
76
|
+
if output_dir is None:
|
|
77
|
+
output_dir = get_session_output_dir()
|
|
78
|
+
|
|
79
|
+
if not output_dir.exists():
|
|
80
|
+
return {}
|
|
81
|
+
|
|
82
|
+
return {str(f.resolve()): f.stat().st_mtime for f in output_dir.rglob("*") if f.is_file()}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def cleanup_session_output_dir(output_dir: Path) -> None:
|
|
86
|
+
"""Remove the entire session output directory.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
output_dir: Path to the session output directory to remove
|
|
90
|
+
"""
|
|
91
|
+
if output_dir.exists() and output_dir.is_dir():
|
|
92
|
+
shutil.rmtree(output_dir, ignore_errors=True)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def generate_chat_id() -> str:
|
|
96
|
+
unique_id = uuid.uuid4().hex[:12]
|
|
97
|
+
timestamp = dt.datetime.now(tz=dt.UTC).strftime("%Y%m%d%H%M%S")
|
|
98
|
+
return f"chat_{timestamp}_{unique_id}"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def is_valid_chat_id(chat_id: str) -> bool:
|
|
102
|
+
"""Validate chat ID format.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
chat_id: Chat identifier to validate
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
bool: True if chat_id matches expected format
|
|
109
|
+
"""
|
|
110
|
+
if not isinstance(chat_id, str):
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
parts = chat_id.split("_")
|
|
114
|
+
if len(parts) != 3:
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
if parts[0] != "chat":
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
# Validate timestamp (14 digits: YYYYMMDDHHMMSS)
|
|
121
|
+
if not (parts[1].isdigit() and len(parts[1]) == 14):
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
# Validate hex ID (12 hex characters)
|
|
125
|
+
if not (len(parts[2]) == 12 and all(c in "0123456789abcdef" for c in parts[2])):
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
return True
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rossum-agent
|
|
3
|
+
Version: 1.0.0rc0
|
|
4
|
+
Summary: AI agent toolkit for Rossum: document workflows conversationally, debug pipelines automatically, and enable agentic configuration of intelligent document processing.
|
|
5
|
+
Author-email: "Dan Stancl (Rossum AI)" <daniel.stancl@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: agent,rossum,document-processing,ai
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: anthropic>=0.75.0
|
|
21
|
+
Requires-Dist: boto3>=1.0
|
|
22
|
+
Requires-Dist: cryptography>=41.0
|
|
23
|
+
Requires-Dist: ddgs>=9.9.0
|
|
24
|
+
Requires-Dist: fastmcp>=2.13.0
|
|
25
|
+
Requires-Dist: httpx>=0.27.0
|
|
26
|
+
Requires-Dist: jinja2>=3.0
|
|
27
|
+
Requires-Dist: PyJWT>=2.8
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: python-dotenv
|
|
30
|
+
Requires-Dist: requests>=2.32
|
|
31
|
+
Requires-Dist: rossum-api>=3.8.0
|
|
32
|
+
Requires-Dist: rossum-deploy>=0.1.0
|
|
33
|
+
Requires-Dist: rossum-mcp>=1.0.0
|
|
34
|
+
Provides-Extra: api
|
|
35
|
+
Requires-Dist: fastapi>=0.115.0; extra == "api"
|
|
36
|
+
Requires-Dist: pydantic>2.0.0; extra == "api"
|
|
37
|
+
Requires-Dist: python-multipart>=0.0.22; extra == "api"
|
|
38
|
+
Requires-Dist: redis>=7.0.0; extra == "api"
|
|
39
|
+
Requires-Dist: slowapi>=0.1.9; extra == "api"
|
|
40
|
+
Requires-Dist: sse-starlette>=2.0.0; extra == "api"
|
|
41
|
+
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "api"
|
|
42
|
+
Provides-Extra: docs
|
|
43
|
+
Requires-Dist: myst-parser>=2.0.0; extra == "docs"
|
|
44
|
+
Requires-Dist: sphinx>=7.0.0; extra == "docs"
|
|
45
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == "docs"
|
|
46
|
+
Requires-Dist: sphinx-copybutton>=0.5.2; extra == "docs"
|
|
47
|
+
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == "docs"
|
|
48
|
+
Provides-Extra: streamlit
|
|
49
|
+
Requires-Dist: pyperclip>=1.0; extra == "streamlit"
|
|
50
|
+
Requires-Dist: redis>=7.0.0; extra == "streamlit"
|
|
51
|
+
Requires-Dist: streamlit>=1.28.0; extra == "streamlit"
|
|
52
|
+
Provides-Extra: tests
|
|
53
|
+
Requires-Dist: coverage>=7.0.0; extra == "tests"
|
|
54
|
+
Requires-Dist: httpx>=0.27.0; extra == "tests"
|
|
55
|
+
Requires-Dist: pytest>=7.0.0; extra == "tests"
|
|
56
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "tests"
|
|
57
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "tests"
|
|
58
|
+
Requires-Dist: redis>=7.0.0; extra == "tests"
|
|
59
|
+
Requires-Dist: streamlit>=1.28.0; extra == "tests"
|
|
60
|
+
Provides-Extra: all
|
|
61
|
+
Requires-Dist: coverage>=7.0.0; extra == "all"
|
|
62
|
+
Requires-Dist: fastapi>=0.115.0; extra == "all"
|
|
63
|
+
Requires-Dist: httpx>=0.27.0; extra == "all"
|
|
64
|
+
Requires-Dist: myst-parser>=2.0.0; extra == "all"
|
|
65
|
+
Requires-Dist: pydantic>2.0.0; extra == "all"
|
|
66
|
+
Requires-Dist: pyperclip>=1.0; extra == "all"
|
|
67
|
+
Requires-Dist: pytest>=7.0.0; extra == "all"
|
|
68
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "all"
|
|
69
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "all"
|
|
70
|
+
Requires-Dist: python-multipart>=0.0.22; extra == "all"
|
|
71
|
+
Requires-Dist: redis>=7.0.0; extra == "all"
|
|
72
|
+
Requires-Dist: slowapi>=0.1.9; extra == "all"
|
|
73
|
+
Requires-Dist: sphinx>=7.0.0; extra == "all"
|
|
74
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == "all"
|
|
75
|
+
Requires-Dist: sphinx-copybutton>=0.5.2; extra == "all"
|
|
76
|
+
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == "all"
|
|
77
|
+
Requires-Dist: sse-starlette>=2.0.0; extra == "all"
|
|
78
|
+
Requires-Dist: streamlit>=1.28.0; extra == "all"
|
|
79
|
+
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "all"
|
|
80
|
+
Dynamic: license-file
|
|
81
|
+
|
|
82
|
+
# Rossum Agent
|
|
83
|
+
|
|
84
|
+
<div align="center">
|
|
85
|
+
|
|
86
|
+
**AI agent for Rossum document processing. Debug hooks, deploy configs, and automate workflows conversationally.**
|
|
87
|
+
|
|
88
|
+
[](https://stancld.github.io/rossum-agents/)
|
|
89
|
+
[](https://www.python.org/downloads/)
|
|
90
|
+
[](https://opensource.org/licenses/MIT)
|
|
91
|
+
[](https://pypi.org/project/rossum-agent/)
|
|
92
|
+
[](https://codecov.io/gh/stancld/rossum-agents)
|
|
93
|
+
|
|
94
|
+
[](https://github.com/rossumai/rossum-api)
|
|
95
|
+
[](https://modelcontextprotocol.io/)
|
|
96
|
+
[](https://www.anthropic.com/claude/opus)
|
|
97
|
+
[](https://github.com/astral-sh/ruff)
|
|
98
|
+
[](https://github.com/astral-sh/ty)
|
|
99
|
+
[](https://github.com/astral-sh/uv)
|
|
100
|
+
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
> [!NOTE]
|
|
104
|
+
> Community-developed integration (not official Rossum). Early stage - breaking changes expected.
|
|
105
|
+
|
|
106
|
+
## Features
|
|
107
|
+
|
|
108
|
+
| Capability | Description |
|
|
109
|
+
|------------|-------------|
|
|
110
|
+
| **Rossum MCP Integration** | Full access to 50 MCP tools for document processing |
|
|
111
|
+
| **Hook Debugging** | Sandboxed execution with Opus sub-agent analysis |
|
|
112
|
+
| **Deployment Tools** | Pull, push, diff, copy configs across environments |
|
|
113
|
+
| **Knowledge Base Search** | AI-powered Rossum documentation search |
|
|
114
|
+
| **Multi-Environment** | Spawn connections to different Rossum environments |
|
|
115
|
+
| **Skills System** | Load domain-specific workflows on demand |
|
|
116
|
+
|
|
117
|
+
**Interfaces:** Streamlit UI, REST API, Python SDK
|
|
118
|
+
|
|
119
|
+
## Quick Start
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Set environment variables
|
|
123
|
+
export ROSSUM_API_TOKEN="your-api-token"
|
|
124
|
+
export ROSSUM_API_BASE_URL="https://api.elis.rossum.ai/v1"
|
|
125
|
+
export AWS_PROFILE="default" # For Bedrock
|
|
126
|
+
|
|
127
|
+
# Run the agent
|
|
128
|
+
uv pip install rossum-agent
|
|
129
|
+
rossum-agent
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or with Docker:
|
|
133
|
+
```bash
|
|
134
|
+
docker-compose up rossum-agent
|
|
135
|
+
# Open http://localhost:8501
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Installation
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
git clone https://github.com/stancld/rossum-agents.git
|
|
142
|
+
cd rossum-mcp/rossum-agent
|
|
143
|
+
uv sync
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**With extras:**
|
|
147
|
+
```bash
|
|
148
|
+
uv sync --extra all # All extras (api, streamlit, docs, tests)
|
|
149
|
+
uv sync --extra api # REST API (FastAPI, Redis)
|
|
150
|
+
uv sync --extra streamlit # Streamlit UI only
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Environment Variables
|
|
154
|
+
|
|
155
|
+
| Variable | Required | Description |
|
|
156
|
+
|----------|----------|-------------|
|
|
157
|
+
| `ROSSUM_API_TOKEN` | Yes | Rossum API authentication token |
|
|
158
|
+
| `ROSSUM_API_BASE_URL` | Yes | Base URL (e.g., `https://api.elis.rossum.ai/v1`) |
|
|
159
|
+
| `AWS_PROFILE` | Yes | AWS profile for Bedrock access |
|
|
160
|
+
| `AWS_DEFAULT_REGION` | No | AWS region (default: `us-east-1`) |
|
|
161
|
+
| `REDIS_HOST` | No | Redis host for chat persistence |
|
|
162
|
+
| `REDIS_PORT` | No | Redis port (default: `6379`) |
|
|
163
|
+
|
|
164
|
+
## Usage
|
|
165
|
+
|
|
166
|
+
### Streamlit UI
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
rossum-agent
|
|
170
|
+
# Or: streamlit run rossum_agent/streamlit_app/app.py
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### REST API
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
rossum-agent-api --host 0.0.0.0 --port 8000
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Python SDK
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
import asyncio
|
|
183
|
+
from rossum_agent.agent import create_agent
|
|
184
|
+
from rossum_agent.rossum_mcp_integration import create_mcp_connection
|
|
185
|
+
|
|
186
|
+
async def main():
|
|
187
|
+
mcp_connection = await create_mcp_connection()
|
|
188
|
+
agent = await create_agent(mcp_connection=mcp_connection)
|
|
189
|
+
|
|
190
|
+
async for step in agent.run("List all queues"):
|
|
191
|
+
if step.final_answer:
|
|
192
|
+
print(step.final_answer)
|
|
193
|
+
|
|
194
|
+
asyncio.run(main())
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Available Tools
|
|
198
|
+
|
|
199
|
+
The agent provides internal tools and access to 50+ MCP tools via dynamic loading.
|
|
200
|
+
|
|
201
|
+
<details>
|
|
202
|
+
<summary><strong>Internal Tools</strong></summary>
|
|
203
|
+
|
|
204
|
+
**File & Knowledge:**
|
|
205
|
+
- `write_file` - Save reports, documentation, analysis results
|
|
206
|
+
- `search_knowledge_base` - Search Rossum docs with AI analysis
|
|
207
|
+
|
|
208
|
+
**Hook Analysis:**
|
|
209
|
+
- `evaluate_python_hook` - Execute hooks in sandboxed environment
|
|
210
|
+
- `debug_hook` - Expert debugging with Opus sub-agent
|
|
211
|
+
|
|
212
|
+
**Schema:**
|
|
213
|
+
- `patch_schema_with_subagent` - Safe schema modifications via Opus
|
|
214
|
+
|
|
215
|
+
**Deployment:**
|
|
216
|
+
- `deploy_pull` - Pull configs from organization
|
|
217
|
+
- `deploy_diff` - Compare local vs remote
|
|
218
|
+
- `deploy_push` - Push local changes
|
|
219
|
+
- `deploy_copy_org` - Copy entire organization
|
|
220
|
+
- `deploy_copy_workspace` - Copy single workspace
|
|
221
|
+
- `deploy_compare_workspaces` - Compare two workspaces
|
|
222
|
+
- `deploy_to_org` - Deploy to target organization
|
|
223
|
+
|
|
224
|
+
**Multi-Environment:**
|
|
225
|
+
- `spawn_mcp_connection` - Connect to different Rossum environment
|
|
226
|
+
- `call_on_connection` - Call tools on spawned connection
|
|
227
|
+
- `close_connection` - Close spawned connection
|
|
228
|
+
|
|
229
|
+
**Skills:**
|
|
230
|
+
- `load_skill` - Load domain-specific workflows (`rossum-deployment`, `hook-debugging`)
|
|
231
|
+
|
|
232
|
+
</details>
|
|
233
|
+
|
|
234
|
+
<details>
|
|
235
|
+
<summary><strong>Dynamic MCP Tool Loading</strong></summary>
|
|
236
|
+
|
|
237
|
+
Tools are loaded on-demand to reduce context usage. Use `load_tool_category` to load tools by category:
|
|
238
|
+
|
|
239
|
+
| Category | Description |
|
|
240
|
+
|----------|-------------|
|
|
241
|
+
| `annotations` | Upload, retrieve, update, confirm documents |
|
|
242
|
+
| `queues` | Create, configure, list queues |
|
|
243
|
+
| `schemas` | Define, modify field structures |
|
|
244
|
+
| `engines` | Extraction and splitting engines |
|
|
245
|
+
| `hooks` | Extensions and webhooks |
|
|
246
|
+
| `email_templates` | Automated email responses |
|
|
247
|
+
| `document_relations` | Export/einvoice links |
|
|
248
|
+
| `relations` | Annotation relations |
|
|
249
|
+
| `rules` | Schema validation rules |
|
|
250
|
+
| `users` | User and role management |
|
|
251
|
+
| `workspaces` | Workspace management |
|
|
252
|
+
|
|
253
|
+
Categories are auto-loaded based on keywords in the user's message.
|
|
254
|
+
|
|
255
|
+
</details>
|
|
256
|
+
|
|
257
|
+
## Architecture
|
|
258
|
+
|
|
259
|
+
```mermaid
|
|
260
|
+
flowchart TB
|
|
261
|
+
subgraph UI["User Interface"]
|
|
262
|
+
S[Streamlit UI]
|
|
263
|
+
A[REST API]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
subgraph Agent["Rossum Agent (Claude Bedrock)"]
|
|
267
|
+
IT[Internal Tools]
|
|
268
|
+
DT[Deploy Tools]
|
|
269
|
+
MT[Spawn MCP Tools]
|
|
270
|
+
SK[Skills System]
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
subgraph MCP["Rossum MCP Server"]
|
|
274
|
+
Tools[50 MCP Tools]
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
API[Rossum API]
|
|
278
|
+
|
|
279
|
+
UI --> Agent
|
|
280
|
+
Agent --> MCP
|
|
281
|
+
MCP --> API
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
<details>
|
|
285
|
+
<summary><strong>REST API Endpoints</strong></summary>
|
|
286
|
+
|
|
287
|
+
| Endpoint | Description |
|
|
288
|
+
|----------|-------------|
|
|
289
|
+
| `GET /api/v1/health` | Health check |
|
|
290
|
+
| `GET /api/v1/chats` | List all chats |
|
|
291
|
+
| `POST /api/v1/chats` | Create new chat |
|
|
292
|
+
| `GET /api/v1/chats/{id}` | Get chat details |
|
|
293
|
+
| `DELETE /api/v1/chats/{id}` | Delete chat |
|
|
294
|
+
| `POST /api/v1/chats/{id}/messages` | Send message (SSE) |
|
|
295
|
+
| `GET /api/v1/chats/{id}/files` | List files |
|
|
296
|
+
| `GET /api/v1/chats/{id}/files/{name}` | Download file |
|
|
297
|
+
|
|
298
|
+
API docs: `/api/docs` (Swagger) or `/api/redoc`
|
|
299
|
+
|
|
300
|
+
</details>
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT License - see [LICENSE](../LICENSE) for details.
|
|
305
|
+
|
|
306
|
+
## Resources
|
|
307
|
+
|
|
308
|
+
- [Full Documentation](https://stancld.github.io/rossum-agents/)
|
|
309
|
+
- [MCP Server README](../rossum-mcp/README.md)
|
|
310
|
+
- [Rossum API Documentation](https://rossum.app/api/docs/)
|
|
311
|
+
- [Main Repository](https://github.com/stancld/rossum-agents)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
rossum_agent/__init__.py,sha256=gcKOXF61VJGZQrGrwOa5K2MICwAMFBtAol-D7DY_9Z4,235
|
|
2
|
+
rossum_agent/agent_logging.py,sha256=d6V-VxFEiSgaiMV7JZnUA1Chg34SLU_e3ZF42gKmoZU,1848
|
|
3
|
+
rossum_agent/bedrock_client.py,sha256=Ri3CmeC3DAazT8TnRf0m8rbyd0chSU0p9nI3an04n2E,2423
|
|
4
|
+
rossum_agent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
rossum_agent/redis_storage.py,sha256=foOQH4VH1vCYY3yjKBC7TxwHhlcwX4Nk_uHtyozG-M8,18369
|
|
6
|
+
rossum_agent/rossum_mcp_integration.py,sha256=zlMHYo3op4I19IV0NvYpY1m4lTmUVsr_8mRIqQSApAQ,4115
|
|
7
|
+
rossum_agent/url_context.py,sha256=u8j9_AFSHnZSkmcMVe6lypKKZ5qL148wKDgPmQA-MBc,5816
|
|
8
|
+
rossum_agent/user_detection.py,sha256=An-B7frKwXg3V0N7tTrbP5YWrsHX2VAk8K7i0JS2JZg,2845
|
|
9
|
+
rossum_agent/utils.py,sha256=UCQEAKBsvGt7OdU1JG30DykPaGwyVb63ciFc-j09F0U,3709
|
|
10
|
+
rossum_agent/agent/__init__.py,sha256=QpdTIYGE5MouIf73gIwXL2hvMTrdeJIMT1aCxwVI04k,753
|
|
11
|
+
rossum_agent/agent/core.py,sha256=8zcgrWcP5AkNOzUO90wSHeKh0S3ucUcNyef7ajYqAl4,38237
|
|
12
|
+
rossum_agent/agent/memory.py,sha256=lfRyFf1coM0JQ5dMFE3x6SjxnQXJhwj3oa_1Vn5Nj5Y,6194
|
|
13
|
+
rossum_agent/agent/models.py,sha256=fdPZpNfrwxNu3dMz_uiWyyo5j9qnsj8UlppoBZtsz8g,4820
|
|
14
|
+
rossum_agent/agent/request_classifier.py,sha256=ni0Aq5c6fFhDFv8NyBhJeYe5f2lmFoubN8GOZwa5fLs,5616
|
|
15
|
+
rossum_agent/agent/skills.py,sha256=u-YarSh8I4monU0v8n74c2M_04x5oKIEOCukCgdnubQ,3922
|
|
16
|
+
rossum_agent/agent/types.py,sha256=3wlQuHRuVRBeDo22Y-GhVsUwFyJdUdZ8QxmDFsBX6Vg,156
|
|
17
|
+
rossum_agent/api/__init__.py,sha256=t3qzj02YM9fC82ZESBxPnt3z2psrFQ4uZb-iCzomm-M,47
|
|
18
|
+
rossum_agent/api/cli.py,sha256=_1K2qGQ_WaSKUMbtIQvNV5iiSGf3wBxbSOXM_bPWN8Q,1681
|
|
19
|
+
rossum_agent/api/dependencies.py,sha256=MWCMH6dfBZC5l3ARK_4ovti0Blq5gvqPB5xymA-emmg,6900
|
|
20
|
+
rossum_agent/api/main.py,sha256=rCp7GYIJkFX8JS5PZ7aVk_53hx-gK7Giu-OCU5iZ7TA,5893
|
|
21
|
+
rossum_agent/api/models/__init__.py,sha256=j4t5I5ptWWMBA_eS5FL3X6MJiAxTDF53ACnJPAvAZbE,54
|
|
22
|
+
rossum_agent/api/models/schemas.py,sha256=g01hly4XhiwlYXVT6wQHGRVttFZRARtnrTVbxra56t4,9085
|
|
23
|
+
rossum_agent/api/routes/__init__.py,sha256=L2rqkYFsGSCU1Qnkgrw5ngCisTmLUPH747uX3ess2NA,26
|
|
24
|
+
rossum_agent/api/routes/chats.py,sha256=0PdFzOWHuxF7ipRqTb0pFSSzT1_MJ-sdn5AgRClOU8s,3845
|
|
25
|
+
rossum_agent/api/routes/files.py,sha256=7SvZ1miOC2fwaFsd5ko9rLCvntgc1YbXK8FchB1aHmk,4539
|
|
26
|
+
rossum_agent/api/routes/health.py,sha256=Sjis2KqfgFkfJAsGFjg5d8BhIswUFhNUfOf56o0MRI4,1435
|
|
27
|
+
rossum_agent/api/routes/messages.py,sha256=2P7b6hZK_ZL6oqeqZtldAdwT8QCK6Vo9TvEWkb7rc6c,8164
|
|
28
|
+
rossum_agent/api/services/__init__.py,sha256=oLA7_0cvWSde2ZDAG2lW-KrAj1E2mZDHhgAugftwnNc,40
|
|
29
|
+
rossum_agent/api/services/agent_service.py,sha256=K6f5SgJg2BO2T2Sg0PEtc42nWle2XKwbnhR6mOscetg,18391
|
|
30
|
+
rossum_agent/api/services/chat_service.py,sha256=sJMRiYmVeIWMVIDFniMC99e03fdIO0IlZnnheh9c180,6745
|
|
31
|
+
rossum_agent/api/services/file_service.py,sha256=9hw5n47ZezRKxD0o9d8dgX4mLDILmP7eCJpsXKtSAOM,1992
|
|
32
|
+
rossum_agent/assets/Primary_light_logo.png,sha256=kKdNl4vB7N2HWjd2WxAe_Hap_PF0LrVHs4rNz066dGA,10441
|
|
33
|
+
rossum_agent/prompts/__init__.py,sha256=_RT2eLtnYobZv4OAQsLFXBRg3pCDxTMGeHGOgLIc97A,714
|
|
34
|
+
rossum_agent/prompts/base_prompt.py,sha256=83wjLpgUCPXq06Z1uruopP3j5OgHAismTPVafIqgy8M,3507
|
|
35
|
+
rossum_agent/prompts/system_prompt.py,sha256=6ogk00BCIusS-PMfM47F0Fit7OYPANoaWLi0fZal_Y0,688
|
|
36
|
+
rossum_agent/skills/hook-debugging.md,sha256=QKUhvWMyRHJZ70Wpu4VDfPxSmC4wLC6er3NbETJNjiM,1134
|
|
37
|
+
rossum_agent/skills/organization-setup.md,sha256=-BCOGB9Jwpy-ffAkiWAfXI2hN8FaLWKkxTOSIZvGsL8,2307
|
|
38
|
+
rossum_agent/skills/rossum-deployment.md,sha256=NeqTdfLzErhQuMrHVpXcAnIil8JTxFxvStJdmLq15Tw,5811
|
|
39
|
+
rossum_agent/skills/schema-patching.md,sha256=CUUwa-cvgSTHugb1VhgP-MtlcVYyHURLTdNflh3zBAo,2158
|
|
40
|
+
rossum_agent/skills/schema-pruning.md,sha256=3lJzT4gUElEoq97uwL0fds78MG8klq-ZJFnNeqVOCnw,681
|
|
41
|
+
rossum_agent/skills/ui-settings.md,sha256=OVYjUhsaE41kOMVg-e5_6wI0p-g1iikkeEElRx6xURE,1782
|
|
42
|
+
rossum_agent/streamlit_app/__init__.py,sha256=X_0wth23f5ZE320MxeXY_zl2d7K9EfdWIqdTA-rABVg,59
|
|
43
|
+
rossum_agent/streamlit_app/app.py,sha256=mo5946c55zQQRBLQRV13eH-DSvHnyIzXLKxbfgHILdA,26133
|
|
44
|
+
rossum_agent/streamlit_app/beep_sound.py,sha256=uafjXOjM65w6D08aq1KIXAd9aomspOP7FAdmihEFEEI,1016
|
|
45
|
+
rossum_agent/streamlit_app/cli.py,sha256=5j9LTv8Qz0xX5Y2TXmZFagylSZqZHOmEJJTvJfT6SJ8,424
|
|
46
|
+
rossum_agent/streamlit_app/render_modules.py,sha256=djB7bdjj9Rea-IifD4vInAwyu2uaQ7yobOdFvbDE5L8,4510
|
|
47
|
+
rossum_agent/streamlit_app/response_formatting.py,sha256=_FXBIJXQ7iV4Y0oNLbeLGej1Yw4PRjJkjer8vh0BMgM,12066
|
|
48
|
+
rossum_agent/tools/__init__.py,sha256=G_GStbSmscHKYLJrJ_OZkhLbQ-0_0lfKdQBFB5W2-BY,5871
|
|
49
|
+
rossum_agent/tools/core.py,sha256=CVJa4HiAUVl0H1jLA-ANe3n4g6ubmzfCX__Gqt5eo8U,5504
|
|
50
|
+
rossum_agent/tools/deploy.py,sha256=yS7PxnIsIdhdfQ3i9cSMmozDF1eeoBQjE002N1x4Mpc,14738
|
|
51
|
+
rossum_agent/tools/dynamic_tools.py,sha256=eAODgnLjf4WhTC1ORkfxYkJuZkMsxiYs0Fc8PKTmomY,12695
|
|
52
|
+
rossum_agent/tools/file_tools.py,sha256=egsWfYa3SFCXL1UySYPmVABuRG04G1sAI5Sf6DQpOKs,1999
|
|
53
|
+
rossum_agent/tools/formula.py,sha256=nL87iU1EqiPZF_riEQ05bpSnady5TvKmTFmCVVg8Yx4,6785
|
|
54
|
+
rossum_agent/tools/skills.py,sha256=Oy_OKaMoCIecrbJcVR6-KhDBR3uKDW8yTO-cTWBzydI,1155
|
|
55
|
+
rossum_agent/tools/spawn_mcp.py,sha256=AjNj-kJDQEY8vi9QxGQqMbKOg-orSukIqNWYO79vfHk,8386
|
|
56
|
+
rossum_agent/tools/subagents/__init__.py,sha256=q3N2RCjgSm6Aw8hNZnCwzriFQaKBiOs3liknBu38Txo,1080
|
|
57
|
+
rossum_agent/tools/subagents/base.py,sha256=sRydE1hkHaxFVDo0jjEVwv9if7dvFgqPgLNB-v7xFoQ,11646
|
|
58
|
+
rossum_agent/tools/subagents/hook_debug.py,sha256=5lJiIQAh1nf6uOF05KB4AAjD72cZUwnSt8R5iyq0H0o,20453
|
|
59
|
+
rossum_agent/tools/subagents/knowledge_base.py,sha256=Xr1I6uscK8ETSwx_bS7ZylgtBI5Cj_p1Pmtd08655BI,10580
|
|
60
|
+
rossum_agent/tools/subagents/mcp_helpers.py,sha256=1yR1gvoWJ1gfzXDcXRwO94viUrRRz7QuRUtCy0dc518,1452
|
|
61
|
+
rossum_agent/tools/subagents/schema_patching.py,sha256=eJWK3HLdZ15EHr7S8myFo8AbX3N8MTN2r1-tAMb4-K4,17377
|
|
62
|
+
rossum_agent-1.0.0rc0.dist-info/licenses/LICENSE,sha256=5nqARgtmPvoIU-1o1az3i8Qi2WOHYIn03vD6haewvEI,1087
|
|
63
|
+
rossum_agent-1.0.0rc0.dist-info/METADATA,sha256=tjL2DsG8BuZ3xtS8zLt1WsA_lLveUQ8vMezIYS0JOnE,10917
|
|
64
|
+
rossum_agent-1.0.0rc0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
65
|
+
rossum_agent-1.0.0rc0.dist-info/entry_points.txt,sha256=1bbSeeptoKqT5-cWG4BuoMOGh_Crhu1sLL8AHXhbAJ0,115
|
|
66
|
+
rossum_agent-1.0.0rc0.dist-info/top_level.txt,sha256=jQm_Tm7Yq8oB68I8Y1BEhGqMGrusIgqfvfzeO1PGQso,13
|
|
67
|
+
rossum_agent-1.0.0rc0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rossum MCP Server Contributors
|
|
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 @@
|
|
|
1
|
+
rossum_agent
|