Skip to content

Commit ab81b1d

Browse files
authored
Papayne/kta panels (#626)
1 parent 30143ce commit ab81b1d

14 files changed

Lines changed: 710 additions & 376 deletions

File tree

assistants/knowledge-transfer-assistant/CLAUDE.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ The system manages three types of conversations:
4343
- Single test: `uv run pytest tests/test_file.py::test_function -v`
4444
- Manual inspector test: `python tests/test_inspector.py` (test state inspector functionality)
4545
- Docker build: `make docker-build` (builds assistant container image)
46+
- Start assistant: `make start` (starts the assistant service)
47+
- Local docker run: `make docker-run-local` (runs assistant in Docker with local workbench)
4648

4749
## Development Notes
4850

@@ -67,6 +69,23 @@ The assistant supports two templates with unified codebase:
6769
- **Information Requests**: Bidirectional communication between coordinators and team members
6870
- **Project Dashboard**: Real-time progress and state information
6971

72+
### Available Commands
73+
74+
#### General Commands (All Users)
75+
- `/help [command]` - Get help with available commands
76+
- `/knowledge-info [brief|digest|status|requests]` - View knowledge package information
77+
78+
#### Coordinator Commands
79+
- `/create-knowledge-brief Title|Description` - Create a knowledge brief
80+
- `/add-learning-objective Objective Name|Description|Learning outcome 1;Learning outcome 2` - Add learning objectives
81+
- `/resolve-request request_id|Resolution information` - Resolve information requests
82+
- `/list-participants` - List all project participants
83+
84+
#### Team Commands
85+
- `/request-info Request Title|Description|priority` - Request information from coordinator
86+
- `/update-status status|progress|message` - Update project status and progress
87+
- `/sync-files` - Synchronize shared files from the project
88+
7089
### Dependencies
7190

7291
The assistant uses several key dependencies from the Semantic Workbench ecosystem:
@@ -80,9 +99,16 @@ The assistant uses several key dependencies from the Semantic Workbench ecosyste
8099

81100
Key architectural files:
82101
- `/assistant/`: Core implementation files
102+
- `assistant.py`: Main assistant with dual-role event handling
103+
- `manager.py`: Project state and artifact management
104+
- `conversation_share_link.py`: Cross-conversation linking and synchronization
105+
- `command_processor.py`: Command handling with role-based authorization
106+
- `inspectors/`: State inspector components (brief, learning, sharing, debug)
107+
- `storage.py` & `storage_models.py`: Persistent state management
108+
- `config.py`: Role-specific prompt templates and configuration
109+
- `text_includes/`: Role-specific prompts and instruction templates
83110
- `/docs/`: Design documentation including `DESIGN.md`, `DEV_GUIDE.md`, and `WORKBENCH_NOTES.md`
84111
- `/tests/`: Test suite with manual inspector testing support
85-
- `/assistant/text_includes/`: Role-specific prompts and instruction templates
86112

87113
## Code Style
88114

@@ -102,3 +128,22 @@ Key architectural files:
102128
- Type checking: Pyright (Python)
103129
- Testing: pytest (Python)
104130
- Package management: uv (Python)
131+
132+
## Testing
133+
134+
The assistant includes comprehensive test coverage:
135+
- `test_artifact_loading.py`: Artifact loading and management tests
136+
- `test_inspector.py`: State inspector functionality tests (can be run manually with `python tests/test_inspector.py`)
137+
- `test_share_manager.py`: File sharing and synchronization tests
138+
- `test_share_storage.py`: Storage system tests
139+
- `test_share_tools.py`: Tool functionality tests
140+
- `test_team_mode.py`: Team mode operation tests
141+
142+
## Philosophy
143+
144+
The codebase follows a **wabi-sabi philosophy** emphasizing:
145+
- Ruthless simplicity with minimal abstractions
146+
- Present-moment focus rather than future-proofing
147+
- Trust in emergence from simple, well-defined components
148+
- Direct library integration with minimal wrappers
149+
- Pragmatic trust in external systems

assistants/knowledge-transfer-assistant/assistant/assistant.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from .logging import logger
4444
from .manager import KnowledgeTransferManager
4545
from .notifications import ProjectNotifier
46-
from .state_inspector import ShareInspectorStateProvider
46+
from .inspectors import BriefInspector, LearningInspector, SharingInspector, DebugInspector
4747
from .storage import ShareStorage
4848
from .storage_models import ConversationRole
4949

@@ -69,7 +69,10 @@ async def content_evaluator_factory(
6969
content_interceptor=content_safety,
7070
capabilities={AssistantCapability.supports_conversation_files},
7171
inspector_state_providers={
72-
"project_status": ShareInspectorStateProvider(assistant_config),
72+
"brief": BriefInspector(assistant_config),
73+
"objectives": LearningInspector(assistant_config),
74+
"requests": SharingInspector(assistant_config),
75+
"debug": DebugInspector(assistant_config),
7376
},
7477
assistant_service_metadata={
7578
**dashboard_card.metadata(
@@ -190,7 +193,7 @@ async def on_conversation_created(context: ConversationContext) -> None:
190193
# Pop open the inspector panel.
191194
await context.send_conversation_state_event(
192195
AssistantStateEvent(
193-
state_id="project_status",
196+
state_id="brief",
194197
event="focus",
195198
state=None,
196199
)
@@ -271,7 +274,7 @@ async def on_message_created(
271274
if len(messages.messages) == 2:
272275
await context.send_conversation_state_event(
273276
AssistantStateEvent(
274-
state_id="project_status",
277+
state_id="brief",
275278
event="focus",
276279
state=None,
277280
)
@@ -544,7 +547,7 @@ async def on_participant_joined(
544547
# Open the Brief tab (state inspector).
545548
await context.send_conversation_state_event(
546549
AssistantStateEvent(
547-
state_id="project_status",
550+
state_id="brief",
548551
event="focus",
549552
state=None,
550553
)

assistants/knowledge-transfer-assistant/assistant/command_processor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
)
2424
from .manager import KnowledgeTransferManager
2525
from .notifications import ProjectNotifier
26-
from .state_inspector import get_priority_emoji, get_status_emoji
26+
from .inspectors.common import get_priority_emoji, get_status_emoji
2727
from .storage import ShareStorage
2828
from .storage_models import ConversationRole
2929

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
Inspector modules for the Knowledge Transfer Assistant.
3+
4+
This package contains the tabbed inspector implementations that provide
5+
different views of the knowledge transfer state in the workbench UI.
6+
"""
7+
8+
from .brief import BriefInspector
9+
from .learning import LearningInspector
10+
from .sharing import SharingInspector
11+
from .debug import DebugInspector
12+
13+
__all__ = ["BriefInspector", "LearningInspector", "SharingInspector", "DebugInspector"]
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""
2+
Brief inspector for knowledge transfer status and brief information.
3+
"""
4+
5+
from typing import Any, List
6+
7+
from semantic_workbench_assistant.assistant_app import (
8+
AssistantConversationInspectorStateDataModel,
9+
ConversationContext,
10+
)
11+
12+
from ..common import detect_assistant_role
13+
from ..conversation_share_link import ConversationKnowledgePackageManager
14+
from ..manager import KnowledgeTransferManager
15+
from ..storage_models import ConversationRole
16+
17+
18+
# Default instructional text to show when no brief has been created
19+
DEFAULT_BRIEF_INSTRUCTION = "_This knowledge brief is displayed in the side panel of all of your team members' conversations, too. Before you share links to your team, ask your assistant to update the brief with whatever details you'd like here. What will help your teammates get off to a good start as they explore the knowledge you are sharing?_"
20+
21+
class BriefInspector:
22+
"""
23+
Inspector for knowledge transfer status and brief information.
24+
25+
Shows role, stage, status message, and knowledge brief content.
26+
"""
27+
28+
display_name = "📋 Brief"
29+
description = "Knowledge share overview"
30+
state_id = "brief"
31+
32+
def __init__(self, config_provider) -> None:
33+
self.config_provider = config_provider
34+
35+
async def is_enabled(self, context: ConversationContext) -> bool:
36+
return True
37+
38+
async def get(self, context: ConversationContext) -> AssistantConversationInspectorStateDataModel:
39+
"""Get brief and status information for display."""
40+
41+
conversation_role = await detect_assistant_role(context)
42+
43+
# Get share information
44+
share_id = await ConversationKnowledgePackageManager.get_associated_share_id(context)
45+
if not share_id:
46+
return AssistantConversationInspectorStateDataModel(
47+
data={"content": "No active knowledge package. Start a conversation to create one."}
48+
)
49+
50+
brief = await KnowledgeTransferManager.get_knowledge_brief(context)
51+
share_info = await KnowledgeTransferManager.get_share_info(context)
52+
53+
if conversation_role == ConversationRole.COORDINATOR:
54+
markdown = await self._format_coordinator_brief(share_id, brief, share_info, context)
55+
else:
56+
markdown = await self._format_team_brief(share_id, brief, share_info, context)
57+
58+
return AssistantConversationInspectorStateDataModel(data={"content": markdown})
59+
60+
async def _format_coordinator_brief(self, share_id: str, brief: Any, share_info: Any, context: ConversationContext) -> str:
61+
"""Format brief information for coordinator."""
62+
63+
lines: List[str] = []
64+
65+
lines.append("**Role:** Coordinator")
66+
67+
# Display knowledge transfer stage
68+
stage_label = "📋 Organizing Knowledge"
69+
if share_info:
70+
stage_label = share_info.get_stage_label(for_coordinator=True)
71+
lines.append(f"**Stage:** {stage_label}")
72+
73+
if share_info and share_info.transfer_notes:
74+
lines.append(f"**Status Message:** {share_info.transfer_notes}")
75+
76+
lines.append("")
77+
78+
# Knowledge Brief section
79+
80+
if brief:
81+
title = brief.title
82+
lines.append(f"## {title}")
83+
lines.append("")
84+
85+
if brief.content:
86+
lines.append(brief.content)
87+
lines.append("")
88+
else:
89+
lines.append("## Knowledge Brief")
90+
lines.append("")
91+
lines.append(DEFAULT_BRIEF_INSTRUCTION)
92+
lines.append("")
93+
94+
95+
return "\n".join(lines)
96+
97+
async def _format_team_brief(self, share_id: str, brief: Any, share_info: Any, context: ConversationContext) -> str:
98+
"""Format brief information for team members."""
99+
100+
lines: List[str] = []
101+
102+
lines.append("**Role:** Team")
103+
104+
# Display knowledge transfer stage for team members
105+
stage_label = "📚 Learning Mode"
106+
if share_info:
107+
stage_label = share_info.get_stage_label(for_coordinator=False)
108+
lines.append(f"**Stage:** {stage_label}")
109+
110+
# Add status message if available
111+
if share_info and share_info.transfer_notes:
112+
lines.append(f"**Status Message:** {share_info.transfer_notes}")
113+
114+
lines.append("")
115+
116+
# Knowledge Brief section
117+
if brief:
118+
title = brief.title
119+
lines.append(f"## {title}")
120+
lines.append("")
121+
122+
if brief.content:
123+
lines.append(brief.content)
124+
lines.append("")
125+
else:
126+
lines.append("## Knowledge Brief")
127+
lines.append("")
128+
lines.append("_The coordinator is still setting up the knowledge brief. Check back soon!_")
129+
lines.append("")
130+
131+
return "\n".join(lines)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Common utilities for inspector modules.
3+
"""
4+
5+
from ..data import RequestPriority, RequestStatus
6+
7+
def get_status_emoji(status: RequestStatus) -> str:
8+
"""Get emoji representation for request status."""
9+
status_emojis = {
10+
RequestStatus.NEW: "🆕", # New
11+
RequestStatus.ACKNOWLEDGED: "👀", # Acknowledged/Seen
12+
RequestStatus.IN_PROGRESS: "⚡", # In Progress
13+
RequestStatus.RESOLVED: "✅", # Resolved/Complete
14+
RequestStatus.DEFERRED: "⏸️", # Deferred/Paused
15+
}
16+
return status_emojis.get(status, "❓") # Unknown status fallback
17+
18+
19+
def get_priority_emoji(priority: RequestPriority) -> str:
20+
"""Get emoji representation for request priority."""
21+
priority_emojis = {
22+
RequestPriority.LOW: "🔹", # Low priority - blue diamond
23+
RequestPriority.MEDIUM: "🔶", # Medium priority - orange diamond
24+
RequestPriority.HIGH: "🔴", # High priority - red circle
25+
RequestPriority.CRITICAL: "⚠️", # Critical priority - warning sign
26+
}
27+
return priority_emojis.get(priority, "🔹") # Default to low priority emoji

0 commit comments

Comments
 (0)