cowork-os 0.3.21 → 0.3.25
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/README.md +372 -10
- package/connectors/README.md +20 -0
- package/connectors/asana-mcp/README.md +24 -0
- package/connectors/asana-mcp/dist/index.js +427 -0
- package/connectors/asana-mcp/package.json +15 -0
- package/connectors/asana-mcp/src/index.ts +553 -0
- package/connectors/asana-mcp/tsconfig.json +13 -0
- package/connectors/hubspot-mcp/README.md +35 -0
- package/connectors/hubspot-mcp/dist/index.js +454 -0
- package/connectors/hubspot-mcp/package.json +15 -0
- package/connectors/hubspot-mcp/src/index.ts +562 -0
- package/connectors/hubspot-mcp/tsconfig.json +13 -0
- package/connectors/jira-mcp/README.md +49 -0
- package/connectors/jira-mcp/dist/index.js +588 -0
- package/connectors/jira-mcp/package.json +15 -0
- package/connectors/jira-mcp/src/index.ts +711 -0
- package/connectors/jira-mcp/tsconfig.json +13 -0
- package/connectors/linear-mcp/README.md +22 -0
- package/connectors/linear-mcp/dist/index.js +402 -0
- package/connectors/linear-mcp/package.json +15 -0
- package/connectors/linear-mcp/src/index.ts +522 -0
- package/connectors/linear-mcp/tsconfig.json +13 -0
- package/connectors/okta-mcp/README.md +24 -0
- package/connectors/okta-mcp/dist/index.js +411 -0
- package/connectors/okta-mcp/package.json +15 -0
- package/connectors/okta-mcp/src/index.ts +520 -0
- package/connectors/okta-mcp/tsconfig.json +13 -0
- package/connectors/salesforce-mcp/README.md +47 -0
- package/connectors/salesforce-mcp/dist/index.js +584 -0
- package/connectors/salesforce-mcp/package.json +15 -0
- package/connectors/salesforce-mcp/src/index.ts +722 -0
- package/connectors/salesforce-mcp/tsconfig.json +13 -0
- package/connectors/servicenow-mcp/README.md +26 -0
- package/connectors/servicenow-mcp/dist/index.js +400 -0
- package/connectors/servicenow-mcp/package.json +15 -0
- package/connectors/servicenow-mcp/src/index.ts +500 -0
- package/connectors/servicenow-mcp/tsconfig.json +13 -0
- package/connectors/templates/mcp-connector/README.md +31 -0
- package/connectors/templates/mcp-connector/package.json +15 -0
- package/connectors/templates/mcp-connector/src/index.ts +330 -0
- package/connectors/templates/mcp-connector/tsconfig.json +13 -0
- package/connectors/zendesk-mcp/README.md +40 -0
- package/connectors/zendesk-mcp/dist/index.js +431 -0
- package/connectors/zendesk-mcp/package.json +15 -0
- package/connectors/zendesk-mcp/src/index.ts +543 -0
- package/connectors/zendesk-mcp/tsconfig.json +13 -0
- package/dist/electron/electron/agent/custom-skill-loader.js +31 -1
- package/dist/electron/electron/agent/daemon.js +189 -13
- package/dist/electron/electron/agent/executor.js +895 -78
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
- package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
- package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
- package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
- package/dist/electron/electron/agent/llm/index.js +13 -1
- package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
- package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
- package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
- package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
- package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
- package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
- package/dist/electron/electron/agent/llm/types.js +66 -1
- package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
- package/dist/electron/electron/agent/search/provider-factory.js +38 -2
- package/dist/electron/electron/agent/tools/box-tools.js +231 -0
- package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
- package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
- package/dist/electron/electron/agent/tools/file-tools.js +66 -3
- package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
- package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
- package/dist/electron/electron/agent/tools/image-tools.js +11 -1
- package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
- package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
- package/dist/electron/electron/agent/tools/registry.js +548 -10
- package/dist/electron/electron/agent/tools/search-tools.js +28 -10
- package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
- package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
- package/dist/electron/electron/agent/tools/x-tools.js +1 -1
- package/dist/electron/electron/agents/agent-dispatch.js +63 -0
- package/dist/electron/electron/database/repositories.js +19 -5
- package/dist/electron/electron/database/schema.js +8 -0
- package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
- package/dist/electron/electron/gateway/index.js +75 -1
- package/dist/electron/electron/gateway/router.js +209 -154
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +763 -267
- package/dist/electron/electron/main.js +63 -0
- package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
- package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
- package/dist/electron/electron/memory/MemoryService.js +2 -1
- package/dist/electron/electron/preload.js +78 -1
- package/dist/electron/electron/settings/appearance-manager.js +18 -1
- package/dist/electron/electron/settings/box-manager.js +54 -0
- package/dist/electron/electron/settings/dropbox-manager.js +54 -0
- package/dist/electron/electron/settings/google-drive-manager.js +54 -0
- package/dist/electron/electron/settings/notion-manager.js +56 -0
- package/dist/electron/electron/settings/onedrive-manager.js +54 -0
- package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
- package/dist/electron/electron/utils/box-api.js +153 -0
- package/dist/electron/electron/utils/dropbox-api.js +144 -0
- package/dist/electron/electron/utils/env-migration.js +19 -0
- package/dist/electron/electron/utils/google-drive-api.js +152 -0
- package/dist/electron/electron/utils/notion-api.js +103 -0
- package/dist/electron/electron/utils/onedrive-api.js +113 -0
- package/dist/electron/electron/utils/sharepoint-api.js +109 -0
- package/dist/electron/electron/utils/validation.js +98 -3
- package/dist/electron/electron/utils/x-cli.js +1 -1
- package/dist/electron/shared/channelMessages.js +284 -3
- package/dist/electron/shared/llm-provider-catalog.js +198 -0
- package/dist/electron/shared/types.js +90 -1
- package/package.json +14 -3
- package/resources/skills/nano-banana-pro.json +4 -4
- package/resources/skills/openai-image-gen.json +3 -3
- package/resources/skills/scripts/gen.py +163 -0
- package/resources/skills/scripts/generate_image.py +91 -0
- package/src/electron/agent/custom-skill-loader.ts +34 -1
- package/src/electron/agent/daemon.ts +210 -14
- package/src/electron/agent/executor.ts +1124 -85
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
- package/src/electron/agent/llm/bedrock-provider.ts +62 -9
- package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
- package/src/electron/agent/llm/groq-provider.ts +39 -0
- package/src/electron/agent/llm/index.ts +6 -0
- package/src/electron/agent/llm/kimi-provider.ts +39 -0
- package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
- package/src/electron/agent/llm/openai-compatible.ts +133 -0
- package/src/electron/agent/llm/openai-oauth.ts +2 -1
- package/src/electron/agent/llm/openrouter-provider.ts +2 -1
- package/src/electron/agent/llm/provider-factory.ts +459 -6
- package/src/electron/agent/llm/types.ts +95 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/search/provider-factory.ts +43 -2
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +36 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/file-tools.ts +66 -3
- package/src/electron/agent/tools/gmail-tools.ts +240 -0
- package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- package/src/electron/agent/tools/grep-tools.ts +97 -12
- package/src/electron/agent/tools/image-tools.ts +11 -1
- package/src/electron/agent/tools/notion-tools.ts +330 -0
- package/src/electron/agent/tools/onedrive-tools.ts +217 -0
- package/src/electron/agent/tools/registry.ts +794 -10
- package/src/electron/agent/tools/search-tools.ts +29 -11
- package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
- package/src/electron/agent/tools/shell-tools.ts +11 -3
- package/src/electron/agent/tools/x-tools.ts +1 -1
- package/src/electron/agents/agent-dispatch.ts +79 -0
- package/src/electron/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/database/repositories.ts +58 -6
- package/src/electron/database/schema.ts +8 -0
- package/src/electron/gateway/channels/discord.ts +4 -0
- package/src/electron/gateway/channels/google-chat.ts +3 -0
- package/src/electron/gateway/channels/line.ts +3 -0
- package/src/electron/gateway/channels/matrix-client.ts +15 -0
- package/src/electron/gateway/channels/matrix.ts +31 -0
- package/src/electron/gateway/channels/mattermost.ts +3 -0
- package/src/electron/gateway/channels/signal.ts +3 -0
- package/src/electron/gateway/channels/slack.ts +9 -4
- package/src/electron/gateway/channels/teams.ts +4 -0
- package/src/electron/gateway/channels/telegram.ts +2 -0
- package/src/electron/gateway/channels/twitch.ts +2 -0
- package/src/electron/gateway/channels/types.ts +8 -0
- package/src/electron/gateway/channels/whatsapp.ts +66 -0
- package/src/electron/gateway/index.ts +95 -2
- package/src/electron/gateway/router.ts +231 -161
- package/src/electron/gateway/security.ts +21 -9
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +848 -292
- package/src/electron/main.ts +35 -0
- package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
- package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
- package/src/electron/memory/MemoryService.ts +7 -1
- package/src/electron/preload.ts +200 -5
- package/src/electron/settings/appearance-manager.ts +20 -2
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-workspace-manager.ts +59 -0
- package/src/electron/settings/notion-manager.ts +60 -0
- package/src/electron/settings/onedrive-manager.ts +58 -0
- package/src/electron/settings/sharepoint-manager.ts +58 -0
- package/src/electron/utils/box-api.ts +184 -0
- package/src/electron/utils/dropbox-api.ts +171 -0
- package/src/electron/utils/env-migration.ts +22 -0
- package/src/electron/utils/gmail-api.ts +121 -0
- package/src/electron/utils/google-calendar-api.ts +115 -0
- package/src/electron/utils/google-workspace-api.ts +228 -0
- package/src/electron/utils/google-workspace-auth.ts +109 -0
- package/src/electron/utils/google-workspace-oauth.ts +232 -0
- package/src/electron/utils/notion-api.ts +126 -0
- package/src/electron/utils/onedrive-api.ts +137 -0
- package/src/electron/utils/sharepoint-api.ts +132 -0
- package/src/electron/utils/validation.ts +128 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +119 -8
- package/src/renderer/components/ActivityFeedItem.tsx +34 -17
- package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
- package/src/renderer/components/AppearanceSettings.tsx +37 -2
- package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
- package/src/renderer/components/BoxSettings.tsx +203 -0
- package/src/renderer/components/BrowserView.tsx +101 -0
- package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
- package/src/renderer/components/CanvasPreview.tsx +68 -1
- package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
- package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
- package/src/renderer/components/ConnectorsSettings.tsx +397 -0
- package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
- package/src/renderer/components/DiscordSettings.tsx +18 -7
- package/src/renderer/components/DropboxSettings.tsx +202 -0
- package/src/renderer/components/EmailSettings.tsx +18 -7
- package/src/renderer/components/FileViewer.tsx +21 -13
- package/src/renderer/components/GoogleChatSettings.tsx +17 -7
- package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
- package/src/renderer/components/ImessageSettings.tsx +22 -11
- package/src/renderer/components/LineIcons.tsx +376 -0
- package/src/renderer/components/LineSettings.tsx +18 -7
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +740 -76
- package/src/renderer/components/MatrixSettings.tsx +18 -7
- package/src/renderer/components/MattermostSettings.tsx +18 -7
- package/src/renderer/components/NodesSettings.tsx +58 -99
- package/src/renderer/components/NotificationPanel.tsx +25 -11
- package/src/renderer/components/NotionSettings.tsx +231 -0
- package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
- package/src/renderer/components/OnboardingModal.tsx +70 -1
- package/src/renderer/components/OneDriveSettings.tsx +212 -0
- package/src/renderer/components/RightPanel.tsx +141 -28
- package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
- package/src/renderer/components/SearchSettings.tsx +118 -114
- package/src/renderer/components/Settings.tsx +1425 -651
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +94 -19
- package/src/renderer/components/SignalSettings.tsx +18 -7
- package/src/renderer/components/SkillHubBrowser.tsx +144 -185
- package/src/renderer/components/SlackSettings.tsx +18 -7
- package/src/renderer/components/TaskQuickActions.tsx +11 -6
- package/src/renderer/components/TaskTimeline.tsx +58 -26
- package/src/renderer/components/TeamsSettings.tsx +18 -7
- package/src/renderer/components/TelegramSettings.tsx +18 -7
- package/src/renderer/components/ThemeIcon.tsx +16 -0
- package/src/renderer/components/TwitchSettings.tsx +18 -7
- package/src/renderer/components/VoiceSettings.tsx +30 -74
- package/src/renderer/components/WhatsAppSettings.tsx +48 -37
- package/src/renderer/components/WorkingStateHistory.tsx +7 -5
- package/src/renderer/components/WorkspaceSelector.tsx +42 -13
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +2333 -209
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +251 -2
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CUSTOM_PROVIDER_IDS = exports.CUSTOM_PROVIDER_MAP = exports.CUSTOM_PROVIDER_CATALOG = void 0;
|
|
4
|
+
exports.CUSTOM_PROVIDER_CATALOG = [
|
|
5
|
+
{
|
|
6
|
+
id: 'opencode',
|
|
7
|
+
name: 'OpenCode Zen',
|
|
8
|
+
compatibility: 'openai',
|
|
9
|
+
defaultModel: '',
|
|
10
|
+
apiKeyLabel: 'API Key / Token',
|
|
11
|
+
apiKeyPlaceholder: 'Enter token',
|
|
12
|
+
requiresBaseUrl: true,
|
|
13
|
+
description: 'OpenAI-compatible endpoint required.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'google-vertex',
|
|
17
|
+
name: 'Google Vertex',
|
|
18
|
+
compatibility: 'openai',
|
|
19
|
+
defaultModel: 'gemini-2.0-flash',
|
|
20
|
+
apiKeyLabel: 'Access Token',
|
|
21
|
+
apiKeyPlaceholder: 'ya29...',
|
|
22
|
+
requiresBaseUrl: true,
|
|
23
|
+
description: 'Requires a compatible gateway endpoint.',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'google-antigravity',
|
|
27
|
+
name: 'Google Antigravity',
|
|
28
|
+
compatibility: 'openai',
|
|
29
|
+
defaultModel: 'gemini-2.0-flash',
|
|
30
|
+
apiKeyLabel: 'Access Token',
|
|
31
|
+
apiKeyPlaceholder: 'ya29...',
|
|
32
|
+
requiresBaseUrl: true,
|
|
33
|
+
description: 'Requires a compatible gateway endpoint.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'google-gemini-cli',
|
|
37
|
+
name: 'Google Gemini CLI',
|
|
38
|
+
compatibility: 'openai',
|
|
39
|
+
defaultModel: 'gemini-2.0-flash',
|
|
40
|
+
apiKeyLabel: 'Access Token',
|
|
41
|
+
apiKeyPlaceholder: 'ya29...',
|
|
42
|
+
requiresBaseUrl: true,
|
|
43
|
+
description: 'Requires a compatible gateway endpoint.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'zai',
|
|
47
|
+
name: 'Z.AI',
|
|
48
|
+
compatibility: 'openai',
|
|
49
|
+
defaultModel: 'glm-4.7',
|
|
50
|
+
apiKeyLabel: 'API Key',
|
|
51
|
+
apiKeyPlaceholder: 'zai-...',
|
|
52
|
+
requiresBaseUrl: true,
|
|
53
|
+
description: 'OpenAI-compatible endpoint required.',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'glm',
|
|
57
|
+
name: 'GLM',
|
|
58
|
+
compatibility: 'openai',
|
|
59
|
+
defaultModel: 'glm-4-plus',
|
|
60
|
+
apiKeyLabel: 'API Key',
|
|
61
|
+
apiKeyPlaceholder: 'glm-...',
|
|
62
|
+
requiresBaseUrl: true,
|
|
63
|
+
description: 'OpenAI-compatible endpoint required.',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'vercel-ai-gateway',
|
|
67
|
+
name: 'Vercel AI Gateway',
|
|
68
|
+
compatibility: 'anthropic',
|
|
69
|
+
baseUrl: 'https://ai-gateway.vercel.sh/v1',
|
|
70
|
+
defaultModel: 'claude-3-5-sonnet-20241022',
|
|
71
|
+
apiKeyLabel: 'API Key',
|
|
72
|
+
apiKeyPlaceholder: 'vgw_...',
|
|
73
|
+
apiKeyUrl: 'https://vercel.com/docs/ai-gateway',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'moonshot',
|
|
77
|
+
name: 'Moonshot (Kimi)',
|
|
78
|
+
compatibility: 'openai',
|
|
79
|
+
baseUrl: 'https://api.moonshot.ai/v1',
|
|
80
|
+
defaultModel: 'kimi-k2.5',
|
|
81
|
+
apiKeyLabel: 'API Key',
|
|
82
|
+
apiKeyPlaceholder: 'sk-...',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'cerebras',
|
|
86
|
+
name: 'Cerebras',
|
|
87
|
+
compatibility: 'openai',
|
|
88
|
+
baseUrl: 'https://api.cerebras.ai/v1',
|
|
89
|
+
defaultModel: 'llama3.1-8b',
|
|
90
|
+
apiKeyLabel: 'API Key',
|
|
91
|
+
apiKeyPlaceholder: 'csk_...',
|
|
92
|
+
apiKeyUrl: 'https://cloud.cerebras.ai/',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'mistral',
|
|
96
|
+
name: 'Mistral',
|
|
97
|
+
compatibility: 'openai',
|
|
98
|
+
baseUrl: 'https://api.mistral.ai/v1',
|
|
99
|
+
defaultModel: 'mistral-large-latest',
|
|
100
|
+
apiKeyLabel: 'API Key',
|
|
101
|
+
apiKeyPlaceholder: 'mistral-...',
|
|
102
|
+
apiKeyUrl: 'https://console.mistral.ai/',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'github-copilot',
|
|
106
|
+
name: 'GitHub Copilot',
|
|
107
|
+
compatibility: 'openai',
|
|
108
|
+
defaultModel: 'gpt-4o',
|
|
109
|
+
apiKeyLabel: 'GitHub Token',
|
|
110
|
+
apiKeyPlaceholder: 'ghp_...',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'qwen-portal',
|
|
114
|
+
name: 'Qwen',
|
|
115
|
+
compatibility: 'anthropic',
|
|
116
|
+
baseUrl: 'https://portal.qwen.ai/v1',
|
|
117
|
+
defaultModel: 'coder-model',
|
|
118
|
+
apiKeyLabel: 'API Key / Token',
|
|
119
|
+
apiKeyPlaceholder: 'qwen-...',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'minimax',
|
|
123
|
+
name: 'MiniMax',
|
|
124
|
+
compatibility: 'openai',
|
|
125
|
+
baseUrl: 'https://api.minimax.chat/v1',
|
|
126
|
+
defaultModel: 'MiniMax-M2.1',
|
|
127
|
+
apiKeyLabel: 'API Key',
|
|
128
|
+
apiKeyPlaceholder: 'minimax-...',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 'minimax-portal',
|
|
132
|
+
name: 'MiniMax Portal',
|
|
133
|
+
compatibility: 'anthropic',
|
|
134
|
+
baseUrl: 'https://api.minimax.io/anthropic',
|
|
135
|
+
defaultModel: 'MiniMax-M2.1',
|
|
136
|
+
apiKeyLabel: 'API Key / Token',
|
|
137
|
+
apiKeyPlaceholder: 'minimax-...',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'xiaomi',
|
|
141
|
+
name: 'Xiaomi MiMo',
|
|
142
|
+
compatibility: 'anthropic',
|
|
143
|
+
baseUrl: 'https://api.xiaomimimo.com/anthropic',
|
|
144
|
+
defaultModel: 'mimo-v2-flash',
|
|
145
|
+
apiKeyLabel: 'API Key',
|
|
146
|
+
apiKeyPlaceholder: 'mimo-...',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'venice',
|
|
150
|
+
name: 'Venice AI',
|
|
151
|
+
compatibility: 'openai',
|
|
152
|
+
baseUrl: 'https://api.venice.ai/api/v1',
|
|
153
|
+
defaultModel: 'llama-3.3-70b',
|
|
154
|
+
apiKeyLabel: 'API Key',
|
|
155
|
+
apiKeyPlaceholder: 'venice-...',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: 'synthetic',
|
|
159
|
+
name: 'Synthetic',
|
|
160
|
+
compatibility: 'anthropic',
|
|
161
|
+
baseUrl: 'https://api.synthetic.new/anthropic',
|
|
162
|
+
defaultModel: 'hf:MiniMaxAI/MiniMax-M2.1',
|
|
163
|
+
apiKeyLabel: 'API Key',
|
|
164
|
+
apiKeyPlaceholder: 'syn_...',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: 'kimi-code',
|
|
168
|
+
name: 'Kimi Code',
|
|
169
|
+
compatibility: 'openai',
|
|
170
|
+
baseUrl: 'https://api.kimi.com/coding/v1',
|
|
171
|
+
defaultModel: 'kimi-for-coding',
|
|
172
|
+
apiKeyLabel: 'API Key',
|
|
173
|
+
apiKeyPlaceholder: 'sk-...',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: 'openai-compatible',
|
|
177
|
+
name: 'OpenAI-Compatible (Custom)',
|
|
178
|
+
compatibility: 'openai',
|
|
179
|
+
baseUrl: 'http://localhost:1234/v1',
|
|
180
|
+
defaultModel: 'gpt-4o-mini',
|
|
181
|
+
apiKeyLabel: 'API Key (Optional)',
|
|
182
|
+
apiKeyPlaceholder: 'sk-...',
|
|
183
|
+
requiresBaseUrl: true,
|
|
184
|
+
apiKeyOptional: true,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 'anthropic-compatible',
|
|
188
|
+
name: 'Anthropic-Compatible (Custom)',
|
|
189
|
+
compatibility: 'anthropic',
|
|
190
|
+
baseUrl: 'http://localhost:4000',
|
|
191
|
+
defaultModel: 'claude-3-5-sonnet-20241022',
|
|
192
|
+
apiKeyLabel: 'API Key',
|
|
193
|
+
apiKeyPlaceholder: 'sk-...',
|
|
194
|
+
requiresBaseUrl: true,
|
|
195
|
+
},
|
|
196
|
+
];
|
|
197
|
+
exports.CUSTOM_PROVIDER_MAP = new Map(exports.CUSTOM_PROVIDER_CATALOG.map((provider) => [provider.id, provider]));
|
|
198
|
+
exports.CUSTOM_PROVIDER_IDS = new Set(exports.CUSTOM_PROVIDER_CATALOG.map((provider) => provider.id));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Core types shared between main and renderer processes
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.VOICE_LANGUAGES = exports.OPENAI_VOICES = exports.DEFAULT_VOICE_SETTINGS = exports.ANALOGY_DOMAINS = exports.DEFAULT_RELATIONSHIP = exports.DEFAULT_QUIRKS = exports.DEFAULT_RESPONSE_STYLE = exports.PERSONA_DEFINITIONS = exports.PERSONALITY_DEFINITIONS = exports.DEFAULT_QUEUE_SETTINGS = exports.DEFAULT_BLOCKED_COMMAND_PATTERNS = exports.DEFAULT_TRUSTED_COMMAND_PATTERNS = exports.IPC_CHANNELS = exports.BOARD_COLUMNS = exports.DEFAULT_AGENT_ROLES = exports.TEMP_WORKSPACE_NAME = exports.TEMP_WORKSPACE_ID = exports.CONTEXT_TOOL_RESTRICTIONS = exports.TOOL_RISK_LEVELS = exports.TOOL_GROUPS = exports.ACCENT_COLORS = void 0;
|
|
4
|
+
exports.VOICE_LANGUAGES = exports.OPENAI_VOICES = exports.DEFAULT_VOICE_SETTINGS = exports.ANALOGY_DOMAINS = exports.DEFAULT_RELATIONSHIP = exports.DEFAULT_QUIRKS = exports.DEFAULT_RESPONSE_STYLE = exports.PERSONA_DEFINITIONS = exports.PERSONALITY_DEFINITIONS = exports.DEFAULT_QUEUE_SETTINGS = exports.DEFAULT_BLOCKED_COMMAND_PATTERNS = exports.DEFAULT_TRUSTED_COMMAND_PATTERNS = exports.LLM_PROVIDER_TYPES = exports.CUSTOM_LLM_PROVIDER_TYPES = exports.BUILTIN_LLM_PROVIDER_TYPES = exports.IPC_CHANNELS = exports.BOARD_COLUMNS = exports.DEFAULT_AGENT_ROLES = exports.TEMP_WORKSPACE_NAME = exports.TEMP_WORKSPACE_ID = exports.CONTEXT_TOOL_RESTRICTIONS = exports.TOOL_RISK_LEVELS = exports.TOOL_GROUPS = exports.ACCENT_COLORS = void 0;
|
|
5
5
|
exports.getPersonalityById = getPersonalityById;
|
|
6
6
|
exports.getPersonaById = getPersonaById;
|
|
7
7
|
exports.ACCENT_COLORS = [
|
|
@@ -59,6 +59,12 @@ exports.TOOL_GROUPS = {
|
|
|
59
59
|
'group:network': [
|
|
60
60
|
'web_search',
|
|
61
61
|
'x_action',
|
|
62
|
+
'notion_action',
|
|
63
|
+
'box_action',
|
|
64
|
+
'onedrive_action',
|
|
65
|
+
'google_drive_action',
|
|
66
|
+
'dropbox_action',
|
|
67
|
+
'sharepoint_action',
|
|
62
68
|
'browser_navigate',
|
|
63
69
|
'browser_screenshot',
|
|
64
70
|
'browser_get_content',
|
|
@@ -141,6 +147,12 @@ exports.TOOL_RISK_LEVELS = {
|
|
|
141
147
|
browser_save_pdf: 'network',
|
|
142
148
|
browser_close: 'network',
|
|
143
149
|
x_action: 'network',
|
|
150
|
+
notion_action: 'network',
|
|
151
|
+
box_action: 'network',
|
|
152
|
+
onedrive_action: 'network',
|
|
153
|
+
google_drive_action: 'network',
|
|
154
|
+
dropbox_action: 'network',
|
|
155
|
+
sharepoint_action: 'network',
|
|
144
156
|
// Meta
|
|
145
157
|
revise_plan: 'read',
|
|
146
158
|
};
|
|
@@ -462,6 +474,7 @@ exports.IPC_CHANNELS = {
|
|
|
462
474
|
WORKSPACE_LIST: 'workspace:list',
|
|
463
475
|
WORKSPACE_CREATE: 'workspace:create',
|
|
464
476
|
WORKSPACE_UPDATE_PERMISSIONS: 'workspace:updatePermissions',
|
|
477
|
+
WORKSPACE_TOUCH: 'workspace:touch',
|
|
465
478
|
WORKSPACE_GET_TEMP: 'workspace:getTemp', // Get or create temp workspace
|
|
466
479
|
// Approval operations
|
|
467
480
|
APPROVAL_RESPOND: 'approval:respond',
|
|
@@ -503,6 +516,9 @@ exports.IPC_CHANNELS = {
|
|
|
503
516
|
LLM_GET_GEMINI_MODELS: 'llm:getGeminiModels',
|
|
504
517
|
LLM_GET_OPENROUTER_MODELS: 'llm:getOpenRouterModels',
|
|
505
518
|
LLM_GET_OPENAI_MODELS: 'llm:getOpenAIModels',
|
|
519
|
+
LLM_GET_GROQ_MODELS: 'llm:getGroqModels',
|
|
520
|
+
LLM_GET_XAI_MODELS: 'llm:getXAIModels',
|
|
521
|
+
LLM_GET_KIMI_MODELS: 'llm:getKimiModels',
|
|
506
522
|
LLM_OPENAI_OAUTH_START: 'llm:openaiOAuthStart',
|
|
507
523
|
LLM_OPENAI_OAUTH_LOGOUT: 'llm:openaiOAuthLogout',
|
|
508
524
|
LLM_GET_BEDROCK_MODELS: 'llm:getBedrockModels',
|
|
@@ -528,6 +544,36 @@ exports.IPC_CHANNELS = {
|
|
|
528
544
|
X_SAVE_SETTINGS: 'x:saveSettings',
|
|
529
545
|
X_TEST_CONNECTION: 'x:testConnection',
|
|
530
546
|
X_GET_STATUS: 'x:getStatus',
|
|
547
|
+
// Notion Settings
|
|
548
|
+
NOTION_GET_SETTINGS: 'notion:getSettings',
|
|
549
|
+
NOTION_SAVE_SETTINGS: 'notion:saveSettings',
|
|
550
|
+
NOTION_TEST_CONNECTION: 'notion:testConnection',
|
|
551
|
+
NOTION_GET_STATUS: 'notion:getStatus',
|
|
552
|
+
// Box Settings
|
|
553
|
+
BOX_GET_SETTINGS: 'box:getSettings',
|
|
554
|
+
BOX_SAVE_SETTINGS: 'box:saveSettings',
|
|
555
|
+
BOX_TEST_CONNECTION: 'box:testConnection',
|
|
556
|
+
BOX_GET_STATUS: 'box:getStatus',
|
|
557
|
+
// OneDrive Settings
|
|
558
|
+
ONEDRIVE_GET_SETTINGS: 'onedrive:getSettings',
|
|
559
|
+
ONEDRIVE_SAVE_SETTINGS: 'onedrive:saveSettings',
|
|
560
|
+
ONEDRIVE_TEST_CONNECTION: 'onedrive:testConnection',
|
|
561
|
+
ONEDRIVE_GET_STATUS: 'onedrive:getStatus',
|
|
562
|
+
// Google Drive Settings
|
|
563
|
+
GOOGLE_DRIVE_GET_SETTINGS: 'googleDrive:getSettings',
|
|
564
|
+
GOOGLE_DRIVE_SAVE_SETTINGS: 'googleDrive:saveSettings',
|
|
565
|
+
GOOGLE_DRIVE_TEST_CONNECTION: 'googleDrive:testConnection',
|
|
566
|
+
GOOGLE_DRIVE_GET_STATUS: 'googleDrive:getStatus',
|
|
567
|
+
// Dropbox Settings
|
|
568
|
+
DROPBOX_GET_SETTINGS: 'dropbox:getSettings',
|
|
569
|
+
DROPBOX_SAVE_SETTINGS: 'dropbox:saveSettings',
|
|
570
|
+
DROPBOX_TEST_CONNECTION: 'dropbox:testConnection',
|
|
571
|
+
DROPBOX_GET_STATUS: 'dropbox:getStatus',
|
|
572
|
+
// SharePoint Settings
|
|
573
|
+
SHAREPOINT_GET_SETTINGS: 'sharepoint:getSettings',
|
|
574
|
+
SHAREPOINT_SAVE_SETTINGS: 'sharepoint:saveSettings',
|
|
575
|
+
SHAREPOINT_TEST_CONNECTION: 'sharepoint:testConnection',
|
|
576
|
+
SHAREPOINT_GET_STATUS: 'sharepoint:getStatus',
|
|
531
577
|
// App Updates
|
|
532
578
|
APP_CHECK_UPDATES: 'app:checkUpdates',
|
|
533
579
|
APP_DOWNLOAD_UPDATE: 'app:downloadUpdate',
|
|
@@ -579,6 +625,8 @@ exports.IPC_CHANNELS = {
|
|
|
579
625
|
MCP_REGISTRY_UNINSTALL: 'mcp:registryUninstall',
|
|
580
626
|
MCP_REGISTRY_CHECK_UPDATES: 'mcp:registryCheckUpdates',
|
|
581
627
|
MCP_REGISTRY_UPDATE_SERVER: 'mcp:registryUpdateServer',
|
|
628
|
+
// MCP Connector OAuth
|
|
629
|
+
MCP_CONNECTOR_OAUTH_START: 'mcp:connectorOAuthStart',
|
|
582
630
|
// MCP Host
|
|
583
631
|
MCP_HOST_START: 'mcp:hostStart',
|
|
584
632
|
MCP_HOST_STOP: 'mcp:hostStop',
|
|
@@ -671,6 +719,7 @@ exports.IPC_CHANNELS = {
|
|
|
671
719
|
CANVAS_EXPORT_HTML: 'canvas:exportHTML',
|
|
672
720
|
CANVAS_EXPORT_TO_FOLDER: 'canvas:exportToFolder',
|
|
673
721
|
CANVAS_OPEN_IN_BROWSER: 'canvas:openInBrowser',
|
|
722
|
+
CANVAS_OPEN_URL: 'canvas:openUrl',
|
|
674
723
|
CANVAS_GET_SESSION_DIR: 'canvas:getSessionDir',
|
|
675
724
|
// Mobile Companion Nodes
|
|
676
725
|
NODE_LIST: 'node:list',
|
|
@@ -718,6 +767,46 @@ exports.IPC_CHANNELS = {
|
|
|
718
767
|
VOICE_TEST_AZURE: 'voice:testAzure',
|
|
719
768
|
VOICE_EVENT: 'voice:event',
|
|
720
769
|
};
|
|
770
|
+
// LLM Provider types
|
|
771
|
+
exports.BUILTIN_LLM_PROVIDER_TYPES = [
|
|
772
|
+
'anthropic',
|
|
773
|
+
'bedrock',
|
|
774
|
+
'ollama',
|
|
775
|
+
'gemini',
|
|
776
|
+
'openrouter',
|
|
777
|
+
'openai',
|
|
778
|
+
'azure',
|
|
779
|
+
'groq',
|
|
780
|
+
'xai',
|
|
781
|
+
'kimi',
|
|
782
|
+
];
|
|
783
|
+
exports.CUSTOM_LLM_PROVIDER_TYPES = [
|
|
784
|
+
'moonshot',
|
|
785
|
+
'opencode',
|
|
786
|
+
'google-vertex',
|
|
787
|
+
'google-antigravity',
|
|
788
|
+
'google-gemini-cli',
|
|
789
|
+
'zai',
|
|
790
|
+
'glm',
|
|
791
|
+
'vercel-ai-gateway',
|
|
792
|
+
'cerebras',
|
|
793
|
+
'mistral',
|
|
794
|
+
'github-copilot',
|
|
795
|
+
'qwen-portal',
|
|
796
|
+
'minimax',
|
|
797
|
+
'minimax-portal',
|
|
798
|
+
'xiaomi',
|
|
799
|
+
'venice',
|
|
800
|
+
'synthetic',
|
|
801
|
+
'kimi-code',
|
|
802
|
+
'kimi-coding',
|
|
803
|
+
'openai-compatible',
|
|
804
|
+
'anthropic-compatible',
|
|
805
|
+
];
|
|
806
|
+
exports.LLM_PROVIDER_TYPES = [
|
|
807
|
+
...exports.BUILTIN_LLM_PROVIDER_TYPES,
|
|
808
|
+
...exports.CUSTOM_LLM_PROVIDER_TYPES,
|
|
809
|
+
];
|
|
721
810
|
// Default trusted command patterns (glob-like patterns)
|
|
722
811
|
exports.DEFAULT_TRUSTED_COMMAND_PATTERNS = [
|
|
723
812
|
'npm test*',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cowork-os",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.25",
|
|
4
4
|
"description": "CoWork OS - The operating system for personal AI assistants",
|
|
5
5
|
"overrides": {
|
|
6
6
|
"undici": "^7.0.0"
|
|
@@ -44,9 +44,10 @@
|
|
|
44
44
|
"dev": "concurrently \"npm run dev:react\" \"npm run dev:electron\"",
|
|
45
45
|
"dev:react": "vite",
|
|
46
46
|
"dev:electron": "tsc -p tsconfig.electron.json && cross-env NODE_ENV=development electron .",
|
|
47
|
-
"build": "npm run build:react && npm run build:electron",
|
|
47
|
+
"build": "npm run build:react && npm run build:electron && npm run build:connectors",
|
|
48
48
|
"build:react": "vite build",
|
|
49
49
|
"build:electron": "tsc -p tsconfig.electron.json",
|
|
50
|
+
"build:connectors": "concurrently -n salesforce,jira,hubspot,zendesk,servicenow,linear,asana,okta \"tsc -p connectors/salesforce-mcp/tsconfig.json\" \"tsc -p connectors/jira-mcp/tsconfig.json\" \"tsc -p connectors/hubspot-mcp/tsconfig.json\" \"tsc -p connectors/zendesk-mcp/tsconfig.json\" \"tsc -p connectors/servicenow-mcp/tsconfig.json\" \"tsc -p connectors/linear-mcp/tsconfig.json\" \"tsc -p connectors/asana-mcp/tsconfig.json\" \"tsc -p connectors/okta-mcp/tsconfig.json\"",
|
|
50
51
|
"package": "npm run build && electron-builder",
|
|
51
52
|
"lint": "eslint src --ext ts,tsx",
|
|
52
53
|
"type-check": "tsc --noEmit",
|
|
@@ -135,7 +136,17 @@
|
|
|
135
136
|
"from": "resources/skills",
|
|
136
137
|
"to": "skills",
|
|
137
138
|
"filter": [
|
|
138
|
-
"**/*.json"
|
|
139
|
+
"**/*.json",
|
|
140
|
+
"scripts/**"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"from": "connectors",
|
|
145
|
+
"to": "connectors",
|
|
146
|
+
"filter": [
|
|
147
|
+
"**/dist/**",
|
|
148
|
+
"**/README.md",
|
|
149
|
+
"**/package.json"
|
|
139
150
|
]
|
|
140
151
|
}
|
|
141
152
|
],
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "nano-banana-pro",
|
|
3
3
|
"name": "Nano-banana-pro",
|
|
4
|
-
"description": "Generate
|
|
5
|
-
"icon": "
|
|
4
|
+
"description": "Generate images using Nano Banana Pro (Gemini 3 Pro) via the built-in tool.",
|
|
5
|
+
"icon": "\ud83c\udf4c",
|
|
6
6
|
"category": "Tools",
|
|
7
|
-
"prompt": "# Nano Banana Pro (
|
|
7
|
+
"prompt": "# Nano Banana Pro (Image Generation)\n\nUse the built-in image generation tool.\n\nGenerate (preferred)\n\n- Call the `generate_image` tool with:\n - `model`: `nano-banana-pro`\n - `prompt`: your image description\n - `imageSize`: `1K` or `2K`\n - `filename`: optional (saved into the workspace)\n\nAPI key\n\n- Requires Gemini API key configured in Settings.\n- If the key is missing, tell the user to set it up and do not attempt fallbacks.\n",
|
|
8
8
|
"parameters": [],
|
|
9
9
|
"enabled": true
|
|
10
|
-
}
|
|
10
|
+
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"id": "openai-image-gen",
|
|
3
3
|
"name": "Openai-image-gen",
|
|
4
4
|
"description": "Batch-generate images via OpenAI Images API. Random prompt sampler + `index.html` gallery.",
|
|
5
|
-
"icon": "
|
|
5
|
+
"icon": "\ud83d\uddbc\ufe0f",
|
|
6
6
|
"category": "Tools",
|
|
7
|
-
"prompt": "# OpenAI Image Gen\n\nGenerate a handful of
|
|
7
|
+
"prompt": "# OpenAI Image Gen\n\nGenerate a handful of \u201crandom but structured\u201d prompts and render them via the OpenAI Images API.\n\n## Run\n\n```bash\npython3 {baseDir}/scripts/gen.py\nopen ~/Projects/tmp/openai-image-gen-*/index.html # if ~/Projects/tmp exists; else ./tmp/...\n```\n\nUseful flags:\n\n```bash\n# GPT image models with various options\npython3 {baseDir}/scripts/gen.py --count 16 --model gpt-image-1\npython3 {baseDir}/scripts/gen.py --prompt \"ultra-detailed studio photo of a lobster astronaut\" --count 4\npython3 {baseDir}/scripts/gen.py --size 1536x1024 --quality high --out-dir ./out/images\npython3 {baseDir}/scripts/gen.py --model gpt-image-1.5 --background transparent --output-format webp\n\n# DALL-E 3 (note: count is automatically limited to 1)\npython3 {baseDir}/scripts/gen.py --model dall-e-3 --quality hd --size 1792x1024 --style vivid\npython3 {baseDir}/scripts/gen.py --model dall-e-3 --style natural --prompt \"serene mountain landscape\"\n\n# DALL-E 2\npython3 {baseDir}/scripts/gen.py --model dall-e-2 --size 512x512 --count 4\n```\n\n## Model-Specific Parameters\n\nDifferent models support different parameter values. The script automatically selects appropriate defaults based on the model.\n\n### Size\n\n- **GPT image models** (`gpt-image-1`, `gpt-image-1-mini`, `gpt-image-1.5`): `1024x1024`, `1536x1024` (landscape), `1024x1536` (portrait), or `auto`\n - Default: `1024x1024`\n- **dall-e-3**: `1024x1024`, `1792x1024`, or `1024x1792`\n - Default: `1024x1024`\n- **dall-e-2**: `256x256`, `512x512`, or `1024x1024`\n - Default: `1024x1024`\n\n### Quality\n\n- **GPT image models**: `auto`, `high`, `medium`, or `low`\n - Default: `high`\n- **dall-e-3**: `hd` or `standard`\n - Default: `standard`\n- **dall-e-2**: `standard` only\n - Default: `standard`\n\n### Other Notable Differences\n\n- **dall-e-3** only supports generating 1 image at a time (`n=1`). The script automatically limits count to 1 when using this model.\n- **GPT image models** support additional parameters:\n - `--background`: `transparent`, `opaque`, or `auto` (default)\n - `--output-format`: `png` (default), `jpeg`, or `webp`\n - Note: `stream` and `moderation` are available via API but not yet implemented in this script\n- **dall-e-3** has a `--style` parameter: `vivid` (hyper-real, dramatic) or `natural` (more natural looking)\n\n## Output\n\n- `*.png`, `*.jpeg`, or `*.webp` images (output format depends on model + `--output-format`)\n- `prompts.json` (prompt \u2192 file mapping)\n- `index.html` (thumbnail gallery)\n\n## API key\n\n- `OPENAI_API_KEY` env var\n- Or set `skills.\\\"openai-image-gen\\\".apiKey` / `skills.\\\"openai-image-gen\\\".env.OPENAI_API_KEY` in `~/.CoWork-OSS/CoWork-OSS.json`\n",
|
|
8
8
|
"parameters": [],
|
|
9
9
|
"enabled": true
|
|
10
|
-
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Minimal OpenAI image generation script (stdlib only)."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import base64
|
|
6
|
+
import datetime
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import random
|
|
10
|
+
import sys
|
|
11
|
+
import urllib.error
|
|
12
|
+
import urllib.request
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
OPENAI_URL = "https://api.openai.com/v1/images/generations"
|
|
16
|
+
|
|
17
|
+
DEFAULT_PROMPTS = [
|
|
18
|
+
"ultra-detailed studio photo of a lobster astronaut",
|
|
19
|
+
"cinematic wide shot of a glasshouse cafe in a tropical rainforest, morning mist",
|
|
20
|
+
"macro photograph of dewdrops on a spiderweb at sunrise, shallow depth of field",
|
|
21
|
+
"isometric cutaway of a cozy cabin library, warm lighting, rainy window",
|
|
22
|
+
"surreal desert landscape with floating rocks, golden hour light",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _require_api_key() -> str:
|
|
27
|
+
api_key = os.environ.get("OPENAI_API_KEY")
|
|
28
|
+
if not api_key:
|
|
29
|
+
print("ERROR: OPENAI_API_KEY is not set", file=sys.stderr)
|
|
30
|
+
sys.exit(2)
|
|
31
|
+
return api_key
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _post_json(payload: dict) -> dict:
|
|
35
|
+
api_key = _require_api_key()
|
|
36
|
+
data = json.dumps(payload).encode("utf-8")
|
|
37
|
+
req = urllib.request.Request(
|
|
38
|
+
OPENAI_URL,
|
|
39
|
+
data=data,
|
|
40
|
+
headers={
|
|
41
|
+
"Authorization": f"Bearer {api_key}",
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
},
|
|
44
|
+
method="POST",
|
|
45
|
+
)
|
|
46
|
+
try:
|
|
47
|
+
with urllib.request.urlopen(req) as resp:
|
|
48
|
+
return json.load(resp)
|
|
49
|
+
except urllib.error.HTTPError as err:
|
|
50
|
+
body = err.read().decode("utf-8", "ignore")
|
|
51
|
+
print(f"OpenAI API error: {err.code} {err.reason}\n{body}", file=sys.stderr)
|
|
52
|
+
sys.exit(3)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _model_supports_gpt_image(model: str) -> bool:
|
|
56
|
+
return model.startswith("gpt-image")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def build_payload(args: argparse.Namespace, prompt: str) -> dict:
|
|
60
|
+
payload = {
|
|
61
|
+
"model": args.model,
|
|
62
|
+
"prompt": prompt,
|
|
63
|
+
"n": args.count,
|
|
64
|
+
"size": args.size,
|
|
65
|
+
"response_format": "b64_json",
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if args.quality:
|
|
69
|
+
payload["quality"] = args.quality
|
|
70
|
+
if args.style and args.model.startswith("dall-e-3"):
|
|
71
|
+
payload["style"] = args.style
|
|
72
|
+
if _model_supports_gpt_image(args.model):
|
|
73
|
+
if args.background:
|
|
74
|
+
payload["background"] = args.background
|
|
75
|
+
if args.output_format:
|
|
76
|
+
payload["output_format"] = args.output_format
|
|
77
|
+
|
|
78
|
+
return payload
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _resolve_output_format(args: argparse.Namespace) -> str:
|
|
82
|
+
if args.output_format:
|
|
83
|
+
return args.output_format
|
|
84
|
+
return "png"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _write_index(out_dir: Path, files: list[str]) -> None:
|
|
88
|
+
index_path = out_dir / "index.html"
|
|
89
|
+
rows = "\n".join([f'<div><img src="{Path(f).name}" alt="image" /></div>' for f in files])
|
|
90
|
+
html = f"""<!doctype html>
|
|
91
|
+
<html>
|
|
92
|
+
<head>
|
|
93
|
+
<meta charset=\"utf-8\" />
|
|
94
|
+
<title>Image Gallery</title>
|
|
95
|
+
<style>body{{font-family:Arial,sans-serif}} img{{max-width:100%;height:auto;margin:8px 0}}</style>
|
|
96
|
+
</head>
|
|
97
|
+
<body>
|
|
98
|
+
{rows}
|
|
99
|
+
</body>
|
|
100
|
+
</html>
|
|
101
|
+
"""
|
|
102
|
+
index_path.write_text(html)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def main() -> None:
|
|
106
|
+
parser = argparse.ArgumentParser(description="OpenAI image generation script")
|
|
107
|
+
parser.add_argument("--prompt", help="Image prompt text")
|
|
108
|
+
parser.add_argument("--count", type=int, default=1)
|
|
109
|
+
parser.add_argument("--model", default="gpt-image-1")
|
|
110
|
+
parser.add_argument("--size", default="1024x1024")
|
|
111
|
+
parser.add_argument("--quality", default=None)
|
|
112
|
+
parser.add_argument("--out-dir", default="./out/images")
|
|
113
|
+
parser.add_argument("--output-format", default=None)
|
|
114
|
+
parser.add_argument("--background", default=None)
|
|
115
|
+
parser.add_argument("--style", default=None)
|
|
116
|
+
args = parser.parse_args()
|
|
117
|
+
|
|
118
|
+
if args.count < 1:
|
|
119
|
+
print("ERROR: --count must be >= 1", file=sys.stderr)
|
|
120
|
+
sys.exit(2)
|
|
121
|
+
|
|
122
|
+
if args.model.startswith("dall-e-3") and args.count != 1:
|
|
123
|
+
print("ERROR: dall-e-3 only supports --count 1", file=sys.stderr)
|
|
124
|
+
sys.exit(2)
|
|
125
|
+
|
|
126
|
+
prompt = args.prompt
|
|
127
|
+
if not prompt:
|
|
128
|
+
prompt = random.choice(DEFAULT_PROMPTS)
|
|
129
|
+
|
|
130
|
+
payload = build_payload(args, prompt)
|
|
131
|
+
result = _post_json(payload)
|
|
132
|
+
data = result.get("data", [])
|
|
133
|
+
if not data:
|
|
134
|
+
print("ERROR: No image data returned", file=sys.stderr)
|
|
135
|
+
sys.exit(4)
|
|
136
|
+
|
|
137
|
+
out_dir = Path(args.out_dir).expanduser()
|
|
138
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
139
|
+
|
|
140
|
+
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
141
|
+
output_format = _resolve_output_format(args)
|
|
142
|
+
|
|
143
|
+
files: list[str] = []
|
|
144
|
+
for idx, item in enumerate(data, start=1):
|
|
145
|
+
b64 = item.get("b64_json")
|
|
146
|
+
if not b64:
|
|
147
|
+
continue
|
|
148
|
+
filename = out_dir / f"image_{ts}_{idx}.{output_format}"
|
|
149
|
+
with open(filename, "wb") as f:
|
|
150
|
+
f.write(base64.b64decode(b64))
|
|
151
|
+
files.append(str(filename))
|
|
152
|
+
print(f"MEDIA: {filename}")
|
|
153
|
+
|
|
154
|
+
# Write prompts.json and index.html for quick browsing
|
|
155
|
+
prompts_path = out_dir / "prompts.json"
|
|
156
|
+
prompts_path.write_text(json.dumps({"prompt": prompt, "files": files}, indent=2))
|
|
157
|
+
_write_index(out_dir, files)
|
|
158
|
+
|
|
159
|
+
print(f"Saved {len(files)} image(s) to {out_dir}")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
main()
|