@1claw/cli 0.37.0 → 0.37.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundled-templates/registry.yaml +62 -0
- package/dist/bundled-templates/templates/agentkit/Dockerfile +28 -0
- package/dist/bundled-templates/templates/agentkit/README.md +36 -0
- package/dist/bundled-templates/templates/agentkit/agent.py +83 -0
- package/dist/bundled-templates/templates/agentkit/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/agentkit/requirements.txt +5 -0
- package/dist/bundled-templates/templates/agentkit/template.yaml +24 -0
- package/dist/bundled-templates/templates/agno/Dockerfile +28 -0
- package/dist/bundled-templates/templates/agno/README.md +36 -0
- package/dist/bundled-templates/templates/agno/agent.py +86 -0
- package/dist/bundled-templates/templates/agno/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/agno/requirements.txt +2 -0
- package/dist/bundled-templates/templates/agno/template.yaml +24 -0
- package/dist/bundled-templates/templates/coder/Dockerfile +28 -0
- package/dist/bundled-templates/templates/coder/README.md +36 -0
- package/dist/bundled-templates/templates/coder/agent.py +119 -0
- package/dist/bundled-templates/templates/coder/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/coder/requirements.txt +4 -0
- package/dist/bundled-templates/templates/coder/template.yaml +24 -0
- package/dist/bundled-templates/templates/crewai/Dockerfile +28 -0
- package/dist/bundled-templates/templates/crewai/README.md +29 -0
- package/dist/bundled-templates/templates/crewai/agent.py +109 -0
- package/dist/bundled-templates/templates/crewai/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/crewai/requirements.txt +3 -0
- package/dist/bundled-templates/templates/crewai/template.yaml +24 -0
- package/dist/bundled-templates/templates/elizaos/Dockerfile +31 -0
- package/dist/bundled-templates/templates/elizaos/README.md +36 -0
- package/dist/bundled-templates/templates/elizaos/agent.ts +100 -0
- package/dist/bundled-templates/templates/elizaos/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/elizaos/package.json +18 -0
- package/dist/bundled-templates/templates/elizaos/template.yaml +25 -0
- package/dist/bundled-templates/templates/elizaos/tsconfig.json +12 -0
- package/dist/bundled-templates/templates/langchain/Dockerfile +28 -0
- package/dist/bundled-templates/templates/langchain/README.md +37 -0
- package/dist/bundled-templates/templates/langchain/agent.py +115 -0
- package/dist/bundled-templates/templates/langchain/entrypoint.sh +36 -0
- package/dist/bundled-templates/templates/langchain/requirements.txt +4 -0
- package/dist/bundled-templates/templates/langchain/template.yaml +24 -0
- package/dist/bundled-templates/templates/llamaindex/Dockerfile +28 -0
- package/dist/bundled-templates/templates/llamaindex/README.md +36 -0
- package/dist/bundled-templates/templates/llamaindex/agent.py +97 -0
- package/dist/bundled-templates/templates/llamaindex/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/llamaindex/requirements.txt +3 -0
- package/dist/bundled-templates/templates/llamaindex/template.yaml +24 -0
- package/dist/bundled-templates/templates/mastra/Dockerfile +31 -0
- package/dist/bundled-templates/templates/mastra/README.md +31 -0
- package/dist/bundled-templates/templates/mastra/agent.ts +112 -0
- package/dist/bundled-templates/templates/mastra/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/mastra/package.json +17 -0
- package/dist/bundled-templates/templates/mastra/template.yaml +25 -0
- package/dist/bundled-templates/templates/mastra/tsconfig.json +12 -0
- package/dist/bundled-templates/templates/openai-agents/Dockerfile +28 -0
- package/dist/bundled-templates/templates/openai-agents/README.md +29 -0
- package/dist/bundled-templates/templates/openai-agents/agent.py +98 -0
- package/dist/bundled-templates/templates/openai-agents/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/openai-agents/requirements.txt +3 -0
- package/dist/bundled-templates/templates/openai-agents/template.yaml +24 -0
- package/dist/bundled-templates/templates/pydantic-ai/Dockerfile +28 -0
- package/dist/bundled-templates/templates/pydantic-ai/README.md +36 -0
- package/dist/bundled-templates/templates/pydantic-ai/agent.py +110 -0
- package/dist/bundled-templates/templates/pydantic-ai/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/pydantic-ai/requirements.txt +2 -0
- package/dist/bundled-templates/templates/pydantic-ai/template.yaml +24 -0
- package/dist/bundled-templates/templates/smolagents/Dockerfile +28 -0
- package/dist/bundled-templates/templates/smolagents/README.md +36 -0
- package/dist/bundled-templates/templates/smolagents/agent.py +97 -0
- package/dist/bundled-templates/templates/smolagents/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/smolagents/requirements.txt +2 -0
- package/dist/bundled-templates/templates/smolagents/template.yaml +24 -0
- package/dist/bundled-templates/templates/typescript-sdk/Dockerfile +31 -0
- package/dist/bundled-templates/templates/typescript-sdk/README.md +29 -0
- package/dist/bundled-templates/templates/typescript-sdk/agent.ts +130 -0
- package/dist/bundled-templates/templates/typescript-sdk/entrypoint.sh +34 -0
- package/dist/bundled-templates/templates/typescript-sdk/package.json +17 -0
- package/dist/bundled-templates/templates/typescript-sdk/template.yaml +25 -0
- package/dist/bundled-templates/templates/typescript-sdk/tsconfig.json +12 -0
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +6 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/proxy.d.ts.map +1 -1
- package/dist/src/commands/proxy.js +4 -0
- package/dist/src/commands/proxy.js.map +1 -1
- package/dist/src/commands/spawn.d.ts.map +1 -1
- package/dist/src/commands/spawn.js +5 -1
- package/dist/src/commands/spawn.js.map +1 -1
- package/dist/src/lib/module-deprecation.d.ts +8 -0
- package/dist/src/lib/module-deprecation.d.ts.map +1 -0
- package/dist/src/lib/module-deprecation.js +15 -0
- package/dist/src/lib/module-deprecation.js.map +1 -0
- package/dist/src/lib/paths.d.ts +5 -4
- package/dist/src/lib/paths.d.ts.map +1 -1
- package/dist/src/lib/paths.js +27 -13
- package/dist/src/lib/paths.js.map +1 -1
- package/dist/src/registry.yaml +62 -0
- package/dist/src/templates/agentkit/Dockerfile +34 -0
- package/dist/src/templates/agentkit/README.md +36 -0
- package/dist/src/templates/agentkit/agent.py +83 -0
- package/dist/src/templates/agentkit/entrypoint.sh +34 -0
- package/dist/src/templates/agentkit/requirements.txt +5 -0
- package/dist/src/templates/agentkit/template.yaml +24 -0
- package/dist/src/templates/agno/Dockerfile +34 -0
- package/dist/src/templates/agno/README.md +36 -0
- package/dist/src/templates/agno/agent.py +86 -0
- package/dist/src/templates/agno/entrypoint.sh +34 -0
- package/dist/src/templates/agno/requirements.txt +2 -0
- package/dist/src/templates/agno/template.yaml +24 -0
- package/dist/src/templates/coder/Dockerfile +34 -0
- package/dist/src/templates/coder/README.md +36 -0
- package/dist/src/templates/coder/agent.py +119 -0
- package/dist/src/templates/coder/entrypoint.sh +34 -0
- package/dist/src/templates/coder/requirements.txt +4 -0
- package/dist/src/templates/coder/template.yaml +24 -0
- package/dist/src/templates/crewai/Dockerfile +34 -0
- package/dist/src/templates/crewai/README.md +29 -0
- package/dist/src/templates/crewai/agent.py +109 -0
- package/dist/src/templates/crewai/entrypoint.sh +34 -0
- package/dist/src/templates/crewai/requirements.txt +3 -0
- package/dist/src/templates/crewai/template.yaml +24 -0
- package/dist/src/templates/elizaos/Dockerfile +31 -0
- package/dist/src/templates/elizaos/README.md +36 -0
- package/dist/src/templates/elizaos/agent.ts +100 -0
- package/dist/src/templates/elizaos/entrypoint.sh +34 -0
- package/dist/src/templates/elizaos/package.json +18 -0
- package/dist/src/templates/elizaos/template.yaml +25 -0
- package/dist/src/templates/elizaos/tsconfig.json +12 -0
- package/dist/src/templates/fetcher.d.ts.map +1 -1
- package/dist/src/templates/fetcher.js +34 -15
- package/dist/src/templates/fetcher.js.map +1 -1
- package/dist/src/templates/langchain/Dockerfile +34 -0
- package/dist/src/templates/langchain/README.md +37 -0
- package/dist/src/templates/langchain/agent.py +115 -0
- package/dist/src/templates/langchain/entrypoint.sh +36 -0
- package/dist/src/templates/langchain/requirements.txt +4 -0
- package/dist/src/templates/langchain/template.yaml +24 -0
- package/dist/src/templates/llamaindex/Dockerfile +34 -0
- package/dist/src/templates/llamaindex/README.md +36 -0
- package/dist/src/templates/llamaindex/agent.py +97 -0
- package/dist/src/templates/llamaindex/entrypoint.sh +34 -0
- package/dist/src/templates/llamaindex/requirements.txt +3 -0
- package/dist/src/templates/llamaindex/template.yaml +24 -0
- package/dist/src/templates/mastra/Dockerfile +31 -0
- package/dist/src/templates/mastra/README.md +31 -0
- package/dist/src/templates/mastra/agent.ts +112 -0
- package/dist/src/templates/mastra/entrypoint.sh +34 -0
- package/dist/src/templates/mastra/package.json +17 -0
- package/dist/src/templates/mastra/template.yaml +25 -0
- package/dist/src/templates/mastra/tsconfig.json +12 -0
- package/dist/src/templates/openai-agents/Dockerfile +34 -0
- package/dist/src/templates/openai-agents/README.md +29 -0
- package/dist/src/templates/openai-agents/agent.py +98 -0
- package/dist/src/templates/openai-agents/entrypoint.sh +34 -0
- package/dist/src/templates/openai-agents/requirements.txt +3 -0
- package/dist/src/templates/openai-agents/template.yaml +24 -0
- package/dist/src/templates/pydantic-ai/Dockerfile +34 -0
- package/dist/src/templates/pydantic-ai/README.md +36 -0
- package/dist/src/templates/pydantic-ai/agent.py +110 -0
- package/dist/src/templates/pydantic-ai/entrypoint.sh +34 -0
- package/dist/src/templates/pydantic-ai/requirements.txt +2 -0
- package/dist/src/templates/pydantic-ai/template.yaml +24 -0
- package/dist/src/templates/smolagents/Dockerfile +34 -0
- package/dist/src/templates/smolagents/README.md +36 -0
- package/dist/src/templates/smolagents/agent.py +97 -0
- package/dist/src/templates/smolagents/entrypoint.sh +34 -0
- package/dist/src/templates/smolagents/requirements.txt +2 -0
- package/dist/src/templates/smolagents/template.yaml +24 -0
- package/dist/src/templates/typescript-sdk/Dockerfile +31 -0
- package/dist/src/templates/typescript-sdk/README.md +29 -0
- package/dist/src/templates/typescript-sdk/agent.ts +130 -0
- package/dist/src/templates/typescript-sdk/entrypoint.sh +34 -0
- package/dist/src/templates/typescript-sdk/package.json +17 -0
- package/dist/src/templates/typescript-sdk/template.yaml +25 -0
- package/dist/src/templates/typescript-sdk/tsconfig.json +12 -0
- package/package.json +1 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LangChain agent pre-wired with 1Claw MCP for secrets and signing.
|
|
3
|
+
|
|
4
|
+
LLM calls are routed through Shroud when ONECLAW_LLM_VIA_SHROUD is set.
|
|
5
|
+
The container never sees raw API keys — they are injected by the host daemon.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import threading
|
|
10
|
+
from flask import Flask, request, jsonify
|
|
11
|
+
from langchain_openai import ChatOpenAI
|
|
12
|
+
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
13
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
14
|
+
from langchain_core.tools import tool
|
|
15
|
+
|
|
16
|
+
app = Flask(__name__)
|
|
17
|
+
|
|
18
|
+
SHROUD_URL = os.environ.get("ONECLAW_SHROUD_URL", "https://shroud.1claw.xyz")
|
|
19
|
+
LLM_VIA_SHROUD = os.environ.get("ONECLAW_LLM_VIA_SHROUD", "").lower() == "true"
|
|
20
|
+
PROVIDER = os.environ.get("ONECLAW_SHROUD_PROVIDER", "openai")
|
|
21
|
+
MODEL = os.environ.get("ONECLAW_SHROUD_MODEL", "gpt-4o-mini")
|
|
22
|
+
|
|
23
|
+
conversation_history: list[dict] = []
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@tool
|
|
27
|
+
def hello_world(name: str) -> str:
|
|
28
|
+
"""Say hello to someone."""
|
|
29
|
+
return f"Hello, {name}! I'm a LangChain agent running inside 1Claw."
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@tool
|
|
33
|
+
def list_env_vars() -> str:
|
|
34
|
+
"""List 1Claw-related environment variables (values redacted)."""
|
|
35
|
+
prefix = "ONECLAW_"
|
|
36
|
+
vars_list = [k for k in sorted(os.environ) if k.startswith(prefix)]
|
|
37
|
+
return "\n".join(f" {k}=***" for k in vars_list) if vars_list else "No ONECLAW_* vars set."
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def build_agent_executor():
|
|
41
|
+
"""Build the LangChain agent. Returns None if no LLM is configured."""
|
|
42
|
+
if not LLM_VIA_SHROUD:
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
llm = ChatOpenAI(
|
|
46
|
+
model=MODEL,
|
|
47
|
+
base_url=f"{SHROUD_URL}/v1",
|
|
48
|
+
api_key="shroud-injected",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
tools = [hello_world, list_env_vars]
|
|
52
|
+
|
|
53
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
54
|
+
("system", "You are a helpful AI agent running inside a secure 1Claw container. "
|
|
55
|
+
"You have access to tools for greeting and inspecting the environment."),
|
|
56
|
+
("placeholder", "{chat_history}"),
|
|
57
|
+
("human", "{input}"),
|
|
58
|
+
("placeholder", "{agent_scratchpad}"),
|
|
59
|
+
])
|
|
60
|
+
|
|
61
|
+
agent = create_tool_calling_agent(llm, tools, prompt)
|
|
62
|
+
return AgentExecutor(agent=agent, tools=tools, verbose=False)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
agent_executor = build_agent_executor()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@app.route("/health")
|
|
69
|
+
def health():
|
|
70
|
+
return jsonify({"status": "ok", "framework": "langchain", "llm_wired": LLM_VIA_SHROUD})
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@app.route("/chat", methods=["POST"])
|
|
74
|
+
def chat():
|
|
75
|
+
data = request.get_json(silent=True) or {}
|
|
76
|
+
message = data.get("message", "").strip()
|
|
77
|
+
if not message:
|
|
78
|
+
return jsonify({"error": "No message provided"}), 400
|
|
79
|
+
|
|
80
|
+
if not agent_executor:
|
|
81
|
+
return jsonify({
|
|
82
|
+
"response": "No LLM configured. Use --llm-api-key or enable Token Billing.",
|
|
83
|
+
"framework": "langchain",
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
result = agent_executor.invoke({
|
|
88
|
+
"input": message,
|
|
89
|
+
"chat_history": conversation_history,
|
|
90
|
+
})
|
|
91
|
+
output = result.get("output", str(result))
|
|
92
|
+
conversation_history.append({"role": "user", "content": message})
|
|
93
|
+
conversation_history.append({"role": "assistant", "content": output})
|
|
94
|
+
return jsonify({"response": output, "framework": "langchain"})
|
|
95
|
+
except Exception as e:
|
|
96
|
+
return jsonify({"error": str(e)}), 500
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@app.route("/")
|
|
100
|
+
def index():
|
|
101
|
+
return """<!DOCTYPE html>
|
|
102
|
+
<html><head><title>1Claw LangChain Agent</title></head>
|
|
103
|
+
<body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
|
|
104
|
+
<h1>1Claw LangChain Agent</h1>
|
|
105
|
+
<p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
|
|
106
|
+
<p>Health: <a href="/health">/health</a></p>
|
|
107
|
+
<p style="color:#666;font-size:0.9em">
|
|
108
|
+
Credentials stay in the host daemon — this container never sees secret values.
|
|
109
|
+
</p></body></html>"""
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if __name__ == "__main__":
|
|
113
|
+
port = int(os.environ.get("CHAT_UI_PORT", "3000"))
|
|
114
|
+
print(f"LangChain agent listening on http://0.0.0.0:{port}")
|
|
115
|
+
app.run(host="0.0.0.0", port=port)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
|
|
5
|
+
CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
|
|
6
|
+
|
|
7
|
+
echo "─────────────────────────────────────────────"
|
|
8
|
+
echo " 1Claw LangChain Agent"
|
|
9
|
+
echo " Framework: langchain"
|
|
10
|
+
echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
|
|
11
|
+
|
|
12
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
13
|
+
echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
|
|
14
|
+
echo " Socket: $DAEMON_SOCKET"
|
|
15
|
+
else
|
|
16
|
+
echo " Mode: standalone (no daemon socket)"
|
|
17
|
+
fi
|
|
18
|
+
echo "─────────────────────────────────────────────"
|
|
19
|
+
|
|
20
|
+
# Route LLM calls through Shroud (transparent to application code)
|
|
21
|
+
if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
|
|
22
|
+
export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
|
|
23
|
+
echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Start MCP server in background (best-effort)
|
|
27
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
28
|
+
if command -v 1claw-mcp >/dev/null 2>&1; then
|
|
29
|
+
ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
|
|
30
|
+
1claw-mcp --local 2>/tmp/mcp.log &
|
|
31
|
+
echo "MCP server started in background."
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
|
|
36
|
+
exec python agent.py
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: langchain
|
|
2
|
+
display_name: "LangChain / LangGraph"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Python agent using LangChain with 1Claw MCP for secrets and signing"
|
|
5
|
+
author: 1Claw
|
|
6
|
+
language: python
|
|
7
|
+
homepage: https://python.langchain.com
|
|
8
|
+
|
|
9
|
+
docker:
|
|
10
|
+
base_image: python:3.12-slim
|
|
11
|
+
context_files:
|
|
12
|
+
- Dockerfile
|
|
13
|
+
- requirements.txt
|
|
14
|
+
- agent.py
|
|
15
|
+
- entrypoint.sh
|
|
16
|
+
env:
|
|
17
|
+
ONECLAW_FRAMEWORK: langchain
|
|
18
|
+
health_endpoint: /health
|
|
19
|
+
health_port: 3000
|
|
20
|
+
|
|
21
|
+
post_spawn_message: |
|
|
22
|
+
Edit agent.py to customize your LangChain agent.
|
|
23
|
+
Your 1Claw MCP server is available at the daemon socket.
|
|
24
|
+
LLM calls are routed through Shroud for inspection and redaction.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
4
|
+
curl tini && \
|
|
5
|
+
rm -rf /var/lib/apt/lists/*
|
|
6
|
+
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
COPY requirements.txt .
|
|
10
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
11
|
+
|
|
12
|
+
COPY agent.py .
|
|
13
|
+
COPY entrypoint.sh .
|
|
14
|
+
RUN chmod +x entrypoint.sh
|
|
15
|
+
|
|
16
|
+
RUN mkdir -p /run/1claw
|
|
17
|
+
|
|
18
|
+
ENV NODE_ENV=production
|
|
19
|
+
ENV ONECLAW_DAEMON_SOCKET=/run/1claw/daemon.sock
|
|
20
|
+
ENV ONECLAW_FRAMEWORK=llamaindex
|
|
21
|
+
|
|
22
|
+
EXPOSE 3000
|
|
23
|
+
|
|
24
|
+
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=5 \
|
|
25
|
+
CMD curl -sf http://localhost:3000/health || exit 1
|
|
26
|
+
|
|
27
|
+
ENTRYPOINT ["tini", "--"]
|
|
28
|
+
CMD ["./entrypoint.sh"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# LlamaIndex Template
|
|
2
|
+
|
|
3
|
+
A Python agent using [LlamaIndex](https://docs.llamaindex.ai) with 1Claw MCP for secrets management and on-chain signing.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
1claw spawn llamaindex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or with your own API key:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
1claw spawn llamaindex --llm-api-key sk-...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What's included
|
|
18
|
+
|
|
19
|
+
- **agent.py** — LlamaIndex ReActAgent with example tools (hello_world, list_env_vars)
|
|
20
|
+
- **Flask server** on port 3000 with `/chat` and `/health` endpoints
|
|
21
|
+
- **Shroud integration** — LLM calls are routed through Shroud for inspection
|
|
22
|
+
- **MCP server** — started automatically for tool access to 1Claw vault
|
|
23
|
+
|
|
24
|
+
## Customizing
|
|
25
|
+
|
|
26
|
+
Edit `agent.py` to add custom tools, connect data sources (documents,
|
|
27
|
+
APIs, databases), or switch to a different agent type. LlamaIndex
|
|
28
|
+
supports RAG, structured output, and multi-step reasoning.
|
|
29
|
+
|
|
30
|
+
## LLM authentication
|
|
31
|
+
|
|
32
|
+
The template supports three methods (configured at spawn time):
|
|
33
|
+
|
|
34
|
+
1. **BYOK** — `1claw spawn llamaindex --llm-api-key sk-...`
|
|
35
|
+
2. **Token Billing** — enable in Dashboard, no key needed
|
|
36
|
+
3. **Anthropic WIF** — OIDC federation for Anthropic models
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LlamaIndex agent pre-wired with 1Claw MCP for secrets and signing.
|
|
3
|
+
|
|
4
|
+
LLM calls are routed through Shroud when ONECLAW_LLM_VIA_SHROUD is set.
|
|
5
|
+
The container never sees raw API keys — they are injected by the host daemon.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from flask import Flask, request, jsonify
|
|
10
|
+
from llama_index.core.agent import ReActAgent
|
|
11
|
+
from llama_index.core.tools import FunctionTool
|
|
12
|
+
from llama_index.llms.openai_like import OpenAILike
|
|
13
|
+
|
|
14
|
+
app = Flask(__name__)
|
|
15
|
+
|
|
16
|
+
SHROUD_URL = os.environ.get("ONECLAW_SHROUD_URL", "https://shroud.1claw.xyz")
|
|
17
|
+
LLM_VIA_SHROUD = os.environ.get("ONECLAW_LLM_VIA_SHROUD", "").lower() == "true"
|
|
18
|
+
MODEL = os.environ.get("ONECLAW_SHROUD_MODEL", "gpt-4o-mini")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def hello_world(name: str) -> str:
|
|
22
|
+
"""Say hello to someone."""
|
|
23
|
+
return f"Hello, {name}! I'm a LlamaIndex agent running inside 1Claw."
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def list_env_vars() -> str:
|
|
27
|
+
"""List 1Claw-related environment variables (values redacted)."""
|
|
28
|
+
prefix = "ONECLAW_"
|
|
29
|
+
vars_list = [k for k in sorted(os.environ) if k.startswith(prefix)]
|
|
30
|
+
return "\n".join(f" {k}=***" for k in vars_list) if vars_list else "No ONECLAW_* vars set."
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def create_agent():
|
|
34
|
+
"""Build the LlamaIndex ReAct agent. Returns None if no LLM."""
|
|
35
|
+
if not LLM_VIA_SHROUD:
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
llm = OpenAILike(
|
|
39
|
+
model=MODEL,
|
|
40
|
+
api_base=f"{SHROUD_URL}/v1",
|
|
41
|
+
api_key="shroud-injected",
|
|
42
|
+
is_chat_model=True,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
tools = [
|
|
46
|
+
FunctionTool.from_defaults(fn=hello_world),
|
|
47
|
+
FunctionTool.from_defaults(fn=list_env_vars),
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
return ReActAgent.from_tools(tools, llm=llm, verbose=False)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
agent = create_agent()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@app.route("/health")
|
|
57
|
+
def health():
|
|
58
|
+
return jsonify({"status": "ok", "framework": "llamaindex", "llm_wired": LLM_VIA_SHROUD})
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@app.route("/chat", methods=["POST"])
|
|
62
|
+
def chat():
|
|
63
|
+
data = request.get_json(silent=True) or {}
|
|
64
|
+
message = data.get("message", "").strip()
|
|
65
|
+
if not message:
|
|
66
|
+
return jsonify({"error": "No message provided"}), 400
|
|
67
|
+
|
|
68
|
+
if not agent:
|
|
69
|
+
return jsonify({
|
|
70
|
+
"response": "No LLM configured. Use --llm-api-key or enable Token Billing.",
|
|
71
|
+
"framework": "llamaindex",
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
response = agent.chat(message)
|
|
76
|
+
return jsonify({"response": str(response), "framework": "llamaindex"})
|
|
77
|
+
except Exception as e:
|
|
78
|
+
return jsonify({"error": str(e)}), 500
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@app.route("/")
|
|
82
|
+
def index():
|
|
83
|
+
return """<!DOCTYPE html>
|
|
84
|
+
<html><head><title>1Claw LlamaIndex Agent</title></head>
|
|
85
|
+
<body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
|
|
86
|
+
<h1>1Claw LlamaIndex Agent</h1>
|
|
87
|
+
<p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
|
|
88
|
+
<p>Health: <a href="/health">/health</a></p>
|
|
89
|
+
<p style="color:#666;font-size:0.9em">
|
|
90
|
+
Credentials stay in the host daemon — this container never sees secret values.
|
|
91
|
+
</p></body></html>"""
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
port = int(os.environ.get("CHAT_UI_PORT", "3000"))
|
|
96
|
+
print(f"LlamaIndex agent listening on http://0.0.0.0:{port}")
|
|
97
|
+
app.run(host="0.0.0.0", port=port)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
|
|
5
|
+
CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
|
|
6
|
+
|
|
7
|
+
echo "─────────────────────────────────────────────"
|
|
8
|
+
echo " 1Claw LlamaIndex Agent"
|
|
9
|
+
echo " Framework: llamaindex"
|
|
10
|
+
echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
|
|
11
|
+
|
|
12
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
13
|
+
echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
|
|
14
|
+
echo " Socket: $DAEMON_SOCKET"
|
|
15
|
+
else
|
|
16
|
+
echo " Mode: standalone (no daemon socket)"
|
|
17
|
+
fi
|
|
18
|
+
echo "─────────────────────────────────────────────"
|
|
19
|
+
|
|
20
|
+
if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
|
|
21
|
+
export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
|
|
22
|
+
echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
26
|
+
if command -v 1claw-mcp >/dev/null 2>&1; then
|
|
27
|
+
ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
|
|
28
|
+
1claw-mcp --local 2>/tmp/mcp.log &
|
|
29
|
+
echo "MCP server started in background."
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
|
|
34
|
+
exec python agent.py
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: llamaindex
|
|
2
|
+
display_name: "LlamaIndex"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "LlamaIndex agent with tool integration and 1Claw MCP"
|
|
5
|
+
author: 1Claw
|
|
6
|
+
language: python
|
|
7
|
+
homepage: https://docs.llamaindex.ai
|
|
8
|
+
|
|
9
|
+
docker:
|
|
10
|
+
base_image: python:3.12-slim
|
|
11
|
+
context_files:
|
|
12
|
+
- Dockerfile
|
|
13
|
+
- requirements.txt
|
|
14
|
+
- agent.py
|
|
15
|
+
- entrypoint.sh
|
|
16
|
+
env:
|
|
17
|
+
ONECLAW_FRAMEWORK: llamaindex
|
|
18
|
+
health_endpoint: /health
|
|
19
|
+
health_port: 3000
|
|
20
|
+
|
|
21
|
+
post_spawn_message: |
|
|
22
|
+
Edit agent.py to customize your LlamaIndex agent's tools and data sources.
|
|
23
|
+
Your 1Claw MCP server is available at the daemon socket.
|
|
24
|
+
LLM calls are routed through Shroud for inspection and redaction.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
FROM node:22-slim
|
|
2
|
+
|
|
3
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
4
|
+
curl tini && \
|
|
5
|
+
rm -rf /var/lib/apt/lists/*
|
|
6
|
+
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
COPY package.json tsconfig.json ./
|
|
10
|
+
RUN npm install --omit=dev 2>/dev/null || npm install
|
|
11
|
+
|
|
12
|
+
RUN npm install -g @1claw/mcp@latest 2>/dev/null || \
|
|
13
|
+
echo "WARN: @1claw/mcp install deferred to runtime"
|
|
14
|
+
|
|
15
|
+
COPY agent.ts .
|
|
16
|
+
COPY entrypoint.sh .
|
|
17
|
+
RUN chmod +x entrypoint.sh
|
|
18
|
+
|
|
19
|
+
RUN mkdir -p /run/1claw
|
|
20
|
+
|
|
21
|
+
ENV NODE_ENV=production
|
|
22
|
+
ENV ONECLAW_DAEMON_SOCKET=/run/1claw/daemon.sock
|
|
23
|
+
ENV ONECLAW_FRAMEWORK=mastra
|
|
24
|
+
|
|
25
|
+
EXPOSE 3000
|
|
26
|
+
|
|
27
|
+
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=5 \
|
|
28
|
+
CMD curl -sf http://localhost:3000/health || exit 1
|
|
29
|
+
|
|
30
|
+
ENTRYPOINT ["tini", "--"]
|
|
31
|
+
CMD ["./entrypoint.sh"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 1Claw Mastra Agent Template
|
|
2
|
+
|
|
3
|
+
TypeScript-first AI agent using [Mastra](https://mastra.ai) + Vercel AI SDK with 1Claw secrets and signing.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
1claw spawn mastra --agent-key ocv_YOUR_KEY
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What's included
|
|
12
|
+
|
|
13
|
+
- `agent.ts` — Mastra agent with AI SDK tool calling, Shroud LLM routing, and `/chat` + `/health` endpoints
|
|
14
|
+
- `Dockerfile` — Node 22 slim image with `@1claw/mcp` for vault access
|
|
15
|
+
- `entrypoint.sh` — Daemon socket detection, Shroud wiring, MCP server startup
|
|
16
|
+
|
|
17
|
+
## LLM authentication
|
|
18
|
+
|
|
19
|
+
The container never sees your LLM API key. Credentials are injected by the host daemon and routed through Shroud.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Bring your own key (stored in vault, routed through Shroud)
|
|
23
|
+
1claw spawn mastra --agent-key ocv_YOUR_KEY --llm-api-key sk-...
|
|
24
|
+
|
|
25
|
+
# Use 1Claw Token Billing (no provider key needed)
|
|
26
|
+
1claw spawn mastra --agent-key ocv_YOUR_KEY
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Customization
|
|
30
|
+
|
|
31
|
+
Edit `agent.ts` to add tools, change the system prompt, or integrate with Mastra workflows.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mastra agent pre-wired with 1Claw MCP for secrets and signing.
|
|
3
|
+
*
|
|
4
|
+
* LLM calls are routed through Shroud when ONECLAW_LLM_VIA_SHROUD is set.
|
|
5
|
+
* The container never sees raw API keys — they are injected by the host daemon.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createServer } from "node:http";
|
|
9
|
+
import { Mastra } from "@mastra/core";
|
|
10
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
11
|
+
import { generateText, tool } from "ai";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
const SHROUD_URL = process.env.ONECLAW_SHROUD_URL ?? "https://shroud.1claw.xyz";
|
|
15
|
+
const LLM_VIA_SHROUD = process.env.ONECLAW_LLM_VIA_SHROUD === "true";
|
|
16
|
+
const PROVIDER = process.env.ONECLAW_SHROUD_PROVIDER ?? "openai";
|
|
17
|
+
const MODEL = process.env.ONECLAW_SHROUD_MODEL ?? "gpt-4o-mini";
|
|
18
|
+
|
|
19
|
+
const conversationHistory: { role: "user" | "assistant"; content: string }[] = [];
|
|
20
|
+
|
|
21
|
+
const openai = LLM_VIA_SHROUD
|
|
22
|
+
? createOpenAI({ baseURL: `${SHROUD_URL}/v1`, apiKey: "shroud-injected" })
|
|
23
|
+
: null;
|
|
24
|
+
|
|
25
|
+
const mastra = new Mastra({});
|
|
26
|
+
|
|
27
|
+
const helloTool = tool({
|
|
28
|
+
description: "Say hello to someone",
|
|
29
|
+
parameters: z.object({ name: z.string().describe("Name to greet") }),
|
|
30
|
+
execute: async ({ name }) =>
|
|
31
|
+
`Hello, ${name}! I'm a Mastra agent running inside 1Claw.`,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const envTool = tool({
|
|
35
|
+
description: "List 1Claw-related environment variables (values redacted)",
|
|
36
|
+
parameters: z.object({}),
|
|
37
|
+
execute: async () => {
|
|
38
|
+
const vars = Object.keys(process.env)
|
|
39
|
+
.filter((k) => k.startsWith("ONECLAW_"))
|
|
40
|
+
.sort()
|
|
41
|
+
.map((k) => ` ${k}=***`);
|
|
42
|
+
return vars.length ? vars.join("\n") : "No ONECLAW_* vars set.";
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
async function handleChat(message: string): Promise<string> {
|
|
47
|
+
if (!openai) {
|
|
48
|
+
return "No LLM configured. Use --llm-api-key or enable Token Billing.";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
conversationHistory.push({ role: "user", content: message });
|
|
52
|
+
|
|
53
|
+
const { text } = await generateText({
|
|
54
|
+
model: openai(MODEL),
|
|
55
|
+
system:
|
|
56
|
+
"You are a helpful AI agent running inside a secure 1Claw container. " +
|
|
57
|
+
"You have access to tools for greeting and inspecting the environment.",
|
|
58
|
+
messages: conversationHistory,
|
|
59
|
+
tools: { hello: helloTool, env: envTool },
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
conversationHistory.push({ role: "assistant", content: text });
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const PORT = parseInt(process.env.CHAT_UI_PORT ?? "3000", 10);
|
|
67
|
+
|
|
68
|
+
const server = createServer(async (req, res) => {
|
|
69
|
+
if (req.url === "/health" && req.method === "GET") {
|
|
70
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
71
|
+
res.end(JSON.stringify({ status: "ok", framework: "mastra", llm_wired: LLM_VIA_SHROUD }));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (req.url === "/chat" && req.method === "POST") {
|
|
76
|
+
const chunks: Buffer[] = [];
|
|
77
|
+
for await (const chunk of req) chunks.push(chunk as Buffer);
|
|
78
|
+
const body = JSON.parse(Buffer.concat(chunks).toString());
|
|
79
|
+
const message = (body.message ?? "").trim();
|
|
80
|
+
|
|
81
|
+
if (!message) {
|
|
82
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
83
|
+
res.end(JSON.stringify({ error: "No message provided" }));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const response = await handleChat(message);
|
|
89
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
90
|
+
res.end(JSON.stringify({ response, framework: "mastra" }));
|
|
91
|
+
} catch (e: any) {
|
|
92
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
93
|
+
res.end(JSON.stringify({ error: e.message }));
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
99
|
+
res.end(`<!DOCTYPE html>
|
|
100
|
+
<html><head><title>1Claw Mastra Agent</title></head>
|
|
101
|
+
<body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:0 20px">
|
|
102
|
+
<h1>1Claw Mastra Agent</h1>
|
|
103
|
+
<p>Send messages via <code>POST /chat</code> with <code>{"message": "..."}</code></p>
|
|
104
|
+
<p>Health: <a href="/health">/health</a></p>
|
|
105
|
+
<p style="color:#666;font-size:0.9em">
|
|
106
|
+
Credentials stay in the host daemon — this container never sees secret values.
|
|
107
|
+
</p></body></html>`);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
server.listen(PORT, "0.0.0.0", () => {
|
|
111
|
+
console.log(`Mastra agent listening on http://0.0.0.0:${PORT}`);
|
|
112
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
DAEMON_SOCKET="${ONECLAW_DAEMON_SOCKET:-/run/1claw/daemon.sock}"
|
|
5
|
+
CHAT_UI_PORT="${CHAT_UI_PORT:-3000}"
|
|
6
|
+
|
|
7
|
+
echo "─────────────────────────────────────────────"
|
|
8
|
+
echo " 1Claw Mastra Agent"
|
|
9
|
+
echo " Framework: mastra (TypeScript)"
|
|
10
|
+
echo " Agent ID: ${ONECLAW_AGENT_ID:-not set}"
|
|
11
|
+
|
|
12
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
13
|
+
echo " Mode: ${ONECLAW_MODE:-cloud} (daemon socket)"
|
|
14
|
+
echo " Socket: $DAEMON_SOCKET"
|
|
15
|
+
else
|
|
16
|
+
echo " Mode: standalone (no daemon socket)"
|
|
17
|
+
fi
|
|
18
|
+
echo "─────────────────────────────────────────────"
|
|
19
|
+
|
|
20
|
+
if [ "$ONECLAW_LLM_VIA_SHROUD" = "true" ]; then
|
|
21
|
+
export OPENAI_BASE_URL="${ONECLAW_SHROUD_URL}/v1"
|
|
22
|
+
echo "LLM routed through Shroud: ${ONECLAW_SHROUD_PROVIDER}/${ONECLAW_SHROUD_MODEL}"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ -S "$DAEMON_SOCKET" ]; then
|
|
26
|
+
if command -v 1claw-mcp >/dev/null 2>&1; then
|
|
27
|
+
ONECLAW_LOCAL_VAULT=true ONECLAW_DAEMON_SOCKET="$DAEMON_SOCKET" \
|
|
28
|
+
1claw-mcp --local 2>/tmp/mcp.log &
|
|
29
|
+
echo "MCP server started in background."
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo "Ready: http://0.0.0.0:${CHAT_UI_PORT}"
|
|
34
|
+
exec npx tsx agent.ts
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "1claw-mastra-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "tsx agent.ts",
|
|
8
|
+
"dev": "tsx watch agent.ts"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@mastra/core": "^0.10.0",
|
|
12
|
+
"@ai-sdk/openai": "^1.0.0",
|
|
13
|
+
"ai": "^4.0.0",
|
|
14
|
+
"tsx": "^4.19.0",
|
|
15
|
+
"typescript": "^5.7.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: mastra
|
|
2
|
+
display_name: "Mastra"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "TypeScript-first AI agent framework with 1Claw MCP for secrets and signing"
|
|
5
|
+
author: 1Claw
|
|
6
|
+
language: node
|
|
7
|
+
homepage: https://mastra.ai
|
|
8
|
+
|
|
9
|
+
docker:
|
|
10
|
+
base_image: node:22-slim
|
|
11
|
+
context_files:
|
|
12
|
+
- Dockerfile
|
|
13
|
+
- package.json
|
|
14
|
+
- tsconfig.json
|
|
15
|
+
- agent.ts
|
|
16
|
+
- entrypoint.sh
|
|
17
|
+
env:
|
|
18
|
+
ONECLAW_FRAMEWORK: mastra
|
|
19
|
+
health_endpoint: /health
|
|
20
|
+
health_port: 3000
|
|
21
|
+
|
|
22
|
+
post_spawn_message: |
|
|
23
|
+
Edit agent.ts to customize your Mastra agent.
|
|
24
|
+
Your 1Claw MCP server is available at the daemon socket.
|
|
25
|
+
LLM calls are routed through Shroud for inspection and redaction.
|