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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to delete a key from the shared environment data.
|
|
6
|
+
class DeleteEnvData < Primitive
|
|
7
|
+
def name
|
|
8
|
+
"delete_env_data"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def description
|
|
12
|
+
"Delete a key from the shared environment data for this delegation chain."
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def parameters
|
|
16
|
+
{
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
key: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "The key to delete"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
required: ["key"]
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def receive(message, context:)
|
|
29
|
+
key = message[:key] || message["key"]
|
|
30
|
+
return "Error: 'key' is required" unless key
|
|
31
|
+
|
|
32
|
+
root_thread_id = resolve_root_thread(context)
|
|
33
|
+
return "Error: Could not resolve thread scope (no active session)" unless root_thread_id
|
|
34
|
+
|
|
35
|
+
store = context.env.session_store
|
|
36
|
+
return "Error: Session store not available" unless store
|
|
37
|
+
|
|
38
|
+
deleted = store.delete_env_data(root_thread_id: root_thread_id, key: key)
|
|
39
|
+
|
|
40
|
+
unless deleted
|
|
41
|
+
return "Key '#{key}' not found in environment data."
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
stored_by = context.calling_po || "unknown"
|
|
45
|
+
|
|
46
|
+
context.bus.publish(
|
|
47
|
+
from: stored_by,
|
|
48
|
+
to: "env_data",
|
|
49
|
+
message: { action: "delete", key: key }
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
context.env.notify_env_data_changed(action: "delete", root_thread_id: root_thread_id, key: key, stored_by: stored_by)
|
|
53
|
+
|
|
54
|
+
"Deleted '#{key}' from environment data."
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def resolve_root_thread(context)
|
|
60
|
+
store = context.env.session_store
|
|
61
|
+
return nil unless store
|
|
62
|
+
|
|
63
|
+
po = context.env.registry.get(context.calling_po)
|
|
64
|
+
return nil unless po&.respond_to?(:session_id) && po.session_id
|
|
65
|
+
|
|
66
|
+
store.resolve_root_thread(po.session_id)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to retrieve shared data by key from the current delegation chain.
|
|
6
|
+
class GetEnvData < Primitive
|
|
7
|
+
def name
|
|
8
|
+
"get_env_data"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def description
|
|
12
|
+
"Retrieve a specific key's full value from the shared environment data. " \
|
|
13
|
+
"Use list_env_data first to see what keys are available."
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def parameters
|
|
17
|
+
{
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
key: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "The key to retrieve"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
required: ["key"]
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def receive(message, context:)
|
|
30
|
+
key = message[:key] || message["key"]
|
|
31
|
+
return "Error: 'key' is required" unless key
|
|
32
|
+
|
|
33
|
+
root_thread_id = resolve_root_thread(context)
|
|
34
|
+
return "Error: Could not resolve thread scope (no active session)" unless root_thread_id
|
|
35
|
+
|
|
36
|
+
store = context.env.session_store
|
|
37
|
+
return "Error: Session store not available" unless store
|
|
38
|
+
|
|
39
|
+
entry = store.get_env_data(root_thread_id: root_thread_id, key: key)
|
|
40
|
+
return "Key '#{key}' not found in environment data." unless entry
|
|
41
|
+
|
|
42
|
+
context.bus.publish(
|
|
43
|
+
from: context.calling_po || "unknown",
|
|
44
|
+
to: "env_data",
|
|
45
|
+
message: { action: "get", key: key }
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
JSON.generate(entry[:value])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def resolve_root_thread(context)
|
|
54
|
+
store = context.env.session_store
|
|
55
|
+
return nil unless store
|
|
56
|
+
|
|
57
|
+
po = context.env.registry.get(context.calling_po)
|
|
58
|
+
return nil unless po&.respond_to?(:session_id) && po.session_id
|
|
59
|
+
|
|
60
|
+
store.resolve_root_thread(po.session_id)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to list all shared environment data keys and descriptions.
|
|
6
|
+
# Returns a lightweight manifest without loading full values.
|
|
7
|
+
class ListEnvData < Primitive
|
|
8
|
+
def name
|
|
9
|
+
"list_env_data"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def description
|
|
13
|
+
"List all keys and descriptions in the shared environment data for this delegation chain. " \
|
|
14
|
+
"Returns keys and short descriptions only (no values). " \
|
|
15
|
+
"Use get_env_data to retrieve a specific key's full value."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def parameters
|
|
19
|
+
{
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {},
|
|
22
|
+
required: []
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def receive(message, context:)
|
|
27
|
+
root_thread_id = resolve_root_thread(context)
|
|
28
|
+
return "Error: Could not resolve thread scope (no active session)" unless root_thread_id
|
|
29
|
+
|
|
30
|
+
store = context.env.session_store
|
|
31
|
+
return "Error: Session store not available" unless store
|
|
32
|
+
|
|
33
|
+
entries = store.list_env_data(root_thread_id: root_thread_id)
|
|
34
|
+
|
|
35
|
+
if entries.empty?
|
|
36
|
+
return "No environment data stored for this delegation chain."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context.bus.publish(
|
|
40
|
+
from: context.calling_po || "unknown",
|
|
41
|
+
to: "env_data",
|
|
42
|
+
message: { action: "list", count: entries.size }
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
JSON.generate(entries)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def resolve_root_thread(context)
|
|
51
|
+
store = context.env.session_store
|
|
52
|
+
return nil unless store
|
|
53
|
+
|
|
54
|
+
po = context.env.registry.get(context.calling_po)
|
|
55
|
+
return nil unless po&.respond_to?(:session_id) && po.session_id
|
|
56
|
+
|
|
57
|
+
store.resolve_root_thread(po.session_id)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to store shared data scoped to the current delegation chain.
|
|
6
|
+
# Any PO in the same delegation tree can read this data via get_env_data or list_env_data.
|
|
7
|
+
class StoreEnvData < Primitive
|
|
8
|
+
def name
|
|
9
|
+
"store_env_data"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def description
|
|
13
|
+
"Store a key-value pair in the shared environment data for this delegation chain. " \
|
|
14
|
+
"All POs in the same delegation tree can access this data. " \
|
|
15
|
+
"If the key already exists, it will be overwritten."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def parameters
|
|
19
|
+
{
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
key: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Namespaced identifier for the data (e.g. 'arc_task', 'findings')"
|
|
25
|
+
},
|
|
26
|
+
short_description: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "1-2 sentence summary of what this data contains (for discoverability via list_env_data)"
|
|
29
|
+
},
|
|
30
|
+
value: {
|
|
31
|
+
description: "The data to store (any JSON-serializable value: string, number, object, array)"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
required: %w[key short_description value]
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def receive(message, context:)
|
|
39
|
+
key = message[:key] || message["key"]
|
|
40
|
+
short_description = message[:short_description] || message["short_description"]
|
|
41
|
+
value = message[:value] || message["value"]
|
|
42
|
+
|
|
43
|
+
return "Error: 'key' is required" unless key
|
|
44
|
+
return "Error: 'short_description' is required" unless short_description
|
|
45
|
+
return "Error: 'value' is required" if value.nil?
|
|
46
|
+
|
|
47
|
+
root_thread_id = resolve_root_thread(context)
|
|
48
|
+
return "Error: Could not resolve thread scope (no active session)" unless root_thread_id
|
|
49
|
+
|
|
50
|
+
store = context.env.session_store
|
|
51
|
+
return "Error: Session store not available" unless store
|
|
52
|
+
|
|
53
|
+
stored_by = context.calling_po || "unknown"
|
|
54
|
+
|
|
55
|
+
store.store_env_data(
|
|
56
|
+
root_thread_id: root_thread_id,
|
|
57
|
+
key: key,
|
|
58
|
+
short_description: short_description,
|
|
59
|
+
value: value,
|
|
60
|
+
stored_by: stored_by
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
context.bus.publish(
|
|
64
|
+
from: stored_by,
|
|
65
|
+
to: "env_data",
|
|
66
|
+
message: { action: "store", key: key, short_description: short_description }
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
context.env.notify_env_data_changed(action: "store", root_thread_id: root_thread_id, key: key, stored_by: stored_by)
|
|
70
|
+
|
|
71
|
+
"Stored '#{key}' in environment data."
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def resolve_root_thread(context)
|
|
77
|
+
store = context.env.session_store
|
|
78
|
+
return nil unless store
|
|
79
|
+
|
|
80
|
+
po = context.env.registry.get(context.calling_po)
|
|
81
|
+
return nil unless po&.respond_to?(:session_id) && po.session_id
|
|
82
|
+
|
|
83
|
+
store.resolve_root_thread(po.session_id)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PromptObjects
|
|
4
|
+
module Universal
|
|
5
|
+
# Universal capability to update an existing shared environment data entry.
|
|
6
|
+
# Fails if the key doesn't exist (use store_env_data for create-or-replace).
|
|
7
|
+
class UpdateEnvData < Primitive
|
|
8
|
+
def name
|
|
9
|
+
"update_env_data"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def description
|
|
13
|
+
"Update an existing key's value and/or description in the shared environment data. " \
|
|
14
|
+
"Fails if the key doesn't exist — use store_env_data to create new entries."
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def parameters
|
|
18
|
+
{
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
key: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "The key to update (must already exist)"
|
|
24
|
+
},
|
|
25
|
+
short_description: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "New description (keeps existing if omitted)"
|
|
28
|
+
},
|
|
29
|
+
value: {
|
|
30
|
+
description: "New value (keeps existing if omitted)"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
required: ["key"]
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def receive(message, context:)
|
|
38
|
+
key = message[:key] || message["key"]
|
|
39
|
+
short_description = message[:short_description] || message["short_description"]
|
|
40
|
+
value = message[:value] || message["value"]
|
|
41
|
+
|
|
42
|
+
return "Error: 'key' is required" unless key
|
|
43
|
+
|
|
44
|
+
root_thread_id = resolve_root_thread(context)
|
|
45
|
+
return "Error: Could not resolve thread scope (no active session)" unless root_thread_id
|
|
46
|
+
|
|
47
|
+
store = context.env.session_store
|
|
48
|
+
return "Error: Session store not available" unless store
|
|
49
|
+
|
|
50
|
+
stored_by = context.calling_po || "unknown"
|
|
51
|
+
|
|
52
|
+
updated = store.update_env_data(
|
|
53
|
+
root_thread_id: root_thread_id,
|
|
54
|
+
key: key,
|
|
55
|
+
short_description: short_description,
|
|
56
|
+
value: value,
|
|
57
|
+
stored_by: stored_by
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
unless updated
|
|
61
|
+
return "Key '#{key}' not found in environment data. Use store_env_data to create it."
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context.bus.publish(
|
|
65
|
+
from: stored_by,
|
|
66
|
+
to: "env_data",
|
|
67
|
+
message: { action: "update", key: key }
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
context.env.notify_env_data_changed(action: "update", root_thread_id: root_thread_id, key: key, stored_by: stored_by)
|
|
71
|
+
|
|
72
|
+
"Updated '#{key}' in environment data."
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def resolve_root_thread(context)
|
|
78
|
+
store = context.env.session_store
|
|
79
|
+
return nil unless store
|
|
80
|
+
|
|
81
|
+
po = context.env.registry.get(context.calling_po)
|
|
82
|
+
return nil unless po&.respond_to?(:session_id) && po.session_id
|
|
83
|
+
|
|
84
|
+
store.resolve_root_thread(po.session_id)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
data/lib/prompt_objects.rb
CHANGED
|
@@ -11,7 +11,7 @@ module PromptObjects
|
|
|
11
11
|
class Error < StandardError; end
|
|
12
12
|
|
|
13
13
|
# Universal capabilities available to all prompt objects (don't need to be declared)
|
|
14
|
-
UNIVERSAL_CAPABILITIES = %w[ask_human think create_capability add_capability remove_capability list_capabilities list_primitives add_primitive create_primitive delete_primitive verify_primitive modify_primitive request_primitive modify_prompt].freeze
|
|
14
|
+
UNIVERSAL_CAPABILITIES = %w[ask_human think create_capability add_capability remove_capability list_capabilities list_primitives add_primitive create_primitive delete_primitive verify_primitive modify_primitive request_primitive modify_prompt store_env_data get_env_data list_env_data update_env_data delete_env_data].freeze
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
require_relative "prompt_objects/capability"
|
|
@@ -60,6 +60,11 @@ require_relative "prompt_objects/universal/verify_primitive"
|
|
|
60
60
|
require_relative "prompt_objects/universal/modify_primitive"
|
|
61
61
|
require_relative "prompt_objects/universal/request_primitive"
|
|
62
62
|
require_relative "prompt_objects/universal/modify_prompt"
|
|
63
|
+
require_relative "prompt_objects/universal/store_env_data"
|
|
64
|
+
require_relative "prompt_objects/universal/get_env_data"
|
|
65
|
+
require_relative "prompt_objects/universal/list_env_data"
|
|
66
|
+
require_relative "prompt_objects/universal/update_env_data"
|
|
67
|
+
require_relative "prompt_objects/universal/delete_env_data"
|
|
63
68
|
|
|
64
69
|
# Connectors (different interfaces to environments)
|
|
65
70
|
require_relative "prompt_objects/connectors/base"
|
data/prompt_objects.gemspec
CHANGED
|
@@ -19,6 +19,10 @@ You are an observation specialist for ARC-AGI grid puzzles. Your job is to look
|
|
|
19
19
|
|
|
20
20
|
When given grid pairs to analyze, you produce a structured observation report. You use your tools — don't try to analyze from descriptions alone. Render the grids, run grid_info, find the objects, diff the pairs.
|
|
21
21
|
|
|
22
|
+
### Check Shared Data First
|
|
23
|
+
|
|
24
|
+
When you're called by another PO (like the solver), start by calling `list_env_data` to see if task data, grids, or other context has been stored for you. If the solver has stored the loaded task data, you can retrieve it with `get_env_data` instead of relying only on what was included in the message. This is especially useful when you need to compare across multiple training pairs.
|
|
25
|
+
|
|
22
26
|
## Observation Framework
|
|
23
27
|
|
|
24
28
|
For each training pair, analyze and report on ALL of these dimensions:
|
|
@@ -26,10 +26,17 @@ Each ARC task gives you 2-5 training pairs (input grid → output grid) and 1-3
|
|
|
26
26
|
|
|
27
27
|
## Solving Process
|
|
28
28
|
|
|
29
|
-
### Step 1: Load and
|
|
29
|
+
### Step 1: Load and Store
|
|
30
30
|
|
|
31
31
|
Load the task with `load_arc_task`, then render every grid. Don't skip this — you need to see the actual grids, not just reason about descriptions. Use `grid_info` on each grid to get dimensions and color distributions.
|
|
32
32
|
|
|
33
|
+
After loading, use `store_env_data` to store key information so your delegates (observer, verifier) can access it directly:
|
|
34
|
+
- **`task_id`** — the task identifier
|
|
35
|
+
- **`task_data`** — the full loaded task (training pairs, test inputs, grids)
|
|
36
|
+
- **`task_summary`** — a brief description of the task (pair count, grid dimensions)
|
|
37
|
+
|
|
38
|
+
This way, when you delegate to the observer or verifier, they can call `list_env_data` and `get_env_data` to retrieve the grids directly instead of relying solely on what you pass in the message.
|
|
39
|
+
|
|
33
40
|
### Step 2: Observe (delegate to observer)
|
|
34
41
|
|
|
35
42
|
Send each training pair to the **observer** and ask it to analyze the transformation. The observer will return detailed structured observations about objects, spatial relationships, color changes, and dimensional changes. Read these carefully.
|
|
@@ -87,6 +94,8 @@ If verification fails:
|
|
|
87
94
|
- Revise your hypothesis to account for the discrepancy
|
|
88
95
|
- Test again
|
|
89
96
|
|
|
97
|
+
After each verification round, store your current hypothesis and its result with `store_env_data` (e.g., key `current_hypothesis`). This lets delegates see what's already been tried and what failed.
|
|
98
|
+
|
|
90
99
|
Iterate. Most tasks are solved within 2-4 hypothesis cycles.
|
|
91
100
|
|
|
92
101
|
### Step 6: Apply to Test Input
|
|
@@ -20,6 +20,10 @@ You are a rigorous verification specialist for ARC-AGI puzzle solving. When give
|
|
|
20
20
|
|
|
21
21
|
When the solver sends you a hypothesis to verify:
|
|
22
22
|
|
|
23
|
+
### 0. Check Shared Data
|
|
24
|
+
|
|
25
|
+
Start by calling `list_env_data` to see what context is available. The solver typically stores the loaded task data (`task_data`), task summary (`task_summary`), and current hypothesis (`current_hypothesis`). Use `get_env_data` to retrieve what you need — this gives you direct access to the grids and training pairs rather than relying solely on what the solver includes in its message.
|
|
26
|
+
|
|
23
27
|
### 1. Understand the Hypothesis
|
|
24
28
|
|
|
25
29
|
Restate the proposed rule in your own words to confirm understanding. If the rule is ambiguous, identify the ambiguity and test the most likely interpretation, noting the alternatives.
|
|
@@ -15,7 +15,7 @@ module PromptObjects
|
|
|
15
15
|
{
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
18
|
-
grid: { type: "array", description: "2D array of integers" },
|
|
18
|
+
grid: { type: "array", items: { type: "array", items: { type: "integer" } }, description: "2D array of integers" },
|
|
19
19
|
background: { type: "integer", description: "Background color to ignore (default: 0)" }
|
|
20
20
|
},
|
|
21
21
|
required: ["grid"]
|
|
@@ -15,8 +15,8 @@ module PromptObjects
|
|
|
15
15
|
{
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
18
|
-
grid_a: { type: "array", description: "First grid (2D array)" },
|
|
19
|
-
grid_b: { type: "array", description: "Second grid (2D array)" }
|
|
18
|
+
grid_a: { type: "array", items: { type: "array", items: { type: "integer" } }, description: "First grid (2D array)" },
|
|
19
|
+
grid_b: { type: "array", items: { type: "array", items: { type: "integer" } }, description: "Second grid (2D array)" }
|
|
20
20
|
},
|
|
21
21
|
required: ["grid_a", "grid_b"]
|
|
22
22
|
}
|
|
@@ -15,7 +15,7 @@ module PromptObjects
|
|
|
15
15
|
{
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
18
|
-
grid: { type: "array", description: "2D array of integers" }
|
|
18
|
+
grid: { type: "array", items: { type: "array", items: { type: "integer" } }, description: "2D array of integers" }
|
|
19
19
|
},
|
|
20
20
|
required: ["grid"]
|
|
21
21
|
}
|
|
@@ -15,7 +15,7 @@ module PromptObjects
|
|
|
15
15
|
{
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
18
|
-
grid: { type: "array", description: "2D array of integers" },
|
|
18
|
+
grid: { type: "array", items: { type: "array", items: { type: "integer" } }, description: "2D array of integers" },
|
|
19
19
|
operation: {
|
|
20
20
|
type: "string",
|
|
21
21
|
enum: %w[rotate_90 rotate_180 rotate_270 flip_h flip_v transpose],
|
|
@@ -21,14 +21,17 @@ module PromptObjects
|
|
|
21
21
|
},
|
|
22
22
|
grid: {
|
|
23
23
|
type: "array",
|
|
24
|
+
items: { type: "array", items: { type: "integer" } },
|
|
24
25
|
description: "A grid to compare directly against expected output (for quick checks)"
|
|
25
26
|
},
|
|
26
27
|
expected: {
|
|
27
28
|
type: "array",
|
|
29
|
+
items: { type: "array", items: { type: "integer" } },
|
|
28
30
|
description: "Expected output grid (used with 'grid' parameter)"
|
|
29
31
|
},
|
|
30
32
|
train: {
|
|
31
33
|
type: "array",
|
|
34
|
+
items: { type: "object" },
|
|
32
35
|
description: "Training pairs array (used with 'primitive_name'). Each element has 'input' and 'output' grids."
|
|
33
36
|
}
|
|
34
37
|
},
|
data/tools/thread-explorer.html
CHANGED
|
@@ -298,6 +298,7 @@ button { font-family:var(--mono); cursor:pointer; }
|
|
|
298
298
|
|
|
299
299
|
// --- State ---
|
|
300
300
|
let treeData = null;
|
|
301
|
+
let envData = []; // root-level env data entries
|
|
301
302
|
let events = []; // flattened event sequence
|
|
302
303
|
let actors = []; // ordered actor names
|
|
303
304
|
let poNames = new Set();
|
|
@@ -335,6 +336,7 @@ function loadFile(file) {
|
|
|
335
336
|
|
|
336
337
|
function loadData(data) {
|
|
337
338
|
treeData = data;
|
|
339
|
+
envData = data.env_data || [];
|
|
338
340
|
allNodes = {};
|
|
339
341
|
indexNodes(data);
|
|
340
342
|
poNames = extractPONames(data);
|
|
@@ -503,9 +505,11 @@ function renderHeader() {
|
|
|
503
505
|
const usage = sumUsageTree(treeData);
|
|
504
506
|
const nEvents = events.length;
|
|
505
507
|
const nSessions = Object.keys(allNodes).length;
|
|
508
|
+
const envCount = envData.length;
|
|
506
509
|
document.getElementById('h-stats').innerHTML =
|
|
507
510
|
`<span><span class="v">${nSessions}</span> sessions</span>`+
|
|
508
511
|
`<span><span class="v">${nEvents}</span> events</span>`+
|
|
512
|
+
(envCount > 0 ? `<span style="color:var(--amber)"><span class="v">${envCount}</span> env data</span>` : '')+
|
|
509
513
|
`<span><span class="v">${fmtNum(usage.input)}</span> in</span>`+
|
|
510
514
|
`<span><span class="v">${fmtNum(usage.output)}</span> out</span>`;
|
|
511
515
|
}
|
|
@@ -817,6 +821,29 @@ function renderDetail() {
|
|
|
817
821
|
html += `<div class="stats"><span><span class="v">${fmtNum(usage.input)}</span> in</span><span><span class="v">${fmtNum(usage.output)}</span> out</span></div>`;
|
|
818
822
|
html += `</div>`;
|
|
819
823
|
|
|
824
|
+
// Env Data section (only on root session when env_data exists)
|
|
825
|
+
if (type === 'root' && envData.length > 0) {
|
|
826
|
+
html += '<div style="padding:8px 16px 0">';
|
|
827
|
+
html += '<div style="font-size:10px;text-transform:uppercase;letter-spacing:0.5px;color:var(--amber);margin-bottom:6px;font-weight:600">Env Data</div>';
|
|
828
|
+
envData.forEach(entry => {
|
|
829
|
+
const eKey = esc(entry.key);
|
|
830
|
+
const eDesc = esc(entry.short_description||'');
|
|
831
|
+
const eBy = esc(entry.stored_by||'');
|
|
832
|
+
const eVal = typeof entry.value === 'string' ? esc(entry.value) : esc(JSON.stringify(entry.value,null,2));
|
|
833
|
+
html += `<div class="tc">`;
|
|
834
|
+
html += `<div class="tc-head" onclick="toggleTc(this)" style="border-left:2px solid var(--amber)">`;
|
|
835
|
+
html += `<span class="chv">▶</span>`;
|
|
836
|
+
html += `<span class="tc-name" style="color:var(--amber)">${eKey}</span>`;
|
|
837
|
+
html += `<span class="tc-label">${eDesc}</span>`;
|
|
838
|
+
html += `<span class="tc-label" style="margin-left:auto">by ${eBy}</span>`;
|
|
839
|
+
html += `</div>`;
|
|
840
|
+
html += `<div class="tc-body">`;
|
|
841
|
+
html += `<div class="tc-section"><div class="tc-section-label">Value</div><pre style="color:var(--amber)">${eVal}</pre></div>`;
|
|
842
|
+
html += `</div></div>`;
|
|
843
|
+
});
|
|
844
|
+
html += '</div>';
|
|
845
|
+
}
|
|
846
|
+
|
|
820
847
|
// Messages
|
|
821
848
|
html += '<div class="messages">';
|
|
822
849
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prompt_objects
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Werner
|
|
@@ -204,12 +204,9 @@ files:
|
|
|
204
204
|
- CHANGELOG.md
|
|
205
205
|
- CLAUDE.md
|
|
206
206
|
- Gemfile
|
|
207
|
-
- Gemfile.lock
|
|
208
|
-
- IMPLEMENTATION_PLAN.md
|
|
209
207
|
- LICENSE
|
|
210
208
|
- README.md
|
|
211
209
|
- Rakefile
|
|
212
|
-
- design-doc-v2.md
|
|
213
210
|
- exe/prompt_objects
|
|
214
211
|
- exe/prompt_objects_mcp
|
|
215
212
|
- frontend/.gitignore
|
|
@@ -231,22 +228,22 @@ files:
|
|
|
231
228
|
- frontend/src/canvas/nodes/PONode.ts
|
|
232
229
|
- frontend/src/canvas/nodes/ToolCallNode.ts
|
|
233
230
|
- frontend/src/canvas/types.ts
|
|
234
|
-
- frontend/src/components/CapabilitiesPanel.tsx
|
|
235
|
-
- frontend/src/components/ChatPanel.tsx
|
|
236
231
|
- frontend/src/components/ContextMenu.tsx
|
|
237
|
-
- frontend/src/components/
|
|
238
|
-
- frontend/src/components/
|
|
232
|
+
- frontend/src/components/EnvDataPane.tsx
|
|
233
|
+
- frontend/src/components/Inspector.tsx
|
|
239
234
|
- frontend/src/components/MarkdownMessage.tsx
|
|
240
|
-
- frontend/src/components/
|
|
235
|
+
- frontend/src/components/MethodList.tsx
|
|
241
236
|
- frontend/src/components/ModelSelector.tsx
|
|
242
237
|
- frontend/src/components/NotificationPanel.tsx
|
|
243
|
-
- frontend/src/components/
|
|
244
|
-
- frontend/src/components/
|
|
245
|
-
- frontend/src/components/
|
|
246
|
-
- frontend/src/components/
|
|
247
|
-
- frontend/src/components/
|
|
238
|
+
- frontend/src/components/ObjectList.tsx
|
|
239
|
+
- frontend/src/components/PaneSlot.tsx
|
|
240
|
+
- frontend/src/components/SourcePane.tsx
|
|
241
|
+
- frontend/src/components/SystemBar.tsx
|
|
242
|
+
- frontend/src/components/Transcript.tsx
|
|
248
243
|
- frontend/src/components/UsagePanel.tsx
|
|
244
|
+
- frontend/src/components/Workspace.tsx
|
|
249
245
|
- frontend/src/components/index.ts
|
|
246
|
+
- frontend/src/hooks/useResize.ts
|
|
250
247
|
- frontend/src/hooks/useWebSocket.ts
|
|
251
248
|
- frontend/src/index.css
|
|
252
249
|
- frontend/src/main.tsx
|
|
@@ -293,8 +290,8 @@ files:
|
|
|
293
290
|
- lib/prompt_objects/server/api/routes.rb
|
|
294
291
|
- lib/prompt_objects/server/app.rb
|
|
295
292
|
- lib/prompt_objects/server/file_watcher.rb
|
|
296
|
-
- lib/prompt_objects/server/public/assets/index-
|
|
297
|
-
- lib/prompt_objects/server/public/assets/index-
|
|
293
|
+
- lib/prompt_objects/server/public/assets/index-DEPawnfZ.js
|
|
294
|
+
- lib/prompt_objects/server/public/assets/index-oMrRce1m.css
|
|
298
295
|
- lib/prompt_objects/server/public/index.html
|
|
299
296
|
- lib/prompt_objects/server/websocket_handler.rb
|
|
300
297
|
- lib/prompt_objects/session/store.rb
|
|
@@ -303,14 +300,19 @@ files:
|
|
|
303
300
|
- lib/prompt_objects/universal/ask_human.rb
|
|
304
301
|
- lib/prompt_objects/universal/create_capability.rb
|
|
305
302
|
- lib/prompt_objects/universal/create_primitive.rb
|
|
303
|
+
- lib/prompt_objects/universal/delete_env_data.rb
|
|
306
304
|
- lib/prompt_objects/universal/delete_primitive.rb
|
|
305
|
+
- lib/prompt_objects/universal/get_env_data.rb
|
|
307
306
|
- lib/prompt_objects/universal/list_capabilities.rb
|
|
307
|
+
- lib/prompt_objects/universal/list_env_data.rb
|
|
308
308
|
- lib/prompt_objects/universal/list_primitives.rb
|
|
309
309
|
- lib/prompt_objects/universal/modify_primitive.rb
|
|
310
310
|
- lib/prompt_objects/universal/modify_prompt.rb
|
|
311
311
|
- lib/prompt_objects/universal/remove_capability.rb
|
|
312
312
|
- lib/prompt_objects/universal/request_primitive.rb
|
|
313
|
+
- lib/prompt_objects/universal/store_env_data.rb
|
|
313
314
|
- lib/prompt_objects/universal/think.rb
|
|
315
|
+
- lib/prompt_objects/universal/update_env_data.rb
|
|
314
316
|
- lib/prompt_objects/universal/verify_primitive.rb
|
|
315
317
|
- objects/coordinator.md
|
|
316
318
|
- objects/greeter.md
|