Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Batch Mode API / Headless #139

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

dkindlund
Copy link

This PR adds a new mode called "Batch Mode" to the computer-use-demo container. If you specify RUN_MODE=batch as an additional environment variable, the code will turn off Streamlit (on port 8080) and turn on the Batch Mode API (on port 8000).

This will allow users to submit asynchronous tasks via this endpoint:

curl -X POST http://localhost:8000/tasks \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Open the Firefox browser and navigate to google.com"
  }'

If the container is NOT running in Google Cloud Run, then this task will return immediately with a task_id. You can then fetch the status and results of the task through the /tasks endpoint, accordingly.

If the container IS running in Google Cloud Run, then this task will switch to synchronous processing. Only when the Agent fully completes, will the final results be returned to the client.

See the updated README.md for more details on these modes (and caveats).

Copy link
Collaborator

@x5a x5a left a comment

Choose a reason for hiding this comment

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

thanks for the contribution @dkindlund.

I'm glad you found this project useful. In its current state, this PR doesn't meet a few criteria we're looking for new features:

  • provider/environment agnostic: this only works with cloud run; the "local" behavior is substantively different than cloud run.
  • broad applicability: because the batch mode resets between inputs, you can't take multi-turn actions. as such, the utility is fairly limited for multi-turn agent use.

@@ -85,7 +86,8 @@ RUN eval "$(pyenv init -)" && \
ENV PATH="$HOME/.pyenv/shims:$HOME/.pyenv/bin:$PATH"

RUN python -m pip install --upgrade pip==23.1.2 setuptools==58.0.4 wheel==0.40.0 && \
python -m pip config set global.disable-pip-version-check true
python -m pip config set global.disable-pip-version-check true && \
python -m pip install fastapi uvicorn
Copy link
Collaborator

Choose a reason for hiding this comment

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

this should be covered by the subsequent line, correct?

Comment on lines +6 to +7
fastapi>=0.104.0
uvicorn[standard]>=0.24.0
Copy link
Collaborator

Choose a reason for hiding this comment

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

add starlette/pydantic given that they are now explicit imports

status: str
created_at: datetime
completed_at: Optional[datetime] = None
messages: list = []
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
messages: list = []
messages: list[BetaMessage] = []


class TaskRequest(BaseModel):
prompt: str
provider: APIProvider = APIProvider.VERTEX # Default to VERTEX since we're in Vertex environment
Copy link
Collaborator

Choose a reason for hiding this comment

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

not necessarily true for a general use case.

logger.info("👋 Batch API server shutting down")

# Add environment detection
IS_CLOUD_RUN = os.getenv('K_SERVICE') is not None # Cloud Run sets this automatically
Copy link
Collaborator

Choose a reason for hiding this comment

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

this would maybe better be called IS_STATELESS or something more generic to indicate that it's behind a load balancer.

Comment on lines +81 to +83
"pkill firefox-esr || true",
"pkill -f 'libreoffice' || true",
"pkill -f 'gedit' || true",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Comment on lines +199 to +203
def get_model(self) -> str:
"""Get the model name, using the default if none specified"""
if self.model is None:
return PROVIDER_TO_DEFAULT_MODEL_NAME[self.provider]
return self.model
Copy link
Collaborator

Choose a reason for hiding this comment

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

use model: str = field(default_factory=_get_model) instead to simplify

echo "✨ Computer Use Demo is ready!"
echo "➡️ Open http://localhost:8080 in your browser to begin"
# Check if we should start in batch mode
if [ "$RUN_MODE" = "batch" ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

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

from my perspective, batch mode and streamlit aren't necessarily mutually exclusive (although if both are supported simulatenously, there should probably be a shared lock)


tasks[task_id] = task_data

if IS_CLOUD_RUN:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand why, but if I wasn't familiar with cloud run, I'd find it surprising how different the cloud run implementation is from the local implementation.

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