prompt_objects 0.5.0 → 0.7.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 +142 -0
- data/README.md +211 -19
- data/exe/poop +5 -0
- data/exe/prompt_objects +1 -1108
- data/exe/prompt_objects_mcp +5 -3
- data/lib/prompt_objects/capability.rb +33 -0
- data/lib/prompt_objects/cli/diagnostics_command.rb +69 -0
- data/lib/prompt_objects/cli/env_command.rb +435 -0
- data/lib/prompt_objects/cli/events_command.rb +145 -0
- data/lib/prompt_objects/cli/explore_command.rb +155 -0
- data/lib/prompt_objects/cli/helpers.rb +91 -0
- data/lib/prompt_objects/cli/message_command.rb +216 -0
- data/lib/prompt_objects/cli/repl_command.rb +366 -0
- data/lib/prompt_objects/cli/serve_command.rb +162 -0
- data/lib/prompt_objects/cli.rb +64 -422
- data/lib/prompt_objects/connectors/base.rb +16 -29
- data/lib/prompt_objects/connectors/mcp.rb +82 -98
- data/lib/prompt_objects/domain/records.rb +45 -0
- data/lib/prompt_objects/environment/exporter.rb +5 -4
- data/lib/prompt_objects/environment/git.rb +21 -1
- data/lib/prompt_objects/environment/importer.rb +5 -4
- data/lib/prompt_objects/environment/manager.rb +44 -6
- data/lib/prompt_objects/environment/manifest.rb +26 -4
- data/lib/prompt_objects/environment.rb +1350 -18
- data/lib/prompt_objects/execution/blocking_executor.rb +88 -0
- data/lib/prompt_objects/execution/context.rb +137 -0
- data/lib/prompt_objects/execution/contracts.rb +59 -0
- data/lib/prompt_objects/execution/permit_pool.rb +49 -0
- data/lib/prompt_objects/execution/policy.rb +47 -0
- data/lib/prompt_objects/execution/resource_lock_manager.rb +63 -0
- data/lib/prompt_objects/execution/runner.rb +498 -0
- data/lib/prompt_objects/execution/scheduler.rb +325 -0
- data/lib/prompt_objects/llm/factory.rb +4 -4
- data/lib/prompt_objects/llm/gemini_adapter.rb +25 -8
- data/lib/prompt_objects/llm/openai_adapter.rb +9 -1
- data/lib/prompt_objects/llm/pricing.rb +9 -2
- data/lib/prompt_objects/llm/response.rb +9 -4
- data/lib/prompt_objects/loader.rb +28 -1
- data/lib/prompt_objects/mcp/server.rb +6 -3
- data/lib/prompt_objects/mcp/tools/get_conversation.rb +15 -11
- data/lib/prompt_objects/mcp/tools/get_pending_requests.rb +2 -2
- data/lib/prompt_objects/mcp/tools/respond_to_request.rb +3 -3
- data/lib/prompt_objects/mcp/tools/send_message.rb +42 -32
- data/lib/prompt_objects/operations/diagnostics.rb +115 -0
- data/lib/prompt_objects/operations/retention.rb +75 -0
- data/lib/prompt_objects/operations/run_trace_builder.rb +152 -0
- data/lib/prompt_objects/primitives/http_get.rb +2 -0
- data/lib/prompt_objects/primitives/list_files.rb +2 -0
- data/lib/prompt_objects/primitives/read_file.rb +2 -0
- data/lib/prompt_objects/primitives/think.rb +36 -0
- data/lib/prompt_objects/primitives/write_file.rb +9 -0
- data/lib/prompt_objects/prompt_object.rb +190 -432
- data/lib/prompt_objects/repositories/artifact_repository.rb +109 -0
- data/lib/prompt_objects/repositories/base_repository.rb +37 -0
- data/lib/prompt_objects/repositories/definition_repository.rb +36 -0
- data/lib/prompt_objects/repositories/env_data_repository.rb +103 -0
- data/lib/prompt_objects/repositories/event_repository.rb +105 -0
- data/lib/prompt_objects/repositories/message_repository.rb +73 -0
- data/lib/prompt_objects/repositories/run_repository.rb +254 -0
- data/lib/prompt_objects/repositories/thread_repository.rb +87 -0
- data/lib/prompt_objects/repositories/tool_execution_repository.rb +88 -0
- data/lib/prompt_objects/repositories/workspace_session_repository.rb +61 -0
- data/lib/prompt_objects/server/api/routes.rb +561 -52
- data/lib/prompt_objects/server/app.rb +134 -1
- data/lib/prompt_objects/server/file_watcher.rb +9 -0
- data/lib/prompt_objects/server/public/assets/index-BjKlODDD.js +90 -0
- data/lib/prompt_objects/server/public/assets/index-w3fpIb5c.css +1 -0
- data/lib/prompt_objects/server/public/index.html +2 -2
- data/lib/prompt_objects/server/websocket_handler.rb +202 -207
- data/lib/prompt_objects/server.rb +170 -1
- data/lib/prompt_objects/service.rb +129 -0
- data/lib/prompt_objects/session/store.rb +774 -15
- data/lib/prompt_objects/universal/add_capability.rb +1 -1
- data/lib/prompt_objects/universal/create_capability.rb +4 -2
- data/lib/prompt_objects/universal/delete_env_data.rb +78 -0
- data/lib/prompt_objects/universal/delete_primitive.rb +1 -1
- data/lib/prompt_objects/universal/dispatch_po.rb +54 -0
- data/lib/prompt_objects/universal/get_env_data.rb +58 -0
- data/lib/prompt_objects/universal/get_run_status.rb +30 -0
- data/lib/prompt_objects/universal/join_runs.rb +35 -0
- data/lib/prompt_objects/universal/list_env_data.rb +57 -0
- data/lib/prompt_objects/universal/modify_primitive.rb +1 -1
- data/lib/prompt_objects/universal/render_artifact.rb +91 -0
- data/lib/prompt_objects/universal/request_primitive.rb +1 -1
- data/lib/prompt_objects/universal/set_env_data.rb +101 -0
- data/lib/prompt_objects/version.rb +5 -0
- data/lib/prompt_objects.rb +36 -6
- data/objects/coordinator.md +8 -4
- data/templates/arc-agi-1/objects/data_manager.md +2 -2
- data/templates/arc-agi-1/objects/observer.md +6 -2
- data/templates/arc-agi-1/objects/solver.md +14 -4
- data/templates/arc-agi-1/objects/verifier.md +6 -2
- data/templates/arc-agi-3/manifest.yml +19 -0
- data/templates/arc-agi-3/objects/analyst.md +79 -0
- data/templates/arc-agi-3/objects/player.md +76 -0
- data/templates/arc-agi-3/objects/strategist.md +97 -0
- data/templates/arc-agi-3/primitives/action_log.rb +133 -0
- data/templates/arc-agi-3/primitives/arc3_api.rb +223 -0
- data/templates/arc-agi-3/primitives/arc3_scorecard.rb +131 -0
- data/templates/arc-agi-3/primitives/frame_diff.rb +143 -0
- data/templates/arc-agi-3/primitives/frame_info.rb +96 -0
- data/templates/arc-agi-3/primitives/render_frame.rb +140 -0
- data/templates/basic/objects/basic.md +11 -3
- data/templates/chiptune/extras/sonic_pi_boot.rb +220 -0
- data/templates/chiptune/manifest.yml +20 -0
- data/templates/chiptune/objects/conductor.md +184 -0
- data/templates/chiptune/objects/sonic_pi.md +65 -0
- data/templates/chiptune/objects/voice_bass.md +44 -0
- data/templates/chiptune/objects/voice_lead.md +44 -0
- data/templates/chiptune/objects/voice_pad.md +43 -0
- data/templates/chiptune/objects/voice_perc.md +45 -0
- data/templates/chiptune/primitives/play_note.rb +59 -0
- data/templates/chiptune/primitives/play_sequence.rb +55 -0
- data/templates/chiptune/primitives/query_sonic_pi.rb +141 -0
- data/templates/chiptune/primitives/set_synth.rb +57 -0
- data/templates/chiptune/primitives/set_tempo.rb +45 -0
- data/templates/chiptune/primitives/stop_voice.rb +46 -0
- data/templates/chiptune/primitives/support/osc_bridge.rb +33 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/developer/objects/code_reviewer.md +1 -1
- data/templates/developer/objects/coordinator.md +16 -3
- data/templates/developer/objects/debugger.md +3 -3
- data/templates/empty/objects/assistant.md +10 -5
- data/templates/minimal/objects/assistant.md +10 -5
- data/templates/music/extras/sonic_pi_boot.rb +220 -0
- data/templates/music/manifest.yml +16 -0
- data/templates/music/objects/conductor.md +154 -0
- data/templates/music/objects/sonic_pi.md +65 -0
- data/templates/music/primitives/play_note.rb +55 -0
- data/templates/music/primitives/play_sequence.rb +51 -0
- data/templates/music/primitives/query_sonic_pi.rb +139 -0
- data/templates/music/primitives/set_synth.rb +53 -0
- data/templates/music/primitives/set_tempo.rb +43 -0
- data/templates/music/primitives/stop_voice.rb +44 -0
- data/templates/music/primitives/support/osc_bridge.rb +33 -0
- data/templates/music/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/music-beginner/README.md +100 -0
- data/templates/music-beginner/extras/README.md +27 -0
- data/templates/music-beginner/extras/sonic_pi_boot.rb +297 -0
- data/templates/music-beginner/manifest.yml +25 -0
- data/templates/music-beginner/objects/conductor.md +222 -0
- data/templates/music-beginner/objects/engine_setup.md +54 -0
- data/templates/music-beginner/objects/voice_bass.md +43 -0
- data/templates/music-beginner/objects/voice_keys.md +48 -0
- data/templates/music-beginner/objects/voice_pad.md +46 -0
- data/templates/music-beginner/objects/voice_percussion.md +45 -0
- data/templates/music-beginner/objects/voice_texture.md +37 -0
- data/templates/music-beginner/primitives/play_pattern.rb +118 -0
- data/templates/music-beginner/primitives/query_music_engine.rb +94 -0
- data/templates/music-beginner/primitives/set_instrument.rb +47 -0
- data/templates/music-beginner/primitives/set_tempo.rb +43 -0
- data/templates/music-beginner/primitives/set_voice_level.rb +46 -0
- data/templates/music-beginner/primitives/stop_voice.rb +37 -0
- data/templates/music-beginner/primitives/support/osc_bridge.rb +25 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/music-pro/extras/AUDITION.md +100 -0
- data/templates/music-pro/extras/sonic_pi_boot.rb +546 -0
- data/templates/music-pro/manifest.yml +19 -0
- data/templates/music-pro/objects/conductor.md +126 -0
- data/templates/music-pro/objects/sonic_pi.md +35 -0
- data/templates/music-pro/objects/voice_harmony.md +48 -0
- data/templates/music-pro/objects/voice_rhythm.md +43 -0
- data/templates/music-pro/objects/voice_texture.md +42 -0
- data/templates/music-pro/primitives/define_patch.rb +46 -0
- data/templates/music-pro/primitives/query_music_engine.rb +69 -0
- data/templates/music-pro/primitives/set_live_pattern.rb +70 -0
- data/templates/music-pro/primitives/set_tempo.rb +31 -0
- data/templates/music-pro/primitives/stop_voice.rb +31 -0
- data/templates/music-pro/primitives/support/music_protocol.rb +136 -0
- data/templates/music-pro/primitives/support/osc_bridge.rb +33 -0
- data/templates/music-pro/primitives/trigger_event.rb +44 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/writer/objects/coordinator.md +14 -3
- data/templates/writer/objects/editor.md +1 -1
- data/templates/writer/objects/researcher.md +2 -2
- data/tools/thread-explorer.html +28 -1
- metadata +175 -65
- data/CLAUDE.md +0 -176
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -233
- data/IMPLEMENTATION_PLAN.md +0 -1073
- data/Rakefile +0 -27
- data/design-doc-v2.md +0 -1232
- data/frontend/.gitignore +0 -3
- data/frontend/index.html +0 -17
- data/frontend/package-lock.json +0 -4540
- data/frontend/package.json +0 -36
- data/frontend/postcss.config.js +0 -6
- data/frontend/src/App.tsx +0 -103
- data/frontend/src/canvas/CanvasView.tsx +0 -113
- data/frontend/src/canvas/ForceLayout.ts +0 -115
- data/frontend/src/canvas/SceneManager.ts +0 -587
- data/frontend/src/canvas/canvasStore.ts +0 -47
- data/frontend/src/canvas/constants.ts +0 -95
- data/frontend/src/canvas/controls/CameraControls.ts +0 -98
- data/frontend/src/canvas/edges/MessageArc.ts +0 -149
- data/frontend/src/canvas/inspector/InspectorPanel.tsx +0 -31
- data/frontend/src/canvas/inspector/POInspector.tsx +0 -262
- data/frontend/src/canvas/inspector/ToolCallInspector.tsx +0 -67
- data/frontend/src/canvas/nodes/PONode.ts +0 -249
- data/frontend/src/canvas/nodes/ToolCallNode.ts +0 -116
- data/frontend/src/canvas/types.ts +0 -24
- data/frontend/src/components/ContextMenu.tsx +0 -68
- data/frontend/src/components/Inspector.tsx +0 -232
- data/frontend/src/components/MarkdownMessage.tsx +0 -155
- data/frontend/src/components/MethodList.tsx +0 -90
- data/frontend/src/components/ModelSelector.tsx +0 -115
- data/frontend/src/components/NotificationPanel.tsx +0 -130
- data/frontend/src/components/ObjectList.tsx +0 -78
- data/frontend/src/components/PaneSlot.tsx +0 -30
- data/frontend/src/components/SourcePane.tsx +0 -202
- data/frontend/src/components/SystemBar.tsx +0 -74
- data/frontend/src/components/Transcript.tsx +0 -76
- data/frontend/src/components/UsagePanel.tsx +0 -105
- data/frontend/src/components/Workspace.tsx +0 -260
- data/frontend/src/components/index.ts +0 -12
- data/frontend/src/hooks/useResize.ts +0 -55
- data/frontend/src/hooks/useWebSocket.ts +0 -517
- data/frontend/src/index.css +0 -103
- data/frontend/src/main.tsx +0 -10
- data/frontend/src/store/index.ts +0 -279
- data/frontend/src/types/index.ts +0 -165
- data/frontend/tailwind.config.js +0 -44
- data/frontend/tsconfig.json +0 -30
- data/frontend/vite.config.ts +0 -29
- data/lib/prompt_objects/server/public/assets/index-D1myxE0l.js +0 -4345
- data/lib/prompt_objects/server/public/assets/index-DdCcwC-Z.css +0 -1
- data/lib/prompt_objects/universal/add_primitive.rb +0 -118
- data/lib/prompt_objects/universal/ask_human.rb +0 -109
- data/lib/prompt_objects/universal/create_primitive.rb +0 -174
- data/lib/prompt_objects/universal/list_primitives.rb +0 -145
- data/lib/prompt_objects/universal/think.rb +0 -41
- data/prompt_objects.gemspec +0 -50
- data/templates/basic/.gitignore +0 -2
- data/templates/developer/.gitignore +0 -5
- data/templates/empty/.gitignore +0 -5
- data/templates/empty/objects/.gitkeep +0 -0
- data/templates/minimal/.gitignore +0 -5
- data/templates/writer/.gitignore +0 -5
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require File.join(File.dirname( __FILE__ ), 'network_packet')
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
|
|
4
|
+
module OSC
|
|
5
|
+
class UnknownType < StandardError; end
|
|
6
|
+
|
|
7
|
+
class OSCPacket
|
|
8
|
+
def self.messages_from_network(string, ip_info=nil)
|
|
9
|
+
messages = []
|
|
10
|
+
osc = new(string)
|
|
11
|
+
|
|
12
|
+
if osc.bundle?
|
|
13
|
+
osc.get_string
|
|
14
|
+
time = osc.get_timestamp
|
|
15
|
+
|
|
16
|
+
osc.get_bundle_messages.each do |message|
|
|
17
|
+
msg = decode_simple_message(time, OSCPacket.new(message))
|
|
18
|
+
if ip_info
|
|
19
|
+
# Append info for the ip address
|
|
20
|
+
msg.ip_port = ip_info.shift
|
|
21
|
+
msg.ip_address = ip_info.join(".")
|
|
22
|
+
end
|
|
23
|
+
messages << msg
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
else
|
|
27
|
+
msg = decode_simple_message(time, osc)
|
|
28
|
+
if ip_info
|
|
29
|
+
# Append info for the ip address
|
|
30
|
+
msg.ip_port = ip_info.shift
|
|
31
|
+
msg.ip_address = ip_info.join(".")
|
|
32
|
+
end
|
|
33
|
+
messages << msg
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return messages
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.decode_simple_message(time, osc_packet)
|
|
40
|
+
address = osc_packet.get_string
|
|
41
|
+
args = osc_packet.get_arguments
|
|
42
|
+
|
|
43
|
+
Message.new_with_time(address, time, nil, *args)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize(string)
|
|
47
|
+
@packet = NetworkPacket.new(string)
|
|
48
|
+
|
|
49
|
+
@types = {
|
|
50
|
+
"i" => lambda{OSCInt32.new(get_int32)},
|
|
51
|
+
"f" => lambda{ OSCFloat32.new(get_float32)},
|
|
52
|
+
"d" => lambda{ OSCDouble64.new(get_double64)},
|
|
53
|
+
"s" => lambda{ OSCString.new(get_string)},
|
|
54
|
+
"b" => lambda{ OSCBlob.new(get_blob)}
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def get_bundle_messages
|
|
59
|
+
bundle_messages = []
|
|
60
|
+
|
|
61
|
+
until @packet.eof?
|
|
62
|
+
l = @packet.getn(4).unpack('N')[0]
|
|
63
|
+
bundle_messages << @packet.getn(l)
|
|
64
|
+
end
|
|
65
|
+
bundle_messages
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def get_string
|
|
69
|
+
result = ''
|
|
70
|
+
until ((c = @packet.getc) == string_delemeter)
|
|
71
|
+
result << c
|
|
72
|
+
end
|
|
73
|
+
@packet.skip_padding
|
|
74
|
+
result
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_timestamp
|
|
78
|
+
#TODO: refactor this so a mortal can figure it out
|
|
79
|
+
t1 = @packet.getn(4).unpack('N')[0]
|
|
80
|
+
t2 = @packet.getn(4).unpack('N')[0]
|
|
81
|
+
@packet.skip_padding
|
|
82
|
+
|
|
83
|
+
if t1 == 0 && t2 == 1
|
|
84
|
+
time = nil
|
|
85
|
+
else
|
|
86
|
+
time = t1 + t2.to_f / (2**32)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
time
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def get_arguments
|
|
93
|
+
if (@packet.getc == ?,)
|
|
94
|
+
tags = get_string
|
|
95
|
+
args = []
|
|
96
|
+
|
|
97
|
+
tags.scan(/./) do |tag|
|
|
98
|
+
type_handler = @types[tag]
|
|
99
|
+
raise(UnknownType, "Unknown OSC type: #{tag}") unless type_handler
|
|
100
|
+
args << type_handler.call
|
|
101
|
+
end
|
|
102
|
+
args
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_int32
|
|
107
|
+
i = @packet.getn(4).unpack('N')[0]
|
|
108
|
+
i -= 2**32 if i > (2**31-1)
|
|
109
|
+
@packet.skip_padding
|
|
110
|
+
i
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def get_float32
|
|
114
|
+
f = @packet.getn(4).unpack('g')[0]
|
|
115
|
+
@packet.skip_padding
|
|
116
|
+
f
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def get_double64
|
|
120
|
+
f = @packet.getn(8).unpack('G')[0]
|
|
121
|
+
@packet.skip_padding
|
|
122
|
+
f
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def get_blob
|
|
126
|
+
l = @packet.getn(4).unpack('N')[0]
|
|
127
|
+
b = @packet.getn(l)
|
|
128
|
+
@packet.skip_padding
|
|
129
|
+
b
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def bundle?
|
|
133
|
+
!(@packet.to_s =~ /\A\#bundle/).nil?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def string_delemeter
|
|
137
|
+
"\x00"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), "osc_argument")
|
|
2
|
+
|
|
3
|
+
module OSC
|
|
4
|
+
class OSCInt32 < OSCArgument
|
|
5
|
+
def tag
|
|
6
|
+
'i'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def encode
|
|
10
|
+
[@val].pack('N').force_encoding("BINARY")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class OSCFloat32 < OSCArgument
|
|
15
|
+
def tag
|
|
16
|
+
'f'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def encode
|
|
20
|
+
[@val].pack('g').force_encoding("BINARY")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class OSCDouble64 < OSCArgument
|
|
25
|
+
def tag
|
|
26
|
+
'd'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def encode
|
|
30
|
+
[@val].pack('G').force_encoding("BINARY")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class OSCString < OSCArgument
|
|
35
|
+
def tag
|
|
36
|
+
's'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def encode
|
|
40
|
+
padding(@val.sub(/\000.*\z/, '') + "\000").force_encoding("BINARY")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class OSCBlob < OSCArgument
|
|
45
|
+
def tag
|
|
46
|
+
'b'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def encode
|
|
50
|
+
padding([@val.size].pack('N') + @val).force_encoding("BINARY")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class Server
|
|
3
|
+
def initialize(port)
|
|
4
|
+
@socket = UDPSocket.new
|
|
5
|
+
@socket.bind('', port)
|
|
6
|
+
@matchers = []
|
|
7
|
+
@queue = Queue.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run
|
|
11
|
+
start_dispatcher
|
|
12
|
+
|
|
13
|
+
start_detector
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def stop
|
|
17
|
+
@socket.close
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_method(address_pattern, &proc)
|
|
21
|
+
matcher = AddressPattern.new(address_pattern)
|
|
22
|
+
|
|
23
|
+
@matchers << [matcher, proc]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def start_detector
|
|
29
|
+
begin
|
|
30
|
+
detector
|
|
31
|
+
rescue
|
|
32
|
+
Thread.main.raise($!)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def start_dispatcher
|
|
37
|
+
Thread.fork do
|
|
38
|
+
begin
|
|
39
|
+
dispatcher
|
|
40
|
+
rescue
|
|
41
|
+
Thread.main.raise($!)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def dispatcher
|
|
47
|
+
loop do
|
|
48
|
+
mesg = @queue.pop
|
|
49
|
+
dispatch_message(mesg)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def dispatch_message(message)
|
|
54
|
+
diff = (message.time || 0) - Time.now.to_ntp
|
|
55
|
+
|
|
56
|
+
if diff <= 0
|
|
57
|
+
sendmesg(message)
|
|
58
|
+
else # spawn a thread to wait until it's time
|
|
59
|
+
Thread.fork do
|
|
60
|
+
sleep(diff)
|
|
61
|
+
sendmesg(message)
|
|
62
|
+
Thread.exit
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def sendmesg(mesg)
|
|
68
|
+
@matchers.each do |matcher, proc|
|
|
69
|
+
if matcher.match?(mesg.address)
|
|
70
|
+
proc.call(mesg)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def detector
|
|
76
|
+
loop do
|
|
77
|
+
osc_data, network = @socket.recvfrom(16384)
|
|
78
|
+
begin
|
|
79
|
+
ip_info = Array.new
|
|
80
|
+
ip_info << network[1]
|
|
81
|
+
ip_info.concat(network[2].split('.'))
|
|
82
|
+
OSCPacket.messages_from_network( osc_data, ip_info ).each do |message|
|
|
83
|
+
@queue.push(message)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
rescue(EOFError)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'thread'
|
|
3
|
+
|
|
4
|
+
# core extensions
|
|
5
|
+
require 'osc-ruby/core_ext/time'
|
|
6
|
+
|
|
7
|
+
# jus the basics
|
|
8
|
+
require 'osc-ruby/osc_types'
|
|
9
|
+
require 'osc-ruby/osc_packet'
|
|
10
|
+
|
|
11
|
+
require 'osc-ruby/message'
|
|
12
|
+
require 'osc-ruby/bundle'
|
|
13
|
+
require 'osc-ruby/address_pattern'
|
|
14
|
+
|
|
15
|
+
# now we gettin fancy
|
|
16
|
+
require 'osc-ruby/server'
|
|
17
|
+
require 'osc-ruby/client'
|
|
18
|
+
require 'osc-ruby/broadcast_client'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Music Beginner
|
|
2
|
+
|
|
3
|
+
`music-beginner` is a constrained-but-generative Sonic Pi ensemble. Five Prompt
|
|
4
|
+
Objects own distinct musical roles, communicate through a shared composition
|
|
5
|
+
contract, and keep rewriting their own looping patterns. The constraints are a
|
|
6
|
+
musical guardrail, not a prerecorded arrangement: agents still choose the
|
|
7
|
+
notes, chords, rests, rhythms, instrumentation, and evolution.
|
|
8
|
+
|
|
9
|
+
New environments default to Gemini 3.5 Flash for a responsive balance of tool
|
|
10
|
+
use and musical direction. The selected provider and model are stored in the
|
|
11
|
+
environment manifest, so the choice survives a server restart. Set
|
|
12
|
+
`GEMINI_API_KEY` before serving the environment.
|
|
13
|
+
|
|
14
|
+
## Start it
|
|
15
|
+
|
|
16
|
+
1. Create a new environment from this template and start Prompt Objects.
|
|
17
|
+
2. Open Sonic Pi.
|
|
18
|
+
3. In an empty Sonic Pi buffer, run one line, replacing the path with the new
|
|
19
|
+
environment's absolute path:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
run_file "/Users/you/.prompt_objects/environments/my-music/extras/sonic_pi_boot.rb"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
4. Send the conductor: `Hit it.` The conductor treats that as a complete cue to
|
|
26
|
+
check Sonic Pi and launch the template's talk-safe backing-track contract.
|
|
27
|
+
5. Start with your computer volume low and bring it up gradually.
|
|
28
|
+
|
|
29
|
+
Once it is playing, the conductor also understands `change it up`, `bring it
|
|
30
|
+
down`, and `stop`/`cut`. These are performance cues rather than fixed songs:
|
|
31
|
+
the voices still compose and perform their own material within the template's
|
|
32
|
+
musical guardrails.
|
|
33
|
+
|
|
34
|
+
The autonomous timer stays dormant until the conductor receives a new human
|
|
35
|
+
message after the server starts. It then waits 45 seconds before its first
|
|
36
|
+
evolution turn, so your initialization prompt always establishes the piece.
|
|
37
|
+
Later timer turns use the short evolution instruction configured in the
|
|
38
|
+
conductor's frontmatter; they do not reuse your original prompt.
|
|
39
|
+
|
|
40
|
+
The conductor verifies every activation against live engine state. “Connected”
|
|
41
|
+
only means the boot engine is reachable; a connected engine with zero active
|
|
42
|
+
voices is silent. Musicians are instructed to perform their playback tool calls
|
|
43
|
+
in the same turn instead of stopping at a prose proposal.
|
|
44
|
+
|
|
45
|
+
The engine listens for OSC on Sonic Pi's standard port `4560`. The Prompt
|
|
46
|
+
Objects query state on port `4561`. Set `SONIC_PI_HOST` or `SONIC_PI_PORT` before
|
|
47
|
+
starting Prompt Objects if you need different OSC settings.
|
|
48
|
+
|
|
49
|
+
The supplied patch set requires Sonic Pi 4.0 or newer (`:bass_foundation` was
|
|
50
|
+
introduced in 4.0). It is developed against Sonic Pi 4.6.0. The Ruby tests can
|
|
51
|
+
verify the protocol and template wiring without audio, but the final balance is
|
|
52
|
+
speaker-, room-, and voice-dependent, so audition it in Sonic Pi before a live
|
|
53
|
+
performance.
|
|
54
|
+
|
|
55
|
+
## Pattern notation
|
|
56
|
+
|
|
57
|
+
A voice sends semicolon-separated events:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
C3+E3+G3@4@0.7@4.5;R@1;F3+A3+C4@3@0.6@3.2
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Each event is `sound@step_beats@amplitude@gate_beats`. Amplitude and gate are
|
|
64
|
+
optional. `step_beats` controls when the next event begins; `gate_beats`
|
|
65
|
+
controls how long sustained presets such as pads, bass, and tonal textures ring,
|
|
66
|
+
so pads may overlap slightly while a keys phrase stays articulated. Amplitude
|
|
67
|
+
is clamped to `0.0..1.0`. Sounds are:
|
|
68
|
+
|
|
69
|
+
- a note: `C4`, `Fs3`, `Eb5`, or MIDI `60`
|
|
70
|
+
- a chord joined with `+`: `C3+E3+G3`
|
|
71
|
+
- a rest: `R`
|
|
72
|
+
- with `gentle_kit`, a real sample token: `kick`, `hat`, `snare`, or `tick`
|
|
73
|
+
|
|
74
|
+
Patterns may contain up to 32 events and 64 beats. The engine pads their length
|
|
75
|
+
to the next whole bar and applies replacements at a synchronized pattern/bar
|
|
76
|
+
boundary, so an agent changing a loop does not knock the ensemble out of time.
|
|
77
|
+
|
|
78
|
+
## The safe palette
|
|
79
|
+
|
|
80
|
+
- `soft_keys` — rounded electric piano
|
|
81
|
+
- `air_pad` — slow, filtered pad
|
|
82
|
+
- `warm_bass` — centered low foundation
|
|
83
|
+
- `felt_pluck` — quiet kalimba-like accents
|
|
84
|
+
- `glass_bell` — very sparse bell color
|
|
85
|
+
- `sine_glow` — nearly pure tonal texture
|
|
86
|
+
- `gentle_kit` — real kick, closed-hat, snare, and tick samples
|
|
87
|
+
|
|
88
|
+
Preset gains, envelopes, filtering, and effects are deliberately conservative.
|
|
89
|
+
Agents can change voice level and per-event amplitude, but the engine applies a
|
|
90
|
+
second hard level clamp. `stop_voice(voice: "all")` is the emergency silence.
|
|
91
|
+
|
|
92
|
+
## A useful first audition
|
|
93
|
+
|
|
94
|
+
Tell the conductor `Hit it.` Its default is `96 BPM, C major pentatonic, Cmaj7 /
|
|
95
|
+
Am7 / Fmaj7 / G6, one chord per bar, flowing-light density`. Bring voices in one
|
|
96
|
+
at a time: connected pad, phrase-based keys, bass, quiet percussion, then
|
|
97
|
+
optional texture. For background use, lower levels rather than asking every
|
|
98
|
+
voice to add more rests. Let it evolve for several minutes; autonomous changes
|
|
99
|
+
develop recognizable new movements by coordinating a few voices around one
|
|
100
|
+
intention while keeping an unchanged voice as a continuity anchor.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Start the Music Beginner engine
|
|
2
|
+
|
|
3
|
+
Open Sonic Pi and run this one line from an empty buffer, replacing the path
|
|
4
|
+
with this environment's absolute path:
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
run_file "/Users/you/.prompt_objects/environments/my-music/extras/sonic_pi_boot.rb"
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Then tell the conductor `Hit it.` It will check the connection and begin a
|
|
11
|
+
quiet talk-safe composition using the template's default musical contract.
|
|
12
|
+
Start with your computer volume low. For immediate silence, tell the conductor
|
|
13
|
+
to stop all voices or press Sonic Pi's Stop button.
|
|
14
|
+
|
|
15
|
+
The default contract uses connected one-bar chord changes and a quiet rhythmic
|
|
16
|
+
spine. If the result sounds like isolated notes separated by long gaps, query
|
|
17
|
+
the live engine: the pad should report `air_pad`, and keys or percussion should
|
|
18
|
+
remain rhythmically active.
|
|
19
|
+
|
|
20
|
+
`connected: true` confirms only that the engine is reachable. The conductor
|
|
21
|
+
must make each musician perform its playback tools and verify that the engine
|
|
22
|
+
reports an active voice; an engine with zero active voices is silent.
|
|
23
|
+
|
|
24
|
+
Pattern notation and audition suggestions are documented in the source
|
|
25
|
+
template's `README.md`. You can also ask the `engine_setup` Prompt Object for
|
|
26
|
+
connection, setup, and notation help. It is intentionally read-only and cannot
|
|
27
|
+
change the music.
|