openwork 0.1.1-rc.0 → 0.1.1-rc.2
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.
package/out/main/index.js
CHANGED
|
@@ -139,21 +139,63 @@ const AVAILABLE_MODELS = [
|
|
|
139
139
|
description: "Fast and cost-effective for real-time tasks",
|
|
140
140
|
available: true
|
|
141
141
|
},
|
|
142
|
-
// OpenAI GPT-5
|
|
142
|
+
// OpenAI GPT-5 series (latest as of Jan 2026)
|
|
143
|
+
{
|
|
144
|
+
id: "gpt-5.2",
|
|
145
|
+
name: "GPT-5.2",
|
|
146
|
+
provider: "openai",
|
|
147
|
+
model: "gpt-5.2",
|
|
148
|
+
description: "Latest flagship with enhanced coding and agentic capabilities",
|
|
149
|
+
available: true
|
|
150
|
+
},
|
|
143
151
|
{
|
|
144
152
|
id: "gpt-5.1",
|
|
145
153
|
name: "GPT-5.1",
|
|
146
154
|
provider: "openai",
|
|
147
155
|
model: "gpt-5.1",
|
|
148
|
-
description: "
|
|
156
|
+
description: "Advanced reasoning and robust performance",
|
|
157
|
+
available: true
|
|
158
|
+
},
|
|
159
|
+
// OpenAI o-series reasoning models
|
|
160
|
+
{
|
|
161
|
+
id: "o3",
|
|
162
|
+
name: "o3",
|
|
163
|
+
provider: "openai",
|
|
164
|
+
model: "o3",
|
|
165
|
+
description: "Advanced reasoning for complex problem-solving",
|
|
166
|
+
available: true
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: "o3-mini",
|
|
170
|
+
name: "o3 Mini",
|
|
171
|
+
provider: "openai",
|
|
172
|
+
model: "o3-mini",
|
|
173
|
+
description: "Cost-effective reasoning with faster response times",
|
|
174
|
+
available: true
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "o4-mini",
|
|
178
|
+
name: "o4 Mini",
|
|
179
|
+
provider: "openai",
|
|
180
|
+
model: "o4-mini",
|
|
181
|
+
description: "Fast, efficient reasoning model succeeding o3",
|
|
182
|
+
available: true
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "o1",
|
|
186
|
+
name: "o1",
|
|
187
|
+
provider: "openai",
|
|
188
|
+
model: "o1",
|
|
189
|
+
description: "Premium reasoning for research, coding, math and science",
|
|
149
190
|
available: true
|
|
150
191
|
},
|
|
192
|
+
// OpenAI GPT-4 series
|
|
151
193
|
{
|
|
152
194
|
id: "gpt-4.1",
|
|
153
195
|
name: "GPT-4.1",
|
|
154
196
|
provider: "openai",
|
|
155
197
|
model: "gpt-4.1",
|
|
156
|
-
description: "
|
|
198
|
+
description: "Strong instruction-following with 1M context window",
|
|
157
199
|
available: true
|
|
158
200
|
},
|
|
159
201
|
{
|
|
@@ -161,7 +203,31 @@ const AVAILABLE_MODELS = [
|
|
|
161
203
|
name: "GPT-4.1 Mini",
|
|
162
204
|
provider: "openai",
|
|
163
205
|
model: "gpt-4.1-mini",
|
|
164
|
-
description: "
|
|
206
|
+
description: "Faster, smaller version balancing performance and efficiency",
|
|
207
|
+
available: true
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: "gpt-4.1-nano",
|
|
211
|
+
name: "GPT-4.1 Nano",
|
|
212
|
+
provider: "openai",
|
|
213
|
+
model: "gpt-4.1-nano",
|
|
214
|
+
description: "Most cost-efficient for lighter tasks",
|
|
215
|
+
available: true
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "gpt-4o",
|
|
219
|
+
name: "GPT-4o",
|
|
220
|
+
provider: "openai",
|
|
221
|
+
model: "gpt-4o",
|
|
222
|
+
description: "Versatile model for text generation and comprehension",
|
|
223
|
+
available: true
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: "gpt-4o-mini",
|
|
227
|
+
name: "GPT-4o Mini",
|
|
228
|
+
provider: "openai",
|
|
229
|
+
model: "gpt-4o-mini",
|
|
230
|
+
description: "Cost-efficient variant with faster response times",
|
|
165
231
|
available: true
|
|
166
232
|
},
|
|
167
233
|
// Google Gemini 3 series (latest as of Jan 2026)
|
|
@@ -702,6 +768,112 @@ class SqlJsSaver extends langgraphCheckpoint.BaseCheckpointSaver {
|
|
|
702
768
|
}
|
|
703
769
|
}
|
|
704
770
|
}
|
|
771
|
+
const BASE_SYSTEM_PROMPT = `You are an AI assistant that helps users with various tasks including coding, research, and analysis.
|
|
772
|
+
|
|
773
|
+
# Core Behavior
|
|
774
|
+
|
|
775
|
+
Be concise and direct. Answer in fewer than 4 lines unless the user asks for detail.
|
|
776
|
+
After working on a file, just stop - don't explain what you did unless asked.
|
|
777
|
+
Avoid unnecessary introductions or conclusions.
|
|
778
|
+
|
|
779
|
+
When you run non-trivial bash commands, briefly explain what they do.
|
|
780
|
+
|
|
781
|
+
## Proactiveness
|
|
782
|
+
Take action when asked, but don't surprise users with unrequested actions.
|
|
783
|
+
If asked how to approach something, answer first before taking action.
|
|
784
|
+
|
|
785
|
+
## Following Conventions
|
|
786
|
+
- Check existing code for libraries and frameworks before assuming availability
|
|
787
|
+
- Mimic existing code style, naming conventions, and patterns
|
|
788
|
+
- Never add comments unless asked
|
|
789
|
+
|
|
790
|
+
## Task Management
|
|
791
|
+
Use write_todos for complex multi-step tasks (3+ steps). Mark tasks in_progress before starting, completed immediately after finishing.
|
|
792
|
+
For simple 1-2 step tasks, just do them directly without todos.
|
|
793
|
+
|
|
794
|
+
## File Reading Best Practices
|
|
795
|
+
|
|
796
|
+
When exploring codebases or reading multiple files, use pagination to prevent context overflow.
|
|
797
|
+
|
|
798
|
+
**Pattern for codebase exploration:**
|
|
799
|
+
1. First scan: \`read_file(path, limit=100)\` - See file structure and key sections
|
|
800
|
+
2. Targeted read: \`read_file(path, offset=100, limit=200)\` - Read specific sections if needed
|
|
801
|
+
3. Full read: Only use \`read_file(path)\` without limit when necessary for editing
|
|
802
|
+
|
|
803
|
+
**When to paginate:**
|
|
804
|
+
- Reading any file >500 lines
|
|
805
|
+
- Exploring unfamiliar codebases (always start with limit=100)
|
|
806
|
+
- Reading multiple files in sequence
|
|
807
|
+
|
|
808
|
+
**When full read is OK:**
|
|
809
|
+
- Small files (<500 lines)
|
|
810
|
+
- Files you need to edit immediately after reading
|
|
811
|
+
|
|
812
|
+
## Working with Subagents (task tool)
|
|
813
|
+
When delegating to subagents:
|
|
814
|
+
- **Use filesystem for large I/O**: If input/output is large (>500 words), communicate via files
|
|
815
|
+
- **Parallelize independent work**: Spawn parallel subagents for independent tasks
|
|
816
|
+
- **Clear specifications**: Tell subagent exactly what format/structure you need
|
|
817
|
+
- **Main agent synthesizes**: Subagents gather/execute, main agent integrates results
|
|
818
|
+
|
|
819
|
+
## Tools
|
|
820
|
+
|
|
821
|
+
### File Tools
|
|
822
|
+
- read_file: Read file contents
|
|
823
|
+
- edit_file: Replace exact strings in files (must read first, provide unique old_string)
|
|
824
|
+
- write_file: Create or overwrite files
|
|
825
|
+
- ls: List directory contents (use "/" for workspace root)
|
|
826
|
+
- glob: Find files by pattern (e.g., "**/*.py")
|
|
827
|
+
- grep: Search file contents
|
|
828
|
+
|
|
829
|
+
All file paths are virtual paths relative to the workspace root, starting with /.
|
|
830
|
+
|
|
831
|
+
## Code References
|
|
832
|
+
When referencing code, use format: \`file_path:line_number\`
|
|
833
|
+
|
|
834
|
+
## Documentation
|
|
835
|
+
- Do NOT create excessive markdown summary/documentation files after completing work
|
|
836
|
+
- Focus on the work itself, not documenting what you did
|
|
837
|
+
- Only create documentation when explicitly requested
|
|
838
|
+
|
|
839
|
+
## Human-in-the-Loop Tool Approval
|
|
840
|
+
|
|
841
|
+
Some tool calls require user approval before execution. When a tool call is rejected by the user:
|
|
842
|
+
1. Accept their decision immediately - do NOT retry the same command
|
|
843
|
+
2. Explain that you understand they rejected the action
|
|
844
|
+
3. Suggest an alternative approach or ask for clarification
|
|
845
|
+
4. Never attempt the exact same rejected command again
|
|
846
|
+
|
|
847
|
+
Respect the user's decisions and work with them collaboratively.
|
|
848
|
+
|
|
849
|
+
## Todo List Management
|
|
850
|
+
|
|
851
|
+
When using the write_todos tool:
|
|
852
|
+
1. Keep the todo list MINIMAL - aim for 3-6 items maximum
|
|
853
|
+
2. Only create todos for complex, multi-step tasks that truly need tracking
|
|
854
|
+
3. Break down work into clear, actionable items without over-fragmenting
|
|
855
|
+
4. For simple tasks (1-2 steps), just do them directly without creating todos
|
|
856
|
+
5. When first creating a todo list for a task, ALWAYS ask the user if the plan looks good before starting work
|
|
857
|
+
- Create the todos, let them render, then ask: "Does this plan look good?" or similar
|
|
858
|
+
- Wait for the user's response before marking the first todo as in_progress
|
|
859
|
+
- If they want changes, adjust the plan accordingly
|
|
860
|
+
6. Update todo status promptly as you complete each item
|
|
861
|
+
|
|
862
|
+
The todo list is a planning tool - use it judiciously to avoid overwhelming the user with excessive task tracking.
|
|
863
|
+
`;
|
|
864
|
+
function getSystemPrompt(workspacePath) {
|
|
865
|
+
const workingDirSection = `
|
|
866
|
+
### File System and Paths
|
|
867
|
+
|
|
868
|
+
**IMPORTANT - Path Handling:**
|
|
869
|
+
- All file paths use virtual paths starting with \`/\` (the workspace root)
|
|
870
|
+
- \`/\` refers to the workspace root directory
|
|
871
|
+
- Example: \`/src/index.ts\`, \`/README.md\`, \`/package.json\`
|
|
872
|
+
- To list the workspace root, use \`ls("/")\`
|
|
873
|
+
- Never use fully qualified system paths like \`${workspacePath}/...\`
|
|
874
|
+
`;
|
|
875
|
+
return workingDirSection + BASE_SYSTEM_PROMPT;
|
|
876
|
+
}
|
|
705
877
|
let checkpointer = null;
|
|
706
878
|
async function getCheckpointer() {
|
|
707
879
|
if (!checkpointer) {
|
|
@@ -724,7 +896,7 @@ function getModelInstance(modelId) {
|
|
|
724
896
|
model,
|
|
725
897
|
anthropicApiKey: apiKey
|
|
726
898
|
});
|
|
727
|
-
} else if (model.startsWith("gpt")) {
|
|
899
|
+
} else if (model.startsWith("gpt") || model.startsWith("o1") || model.startsWith("o3") || model.startsWith("o4")) {
|
|
728
900
|
const apiKey = getApiKey("openai");
|
|
729
901
|
console.log("[Runtime] OpenAI API key present:", !!apiKey);
|
|
730
902
|
if (!apiKey) {
|
|
@@ -742,7 +914,9 @@ function getModelInstance(modelId) {
|
|
|
742
914
|
async function createAgentRuntime(options) {
|
|
743
915
|
const { modelId, workspacePath } = options;
|
|
744
916
|
if (!workspacePath) {
|
|
745
|
-
throw new Error(
|
|
917
|
+
throw new Error(
|
|
918
|
+
"Workspace path is required. Please select a workspace folder before running the agent."
|
|
919
|
+
);
|
|
746
920
|
}
|
|
747
921
|
console.log("[Runtime] Creating agent runtime...");
|
|
748
922
|
console.log("[Runtime] Workspace path:", workspacePath);
|
|
@@ -753,12 +927,13 @@ async function createAgentRuntime(options) {
|
|
|
753
927
|
const backend = new deepagents.FilesystemBackend({
|
|
754
928
|
rootDir: workspacePath,
|
|
755
929
|
virtualMode: true
|
|
756
|
-
// Use virtual paths starting with /
|
|
757
930
|
});
|
|
931
|
+
const systemPrompt = getSystemPrompt(workspacePath);
|
|
758
932
|
const agent = deepagents.createDeepAgent({
|
|
759
933
|
model,
|
|
760
934
|
checkpointer: checkpointer2,
|
|
761
|
-
backend
|
|
935
|
+
backend,
|
|
936
|
+
systemPrompt
|
|
762
937
|
});
|
|
763
938
|
console.log("[Runtime] Deep agent created with FilesystemBackend at:", workspacePath);
|
|
764
939
|
return agent;
|
|
@@ -1845,6 +1845,16 @@
|
|
|
1845
1845
|
}
|
|
1846
1846
|
|
|
1847
1847
|
@media (hover: hover) {
|
|
1848
|
+
.hover\:bg-accent\/50:hover {
|
|
1849
|
+
background-color: var(--accent);
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1853
|
+
.hover\:bg-accent\/50:hover {
|
|
1854
|
+
background-color: color-mix(in oklab, var(--accent) 50%, transparent);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1848
1858
|
.hover\:bg-background-interactive:hover {
|
|
1849
1859
|
background-color: var(--background-interactive);
|
|
1850
1860
|
}
|
|
@@ -73633,6 +73633,25 @@ function ModelSwitcher() {
|
|
|
73633
73633
|
)
|
|
73634
73634
|
] });
|
|
73635
73635
|
}
|
|
73636
|
+
async function selectWorkspaceFolder(currentThreadId, setWorkspacePath, setWorkspaceFiles, setLoading, setOpen) {
|
|
73637
|
+
if (!currentThreadId) return;
|
|
73638
|
+
setLoading(true);
|
|
73639
|
+
try {
|
|
73640
|
+
const path2 = await window.api.workspace.select(currentThreadId);
|
|
73641
|
+
if (path2) {
|
|
73642
|
+
setWorkspacePath(path2);
|
|
73643
|
+
const result = await window.api.workspace.loadFromDisk(currentThreadId);
|
|
73644
|
+
if (result.success && result.files) {
|
|
73645
|
+
setWorkspaceFiles(result.files);
|
|
73646
|
+
}
|
|
73647
|
+
}
|
|
73648
|
+
if (setOpen) setOpen(false);
|
|
73649
|
+
} catch (e) {
|
|
73650
|
+
console.error("[WorkspacePicker] Select folder error:", e);
|
|
73651
|
+
} finally {
|
|
73652
|
+
setLoading(false);
|
|
73653
|
+
}
|
|
73654
|
+
}
|
|
73636
73655
|
function WorkspacePicker() {
|
|
73637
73656
|
const { workspacePath, currentThreadId, setWorkspacePath, setWorkspaceFiles } = useAppStore();
|
|
73638
73657
|
const [open, setOpen] = reactExports.useState(false);
|
|
@@ -73653,23 +73672,7 @@ function WorkspacePicker() {
|
|
|
73653
73672
|
loadWorkspace();
|
|
73654
73673
|
}, [currentThreadId, setWorkspacePath, setWorkspaceFiles]);
|
|
73655
73674
|
async function handleSelectFolder() {
|
|
73656
|
-
|
|
73657
|
-
setLoading(true);
|
|
73658
|
-
try {
|
|
73659
|
-
const path2 = await window.api.workspace.select(currentThreadId);
|
|
73660
|
-
if (path2) {
|
|
73661
|
-
setWorkspacePath(path2);
|
|
73662
|
-
const result = await window.api.workspace.loadFromDisk(currentThreadId);
|
|
73663
|
-
if (result.success && result.files) {
|
|
73664
|
-
setWorkspaceFiles(result.files);
|
|
73665
|
-
}
|
|
73666
|
-
}
|
|
73667
|
-
setOpen(false);
|
|
73668
|
-
} catch (e) {
|
|
73669
|
-
console.error("[WorkspacePicker] Select folder error:", e);
|
|
73670
|
-
} finally {
|
|
73671
|
-
setLoading(false);
|
|
73672
|
-
}
|
|
73675
|
+
await selectWorkspaceFolder(currentThreadId, setWorkspacePath, setWorkspaceFiles, setLoading, setOpen);
|
|
73673
73676
|
}
|
|
73674
73677
|
const folderName = workspacePath?.split("/").pop();
|
|
73675
73678
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
@@ -74656,13 +74659,31 @@ function ChatContainer({ threadId }) {
|
|
|
74656
74659
|
const handleCancel = async () => {
|
|
74657
74660
|
await stream.stop();
|
|
74658
74661
|
};
|
|
74662
|
+
const handleSelectWorkspaceFromEmptyState = async () => {
|
|
74663
|
+
await selectWorkspaceFolder(threadId, setWorkspacePath, setWorkspaceFiles, () => {
|
|
74664
|
+
}, void 0);
|
|
74665
|
+
};
|
|
74659
74666
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
|
|
74660
74667
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", ref: scrollRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-3xl mx-auto space-y-4", children: [
|
|
74661
74668
|
displayMessages.length === 0 && !stream.isLoading && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-20 text-muted-foreground", children: [
|
|
74662
74669
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-2", children: "NEW THREAD" }),
|
|
74663
|
-
workspacePath ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm", children: "Start a conversation with the agent" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center", children: [
|
|
74664
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
74665
|
-
|
|
74670
|
+
workspacePath ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm", children: "Start a conversation with the agent" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center space-y-3", children: [
|
|
74671
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
74672
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-500", children: "Select a workspace folder" }),
|
|
74673
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs mt-1 opacity-75", children: "The agent needs a workspace to create and modify files" })
|
|
74674
|
+
] }),
|
|
74675
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
74676
|
+
"button",
|
|
74677
|
+
{
|
|
74678
|
+
type: "button",
|
|
74679
|
+
className: "inline-flex items-center justify-center rounded-md border border-border bg-background px-2 h-7 text-xs gap-1.5 text-amber-500 hover:bg-accent/50 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
74680
|
+
onClick: handleSelectWorkspaceFromEmptyState,
|
|
74681
|
+
children: [
|
|
74682
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-3.5" }),
|
|
74683
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "max-w-[120px] truncate", children: "Select workspace" })
|
|
74684
|
+
]
|
|
74685
|
+
}
|
|
74686
|
+
)
|
|
74666
74687
|
] })
|
|
74667
74688
|
] }),
|
|
74668
74689
|
displayMessages.map((message) => /* @__PURE__ */ jsxRuntimeExports.jsx(MessageBubble, { message, toolResults }, message.id)),
|
|
@@ -75514,7 +75535,7 @@ function App() {
|
|
|
75514
75535
|
},
|
|
75515
75536
|
children: [
|
|
75516
75537
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
|
|
75517
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.1.1-rc.
|
|
75538
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.1.1-rc.2" })
|
|
75518
75539
|
]
|
|
75519
75540
|
}
|
|
75520
75541
|
),
|
package/out/renderer/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
http-equiv="Content-Security-Policy"
|
|
8
8
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
|
9
9
|
/>
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-Dyv8tZ_T.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/index-D2W2biEe.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openwork",
|
|
3
|
-
"version": "0.1.1-rc.
|
|
3
|
+
"version": "0.1.1-rc.2",
|
|
4
4
|
"description": "A tactical agent interface for deepagentsjs",
|
|
5
5
|
"main": "./out/main/index.js",
|
|
6
6
|
"files": [
|
|
@@ -102,5 +102,6 @@
|
|
|
102
102
|
"tailwindcss": "^4.0.0",
|
|
103
103
|
"typescript": "^5.9.3",
|
|
104
104
|
"vite": "^7.2.6"
|
|
105
|
-
}
|
|
105
|
+
},
|
|
106
|
+
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
|
|
106
107
|
}
|