promptlayer 1.2.1 → 1.2.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/claude-agents.js +1 -1
- package/dist/claude-agents.js.map +1 -1
- package/dist/esm/{chunk-UKSCOWKT.js → chunk-7Y65WGSZ.js} +2 -2
- package/dist/esm/claude-agents.js +1 -1
- package/dist/esm/claude-agents.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/openai-agents.js +1 -1
- package/dist/index.js +1 -1
- package/dist/openai-agents.js +1 -1
- package/package.json +1 -1
- package/vendor/claude-agents/trace/hooks/lib.sh +4 -522
- package/vendor/claude-agents/trace/hooks/post_tool_use.sh +2 -27
- package/vendor/claude-agents/trace/hooks/py/__init__.py +1 -0
- package/vendor/claude-agents/trace/hooks/py/cli.py +81 -0
- package/vendor/claude-agents/trace/hooks/py/context.py +63 -0
- package/vendor/claude-agents/trace/hooks/py/handlers.py +244 -0
- package/vendor/claude-agents/trace/hooks/py/otlp.py +278 -0
- package/vendor/claude-agents/trace/hooks/py/settings.py +33 -0
- package/vendor/claude-agents/trace/hooks/py/state.py +135 -0
- package/vendor/claude-agents/trace/hooks/{parse_stop_transcript.py → py/stop_parser.py} +69 -31
- package/vendor/claude-agents/trace/hooks/py/traceparent.py +31 -0
- package/vendor/claude-agents/trace/hooks/session_end.sh +1 -23
- package/vendor/claude-agents/trace/hooks/session_start.sh +5 -41
- package/vendor/claude-agents/trace/hooks/stop_hook.sh +3 -106
- package/vendor/claude-agents/trace/hooks/user_prompt_submit.sh +1 -11
- package/vendor/claude-agents/trace/setup.sh +170 -0
- package/vendor/claude-agents/vendor_metadata.json +2 -2
- package/vendor/claude-agents/trace/hooks/hook_utils.py +0 -38
- /package/dist/esm/{chunk-UKSCOWKT.js.map → chunk-7Y65WGSZ.js.map} +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
echo "PromptLayer Claude Code tracing setup"
|
|
5
|
+
echo "====================================="
|
|
6
|
+
echo ""
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
HOOKS_DIR="$SCRIPT_DIR/hooks"
|
|
10
|
+
DEFAULT_ENDPOINT="https://api.promptlayer.com/v1/traces"
|
|
11
|
+
|
|
12
|
+
install_hint() {
|
|
13
|
+
local cmd="$1"
|
|
14
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
15
|
+
echo " Install with: brew install $cmd"
|
|
16
|
+
else
|
|
17
|
+
echo " Install with: sudo apt-get install $cmd"
|
|
18
|
+
fi
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
load_env_key() {
|
|
22
|
+
local dir="$PWD"
|
|
23
|
+
while [[ "$dir" != "/" ]]; do
|
|
24
|
+
if [[ -f "$dir/.env" ]]; then
|
|
25
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
26
|
+
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
|
|
27
|
+
if [[ "$line" =~ ^[[:space:]]*PROMPTLAYER_API_KEY= ]]; then
|
|
28
|
+
local value
|
|
29
|
+
value="${line#*=}"
|
|
30
|
+
value="${value%\"}"
|
|
31
|
+
value="${value#\"}"
|
|
32
|
+
value="${value%\'}"
|
|
33
|
+
value="${value#\'}"
|
|
34
|
+
if [[ -n "$value" ]]; then
|
|
35
|
+
echo "$value"
|
|
36
|
+
return 0
|
|
37
|
+
fi
|
|
38
|
+
fi
|
|
39
|
+
done <"$dir/.env"
|
|
40
|
+
fi
|
|
41
|
+
dir="$(dirname "$dir")"
|
|
42
|
+
done
|
|
43
|
+
return 1
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test_endpoint() {
|
|
47
|
+
local endpoint="$1"
|
|
48
|
+
local api_key="$2"
|
|
49
|
+
local status
|
|
50
|
+
status="$(python3 "$HOOKS_DIR/py/cli.py" probe-endpoint "$endpoint" "$api_key")"
|
|
51
|
+
|
|
52
|
+
if [[ "$status" == "000" || -z "$status" ]]; then
|
|
53
|
+
echo "WARN: Could not reach endpoint: $endpoint"
|
|
54
|
+
echo " Check network/DNS/firewall settings."
|
|
55
|
+
return 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
if [[ "$status" =~ ^2[0-9][0-9]$ ]]; then
|
|
59
|
+
echo "OK: Endpoint reachable and accepted probe payload (HTTP $status)."
|
|
60
|
+
return 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if [[ "$status" =~ ^4[0-9][0-9]$ ]]; then
|
|
64
|
+
if [[ "$status" == "401" || "$status" == "403" ]]; then
|
|
65
|
+
echo "WARN: Endpoint reachable but API key may be invalid (HTTP $status)."
|
|
66
|
+
else
|
|
67
|
+
echo "WARN: Endpoint reachable but probe rejected (HTTP $status)."
|
|
68
|
+
fi
|
|
69
|
+
return 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if [[ "$status" =~ ^5[0-9][0-9]$ ]]; then
|
|
73
|
+
echo "WARN: Endpoint reachable but returned server error (HTTP $status)."
|
|
74
|
+
return 0
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "WARN: Endpoint check returned unexpected status: $status"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for hook in lib.sh session_start.sh user_prompt_submit.sh post_tool_use.sh stop_hook.sh session_end.sh hooks.json; do
|
|
81
|
+
if [[ ! -f "$HOOKS_DIR/$hook" ]]; then
|
|
82
|
+
echo "Error: missing plugin file: $HOOKS_DIR/$hook"
|
|
83
|
+
exit 1
|
|
84
|
+
fi
|
|
85
|
+
done
|
|
86
|
+
|
|
87
|
+
for py_file in cli.py context.py handlers.py otlp.py settings.py state.py stop_parser.py traceparent.py; do
|
|
88
|
+
if [[ ! -f "$HOOKS_DIR/py/$py_file" ]]; then
|
|
89
|
+
echo "Error: missing plugin file: $HOOKS_DIR/py/$py_file"
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
done
|
|
93
|
+
|
|
94
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
95
|
+
echo "Error: missing required command: python3"
|
|
96
|
+
install_hint "python3"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
default_key="${PROMPTLAYER_API_KEY:-}"
|
|
101
|
+
if [[ -z "$default_key" ]]; then
|
|
102
|
+
if env_key="$(load_env_key 2>/dev/null)"; then
|
|
103
|
+
default_key="$env_key"
|
|
104
|
+
echo "Found PROMPTLAYER_API_KEY in a parent .env file."
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
if [[ -n "$default_key" ]]; then
|
|
109
|
+
echo "Press Enter to use detected PROMPTLAYER_API_KEY, or type a different key:"
|
|
110
|
+
read -r -s -p "> " input_key
|
|
111
|
+
echo ""
|
|
112
|
+
api_key="${input_key:-$default_key}"
|
|
113
|
+
else
|
|
114
|
+
echo "You can find or create an API key at: https://dashboard.promptlayer.com"
|
|
115
|
+
read -r -s -p "Enter PROMPTLAYER_API_KEY (input hidden): " input_key
|
|
116
|
+
echo ""
|
|
117
|
+
api_key="$input_key"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
if [[ -z "$api_key" ]]; then
|
|
121
|
+
echo "Error: PROMPTLAYER_API_KEY is required."
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if [[ ! "$api_key" =~ ^pl_ ]]; then
|
|
126
|
+
echo "Warning: API key does not start with 'pl_'. Continuing anyway."
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
read -r -p "OTLP endpoint [$DEFAULT_ENDPOINT]: " input_endpoint
|
|
130
|
+
endpoint="${input_endpoint:-$DEFAULT_ENDPOINT}"
|
|
131
|
+
if [[ "$endpoint" == *"/otel/v1/traces" ]]; then
|
|
132
|
+
endpoint="${endpoint%/otel/v1/traces}/v1/traces"
|
|
133
|
+
echo "Updated endpoint to new ingestion route: $endpoint"
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [[ ! "$endpoint" =~ ^https?:// ]]; then
|
|
137
|
+
echo "Error: endpoint must start with http:// or https://"
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
read -r -p "Enable debug logging? (y/N): " input_debug
|
|
142
|
+
if [[ "$input_debug" =~ ^[Yy]$ ]]; then
|
|
143
|
+
debug="true"
|
|
144
|
+
else
|
|
145
|
+
debug="false"
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
mkdir -p "$HOME/.claude"
|
|
149
|
+
settings_file="$HOME/.claude/settings.json"
|
|
150
|
+
|
|
151
|
+
if ! python3 "$HOOKS_DIR/py/cli.py" write-settings-env "$settings_file" "$api_key" "$endpoint" "$debug" >/dev/null 2>&1; then
|
|
152
|
+
echo "Error: $settings_file exists but is not valid JSON."
|
|
153
|
+
echo "Fix or remove it, then rerun setup."
|
|
154
|
+
exit 1
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
chmod 600 "$settings_file" 2>/dev/null || true
|
|
158
|
+
|
|
159
|
+
echo ""
|
|
160
|
+
echo "Configuration written to $settings_file"
|
|
161
|
+
echo "Testing endpoint connectivity..."
|
|
162
|
+
test_endpoint "$endpoint" "$api_key"
|
|
163
|
+
echo ""
|
|
164
|
+
echo "Setup complete."
|
|
165
|
+
echo "Next:"
|
|
166
|
+
echo " 1. Start Claude Code in this directory: claude"
|
|
167
|
+
echo " 2. Run one prompt and tool call"
|
|
168
|
+
echo " 3. View your traces at: https://dashboard.promptlayer.com"
|
|
169
|
+
echo ""
|
|
170
|
+
echo "Debug logs: tail -f ~/.claude/state/promptlayer_hook.log"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repository": "https://github.com/MagnivOrg/promptlayer-claude-plugins",
|
|
3
|
-
"commit_sha": "
|
|
4
|
-
"timestamp": "2026-03-
|
|
3
|
+
"commit_sha": "f5acd222d23b63ccda9cdf44b11f6cec6ee47e1e",
|
|
4
|
+
"timestamp": "2026-03-23T21:01:42.396Z"
|
|
5
5
|
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
import base64
|
|
4
|
-
import binascii
|
|
5
|
-
import sys
|
|
6
|
-
import time
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def hex_to_base64(hex_value: str) -> int:
|
|
10
|
-
raw = binascii.unhexlify(hex_value)
|
|
11
|
-
print(base64.b64encode(raw).decode("ascii"))
|
|
12
|
-
return 0
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def now_ns() -> int:
|
|
16
|
-
print(time.time_ns())
|
|
17
|
-
return 0
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def main() -> int:
|
|
21
|
-
if len(sys.argv) < 2:
|
|
22
|
-
raise SystemExit("usage: hook_utils.py <command> [args]")
|
|
23
|
-
|
|
24
|
-
command = sys.argv[1]
|
|
25
|
-
if command == "hex_to_base64":
|
|
26
|
-
if len(sys.argv) != 3:
|
|
27
|
-
raise SystemExit("usage: hook_utils.py hex_to_base64 <hex>")
|
|
28
|
-
return hex_to_base64(sys.argv[2])
|
|
29
|
-
if command == "now_ns":
|
|
30
|
-
if len(sys.argv) != 2:
|
|
31
|
-
raise SystemExit("usage: hook_utils.py now_ns")
|
|
32
|
-
return now_ns()
|
|
33
|
-
|
|
34
|
-
raise SystemExit(f"unknown command: {command}")
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if __name__ == "__main__":
|
|
38
|
-
raise SystemExit(main())
|
|
File without changes
|