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,197 @@
|
|
|
1
|
+
"""Chat service for managing chat sessions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import datetime as dt
|
|
6
|
+
import logging
|
|
7
|
+
import secrets
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from rossum_agent.api.models.schemas import (
|
|
11
|
+
ChatDetail,
|
|
12
|
+
ChatListResponse,
|
|
13
|
+
ChatResponse,
|
|
14
|
+
ChatSummary,
|
|
15
|
+
FileInfo,
|
|
16
|
+
Message,
|
|
17
|
+
)
|
|
18
|
+
from rossum_agent.redis_storage import ChatData, ChatMetadata, RedisStorage
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any, Literal
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ChatService:
|
|
28
|
+
"""Service for managing chat sessions.
|
|
29
|
+
|
|
30
|
+
Wraps RedisStorage to provide chat CRUD operations with proper
|
|
31
|
+
data transformation to/from API schemas.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(self, redis_storage: RedisStorage | None = None) -> None:
|
|
35
|
+
self._storage = redis_storage or RedisStorage()
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def storage(self) -> RedisStorage:
|
|
39
|
+
"""Get the underlying RedisStorage instance."""
|
|
40
|
+
return self._storage
|
|
41
|
+
|
|
42
|
+
def is_connected(self) -> bool:
|
|
43
|
+
"""Check if Redis is connected."""
|
|
44
|
+
return self._storage.is_connected()
|
|
45
|
+
|
|
46
|
+
def create_chat(
|
|
47
|
+
self, user_id: str | None, mcp_mode: Literal["read-only", "read-write"] = "read-only"
|
|
48
|
+
) -> ChatResponse:
|
|
49
|
+
"""Create a new chat session.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
user_id: User identifier for isolation.
|
|
53
|
+
mcp_mode: MCP mode for this chat session.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
ChatResponse with the new chat_id and created_at timestamp.
|
|
57
|
+
"""
|
|
58
|
+
timestamp = dt.datetime.now(dt.UTC)
|
|
59
|
+
timestamp_str = timestamp.strftime("%Y%m%d%H%M%S")
|
|
60
|
+
unique_suffix = secrets.token_hex(4)
|
|
61
|
+
chat_id = f"chat_{timestamp_str}_{unique_suffix}"
|
|
62
|
+
|
|
63
|
+
initial_messages: list[dict[str, Any]] = []
|
|
64
|
+
metadata = ChatMetadata(mcp_mode=mcp_mode)
|
|
65
|
+
self._storage.save_chat(user_id, chat_id, initial_messages, metadata=metadata)
|
|
66
|
+
|
|
67
|
+
logger.info(f"Created chat {chat_id} for user {user_id or 'shared'} with mcp_mode={mcp_mode}")
|
|
68
|
+
return ChatResponse(chat_id=chat_id, created_at=timestamp)
|
|
69
|
+
|
|
70
|
+
def list_chats(self, user_id: str | None, limit: int = 50, offset: int = 0) -> ChatListResponse:
|
|
71
|
+
"""List chat sessions for a user.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
user_id: User identifier for isolation.
|
|
75
|
+
limit: Maximum number of chats to return.
|
|
76
|
+
offset: Pagination offset.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
ChatListResponse with paginated chat list.
|
|
80
|
+
"""
|
|
81
|
+
all_chats = self._storage.list_all_chats(user_id)
|
|
82
|
+
|
|
83
|
+
paginated = all_chats[offset : offset + limit]
|
|
84
|
+
chats = [
|
|
85
|
+
ChatSummary(
|
|
86
|
+
chat_id=chat["chat_id"],
|
|
87
|
+
timestamp=chat["timestamp"],
|
|
88
|
+
message_count=chat["message_count"],
|
|
89
|
+
first_message=chat["first_message"],
|
|
90
|
+
preview=chat.get("preview"),
|
|
91
|
+
)
|
|
92
|
+
for chat in paginated
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
return ChatListResponse(chats=chats, total=len(all_chats), limit=limit, offset=offset)
|
|
96
|
+
|
|
97
|
+
def get_chat(self, user_id: str | None, chat_id: str) -> ChatDetail | None:
|
|
98
|
+
"""Get detailed chat information.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
user_id: User identifier for isolation.
|
|
102
|
+
chat_id: Chat session identifier.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
ChatDetail with messages and files, or None if not found.
|
|
106
|
+
"""
|
|
107
|
+
if (chat_data := self._storage.load_chat(user_id, chat_id)) is None:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
messages = []
|
|
111
|
+
for msg in chat_data.messages:
|
|
112
|
+
msg_type = msg.get("type")
|
|
113
|
+
role = msg.get("role")
|
|
114
|
+
|
|
115
|
+
if msg_type == "task_step":
|
|
116
|
+
task_content = msg.get("task", "")
|
|
117
|
+
messages.append(Message(role="user", content=task_content))
|
|
118
|
+
elif msg_type == "memory_step":
|
|
119
|
+
text = msg.get("text")
|
|
120
|
+
if text:
|
|
121
|
+
messages.append(Message(role="assistant", content=text))
|
|
122
|
+
elif role in ("user", "assistant"):
|
|
123
|
+
messages.append(Message(role=role, content=msg.get("content", "")))
|
|
124
|
+
|
|
125
|
+
files_data = self._storage.list_files(chat_id)
|
|
126
|
+
files = [FileInfo(filename=f["filename"], size=f["size"], timestamp=f["timestamp"]) for f in files_data]
|
|
127
|
+
|
|
128
|
+
timestamp_str = chat_id.split("_")[1]
|
|
129
|
+
created_at = dt.datetime.strptime(timestamp_str, "%Y%m%d%H%M%S").replace(tzinfo=dt.UTC)
|
|
130
|
+
|
|
131
|
+
return ChatDetail(chat_id=chat_id, messages=messages, created_at=created_at, files=files)
|
|
132
|
+
|
|
133
|
+
def delete_chat(self, user_id: str | None, chat_id: str) -> bool:
|
|
134
|
+
"""Delete a chat session.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
user_id: User identifier for isolation.
|
|
138
|
+
chat_id: Chat session identifier.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
True if deleted, False otherwise.
|
|
142
|
+
"""
|
|
143
|
+
self._storage.delete_all_files(chat_id)
|
|
144
|
+
deleted = self._storage.delete_chat(user_id, chat_id)
|
|
145
|
+
logger.info(f"Deleted chat {chat_id} for user {user_id or 'shared'}: {deleted}")
|
|
146
|
+
return deleted
|
|
147
|
+
|
|
148
|
+
def chat_exists(self, user_id: str | None, chat_id: str) -> bool:
|
|
149
|
+
"""Check if a chat exists.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
user_id: User identifier for isolation.
|
|
153
|
+
chat_id: Chat session identifier.
|
|
154
|
+
"""
|
|
155
|
+
return self._storage.chat_exists(user_id, chat_id)
|
|
156
|
+
|
|
157
|
+
def get_messages(self, user_id: str | None, chat_id: str) -> list[dict[str, Any]] | None:
|
|
158
|
+
"""Get raw messages for a chat session.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
user_id: User identifier for isolation.
|
|
162
|
+
chat_id: Chat session identifier.
|
|
163
|
+
"""
|
|
164
|
+
if (chat_data := self._storage.load_chat(user_id, chat_id)) is None:
|
|
165
|
+
return None
|
|
166
|
+
return chat_data.messages
|
|
167
|
+
|
|
168
|
+
def get_chat_data(self, user_id: str | None, chat_id: str) -> ChatData | None:
|
|
169
|
+
"""Get full chat data including metadata.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
user_id: User identifier for isolation.
|
|
173
|
+
chat_id: Chat session identifier.
|
|
174
|
+
"""
|
|
175
|
+
return self._storage.load_chat(user_id, chat_id)
|
|
176
|
+
|
|
177
|
+
def save_messages(
|
|
178
|
+
self,
|
|
179
|
+
user_id: str | None,
|
|
180
|
+
chat_id: str,
|
|
181
|
+
messages: list[dict[str, Any]],
|
|
182
|
+
output_dir: Path | None = None,
|
|
183
|
+
metadata: ChatMetadata | None = None,
|
|
184
|
+
) -> bool:
|
|
185
|
+
"""Save messages to a chat session.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
user_id: User identifier for isolation.
|
|
189
|
+
chat_id: Chat session identifier.
|
|
190
|
+
messages: List of message dicts to save.
|
|
191
|
+
output_dir: Optional output directory path.
|
|
192
|
+
metadata: Optional chat metadata with token counts and step info.
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
True if saved successfully, False otherwise.
|
|
196
|
+
"""
|
|
197
|
+
return self._storage.save_chat(user_id, chat_id, messages, output_dir, metadata)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""File service for managing chat session files."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import mimetypes
|
|
6
|
+
|
|
7
|
+
from rossum_agent.api.models.schemas import FileInfo
|
|
8
|
+
from rossum_agent.redis_storage import RedisStorage
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FileService:
|
|
12
|
+
"""Service for managing files associated with chat sessions.
|
|
13
|
+
|
|
14
|
+
Wraps RedisStorage file operations with proper validation and
|
|
15
|
+
data transformation to/from API schemas.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, redis_storage: RedisStorage | None = None) -> None:
|
|
19
|
+
self._storage = redis_storage or RedisStorage()
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def storage(self) -> RedisStorage:
|
|
23
|
+
"""Get the underlying RedisStorage instance."""
|
|
24
|
+
return self._storage
|
|
25
|
+
|
|
26
|
+
def list_files(self, chat_id: str) -> list[FileInfo]:
|
|
27
|
+
"""List all files for a chat session.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
chat_id: Chat session identifier.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
List of FileInfo objects with file metadata.
|
|
34
|
+
"""
|
|
35
|
+
files_data = self._storage.list_files(chat_id)
|
|
36
|
+
return [
|
|
37
|
+
FileInfo(
|
|
38
|
+
filename=f["filename"],
|
|
39
|
+
size=f["size"],
|
|
40
|
+
timestamp=f["timestamp"],
|
|
41
|
+
mime_type=self._guess_mime_type(f["filename"]),
|
|
42
|
+
)
|
|
43
|
+
for f in files_data
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
def get_file(self, chat_id: str, filename: str) -> tuple[bytes, str] | None:
|
|
47
|
+
"""Get file content and MIME type.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
chat_id: Chat session identifier.
|
|
51
|
+
filename: Name of the file.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Tuple of (content bytes, mime_type) or None if not found.
|
|
55
|
+
"""
|
|
56
|
+
if (content := self._storage.load_file(chat_id, filename)) is None:
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
mime_type = self._guess_mime_type(filename)
|
|
60
|
+
return content, mime_type
|
|
61
|
+
|
|
62
|
+
def _guess_mime_type(self, filename: str) -> str:
|
|
63
|
+
"""Guess MIME type from filename."""
|
|
64
|
+
mime_type, _ = mimetypes.guess_type(filename)
|
|
65
|
+
return mime_type or "application/octet-stream"
|
|
Binary file
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""AWS Bedrock client module for direct communication with Anthropic models via boto3.Session."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
import boto3
|
|
8
|
+
from anthropic import AnthropicBedrock
|
|
9
|
+
|
|
10
|
+
OPUS_MODEL_ID = "eu.anthropic.claude-opus-4-5-20251101-v1:0"
|
|
11
|
+
HAIKU_MODEL_ID = "eu.anthropic.claude-haiku-4-5-20251001-v1:0"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def create_bedrock_client(
|
|
15
|
+
aws_region: str | None = None, aws_profile: str | None = None, session: boto3.Session | None = None
|
|
16
|
+
) -> AnthropicBedrock:
|
|
17
|
+
"""Create AnthropicBedrock client using boto3.Session credentials.
|
|
18
|
+
|
|
19
|
+
This function supports multiple credential sources:
|
|
20
|
+
1. Explicit boto3.Session passed as argument
|
|
21
|
+
2. AWS profile name (uses named profile from ~/.aws/credentials)
|
|
22
|
+
3. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)
|
|
23
|
+
4. IAM role credentials (when running on AWS infrastructure)
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
aws_region: AWS region for Bedrock service. Defaults to AWS_REGION env var
|
|
27
|
+
or 'eu-central-1'.
|
|
28
|
+
aws_profile: AWS profile name from ~/.aws/credentials. Overridden if session
|
|
29
|
+
is provided.
|
|
30
|
+
session: Pre-configured boto3.Session. If provided, aws_profile is ignored.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Configured AnthropicBedrock client ready for API calls.
|
|
34
|
+
"""
|
|
35
|
+
region = aws_region or os.environ.get("AWS_REGION")
|
|
36
|
+
|
|
37
|
+
if session is None:
|
|
38
|
+
session = boto3.Session(profile_name=aws_profile, region_name=region)
|
|
39
|
+
|
|
40
|
+
if (credentials := session.get_credentials()) is None:
|
|
41
|
+
raise RuntimeError(
|
|
42
|
+
"No AWS credentials found. Please configure AWS credentials via environment "
|
|
43
|
+
"variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), AWS profile, or IAM role."
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
frozen_credentials = credentials.get_frozen_credentials()
|
|
47
|
+
|
|
48
|
+
return AnthropicBedrock(
|
|
49
|
+
aws_access_key=frozen_credentials.access_key,
|
|
50
|
+
aws_secret_key=frozen_credentials.secret_key,
|
|
51
|
+
aws_session_token=frozen_credentials.token,
|
|
52
|
+
aws_region=session.region_name or region,
|
|
53
|
+
max_retries=5,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_model_id() -> str:
|
|
58
|
+
"""Return AWS_BEDROCK_MODEL_ARN if set, otherwise default Opus model."""
|
|
59
|
+
return os.environ.get("AWS_BEDROCK_MODEL_ARN", OPUS_MODEL_ID)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_small_model_id() -> str:
|
|
63
|
+
"""Return AWS_BEDROCK_MODEL_ARN_SMALL if set, otherwise default Haiku model."""
|
|
64
|
+
return os.environ.get("AWS_BEDROCK_MODEL_ARN_SMALL", HAIKU_MODEL_ID)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Prompt templates for the Rossum Agent.
|
|
2
|
+
|
|
3
|
+
This package contains shared prompt content and specialized prompt builders
|
|
4
|
+
for different agent paradigms (tool-use, code-execution).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from rossum_agent.prompts.base_prompt import (
|
|
10
|
+
CONFIGURATION_WORKFLOWS,
|
|
11
|
+
CRITICAL_REQUIREMENTS,
|
|
12
|
+
DOCUMENTATION_WORKFLOWS,
|
|
13
|
+
OUTPUT_FORMATTING,
|
|
14
|
+
ROSSUM_EXPERT_INTRO,
|
|
15
|
+
get_shared_prompt_sections,
|
|
16
|
+
)
|
|
17
|
+
from rossum_agent.prompts.system_prompt import get_system_prompt
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"CONFIGURATION_WORKFLOWS",
|
|
21
|
+
"CRITICAL_REQUIREMENTS",
|
|
22
|
+
"DOCUMENTATION_WORKFLOWS",
|
|
23
|
+
"OUTPUT_FORMATTING",
|
|
24
|
+
"ROSSUM_EXPERT_INTRO",
|
|
25
|
+
"get_shared_prompt_sections",
|
|
26
|
+
"get_system_prompt",
|
|
27
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Shared prompt content for the Rossum Agent.
|
|
2
|
+
|
|
3
|
+
Optimized for Opus 4.5: Goals + constraints, not procedures.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
ROSSUM_EXPERT_INTRO = """You are an expert Rossum platform specialist. Help users understand, document, debug, and configure document processing workflows.
|
|
9
|
+
|
|
10
|
+
**CRITICAL - Use `search_knowledge_base` before**:
|
|
11
|
+
- Explaining ANY extension/hook behavior (except simple function hooks you can read directly)
|
|
12
|
+
- Debugging issues - knowledge base contains known issues and solutions
|
|
13
|
+
- Configuring extensions - knowledge base has required settings and examples
|
|
14
|
+
|
|
15
|
+
**Skills** (load FIRST when relevant):
|
|
16
|
+
- `load_skill("rossum-deployment")` → sandbox, deploy, cross-org, migrate
|
|
17
|
+
- `load_skill("hook-debugging")` → debug/fix function hooks
|
|
18
|
+
- `load_skill("organization-setup")` → new customer onboarding, queue templates
|
|
19
|
+
- `load_skill("schema-patching")` → modify schemas, add/remove fields, formulas
|
|
20
|
+
- `load_skill("schema-pruning")` → bulk remove unwanted fields from schema
|
|
21
|
+
- `load_skill("ui-settings")` → update queue UI settings, annotation list columns
|
|
22
|
+
|
|
23
|
+
**MCP Tools** (pre-loaded based on request keywords, or load manually):
|
|
24
|
+
- `load_tool_category(["queues", "schemas"])` to load multiple categories at once
|
|
25
|
+
- Categories: annotations, queues, schemas, engines, hooks, email_templates, document_relations, relations, rules, users, workspaces"""
|
|
26
|
+
|
|
27
|
+
CRITICAL_REQUIREMENTS = """
|
|
28
|
+
# Domain Knowledge
|
|
29
|
+
|
|
30
|
+
**Schema**: sections → datapoints | multivalues → tuples (tables). Datapoint fields: `id`, `label`, `type`, `is_formula`, `formula`, `is_reasoning`, `prompt`, `score_threshold`.
|
|
31
|
+
|
|
32
|
+
**API constraints**:
|
|
33
|
+
- IDs are integers: `queue_id=12345` not `"12345"`
|
|
34
|
+
- `score_threshold` cannot be null (default `0.8`) - API rejects null values
|
|
35
|
+
- Annotation updates use numeric `id`, not `schema_id` string
|
|
36
|
+
|
|
37
|
+
**Engine training**: Inbox queues cannot train classification engines - they contain unsplit documents without `document_type`. Only typed documents in training_queues contribute."""
|
|
38
|
+
|
|
39
|
+
DOCUMENTATION_WORKFLOWS = """
|
|
40
|
+
# Visual Documentation
|
|
41
|
+
|
|
42
|
+
Use Mermaid diagrams for workflows. Apply this styling:
|
|
43
|
+
|
|
44
|
+
```mermaid
|
|
45
|
+
graph TD
|
|
46
|
+
Start[Document Upload]
|
|
47
|
+
Start --> Event1["annotation_status<br/>2 hooks"]
|
|
48
|
+
style Event1 fill:#E8F4F8,stroke:#4A90E2,stroke-width:2px
|
|
49
|
+
Event1 --> Hook1["Validation Hook<br/>[function]"]
|
|
50
|
+
style Hook1 fill:#4A90E2,stroke:#2E5C8A,color:#fff
|
|
51
|
+
Event1 --> End[Complete]
|
|
52
|
+
|
|
53
|
+
click Event1 "#annotation_status"
|
|
54
|
+
click Hook1 "#validation_hook"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Event nodes: light blue (`#E8F4F8`). Hook nodes: darker blue (`#4A90E2`, white text). Add clickable anchors."""
|
|
58
|
+
|
|
59
|
+
CONFIGURATION_WORKFLOWS = """
|
|
60
|
+
# Configuration
|
|
61
|
+
|
|
62
|
+
**Sandbox deployments**: Load `rossum-deployment` skill first. Execute autonomously through diff, then wait for user approval before deploying.
|
|
63
|
+
|
|
64
|
+
**Direct operations**: For single-org changes without sandbox, use MCP tools directly.
|
|
65
|
+
|
|
66
|
+
**Hooks**: Prefer `list_hook_templates` + `create_hook_from_template` over custom code."""
|
|
67
|
+
|
|
68
|
+
OUTPUT_FORMATTING = """
|
|
69
|
+
# Output
|
|
70
|
+
|
|
71
|
+
Match response length to question complexity. Be concise for simple questions.
|
|
72
|
+
|
|
73
|
+
For documentation: use Mermaid diagrams, cross-reference with anchors, explain business logic in prose (not JSON dumps), flag issues with `⚠️ SUSPICIOUS:`."""
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_shared_prompt_sections() -> str:
|
|
77
|
+
"""Get all shared prompt sections combined."""
|
|
78
|
+
return "\n\n---\n".join(
|
|
79
|
+
[CRITICAL_REQUIREMENTS, DOCUMENTATION_WORKFLOWS, CONFIGURATION_WORKFLOWS, OUTPUT_FORMATTING]
|
|
80
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""System prompt for the RossumAgent using Anthropic's tool use API.
|
|
2
|
+
|
|
3
|
+
This module provides the system prompt that defines the agent's behavior,
|
|
4
|
+
capabilities, and guidelines for interacting with the Rossum platform.
|
|
5
|
+
The prompt is adapted for use with Anthropic's native tool use API.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from rossum_agent.prompts.base_prompt import ROSSUM_EXPERT_INTRO, get_shared_prompt_sections
|
|
11
|
+
|
|
12
|
+
SYSTEM_PROMPT = f"""{ROSSUM_EXPERT_INTRO}
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
{get_shared_prompt_sections()}"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_system_prompt() -> str:
|
|
19
|
+
"""Get the system prompt for the RossumAgent.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
The system prompt string defining agent behavior.
|
|
23
|
+
"""
|
|
24
|
+
return SYSTEM_PROMPT
|
rossum_agent/py.typed
ADDED
|
File without changes
|