Skip to content

Bundle multi-agent assets into exportable agents suite#1

Draft
Codex wants to merge 19 commits intomainfrom
codex/extract-multi-agents-ai
Draft

Bundle multi-agent assets into exportable agents suite#1
Codex wants to merge 19 commits intomainfrom
codex/extract-multi-agents-ai

Conversation

@Codex
Copy link

@Codex Codex AI commented Mar 6, 2026

The repo needed a single, portable bundle containing all existing multi-agent/automation/AI artifacts for downstream migration.

  • Created export bundle: Added agents-suite/ consolidating backend/ai, platforms/_shared, platforms/automation-platform, platforms/automation, platforms/eco-superai, platforms/ng-era-platforms, and Agent_Actions.zip to simplify extraction.
  • Documented contents: New agents-suite/README.md outlines what’s included, source paths, and migration tips (e.g., keep _shared with automation-platform for protocol imports).

Example layout:

agents-suite/
├── backend-ai/
├── automation-platform/
├── automation/
├── _shared/
├── eco-superai/
├── ng-era-platforms/
├── Agent_Actions.zip
└── README.md

@Codex Codex AI changed the title [WIP] Extract existing multi-agent automation components Bundle multi-agent assets into exportable agents suite Mar 6, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR bundles all existing multi-agent, automation, and AI artifacts into a single portable agents-suite/ directory for downstream migration.

Changes:

  • Added agents-suite/ directory consolidating backend AI, shared kernel, automation platform, automation pipelines, eco-superai, and ng-era-platforms assets
  • Added agents-suite/README.md documenting contents, source paths, and migration tips

Reviewed changes

Copilot reviewed 90 out of 2750 changed files in this pull request and generated 10 comments.

File Description
agents-suite/README.md Top-level documentation for the bundle layout and migration guidance
agents-suite/_shared/** Shared kernel: sandbox, container, environment, protocols
agents-suite/automation-platform/** Multi-agent pipeline orchestrator, domain entities, engines, and tests
agents-suite/automation/instant/** Instant execution scripts, configs, docs, and legacy artifacts

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"-H",
"Content-Type: application/json",
"-d",
str(config).replace("'", '"'),
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Using Python's str() on a dict and then replacing single quotes with double quotes does not produce valid JSON. For example, Python's True/False/None will be serialized as True/False/None instead of true/false/null, and string values containing apostrophes will be mangled. Use json.dumps(config) instead to produce a properly serialized JSON string.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +29
- id: "load_unified_pipeline"
action: "mcp.pipeline.load"
description: "Load the unified pipeline to ensure MCP methodology is applied."
inputs:
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The description field on lines 28, 36, 53, and 70 is consistently mis-indented to be at the same level as the - id: list marker rather than being a child property of the step. This makes description a sibling of the step object rather than a property of it, and most YAML parsers will either error or silently ignore it. All description fields should be indented to align with action, inputs, etc.

Copilot uses AI. Check for mistakes.
codevantaceo and others added 9 commits March 6, 2026 20:02
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…n.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…n.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@codevantaceo codevantaceo requested a review from Copilot March 6, 2026 12:04
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 90 out of 2753 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# Move the file
echo -e "${GREEN}✓ Moving${NC} $file -> $dest$filename"
mv "$file" "$dest$filename"
((MOVED_COUNT++))
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The MOVED_COUNT increment is inside a while read loop fed by a subshell pipeline (find ... | ... | while read). In bash, pipe components run in subshells, so MOVED_COUNT increments are lost and the variable always remains 0 in the parent shell. The final summary will always report 0 moved files. To fix this, either use process substitution (while read file; do ... done < <(find ...)) or redirect with a here-string to keep the loop in the current shell.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +2
# @ECO-governed
# @ECO-layer: GL00-09
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

This file has a .json extension but begins with #-prefixed comment lines, which are not valid JSON. Any JSON parser (including jq, Python's json.loads, etc.) will fail to parse this file. The governance header comments should either be removed, moved to a companion .yaml metadata file, or placed inside the JSON structure as a "_governance" key.

Copilot uses AI. Check for mistakes.
codevantaceo and others added 6 commits March 6, 2026 20:14
…ig.yaml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…9-000725.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…25.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…GGERS-IMPLEMENTATION-REPORT.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…es/execution_engine.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@codevantaceo codevantaceo requested a review from Copilot March 6, 2026 12:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 90 out of 2753 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

#
# GL Unified Architecture Governance Framework Activated

#!/usr/bin/env python3
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The shebang line #!/usr/bin/env python3 appears on line 9, after several comment header lines. A shebang is only interpreted by the OS when it is the very first line of the file (line 1). As the file currently begins with ECO governance header comments, the shebang is ignored. Move it to line 1 if the script needs to be directly executable.

Copilot uses AI. Check for mistakes.
#
# GL Unified Architecture Governance Framework Activated

#!/usr/bin/env python3
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Same issue as in instant_archiver_v1.py: the shebang #!/usr/bin/env python3 is on line 9 instead of line 1. The OS will not interpret it as a shebang, rendering the script non-directly executable. Move it to line 1 if that is the intent.

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +175
This method may mutate ``task.mode`` in place. If the task's mode is
``ExecutionMode.STANDARD`` and a command is present, a more specific
mode is auto-selected and written back to the provided ``Task`` instance
before execution.
"""
if task.mode == ExecutionMode.STANDARD and task.command:
# Auto-select a more specific mode (intentionally mutates task.mode)
task.mode = _estimate_mode(task)

sla = _SLA_CEILINGS[task.mode]

async with self._semaphore:
task.mark_running()
self._status = EngineStatus.RUNNING

self._events.append(
TaskDispatched(
task_id=task.id,
command=task.command,
agent_id="engine",
mode=task.mode.value,
)
)

start = time.monotonic()
try:
result = await asyncio.wait_for(self._handler(task), timeout=sla)
elapsed = time.monotonic() - start
task.mark_completed(result)
self._tasks_run += 1

self._events.append(
TaskCompleted(
task_id=task.id,
success=True,
duration_seconds=elapsed,
result=result,
)
)
except asyncio.TimeoutError:
elapsed = time.monotonic() - start
task.mark_timed_out()
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise TaskTimeoutError(task.id, sla)
except Exception as exc:
elapsed = time.monotonic() - start
task.mark_failed(str(exc))
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

execute_task silently mutates the caller's Task object by overwriting task.mode. This is a side-effect that callers are unlikely to anticipate, and the docstring note only partially mitigates this. The method should either work on a copy of the task, or accept an explicit mode parameter, to avoid surprising callers who inspect task.mode after the call and observe an unexpected value.

Suggested change
This method may mutate ``task.mode`` in place. If the task's mode is
``ExecutionMode.STANDARD`` and a command is present, a more specific
mode is auto-selected and written back to the provided ``Task`` instance
before execution.
"""
if task.mode == ExecutionMode.STANDARD and task.command:
# Auto-select a more specific mode (intentionally mutates task.mode)
task.mode = _estimate_mode(task)
sla = _SLA_CEILINGS[task.mode]
async with self._semaphore:
task.mark_running()
self._status = EngineStatus.RUNNING
self._events.append(
TaskDispatched(
task_id=task.id,
command=task.command,
agent_id="engine",
mode=task.mode.value,
)
)
start = time.monotonic()
try:
result = await asyncio.wait_for(self._handler(task), timeout=sla)
elapsed = time.monotonic() - start
task.mark_completed(result)
self._tasks_run += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=True,
duration_seconds=elapsed,
result=result,
)
)
except asyncio.TimeoutError:
elapsed = time.monotonic() - start
task.mark_timed_out()
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise TaskTimeoutError(task.id, sla)
except Exception as exc:
elapsed = time.monotonic() - start
task.mark_failed(str(exc))
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise
This method temporarily mutates ``task.mode`` during execution. If the
task's mode is ``ExecutionMode.STANDARD`` and a command is present, a
more specific mode is auto-selected and applied to the provided
``Task`` instance while it is being processed. The original mode is
restored before this method returns.
"""
original_mode = task.mode
selected_mode = original_mode
if original_mode == ExecutionMode.STANDARD and task.command:
# Auto-select a more specific mode (applies during execution only)
selected_mode = _estimate_mode(task)
sla = _SLA_CEILINGS[selected_mode]
async with self._semaphore:
# Ensure that internal execution sees the selected mode, but do not
# leave the caller's Task instance permanently mutated.
if selected_mode is not original_mode:
task.mode = selected_mode
try:
task.mark_running()
self._status = EngineStatus.RUNNING
self._events.append(
TaskDispatched(
task_id=task.id,
command=task.command,
agent_id="engine",
mode=selected_mode.value,
)
)
start = time.monotonic()
try:
result = await asyncio.wait_for(self._handler(task), timeout=sla)
elapsed = time.monotonic() - start
task.mark_completed(result)
self._tasks_run += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=True,
duration_seconds=elapsed,
result=result,
)
)
except asyncio.TimeoutError:
elapsed = time.monotonic() - start
task.mark_timed_out()
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise TaskTimeoutError(task.id, sla)
except Exception as exc:
elapsed = time.monotonic() - start
task.mark_failed(str(exc))
self._tasks_failed += 1
self._events.append(
TaskCompleted(
task_id=task.id,
success=False,
duration_seconds=elapsed,
)
)
raise
finally:
# Restore the original mode so callers do not observe a
# permanently mutated Task.mode after execution.
task.mode = original_mode

Copilot uses AI. Check for mistakes.
Comment on lines +97 to +103
await self._semaphore.acquire()
try:
agent = self._acquire_agent()
if agent is None:
# Shouldn't happen with proper semaphore sizing, but be defensive
self._semaphore.release()
raise AgentPoolExhaustedError(self._agent_type.value, self._pool_size)
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

When _acquire_agent() returns None on line 100, the semaphore is released manually on line 102 before raising the exception. However, because the acquire() was called outside the inner try block (line 97), and the explicit release() then raises, the outer try/except blocks (lines 146-149) will re-raise the AgentPoolExhaustedError without a second release. This is handled correctly. However, if an exception occurs between line 97 and line 118 (e.g., in agent.assign_task) that is not AgentPoolExhaustedError, the semaphore acquired on line 97 will never be released because the finally block for self._semaphore.release() is inside the inner try (line 141), which would not be reached. To ensure the semaphore is always released, move self._semaphore.release() to a finally block that wraps the entire body after await self._semaphore.acquire().

Copilot uses AI. Check for mistakes.
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.

5 participants