prompt_objects 0.1.0
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.
- checksums.yaml +7 -0
- data/CLAUDE.md +108 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +231 -0
- data/IMPLEMENTATION_PLAN.md +1073 -0
- data/LICENSE +21 -0
- data/README.md +73 -0
- data/Rakefile +27 -0
- data/design-doc-v2.md +1232 -0
- data/exe/prompt_objects +572 -0
- data/exe/prompt_objects_mcp +34 -0
- data/frontend/.gitignore +3 -0
- data/frontend/index.html +13 -0
- data/frontend/package-lock.json +4417 -0
- data/frontend/package.json +32 -0
- data/frontend/postcss.config.js +6 -0
- data/frontend/src/App.tsx +95 -0
- data/frontend/src/components/CapabilitiesPanel.tsx +44 -0
- data/frontend/src/components/ChatPanel.tsx +251 -0
- data/frontend/src/components/Dashboard.tsx +83 -0
- data/frontend/src/components/Header.tsx +141 -0
- data/frontend/src/components/MarkdownMessage.tsx +153 -0
- data/frontend/src/components/MessageBus.tsx +55 -0
- data/frontend/src/components/ModelSelector.tsx +112 -0
- data/frontend/src/components/NotificationPanel.tsx +134 -0
- data/frontend/src/components/POCard.tsx +56 -0
- data/frontend/src/components/PODetail.tsx +117 -0
- data/frontend/src/components/PromptPanel.tsx +51 -0
- data/frontend/src/components/SessionsPanel.tsx +174 -0
- data/frontend/src/components/ThreadsSidebar.tsx +119 -0
- data/frontend/src/components/index.ts +11 -0
- data/frontend/src/hooks/useWebSocket.ts +363 -0
- data/frontend/src/index.css +37 -0
- data/frontend/src/main.tsx +10 -0
- data/frontend/src/store/index.ts +246 -0
- data/frontend/src/types/index.ts +146 -0
- data/frontend/tailwind.config.js +25 -0
- data/frontend/tsconfig.json +30 -0
- data/frontend/vite.config.ts +29 -0
- data/lib/prompt_objects/capability.rb +46 -0
- data/lib/prompt_objects/cli.rb +431 -0
- data/lib/prompt_objects/connectors/base.rb +73 -0
- data/lib/prompt_objects/connectors/mcp.rb +524 -0
- data/lib/prompt_objects/environment/exporter.rb +83 -0
- data/lib/prompt_objects/environment/git.rb +118 -0
- data/lib/prompt_objects/environment/importer.rb +159 -0
- data/lib/prompt_objects/environment/manager.rb +401 -0
- data/lib/prompt_objects/environment/manifest.rb +218 -0
- data/lib/prompt_objects/environment.rb +283 -0
- data/lib/prompt_objects/human_queue.rb +144 -0
- data/lib/prompt_objects/llm/anthropic_adapter.rb +137 -0
- data/lib/prompt_objects/llm/factory.rb +84 -0
- data/lib/prompt_objects/llm/gemini_adapter.rb +209 -0
- data/lib/prompt_objects/llm/openai_adapter.rb +104 -0
- data/lib/prompt_objects/llm/response.rb +61 -0
- data/lib/prompt_objects/loader.rb +32 -0
- data/lib/prompt_objects/mcp/server.rb +167 -0
- data/lib/prompt_objects/mcp/tools/get_conversation.rb +60 -0
- data/lib/prompt_objects/mcp/tools/get_pending_requests.rb +54 -0
- data/lib/prompt_objects/mcp/tools/inspect_po.rb +73 -0
- data/lib/prompt_objects/mcp/tools/list_prompt_objects.rb +37 -0
- data/lib/prompt_objects/mcp/tools/respond_to_request.rb +68 -0
- data/lib/prompt_objects/mcp/tools/send_message.rb +71 -0
- data/lib/prompt_objects/message_bus.rb +97 -0
- data/lib/prompt_objects/primitive.rb +13 -0
- data/lib/prompt_objects/primitives/http_get.rb +72 -0
- data/lib/prompt_objects/primitives/list_files.rb +95 -0
- data/lib/prompt_objects/primitives/read_file.rb +81 -0
- data/lib/prompt_objects/primitives/write_file.rb +73 -0
- data/lib/prompt_objects/prompt_object.rb +415 -0
- data/lib/prompt_objects/registry.rb +88 -0
- data/lib/prompt_objects/server/api/routes.rb +297 -0
- data/lib/prompt_objects/server/app.rb +174 -0
- data/lib/prompt_objects/server/file_watcher.rb +113 -0
- data/lib/prompt_objects/server/public/assets/index-2acS2FYZ.js +77 -0
- data/lib/prompt_objects/server/public/assets/index-DXU5uRXQ.css +1 -0
- data/lib/prompt_objects/server/public/index.html +14 -0
- data/lib/prompt_objects/server/websocket_handler.rb +619 -0
- data/lib/prompt_objects/server.rb +166 -0
- data/lib/prompt_objects/session/store.rb +826 -0
- data/lib/prompt_objects/universal/add_capability.rb +74 -0
- data/lib/prompt_objects/universal/add_primitive.rb +113 -0
- data/lib/prompt_objects/universal/ask_human.rb +109 -0
- data/lib/prompt_objects/universal/create_capability.rb +219 -0
- data/lib/prompt_objects/universal/create_primitive.rb +170 -0
- data/lib/prompt_objects/universal/list_capabilities.rb +55 -0
- data/lib/prompt_objects/universal/list_primitives.rb +145 -0
- data/lib/prompt_objects/universal/modify_primitive.rb +180 -0
- data/lib/prompt_objects/universal/request_primitive.rb +287 -0
- data/lib/prompt_objects/universal/think.rb +41 -0
- data/lib/prompt_objects/universal/verify_primitive.rb +173 -0
- data/lib/prompt_objects.rb +62 -0
- data/objects/coordinator.md +48 -0
- data/objects/greeter.md +30 -0
- data/objects/reader.md +33 -0
- data/prompt_objects.gemspec +50 -0
- data/templates/basic/.gitignore +2 -0
- data/templates/basic/manifest.yml +7 -0
- data/templates/basic/objects/basic.md +32 -0
- data/templates/developer/.gitignore +5 -0
- data/templates/developer/manifest.yml +17 -0
- data/templates/developer/objects/code_reviewer.md +33 -0
- data/templates/developer/objects/coordinator.md +39 -0
- data/templates/developer/objects/debugger.md +35 -0
- data/templates/empty/.gitignore +5 -0
- data/templates/empty/manifest.yml +14 -0
- data/templates/empty/objects/.gitkeep +0 -0
- data/templates/empty/objects/assistant.md +41 -0
- data/templates/minimal/.gitignore +5 -0
- data/templates/minimal/manifest.yml +7 -0
- data/templates/minimal/objects/assistant.md +41 -0
- data/templates/writer/.gitignore +5 -0
- data/templates/writer/manifest.yml +17 -0
- data/templates/writer/objects/coordinator.md +33 -0
- data/templates/writer/objects/editor.md +33 -0
- data/templates/writer/objects/researcher.md +34 -0
- metadata +343 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { create } from 'zustand'
|
|
2
|
+
import { useShallow } from 'zustand/react/shallow'
|
|
3
|
+
import type {
|
|
4
|
+
PromptObject,
|
|
5
|
+
BusMessage,
|
|
6
|
+
Notification,
|
|
7
|
+
Environment,
|
|
8
|
+
Message,
|
|
9
|
+
LLMConfig,
|
|
10
|
+
} from '../types'
|
|
11
|
+
|
|
12
|
+
interface Store {
|
|
13
|
+
// Connection state
|
|
14
|
+
connected: boolean
|
|
15
|
+
setConnected: (connected: boolean) => void
|
|
16
|
+
|
|
17
|
+
// Environment
|
|
18
|
+
environment: Environment | null
|
|
19
|
+
setEnvironment: (env: Environment) => void
|
|
20
|
+
|
|
21
|
+
// Prompt Objects
|
|
22
|
+
promptObjects: Record<string, PromptObject>
|
|
23
|
+
setPromptObject: (name: string, state: Partial<PromptObject>) => void
|
|
24
|
+
removePromptObject: (name: string) => void
|
|
25
|
+
updatePromptObjectStatus: (name: string, status: PromptObject['status']) => void
|
|
26
|
+
addMessageToPO: (poName: string, message: Message) => void
|
|
27
|
+
updateSessionMessages: (poName: string, sessionId: string, messages: Message[]) => void
|
|
28
|
+
switchPOSession: (poName: string, sessionId: string) => void
|
|
29
|
+
|
|
30
|
+
// Navigation
|
|
31
|
+
selectedPO: string | null
|
|
32
|
+
selectPO: (name: string | null) => void
|
|
33
|
+
activeTab: 'chat' | 'sessions' | 'capabilities' | 'prompt'
|
|
34
|
+
setActiveTab: (tab: Store['activeTab']) => void
|
|
35
|
+
|
|
36
|
+
// Message Bus
|
|
37
|
+
busMessages: BusMessage[]
|
|
38
|
+
addBusMessage: (message: BusMessage) => void
|
|
39
|
+
busOpen: boolean
|
|
40
|
+
toggleBus: () => void
|
|
41
|
+
|
|
42
|
+
// Notifications
|
|
43
|
+
notifications: Notification[]
|
|
44
|
+
addNotification: (notification: Notification) => void
|
|
45
|
+
removeNotification: (id: string) => void
|
|
46
|
+
|
|
47
|
+
// Streaming
|
|
48
|
+
streamingContent: Record<string, string>
|
|
49
|
+
appendStreamChunk: (poName: string, chunk: string) => void
|
|
50
|
+
clearStream: (poName: string) => void
|
|
51
|
+
|
|
52
|
+
// Response handling
|
|
53
|
+
pendingResponse: Record<string, string>
|
|
54
|
+
setPendingResponse: (poName: string, content: string) => void
|
|
55
|
+
clearPendingResponse: (poName: string) => void
|
|
56
|
+
|
|
57
|
+
// LLM Config
|
|
58
|
+
llmConfig: LLMConfig | null
|
|
59
|
+
setLLMConfig: (config: LLMConfig) => void
|
|
60
|
+
updateCurrentLLM: (provider: string, model: string) => void
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const useStore = create<Store>((set) => ({
|
|
64
|
+
// Connection
|
|
65
|
+
connected: false,
|
|
66
|
+
setConnected: (connected) => set({ connected }),
|
|
67
|
+
|
|
68
|
+
// Environment
|
|
69
|
+
environment: null,
|
|
70
|
+
setEnvironment: (environment) => set({ environment }),
|
|
71
|
+
|
|
72
|
+
// Prompt Objects
|
|
73
|
+
promptObjects: {},
|
|
74
|
+
setPromptObject: (name, state) =>
|
|
75
|
+
set((s) => ({
|
|
76
|
+
promptObjects: {
|
|
77
|
+
...s.promptObjects,
|
|
78
|
+
[name]: {
|
|
79
|
+
...s.promptObjects[name],
|
|
80
|
+
...state,
|
|
81
|
+
name, // Ensure name is always set
|
|
82
|
+
} as PromptObject,
|
|
83
|
+
},
|
|
84
|
+
})),
|
|
85
|
+
removePromptObject: (name) =>
|
|
86
|
+
set((s) => {
|
|
87
|
+
const { [name]: _, ...rest } = s.promptObjects
|
|
88
|
+
// If we're viewing this PO, deselect it
|
|
89
|
+
const selectedPO = s.selectedPO === name ? null : s.selectedPO
|
|
90
|
+
return { promptObjects: rest, selectedPO }
|
|
91
|
+
}),
|
|
92
|
+
updatePromptObjectStatus: (name, status) =>
|
|
93
|
+
set((s) => ({
|
|
94
|
+
promptObjects: {
|
|
95
|
+
...s.promptObjects,
|
|
96
|
+
[name]: {
|
|
97
|
+
...s.promptObjects[name],
|
|
98
|
+
status,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
})),
|
|
102
|
+
addMessageToPO: (poName, message) =>
|
|
103
|
+
set((s) => {
|
|
104
|
+
const po = s.promptObjects[poName]
|
|
105
|
+
if (!po) return s
|
|
106
|
+
|
|
107
|
+
// Handle case where current_session doesn't exist yet (new POs)
|
|
108
|
+
const currentMessages = po.current_session?.messages || []
|
|
109
|
+
return {
|
|
110
|
+
promptObjects: {
|
|
111
|
+
...s.promptObjects,
|
|
112
|
+
[poName]: {
|
|
113
|
+
...po,
|
|
114
|
+
current_session: {
|
|
115
|
+
id: po.current_session?.id || 'pending',
|
|
116
|
+
messages: [...currentMessages, message],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
}),
|
|
122
|
+
updateSessionMessages: (poName, sessionId, messages) =>
|
|
123
|
+
set((s) => {
|
|
124
|
+
const po = s.promptObjects[poName]
|
|
125
|
+
if (!po) return s
|
|
126
|
+
|
|
127
|
+
// Update current_session if it matches the sessionId, OR if current_session is null
|
|
128
|
+
// (handles newly created POs that didn't have session info yet)
|
|
129
|
+
if (po.current_session?.id === sessionId || !po.current_session) {
|
|
130
|
+
return {
|
|
131
|
+
promptObjects: {
|
|
132
|
+
...s.promptObjects,
|
|
133
|
+
[poName]: {
|
|
134
|
+
...po,
|
|
135
|
+
current_session: {
|
|
136
|
+
id: sessionId,
|
|
137
|
+
messages,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Otherwise, just update the session in the sessions list (message count)
|
|
145
|
+
// The full messages will be loaded when the user switches to that session
|
|
146
|
+
return s
|
|
147
|
+
}),
|
|
148
|
+
switchPOSession: (poName, sessionId) =>
|
|
149
|
+
set((s) => {
|
|
150
|
+
const po = s.promptObjects[poName]
|
|
151
|
+
if (!po) return s
|
|
152
|
+
|
|
153
|
+
// Switch to a new session - clear messages until session_updated arrives
|
|
154
|
+
return {
|
|
155
|
+
promptObjects: {
|
|
156
|
+
...s.promptObjects,
|
|
157
|
+
[poName]: {
|
|
158
|
+
...po,
|
|
159
|
+
current_session: {
|
|
160
|
+
id: sessionId,
|
|
161
|
+
messages: [], // Will be populated by session_updated
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
}),
|
|
167
|
+
|
|
168
|
+
// Navigation
|
|
169
|
+
selectedPO: null,
|
|
170
|
+
selectPO: (name) => set({ selectedPO: name, activeTab: 'chat' }),
|
|
171
|
+
activeTab: 'chat',
|
|
172
|
+
setActiveTab: (activeTab) => set({ activeTab }),
|
|
173
|
+
|
|
174
|
+
// Message Bus
|
|
175
|
+
busMessages: [],
|
|
176
|
+
addBusMessage: (message) =>
|
|
177
|
+
set((s) => ({
|
|
178
|
+
busMessages: [...s.busMessages.slice(-99), message], // Keep last 100
|
|
179
|
+
})),
|
|
180
|
+
busOpen: false,
|
|
181
|
+
toggleBus: () => set((s) => ({ busOpen: !s.busOpen })),
|
|
182
|
+
|
|
183
|
+
// Notifications
|
|
184
|
+
notifications: [],
|
|
185
|
+
addNotification: (notification) =>
|
|
186
|
+
set((s) => ({
|
|
187
|
+
notifications: [...s.notifications, notification],
|
|
188
|
+
})),
|
|
189
|
+
removeNotification: (id) =>
|
|
190
|
+
set((s) => ({
|
|
191
|
+
notifications: s.notifications.filter((n) => n.id !== id),
|
|
192
|
+
})),
|
|
193
|
+
|
|
194
|
+
// Streaming
|
|
195
|
+
streamingContent: {},
|
|
196
|
+
appendStreamChunk: (poName, chunk) =>
|
|
197
|
+
set((s) => ({
|
|
198
|
+
streamingContent: {
|
|
199
|
+
...s.streamingContent,
|
|
200
|
+
[poName]: (s.streamingContent[poName] || '') + chunk,
|
|
201
|
+
},
|
|
202
|
+
})),
|
|
203
|
+
clearStream: (poName) =>
|
|
204
|
+
set((s) => {
|
|
205
|
+
const { [poName]: _, ...rest } = s.streamingContent
|
|
206
|
+
return { streamingContent: rest }
|
|
207
|
+
}),
|
|
208
|
+
|
|
209
|
+
// Response handling
|
|
210
|
+
pendingResponse: {},
|
|
211
|
+
setPendingResponse: (poName, content) =>
|
|
212
|
+
set((s) => ({
|
|
213
|
+
pendingResponse: {
|
|
214
|
+
...s.pendingResponse,
|
|
215
|
+
[poName]: content,
|
|
216
|
+
},
|
|
217
|
+
})),
|
|
218
|
+
clearPendingResponse: (poName) =>
|
|
219
|
+
set((s) => {
|
|
220
|
+
const { [poName]: _, ...rest } = s.pendingResponse
|
|
221
|
+
return { pendingResponse: rest }
|
|
222
|
+
}),
|
|
223
|
+
|
|
224
|
+
// LLM Config
|
|
225
|
+
llmConfig: null,
|
|
226
|
+
setLLMConfig: (config) => set({ llmConfig: config }),
|
|
227
|
+
updateCurrentLLM: (provider, model) =>
|
|
228
|
+
set((s) => ({
|
|
229
|
+
llmConfig: s.llmConfig
|
|
230
|
+
? { ...s.llmConfig, current_provider: provider, current_model: model }
|
|
231
|
+
: null,
|
|
232
|
+
})),
|
|
233
|
+
}))
|
|
234
|
+
|
|
235
|
+
// Selectors - use useShallow to prevent infinite re-renders with derived arrays
|
|
236
|
+
export const usePromptObjects = () =>
|
|
237
|
+
useStore(useShallow((s) => Object.values(s.promptObjects)))
|
|
238
|
+
|
|
239
|
+
export const useSelectedPO = () =>
|
|
240
|
+
useStore((s) => (s.selectedPO ? s.promptObjects[s.selectedPO] : null))
|
|
241
|
+
|
|
242
|
+
export const useNotificationCount = () =>
|
|
243
|
+
useStore((s) => s.notifications.length)
|
|
244
|
+
|
|
245
|
+
export const usePONotifications = (poName: string) =>
|
|
246
|
+
useStore(useShallow((s) => s.notifications.filter((n) => n.po_name === poName)))
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Core types for PromptObjects frontend
|
|
2
|
+
|
|
3
|
+
export interface Message {
|
|
4
|
+
role: 'user' | 'assistant' | 'tool'
|
|
5
|
+
content: string | null
|
|
6
|
+
from?: string
|
|
7
|
+
tool_calls?: ToolCall[]
|
|
8
|
+
results?: ToolResult[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ToolCall {
|
|
12
|
+
id: string
|
|
13
|
+
name: string
|
|
14
|
+
arguments: Record<string, unknown>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ToolResult {
|
|
18
|
+
tool_call_id: string
|
|
19
|
+
content: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ThreadType = 'root' | 'continuation' | 'delegation' | 'fork'
|
|
23
|
+
|
|
24
|
+
export interface Session {
|
|
25
|
+
id: string
|
|
26
|
+
name: string | null
|
|
27
|
+
message_count: number
|
|
28
|
+
updated_at?: string
|
|
29
|
+
// Thread fields
|
|
30
|
+
parent_session_id?: string
|
|
31
|
+
parent_po?: string
|
|
32
|
+
thread_type: ThreadType
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ThreadTree {
|
|
36
|
+
session: Session
|
|
37
|
+
children: ThreadTree[]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CurrentSession {
|
|
41
|
+
id: string
|
|
42
|
+
messages: Message[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface PromptObject {
|
|
46
|
+
name: string
|
|
47
|
+
description: string
|
|
48
|
+
status: 'idle' | 'thinking' | 'calling_tool'
|
|
49
|
+
capabilities: string[]
|
|
50
|
+
current_session: CurrentSession | null
|
|
51
|
+
sessions: Session[]
|
|
52
|
+
prompt?: string // The markdown body/prompt
|
|
53
|
+
config?: Record<string, unknown> // The YAML frontmatter config
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface BusMessage {
|
|
57
|
+
from: string
|
|
58
|
+
to: string
|
|
59
|
+
content: string
|
|
60
|
+
timestamp: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface Notification {
|
|
64
|
+
id: string
|
|
65
|
+
po_name: string
|
|
66
|
+
type: string
|
|
67
|
+
message: string
|
|
68
|
+
options: string[]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface Environment {
|
|
72
|
+
name: string
|
|
73
|
+
path: string
|
|
74
|
+
po_count: number
|
|
75
|
+
primitive_count: number
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// LLM Provider configuration
|
|
79
|
+
export interface LLMProvider {
|
|
80
|
+
name: string
|
|
81
|
+
models: string[]
|
|
82
|
+
default_model: string
|
|
83
|
+
available: boolean
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface LLMConfig {
|
|
87
|
+
current_provider: string
|
|
88
|
+
current_model: string
|
|
89
|
+
providers: LLMProvider[]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// WebSocket message types
|
|
93
|
+
export type WSMessageType =
|
|
94
|
+
| 'environment'
|
|
95
|
+
| 'po_state'
|
|
96
|
+
| 'po_response'
|
|
97
|
+
| 'po_added'
|
|
98
|
+
| 'po_modified'
|
|
99
|
+
| 'po_removed'
|
|
100
|
+
| 'stream'
|
|
101
|
+
| 'stream_end'
|
|
102
|
+
| 'bus_message'
|
|
103
|
+
| 'notification'
|
|
104
|
+
| 'notification_resolved'
|
|
105
|
+
| 'session_created'
|
|
106
|
+
| 'session_switched'
|
|
107
|
+
| 'session_updated'
|
|
108
|
+
| 'thread_created'
|
|
109
|
+
| 'thread_tree'
|
|
110
|
+
| 'llm_config'
|
|
111
|
+
| 'llm_switched'
|
|
112
|
+
| 'error'
|
|
113
|
+
| 'pong'
|
|
114
|
+
|
|
115
|
+
export interface WSMessage<T = unknown> {
|
|
116
|
+
type: WSMessageType
|
|
117
|
+
payload: T
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Client -> Server message types
|
|
121
|
+
export interface SendMessagePayload {
|
|
122
|
+
target: string
|
|
123
|
+
content: string
|
|
124
|
+
new_thread?: boolean // If true, create a new thread before sending
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface RespondToNotificationPayload {
|
|
128
|
+
id: string
|
|
129
|
+
response: string
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface CreateSessionPayload {
|
|
133
|
+
target: string
|
|
134
|
+
name?: string
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface SwitchSessionPayload {
|
|
138
|
+
target: string
|
|
139
|
+
session_id: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface CreateThreadPayload {
|
|
143
|
+
target: string
|
|
144
|
+
name?: string
|
|
145
|
+
thread_type?: ThreadType
|
|
146
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: [
|
|
4
|
+
"./index.html",
|
|
5
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
6
|
+
],
|
|
7
|
+
theme: {
|
|
8
|
+
extend: {
|
|
9
|
+
colors: {
|
|
10
|
+
// Custom colors for PromptObjects
|
|
11
|
+
po: {
|
|
12
|
+
bg: '#0f0f1a',
|
|
13
|
+
surface: '#1a1a2e',
|
|
14
|
+
border: '#2d2d44',
|
|
15
|
+
accent: '#7c3aed',
|
|
16
|
+
'accent-hover': '#9061f9',
|
|
17
|
+
success: '#22c55e',
|
|
18
|
+
warning: '#f59e0b',
|
|
19
|
+
error: '#ef4444',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
plugins: [],
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
|
|
23
|
+
/* Paths */
|
|
24
|
+
"baseUrl": ".",
|
|
25
|
+
"paths": {
|
|
26
|
+
"@/*": ["src/*"]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"include": ["src"]
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
|
|
4
|
+
// https://vite.dev/config/
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
|
|
8
|
+
// Output to Ruby server's public directory for production
|
|
9
|
+
build: {
|
|
10
|
+
outDir: '../lib/prompt_objects/server/public',
|
|
11
|
+
emptyOutDir: true,
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
// Development proxy to Ruby server
|
|
15
|
+
server: {
|
|
16
|
+
port: 5173,
|
|
17
|
+
proxy: {
|
|
18
|
+
'/api': {
|
|
19
|
+
target: 'http://localhost:3000',
|
|
20
|
+
changeOrigin: true,
|
|
21
|
+
},
|
|
22
|
+
// WebSocket proxy
|
|
23
|
+
'/ws': {
|
|
24
|
+
target: 'ws://localhost:3000',
|
|
25
|
+
ws: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
# Base class for all capabilities (both primitives and prompt objects).
|
|
5
|
+
# Everything in the system implements this interface.
|
|
6
|
+
class Capability
|
|
7
|
+
attr_reader :name, :description
|
|
8
|
+
attr_accessor :state
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@state = :idle
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Handle a message and return a response.
|
|
15
|
+
# @param message [String, Hash] The incoming message
|
|
16
|
+
# @param context [Context] Execution context with environment reference
|
|
17
|
+
# @return [String] The response
|
|
18
|
+
def receive(message, context:)
|
|
19
|
+
raise NotImplementedError, "#{self.class} must implement #receive"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Generate a tool descriptor for LLM function calling.
|
|
23
|
+
# @return [Hash] OpenAI-compatible tool descriptor
|
|
24
|
+
def descriptor
|
|
25
|
+
{
|
|
26
|
+
type: "function",
|
|
27
|
+
function: {
|
|
28
|
+
name: name,
|
|
29
|
+
description: description,
|
|
30
|
+
parameters: parameters
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Define the parameters this capability accepts.
|
|
36
|
+
# Override in subclasses for specific parameter schemas.
|
|
37
|
+
# @return [Hash] JSON Schema for parameters
|
|
38
|
+
def parameters
|
|
39
|
+
{
|
|
40
|
+
type: "object",
|
|
41
|
+
properties: {},
|
|
42
|
+
required: []
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|