little_ghost 0.8.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 +1 -1
- data/docs/guides/assemblies.md +21 -9
- data/docs/guides/getting_started.md +1 -1
- data/docs/guides/prompt_views.md +234 -27
- 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 +37 -4
- data/lib/little_ghost/assembly_builder.rb +1 -1
- data/lib/little_ghost/cli.rb +291 -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/errors.rb +19 -1
- data/lib/little_ghost/framework_prompts.rb +376 -0
- data/lib/little_ghost/generators/application_generator.rb +1 -1
- data/lib/little_ghost/graph.rb +24 -5
- data/lib/little_ghost/mcp/client.rb +18 -10
- data/lib/little_ghost/model_operations.rb +103 -36
- 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/runtime/hooks/artifacts.rb +58 -22
- data/lib/little_ghost/runtime.rb +8 -3
- data/lib/little_ghost/sandbox/filesystem.rb +51 -33
- 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 +10 -6
- data/lib/little_ghost/skills/catalog.rb +32 -37
- 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 +42 -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 +5 -2
- metadata +187 -2
- /data/lib/little_ghost/generators/templates/application/app/prompts/application/{system.erb.tt → system_prompt.erb.tt} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 271908b0fc40900504fb25cd57d2cbcc8d987ac1ab32a0db58353562793446fc
|
|
4
|
+
data.tar.gz: 507e5d747e8b341dd60b1edce8811e0dc5b2d41f98cb970e801284b2a326a49f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 830edf81e2d4892e7b72def07ba1d1be85843c8abf5cbb25d744ad520e8586fe9de2ae1cb32084ce832bb1eb866f4fa083af95b93e59df2b3e2c47f4e5c7aea9
|
|
7
|
+
data.tar.gz: a8dba3d880bdc6adc4271daac984f9ab6384d34520a5be2071e66d1d746f4979952c13e7743364e2de2f2c2aa721057e12e54ca29c83a382b6506e49889ee43e
|
data/README.md
CHANGED
|
@@ -148,7 +148,7 @@ upgrading, because interfaces may change between releases.
|
|
|
148
148
|
- [Core Concepts](docs/guides/core_concepts.md) builds the mental model from Agent to Assembly.
|
|
149
149
|
- [Models and Providers](docs/guides/models_and_providers.md) explains targets, shared roles, and per-request model selection.
|
|
150
150
|
- [Provider Support](docs/guides/providers.md) has copyable setup for hosted APIs and local model servers.
|
|
151
|
-
- [Prompts as Views](docs/guides/prompt_views.md)
|
|
151
|
+
- [Prompts as Views](docs/guides/prompt_views.md) explains Agent instructions and shared partials, including how to customize LittleGhost's bundled framework prompts.
|
|
152
152
|
- [Tools](docs/guides/tools.md) explains how models call focused Ruby operations.
|
|
153
153
|
- [MCP](docs/guides/mcp.md) connects agents to operations published through the Model Context Protocol.
|
|
154
154
|
- [Structured Results and Content](docs/guides/structured_outputs_and_content.md) covers checked result shapes, images, and documents.
|
data/docs/guides/assemblies.md
CHANGED
|
@@ -15,7 +15,7 @@ run = entrypoint.ask(question)
|
|
|
15
15
|
|
|
16
16
|
## Use a Workflow for explicit application logic
|
|
17
17
|
|
|
18
|
-
A Workflow's `perform` method is ordinary Ruby. Inside it, `invoke` prepares a child call. Read `.output` when you need an intermediate answer. Return the final `invoke` call untouched so its response can stream to the caller.
|
|
18
|
+
A Workflow's `perform` method is ordinary Ruby. Inside it, `invoke` prepares a child call. Read `.output` when you need an intermediate answer. Return the final `invoke` call untouched so its response can stream to the caller, or return a value that Ruby computes from the intermediate answers.
|
|
19
19
|
|
|
20
20
|
```ruby
|
|
21
21
|
class ResponseWorkflow < LittleGhost::Workflow
|
|
@@ -41,25 +41,37 @@ Every participant passed to `invoke` can be an Agent or another Assembly. By def
|
|
|
41
41
|
|
|
42
42
|
Each child Agent keeps its own [prompt view](prompt_views.md). The Workflow supplies request-specific input; it does not replace that Agent's reusable system instructions.
|
|
43
43
|
|
|
44
|
-
The last child is special
|
|
44
|
+
The last child is special when its events should become the Workflow's public stream. Return that `invoke` without consuming it:
|
|
45
45
|
|
|
46
46
|
```ruby
|
|
47
|
-
# Wrong: this returns a String after consuming the final invocation.
|
|
48
47
|
def perform
|
|
49
|
-
invoke
|
|
48
|
+
invoke CustomerSupportAgent
|
|
50
49
|
end
|
|
50
|
+
```
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
When Ruby should compute the caller-visible result, consume every child and return the computed value:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
class EvidenceWorkflow < LittleGhost::Workflow
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def perform
|
|
59
|
+
findings = parallel(
|
|
60
|
+
invoke(LedgerResearchAgent),
|
|
61
|
+
invoke(PolicyResearchAgent),
|
|
62
|
+
max_concurrency: 2
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
{"findings" => findings}
|
|
66
|
+
end
|
|
55
67
|
end
|
|
56
68
|
```
|
|
57
69
|
|
|
58
|
-
|
|
70
|
+
A returned String becomes the Workflow's textual response. Arrays, mappings, numbers, and booleans become a structured result available through `RunResult#output`, including when the Workflow is exposed with `assembly_as_tool`. Direct structured results must be JSON-compatible and stay within LittleGhost's structured-result size, depth, and complexity limits. Return an explicit value: `nil` remains a `ProtocolError`, which catches forgotten returns.
|
|
59
71
|
|
|
60
72
|
### Choose a branch in Ruby
|
|
61
73
|
|
|
62
|
-
Each branch should end with its final unconsumed invocation:
|
|
74
|
+
Each branch should end with its final unconsumed invocation or a directly computed value:
|
|
63
75
|
|
|
64
76
|
```ruby
|
|
65
77
|
class RoutedResponseWorkflow < LittleGhost::Workflow
|
data/docs/guides/prompt_views.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Prompts as Views
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Keep growing Agent instructions readable by moving them into a **prompt view**:
|
|
4
|
+
an ERB file that LittleGhost finds and renders for the Agent. The Agent prepares
|
|
5
|
+
any application values the prompt needs, while the view holds the instructions
|
|
6
|
+
sent to the model.
|
|
6
7
|
|
|
7
8
|
## Start with the inline prompt
|
|
8
9
|
|
|
@@ -28,7 +29,7 @@ class CustomerSupportAgent < LittleGhost::Agent
|
|
|
28
29
|
end
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
Then create `app/prompts/customer_support/
|
|
32
|
+
Then create `app/prompts/customer_support/system_prompt.erb`:
|
|
32
33
|
|
|
33
34
|
```erb
|
|
34
35
|
You help customers understand their orders and account.
|
|
@@ -38,57 +39,115 @@ Never invent company guidance. Check the help center when policy matters.
|
|
|
38
39
|
Use the order status tool before making a claim about a private order.
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
That is enough. `CustomerSupportAgent`
|
|
42
|
+
That is enough. LittleGhost turns `CustomerSupportAgent` into the logical path
|
|
43
|
+
`customer_support` and looks for
|
|
44
|
+
`app/prompts/customer_support/system_prompt.erb`.
|
|
42
45
|
|
|
43
|
-
The prompt is still a system instruction sent to the selected model provider.
|
|
46
|
+
The prompt is still a system instruction sent to the selected model provider.
|
|
47
|
+
Keeping it in a view improves organization; it does not keep the content inside
|
|
48
|
+
your process.
|
|
44
49
|
|
|
45
|
-
##
|
|
50
|
+
## Prepare application values with Ruby
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
Define `system_prompt` as an instance method when the view needs values from
|
|
53
|
+
your application. Assign those values to instance variables:
|
|
48
54
|
|
|
49
55
|
```ruby
|
|
50
56
|
class CustomerSupportAgent < LittleGhost::Agent
|
|
51
|
-
|
|
57
|
+
def system_prompt
|
|
58
|
+
@company_name = "Northstar"
|
|
59
|
+
@policy_version = SupportPolicy.current_version
|
|
60
|
+
end
|
|
52
61
|
end
|
|
53
62
|
```
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
LittleGhost calls the method before it renders the view. The instance variables
|
|
65
|
+
are available there by the same names:
|
|
56
66
|
|
|
57
67
|
```erb
|
|
58
|
-
You are a customer support agent for <%= company_name %>.
|
|
68
|
+
You are a customer support agent for <%= @company_name %>.
|
|
69
|
+
Follow support policy <%= @policy_version %>.
|
|
59
70
|
Answer clearly and concisely.
|
|
60
71
|
```
|
|
61
72
|
|
|
62
|
-
|
|
73
|
+
If you know Rails controllers, the pairing is familiar: the method prepares
|
|
74
|
+
values, and the ERB file presents them. The method's return value is ignored. If
|
|
75
|
+
it raises an exception, the Run fails in the usual way.
|
|
76
|
+
|
|
77
|
+
An inline `system_prompt` declaration still takes precedence over a view. Remove
|
|
78
|
+
the inline declaration when you want LittleGhost to call the instance method and
|
|
79
|
+
render `system_prompt.erb`.
|
|
80
|
+
|
|
81
|
+
Subclass actions can call `super` before adding their own values:
|
|
63
82
|
|
|
64
83
|
```ruby
|
|
65
|
-
class
|
|
66
|
-
|
|
84
|
+
class BillingSupportAgent < CustomerSupportAgent
|
|
85
|
+
def system_prompt
|
|
86
|
+
super
|
|
87
|
+
@billing_region = "US"
|
|
88
|
+
end
|
|
67
89
|
end
|
|
68
90
|
```
|
|
69
91
|
|
|
70
|
-
Prompt views also receive
|
|
92
|
+
Prompt views also receive three built-in local variables: `invocation` for the
|
|
93
|
+
current request, `run` for its lifecycle, and `agent` for the run-scoped Agent.
|
|
94
|
+
Use them when an instruction genuinely depends on the current request. Keep the
|
|
95
|
+
customer's wording in the caller message unless it belongs in the system
|
|
96
|
+
instruction.
|
|
71
97
|
|
|
72
|
-
Every rendered value may be sent to the model provider.
|
|
98
|
+
Every rendered value may be sent to the model provider. Put only data that
|
|
99
|
+
belongs in the prompt into the view.
|
|
73
100
|
|
|
74
101
|
## Share a small partial
|
|
75
102
|
|
|
76
103
|
Partials keep repeated instructions in one place. Create `app/prompts/shared/_voice.erb`:
|
|
77
104
|
|
|
78
105
|
```erb
|
|
79
|
-
Use a warm, direct voice for <%= company_name %>.
|
|
106
|
+
Use a warm, direct voice for <%= @company_name %>.
|
|
80
107
|
Prefer one clear next step over a long list of possibilities.
|
|
81
108
|
```
|
|
82
109
|
|
|
83
110
|
Render it from the Agent's system view:
|
|
84
111
|
|
|
85
112
|
```erb
|
|
86
|
-
You are a customer support agent for <%= company_name %>.
|
|
113
|
+
You are a customer support agent for <%= @company_name %>.
|
|
114
|
+
|
|
115
|
+
<%= partial "shared/voice" %>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The underscore marks a partial. Partials share the Agent's instance variables,
|
|
119
|
+
so `@company_name` remains available without extra wiring.
|
|
120
|
+
|
|
121
|
+
Use an explicit local for a value that belongs only to one partial. For example,
|
|
122
|
+
create `app/prompts/shared/_closing.erb`:
|
|
123
|
+
|
|
124
|
+
```erb
|
|
125
|
+
Offer one clear next step for <%= audience %>.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Then pass `audience` when you render it:
|
|
87
129
|
|
|
88
|
-
|
|
130
|
+
```erb
|
|
131
|
+
<%= partial "shared/closing", locals: {audience: "account owners"} %>
|
|
89
132
|
```
|
|
90
133
|
|
|
91
|
-
|
|
134
|
+
Locals do not flow into nested partials unless you pass them again.
|
|
135
|
+
|
|
136
|
+
## Keep repeated renders predictable
|
|
137
|
+
|
|
138
|
+
LittleGhost calls `system_prompt` once for each file-backed prompt render. Each
|
|
139
|
+
call starts with the instance variables captured after LittleGhost's
|
|
140
|
+
`after_initialize` callbacks finish. Values left behind by a later callback,
|
|
141
|
+
Tool, or earlier render do not become prompt assigns by accident.
|
|
142
|
+
|
|
143
|
+
After preparing the view, LittleGhost restores the Agent's live instance
|
|
144
|
+
variables. The objects assigned to the view are still ordinary Ruby objects,
|
|
145
|
+
though, so the view sees the same mutable objects. Treat them as read-only, or
|
|
146
|
+
duplicate a value before assigning it when the template needs an isolated copy.
|
|
147
|
+
|
|
148
|
+
For state that should change across invocations, read from `run`, a session, or
|
|
149
|
+
an application object in `system_prompt` instead of relying on an earlier
|
|
150
|
+
prompt render.
|
|
92
151
|
|
|
93
152
|
## Choose a different template path
|
|
94
153
|
|
|
@@ -104,10 +163,154 @@ LittleGhost chooses one prompt source in this order:
|
|
|
104
163
|
|
|
105
164
|
1. An inline `system_prompt`
|
|
106
165
|
2. An explicit `system_template`
|
|
107
|
-
3. The Agent's conventional `
|
|
166
|
+
3. The Agent's conventional `system_prompt.erb` view
|
|
108
167
|
|
|
109
168
|
Applications can add prompt lookup roots through `Configuration#prompt_paths`.
|
|
110
|
-
Earlier roots win,
|
|
169
|
+
Earlier roots win, so an application can override a view from a shared prompt
|
|
170
|
+
package.
|
|
171
|
+
|
|
172
|
+
## Customize LittleGhost's framework prompts
|
|
173
|
+
|
|
174
|
+
You can change LittleGhost's own model-facing language without replacing its
|
|
175
|
+
Ruby behavior. Tool descriptions, structured-result repair requests, context
|
|
176
|
+
summaries, code-mode instructions, and other framework messages all come from
|
|
177
|
+
bundled prompt views under the `little_ghost/` namespace.
|
|
178
|
+
|
|
179
|
+
### Decide when to customize
|
|
180
|
+
|
|
181
|
+
Models can respond differently to the same instruction, even when the Tool,
|
|
182
|
+
schema, and task stay the same. Wording that works well with one model may lead
|
|
183
|
+
another model to miss a Tool constraint, mishandle a repair request, or recover
|
|
184
|
+
less reliably from a failed call. Adjusting the relevant framework prompt gives
|
|
185
|
+
you a direct way to improve that interaction without forking LittleGhost.
|
|
186
|
+
|
|
187
|
+
An override can also align framework language with your application's
|
|
188
|
+
terminology and voice. Start with the narrowest template that covers the
|
|
189
|
+
behavior you want to change, and evaluate it with the models your application
|
|
190
|
+
uses. Keep protocol checks, authorization, and execution limits in Ruby;
|
|
191
|
+
prompt wording guides the model but does not enforce those boundaries.
|
|
192
|
+
|
|
193
|
+
### Find the prompt you want to change
|
|
194
|
+
|
|
195
|
+
Browse the catalog from your application:
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
$ little_ghost prompts list
|
|
199
|
+
$ little_ghost prompts list structured_output
|
|
200
|
+
$ little_ghost prompts list structured_output/repair
|
|
201
|
+
$ little_ghost prompts show structured_output/repair/request
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The bare `list` command shows top-level features with template counts. Pass a
|
|
205
|
+
feature or component path to browse its immediate children, or use `list --all`
|
|
206
|
+
to print every template key. Keys follow `feature/component/purpose`. For
|
|
207
|
+
example, built-in Tool descriptions live under `tools/built_in`, while JSON
|
|
208
|
+
Schema feedback lives under `tools/validation/schema`. Directories named
|
|
209
|
+
`feedback` contain conditions the model can correct. Directories named `errors`
|
|
210
|
+
contain operational failures.
|
|
211
|
+
|
|
212
|
+
`show` prints the bundled ERB source. Every bundled template starts with a
|
|
213
|
+
structured ERB comment that explains where LittleGhost renders it, its locals,
|
|
214
|
+
and any formatting constraints. These headers use `<%# ... -%>`, so neither the
|
|
215
|
+
comment nor its trailing newline enters the rendered prompt. Each interior line
|
|
216
|
+
also starts with `#` so Ruby-aware editors recognize the whole header as a
|
|
217
|
+
comment. A `#` line outside `<%# ... -%>` and an HTML comment are output text and
|
|
218
|
+
would be sent to the model.
|
|
219
|
+
|
|
220
|
+
Bundled prompts use plain text and Markdown. When a prompt needs headings or
|
|
221
|
+
structured sections, the default template uses Markdown headings and lists
|
|
222
|
+
rather than XML-like wrapper tags.
|
|
223
|
+
|
|
224
|
+
### Copy an override into your application
|
|
225
|
+
|
|
226
|
+
Copy one template into the default application prompt root before editing it:
|
|
227
|
+
|
|
228
|
+
```sh
|
|
229
|
+
$ little_ghost prompts copy structured_output/repair/request
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
That creates
|
|
233
|
+
`app/prompts/little_ghost/structured_output/repair/request.erb`. Use `--root` when the
|
|
234
|
+
application configures a different prompt root:
|
|
235
|
+
|
|
236
|
+
```sh
|
|
237
|
+
$ little_ghost prompts copy structured_output/repair/request --root config/prompts
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Use `--agent` when one Agent needs different wording from the rest of the
|
|
241
|
+
application. Pass the Agent's logical path, which is its underscored class name
|
|
242
|
+
without the `Agent` suffix:
|
|
243
|
+
|
|
244
|
+
```sh
|
|
245
|
+
$ little_ghost prompts copy structured_output/repair/request --agent customer_support
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
That creates
|
|
249
|
+
`app/prompts/customer_support/little_ghost/structured_output/repair/request.erb`.
|
|
250
|
+
Namespaced classes use a namespaced logical path, such as
|
|
251
|
+
`Admin::CustomerSupportAgent` becoming `admin/customer_support`.
|
|
252
|
+
|
|
253
|
+
Copy the complete catalog when an application deliberately wants to own every
|
|
254
|
+
piece of framework wording:
|
|
255
|
+
|
|
256
|
+
```sh
|
|
257
|
+
$ little_ghost prompts copy --all
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Copy commands refuse to overwrite any existing destination. With `--all`, the
|
|
261
|
+
command checks every destination before it starts writing. Copied templates
|
|
262
|
+
retain their invisible documentation headers so the override remains
|
|
263
|
+
self-explanatory in the application.
|
|
264
|
+
|
|
265
|
+
### Choose the override scope
|
|
266
|
+
|
|
267
|
+
For every framework prompt that applies to an Agent invocation, LittleGhost
|
|
268
|
+
uses the first matching template in this order:
|
|
269
|
+
|
|
270
|
+
1. An invocation-specific `TrustedPath` root
|
|
271
|
+
2. The Agent-scoped directory inside a configured prompt root
|
|
272
|
+
3. The runtime-wide directory inside a configured prompt root
|
|
273
|
+
4. The template bundled with LittleGhost
|
|
274
|
+
|
|
275
|
+
Each root keeps the same `little_ghost/<key>.erb` namespace. Agent scope inserts
|
|
276
|
+
the logical path before that namespace.
|
|
277
|
+
|
|
278
|
+
Runtime-wide overrides normally live in the default `app/prompts` root. Add or
|
|
279
|
+
replace configured roots when the application uses another location:
|
|
280
|
+
|
|
281
|
+
```ruby
|
|
282
|
+
LittleGhost.configure do |config|
|
|
283
|
+
config.prompt_paths = ["config/prompts", "app/prompts"]
|
|
284
|
+
end
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The uncommon invocation-specific layer is explicit because it can change model
|
|
288
|
+
instructions for only one call. From `config/little_ghost.rb`:
|
|
289
|
+
|
|
290
|
+
```ruby
|
|
291
|
+
campaign_prompts = LittleGhost::TrustedPath.new(
|
|
292
|
+
path: File.expand_path("campaign_prompts", __dir__)
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
CustomerSupportAgent.ask(
|
|
296
|
+
"Where is my order?",
|
|
297
|
+
template_paths: [campaign_prompts]
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The invocation root contains
|
|
302
|
+
`little_ghost/structured_output/repair/request.erb`, as a runtime root does.
|
|
303
|
+
Direct `LittleGhost.generate` calls accept the same `template_paths:` option.
|
|
304
|
+
|
|
305
|
+
### Know what an override can change
|
|
306
|
+
|
|
307
|
+
Framework templates control model-facing language, not protocol roles, Tool
|
|
308
|
+
names, schemas, validation behavior, security checks, or execution limits. A
|
|
309
|
+
required template cannot render as blank.
|
|
310
|
+
|
|
311
|
+
LittleGhost is pre-1.0. Template keys and their documented locals are maintained
|
|
312
|
+
on a best-effort basis until 1.0, so review release notes and copied overrides
|
|
313
|
+
when upgrading.
|
|
111
314
|
|
|
112
315
|
## Treat views as application code
|
|
113
316
|
|
|
@@ -115,13 +318,16 @@ Prompt views run as ERB inside the Ruby process and can call Ruby. Keep prompt
|
|
|
115
318
|
directories with the rest of your application code rather than letting a
|
|
116
319
|
request choose one.
|
|
117
320
|
|
|
118
|
-
`TrustedPath`
|
|
119
|
-
|
|
120
|
-
|
|
321
|
+
Use `TrustedPath` only when application code needs to select a request-specific
|
|
322
|
+
root. Do not derive its path from a request parameter, model output, or Tool
|
|
323
|
+
argument. The wrapper confirms that the directory exists and resolves symbolic
|
|
324
|
+
links. It does not inspect who can edit the directory or restrict what its ERB
|
|
325
|
+
can execute.
|
|
121
326
|
|
|
122
327
|
## Build request-specific input in a Workflow
|
|
123
328
|
|
|
124
|
-
A prompt view defines reusable instructions for one Agent. A Workflow may still
|
|
329
|
+
A prompt view defines reusable instructions for one Agent. A Workflow may still
|
|
330
|
+
build request-specific input for that Agent:
|
|
125
331
|
|
|
126
332
|
```ruby
|
|
127
333
|
invoke CustomerSupportAgent, input: <<~MESSAGE
|
|
@@ -132,7 +338,8 @@ invoke CustomerSupportAgent, input: <<~MESSAGE
|
|
|
132
338
|
MESSAGE
|
|
133
339
|
```
|
|
134
340
|
|
|
135
|
-
The Workflow is composing this request. `CustomerSupportAgent` still receives
|
|
341
|
+
The Workflow is composing this request. `CustomerSupportAgent` still receives
|
|
342
|
+
its own system prompt view when it runs.
|
|
136
343
|
|
|
137
344
|
Continue with [Tools](tools.md) to give those Agents application capabilities
|
|
138
345
|
while keeping model input, trusted context, and delegated sandbox operations
|
|
@@ -35,17 +35,6 @@ module LittleGhost
|
|
|
35
35
|
DEFAULT_PRESERVE_RECENT_MESSAGES = 10 # :nodoc:
|
|
36
36
|
ESTIMATED_CHARS_PER_TOKEN = 4 # :nodoc:
|
|
37
37
|
OUTPUT_LIMIT_STOP_REASONS = %i[max_tokens limit_output_tokens limit_total_tokens limit_turns].freeze # :nodoc:
|
|
38
|
-
SUMMARIZATION_PROMPT = <<~PROMPT # :nodoc:
|
|
39
|
-
You are a conversation summarizer. Provide a concise summary of the conversation history.
|
|
40
|
-
|
|
41
|
-
Format requirements:
|
|
42
|
-
- Create a structured, concise summary in bullet-point format.
|
|
43
|
-
- Do not respond conversationally, address the user directly, or comment on tool availability.
|
|
44
|
-
- Preserve key topics, questions, significant tool executions and results, code or technical information, and key insights.
|
|
45
|
-
- Do not assume tool executions failed unless otherwise stated.
|
|
46
|
-
- Write the summary in the third person.
|
|
47
|
-
PROMPT
|
|
48
|
-
|
|
49
38
|
def self.included(base) # :nodoc:
|
|
50
39
|
base.extend(ClassMethods)
|
|
51
40
|
base.class_attribute :context_management_configuration_value
|
|
@@ -193,9 +182,9 @@ module LittleGhost
|
|
|
193
182
|
started_at = monotonic_time
|
|
194
183
|
summary_request = ModelRequest.new(
|
|
195
184
|
messages: [
|
|
196
|
-
Message.new(role: :system, content:
|
|
185
|
+
Message.new(role: :system, content: render_framework_prompt("context_management/summary/system_instruction")),
|
|
197
186
|
*messages,
|
|
198
|
-
Message.new(role: :user, content: "
|
|
187
|
+
Message.new(role: :user, content: render_framework_prompt("context_management/summary/request"))
|
|
199
188
|
],
|
|
200
189
|
tools: [],
|
|
201
190
|
settings: request.settings,
|
|
@@ -17,8 +17,10 @@ module LittleGhost
|
|
|
17
17
|
# Static declarations may be combined with a resolver that returns dynamic
|
|
18
18
|
# Subagents::Definition objects. Managed conversations persist when a session
|
|
19
19
|
# store is configured unless <tt>persist: false</tt> keeps them local to one
|
|
20
|
-
# invocation.
|
|
21
|
-
#
|
|
20
|
+
# invocation. A class-declared agent exposed as a tool starts with an empty
|
|
21
|
+
# history and a fresh run-scoped Agent for every call. Set
|
|
22
|
+
# <tt>preserve_context: true</tt> to serialize calls through one Agent and
|
|
23
|
+
# retain its history.
|
|
22
24
|
#
|
|
23
25
|
# Tool overrides must be classes. A delegated agent otherwise receives only
|
|
24
26
|
# its own declared tools; it does not inherit the parent's registry. The
|
|
@@ -91,8 +93,9 @@ module LittleGhost
|
|
|
91
93
|
|
|
92
94
|
# Exposes +agent_class+ as one ordinary tool.
|
|
93
95
|
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
+
# By default, every tool call builds and closes a fresh delegated Agent.
|
|
97
|
+
# Pass <tt>preserve_context: true</tt> to serialize calls through one
|
|
98
|
+
# Agent and retain its conversational history between calls.
|
|
96
99
|
def agent_as_tool(agent_class, name: nil, description: nil, model: nil, tools: nil,
|
|
97
100
|
preserve_context: false)
|
|
98
101
|
assembly_as_tool(
|
|
@@ -40,7 +40,8 @@ module LittleGhost
|
|
|
40
40
|
paths:,
|
|
41
41
|
resource_root: binding.run&.runtime&.skill_resource_root,
|
|
42
42
|
workspace: binding.workspace,
|
|
43
|
-
sandbox: binding.sandbox
|
|
43
|
+
sandbox: binding.sandbox,
|
|
44
|
+
prompt_renderer: binding.agent.method(:render_framework_prompt)
|
|
44
45
|
)
|
|
45
46
|
)
|
|
46
47
|
return [] if catalog.names.empty?
|
|
@@ -70,10 +71,6 @@ module LittleGhost
|
|
|
70
71
|
end
|
|
71
72
|
self.skills_configuration_value = options.merge(paths: configured_paths)
|
|
72
73
|
tools CatalogTools
|
|
73
|
-
prompt_local(:skills_prompt) do
|
|
74
|
-
tool = tools.fetch("skills") if tools.names.include?("skills")
|
|
75
|
-
tool&.catalog&.discovery_prompt.to_s
|
|
76
|
-
end
|
|
77
74
|
before_invocation :include_skills_prompt
|
|
78
75
|
end
|
|
79
76
|
|
|
@@ -82,8 +79,13 @@ module LittleGhost
|
|
|
82
79
|
|
|
83
80
|
private
|
|
84
81
|
|
|
82
|
+
def skills_prompt
|
|
83
|
+
tool = tools.fetch("skills") if tools.names.include?("skills")
|
|
84
|
+
tool&.catalog&.discovery_prompt.to_s
|
|
85
|
+
end
|
|
86
|
+
|
|
85
87
|
def include_skills_prompt(payload)
|
|
86
|
-
prompt =
|
|
88
|
+
prompt = skills_prompt
|
|
87
89
|
return Support::Callbacks.continue if prompt.empty?
|
|
88
90
|
|
|
89
91
|
messages = payload.fetch(:messages).dup
|
|
@@ -27,8 +27,6 @@ module LittleGhost
|
|
|
27
27
|
# changed result resets that sequence, while a terminating repeat prevents
|
|
28
28
|
# the duplicate tool body from running again.
|
|
29
29
|
module ToolLoop
|
|
30
|
-
WARNING = "Repeated tool call detected. Change the approach or arguments before calling this tool again." # :nodoc:
|
|
31
|
-
FINAL_WARNING = "Final repeated tool call warning. Calling this tool again with identical arguments and result will stop the run." # :nodoc:
|
|
32
30
|
TRACKED_INVOCATION_LIMIT = 1_000 # :nodoc:
|
|
33
31
|
|
|
34
32
|
def self.included(base) # :nodoc:
|
|
@@ -120,7 +118,7 @@ module LittleGhost
|
|
|
120
118
|
newly_terminated = false
|
|
121
119
|
if repeat && repeat[:count] >= @tool_loop_terminate_at - 1
|
|
122
120
|
unless state[:termination]
|
|
123
|
-
state[:termination] = "
|
|
121
|
+
state[:termination] = render_framework_prompt("tools/loop/notices/termination", tool_name: tool_use.name)
|
|
124
122
|
newly_terminated = true
|
|
125
123
|
end
|
|
126
124
|
end
|
|
@@ -165,7 +163,9 @@ module LittleGhost
|
|
|
165
163
|
return Support::Callbacks.continue unless count == @tool_loop_warning_at || count == @tool_loop_terminate_at - 1
|
|
166
164
|
|
|
167
165
|
action = (count == @tool_loop_warning_at) ? :warn : :final_warning
|
|
168
|
-
warning = (
|
|
166
|
+
warning = render_framework_prompt(
|
|
167
|
+
(action == :warn) ? "tools/loop/notices/warning" : "tools/loop/notices/final_warning"
|
|
168
|
+
)
|
|
169
169
|
Instrumentation.publish(
|
|
170
170
|
:tool_loop,
|
|
171
171
|
operation_id: payload[:operation_id],
|