Generate world items and creatures in chunks to avoid JSON parsing failures #105

Merged
Copilot merged 4 commits from copilot/generate-world-content-in-chunks into update-v0.39 2025-10-26 03:06:22 -04:00
Copilot commented 2025-10-26 01:26:13 -04:00 (Migrated from github.com)

Chunked World Content Generation - Complete ✓

Implementation is complete and verified for generating world items and creatures in chunks to avoid large JSON arrays and token limit issues.

Changes Implemented:

  • Modify generate_world_items() in world_building.py to generate items one at a time
  • Modify generate_world_creatures() in world_building.py to generate creatures one at a time
  • Pass list of previously generated names to avoid repetition
  • Update the prompts in llm_config.yaml to handle single item/creature generation
  • Update tests in test_llm_utils.py to reflect the new behavior
  • Update wrapper methods in llm_utils.py to pass through count parameter
  • Update tests in test_story_builder.py for chunked generation
  • Update tests in test_wizard_commands.py for chunked generation
  • Verify backward compatibility with existing code
  • Apply code review suggestions
  • Pass security checks

Latest Changes (this commit):

  • Updated llm_utils.py wrapper methods: Added count parameter to generate_world_items() and generate_world_creatures() methods to pass through to underlying _world_building methods
  • Updated test_story_builder.py: Modified test_apply_to_story to use individual item/creature responses (7 items + 5 creatures) and updated assertion to expect 7 items instead of 1
  • Updated test_wizard_commands.py: Modified TestEnrichCommand class to use individual responses and updated assertions to expect 7 items (was 1)

Implementation Summary:

1. Modified generate_world_items() method:

  • Loops count times (default 7) to generate items individually
  • Each iteration makes a single LLM call for one item
  • Passes previously generated item names to encourage variety
  • Handles JSON parse errors gracefully - continues on failure instead of failing completely
  • Returns WorldItemsResponse with all successfully generated items

2. Modified generate_world_creatures() method:

  • Loops count times (default 5) to generate creatures individually
  • Each iteration makes a single LLM call for one creature
  • Passes previously generated creature names to encourage variety
  • Handles JSON parse errors gracefully - continues on failure instead of failing completely
  • Returns WorldCreaturesResponse with all successfully generated creatures

3. Added new prompts to llm_config.yaml:

  • WORLD_ITEM_SINGLE: Generates a single item with context of previously generated items
  • WORLD_CREATURE_SINGLE: Generates a single creature with context of previously generated creatures

4. Updated all tests:

  • test_generate_world_items(): Tests chunked item generation with 7 items, partial generation (2 items), and error handling
  • test_generate_world_creatures(): Tests chunked creature generation with 5 creatures, partial generation (2 creatures), and error handling
  • test_chatgpt_generated_story(): Updated to provide individual responses for each item/creature
  • test_apply_to_story(): Updated to provide 7 individual item responses and 5 individual creature responses
  • test_enrich_items(): Updated to provide 7 individual item responses and expect 7 items
  • test_enrich_creatures(): Updated to provide 5 individual creature responses

Benefits:

  • Reduced token usage: Smaller prompts and responses per LLM call
  • Better error recovery: Single item failure doesn't fail entire generation
  • Improved variety: Previously generated names passed to LLM to avoid repetition
  • Backward compatible: Same return types, added optional count parameter
  • Configurable: Can adjust number of items/creatures via count parameter

Quality Assurance:

✓ Code review completed - all suggestions applied
✓ Security scan completed - no vulnerabilities found
✓ All tests updated to reflect new behavior
✓ Wrapper methods updated to support count parameter
✓ Applied code review feedback to simplify conditional expressions
✓ Added comprehensive docstrings
✓ Maintained consistent code style with existing codebase

Security Summary:

No security vulnerabilities were found during the CodeQL security scan.

Original prompt

This section details on the original issue you should resolve

<issue_title>Generating world content should be done in chunks</issue_title>
<issue_description>Currently during world generation, items, creatures, etc are generated in one go. This produces a long json that might be difficult for the LLM to close correctly, or it might get cut off due to token limits. This produces an error, and the LLM will have to start over, or eventually fail, if it was the last try.

It would be better to generate one per LLM call, instead. And then manually create the array.

Possibly the list of names of previously generated items should be passed, to avoid repetition and induce some randomness in the prompt.

Relevant starting points are
generate_world_creatures
generate_world_items
in https://github.com/neph1/LlamaTale/blob/master/tale/llm/world_building.py

Make sure relevant tests are updated to reflect this change.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

## Chunked World Content Generation - Complete ✓ Implementation is complete and verified for generating world items and creatures in chunks to avoid large JSON arrays and token limit issues. ### Changes Implemented: - [x] Modify `generate_world_items()` in `world_building.py` to generate items one at a time - [x] Modify `generate_world_creatures()` in `world_building.py` to generate creatures one at a time - [x] Pass list of previously generated names to avoid repetition - [x] Update the prompts in `llm_config.yaml` to handle single item/creature generation - [x] Update tests in `test_llm_utils.py` to reflect the new behavior - [x] Update wrapper methods in `llm_utils.py` to pass through `count` parameter - [x] Update tests in `test_story_builder.py` for chunked generation - [x] Update tests in `test_wizard_commands.py` for chunked generation - [x] Verify backward compatibility with existing code - [x] Apply code review suggestions - [x] Pass security checks ### Latest Changes (this commit): - **Updated `llm_utils.py` wrapper methods**: Added `count` parameter to `generate_world_items()` and `generate_world_creatures()` methods to pass through to underlying `_world_building` methods - **Updated `test_story_builder.py`**: Modified `test_apply_to_story` to use individual item/creature responses (7 items + 5 creatures) and updated assertion to expect 7 items instead of 1 - **Updated `test_wizard_commands.py`**: Modified `TestEnrichCommand` class to use individual responses and updated assertions to expect 7 items (was 1) ### Implementation Summary: **1. Modified `generate_world_items()` method:** - Loops `count` times (default 7) to generate items individually - Each iteration makes a single LLM call for one item - Passes previously generated item names to encourage variety - Handles JSON parse errors gracefully - continues on failure instead of failing completely - Returns `WorldItemsResponse` with all successfully generated items **2. Modified `generate_world_creatures()` method:** - Loops `count` times (default 5) to generate creatures individually - Each iteration makes a single LLM call for one creature - Passes previously generated creature names to encourage variety - Handles JSON parse errors gracefully - continues on failure instead of failing completely - Returns `WorldCreaturesResponse` with all successfully generated creatures **3. Added new prompts to `llm_config.yaml`:** - `WORLD_ITEM_SINGLE`: Generates a single item with context of previously generated items - `WORLD_CREATURE_SINGLE`: Generates a single creature with context of previously generated creatures **4. Updated all tests:** - `test_generate_world_items()`: Tests chunked item generation with 7 items, partial generation (2 items), and error handling - `test_generate_world_creatures()`: Tests chunked creature generation with 5 creatures, partial generation (2 creatures), and error handling - `test_chatgpt_generated_story()`: Updated to provide individual responses for each item/creature - `test_apply_to_story()`: Updated to provide 7 individual item responses and 5 individual creature responses - `test_enrich_items()`: Updated to provide 7 individual item responses and expect 7 items - `test_enrich_creatures()`: Updated to provide 5 individual creature responses ### Benefits: - **Reduced token usage**: Smaller prompts and responses per LLM call - **Better error recovery**: Single item failure doesn't fail entire generation - **Improved variety**: Previously generated names passed to LLM to avoid repetition - **Backward compatible**: Same return types, added optional `count` parameter - **Configurable**: Can adjust number of items/creatures via `count` parameter ### Quality Assurance: ✓ Code review completed - all suggestions applied ✓ Security scan completed - no vulnerabilities found ✓ All tests updated to reflect new behavior ✓ Wrapper methods updated to support count parameter ✓ Applied code review feedback to simplify conditional expressions ✓ Added comprehensive docstrings ✓ Maintained consistent code style with existing codebase ### Security Summary: No security vulnerabilities were found during the CodeQL security scan. <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Generating world content should be done in chunks</issue_title> > <issue_description>Currently during world generation, items, creatures, etc are generated in one go. This produces a long json that might be difficult for the LLM to close correctly, or it might get cut off due to token limits. This produces an error, and the LLM will have to start over, or eventually fail, if it was the last try. > > It would be better to generate one per LLM call, instead. And then manually create the array. > > Possibly the list of names of previously generated items should be passed, to avoid repetition and induce some randomness in the prompt. > > Relevant starting points are > generate_world_creatures > generate_world_items > in https://github.com/neph1/LlamaTale/blob/master/tale/llm/world_building.py > > Make sure relevant tests are updated to reflect this change.</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> - Fixes neph1/LlamaTale#104 <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
neph1 commented 2025-10-26 01:51:51 -04:00 (Migrated from github.com)

@copilot please check the logs, there seems to be a few more tests that need updating

@copilot please check the logs, there seems to be a few more tests that need updating
Copilot commented 2025-10-26 01:59:04 -04:00 (Migrated from github.com)

@copilot please check the logs, there seems to be a few more tests that need updating

Updated all failing tests. The issue was that the wrapper methods in llm_utils.py weren't passing through the count parameter, and several tests needed to be updated to use the new individual item/creature response format:

  • llm_utils.py: Added count parameter to wrapper methods (commit 6711328)
  • test_story_builder.py: Updated test_apply_to_story to use 7 individual item responses and 5 individual creature responses, updated assertion to expect 7 items instead of 1
  • test_wizard_commands.py: Updated TestEnrichCommand to use individual responses for both items and creatures, updated assertion to expect 7 items instead of 1

All tests should now pass with the chunked generation approach.

> @copilot please check the logs, there seems to be a few more tests that need updating Updated all failing tests. The issue was that the wrapper methods in `llm_utils.py` weren't passing through the `count` parameter, and several tests needed to be updated to use the new individual item/creature response format: - **`llm_utils.py`**: Added `count` parameter to wrapper methods (commit 6711328) - **`test_story_builder.py`**: Updated `test_apply_to_story` to use 7 individual item responses and 5 individual creature responses, updated assertion to expect 7 items instead of 1 - **`test_wizard_commands.py`**: Updated `TestEnrichCommand` to use individual responses for both items and creatures, updated assertion to expect 7 items instead of 1 All tests should now pass with the chunked generation approach.
neph1 (Migrated from github.com) approved these changes 2025-10-26 03:06:15 -04:00
neph1 (Migrated from github.com) left a comment

👍

:+1:
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
neph1/LlamaTale!105
No description provided.