prompt_objects 0.4.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +33 -0
- data/CLAUDE.md +113 -44
- data/README.md +140 -14
- data/frontend/index.html +5 -1
- data/frontend/src/App.tsx +72 -79
- data/frontend/src/canvas/CanvasView.tsx +5 -5
- data/frontend/src/canvas/constants.ts +31 -31
- data/frontend/src/canvas/inspector/InspectorPanel.tsx +4 -4
- data/frontend/src/canvas/inspector/POInspector.tsx +35 -35
- data/frontend/src/canvas/inspector/ToolCallInspector.tsx +13 -13
- data/frontend/src/canvas/nodes/PONode.ts +2 -2
- data/frontend/src/components/ContextMenu.tsx +5 -4
- data/frontend/src/components/EnvDataPane.tsx +69 -0
- data/frontend/src/components/Inspector.tsx +263 -0
- data/frontend/src/components/MarkdownMessage.tsx +22 -20
- data/frontend/src/components/MethodList.tsx +90 -0
- data/frontend/src/components/ModelSelector.tsx +13 -14
- data/frontend/src/components/NotificationPanel.tsx +29 -33
- data/frontend/src/components/ObjectList.tsx +78 -0
- data/frontend/src/components/PaneSlot.tsx +30 -0
- data/frontend/src/components/SourcePane.tsx +202 -0
- data/frontend/src/components/SystemBar.tsx +74 -0
- data/frontend/src/components/Transcript.tsx +76 -0
- data/frontend/src/components/UsagePanel.tsx +27 -27
- data/frontend/src/components/Workspace.tsx +260 -0
- data/frontend/src/components/index.ts +10 -9
- data/frontend/src/hooks/useResize.ts +55 -0
- data/frontend/src/hooks/useWebSocket.ts +70 -0
- data/frontend/src/index.css +27 -10
- data/frontend/src/store/index.ts +36 -0
- data/frontend/src/types/index.ts +13 -0
- data/frontend/tailwind.config.js +28 -9
- data/lib/prompt_objects/capability.rb +23 -1
- data/lib/prompt_objects/connectors/mcp.rb +2 -16
- data/lib/prompt_objects/environment.rb +15 -0
- data/lib/prompt_objects/llm/openai_adapter.rb +22 -0
- data/lib/prompt_objects/mcp/tools/inspect_po.rb +1 -31
- data/lib/prompt_objects/mcp/tools/list_prompt_objects.rb +1 -6
- data/lib/prompt_objects/prompt_object.rb +239 -7
- data/lib/prompt_objects/server/api/routes.rb +16 -48
- data/lib/prompt_objects/server/app.rb +14 -0
- data/lib/prompt_objects/server/public/assets/{index-xvyeb-5Z.js → index-DEPawnfZ.js} +206 -206
- data/lib/prompt_objects/server/public/assets/index-oMrRce1m.css +1 -0
- data/lib/prompt_objects/server/public/index.html +7 -3
- data/lib/prompt_objects/server/websocket_handler.rb +41 -98
- data/lib/prompt_objects/server.rb +6 -62
- data/lib/prompt_objects/session/store.rb +176 -4
- data/lib/prompt_objects/universal/delete_env_data.rb +70 -0
- data/lib/prompt_objects/universal/get_env_data.rb +64 -0
- data/lib/prompt_objects/universal/list_env_data.rb +61 -0
- data/lib/prompt_objects/universal/store_env_data.rb +87 -0
- data/lib/prompt_objects/universal/update_env_data.rb +88 -0
- data/lib/prompt_objects.rb +6 -1
- data/prompt_objects.gemspec +1 -1
- data/templates/arc-agi-1/objects/observer.md +4 -0
- data/templates/arc-agi-1/objects/solver.md +10 -1
- data/templates/arc-agi-1/objects/verifier.md +4 -0
- data/templates/arc-agi-1/primitives/find_objects.rb +1 -1
- data/templates/arc-agi-1/primitives/grid_diff.rb +2 -2
- data/templates/arc-agi-1/primitives/grid_info.rb +1 -1
- data/templates/arc-agi-1/primitives/grid_transform.rb +1 -1
- data/templates/arc-agi-1/primitives/render_grid.rb +1 -0
- data/templates/arc-agi-1/primitives/test_solution.rb +3 -0
- data/tools/thread-explorer.html +27 -0
- metadata +18 -16
- data/Gemfile.lock +0 -233
- data/IMPLEMENTATION_PLAN.md +0 -1073
- data/design-doc-v2.md +0 -1232
- data/frontend/src/components/CapabilitiesPanel.tsx +0 -141
- data/frontend/src/components/ChatPanel.tsx +0 -296
- data/frontend/src/components/Dashboard.tsx +0 -83
- data/frontend/src/components/Header.tsx +0 -153
- data/frontend/src/components/MessageBus.tsx +0 -56
- data/frontend/src/components/POCard.tsx +0 -56
- data/frontend/src/components/PODetail.tsx +0 -124
- data/frontend/src/components/PromptPanel.tsx +0 -156
- data/frontend/src/components/SessionsPanel.tsx +0 -174
- data/frontend/src/components/ThreadsSidebar.tsx +0 -163
- data/lib/prompt_objects/server/public/assets/index-6y64NXFy.css +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e9bb13a5f2b407279723343fe43ce570119e64a3fe2a115e4f427d195ec7040
|
|
4
|
+
data.tar.gz: fc1300754c1774ec388928752b84dd8a60286659904b8b72053fde457842ea71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56e4a427b43b49fc7520f9268a3e31c4a81d39c50ad0329985ab9d678631a2a88c41d070a7e13d97c01e2328de56e917d59b2b06c078fef9174a5a7fdc5db87b
|
|
7
|
+
data.tar.gz: a6bb7914d1b58c8c445deae870c2a06c004b9e7604b72107574f89c7ea9da2b8172034c358078b920d52b57eefe24acb68668d7057f16e61ed2e62ee2a85ca95
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to PromptObjects are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.6.0] - 2026-02-17
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Shared environment data** — 5 new universal capabilities (`store_env_data`, `get_env_data`, `list_env_data`, `update_env_data`, `delete_env_data`) provide a thread-scoped key-value store for delegation chains. Data is scoped to the root thread so separate conversations stay isolated. Entries include a `short_description` for lightweight LLM discovery without fetching full values.
|
|
10
|
+
- **Live environment data pane** — New collapsible pane in the Inspector shows shared env data updating in real-time as POs store and modify entries during delegation chains. WebSocket broadcasting (`env_data_changed`, `env_data_list`), a REST endpoint (`GET /api/sessions/:id/env_data`), and env data rendering in the Thread Explorer.
|
|
11
|
+
- **Delegation context** — POs now receive context about their delegation chain. An expanded system prompt teaches POs about their nature, a delegation preamble prepends caller context to delegated messages, and the full delegation chain is built from thread lineage.
|
|
12
|
+
- **Capability guard** — `execute_tool_calls` now rejects tools not in a PO's allowed set (declared capabilities + universals). Previously the LLM could hallucinate calls to any registered tool and they would execute. Now it receives an error directing it to use `add_capability` first.
|
|
13
|
+
- **Env data in thread exports** — `serialize_tree_for_export` includes env data entries at the root level of exported thread trees. Thread Explorer renders these in an amber-colored section.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Root font-size causing undersized text** — Removed a `font-size: 14px` on the root `html` element that made all rem-based Tailwind sizes ~12% smaller than intended (e.g. `text-xs` computed to 10.5px instead of 12px).
|
|
18
|
+
- **Invisible resize handle boundaries** — Added border styling to horizontal and vertical resize handles so pane boundaries are visible without hovering.
|
|
19
|
+
- **Stale MCP tools tests** — Fixed test expectations broken by PO serialization centralization in 0.5.0.
|
|
20
|
+
|
|
21
|
+
## [0.5.0] - 2026-02-13
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Smalltalk System Browser redesign** — Complete frontend overhaul replacing the chat-app UI with a multi-pane object browser. POs are treated as live objects in a running image: permanent ObjectList (left pane), multi-pane Inspector with MethodList + SourcePane, REPL-style Workspace, and bottom Transcript. Warm charcoal + amber palette with Geist fonts. All panels resizable via drag handles.
|
|
26
|
+
- **Collapsible inspector top pane** — The Methods + Source pane has a thin header bar with a collapse/expand toggle. When collapsed, the Workspace fills the full inspector height. Collapse state persists across PO switches.
|
|
27
|
+
- **Source entry in method list** — A "Source" entry at the top of the method list provides a clear way to navigate back to the PO's prompt after inspecting a capability.
|
|
28
|
+
- **Dynamic Ollama model discovery** — LLM config now queries the Ollama API for installed models instead of using a static list.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **Capabilities disappearing on file save** — `po_modified` events were sending capabilities as plain string names instead of rich objects, overwriting the store. All serialization paths now emit consistent `{name, description, parameters}` objects.
|
|
33
|
+
- **Centralized PO serialization** — Moved duplicated state/message/session serialization from WebSocketHandler and API routes into `PromptObject` (`to_state_hash`, `to_summary_hash`, `to_inspect_hash`). Eliminates inconsistent serialization as a class of bug.
|
|
34
|
+
- **Missing items field in array tool schemas** — LLM APIs reject array parameters without an `items` field. Added a defensive sanitizer in `Capability#descriptor` as a fallback.
|
|
35
|
+
- **OpenAI adapter error details** — 4xx errors from Ollama now surface the actual rejection reason instead of just "status 400".
|
|
36
|
+
- **All WebSocket message types handled** — Added frontend handlers for `prompt_updated`, `llm_error`, `session_created`, and `session_switched`. Removed defensive normalization workarounds.
|
|
37
|
+
|
|
5
38
|
## [0.4.0] - 2026-02-11
|
|
6
39
|
|
|
7
40
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -6,17 +6,21 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
6
6
|
|
|
7
7
|
**PromptObjects** is a Ruby framework where markdown files with LLM-backed behavior act as first-class autonomous entities. The core insight: **everything is a capability**—primitives (Ruby code) and Prompt-Objects (markdown files) share the same interface, differing only in interpretation complexity.
|
|
8
8
|
|
|
9
|
-
**Current Status**:
|
|
9
|
+
**Current Status**: v0.5.0 — The core framework is fully implemented and functional. The original 6-phase implementation plan is complete. Active development is focused on visualization, developer experience, and exploring new primitives. See `CHANGELOG.md` for release history and `docs/archive/` for original design context.
|
|
10
10
|
|
|
11
11
|
## Architecture
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
|
|
14
|
+
RUNTIME (Environment)
|
|
15
15
|
├── CAPABILITY REGISTRY
|
|
16
16
|
│ ├── PRIMITIVES (Ruby) - deterministic interpretation
|
|
17
|
-
│
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
│ ├── PROMPT-OBJECTS (Markdown) - semantic interpretation via LLM
|
|
18
|
+
│ └── UNIVERSAL CAPABILITIES - available to all POs automatically
|
|
19
|
+
├── MESSAGE BUS - routes messages, logs to SQLite for replay
|
|
20
|
+
├── SESSION STORE (SQLite) - persistent conversation threads, delegation tracking
|
|
21
|
+
├── HUMAN QUEUE - non-blocking ask_human requests
|
|
22
|
+
├── WEB SERVER (Falcon + async-websocket) - serves React frontend
|
|
23
|
+
└── MCP SERVER - exposes POs as tools via Model Context Protocol
|
|
20
24
|
```
|
|
21
25
|
|
|
22
26
|
### Unified Capability Interface
|
|
@@ -53,56 +57,121 @@ You are a careful, thoughtful file reader...
|
|
|
53
57
|
Available to all Prompt-Objects automatically (no frontmatter declaration needed):
|
|
54
58
|
- `ask_human` - pause for human input/confirmation
|
|
55
59
|
- `think` - internal reasoning (not shown to human)
|
|
56
|
-
- `
|
|
60
|
+
- `create_capability` / `add_capability` / `remove_capability` - self-modification
|
|
61
|
+
- `list_capabilities` / `list_primitives` - introspection
|
|
62
|
+
- `create_primitive` / `add_primitive` / `delete_primitive` / `verify_primitive` / `modify_primitive` / `request_primitive` - primitive management
|
|
63
|
+
- `modify_prompt` - rewrite own system prompt at runtime
|
|
64
|
+
- `store_env_data` / `get_env_data` / `list_env_data` / `update_env_data` / `delete_env_data` - thread-scoped shared key-value store for delegation chains
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- **Ruby** - core implementation
|
|
61
|
-
- **LLM APIs** - OpenAI, Anthropic, Gemini (adapter pattern)
|
|
62
|
-
- **Charm** - Terminal UI (Bubble Tea for interaction, Lipgloss for styling, Glamour for markdown)
|
|
63
|
-
- **MCP** - Model Context Protocol integration
|
|
66
|
+
### PO-to-PO Delegation
|
|
67
|
+
When a PO calls another PO, the system creates an isolated delegation thread in the target PO. The caller's context is tracked so messages show correct provenance. Delegation start/complete events are broadcast via WebSocket for real-time UI updates.
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
## Technology Stack
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
- **Ruby** (>= 3.2, tested through Ruby 4) - core implementation
|
|
72
|
+
- **LLM APIs** - OpenAI, Anthropic, Gemini, Ollama, OpenRouter (adapter pattern via `LLM::Factory`)
|
|
73
|
+
- **Falcon** - async HTTP server for REST API and static file serving
|
|
74
|
+
- **async-websocket** - real-time WebSocket communication
|
|
75
|
+
- **React + TypeScript** - web frontend (Smalltalk System Browser-inspired multi-pane UI)
|
|
76
|
+
- **Three.js** - spatial canvas visualization (force-directed PO graph)
|
|
77
|
+
- **SQLite** - session persistence and event log storage
|
|
78
|
+
- **MCP** - Model Context Protocol server mode
|
|
68
79
|
|
|
69
|
-
##
|
|
80
|
+
## File Structure
|
|
70
81
|
|
|
71
82
|
```
|
|
72
83
|
prompt_objects/
|
|
73
|
-
├── exe/prompt_objects
|
|
84
|
+
├── exe/prompt_objects # CLI entrypoint
|
|
74
85
|
├── lib/
|
|
75
|
-
│ ├── prompt_objects.rb
|
|
86
|
+
│ ├── prompt_objects.rb # Main entry, requires all modules
|
|
76
87
|
│ └── prompt_objects/
|
|
77
|
-
│ ├── environment.rb
|
|
78
|
-
│ ├── capability.rb
|
|
79
|
-
│ ├── prompt_object.rb
|
|
80
|
-
│ ├── primitive.rb
|
|
81
|
-
│ ├── loader.rb
|
|
82
|
-
│ ├── registry.rb
|
|
83
|
-
│ ├── message_bus.rb
|
|
84
|
-
│ ├──
|
|
85
|
-
│ ├──
|
|
86
|
-
│ ├──
|
|
87
|
-
│ ├──
|
|
88
|
-
│
|
|
89
|
-
├──
|
|
90
|
-
|
|
88
|
+
│ ├── environment.rb # Runtime container (registry, bus, LLM, sessions)
|
|
89
|
+
│ ├── capability.rb # Base capability interface
|
|
90
|
+
│ ├── prompt_object.rb # PO implementation (LLM conversation loop)
|
|
91
|
+
│ ├── primitive.rb # Primitive tool wrapper
|
|
92
|
+
│ ├── loader.rb # Parses frontmatter + body from .md files
|
|
93
|
+
│ ├── registry.rb # Capability registration and lookup
|
|
94
|
+
│ ├── message_bus.rb # Message routing, logging, SQLite persistence
|
|
95
|
+
│ ├── human_queue.rb # Non-blocking human interaction queue
|
|
96
|
+
│ ├── cli.rb # CLI command definitions
|
|
97
|
+
│ ├── server.rb # Web server setup
|
|
98
|
+
│ ├── server/
|
|
99
|
+
│ │ ├── app.rb # Sinatra application
|
|
100
|
+
│ │ ├── api/routes.rb # REST API endpoints
|
|
101
|
+
│ │ ├── websocket_handler.rb # WebSocket event handling
|
|
102
|
+
│ │ └── file_watcher.rb # Live .md file change detection
|
|
103
|
+
│ ├── llm/
|
|
104
|
+
│ │ ├── factory.rb # Provider/model selection
|
|
105
|
+
│ │ ├── response.rb # Unified response object
|
|
106
|
+
│ │ ├── pricing.rb # Token cost calculation
|
|
107
|
+
│ │ ├── openai_adapter.rb # OpenAI + Ollama + OpenRouter
|
|
108
|
+
│ │ ├── anthropic_adapter.rb
|
|
109
|
+
│ │ └── gemini_adapter.rb
|
|
110
|
+
│ ├── primitives/ # Built-in: read_file, list_files, write_file, http_get
|
|
111
|
+
│ ├── universal/ # 14 universal capabilities (see list above)
|
|
112
|
+
│ ├── connectors/ # Interface adapters (base, mcp)
|
|
113
|
+
│ ├── mcp/ # MCP server and tool definitions
|
|
114
|
+
│ ├── session/
|
|
115
|
+
│ │ └── store.rb # SQLite session/thread persistence
|
|
116
|
+
│ └── environment/
|
|
117
|
+
│ ├── manager.rb # Create/list/clone environments
|
|
118
|
+
│ ├── manifest.rb # Environment metadata (manifest.yml)
|
|
119
|
+
│ ├── git.rb # Auto-commit integration
|
|
120
|
+
│ ├── exporter.rb # Environment export
|
|
121
|
+
│ └── importer.rb # Environment import
|
|
122
|
+
├── frontend/ # React + TypeScript web UI
|
|
123
|
+
│ └── src/
|
|
124
|
+
│ ├── App.tsx
|
|
125
|
+
│ ├── components/ # SystemBar, ObjectList, Inspector, Workspace, Transcript
|
|
126
|
+
│ ├── canvas/ # Three.js spatial visualization
|
|
127
|
+
│ ├── hooks/ # WebSocket, state management hooks
|
|
128
|
+
│ ├── store/ # Frontend state
|
|
129
|
+
│ └── types/ # TypeScript type definitions
|
|
130
|
+
├── objects/ # Default POs: greeter, reader, coordinator
|
|
131
|
+
├── templates/ # Environment templates (basic, developer, writer, arc-agi-1, etc.)
|
|
132
|
+
├── tools/ # Development tooling
|
|
133
|
+
└── test/ # Unit and integration tests
|
|
91
134
|
```
|
|
92
135
|
|
|
93
|
-
## Implementation Phases
|
|
94
|
-
|
|
95
|
-
1. **Core Loop**: Capability base, PromptObject, Loader, single LLM adapter, simple REPL
|
|
96
|
-
2. **Primitives & Binding**: Primitive base, built-in primitives, Registry
|
|
97
|
-
3. **Multi-Capability**: Message bus with logging, PO↔PO communication
|
|
98
|
-
4. **Self-Modification**: Universal capabilities including create_capability
|
|
99
|
-
5. **Polish & UI**: Full Charm integration, all UI components
|
|
100
|
-
6. **Demo Ready**: Error handling, testing, practice runs
|
|
101
|
-
|
|
102
136
|
## Key Concepts
|
|
103
137
|
|
|
104
138
|
- **Semantic Binding**: Natural language → capability call (visible in message log)
|
|
105
|
-
- **PO↔PO Communication**: Prompt-Objects
|
|
106
|
-
- **Self-Modification**:
|
|
107
|
-
- **Human-in-the-Loop**: POs
|
|
108
|
-
- **
|
|
139
|
+
- **PO↔PO Communication**: Prompt-Objects call each other as capabilities through isolated delegation threads
|
|
140
|
+
- **Self-Modification**: POs can create new POs and primitives at runtime (with human approval)
|
|
141
|
+
- **Human-in-the-Loop**: POs use `ask_human` to pause and queue notifications; human responds asynchronously via the web UI
|
|
142
|
+
- **Environments**: Isolated collections of POs with their own sessions, git history, and configuration. Created from templates via CLI.
|
|
143
|
+
- **Thread Export**: Conversation threads (including delegation chains) exportable as Markdown or JSON
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Install dependencies
|
|
149
|
+
bundle install
|
|
150
|
+
cd frontend && npm install && cd ..
|
|
151
|
+
|
|
152
|
+
# Run tests
|
|
153
|
+
bundle exec rake test
|
|
154
|
+
|
|
155
|
+
# Serve an environment with web UI
|
|
156
|
+
prompt_objects serve <env-name> --open
|
|
157
|
+
|
|
158
|
+
# Environment management
|
|
159
|
+
prompt_objects env create <name> --template basic
|
|
160
|
+
prompt_objects env list
|
|
161
|
+
prompt_objects env info <name>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Releases
|
|
165
|
+
|
|
166
|
+
Always tag releases. Pushing a version tag triggers the Discord notification workflow (`.github/workflows/discord-release.yml`), which extracts the matching section from `CHANGELOG.md` and posts it.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# 1. Update version in prompt_objects.gemspec
|
|
170
|
+
# 2. Add changelog entry under ## [X.Y.Z] - YYYY-MM-DD
|
|
171
|
+
# 3. Commit: "Release vX.Y.Z — short description"
|
|
172
|
+
# 4. Tag and push:
|
|
173
|
+
git tag vX.Y.Z
|
|
174
|
+
git push && git push origin vX.Y.Z
|
|
175
|
+
# 5. Publish gem:
|
|
176
|
+
gem build prompt_objects.gemspec && gem push prompt_objects-X.Y.Z.gem
|
|
177
|
+
```
|
data/README.md
CHANGED
|
@@ -27,8 +27,86 @@ A Ruby framework where:
|
|
|
27
27
|
- **Markdown files** define autonomous entities (Prompt Objects)
|
|
28
28
|
- **YAML frontmatter** declares capabilities and configuration
|
|
29
29
|
- **Markdown body** becomes identity and behavior (the system prompt)
|
|
30
|
-
- **Capabilities** are shared between primitives (Ruby) and Prompt Objects (markdown)
|
|
31
|
-
- **Environments** isolate collections of objects with their own memory
|
|
30
|
+
- **Capabilities** are shared between primitives (Ruby) and Prompt Objects (markdown) -- everything is a capability
|
|
31
|
+
- **Environments** isolate collections of objects with their own memory, git history, and configuration
|
|
32
|
+
- **PO-to-PO delegation** lets objects call each other through isolated threads with full provenance tracking
|
|
33
|
+
|
|
34
|
+
### Prompt Object structure
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
---
|
|
38
|
+
name: reader
|
|
39
|
+
description: Helps people understand files
|
|
40
|
+
capabilities:
|
|
41
|
+
- read_file
|
|
42
|
+
- list_files
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# Reader
|
|
46
|
+
## Identity
|
|
47
|
+
You are a careful, thoughtful file reader...
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Web UI
|
|
51
|
+
|
|
52
|
+
The web interface is modeled after the Smalltalk System Browser -- a multi-pane environment for inspecting and interacting with live objects:
|
|
53
|
+
|
|
54
|
+
- **ObjectList** -- permanent left pane listing all POs in the environment
|
|
55
|
+
- **Inspector** -- split into a MethodList (capabilities) and SourcePane (the prompt markdown or capability source)
|
|
56
|
+
- **Workspace** -- a REPL-style chat pane for sending messages to the selected PO
|
|
57
|
+
- **Transcript** -- bottom pane showing message bus events in real time
|
|
58
|
+
|
|
59
|
+
All panels are resizable. The inspector's top pane collapses so the Workspace can fill the full height when you just want to talk.
|
|
60
|
+
|
|
61
|
+
### Spatial Canvas
|
|
62
|
+
|
|
63
|
+
Navigate to `/canvas` for a Three.js 2D visualization of your environment. POs appear as glowing hexagonal nodes in a force-directed layout. Tool calls show as diamonds. Message arcs animate with traveling particles. Delegation lights up the target PO with a cyan glow. Click any node to inspect it. Keyboard shortcuts: F to fit, Escape to deselect.
|
|
64
|
+
|
|
65
|
+
### MCP Server mode
|
|
66
|
+
|
|
67
|
+
Run any environment as an MCP (Model Context Protocol) server for integration with Claude Desktop, Cursor, or any MCP-compatible client:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
prompt_objects serve my-assistant --mcp
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add to your `claude_desktop_config.json`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"my-assistant": {
|
|
79
|
+
"command": "prompt_objects",
|
|
80
|
+
"args": ["serve", "--mcp", "my-assistant"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Exposes tools for sending messages, listing POs, inspecting state, getting conversations, and responding to pending `ask_human` requests.
|
|
87
|
+
|
|
88
|
+
### Multi-provider LLM support
|
|
89
|
+
|
|
90
|
+
Swap providers with an environment variable. Adapters for:
|
|
91
|
+
|
|
92
|
+
- **OpenAI** -- GPT-5.2, GPT-4.1, o3-mini, o1
|
|
93
|
+
- **Anthropic** -- Claude Haiku 4.5, Claude Sonnet 4.5, Claude Opus 4
|
|
94
|
+
- **Gemini** -- Gemini 3 Flash, Gemini 2.5 Pro, Gemini 2.5 Flash
|
|
95
|
+
- **Ollama** -- any locally installed model, discovered automatically
|
|
96
|
+
- **OpenRouter** -- access any model through a single API key
|
|
97
|
+
|
|
98
|
+
### Thread Explorer
|
|
99
|
+
|
|
100
|
+
A standalone HTML visualizer for exported conversation threads. Open it from the CLI to browse delegation chains, message flow, and tool call sequences:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
prompt_objects explore my-env
|
|
104
|
+
prompt_objects explore my-env --session abc123
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Note on the TUI
|
|
108
|
+
|
|
109
|
+
A terminal UI (built with Charm libraries) exists in the codebase but is deprioritized. The web UI is the primary interface for day-to-day use.
|
|
32
110
|
|
|
33
111
|
How
|
|
34
112
|
===
|
|
@@ -49,25 +127,73 @@ prompt_objects env create my-project --template basic
|
|
|
49
127
|
prompt_objects serve my-project --open
|
|
50
128
|
```
|
|
51
129
|
|
|
52
|
-
###
|
|
130
|
+
### Commands
|
|
53
131
|
|
|
54
|
-
```
|
|
55
|
-
prompt_objects env
|
|
56
|
-
prompt_objects
|
|
57
|
-
prompt_objects
|
|
58
|
-
prompt_objects
|
|
132
|
+
```
|
|
133
|
+
prompt_objects serve <env> Start web server (default)
|
|
134
|
+
prompt_objects serve <env> --open Start and open browser
|
|
135
|
+
prompt_objects serve <env> --mcp Start as MCP server
|
|
136
|
+
prompt_objects serve <env> --port 4000 Custom port (default: 3000)
|
|
137
|
+
|
|
138
|
+
prompt_objects repl [name] [objects_dir] Interactive REPL with a prompt object
|
|
139
|
+
prompt_objects repl --sandbox REPL in sandbox mode (isolates changes)
|
|
140
|
+
|
|
141
|
+
prompt_objects message <env> <po> "text" Send a message and print the response
|
|
142
|
+
prompt_objects message <env> <po> "text" --json JSON output
|
|
143
|
+
prompt_objects message <env> <po> "text" --events Include event log
|
|
144
|
+
|
|
145
|
+
prompt_objects events <env> Show recent message bus events
|
|
146
|
+
prompt_objects events <env> --session ID Events for a specific session
|
|
147
|
+
prompt_objects events <env> --json JSON output
|
|
148
|
+
|
|
149
|
+
prompt_objects explore [env] Open Thread Explorer in browser
|
|
150
|
+
prompt_objects explore <env> --session ID Visualize a specific thread
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Environment management
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
prompt_objects env list List all environments
|
|
157
|
+
prompt_objects env create <name> Create new environment
|
|
158
|
+
prompt_objects env create <name> -t <tmpl> Create from template
|
|
159
|
+
prompt_objects env info <name> Show environment details
|
|
160
|
+
prompt_objects env clone <src> <dst> Clone an environment
|
|
161
|
+
prompt_objects env export <name> Export as .poenv bundle
|
|
162
|
+
prompt_objects env import <file.poenv> Import from bundle
|
|
163
|
+
prompt_objects env archive <name> Soft-delete (archive)
|
|
164
|
+
prompt_objects env restore <name> Restore archived environment
|
|
165
|
+
prompt_objects env delete <name> --permanent Permanently delete archived env
|
|
166
|
+
prompt_objects env default <name> Set the default environment
|
|
59
167
|
```
|
|
60
168
|
|
|
61
169
|
### Templates
|
|
62
170
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
171
|
+
Create an environment from a template with `prompt_objects env create <name> --template <template>`:
|
|
172
|
+
|
|
173
|
+
| Template | Description |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `basic` | No capabilities, learns as needed -- great for demos |
|
|
176
|
+
| `minimal` | Basic assistant with file reading |
|
|
177
|
+
| `developer` | Code review, debugging, testing specialists |
|
|
178
|
+
| `writer` | Editor, researcher for content creation |
|
|
179
|
+
| `empty` | Start from scratch with just a bootstrap assistant |
|
|
180
|
+
| `arc-agi-1` | ARC-AGI-1 challenge solver with grid primitives |
|
|
67
181
|
|
|
68
182
|
Extras
|
|
69
183
|
======
|
|
70
184
|
|
|
71
|
-
|
|
72
|
-
|
|
185
|
+
### Community
|
|
186
|
+
|
|
187
|
+
Join the [Discord](https://discord.gg/fcMvcwdrZS) for support, discussion, and updates.
|
|
188
|
+
|
|
189
|
+
### Blog Posts
|
|
190
|
+
|
|
191
|
+
- [What if we took message passing seriously?](https://worksonmymachine.ai/p/what-if-we-took-message-passing-seriously) -- the origin story and motivation behind Prompt Objects
|
|
192
|
+
- [As complexity grows, architecture](https://worksonmymachine.ai/p/as-complexity-grows-architecture) -- on why the hard problems are structural, not generative
|
|
193
|
+
|
|
194
|
+
### Links
|
|
195
|
+
|
|
73
196
|
- **Repository**: https://github.com/works-on-your-machine/prompt_objects
|
|
197
|
+
- **Changelog**: https://github.com/works-on-your-machine/prompt_objects/blob/main/CHANGELOG.md
|
|
198
|
+
- **License**: MIT
|
|
199
|
+
- **Ruby**: >= 3.2.0 (tested through Ruby 4)
|
data/frontend/index.html
CHANGED
|
@@ -4,9 +4,13 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
|
|
8
|
+
<link href="https://cdn.jsdelivr.net/fontsource/fonts/geist@latest/latin-400-normal.woff2" as="font" type="font/woff2" crossorigin />
|
|
9
|
+
<link href="https://cdn.jsdelivr.net/npm/geist@1/dist/fonts/geist-sans/style.css" rel="stylesheet" />
|
|
10
|
+
<link href="https://cdn.jsdelivr.net/npm/geist@1/dist/fonts/geist-mono/style.css" rel="stylesheet" />
|
|
7
11
|
<title>PromptObjects</title>
|
|
8
12
|
</head>
|
|
9
|
-
<body class="bg-po-bg text-
|
|
13
|
+
<body class="bg-po-bg text-po-text-primary font-ui">
|
|
10
14
|
<div id="root"></div>
|
|
11
15
|
<script type="module" src="/src/main.tsx"></script>
|
|
12
16
|
</body>
|
data/frontend/src/App.tsx
CHANGED
|
@@ -1,103 +1,96 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
1
|
import { useWebSocket } from './hooks/useWebSocket'
|
|
3
2
|
import { useStore, useSelectedPO } from './store'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
3
|
+
import { useResize } from './hooks/useResize'
|
|
4
|
+
import { SystemBar } from './components/SystemBar'
|
|
5
|
+
import { ObjectList } from './components/ObjectList'
|
|
6
|
+
import { Inspector } from './components/Inspector'
|
|
7
|
+
import { Transcript } from './components/Transcript'
|
|
8
8
|
import { NotificationPanel } from './components/NotificationPanel'
|
|
9
|
-
import { ThreadsSidebar } from './components/ThreadsSidebar'
|
|
10
9
|
import { UsagePanel } from './components/UsagePanel'
|
|
11
10
|
import { CanvasView } from './canvas/CanvasView'
|
|
12
11
|
|
|
13
12
|
export default function App() {
|
|
14
|
-
const { sendMessage, respondToNotification, createSession, switchSession, switchLLM, createThread, updatePrompt, requestUsage, exportThread } =
|
|
13
|
+
const { sendMessage, respondToNotification, createSession, switchSession, switchLLM, createThread, updatePrompt, requestUsage, exportThread, requestEnvData } =
|
|
15
14
|
useWebSocket()
|
|
16
15
|
const { selectedPO, busOpen, notifications, usageData, clearUsageData, currentView } = useStore()
|
|
17
16
|
const selectedPOData = useSelectedPO()
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
const objectListResize = useResize({
|
|
19
|
+
direction: 'horizontal',
|
|
20
|
+
initialSize: 192,
|
|
21
|
+
minSize: 120,
|
|
22
|
+
maxSize: 320,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const transcriptResize = useResize({
|
|
26
|
+
direction: 'vertical',
|
|
27
|
+
initialSize: 180,
|
|
28
|
+
minSize: 80,
|
|
29
|
+
maxSize: 400,
|
|
30
|
+
inverted: true,
|
|
31
|
+
})
|
|
19
32
|
|
|
20
33
|
return (
|
|
21
34
|
<div className="h-screen flex flex-col bg-po-bg">
|
|
22
|
-
<
|
|
35
|
+
<SystemBar switchLLM={switchLLM} />
|
|
23
36
|
|
|
24
|
-
<div className="flex-1 flex overflow-hidden">
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
<h2 className="text-sm font-medium text-gray-400">Prompt Objects</h2>
|
|
36
|
-
<button
|
|
37
|
-
onClick={() => setSplitView(false)}
|
|
38
|
-
className="text-xs text-gray-500 hover:text-white"
|
|
39
|
-
title="Hide sidebar"
|
|
40
|
-
>
|
|
41
|
-
✕
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
<div className="flex-1 overflow-auto">
|
|
45
|
-
<Dashboard compact />
|
|
46
|
-
</div>
|
|
47
|
-
</aside>
|
|
48
|
-
|
|
49
|
-
{/* Threads List for selected PO */}
|
|
50
|
-
{selectedPOData && (
|
|
51
|
-
<aside className="w-56 border-r border-po-border bg-po-bg overflow-hidden">
|
|
52
|
-
<ThreadsSidebar
|
|
53
|
-
po={selectedPOData}
|
|
54
|
-
switchSession={switchSession}
|
|
55
|
-
createThread={createThread}
|
|
56
|
-
requestUsage={requestUsage}
|
|
57
|
-
exportThread={exportThread}
|
|
58
|
-
/>
|
|
59
|
-
</aside>
|
|
60
|
-
)}
|
|
61
|
-
</>
|
|
62
|
-
)}
|
|
37
|
+
<div className="flex-1 flex flex-col overflow-hidden">
|
|
38
|
+
{/* Main view area */}
|
|
39
|
+
<div className="flex-1 flex overflow-hidden">
|
|
40
|
+
{currentView === 'canvas' ? (
|
|
41
|
+
<CanvasView />
|
|
42
|
+
) : (
|
|
43
|
+
<>
|
|
44
|
+
{/* Object List - resizable */}
|
|
45
|
+
<div style={{ width: objectListResize.size }} className="flex-shrink-0">
|
|
46
|
+
<ObjectList />
|
|
47
|
+
</div>
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
onClick={() => setSplitView(true)}
|
|
70
|
-
className="absolute left-2 top-16 z-10 bg-po-surface border border-po-border rounded px-2 py-1 text-xs text-gray-400 hover:text-white hover:border-po-accent transition-colors"
|
|
71
|
-
title="Show dashboard sidebar"
|
|
72
|
-
>
|
|
73
|
-
☰ POs
|
|
74
|
-
</button>
|
|
75
|
-
)}
|
|
49
|
+
{/* Resize handle */}
|
|
50
|
+
<div
|
|
51
|
+
className="resize-handle"
|
|
52
|
+
onMouseDown={objectListResize.onMouseDown}
|
|
53
|
+
/>
|
|
76
54
|
|
|
77
|
-
{
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
55
|
+
{/* Main content */}
|
|
56
|
+
<main className="flex-1 overflow-hidden flex flex-col">
|
|
57
|
+
{selectedPO && selectedPOData ? (
|
|
58
|
+
<Inspector
|
|
59
|
+
po={selectedPOData}
|
|
60
|
+
sendMessage={sendMessage}
|
|
61
|
+
createSession={createSession}
|
|
62
|
+
switchSession={switchSession}
|
|
63
|
+
createThread={createThread}
|
|
64
|
+
updatePrompt={updatePrompt}
|
|
65
|
+
requestUsage={requestUsage}
|
|
66
|
+
exportThread={exportThread}
|
|
67
|
+
requestEnvData={requestEnvData}
|
|
68
|
+
/>
|
|
69
|
+
) : (
|
|
70
|
+
<div className="h-full flex items-center justify-center text-po-text-ghost">
|
|
71
|
+
<span className="font-mono text-xs">Select an object</span>
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
</main>
|
|
75
|
+
</>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
91
78
|
|
|
92
|
-
{/*
|
|
79
|
+
{/* Transcript - resizable bottom pane, visible in both views */}
|
|
93
80
|
{busOpen && (
|
|
94
|
-
|
|
95
|
-
<
|
|
96
|
-
|
|
81
|
+
<>
|
|
82
|
+
<div
|
|
83
|
+
className="resize-handle-h"
|
|
84
|
+
onMouseDown={transcriptResize.onMouseDown}
|
|
85
|
+
/>
|
|
86
|
+
<div style={{ height: transcriptResize.size }} className="flex-shrink-0">
|
|
87
|
+
<Transcript />
|
|
88
|
+
</div>
|
|
89
|
+
</>
|
|
97
90
|
)}
|
|
98
91
|
</div>
|
|
99
92
|
|
|
100
|
-
{/* Notification panel */}
|
|
93
|
+
{/* Notification panel - floating */}
|
|
101
94
|
{notifications.length > 0 && (
|
|
102
95
|
<NotificationPanel respondToNotification={respondToNotification} />
|
|
103
96
|
)}
|
|
@@ -83,17 +83,17 @@ export function CanvasView() {
|
|
|
83
83
|
<div className="absolute top-3 left-3 flex gap-2 z-10">
|
|
84
84
|
<button
|
|
85
85
|
onClick={() => sceneRef.current?.fitAll()}
|
|
86
|
-
className="px-
|
|
86
|
+
className="px-2.5 py-1 text-xs bg-po-surface-2/80 backdrop-blur border border-po-border rounded hover:border-po-accent transition-colors duration-150 text-po-text-secondary hover:text-po-text-primary"
|
|
87
87
|
title="Fit all nodes (F)"
|
|
88
88
|
>
|
|
89
89
|
Fit All
|
|
90
90
|
</button>
|
|
91
91
|
<button
|
|
92
92
|
onClick={toggleLabels}
|
|
93
|
-
className={`px-
|
|
93
|
+
className={`px-2.5 py-1 text-xs backdrop-blur border rounded transition-colors duration-150 ${
|
|
94
94
|
showLabels
|
|
95
|
-
? 'bg-po-accent
|
|
96
|
-
: 'bg-po-surface/80 border-po-border text-
|
|
95
|
+
? 'bg-po-accent-wash border-po-accent text-po-accent'
|
|
96
|
+
: 'bg-po-surface-2/80 border-po-border text-po-text-secondary hover:text-po-text-primary'
|
|
97
97
|
}`}
|
|
98
98
|
title="Toggle labels"
|
|
99
99
|
>
|
|
@@ -102,7 +102,7 @@ export function CanvasView() {
|
|
|
102
102
|
</div>
|
|
103
103
|
|
|
104
104
|
{/* Help hint */}
|
|
105
|
-
<div className="absolute bottom-3 left-3 text-
|
|
105
|
+
<div className="absolute bottom-3 left-3 text-2xs text-po-text-ghost z-10 font-mono">
|
|
106
106
|
Scroll to zoom · Shift+drag to pan · F to fit · Click node to inspect
|
|
107
107
|
</div>
|
|
108
108
|
|