cowork-dash 0.1.3__py3-none-any.whl → 0.1.5__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.
cowork_dash/tools.py CHANGED
@@ -6,7 +6,7 @@ import subprocess
6
6
  from contextlib import redirect_stdout, redirect_stderr
7
7
 
8
8
  from .config import WORKSPACE_ROOT
9
- from .canvas import parse_canvas_object
9
+ from .canvas import parse_canvas_object, generate_canvas_id
10
10
 
11
11
 
12
12
  # =============================================================================
@@ -592,46 +592,123 @@ def clear_notebook_canvas_items() -> Dict[str, Any]:
592
592
  # CANVAS TOOLS
593
593
  # =============================================================================
594
594
 
595
- def add_to_canvas(content: Any) -> Dict[str, Any]:
595
+ def add_to_canvas(content: Any, title: Optional[str] = None, item_id: Optional[str] = None) -> Dict[str, Any]:
596
596
  """Add an item to the canvas for visualization. Canvas is like a note-taking tool where
597
597
  you can store charts, dataframes, images, and markdown text for the user to see.
598
598
 
599
599
  Args:
600
600
  content: Can be a pandas DataFrame, matplotlib Figure, plotly Figure,
601
601
  PIL Image, dictionary (for Plotly JSON), or string (for Markdown)
602
- workspace_root: Path to the workspace root directory
602
+ title: Optional title for the canvas item (displayed as a header)
603
+ item_id: Optional unique ID for the item. If provided, can be used to update
604
+ or remove the item later. Auto-generated if not provided.
603
605
 
604
606
  Returns:
605
- Dictionary with the parsed canvas object
607
+ Dictionary with the parsed canvas object including its id, type, and data
606
608
 
607
609
  Examples:
608
- # Add a DataFrame
610
+ # Add a DataFrame with a title
609
611
  import pandas as pd
610
612
  df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
611
- add_to_canvas(df)
613
+ add_to_canvas(df, title="Sales Data")
612
614
 
613
- # Add a Matplotlib chart
615
+ # Add a Matplotlib chart with a custom ID for later updates
614
616
  import matplotlib.pyplot as plt
615
617
  fig, ax = plt.subplots()
616
618
  ax.plot([1, 2, 3], [1, 4, 9])
617
- add_to_canvas(fig)
619
+ add_to_canvas(fig, title="Growth Chart", item_id="growth_chart")
618
620
 
619
621
  # Add Markdown text
620
- add_to_canvas("## Key Findings\\n- Point 1\\n- Point 2")
622
+ add_to_canvas("## Key Findings\\n- Point 1\\n- Point 2", title="Summary")
623
+
624
+ # Update an existing item by using the same ID
625
+ add_to_canvas(new_fig, item_id="growth_chart") # Replaces the previous chart
621
626
  """
622
627
  try:
623
- # Parse the content into canvas format
624
- parsed = parse_canvas_object(content, workspace_root=WORKSPACE_ROOT)
628
+ # Parse the content into canvas format with optional title and ID
629
+ parsed = parse_canvas_object(
630
+ content,
631
+ workspace_root=WORKSPACE_ROOT,
632
+ title=title,
633
+ item_id=item_id
634
+ )
625
635
  # Return the parsed object (deepagents will handle the JSON serialization)
626
636
  return parsed
627
637
  except Exception as e:
628
638
  return {
629
639
  "type": "error",
640
+ "id": item_id or generate_canvas_id(),
630
641
  "data": f"Failed to add to canvas: {str(e)}",
631
642
  "error": str(e)
632
643
  }
633
644
 
634
645
 
646
+ def update_canvas_item(item_id: str, content: Any, title: Optional[str] = None) -> Dict[str, Any]:
647
+ """Update an existing canvas item by its ID. If the item doesn't exist, it will be added.
648
+
649
+ This is useful for updating charts or data that change over time, like progress
650
+ indicators, live data visualizations, or iteratively refined content.
651
+
652
+ Args:
653
+ item_id: The unique ID of the canvas item to update
654
+ content: The new content (DataFrame, Figure, Image, string, etc.)
655
+ title: Optional new title for the item
656
+
657
+ Returns:
658
+ Dictionary with the updated canvas object
659
+
660
+ Examples:
661
+ # Create an initial chart
662
+ add_to_canvas(initial_fig, title="Progress", item_id="progress_chart")
663
+
664
+ # Later, update it with new data
665
+ update_canvas_item("progress_chart", updated_fig)
666
+
667
+ # Update with a new title too
668
+ update_canvas_item("progress_chart", final_fig, title="Final Results")
669
+ """
670
+ try:
671
+ parsed = parse_canvas_object(
672
+ content,
673
+ workspace_root=WORKSPACE_ROOT,
674
+ title=title,
675
+ item_id=item_id
676
+ )
677
+ parsed["_action"] = "update" # Signal to app.py to update existing item
678
+ return parsed
679
+ except Exception as e:
680
+ return {
681
+ "type": "error",
682
+ "id": item_id,
683
+ "_action": "update",
684
+ "data": f"Failed to update canvas item: {str(e)}",
685
+ "error": str(e)
686
+ }
687
+
688
+
689
+ def remove_canvas_item(item_id: str) -> Dict[str, Any]:
690
+ """Remove a canvas item by its ID.
691
+
692
+ Args:
693
+ item_id: The unique ID of the canvas item to remove
694
+
695
+ Returns:
696
+ Dictionary confirming the removal action
697
+
698
+ Examples:
699
+ # Add a temporary notification
700
+ add_to_canvas("Processing...", title="Status", item_id="status_msg")
701
+
702
+ # Remove it when done
703
+ remove_canvas_item("status_msg")
704
+ """
705
+ return {
706
+ "type": "remove",
707
+ "id": item_id,
708
+ "_action": "remove"
709
+ }
710
+
711
+
635
712
  # =============================================================================
636
713
  # BASH TOOL
637
714
  # =============================================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cowork-dash
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: AI Agent Web Interface with Filesystem and Canvas Visualization
5
5
  Project-URL: Homepage, https://github.com/dkedar7/cowork-dash
6
6
  Project-URL: Documentation, https://github.com/dkedar7/cowork-dash/blob/main/README.md
@@ -51,6 +51,11 @@ Description-Content-Type: text/markdown
51
51
 
52
52
  A web interface for AI agent interactions with filesystem workspace, canvas visualization, and real-time streaming.
53
53
 
54
+ <p align="center">
55
+ <img src="docs/light.png" alt="Cowork Dash - Light Mode" width="48%">
56
+ <img src="docs/dark.png" alt="Cowork Dash - Dark Mode" width="48%">
57
+ </p>
58
+
54
59
  ## Features
55
60
 
56
61
  - **AI Agent Chat**: Real-time streaming with thinking process and task progress
@@ -58,6 +63,15 @@ A web interface for AI agent interactions with filesystem workspace, canvas visu
58
63
  - **Canvas**: Visualize DataFrames, Plotly/Matplotlib charts, Mermaid diagrams, images
59
64
  - **Flexible Configuration**: Environment variables, CLI args, or config file
60
65
 
66
+ ## Demo
67
+
68
+ <p align="center">
69
+ <em>Organizing files with an AI agent</em><br><br>
70
+ <a href="https://www.youtube.com/watch?v=yKB9cBx80VE">
71
+ <img src="https://img.youtube.com/vi/yKB9cBx80VE/maxresdefault.jpg" alt="Cowork Dash Demo Video" width="70%">
72
+ </a>
73
+ </p>
74
+
61
75
  ## Quick Start
62
76
 
63
77
  ### Installation
@@ -68,7 +82,7 @@ pip install cowork-dash
68
82
 
69
83
  # Or run directly with uvx (no installation needed)
70
84
  export ANTHROPIC_API_KEY="your_anthropic_api_key"
71
- uvx cowork-dash run --workspace ~/my-workspace
85
+ cowork-dash run
72
86
  ```
73
87
 
74
88
  ### Run
@@ -100,19 +114,6 @@ Open browser to `http://localhost:8050`
100
114
  2. **Environment Variables** - `DEEPAGENT_*`
101
115
  3. **Config File** - `config.py` defaults
102
116
 
103
- ### Environment Variables (optional)
104
-
105
- ```bash
106
- export DEEPAGENT_SPEC=my_agent.py:agent # Set any Langgraph agent
107
- export DEEPAGENT_WORKSPACE_ROOT=/path/to/workspace
108
- export DEEPAGENT_PORT=9000 # optional (default: 8050)
109
- export DEEPAGENT_HOST=0.0.0.0 # optional (default: localhost)
110
- export DEEPAGENT_DEBUG=true # optional (default: false)
111
- export DEEPAGENT_APP_TITLE="My App" # optional
112
- export DEEPAGENT_APP_SUBTITLE="Subtitle" # optional
113
-
114
- cowork-dash run
115
- ```
116
117
 
117
118
  ### CLI Options (all optional)
118
119
 
@@ -120,12 +121,26 @@ cowork-dash run
120
121
  cowork-dash run [OPTIONS]
121
122
 
122
123
  --workspace PATH Workspace directory (default: current directory)
123
- --agent PATH:OBJECT Agent spec (default: none, manual mode)
124
+ --agent PATH:OBJECT Point to your Langgraph agent (default: default agent, manual mode)
124
125
  --port PORT Server port (default: 8050)
125
126
  --host HOST Server host (default: localhost)
126
127
  --debug Enable debug mode
127
128
  --title TITLE App title (default: "Cowork Dash")
128
129
  --subtitle TEXT App subtitle (default: "AI-Powered Workspace")
130
+ --welcome-message TEXT Welcome message shown in chat (supports markdown)
131
+ ```
132
+
133
+ ### Environment Variables (optional)
134
+
135
+ ```bash
136
+ export DEEPAGENT_SPEC=my_agent.py:agent # Set any Langgraph agent
137
+ export DEEPAGENT_WORKSPACE_ROOT=/path/to/workspace
138
+ export DEEPAGENT_DEBUG=true # optional (default: false)
139
+ export DEEPAGENT_APP_TITLE="My App" # optional
140
+ export DEEPAGENT_APP_SUBTITLE="Subtitle" # optional
141
+ export DEEPAGENT_WELCOME_MESSAGE="Hello!" # optional (supports markdown)
142
+
143
+ cowork-dash run
129
144
  ```
130
145
 
131
146
  ### Python API
@@ -141,27 +156,10 @@ run_app(agent, workspace="~/my-workspace")
141
156
  # Option 2: Use agent spec
142
157
  run_app(agent_spec="my_agent.py:agent", workspace="~/my-workspace")
143
158
 
144
- # Option 3: Manual mode (no agent)
145
- run_app(workspace="~/my-workspace", port=8080, debug=True)
146
159
  ```
147
160
 
148
161
  ## Agent Integration
149
162
 
150
- ### Workspace Access
151
-
152
- Cowork Dash sets `DEEPAGENT_WORKSPACE_ROOT` environment variable for your agent:
153
-
154
- ```python
155
- import os
156
- from pathlib import Path
157
-
158
- # In your agent code
159
- workspace = Path(os.getenv('DEEPAGENT_WORKSPACE_ROOT', './'))
160
-
161
- # Read/write files in workspace
162
- config_file = workspace / "config.json"
163
- ```
164
-
165
163
  ### Agent Specification
166
164
 
167
165
  Load agents using `path:object` format:
@@ -174,13 +172,6 @@ cowork-dash run --agent agent.py:my_agent
174
172
  cowork-dash run --agent /path/to/agent.py:agent_instance
175
173
  ```
176
174
 
177
- ### Agent Requirements
178
-
179
- Your agent must implement:
180
- - **Streaming**: `agent.stream(input, stream_mode="updates")`
181
- - **Message format**: `{"messages": [{"role": "user", "content": "..."}]}`
182
- - **Workspace access** (optional): Read `DEEPAGENT_WORKSPACE_ROOT` env var
183
-
184
175
  ### Example Agent Setup
185
176
 
186
177
  ```python
@@ -0,0 +1,20 @@
1
+ cowork_dash/__init__.py,sha256=37qBKl7g12Zos8GFukXLXligCdpD32e2qe9F8cd8Qdk,896
2
+ cowork_dash/__main__.py,sha256=CCM9VIkWuwh7hwVGNBBgCCbeVAcHj1soyBVXUaPgABk,131
3
+ cowork_dash/agent.py,sha256=A0fz8KEP3iJVm7tTJBGxiBB5q3ArRmeUJdNoAoK8cPQ,4368
4
+ cowork_dash/app.py,sha256=Pcp5l-YWv2f_guH5ol78kQqBlV_TsscEpJyS132565k,95651
5
+ cowork_dash/canvas.py,sha256=sF00c0amtF5AayLG8JKMSPwKEumNfDXd6r6gSDfvTHk,15446
6
+ cowork_dash/cli.py,sha256=RlTRp1VB8f8xbFo_rrNly0COIMMGO0IZi3TYXP3yTCI,6719
7
+ cowork_dash/components.py,sha256=3Nb9zblt3c3cHuE4mP6jLCJI-vALGxcpNqlQ1Sbr_rE,23832
8
+ cowork_dash/config.py,sha256=v-qdQUtWgJE8nYxMgSquMBlWS_tMTfoYx5oPSJt0V30,3774
9
+ cowork_dash/file_utils.py,sha256=R1Pzr05iLfzPgPKIMplF6upTX1sJy1xzMTQ7gjsVesA,9108
10
+ cowork_dash/layout.py,sha256=GQEd_paz4XTVTQqfLYfyabknDMffze3Wor3umuUyhxQ,16003
11
+ cowork_dash/tools.py,sha256=pHX8PhsY70YwCF5JZfb7vZLoc5c89QWQB6T6OhR5svU,25862
12
+ cowork_dash/assets/app.js,sha256=Fo_tgFat9eXtpvrptLHmS0qAs04pfF0IaQYiT-Tohm8,8768
13
+ cowork_dash/assets/favicon.ico,sha256=IiP0rVr0m-TBGGmCY88SyFC14drNwDhLRqb0n2ZufKk,54252
14
+ cowork_dash/assets/favicon.svg,sha256=MdT50APCvIlWh3HSwW5SNXYWB3q_wKfuLP-JV53SnKg,1065
15
+ cowork_dash/assets/styles.css,sha256=iHwGFZhzTP3nQEa_vyhoa-ADAW9DV-kU5OqYP7N2S7Q,23891
16
+ cowork_dash-0.1.5.dist-info/METADATA,sha256=UYjwT-OXwZk5bOwJrLLjdsbUipsZDJQSBsnwSJ0lQ8c,6719
17
+ cowork_dash-0.1.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
18
+ cowork_dash-0.1.5.dist-info/entry_points.txt,sha256=lL_9XJINiky3nh13tLqWd61LitKbbyh085ROATH9fck,53
19
+ cowork_dash-0.1.5.dist-info/licenses/LICENSE,sha256=2SFXFfIa_c_g_uwY0JApQDXI1mWqEfJeG87Pn4ehLMQ,1072
20
+ cowork_dash-0.1.5.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- cowork_dash/__init__.py,sha256=37qBKl7g12Zos8GFukXLXligCdpD32e2qe9F8cd8Qdk,896
2
- cowork_dash/__main__.py,sha256=CCM9VIkWuwh7hwVGNBBgCCbeVAcHj1soyBVXUaPgABk,131
3
- cowork_dash/agent.py,sha256=dj50jBzP69YgEzEF44IeE8p11X0ap3xKwdITORnpkhs,4318
4
- cowork_dash/app.py,sha256=kMTLzE6FA6cDwuWIxSCB62YZ_Z1an6PaX9sv220o6mI,70709
5
- cowork_dash/canvas.py,sha256=9X_Z6gOwFwIfBk8rsXi4s1hpKAyaK6wglgZ_1UGjZ3E,11093
6
- cowork_dash/cli.py,sha256=N9APQlQ-5oahUxMoICpJV1FcmVOFNmJpCfaULDeYhRY,6491
7
- cowork_dash/components.py,sha256=VDJ_IQ8qW7O3dAMVoz97yzBByRBC7XvpnVmDMCIlEUY,20538
8
- cowork_dash/config.py,sha256=6SfKDJmcK4X2ew4ao53Cg_RKqhDIw5V3BFiaDxbvKsY,3207
9
- cowork_dash/file_utils.py,sha256=s2-L5wFOE-ChpKaZQwdRUSx5qA96ATR1QtmpkrJXUJY,8542
10
- cowork_dash/layout.py,sha256=e9E0okLhGf4E-slFjO0udyVD5IrpbVgXS4fXHZsMiXQ,11225
11
- cowork_dash/tools.py,sha256=6WYK9-s32R5PfZvcpBIR55Z0I6wBgrxJvcxcgfnQ54E,23125
12
- cowork_dash/assets/app.js,sha256=CIRhskgTn4zPJGfubTYvsZFYSj-0XJNniGlSggy75L4,8162
13
- cowork_dash/assets/favicon.svg,sha256=MdT50APCvIlWh3HSwW5SNXYWB3q_wKfuLP-JV53SnKg,1065
14
- cowork_dash/assets/styles.css,sha256=ZiWpULBDO64Hu6bZ5NYFbzDfQ8Ezn66eKjW1LpJ8anM,20621
15
- cowork_dash-0.1.3.dist-info/METADATA,sha256=4UGO7YjH0El6Ta4vEMZSK0bgCSPgy4rqTHfgdYMAvOA,6959
16
- cowork_dash-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
- cowork_dash-0.1.3.dist-info/entry_points.txt,sha256=lL_9XJINiky3nh13tLqWd61LitKbbyh085ROATH9fck,53
18
- cowork_dash-0.1.3.dist-info/licenses/LICENSE,sha256=2SFXFfIa_c_g_uwY0JApQDXI1mWqEfJeG87Pn4ehLMQ,1072
19
- cowork_dash-0.1.3.dist-info/RECORD,,