Skip to content

Commit 357da65

Browse files
authored
Merge pull request #21 from voarsh2/ctx-glm-claude-hook-refrag
Fix refrag GLM mode, add GLM support to CTX, ctx based Claude Code hook to enhance user prompts
2 parents f424d90 + 8811a72 commit 357da65

File tree

9 files changed

+469
-108
lines changed

9 files changed

+469
-108
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ REFRAG_SENSE=heuristic
127127
LLAMACPP_URL=http://llamacpp:8080
128128
REFRAG_DECODER_MODE=prompt # prompt|soft
129129

130+
# GLM_API_BASE=https://api.z.ai/api/coding/paas/v4/
131+
# GLM_MODEL=glm-4.6
132+
130133
# GPU Performance Toggle
131134
# Set to 1 to use native GPU-accelerated server on localhost:8081
132135
# Set to 0 to use Docker CPU-only server (default, stable)

Dockerfile.indexer

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
88
# OS packages needed: git for history ingestion
99
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates && rm -rf /var/lib/apt/lists/*
1010

11-
RUN pip install --no-cache-dir qdrant-client fastembed watchdog onnxruntime tokenizers tree_sitter tree_sitter_languages
11+
# Python deps: reuse shared requirements file
12+
COPY requirements.txt /tmp/requirements.txt
13+
RUN pip install --no-cache-dir --upgrade -r /tmp/requirements.txt
1214

1315
# Bake scripts into the image so we can mount arbitrary code at /work
1416
COPY scripts /app/scripts

Dockerfile.mcp-indexer

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
1010
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates \
1111
&& rm -rf /var/lib/apt/lists/*
1212

13-
# Python deps: include FastMCP with Streamable HTTP (RMCP) support
14-
RUN pip install --no-cache-dir --upgrade qdrant-client fastembed watchdog onnxruntime tokenizers \
15-
tree_sitter tree_sitter_languages mcp fastmcp
13+
# Python deps: reuse shared requirements (includes FastMCP + OpenAI SDK)
14+
COPY requirements.txt /tmp/requirements.txt
15+
RUN pip install --no-cache-dir --upgrade -r /tmp/requirements.txt
1616

1717
# Bake scripts into the image so entrypoints don't rely on /work
1818
COPY scripts /app/scripts

ctx-hook-simple.sh

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/bin/bash
2+
3+
# Simplified Claude Code UserPromptSubmit hook for ctx.py
4+
# Takes JSON input from Claude Code and outputs enhanced prompt
5+
6+
# Read JSON input from stdin
7+
INPUT=$(cat)
8+
9+
# Extract the user message using jq
10+
if command -v jq >/dev/null 2>&1; then
11+
USER_MESSAGE=$(echo "$INPUT" | jq -r '.user_message')
12+
else
13+
echo "$INPUT"
14+
exit 0
15+
fi
16+
17+
# Skip if empty message
18+
if [ -z "$USER_MESSAGE" ] || [ "$USER_MESSAGE" = "null" ]; then
19+
echo "$INPUT"
20+
exit 0
21+
fi
22+
23+
# Easy bypass patterns - any of these will skip ctx enhancement
24+
if [[ "$USER_MESSAGE" =~ ^(noctx|raw|bypass|skip|no-enhance): ]] || \
25+
[[ "$USER_MESSAGE" =~ ^\\ ]] || \
26+
[[ "$USER_MESSAGE" =~ ^\< ]] || \
27+
[[ "$USER_MESSAGE" =~ ^(/help|/clear|/exit|/quit) ]] || \
28+
[[ "$USER_MESSAGE" =~ ^\?\s*$ ]] || \
29+
[ ${#USER_MESSAGE} -lt 12 ]; then
30+
echo "$INPUT"
31+
exit 0
32+
fi
33+
34+
# Set working directory to where the hook script is located
35+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
36+
cd "$SCRIPT_DIR"
37+
38+
# Read all settings from ctx_config.json
39+
CONFIG_FILE="ctx_config.json"
40+
if [ -f "$CONFIG_FILE" ]; then
41+
CTX_COLLECTION=$(grep -o '"default_collection"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | sed 's/.*"default_collection"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
42+
REFRAG_RUNTIME=$(grep -o '"refrag_runtime"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | sed 's/.*"refrag_runtime"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' || echo "glm")
43+
GLM_API_KEY=$(grep -o '"glm_api_key"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | sed 's/.*"glm_api_key"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
44+
GLM_API_BASE=$(grep -o '"glm_api_base"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_FILE" | sed 's/.*"glm_api_base"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
45+
GLM_MODEL=$(grep -o '"glm_model"[[:space:]]*:[[:space:]]*"[^\"]*"' "$CONFIG_FILE" | sed 's/.*"glm_model"[[:space:]]*:[[:space:]]*"\([^\"]*\)".*/\1/' || echo "glm-4.6")
46+
CTX_DEFAULT_MODE=$(grep -o '"default_mode"[[:space:]]*:[[:space:]]*"[^\"]*"' "$CONFIG_FILE" | sed 's/.*"default_mode"[[:space:]]*:[[:space:]]*"\([^\"]*\)".*/\1/')
47+
CTX_REQUIRE_CONTEXT=$(grep -o '"require_context"[[:space:]]*:[[:space:]]*\(true\|false\)' "$CONFIG_FILE" | sed 's/.*"require_context"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/')
48+
CTX_RELEVANCE_GATE=$(grep -o '"relevance_gate_enabled"[[:space:]]*:[[:space:]]*\(true\|false\)' "$CONFIG_FILE" | sed 's/.*"relevance_gate_enabled"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/')
49+
CTX_MIN_RELEVANCE=$(grep -o '"min_relevance"[[:space:]]*:[[:space:]]*[0-9.][0-9.]*' "$CONFIG_FILE" | sed 's/.*"min_relevance"[[:space:]]*:[[:space:]]*\([0-9.][0-9.]*\).*/\1/')
50+
fi
51+
52+
# Set defaults if not found in config
53+
CTX_COLLECTION=${CTX_COLLECTION:-"codebase"}
54+
REFRAG_RUNTIME=${REFRAG_RUNTIME:-"glm"}
55+
GLM_API_KEY=${GLM_API_KEY:-}
56+
GLM_API_BASE=${GLM_API_BASE:-}
57+
GLM_MODEL=${GLM_MODEL:-"glm-4.6"}
58+
CTX_DEFAULT_MODE=${CTX_DEFAULT_MODE:-"default"}
59+
CTX_REQUIRE_CONTEXT=${CTX_REQUIRE_CONTEXT:-true}
60+
CTX_RELEVANCE_GATE=${CTX_RELEVANCE_GATE:-false}
61+
CTX_MIN_RELEVANCE=${CTX_MIN_RELEVANCE:-0.1}
62+
63+
# Export GLM/context environment variables from config
64+
export REFRAG_RUNTIME GLM_API_KEY GLM_API_BASE GLM_MODEL CTX_REQUIRE_CONTEXT CTX_RELEVANCE_GATE CTX_MIN_RELEVANCE
65+
66+
# Build ctx command with optional unicorn flag
67+
CTX_CMD=(python3 scripts/ctx.py)
68+
case "${CTX_DEFAULT_MODE,,}" in
69+
unicorn)
70+
CTX_CMD+=("--unicorn")
71+
;;
72+
detail)
73+
CTX_CMD+=("--detail")
74+
;;
75+
esac
76+
CTX_CMD+=("$USER_MESSAGE" --collection "$CTX_COLLECTION")
77+
78+
# Run ctx with collection
79+
ENHANCED=$(timeout 30s "${CTX_CMD[@]}" 2>/dev/null || echo "$USER_MESSAGE")
80+
81+
# Replace user message with enhanced version using jq
82+
echo "$INPUT" | jq --arg enhanced "$ENHANCED" '.user_message = $enhanced'

ctx_config.example.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
{
2+
"default_collection": "codebase",
3+
"refrag_runtime": "glm",
4+
"glm_api_key": "",
5+
"glm_api_base": "https://api.z.ai/api/coding/paas/v4/",
6+
"glm_model": "glm-4.6",
27
"always_include_tests": true,
38
"prefer_bullet_commands": false,
49
"extra_instructions": "Always consider error handling and edge cases",
5-
"streaming": true
10+
"default_mode": "unicorn",
11+
"streaming": true,
12+
"require_context": true,
13+
"relevance_gate_enabled": false,
14+
"min_relevance": 0.1
615
}
716

docker-compose.dev-remote.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ services:
7575
- FASTMCP_HOST=${FASTMCP_HOST}
7676
- FASTMCP_INDEXER_PORT=${FASTMCP_INDEXER_PORT}
7777
- QDRANT_URL=${QDRANT_URL}
78+
- REFRAG_DECODER=${REFRAG_DECODER:-1}
79+
- REFRAG_RUNTIME=${REFRAG_RUNTIME:-llamacpp}
80+
- GLM_API_KEY=${GLM_API_KEY}
81+
- GLM_API_BASE=${GLM_API_BASE:-https://api.z.ai/api/paas/v4/}
82+
- GLM_MODEL=${GLM_MODEL:-glm-4.6}
83+
- LLAMACPP_URL=${LLAMACPP_URL:-http://llamacpp:8080}
7884
- COLLECTION_NAME=${COLLECTION_NAME}
7985
- PATH_EMIT_MODE=container
8086
- HF_HOME=/tmp/huggingface
@@ -156,6 +162,12 @@ services:
156162
- FASTMCP_INDEXER_PORT=8001
157163
- FASTMCP_TRANSPORT=${FASTMCP_HTTP_TRANSPORT}
158164
- QDRANT_URL=${QDRANT_URL}
165+
- REFRAG_DECODER=${REFRAG_DECODER:-1}
166+
- REFRAG_RUNTIME=${REFRAG_RUNTIME:-llamacpp}
167+
- GLM_API_KEY=${GLM_API_KEY}
168+
- GLM_API_BASE=${GLM_API_BASE:-https://api.z.ai/api/paas/v4/}
169+
- GLM_MODEL=${GLM_MODEL:-glm-4.6}
170+
- LLAMACPP_URL=${LLAMACPP_URL:-http://llamacpp:8080}
159171
- FASTMCP_HEALTH_PORT=18001
160172
- COLLECTION_NAME=${COLLECTION_NAME}
161173
- PATH_EMIT_MODE=container

0 commit comments

Comments
 (0)