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.
Files changed (29) hide show
  1. package/dist/claude-agents.js +1 -1
  2. package/dist/claude-agents.js.map +1 -1
  3. package/dist/esm/{chunk-UKSCOWKT.js → chunk-7Y65WGSZ.js} +2 -2
  4. package/dist/esm/claude-agents.js +1 -1
  5. package/dist/esm/claude-agents.js.map +1 -1
  6. package/dist/esm/index.js +1 -1
  7. package/dist/esm/openai-agents.js +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/openai-agents.js +1 -1
  10. package/package.json +1 -1
  11. package/vendor/claude-agents/trace/hooks/lib.sh +4 -522
  12. package/vendor/claude-agents/trace/hooks/post_tool_use.sh +2 -27
  13. package/vendor/claude-agents/trace/hooks/py/__init__.py +1 -0
  14. package/vendor/claude-agents/trace/hooks/py/cli.py +81 -0
  15. package/vendor/claude-agents/trace/hooks/py/context.py +63 -0
  16. package/vendor/claude-agents/trace/hooks/py/handlers.py +244 -0
  17. package/vendor/claude-agents/trace/hooks/py/otlp.py +278 -0
  18. package/vendor/claude-agents/trace/hooks/py/settings.py +33 -0
  19. package/vendor/claude-agents/trace/hooks/py/state.py +135 -0
  20. package/vendor/claude-agents/trace/hooks/{parse_stop_transcript.py → py/stop_parser.py} +69 -31
  21. package/vendor/claude-agents/trace/hooks/py/traceparent.py +31 -0
  22. package/vendor/claude-agents/trace/hooks/session_end.sh +1 -23
  23. package/vendor/claude-agents/trace/hooks/session_start.sh +5 -41
  24. package/vendor/claude-agents/trace/hooks/stop_hook.sh +3 -106
  25. package/vendor/claude-agents/trace/hooks/user_prompt_submit.sh +1 -11
  26. package/vendor/claude-agents/trace/setup.sh +170 -0
  27. package/vendor/claude-agents/vendor_metadata.json +2 -2
  28. package/vendor/claude-agents/trace/hooks/hook_utils.py +0 -38
  29. /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": "f3796e77977c750a912f4b607bd162fdff5ce186",
4
- "timestamp": "2026-03-19T22:27:47.129Z"
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())