mirror of
https://github.com/cheikh2shift/godex.git
synced 2026-10-23 11:22:18 -05:00
Enhance DYNO setup: update Dockerfile for Go installation, improve mock server responses, and streamline run script; add dummy provider configuration
This commit is contained in:
1 parent
7c5e85e116
commit
a817486d55
5 files changed
+118
-121
No files matched your search
@@ -10,3 +10,6 @@ workspace/
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
gtext/
|
||||
.git/
|
||||
.gtree
|
||||
+17
-7
@@ -8,10 +8,17 @@ RUN apk add --no-cache \
|
||||
bash \
|
||||
git \
|
||||
curl \
|
||||
go \
|
||||
musl-dev \
|
||||
gcc
|
||||
|
||||
# Install newer Go version
|
||||
RUN curl -fsSL https://go.dev/dl/go1.25.7.linux-amd64.tar.gz -o /tmp/go.tar.gz && \
|
||||
rm -rf /usr/local/go && \
|
||||
tar -C /usr/local -xzf /tmp/go.tar.gz && \
|
||||
rm /tmp/go.tar.gz
|
||||
|
||||
ENV PATH=/usr/local/go/bin:$PATH
|
||||
|
||||
# Build godex from source (build context is project root)
|
||||
WORKDIR /build
|
||||
COPY go.mod go.sum ./
|
||||
@@ -37,18 +44,19 @@ RUN apk add --no-cache \
|
||||
jq
|
||||
|
||||
# Install mock HTTP server dependencies
|
||||
RUN pip3 install --no-cache-dir flask requests
|
||||
RUN pip3 install --no-cache-dir --break-system-packages flask requests
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /dyno/logs /dyno/workspace /dyno/mocks
|
||||
RUN mkdir -p /dyno/logs /dyno/workspace /dyno/mocks /root/.godex
|
||||
|
||||
# Copy built binary
|
||||
COPY --from=builder /build/godex /usr/local/bin/godex
|
||||
|
||||
# Copy dyno scripts
|
||||
COPY dyno-mock-server.py /dyno/dyno-mock-server.py
|
||||
COPY dyno-entrypoint.sh /dyno/dyno-entrypoint.sh
|
||||
COPY dyno.env /dyno/dyno.env
|
||||
# Copy dyno scripts (from dyno/ folder in build context)
|
||||
COPY dyno/dyno-mock-server.py /dyno/dyno-mock-server.py
|
||||
COPY dyno/dyno-entrypoint.sh /dyno/dyno-entrypoint.sh
|
||||
COPY dyno/dyno.env /dyno/dyno.env
|
||||
COPY dyno/dummy-provider.yaml /root/.godex/providers.yaml
|
||||
|
||||
RUN chmod +x /dyno/*.sh /dyno/dyno-mock-server.py
|
||||
|
||||
@@ -61,6 +69,8 @@ ENV DYNO_MOCK_HTTP=true
|
||||
ENV DYNO_MOCK_FILEOPS=true
|
||||
ENV DYNO_MOCK_COMMANDS=true
|
||||
ENV DYNO_TRACKING_ENABLED=true
|
||||
ENV CODEX_CONFIG_PATH=/root/.godex/providers.yaml
|
||||
ENV CODEX_PROVIDER_NAME=dyno-mock
|
||||
|
||||
# Volume for outputs
|
||||
VOLUME ["/dyno/logs", "/dyno/workspace"]
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
providers:
|
||||
- name: dyno-mock
|
||||
type: ollama
|
||||
endpoint: http://localhost:8888/v1
|
||||
model: gpt-4
|
||||
api_key: dummy-key-for-testing
|
||||
default_provider: dyno-mock
|
||||
vision_enabled: true
|
||||
vision_cli_downloaded: true
|
||||
|
||||
+81
-104
@@ -3,10 +3,7 @@
|
||||
DYNO Mock Server - Intercepts all HTTP requests and returns mock responses
|
||||
to simulate tool calling for godex testing.
|
||||
|
||||
This server:
|
||||
- Logs all HTTP requests to tracking files
|
||||
- Returns dummy responses that simulate AI tool calling
|
||||
- Supports OpenAI-compatible API responses
|
||||
Handles both OpenAI and Ollama API formats.
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -63,103 +60,102 @@ class MockHandler(BaseHTTPRequestHandler):
|
||||
def get_mock_response(self, method, path, headers=None, body=None):
|
||||
"""Determine mock response based on request"""
|
||||
|
||||
# Check for tool result in request
|
||||
if body:
|
||||
try:
|
||||
req_data = json.loads(body)
|
||||
if 'messages' in req_data:
|
||||
last_msg = req_data['messages'][-1] if req_data['messages'] else {}
|
||||
if last_msg.get('role') == 'tool':
|
||||
return self.mock_tool_result_response(last_msg)
|
||||
except:
|
||||
pass
|
||||
# Ollama endpoints
|
||||
if '/api/chat' in path:
|
||||
return self.mock_ollama_chat(body)
|
||||
if '/api/show' in path:
|
||||
return self.mock_ollama_show(body)
|
||||
if '/api/generate' in path:
|
||||
return self.mock_ollama_generate(body)
|
||||
if '/api/tags' in path or '/tags' in path:
|
||||
return self.mock_ollama_tags()
|
||||
|
||||
# OpenAI/ChatGPT style endpoints
|
||||
# OpenAI endpoints
|
||||
if '/v1/chat/completions' in path or 'chat/completions' in path:
|
||||
return self.mock_chat_completion(body)
|
||||
|
||||
# OpenAI embeddings
|
||||
if '/v1/embeddings' in path or 'embeddings' in path:
|
||||
return self.mock_embeddings_response()
|
||||
|
||||
# Anthropic Claude
|
||||
if 'anthropic.com' in path or '/v1/messages' in path:
|
||||
return self.mock_anthropic_response(body)
|
||||
|
||||
# Default: generic success response
|
||||
return self.mock_default_response()
|
||||
|
||||
def mock_tool_result_response(self, tool_msg):
|
||||
"""Return mock response after tool execution"""
|
||||
tool_name = tool_msg.get('name', 'unknown')
|
||||
content = tool_msg.get('content', '')
|
||||
|
||||
logger.info(f"Mocking tool result for: {tool_name}")
|
||||
|
||||
response = {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": f"[Tool {tool_name} executed successfully. Result: {content[:200]}]"
|
||||
},
|
||||
"finish_reason": "stop"
|
||||
}],
|
||||
"usage": {
|
||||
"prompt_tokens": 100,
|
||||
"completion_tokens": 50,
|
||||
"total_tokens": 150
|
||||
}
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_chat_completion(self, body):
|
||||
"""Mock OpenAI chat completion - simulates tool calling"""
|
||||
def mock_ollama_chat(self, body):
|
||||
"""Mock Ollama chat response"""
|
||||
try:
|
||||
req_data = json.loads(body) if body else {}
|
||||
except:
|
||||
req_data = {}
|
||||
|
||||
# Check if this is a tool call request
|
||||
tools = req_data.get('tools', [])
|
||||
model = req_data.get('model', 'gpt-4')
|
||||
messages = req_data.get('messages', [])
|
||||
|
||||
# If tools provided and no tool call yet, simulate a tool call
|
||||
if tools and not any(m.get('tool_calls', []) for m in messages if isinstance(m, dict)):
|
||||
# Simulate tool calling behavior
|
||||
tool_name = tools[0].get('function', {}).get('name', 'example_tool')
|
||||
|
||||
response = {
|
||||
"id": "chatcmpl-mock-dyno-001",
|
||||
"object": "chat.completion",
|
||||
"created": int(datetime.now().timestamp()),
|
||||
"model": req_data.get('model', 'gpt-4'),
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"tool_calls": [{
|
||||
"id": "call_mock_001",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": tool_name,
|
||||
"arguments": json.dumps({"query": "mocked query for testing"})
|
||||
}
|
||||
}]
|
||||
},
|
||||
"finish_reason": "tool_calls"
|
||||
}],
|
||||
"usage": {
|
||||
"prompt_tokens": 50,
|
||||
"completion_tokens": 30,
|
||||
"total_tokens": 80
|
||||
}
|
||||
}
|
||||
return 200, response
|
||||
|
||||
# Regular chat response
|
||||
# Build a response
|
||||
response = {
|
||||
"id": "chatcmpl-mock-dyno-002",
|
||||
"model": model,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "[DYNO MOCK] This is a simulated AI response. All network calls are being tracked and mocked for testing purposes."
|
||||
},
|
||||
"done": True
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_ollama_show(self, body):
|
||||
"""Mock Ollama show response"""
|
||||
try:
|
||||
req_data = json.loads(body) if body else {}
|
||||
except:
|
||||
req_data = {}
|
||||
|
||||
model = req_data.get('name', 'gpt-4')
|
||||
|
||||
response = {
|
||||
"model": model,
|
||||
"modified_at": "2026-01-01T00:00:00Z",
|
||||
"size": 0,
|
||||
"digest": "mockdigest123"
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_ollama_generate(self, body):
|
||||
"""Mock Ollama generate response"""
|
||||
try:
|
||||
req_data = json.loads(body) if body else {}
|
||||
except:
|
||||
req_data = {}
|
||||
|
||||
model = req_data.get('model', 'gpt-4')
|
||||
|
||||
response = {
|
||||
"model": model,
|
||||
"response": "[DYNO MOCK] This is a simulated AI response.",
|
||||
"done": True
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_ollama_tags(self):
|
||||
"""Mock Ollama tags response"""
|
||||
response = {
|
||||
"models": [
|
||||
{
|
||||
"name": "gpt-4",
|
||||
"modified_at": "2026-01-01T00:00:00Z",
|
||||
"size": 0,
|
||||
"digest": "mockdigest123"
|
||||
}
|
||||
]
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_chat_completion(self, body):
|
||||
"""Mock OpenAI chat completion"""
|
||||
try:
|
||||
req_data = json.loads(body) if body else {}
|
||||
except:
|
||||
req_data = {}
|
||||
|
||||
response = {
|
||||
"id": "chatcmpl-mock-dyno-001",
|
||||
"object": "chat.completion",
|
||||
"created": int(datetime.now().timestamp()),
|
||||
"model": req_data.get('model', 'gpt-4'),
|
||||
@@ -167,7 +163,7 @@ class MockHandler(BaseHTTPRequestHandler):
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "[DYNO MOCK RESPONSE] This is a simulated AI response. All network calls are being tracked and mocked for testing purposes."
|
||||
"content": "[DYNO MOCK] This is a simulated AI response."
|
||||
},
|
||||
"finish_reason": "stop"
|
||||
}],
|
||||
@@ -196,25 +192,6 @@ class MockHandler(BaseHTTPRequestHandler):
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_anthropic_response(self, body):
|
||||
"""Mock Anthropic Claude response"""
|
||||
response = {
|
||||
"id": "msg_mock_001",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": "[DYNO MOCK RESPONSE] This is a simulated Claude response. All network calls are being tracked and mocked."
|
||||
}],
|
||||
"model": "claude-3-sonnet-20240229",
|
||||
"stop_reason": "end_turn",
|
||||
"usage": {
|
||||
"input_tokens": 50,
|
||||
"output_tokens": 50
|
||||
}
|
||||
}
|
||||
return 200, response
|
||||
|
||||
def mock_default_response(self):
|
||||
"""Default mock response"""
|
||||
response = {
|
||||
|
||||
+7
-10
@@ -14,12 +14,12 @@ log_error() { echo "[DYNO] ERROR: $1"; }
|
||||
build_dyno_image() {
|
||||
log_info "Building DYNO Docker image..."
|
||||
cd "$PROJECT_ROOT"
|
||||
build_dyno_image() {
|
||||
log_info "Building DYNO Docker image..."
|
||||
cd "$SCRIPT_DIR"
|
||||
docker build -t "$DOCKER_IMAGE" .
|
||||
docker build --no-cache -t "$DOCKER_IMAGE" -f "$SCRIPT_DIR/Dockerfile" .
|
||||
log_success "Built Docker image: $DOCKER_IMAGE"
|
||||
}
|
||||
|
||||
run_dyno() {
|
||||
local args="$@"
|
||||
log_info "Running godex in isolated DYNO container..."
|
||||
log_info "Arguments: $args"
|
||||
|
||||
@@ -39,11 +39,8 @@ build_dyno_image() {
|
||||
-e DYNO_TRACKING_ENABLED=true \
|
||||
-e DYNO_MOCK_HTTP=true \
|
||||
-e DYNO_MOCK_FILEOPS=true \
|
||||
-e DYNO_MOCK_COMMANDS=true \
|
||||
-e DYNO_LOG_DIR=/dyno/logs \
|
||||
-e GODEX_ARGS="$args" \
|
||||
"$DOCKER_IMAGE" \
|
||||
godex $args
|
||||
"$DOCKER_IMAGE"
|
||||
|
||||
log_success "DYNO execution completed"
|
||||
}
|
||||
@@ -61,13 +58,13 @@ show_logs() {
|
||||
|
||||
main() {
|
||||
local cmd="${1:-run}"
|
||||
shift || true
|
||||
|
||||
|
||||
case "$cmd" in
|
||||
build)
|
||||
build_dyno_image
|
||||
;;
|
||||
run)
|
||||
shift
|
||||
run_dyno "$@"
|
||||
;;
|
||||
logs)
|
||||
|
||||
Reference in new issue
Block a user