Skip to content

Commit 425ddb3

Browse files
feat: publish Orca CLMM toolkit and agent runtime
0 parents  commit 425ddb3

176 files changed

Lines changed: 64135 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codex/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[features]
2+
hooks = true

.codex/hooks.json

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"hooks": {
3+
"SessionStart": [
4+
{
5+
"matcher": "startup|resume",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event SessionStart",
10+
"timeout": 10,
11+
"statusMessage": "Recording Codex session start"
12+
}
13+
]
14+
}
15+
],
16+
"UserPromptSubmit": [
17+
{
18+
"hooks": [
19+
{
20+
"type": "command",
21+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event UserPromptSubmit",
22+
"timeout": 10,
23+
"statusMessage": "Recording user prompt metadata"
24+
}
25+
]
26+
}
27+
],
28+
"PreToolUse": [
29+
{
30+
"matcher": ".*",
31+
"hooks": [
32+
{
33+
"type": "command",
34+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event PreToolUse",
35+
"timeout": 10,
36+
"statusMessage": "Recording tool request"
37+
}
38+
]
39+
}
40+
],
41+
"PostToolUse": [
42+
{
43+
"matcher": ".*",
44+
"hooks": [
45+
{
46+
"type": "command",
47+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event PostToolUse",
48+
"timeout": 10,
49+
"statusMessage": "Recording tool result"
50+
}
51+
]
52+
}
53+
],
54+
"PermissionRequest": [
55+
{
56+
"matcher": ".*",
57+
"hooks": [
58+
{
59+
"type": "command",
60+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event PermissionRequest",
61+
"timeout": 10,
62+
"statusMessage": "Recording permission request"
63+
}
64+
]
65+
}
66+
],
67+
"Stop": [
68+
{
69+
"hooks": [
70+
{
71+
"type": "command",
72+
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/observer.py\" --event Stop",
73+
"timeout": 10,
74+
"statusMessage": "Recording turn stop"
75+
}
76+
]
77+
}
78+
]
79+
}
80+
}

.codex/hooks/observer.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env python3
2+
"""Sanitized Codex hook recorder for trading-runtime observability."""
3+
4+
from __future__ import annotations
5+
6+
import argparse
7+
import datetime as dt
8+
import hashlib
9+
import json
10+
import os
11+
import re
12+
import sys
13+
from pathlib import Path
14+
from typing import Any
15+
16+
MAX_TEXT = 4000
17+
SECRET_PATTERNS = [
18+
re.compile(r"(?i)(api[_-]?key|bearer|private[_-]?key|secret|token|seed|mnemonic)(['\"\s:=]+)[^\s'\",}]+"),
19+
re.compile(r"\b[1-9A-HJ-NP-Za-km-z]{80,}\b"),
20+
]
21+
SENSITIVE_KEYS = re.compile(r"(?i)(api[_-]?key|auth|bearer|mnemonic|private|secret|seed|token)")
22+
SIGNATURE_RE = re.compile(r"\b[1-9A-HJ-NP-Za-km-z]{64,88}\b")
23+
24+
25+
def now_utc() -> str:
26+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
27+
28+
29+
def read_input() -> dict[str, Any]:
30+
raw = sys.stdin.read()
31+
if not raw.strip():
32+
return {}
33+
try:
34+
value = json.loads(raw)
35+
except json.JSONDecodeError:
36+
return {"raw_stdin": redact_text(raw)}
37+
return value if isinstance(value, dict) else {"value": value}
38+
39+
40+
def redact_text(value: str) -> str:
41+
value = value[:MAX_TEXT]
42+
for pattern in SECRET_PATTERNS:
43+
value = pattern.sub(redact_match, value)
44+
return value
45+
46+
47+
def redact_match(match: re.Match[str]) -> str:
48+
if match.lastindex and match.lastindex >= 2:
49+
return f"{match.group(1)}{match.group(2)}[REDACTED]"
50+
return "[REDACTED_LONG_BASE58]"
51+
52+
53+
def sanitize(value: Any) -> Any:
54+
if isinstance(value, dict):
55+
return {
56+
str(key): "[REDACTED]" if SENSITIVE_KEYS.search(str(key)) else sanitize(item)
57+
for key, item in value.items()
58+
}
59+
if isinstance(value, list):
60+
return [sanitize(item) for item in value[:50]]
61+
if isinstance(value, str):
62+
return redact_text(value)
63+
return value
64+
65+
66+
def event_summary(event: str, payload: dict[str, Any]) -> dict[str, Any]:
67+
summary: dict[str, Any] = {"event": event}
68+
for key in ("session_id", "turn_id", "cwd", "hook_event_name", "source"):
69+
if payload.get(key):
70+
summary[key] = payload[key]
71+
if prompt := payload.get("prompt"):
72+
summary["prompt_sha256"] = hashlib.sha256(str(prompt).encode()).hexdigest()
73+
summary["prompt_chars"] = len(str(prompt))
74+
if tool_name := payload.get("tool_name"):
75+
summary["tool_name"] = tool_name
76+
if tool_input := payload.get("tool_input"):
77+
command = tool_input.get("command") if isinstance(tool_input, dict) else None
78+
if command:
79+
summary["command"] = redact_text(str(command))
80+
tool_response = payload.get("tool_response")
81+
if isinstance(tool_response, dict):
82+
output = json.dumps(tool_response, sort_keys=True, default=str)
83+
signatures = sorted(set(SIGNATURE_RE.findall(output)))
84+
if signatures:
85+
summary["signatures"] = signatures[:10]
86+
summary["tool_response_chars"] = len(output)
87+
return summary
88+
89+
90+
def append_jsonl(path: Path, row: dict[str, Any]) -> None:
91+
path.parent.mkdir(parents=True, exist_ok=True)
92+
with path.open("a", encoding="utf-8") as handle:
93+
handle.write(json.dumps(row, sort_keys=True) + "\n")
94+
95+
96+
def append_markdown(path: Path, row: dict[str, Any]) -> None:
97+
path.parent.mkdir(parents=True, exist_ok=True)
98+
summary = row["summary"]
99+
parts = [f"- `{row['timestamp']}` `{row['event']}`"]
100+
if summary.get("tool_name"):
101+
parts.append(f"tool `{summary['tool_name']}`")
102+
if summary.get("prompt_chars") is not None:
103+
parts.append(f"prompt chars `{summary['prompt_chars']}`")
104+
if summary.get("signatures"):
105+
parts.append("signatures `" + "`, `".join(summary["signatures"]) + "`")
106+
with path.open("a", encoding="utf-8") as handle:
107+
handle.write(" ".join(parts) + "\n")
108+
109+
110+
def codex_json_summary(payload: dict[str, Any]) -> dict[str, Any]:
111+
summary: dict[str, Any] = {"event": "CodexExecJson"}
112+
if event_type := payload.get("type"):
113+
summary["codex_event_type"] = event_type
114+
item = payload.get("item")
115+
if isinstance(item, dict):
116+
summary["item_type"] = item.get("type")
117+
if text := item.get("text"):
118+
summary["text_sha256"] = hashlib.sha256(str(text).encode()).hexdigest()
119+
summary["text_chars"] = len(str(text))
120+
if usage := payload.get("usage"):
121+
summary["usage"] = usage
122+
return summary
123+
124+
125+
def stream_codex_jsonl(root: Path) -> int:
126+
for line in sys.stdin:
127+
if not line.strip():
128+
continue
129+
try:
130+
raw_payload = json.loads(line)
131+
except json.JSONDecodeError:
132+
raw_payload = {"raw_line": line}
133+
payload = sanitize(raw_payload)
134+
timestamp = now_utc()
135+
row = {
136+
"timestamp": timestamp,
137+
"event": "CodexExecJson",
138+
"summary": codex_json_summary(raw_payload),
139+
"payload": payload,
140+
}
141+
append_jsonl(root / "codex-exec-events.jsonl", row)
142+
append_markdown(root / f"{timestamp[:10]}.md", row)
143+
print(json.dumps(payload, sort_keys=True), flush=True)
144+
return 0
145+
146+
147+
def main() -> int:
148+
parser = argparse.ArgumentParser()
149+
parser.add_argument("--event", required=True)
150+
parser.add_argument("--stream-jsonl", action="store_true")
151+
args = parser.parse_args()
152+
153+
root = Path(os.environ.get("CODEX_OBSERVABILITY_DIR", ".agent-observability"))
154+
if args.stream_jsonl:
155+
return stream_codex_jsonl(root)
156+
157+
raw_payload = read_input()
158+
payload = sanitize(raw_payload)
159+
timestamp = now_utc()
160+
row = {
161+
"timestamp": timestamp,
162+
"event": args.event,
163+
"summary": event_summary(args.event, raw_payload),
164+
"payload": payload,
165+
}
166+
append_jsonl(root / "events.jsonl", row)
167+
append_markdown(root / f"{timestamp[:10]}.md", row)
168+
return 0
169+
170+
171+
if __name__ == "__main__":
172+
raise SystemExit(main())

.dockerignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.git
2+
node_modules
3+
**/node_modules
4+
dist
5+
**/dist
6+
coverage
7+
**/coverage
8+
9+
.env
10+
.env.*
11+
!.env.example
12+
!**/.env.example
13+
.env.yaml
14+
*.env.yaml
15+
*keypair*
16+
*secret*
17+
*.pem
18+
*.key
19+
*.p12
20+
*.pfx
21+
id_rsa*
22+
id_ed25519*
23+
24+
points.json
25+
log.txt
26+
*.log
27+
*.tgz
28+
.learnings
29+
.journal
30+
31+
.agent-actions
32+
.agent-observability
33+
.worktrees
34+
portfolio-advisor-wallets.json
35+
wallet.json
36+
wallets.json
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Bug report
2+
description: Report a reproducible problem.
3+
title: "bug: "
4+
labels: ["bug"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Do not include private keys, seed phrases, API keys, wallet files, or sensitive wallet details.
10+
- type: textarea
11+
id: summary
12+
attributes:
13+
label: Summary
14+
description: What failed?
15+
validations:
16+
required: true
17+
- type: textarea
18+
id: reproduce
19+
attributes:
20+
label: Reproduction
21+
description: Minimal steps, command, or code snippet.
22+
validations:
23+
required: true
24+
- type: textarea
25+
id: expected
26+
attributes:
27+
label: Expected behavior
28+
validations:
29+
required: true
30+
- type: textarea
31+
id: environment
32+
attributes:
33+
label: Environment
34+
description: Node version, package version, RPC type, and OS.
35+

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blank_issues_enabled: true
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Feature request
2+
description: Suggest a focused improvement.
3+
title: "feat: "
4+
labels: ["enhancement"]
5+
body:
6+
- type: textarea
7+
id: problem
8+
attributes:
9+
label: Problem
10+
description: What use case should this solve?
11+
validations:
12+
required: true
13+
- type: textarea
14+
id: proposal
15+
attributes:
16+
label: Proposal
17+
description: What should change?
18+
validations:
19+
required: true
20+
- type: textarea
21+
id: safety
22+
attributes:
23+
label: Transaction or security impact
24+
description: Does this affect signing, swapping, bridging, opening, or closing positions?
25+

.github/dependabot.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: npm
4+
directory: /package
5+
schedule:
6+
interval: weekly
7+
open-pull-requests-limit: 5
8+
- package-ecosystem: github-actions
9+
directory: /
10+
schedule:
11+
interval: weekly
12+
open-pull-requests-limit: 5

.github/pull_request_template.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Summary
2+
3+
-
4+
5+
## Testing
6+
7+
- [ ] `cd package && npm run build`
8+
- [ ] `cd package && npm run test:unit`
9+
- [ ] Integration tests, if relevant
10+
11+
## Safety
12+
13+
- [ ] No private keys, seed phrases, `.env` files, RPC credentials, exchange credentials, or generated logs are included.
14+
- [ ] Live transaction behavior is documented or explicitly out of scope.
15+

0 commit comments

Comments
 (0)