little_ghost 0.7.0 → 0.9.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/README.md +34 -6
- data/docs/guides/assemblies.md +21 -9
- data/docs/guides/code_mode.md +2 -2
- data/docs/guides/getting_started.md +27 -2
- data/docs/guides/integrations.md +20 -161
- data/docs/guides/mcp.md +288 -0
- data/docs/guides/models_and_providers.md +21 -54
- data/docs/guides/production.md +14 -5
- data/docs/guides/prompt_views.md +234 -27
- data/docs/guides/providers.md +275 -0
- data/docs/guides/sandboxing.md +42 -7
- data/docs/guides/skills.md +1 -3
- data/docs/guides/tools.md +2 -0
- data/exe/little_ghost +12 -0
- data/lib/little_ghost/agent/context_management.rb +2 -13
- data/lib/little_ghost/agent/delegation.rb +7 -4
- data/lib/little_ghost/agent/skills.rb +8 -6
- data/lib/little_ghost/agent/tool_loop.rb +4 -4
- data/lib/little_ghost/agent.rb +230 -70
- data/lib/little_ghost/agent_builder.rb +16 -4
- data/lib/little_ghost/artifacts/workspace_store.rb +16 -14
- data/lib/little_ghost/assembly.rb +48 -7
- data/lib/little_ghost/assembly_builder.rb +3 -3
- data/lib/little_ghost/cli.rb +429 -0
- data/lib/little_ghost/code_mode/broker.rb +11 -3
- data/lib/little_ghost/code_mode/javascript/client.rb +58 -11
- data/lib/little_ghost/code_mode/javascript/host.rb +37 -13
- data/lib/little_ghost/code_mode/javascript/session.rb +21 -9
- data/lib/little_ghost/code_mode/javascript_engine.rb +21 -42
- data/lib/little_ghost/code_mode/ruby/host.rb +8 -4
- data/lib/little_ghost/code_mode/ruby/session.rb +41 -14
- data/lib/little_ghost/code_mode/ruby_engine.rb +6 -36
- data/lib/little_ghost/code_mode/runtime.rb +57 -24
- data/lib/little_ghost/console.rb +17 -0
- data/lib/little_ghost/errors.rb +20 -2
- data/lib/little_ghost/framework_prompts.rb +376 -0
- data/lib/little_ghost/generators/application_generator.rb +179 -0
- data/lib/little_ghost/generators/templates/application/Gemfile.tt +3 -0
- data/lib/little_ghost/generators/templates/application/README.md.tt +29 -0
- data/lib/little_ghost/generators/templates/application/app/agents/application_agent.rb.tt +5 -0
- data/lib/little_ghost/generators/templates/application/app/prompts/application/system_prompt.erb.tt +1 -0
- data/lib/little_ghost/generators/templates/application/bin/application.tt +10 -0
- data/lib/little_ghost/generators/templates/application/config/little_ghost.rb.tt +5 -0
- data/lib/little_ghost/generators/templates/application/gitignore.tt +2 -0
- data/lib/little_ghost/generators/templates/application/keep.tt +0 -0
- data/lib/little_ghost/graph.rb +24 -5
- data/lib/little_ghost/mcp/client.rb +307 -610
- data/lib/little_ghost/mcp/toolset.rb +133 -95
- data/lib/little_ghost/mcp.rb +21 -3
- data/lib/little_ghost/model_operations.rb +103 -36
- data/lib/little_ghost/model_resolver.rb +2 -0
- data/lib/little_ghost/models/catalog/models_dev_source.rb +4 -1
- data/lib/little_ghost/prompt_resolver.rb +61 -27
- data/lib/little_ghost/prompts/little_ghost/agent/interjections/instructions.erb +12 -0
- data/lib/little_ghost/prompts/little_ghost/agent/system/default.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/batch/feedback/batch_too_large.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/batch/feedback/batch_too_many.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/batch/feedback/item_too_large.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/errors/preparation_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/errors/resolver_invalid.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/errors/value_unstorable.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/presentation/format/reference.erb +13 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/presentation/format/references.erb +12 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/presentation/format/workspace_references.erb +12 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/presentation/notices/full_result.erb +14 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/presentation/notices/storage_failed.erb +13 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/errors/destination_unsafe.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/errors/secure_unavailable.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/errors/workspace_changed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/errors/workspace_unavailable.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/errors/workspace_unsafe.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/feedback/count_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/feedback/destination_exists.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/feedback/too_large.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/artifacts/storage/feedback/total_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/assembly/feedback/transition_only.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/assembly/tools/fallback/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/artifacts/format/references.erb +12 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/errors/brokered_close.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/errors/cleanup_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/errors/execution_failed.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/arguments_object.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/closed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/control_active.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/limit_exceeded.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/not_active.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/program_active.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/program_timed_out.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/unavailable_tool.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/feedback/unknown_program.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/active_programs_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/cleanup_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/execution_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/invalid_request.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/memory_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/pending_calls_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/source_size_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/errors/tools_array.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/javascript/instructions.erb +35 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/ruby/feedback/parallel_callables.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/ruby/instructions.erb +40 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/tools/exec/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/tools/stop/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/tools/stop/inputs/max_output_tokens/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/tools/wait/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/code_mode/tools/wait/inputs/max_output_tokens/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/context_management/summary/request.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/context_management/summary/system_instruction.erb +16 -0
- data/lib/little_ghost/prompts/little_ghost/graph/context/format/failed_input.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/graph/context/format/previous_input.erb +13 -0
- data/lib/little_ghost/prompts/little_ghost/graph/context/headings/original_task.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/graph/context/headings/previous_inputs.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/mcp/errors/request_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/mcp/errors/transformation_unserializable.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/mcp/tools/fallback/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/output/truncation/marker.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/errors/mount_changed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/errors/secure_traversal_unavailable.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/errors/workspace_root_changed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/directory_listing_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/entry_required.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/file_read_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/invalid_utf8.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/mount_escape.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/mount_missing.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/multiply_linked.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/not_directory.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/not_file.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/null_byte.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/outside_scope.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/parent_escape.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/path_missing.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/path_traverses_symlink.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/read_only.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/replace_empty.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/symlink_path.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/text_multiple.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/text_not_found.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/write_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/write_parent_missing.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/filesystem/feedback/write_target_symlink.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/policy/feedback/feature_denied.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/errors/program_supervisor_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/feedback/command_timed_out.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/feedback/executable_required.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/feedback/program_memory_exceeded.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/feedback/program_output_exceeded.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/sandbox/process/feedback/program_timed_out.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/skills/discovery/instructions.erb +18 -0
- data/lib/little_ghost/prompts/little_ghost/skills/feedback/unknown.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/skills/resources/notices/truncated.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/skills/tools/activate/content.erb +28 -0
- data/lib/little_ghost/prompts/little_ghost/skills/tools/activate/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/skills/tools/activate/inputs/name/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/persistence/format/redaction.erb +12 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/repair/feedback/invalid_result.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/repair/feedback/schema_errors.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/repair/request.erb +14 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/tools/result/description.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/invalid_json.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/missing_tool.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/multiple_tools.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/too_complex.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/too_deep.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/too_large.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/structured_output/validation/feedback/tool_not_exclusive.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/errors/create_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/errors/previous_turn_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/errors/restore_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/errors/turn_failed.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/duplicate_ids.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/duplicate_path.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/identity_capacity.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/inactive.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/interjection_chars_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/interjection_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/interjection_unsupported.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/invalid_cursor.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/invalid_mode.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/list_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/message_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/message_type.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/not_running.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/queue_capacity.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/task_name_invalid.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/task_name_limit.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/terminal_identity.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/turn_capacity.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/unknown_id.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/feedback/unknown_kind.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/notices/turn_cancelled.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/interject/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/interject/inputs/active_id/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/interject/inputs/message/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/list/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/send/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/send/inputs/id/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/send/inputs/message/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/send/inputs/send_mode/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/spawn/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/spawn/inputs/kind/description.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/spawn/inputs/spawn_mode/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/spawn/inputs/task/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/spawn/inputs/task_name/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/wait/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/subagents/tools/wait/inputs/ids/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/swarm/handoff/notice.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/swarm/handoff/request.erb +16 -0
- data/lib/little_ghost/prompts/little_ghost/swarm/tools/handoff/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/list_files/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/read_file/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/replace_in_file/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/shell/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/write_file/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/write_todos/description.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/write_todos/feedback/single_progress.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/built_in/write_todos/feedback/unique_ids.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/errors/unexpected_failure.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/errors/unserializable_result.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/feedback/invalid_input.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/feedback/unknown.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/loop/notices/final_warning.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/loop/notices/termination.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/loop/notices/warning.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/additional_property.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/enum.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/invalid_format.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/invalid_pattern.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/max_items.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/max_length.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/maximum.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/min_items.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/min_length.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/minimum.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/required.erb +10 -0
- data/lib/little_ghost/prompts/little_ghost/tools/validation/schema/type.erb +11 -0
- data/lib/little_ghost/prompts/little_ghost/workspace/feedback/path_changed.erb +10 -0
- data/lib/little_ghost/provider_registry.rb +1 -0
- data/lib/little_ghost/providers/lm_studio/catalog_source.rb +201 -0
- data/lib/little_ghost/providers/lm_studio.rb +52 -0
- data/lib/little_ghost/providers/openai.rb +3 -75
- data/lib/little_ghost/providers/openai_compatible.rb +78 -1
- data/lib/little_ghost/runtime/hooks/artifacts.rb +58 -22
- data/lib/little_ghost/runtime.rb +8 -3
- data/lib/little_ghost/sandbox/environment_policy.rb +29 -4
- data/lib/little_ghost/sandbox/filesystem.rb +51 -33
- data/lib/little_ghost/sandbox/policy.rb +28 -6
- data/lib/little_ghost/sandbox/process_runner.rb +6 -2
- data/lib/little_ghost/sandbox/process_session.rb +8 -4
- data/lib/little_ghost/sandbox/scope.rb +4 -1
- data/lib/little_ghost/sandboxes/seatbelt.rb +3 -1
- data/lib/little_ghost/sandboxes/unrestricted.rb +17 -9
- data/lib/little_ghost/skills/catalog.rb +41 -36
- data/lib/little_ghost/structured_output.rb +6 -6
- data/lib/little_ghost/subagents/control_tool.rb +58 -0
- data/lib/little_ghost/subagents/manager.rb +99 -74
- data/lib/little_ghost/support/output_truncation.rb +28 -4
- data/lib/little_ghost/swarm.rb +20 -7
- data/lib/little_ghost/tool.rb +47 -20
- data/lib/little_ghost/tool_registry.rb +2 -2
- data/lib/little_ghost/tools/filesystem.rb +12 -4
- data/lib/little_ghost/tools/shell.rb +5 -1
- data/lib/little_ghost/tools/write_todos.rb +9 -9
- data/lib/little_ghost/version.rb +1 -1
- data/lib/little_ghost/workflow.rb +199 -27
- data/lib/little_ghost/workspace.rb +2 -2
- data/lib/little_ghost.rb +6 -2
- metadata +222 -7
- data/lib/little_ghost/mcp/types.rb +0 -216
data/docs/guides/mcp.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Connect agents to MCP servers
|
|
2
|
+
|
|
3
|
+
Give an Agent access to operations published by a Model Context Protocol (MCP)
|
|
4
|
+
server without changing how your application calls the Agent.
|
|
5
|
+
`LittleGhost::MCP::Toolset` turns operations discovered by the official MCP Ruby
|
|
6
|
+
client into LittleGhost Tool classes, which join the same `tools` declaration as
|
|
7
|
+
local application Tools.
|
|
8
|
+
|
|
9
|
+
MCP support is opt-in. Requiring `little_ghost` alone does not install or load
|
|
10
|
+
the SDK or its transports.
|
|
11
|
+
|
|
12
|
+
## Connect over Streamable HTTP
|
|
13
|
+
|
|
14
|
+
Add the official SDK and its HTTP dependencies to your bundle:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
gem "mcp", "~> 1.3"
|
|
18
|
+
gem "faraday", "~> 2.0"
|
|
19
|
+
gem "event_stream_parser", "~> 1.0"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Require the integration explicitly, then create a Toolset with a `client`
|
|
23
|
+
block. Return a new official client from the block:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require "little_ghost/mcp"
|
|
27
|
+
|
|
28
|
+
class HelpCenterTools < LittleGhost::MCP::Toolset
|
|
29
|
+
client do |_binding|
|
|
30
|
+
transport = MCP::Client::HTTP.new(
|
|
31
|
+
url: "https://mcp.example/rpc"
|
|
32
|
+
)
|
|
33
|
+
MCP::Client.new(transport:)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class CustomerSupportAgent < LittleGhost::Agent
|
|
38
|
+
system_prompt "Use help-center tools for published guidance."
|
|
39
|
+
tools HelpCenterTools
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
run = CustomerSupportAgent.ask("How long do refunds take?")
|
|
43
|
+
run.response
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
LittleGhost calls the block once for each Agent run. It connects the client,
|
|
47
|
+
discovers the server's Tools, and closes the transport when the run ends.
|
|
48
|
+
|
|
49
|
+
The `client` block receives the current `Tool::Binding`. Use it to build headers
|
|
50
|
+
or credentials from authenticated application context without storing them on
|
|
51
|
+
the Toolset:
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
class AccountTools < LittleGhost::MCP::Toolset
|
|
55
|
+
client do |binding|
|
|
56
|
+
token = McpAccessTokens.for_actor(binding.run.invocation.actor_id)
|
|
57
|
+
transport = MCP::Client::HTTP.new(
|
|
58
|
+
url: "https://mcp.example/rpc",
|
|
59
|
+
headers: {"Authorization" => "Bearer #{token}"}
|
|
60
|
+
)
|
|
61
|
+
MCP::Client.new(transport:)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Connect a local server over standard input and output
|
|
67
|
+
|
|
68
|
+
A standard input and output (stdio) connection needs only the official SDK:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
gem "mcp", "~> 1.3"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Construct the SDK transport in the same `client` block:
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
class LocalDatabaseTools < LittleGhost::MCP::Toolset
|
|
78
|
+
client do |_binding|
|
|
79
|
+
transport = MCP::Client::Stdio.new(
|
|
80
|
+
command: "bundle",
|
|
81
|
+
args: ["exec", "database-mcp"],
|
|
82
|
+
env: {"APP_ENV" => "production"},
|
|
83
|
+
read_timeout: 30
|
|
84
|
+
)
|
|
85
|
+
MCP::Client.new(transport:)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
A stdio server is a child process with the same operating-system permissions as
|
|
91
|
+
your Ruby process. It is not a sandbox. Use an operating-system sandbox when
|
|
92
|
+
you do not fully trust the executable.
|
|
93
|
+
|
|
94
|
+
The `env` Hash changes only the variables you name. The child inherits every
|
|
95
|
+
other variable from the parent process. Clear sensitive variables explicitly,
|
|
96
|
+
or launch the server through an isolated wrapper when it must not receive
|
|
97
|
+
ambient credentials.
|
|
98
|
+
|
|
99
|
+
## Configure the official client
|
|
100
|
+
|
|
101
|
+
Set timeouts, message limits, OAuth, middleware, and other transport behavior
|
|
102
|
+
through the SDK. Keyword arguments on `client` go directly to
|
|
103
|
+
`MCP::Client#connect`; use them for an explicit protocol mode, version, or client
|
|
104
|
+
capability.
|
|
105
|
+
|
|
106
|
+
### Respond to server requests
|
|
107
|
+
|
|
108
|
+
A server may need more information while handling a Tool call. MCP calls this
|
|
109
|
+
elicitation. Advertise the capability when connecting, then register a handler
|
|
110
|
+
on the client:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
class InteractiveTools < LittleGhost::MCP::Toolset
|
|
114
|
+
client(capabilities: {elicitation: {}}) do |binding|
|
|
115
|
+
transport = MCP::Client::HTTP.new(url: "https://mcp.example/rpc")
|
|
116
|
+
MCP::Client.new(transport:).tap do |official_client|
|
|
117
|
+
official_client.on_elicitation do |request|
|
|
118
|
+
Elicitations.answer(request, run: binding.run)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The handler can answer from the current Run or pass the request to an application
|
|
126
|
+
interface. Sampling similarly lets a server request a model call, while roots
|
|
127
|
+
tell a server which directories the application makes available. Configure
|
|
128
|
+
these features on the official client.
|
|
129
|
+
|
|
130
|
+
Treat every server-initiated handler request as untrusted. Authorize it against
|
|
131
|
+
the current run, restrict roots to intended paths, constrain model sampling and
|
|
132
|
+
its cost, and return only the application data that server is allowed to receive.
|
|
133
|
+
|
|
134
|
+
Return a new, unconnected client for every run. Building it should not start
|
|
135
|
+
remote work. LittleGhost closes transports that provide `close`, including when
|
|
136
|
+
connection or discovery fails. If a custom transport owns other resources, it
|
|
137
|
+
must release them itself.
|
|
138
|
+
|
|
139
|
+
Set transport timeouts to match the application's deadline. LittleGhost passes
|
|
140
|
+
Run cancellation and deadlines to Tool discovery and calls, but connection has
|
|
141
|
+
its own timeout behavior.
|
|
142
|
+
|
|
143
|
+
## Plan concurrency and cancellation
|
|
144
|
+
|
|
145
|
+
Most applications only need transport timeouts. The details below matter when
|
|
146
|
+
the application uses a Fiber scheduler or runs independent Tools concurrently.
|
|
147
|
+
|
|
148
|
+
### Connection
|
|
149
|
+
|
|
150
|
+
LittleGhost connects while it discovers the Agent's Tools. Run cancellation
|
|
151
|
+
does not interrupt connection, so the transport's connection and read timeouts
|
|
152
|
+
control how long it can wait. Choose a scheduler-compatible transport adapter
|
|
153
|
+
when other fibers must continue during that time.
|
|
154
|
+
|
|
155
|
+
### Tool discovery and calls
|
|
156
|
+
|
|
157
|
+
Tool discovery and calls honor Run cancellation and deadlines. Cancelling an
|
|
158
|
+
HTTP call returns control to the Run, but the underlying request may continue
|
|
159
|
+
waiting until the server responds or the transport closes.
|
|
160
|
+
|
|
161
|
+
All Tools for one run share the same client. HTTP calls may overlap when
|
|
162
|
+
LittleGhost runs independent Tools concurrently, so choose a Faraday adapter
|
|
163
|
+
that supports overlapping calls. If the server or transport requires one call
|
|
164
|
+
at a time, mark the generated Tools exclusive:
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
map_tool do |tool_class, mcp_tool:, binding:|
|
|
168
|
+
tool_class.exclusive true
|
|
169
|
+
tool_class
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
LittleGhost serializes calls through the official stdio transport. If one of
|
|
174
|
+
those calls is cancelled, it closes that run's session rather than risk reading
|
|
175
|
+
a late response as the answer to a later call. A custom or decorated stdio
|
|
176
|
+
transport must provide its own serialization, cancellation behavior, and
|
|
177
|
+
cleanup.
|
|
178
|
+
|
|
179
|
+
### Server handlers
|
|
180
|
+
|
|
181
|
+
The server may invoke a handler while other work is active. Write handlers for
|
|
182
|
+
concurrent use and capture the application values they need when building the
|
|
183
|
+
client. Do not rely on fiber-local state inside a handler.
|
|
184
|
+
|
|
185
|
+
## Select and map Tools
|
|
186
|
+
|
|
187
|
+
By default, the Agent receives every Tool published by the server. LittleGhost
|
|
188
|
+
normalizes each name for the model and keeps the server's original name for
|
|
189
|
+
calls. Discovery stops after 1,000 Tools or 100 pages, which bounds the work an
|
|
190
|
+
untrusted catalog can create in one run.
|
|
191
|
+
|
|
192
|
+
Use `map_tool` to omit operations or configure their generated classes:
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
class CuratedHelpCenterTools < HelpCenterTools
|
|
196
|
+
map_tool do |tool_class, mcp_tool:, binding:|
|
|
197
|
+
next unless %w[search fetch].include?(mcp_tool.name)
|
|
198
|
+
|
|
199
|
+
tool_class.tool_name "help_center_#{mcp_tool.name}"
|
|
200
|
+
tool_class
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`mcp_tool` is the Tool published by the official client. Return the generated
|
|
206
|
+
class, a subclass, or `nil` to omit it. Renaming the generated Tool changes the
|
|
207
|
+
name shown to the model, not the name sent back to the server.
|
|
208
|
+
|
|
209
|
+
LittleGhost sends the server's input schema to the model unchanged. It does not
|
|
210
|
+
validate arguments against that schema; the server must validate them before
|
|
211
|
+
performing an operation. LittleGhost limits schema depth and node count during
|
|
212
|
+
discovery. Configure the transport's message-size limit to bound the bytes
|
|
213
|
+
accepted from a server.
|
|
214
|
+
|
|
215
|
+
> **Safety note:** Server descriptions and results become visible to the model.
|
|
216
|
+
> Treat them as untrusted content. Expose only the operations the Agent needs,
|
|
217
|
+
> use narrowly scoped credentials, and have the server authorize every sensitive
|
|
218
|
+
> call.
|
|
219
|
+
|
|
220
|
+
## Convert results
|
|
221
|
+
|
|
222
|
+
Without a mapping, LittleGhost returns `structuredContent` when the server sends
|
|
223
|
+
it. Otherwise, it returns the text or remaining visible content blocks. MCP
|
|
224
|
+
image blocks become Artifacts.
|
|
225
|
+
|
|
226
|
+
Suppose the help-center server returns `structuredContent` with an `articles`
|
|
227
|
+
array. Use `map_result` to present each article as a short line:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
map_result do |value, mcp_tool:, **|
|
|
231
|
+
next value unless mcp_tool.name == "search"
|
|
232
|
+
|
|
233
|
+
value.fetch("articles").map do |article|
|
|
234
|
+
"#{article.fetch("title")}: #{article.fetch("url")}"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
`value` is LittleGhost's default conversion, and `mcp_tool` identifies the
|
|
240
|
+
server operation. Return `value` unchanged or replace it with any Ruby value or
|
|
241
|
+
`Tool::Result`. The block can also receive the raw result, sent arguments, and
|
|
242
|
+
current binding; see the [`MCP::Toolset`
|
|
243
|
+
API](rdoc-ref:LittleGhost::MCP::Toolset) for their exact shapes.
|
|
244
|
+
|
|
245
|
+
Image Artifacts remain attached to the mapped result. A server result marked
|
|
246
|
+
`isError` remains a model-visible Tool error.
|
|
247
|
+
|
|
248
|
+
For custom images, files, or deferred Artifacts, continue with [Structured
|
|
249
|
+
Results and Content](structured_outputs_and_content.md). A deferred resolver
|
|
250
|
+
must verify ownership, fetch only from the intended service, and limit response
|
|
251
|
+
size.
|
|
252
|
+
|
|
253
|
+
## Keep an optional server from blocking a run
|
|
254
|
+
|
|
255
|
+
An optional server can fail discovery without preventing Agent construction:
|
|
256
|
+
|
|
257
|
+
```ruby
|
|
258
|
+
class OptionalHelpCenterTools < HelpCenterTools
|
|
259
|
+
optional true
|
|
260
|
+
on_error do |error, binding:|
|
|
261
|
+
McpAvailability.report(error, run_id: binding.run.invocation.run_id)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
`optional true` turns an expected connection or protocol error during discovery
|
|
267
|
+
into an empty Tool set. Configuration errors, cancellation, deadlines, and
|
|
268
|
+
failures in application callbacks still stop the run.
|
|
269
|
+
|
|
270
|
+
## Let the SDK negotiate the protocol version
|
|
271
|
+
|
|
272
|
+
The [official MCP Ruby SDK](https://github.com/modelcontextprotocol/ruby-sdk)
|
|
273
|
+
handles protocol negotiation and transport behavior. Without explicit connect
|
|
274
|
+
options, it negotiates with the server using a protocol version the installed
|
|
275
|
+
SDK supports. Pin `protocol_version` or `mode` only when interoperability
|
|
276
|
+
requires it.
|
|
277
|
+
|
|
278
|
+
Need sampling, roots, elicitation, or another client capability? Configure it
|
|
279
|
+
on the client you build above. The installed SDK and negotiated protocol version
|
|
280
|
+
determine what is available. Check the [Ruby SDK client
|
|
281
|
+
documentation](https://ruby.sdk.modelcontextprotocol.io/client/) and the
|
|
282
|
+
[versioned MCP specification](https://modelcontextprotocol.io/specification/)
|
|
283
|
+
for the capability you need.
|
|
284
|
+
|
|
285
|
+
Continue with [Tools](tools.md) for the local Tool boundary,
|
|
286
|
+
[Integrations](integrations.md) to send Runs through AG-UI or OpenTelemetry, or
|
|
287
|
+
the [`MCP::Toolset` API](rdoc-ref:LittleGhost::MCP::Toolset) for exact mapping
|
|
288
|
+
and ownership contracts.
|
|
@@ -62,11 +62,11 @@ run = CustomerSupportAgent.ask(
|
|
|
62
62
|
Build these settings in application code instead of passing request parameters
|
|
63
63
|
through unchanged. Settings can affect cost, latency, and model behavior.
|
|
64
64
|
|
|
65
|
-
##
|
|
65
|
+
## Connect the provider you chose
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
Connections may live in an initializer or in the conventional files under
|
|
68
|
+
`config/little_ghost`. [Provider Support](providers.md) has copyable settings
|
|
69
|
+
for each built-in adapter, compatible endpoints, Ollama, and LM Studio.
|
|
70
70
|
|
|
71
71
|
Keep credentials in your application's secret manager. Agents refer to a role
|
|
72
72
|
or configured connection; they don't need to contain credentials. If your
|
|
@@ -120,6 +120,11 @@ choose a structured-result strategy.
|
|
|
120
120
|
Provider capabilities can change. Handle failed Runs and provider errors even
|
|
121
121
|
when the catalog says a feature is supported.
|
|
122
122
|
|
|
123
|
+
Most application code does not call the resolver directly. Declaring an
|
|
124
|
+
Agent's model, or passing `model:` to generation or embedding, resolves the
|
|
125
|
+
selection for you. Inspect model details when an interface needs to explain
|
|
126
|
+
limits or your application wants to check an attachment before sending it.
|
|
127
|
+
|
|
123
128
|
## Call a model without an Agent
|
|
124
129
|
|
|
125
130
|
Some application work needs one model response rather than an Agent. Use
|
|
@@ -141,57 +146,23 @@ response.usage.total_tokens
|
|
|
141
146
|
```
|
|
142
147
|
|
|
143
148
|
The operation returns a `LittleGhost::RunResult`, the same result type returned
|
|
144
|
-
by an Agent invocation
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
creating a Run. Structured generation may make one additional repair request.
|
|
148
|
-
|
|
149
|
-
Pass a strict object schema when application code needs checked JSON:
|
|
149
|
+
by an Agent invocation. Application code can read `output`, `usage`, and the
|
|
150
|
+
final message in the same way. Plain generation makes one model request without
|
|
151
|
+
starting an Agent or creating a Run.
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
result_schema: {
|
|
156
|
-
name: "classification",
|
|
157
|
-
description: "Classify one support request",
|
|
158
|
-
schema: {
|
|
159
|
-
type: "object",
|
|
160
|
-
properties: {category: {type: "string"}},
|
|
161
|
-
required: ["category"],
|
|
162
|
-
additionalProperties: false
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
response.output
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
LittleGhost checks the result against the schema and gives the model one repair
|
|
171
|
-
attempt by default. Add `structured_result_repair_attempts: 3` to the call
|
|
172
|
-
above when a checked result warrants additional attempts. The setting accepts
|
|
173
|
-
integers from zero through three.
|
|
174
|
-
|
|
175
|
-
Read the checked value through `response.output`. If every permitted attempt is
|
|
176
|
-
invalid, the call raises `LittleGhost::StructuredResultError`.
|
|
177
|
-
|
|
178
|
-
A schema checks the shape of a value, not whether your application should act
|
|
179
|
-
on it. Check identifiers, permissions, and business rules before using the
|
|
180
|
-
result to change application state.
|
|
153
|
+
Pass `result_schema:` when application code needs checked JSON. [Structured
|
|
154
|
+
Results and Content](structured_outputs_and_content.md) covers strict schemas,
|
|
155
|
+
provider strategies, repair behavior, and the application checks that still
|
|
156
|
+
belong outside the schema.
|
|
181
157
|
|
|
182
158
|
## Create embeddings
|
|
183
159
|
|
|
184
160
|
Use `LittleGhost.embed` when your application needs numeric representations for
|
|
185
161
|
search, clustering, or another similarity-based feature:
|
|
186
162
|
|
|
187
|
-
The example assumes application startup maps `search_embeddings` to an
|
|
188
|
-
embedding model, following the role configuration shown earlier on this page.
|
|
189
|
-
The selected provider adapter's API reference lists the model-specific
|
|
190
|
-
settings.
|
|
191
|
-
|
|
192
163
|
```ruby
|
|
193
164
|
response = LittleGhost.embed(
|
|
194
|
-
model: :
|
|
165
|
+
model: "primary:openai/text-embedding-3-small",
|
|
195
166
|
inputs: ["Reset a password", "Track a transfer"]
|
|
196
167
|
)
|
|
197
168
|
|
|
@@ -202,14 +173,10 @@ response.usage.input_tokens
|
|
|
202
173
|
|
|
203
174
|
The response keeps vectors in the same order as the inputs. LittleGhost rejects
|
|
204
175
|
an incomplete or malformed response instead of returning a partial batch.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
Embedding text is sent to the selected provider. Choose a provider that is
|
|
210
|
-
appropriate for that data, just as you would for an Agent request. See
|
|
211
|
-
`LittleGhost::Embeddings::Request` and your provider adapter's API reference for
|
|
212
|
-
the supported settings and request bounds.
|
|
176
|
+
Embedding text is sent to the selected provider, so choose one appropriate for
|
|
177
|
+
that data. [Provider Support](providers.md) identifies adapters with embedding
|
|
178
|
+
support; `LittleGhost::Embeddings::Request` documents settings and request
|
|
179
|
+
bounds.
|
|
213
180
|
|
|
214
181
|
Continue with [Prompts as Views](prompt_views.md) when an Agent's instructions
|
|
215
182
|
outgrow one string. See [Structured Results and Content](structured_outputs_and_content.md)
|
data/docs/guides/production.md
CHANGED
|
@@ -37,7 +37,15 @@ class CustomerSupportAgent < LittleGhost::Agent
|
|
|
37
37
|
end
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Provider connections and model roles can
|
|
40
|
+
Provider connections and model roles can live in the Ruby initializer or in
|
|
41
|
+
YAML under `config/little_ghost`. Values set in Ruby take priority. See
|
|
42
|
+
`LittleGhost::Configuration` for custom files and the full precedence order.
|
|
43
|
+
|
|
44
|
+
[Provider Support](providers.md) lists the credentials and endpoint settings
|
|
45
|
+
for hosted and local providers. Choose connection names, model identifiers,
|
|
46
|
+
and custom headers during application startup. Read secrets from deployment
|
|
47
|
+
configuration or a secret manager; do not copy request parameters into these
|
|
48
|
+
settings.
|
|
41
49
|
|
|
42
50
|
Prompts, caller input and history, Tool results, and attachments may go to the
|
|
43
51
|
selected provider. Choose configured providers that are appropriate for that
|
|
@@ -289,14 +297,15 @@ LittleGhost.configure do |config|
|
|
|
289
297
|
end
|
|
290
298
|
config.sandbox = {
|
|
291
299
|
provider: :native,
|
|
292
|
-
files: {root: :read_write}
|
|
293
|
-
root_filesystem: :isolated,
|
|
294
|
-
environment: {inherit: false, set: {"LANG" => "C.UTF-8"}},
|
|
295
|
-
network: :none
|
|
300
|
+
files: {root: :read_write}
|
|
296
301
|
}
|
|
297
302
|
end
|
|
298
303
|
```
|
|
299
304
|
|
|
305
|
+
The native backend isolates the host root, removes child-process network
|
|
306
|
+
access, and starts with a scrubbed child environment unless you configure a
|
|
307
|
+
different policy.
|
|
308
|
+
|
|
300
309
|
The temporary Workspace above is useful when files should live for one Run. Use application-managed storage, with tenant isolation and concurrency control, when files must persist or several Runs share a root.
|
|
301
310
|
|
|
302
311
|
The Run opens a Runtime-created Workspace before its Sandbox and closes them in reverse order after every outcome. Closing a Workspace invokes its configured teardown; it does not delete files by default. Cleanup failures raise because LittleGhost cannot confirm a clean shutdown of every owned resource. Existing instances passed by the application remain caller-owned.
|