Skip to content

Upgrade to Agentic Platform with Llama 3 ReAct agent, provisioning workflow, and enhanced tooling#8

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/upgrade-brain-to-llama-3
Draft

Upgrade to Agentic Platform with Llama 3 ReAct agent, provisioning workflow, and enhanced tooling#8
Copilot wants to merge 3 commits into
mainfrom
copilot/upgrade-brain-to-llama-3

Conversation

Copy link
Copy Markdown

Copilot AI commented Dec 10, 2025

Transforms the API from a passive remote control into an autonomous co-pilot using Llama 3 8B Instruct with proper ReAct (Reasoning + Acting) loop. Adds infrastructure provisioning workflow for "Day 0" setup compatible with Dashboard CI/CD, and expands agent tooling for deployment analysis.

Core Changes

ReAct Agent Implementation (src/index.ts)

  • Llama 3 8B Instruct (@cf/meta/llama-3-8b-instruct) with iterative reasoning (max 5 loops)
  • System prompt injects all MCP tools from registry
  • Parses JSON tool calls, executes internally, feeds results back to model
  • Validates tool call structure before execution
// Agent now handles: "Fix the error on the billing worker"
// Instead of: Waiting for manual button clicks
const aiResponse = await c.env.AI.run('@cf/meta/llama-3-8b-instruct', {
  messages: [
    { role: 'system', content: systemPrompt },
    { role: 'user', content: prompt }
  ]
});

Provisioning Workflow (src/workflows/provision.ts)

  • Creates Worker placeholder, then resources (KV, D1, R2, Queues) via Cloudflare API
  • Generates wrangler.jsonc snippets for copy-paste into repo
  • WorkflowEntrypoint handles long-running operations without HTTP timeouts
  • Placeholder Worker intentionally empty—Dashboard CI/CD applies bindings from generated config

New Agent Tools (src/mcp/agent-tools.ts)

  • get_deployment_logs: Fetches deployment history for failure analysis
  • get_rollback_info: Retrieves previous deployment metadata (note: actual rollback requires stored worker content)
  • get_provisioning_status: Checks workflow instance state

Configuration Flexibility (src/routes/flows/deploy.ts, src/types.ts)

  • Replaced hardcoded subdomain with env.WORKERS_DEV_SUBDOMAIN (3 locations)
  • Graceful handling for existing subdomains—logs warning, continues execution
  • Added PROVISIONING_WORKFLOW binding type

Technical Notes

  • Fixed pre-existing bug: blockConcurrencyWhile called on wrong object in consultation DO
  • Added TypeScript interfaces for workflow resource creation results
  • SDK type casts documented with explanations (API response structures vary)
  • Singleton-per-request pattern documented for Cloudflare client initialization
Original prompt

Context: I am building core-cloudflare-management-api, a comprehensive Worker that manages my Cloudflare infrastructure. I need to upgrade it from a simple API into an "Agentic Platform" that can autonomously manage resources.

Constraints:

CI/CD: Do not generate GitHub Actions files or perform Git operations. CI/CD is handled natively in the Cloudflare Dashboard. Focus workflows on provisioning the resources (Worker, DBs, KV) so they are ready for the Dash to take over.

Environment: This runs on Cloudflare Workers. Use @cloudflare/ai for the LLM and cloudflare:workflows for long-running tasks.

Tasks to Implement:

  1. Upgrade "Brain" to Llama 3 (Refactor src/index.ts)
    Replace the regex-based logic in the /agent endpoint with a proper ReAct (Reasoning + Acting) loop using @cloudflare/ai.

Model: Use @cf/meta/llama-3-8b-instruct.

Loop:

Inject available tools from src/mcp/index.ts into the system prompt.

Send user prompt to LLM.

If LLM requests a tool (JSON output), execute it internally.

Feed the result back to the LLM.

Return the final natural language response.

State: Use Ai binding from env.AI.

  1. Create "Provisioning Workflow" (New File: src/workflows/provision.ts)
    Implement a Cloudflare Workflow that acts as an "Infrastructure Easy Button" to prepare a project for Dashboard CI/CD.

Input: projectName, requestedBindings (e.g., ["kv", "d1"]).

Steps:

Create Worker: Create the script placeholder via API.

Create Resources: Loop through requested bindings and create the actual resources (D1 Database, KV Namespace) if they don't exist.

Generate Config: Create a wrangler.jsonc or toml configuration snippet that maps these new resources to the worker.

Report: Return the config snippet so I can copy-paste it into my repo before connecting it in the Dashboard.

  1. Add New Agent Tools (Refactor src/mcp/)
    Expose these functions as tools so the Agent can use them:

get_deployment_logs: Fetch logs from src/routes/api/workers.ts (or the underlying SDK) to analyze failures.

rollback_worker: Trigger a rollback for a specific worker.

get_provisioning_status: Check the status of the Provisioning Workflow.

  1. Fix Hardcoded Values (src/routes/flows/deploy.ts)
    Identify the hardcoded desiredSubdomain checks (around lines 46 and 147).

Refactor this to use env.WORKERS_DEV_SUBDOMAIN.

Add logic to gracefully handle "Subdomain already exists" errors (don't fail the flow).

  1. Optimization
    In src/index.ts, ensure Cloudflare client and Ai instances are initialized efficiently (e.g., using a singleton pattern or passing them through context) rather than re-instantiating heavy objects unnecessarily.

Explanation of the Strategy
Respecting Dash CI/CD: Instead of the agent trying to push code to GitHub (which conflicts with the Dash), the Provisioning Workflow focuses on the "Day 0" setup: creating the empty Worker, the Database, and the Bucket. It then hands you the wrangler.toml keys you need to commit. Once you commit that, the Dash CI/CD takes over.

Llama 3 Loop: This turns your API from a "remote control" (waiting for you to click buttons) into a "co-pilot" (you tell it "Fix the error on the billing worker," and it looks up logs, analyzes them, and suggests a fix).

Workflow vs. Route: Provisioning resources (D1, KV, R2) can take time. Moving this to a Workflow prevents HTTP timeouts and ensures that if one creation fails, it can retry automatically.


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

…w, and new agent tools

Co-authored-by: jmbish04 <26469722+jmbish04@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
🔵 In progress
View logs
core-cloudflare-management-api 0908fce Dec 10 2025, 05:32 AM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 10, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
core-cloudflare-management-api ae55e8f Dec 10 2025, 05:38 AM

…documentation

Co-authored-by: jmbish04 <26469722+jmbish04@users.noreply.github.com>
Copilot AI changed the title [WIP] Upgrade Brain to Llama 3 with ReAct loop Upgrade to Agentic Platform with Llama 3 ReAct agent, provisioning workflow, and enhanced tooling Dec 10, 2025
Copilot AI requested a review from jmbish04 December 10, 2025 05:40
@jmbish04
Copy link
Copy Markdown
Owner

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an impressive and substantial upgrade, transforming the API into a more autonomous and powerful platform. The introduction of the Llama 3-based ReAct agent is a major step forward, and the implementation of the reasoning loop with tool-use is well-executed. The new provisioning workflow is a fantastic addition, streamlining the 'Day 0' setup process for new projects. I also appreciate the thoughtful additions of new agent tools for deployment analysis and the refactoring to remove hardcoded subdomains, which significantly improves configuration flexibility and robustness. My review includes a few suggestions to enhance type safety, improve the reliability of the agent's JSON parsing, and make the workflow's configuration generation more robust.

Comment thread src/index.ts

// PATCHED: Token middleware fix for /api/tokens routes
const apiClientMiddleware = async (c: Context<{ Bindings: Env; Variables: Variables }>, next: Next) => {
const apiClientMiddleware = async (c: any, next: any) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The parameters for apiClientMiddleware were changed from specific Hono types to any. This is a regression in type safety that can hide potential bugs and makes the code harder to maintain. Please consider reverting to using the Context and Next types to leverage TypeScript's full benefits. You may need to import them from 'hono'.

Suggested change
const apiClientMiddleware = async (c: any, next: any) => {
const apiClientMiddleware = async (c: Context<{ Bindings: Env; Variables: Variables }>, next: Next) => {

Comment thread src/index.ts
Comment on lines +387 to +394
const jsonMatch = responseText.match(/\{[\s\S]*?\}(?=\s|$)/);
if (jsonMatch) {
const parsed = JSON.parse(jsonMatch[0]);
// Validate it has the expected structure for a tool call
if (parsed.tool && typeof parsed.tool === 'string') {
toolCall = parsed;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regular expression used to extract the JSON tool call is brittle. It can fail if the model includes surrounding text or wraps the JSON in markdown code fences, which is a common behavior. To make parsing more reliable, I recommend updating the system prompt to instruct the model to use markdown fences (e.g., ```json ... ```) and using a more robust regex that can handle both raw JSON and fenced JSON.

        const jsonMatch = responseText.match(/```json\s*([\s\S]*?)\s*```|(\{[\s\S]*\})/);
        if (jsonMatch) {
          // Use the first non-null capture group, which will be either the content of the JSON block or the raw JSON object.
          const jsonString = jsonMatch[1] || jsonMatch[2];
          const parsed = JSON.parse(jsonString);
          // Validate it has the expected structure for a tool call
          if (parsed.tool && typeof parsed.tool === 'string') {
            toolCall = parsed;
          }
        }

Comment on lines +274 to +327
result.wranglerConfig = await step.do('generate-config', async () => {
let config = `{\n "name": "${projectName}",\n "main": "src/index.ts",\n "compatibility_date": "2024-06-01",\n`;

// Add KV namespaces
if (result.resourcesCreated.kv.length > 0) {
config += ` "kv_namespaces": [\n`;
result.resourcesCreated.kv.forEach((kv, index) => {
const comma = index < result.resourcesCreated.kv.length - 1 ? ',' : '';
config += ` { "binding": "${kv.binding}", "id": "${kv.id}" }${comma}\n`;
});
config += ` ],\n`;
}

// Add D1 databases
if (result.resourcesCreated.d1.length > 0) {
config += ` "d1_databases": [\n`;
result.resourcesCreated.d1.forEach((d1, index) => {
const comma = index < result.resourcesCreated.d1.length - 1 ? ',' : '';
config += ` { "binding": "${d1.binding}", "database_name": "${d1.name}", "database_id": "${d1.id}" }${comma}\n`;
});
config += ` ],\n`;
}

// Add R2 buckets
if (result.resourcesCreated.r2.length > 0) {
config += ` "r2_buckets": [\n`;
result.resourcesCreated.r2.forEach((r2, index) => {
const comma = index < result.resourcesCreated.r2.length - 1 ? ',' : '';
config += ` { "binding": "${r2.binding}", "bucket_name": "${r2.name}" }${comma}\n`;
});
config += ` ],\n`;
}

// Add Queues
if (result.resourcesCreated.queues.length > 0) {
config += ` "queues": {\n`;
config += ` "producers": [\n`;
result.resourcesCreated.queues.forEach((queue, index) => {
const comma = index < result.resourcesCreated.queues.length - 1 ? ',' : '';
config += ` { "binding": "${queue.binding}", "queue": "${queue.name}" }${comma}\n`;
});
config += ` ]\n`;
config += ` },\n`;
}

// Remove trailing comma from last section more robustly
config = config.trimEnd();
if (config.endsWith(',')) {
config = config.slice(0, -1);
}
config += `\n}\n`;

return config;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Manually building a JSON string via concatenation is error-prone, especially with handling trailing commas. This can lead to invalid JSON. A safer and more maintainable approach is to construct a JavaScript object representing the configuration and then use JSON.stringify(config, null, 2) to generate a well-formed and correctly indented JSON string. This eliminates the risk of manual string manipulation errors.

    result.wranglerConfig = await step.do('generate-config', async () => {
      const config: any = {
        name: projectName,
        main: "src/index.ts",
        compatibility_date: "2024-06-01",
      };

      if (result.resourcesCreated.kv.length > 0) {
        config.kv_namespaces = result.resourcesCreated.kv.map(kv => ({
          binding: kv.binding,
          id: kv.id,
        }));
      }

      if (result.resourcesCreated.d1.length > 0) {
        config.d1_databases = result.resourcesCreated.d1.map(d1 => ({
          binding: d1.binding,
          database_name: d1.name,
          database_id: d1.id,
        }));
      }

      if (result.resourcesCreated.r2.length > 0) {
        config.r2_buckets = result.resourcesCreated.r2.map(r2 => ({
          binding: r2.binding,
          bucket_name: r2.name,
        }));
      }

      if (result.resourcesCreated.queues.length > 0) {
        config.queues = {
          producers: result.resourcesCreated.queues.map(queue => ({
            binding: queue.binding,
            queue: queue.name,
          })),
        };
      }

      return JSON.stringify(config, null, 2);
    });

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.

2 participants