Skip to content

Feature/scheduled agents update#8

Merged
AndreiDrang merged 11 commits into
mainfrom
feature/scheduled-agents-update
Jun 27, 2026
Merged

Feature/scheduled agents update#8
AndreiDrang merged 11 commits into
mainfrom
feature/scheduled-agents-update

Conversation

@AndreiDrang

Copy link
Copy Markdown
Owner

No description provided.

AndreiDrang and others added 8 commits June 27, 2026 04:30
Adds detailed plan for implementing scheduled (cron-based) AGENTS.md file updates:
- Flexible YAML configuration (.zai-scheduled.yml)
- GitHub schedule event support
- Extensible architecture for future scheduled tasks
- PR creation with changes
- Configuration examples and workflow setup

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Implements scheduled (cron-based) AGENTS.md file updates:

- Add schedule event support in events.js
- Create scheduled-config.js for YAML configuration loading
- Create scheduled.js handler with update-agents task
- Add /zai update-agents manual command
- Update action.yml with new inputs (ZAI_SCHEDULED_ENABLED, ZAI_SCHEDULED_CONFIG_PATH)

Features:
- Flexible YAML configuration (.zai-scheduled.yml)
- Fetches content from configurable Gist URL
- Creates PR with changes when files are updated
- Extensible architecture for future scheduled tasks
- Manual command for testing

Consumer repos need to:
1. Create .zai-scheduled.yml configuration
2. Create .github/workflows/zai-scheduled.yml workflow
3. Configure GITHUB_TOKEN with write permissions

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
…branch names

Changes based on user requirements:
1. Gist URL configurable via ZAI_AGENTS_GIST_URL environment variable
   - Added getGistUrl() function with priority: task config > defaults > env var
   - Removed hardcoded URLs from implementation
   - Added ZAI_AGENTS_GIST_URL to action.yml inputs

2. Branch naming format: zai-scheduled/yyyy.mm.dd_hh.mm
   - Changed from timestamp-based to date-based format
   - More human-readable and easier to identify

3. Multiple files support: Confirmed and documented

4. Fork support: Confirmed working with fork's API key
   - Uses provided apiKey parameter, works everywhere

Updated documentation:
- .zai-scheduled.yml.template with env var example
- plans/scheduled-agents-update.md with answers and implementation notes

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Add two example workflow files:
- zai-agents-update.yml: Production-ready workflow running Mondays
- zai-agents-init-example.yml: Example with detailed comments

Both workflows:
- Run on schedule (every Monday at midnight UTC)
- Support manual triggering via workflow_dispatch
- Configure ZAI_AGENTS_GIST_URL for gist-based AGENTS.md updates
- Use scheduled tasks feature

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Adds working scheduled tasks configuration for this repository:
- Weekly AGENTS.md updates on Monday at midnight UTC
- Targets all AGENTS.md files in the repository
- Uses ZAI_AGENTS_GIST_URL environment variable for Gist URL
- Creates PR with clear documentation

This configuration will be used by the scheduled workflows to:
1. Fetch content from the configured Gist URL
2. Update all specified AGENTS.md files
3. Create a PR if changes are detected

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
- Added gist_url to defaults section with raw GitHub URL
- Updated comments to explain priority order
- Gist URL: https://gist.githubusercontent.com/AndreiDrang/1580ae796fe56074b600cee6352a5f14/raw

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Updated handleUpdateAgentsTask to:
- Execute the command from Gist via Z.ai API
- Support both /zai commands and direct prompts
- Fall back to raw Gist content if execution fails

Added new functions:
- executeCommandAndGetContent() - Executes command and returns generated content
- callZaiApiWithRetry() - Robust Z.ai API caller with retry logic
- buildCommandPrompt() - Formats /zai commands for API
- buildAgentsGenerationPrompt() - Formats direct prompts for API

Updated .zai-scheduled.yml:
- Added gist_url to defaults with raw GitHub URL
- Updated comments to explain command execution flow
- Clarified that Gist should contain a command to generate content

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@github-actions

github-actions Bot commented Jun 27, 2026

Copy link
Copy Markdown

Z.ai Code Review

## 🔍 Review Summary
This PR introduces a robust scheduled task feature that allows the bot to autonomously generate and update AGENTS.md files based on Gist content and AI prompts. The architecture is generally well-thought-out, featuring modular configuration handling and extensible task handlers. However, the implementation contains critical runtime errors related to variable scope and flawed error handling logic that poses a risk to data integrity.

## 🚨 Critical Issues & Bugs

  • src/lib/handlers/scheduled.js: Critical Runtime Error (Undefined logger)
    Several exported utility functions (fetchFromUrl, callZaiApiWithRetry, createPR) attempt to use a logger variable. However, logger is defined as a local constant within handleScheduledEvent and is not accessible in the module scope where these functions are defined. This will cause an immediate ReferenceError crash when any scheduled task runs.

    • Fix: Pass logger as a parameter to these functions or wrap them in a class/context.
    // Example Fix for createPR
    async function createPR(octokit, owner, repo, { title, body, base, files, commitMessage }, logger) { // Add logger arg
      // ... inside function
      logger.info(`Creating branch ${branchName} from ${base}`);
      // ...
    }
  • src/lib/handlers/scheduled.js: Unsafe Error Handling Leading to Data Loss
    In parseFileUpdatesFromResponse (inside handleUpdateAgentsTask), the code catches errors when fetching existing file content. If a fetch fails (e.g., network blip, API rate limit), it defaults isNew: true and assumes the file does not exist. This logic is dangerous as it may attempt to overwrite existing files or create duplicates based on transient failures rather than actual absence.

    // Current risky code:
    } catch (error) {
      // If this is a 500 error, file might still exist!
      fileUpdates.push({ file: filePath, oldContent: null, newContent, changed: true, isNew: true });
    }
    • Fix: Distinguish between 404 (Not Found) and other errors. Only assume isNew: true on 404.
  • src/lib/config/scheduled-config.js: Incorrect Environment Variable Lookup
    The function loadScheduledConfig attempts to read process.env.ZAI_SCHEDULED_CONFIG_PATH. In GitHub Actions, inputs defined in action.yml are mapped to process.env.INPUT_<NAME>. Accessing the undecorated variable name will likely return undefined, forcing the code to always use the hardcoded default .zai-scheduled.yml and ignoring user inputs.

    • Fix: Use core.getInput('ZAI_SCHEDULED_CONFIG_PATH') or pass the path explicitly from src/index.js.
  • src/lib/handlers/scheduled.js: Branch Creation Race Condition
    The branch naming strategy uses minute-level precision (YYYY.MM.DD_HH.MM). If the bot runs multiple times within the same minute (e.g., manual trigger during a scheduled run), the second execution will catch the 422 error (branch exists) and reuse the branch. This leads to a race condition where two processes attempt to commit to the same branch simultaneously, resulting in an undefined final state and potential commit conflicts.

    • Fix: Include milliseconds or a UUID in the branch name to ensure uniqueness.

## 💡 Suggestions & Best Practices

  • src/lib/handlers/scheduled.js: Modularization
    The file is over 1000 lines long and mixes concerns (HTTP fetching, GitHub API interactions, AI logic, and Git operations). Consider splitting this into:

    1. utils/http.js (for fetchFromUrl, callZaiApiWithRetry)
    2. utils/github.js (for createPR, updateFileInRepo)
    3. tasks/update-agents.js (specific logic for the agents task)
  • src/index.js: Dependency Injection Consistency
    The update-agents command case manually requires handleUpdateAgentsTask and constructs mocks for dependencies (fetchFile, createPullRequest). This creates tight coupling and makes testing difficult. Consider refactoring handleUpdateAgentsTask to accept a generic context object (similar to how the scheduled handler does it) rather than constructing it ad-hoc in the switch statement.

  • src/lib/handlers/scheduled.js: Use Action-Specific HTTP Libraries
    Instead of using the raw node:https module, utilize @actions/http-client or @actions/core's built-in utilities if available. This provides better proxy support, user-agent handling, and retry logic consistent with the GitHub Actions environment.

  • src/lib/handlers/scheduled.js: Input Validation
    The fetchFromUrl function accepts arbitrary URLs. While the bot runs on user repos, it's good practice to validate that the URL protocol is https and potentially restrict domains if the intention is only to support Gists, to prevent SSRF (Server-Side Request Forgery) vulnerabilities.

## 📊 Final Assessment

  • Rating: Normal
  • Reason: The feature architecture is solid and the code follows the project's existing patterns, but the PR introduces critical runtime errors (variable scope issues) and risky logic in error handling that will lead to crashes and potential data corruption. These must be resolved before merging.

AndreiDrang and others added 3 commits June 27, 2026 05:11
- Add auto_discover_files configuration option to .zai-scheduled.yml
- Implement executeCommandAndGetFileUpdates() for structured JSON response parsing
- Add processManualFiles() helper for manual file list mode
- Add buildAutoDiscoveryPrompt() to instruct AI to return JSON file map
- Add parseFileUpdatesFromResponse() and extractFilesFromText() for response handling
- Update template with documentation for both modes
- Remove hardcoded file list from default config, use auto-discovery

In auto-discovery mode, the command from Gist scans the entire repository
and returns a JSON structure with all AGENTS.md files to create/update.
The bot then processes each file individually, creating a PR with all changes.

Fallback to manual mode if auto-discovery returns no results.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
- Remove auto_discover_files flag - auto-discovery is now mandatory
- Remove processManualFiles() function - no longer needed
- Remove all manual file list configuration options
- Simplify handler to only support structured JSON response from commands
- Update config and template to reflect single mode of operation
- Command MUST return JSON with files array for AGENTS.md updates

The bot now ONLY supports the auto-discovery workflow where the command
from the Gist scans the repository and returns JSON with all AGENTS.md
files to create/update.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
@AndreiDrang AndreiDrang merged commit 4fd6a9f into main Jun 27, 2026
5 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant