connectonion 0.5.8__py3-none-any.whl
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.
- connectonion/__init__.py +78 -0
- connectonion/address.py +320 -0
- connectonion/agent.py +450 -0
- connectonion/announce.py +84 -0
- connectonion/asgi.py +287 -0
- connectonion/auto_debug_exception.py +181 -0
- connectonion/cli/__init__.py +3 -0
- connectonion/cli/browser_agent/__init__.py +5 -0
- connectonion/cli/browser_agent/browser.py +243 -0
- connectonion/cli/browser_agent/prompt.md +107 -0
- connectonion/cli/commands/__init__.py +1 -0
- connectonion/cli/commands/auth_commands.py +527 -0
- connectonion/cli/commands/browser_commands.py +27 -0
- connectonion/cli/commands/create.py +511 -0
- connectonion/cli/commands/deploy_commands.py +220 -0
- connectonion/cli/commands/doctor_commands.py +173 -0
- connectonion/cli/commands/init.py +469 -0
- connectonion/cli/commands/project_cmd_lib.py +828 -0
- connectonion/cli/commands/reset_commands.py +149 -0
- connectonion/cli/commands/status_commands.py +168 -0
- connectonion/cli/docs/co-vibecoding-principles-docs-contexts-all-in-one.md +2010 -0
- connectonion/cli/docs/connectonion.md +1256 -0
- connectonion/cli/docs.md +123 -0
- connectonion/cli/main.py +148 -0
- connectonion/cli/templates/meta-agent/README.md +287 -0
- connectonion/cli/templates/meta-agent/agent.py +196 -0
- connectonion/cli/templates/meta-agent/prompts/answer_prompt.md +9 -0
- connectonion/cli/templates/meta-agent/prompts/docs_retrieve_prompt.md +15 -0
- connectonion/cli/templates/meta-agent/prompts/metagent.md +71 -0
- connectonion/cli/templates/meta-agent/prompts/think_prompt.md +18 -0
- connectonion/cli/templates/minimal/README.md +56 -0
- connectonion/cli/templates/minimal/agent.py +40 -0
- connectonion/cli/templates/playwright/README.md +118 -0
- connectonion/cli/templates/playwright/agent.py +336 -0
- connectonion/cli/templates/playwright/prompt.md +102 -0
- connectonion/cli/templates/playwright/requirements.txt +3 -0
- connectonion/cli/templates/web-research/agent.py +122 -0
- connectonion/connect.py +128 -0
- connectonion/console.py +539 -0
- connectonion/debug_agent/__init__.py +13 -0
- connectonion/debug_agent/agent.py +45 -0
- connectonion/debug_agent/prompts/debug_assistant.md +72 -0
- connectonion/debug_agent/runtime_inspector.py +406 -0
- connectonion/debug_explainer/__init__.py +10 -0
- connectonion/debug_explainer/explain_agent.py +114 -0
- connectonion/debug_explainer/explain_context.py +263 -0
- connectonion/debug_explainer/explainer_prompt.md +29 -0
- connectonion/debug_explainer/root_cause_analysis_prompt.md +43 -0
- connectonion/debugger_ui.py +1039 -0
- connectonion/decorators.py +208 -0
- connectonion/events.py +248 -0
- connectonion/execution_analyzer/__init__.py +9 -0
- connectonion/execution_analyzer/execution_analysis.py +93 -0
- connectonion/execution_analyzer/execution_analysis_prompt.md +47 -0
- connectonion/host.py +579 -0
- connectonion/interactive_debugger.py +342 -0
- connectonion/llm.py +801 -0
- connectonion/llm_do.py +307 -0
- connectonion/logger.py +300 -0
- connectonion/prompt_files/__init__.py +1 -0
- connectonion/prompt_files/analyze_contact.md +62 -0
- connectonion/prompt_files/eval_expected.md +12 -0
- connectonion/prompt_files/react_evaluate.md +11 -0
- connectonion/prompt_files/react_plan.md +16 -0
- connectonion/prompt_files/reflect.md +22 -0
- connectonion/prompts.py +144 -0
- connectonion/relay.py +200 -0
- connectonion/static/docs.html +688 -0
- connectonion/tool_executor.py +279 -0
- connectonion/tool_factory.py +186 -0
- connectonion/tool_registry.py +105 -0
- connectonion/trust.py +166 -0
- connectonion/trust_agents.py +71 -0
- connectonion/trust_functions.py +88 -0
- connectonion/tui/__init__.py +57 -0
- connectonion/tui/divider.py +39 -0
- connectonion/tui/dropdown.py +251 -0
- connectonion/tui/footer.py +31 -0
- connectonion/tui/fuzzy.py +56 -0
- connectonion/tui/input.py +278 -0
- connectonion/tui/keys.py +35 -0
- connectonion/tui/pick.py +130 -0
- connectonion/tui/providers.py +155 -0
- connectonion/tui/status_bar.py +163 -0
- connectonion/usage.py +161 -0
- connectonion/useful_events_handlers/__init__.py +16 -0
- connectonion/useful_events_handlers/reflect.py +116 -0
- connectonion/useful_plugins/__init__.py +20 -0
- connectonion/useful_plugins/calendar_plugin.py +163 -0
- connectonion/useful_plugins/eval.py +139 -0
- connectonion/useful_plugins/gmail_plugin.py +162 -0
- connectonion/useful_plugins/image_result_formatter.py +127 -0
- connectonion/useful_plugins/re_act.py +78 -0
- connectonion/useful_plugins/shell_approval.py +159 -0
- connectonion/useful_tools/__init__.py +44 -0
- connectonion/useful_tools/diff_writer.py +192 -0
- connectonion/useful_tools/get_emails.py +183 -0
- connectonion/useful_tools/gmail.py +1596 -0
- connectonion/useful_tools/google_calendar.py +613 -0
- connectonion/useful_tools/memory.py +380 -0
- connectonion/useful_tools/microsoft_calendar.py +604 -0
- connectonion/useful_tools/outlook.py +488 -0
- connectonion/useful_tools/send_email.py +205 -0
- connectonion/useful_tools/shell.py +97 -0
- connectonion/useful_tools/slash_command.py +201 -0
- connectonion/useful_tools/terminal.py +285 -0
- connectonion/useful_tools/todo_list.py +241 -0
- connectonion/useful_tools/web_fetch.py +216 -0
- connectonion/xray.py +467 -0
- connectonion-0.5.8.dist-info/METADATA +741 -0
- connectonion-0.5.8.dist-info/RECORD +113 -0
- connectonion-0.5.8.dist-info/WHEEL +4 -0
- connectonion-0.5.8.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>ConnectOnion API</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root{
|
|
9
|
+
--bg: #1a1a1a;
|
|
10
|
+
--panel: #1c1c1e;
|
|
11
|
+
--panel-border: #2d2d2d;
|
|
12
|
+
--text: #e6edf3;
|
|
13
|
+
--muted: #8b98a5;
|
|
14
|
+
--accent: #49cc90;
|
|
15
|
+
--accent-hover: #3db37c;
|
|
16
|
+
--get: #61affe;
|
|
17
|
+
--post: #49cc90;
|
|
18
|
+
--delete: #f93e3e;
|
|
19
|
+
--ws: #9b59b6;
|
|
20
|
+
--code: #0d0d0d;
|
|
21
|
+
--chip: #2a2a2a;
|
|
22
|
+
--shadow: 0 1px 2px rgba(0,0,0,0.3);
|
|
23
|
+
}
|
|
24
|
+
@media (prefers-color-scheme: light){
|
|
25
|
+
:root{
|
|
26
|
+
--bg: #fafafa;
|
|
27
|
+
--panel: #ffffff;
|
|
28
|
+
--panel-border: #e0e0e0;
|
|
29
|
+
--text: #3b4151;
|
|
30
|
+
--muted: #6b7280;
|
|
31
|
+
--code: #f5f5f5;
|
|
32
|
+
--chip: #f0f0f0;
|
|
33
|
+
--shadow: 0 1px 2px rgba(0,0,0,0.1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
*{ box-sizing: border-box; }
|
|
37
|
+
html, body { height: 100%; }
|
|
38
|
+
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
|
|
39
|
+
|
|
40
|
+
/* Header - Swagger style */
|
|
41
|
+
header { background: #1f1f1f; border-bottom: 1px solid #333; padding: 12px 20px; }
|
|
42
|
+
header .container { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
|
|
43
|
+
.brand { display: flex; align-items: center; gap: 10px; }
|
|
44
|
+
.brand .logo { width: 32px; height: 32px; background: linear-gradient(135deg, #49cc90, #38a169); border-radius: 6px; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #fff; font-size: 16px; }
|
|
45
|
+
.brand .title { color: #fff; font-size: 18px; font-weight: 600; }
|
|
46
|
+
.brand .version { background: #49cc90; color: #000; font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 600; }
|
|
47
|
+
.server-form { display: flex; align-items: center; gap: 8px; }
|
|
48
|
+
.server-form input { height: 40px; background: #333; border: 1px solid #444; border-radius: 4px; color: #fff; padding: 0 12px; min-width: 280px; font-size: 13px; transition: border-color 0.15s ease; }
|
|
49
|
+
.server-form input:focus { outline: none; border-color: #49cc90; }
|
|
50
|
+
.server-form button { height: 40px; min-height: 40px; background: #4990e2; border: none; border-radius: 4px; color: #fff; padding: 0 16px; cursor: pointer; font-weight: 500; transition: background 0.15s ease; }
|
|
51
|
+
.server-form button:hover { background: #3a7bc8; }
|
|
52
|
+
.server-form button:focus { outline: 2px solid #49cc90; outline-offset: 2px; }
|
|
53
|
+
|
|
54
|
+
/* Main content */
|
|
55
|
+
main { max-width: 1200px; margin: 0 auto; padding: 20px; }
|
|
56
|
+
|
|
57
|
+
/* Info bar */
|
|
58
|
+
.info-bar { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 4px; margin-bottom: 20px; }
|
|
59
|
+
.info-bar summary { padding: 12px 16px; cursor: pointer; font-weight: 600; display: flex; align-items: center; gap: 12px; }
|
|
60
|
+
.info-bar summary::-webkit-details-marker { display: none; }
|
|
61
|
+
.info-bar summary::before { content: "▶"; font-size: 10px; transition: transform 0.2s; }
|
|
62
|
+
.info-bar[open] summary::before { transform: rotate(90deg); }
|
|
63
|
+
.info-bar .content { padding: 0 16px 16px; border-top: 1px solid var(--panel-border); }
|
|
64
|
+
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-top: 12px; }
|
|
65
|
+
.info-item { display: flex; flex-direction: column; gap: 2px; }
|
|
66
|
+
.info-item .label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }
|
|
67
|
+
.info-item .value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
|
|
68
|
+
.trust-badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 600; }
|
|
69
|
+
.trust-badge.open { background: #61affe20; color: #61affe; }
|
|
70
|
+
.trust-badge.careful { background: #f59e0b20; color: #f59e0b; }
|
|
71
|
+
.trust-badge.strict { background: #f93e3e20; color: #f93e3e; }
|
|
72
|
+
|
|
73
|
+
/* Endpoint cards - Swagger style */
|
|
74
|
+
.endpoint { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 4px; margin-bottom: 12px; overflow: hidden; transition: border-color 0.15s ease; }
|
|
75
|
+
.endpoint:hover { border-color: var(--muted); }
|
|
76
|
+
.endpoint-header { display: flex; align-items: center; gap: 12px; padding: 10px 16px; cursor: pointer; min-height: 48px; transition: background 0.15s ease; }
|
|
77
|
+
.endpoint-header:hover { background: rgba(255,255,255,0.03); }
|
|
78
|
+
.method { padding: 6px 12px; border-radius: 3px; font-size: 12px; font-weight: 700; text-transform: uppercase; min-width: 70px; text-align: center; }
|
|
79
|
+
.method.get { background: var(--get); color: #fff; }
|
|
80
|
+
.method.post { background: var(--post); color: #fff; }
|
|
81
|
+
.method.delete { background: var(--delete); color: #fff; }
|
|
82
|
+
.method.ws { background: var(--ws); color: #fff; }
|
|
83
|
+
.endpoint-path { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; font-weight: 600; }
|
|
84
|
+
.endpoint-desc { color: var(--muted); font-size: 13px; margin-left: auto; }
|
|
85
|
+
.endpoint-expand { color: var(--muted); font-size: 18px; margin-left: 8px; transition: transform 0.2s; }
|
|
86
|
+
.endpoint[open] .endpoint-expand { transform: rotate(180deg); }
|
|
87
|
+
|
|
88
|
+
.endpoint-body { border-top: 1px solid var(--panel-border); padding: 16px; background: rgba(0,0,0,0.1); }
|
|
89
|
+
.endpoint-section { margin-bottom: 16px; }
|
|
90
|
+
.endpoint-section:last-child { margin-bottom: 0; }
|
|
91
|
+
.endpoint-section h4 { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin: 0 0 8px; }
|
|
92
|
+
|
|
93
|
+
/* Form elements */
|
|
94
|
+
label { font-size: 12px; color: var(--muted); margin-bottom: 4px; display: block; }
|
|
95
|
+
textarea, input[type="text"] { width: 100%; background: var(--code); border: 1px solid var(--panel-border); color: var(--text); border-radius: 4px; padding: 10px 12px; outline: none; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
|
|
96
|
+
textarea { min-height: 100px; resize: vertical; }
|
|
97
|
+
textarea:focus, input[type="text"]:focus { border-color: var(--accent); }
|
|
98
|
+
|
|
99
|
+
/* Buttons */
|
|
100
|
+
.btn { padding: 10px 16px; min-height: 44px; border-radius: 4px; border: 1px solid var(--panel-border); background: var(--chip); color: var(--text); cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.15s ease; }
|
|
101
|
+
.btn:hover { filter: brightness(1.1); }
|
|
102
|
+
.btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
103
|
+
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
104
|
+
.btn.execute { background: var(--accent); color: #000; border: none; font-weight: 600; }
|
|
105
|
+
.btn.execute:hover { background: var(--accent-hover); }
|
|
106
|
+
.btn.connect { background: var(--ws); color: #fff; border: none; }
|
|
107
|
+
.btn.connect:hover { background: #8e44ad; }
|
|
108
|
+
|
|
109
|
+
/* Response area */
|
|
110
|
+
pre { background: var(--code); padding: 12px; border-radius: 4px; overflow: auto; border: 1px solid var(--panel-border); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; margin: 0; max-height: 300px; }
|
|
111
|
+
|
|
112
|
+
/* Row helpers */
|
|
113
|
+
.row { display: flex; gap: 8px; align-items: center; }
|
|
114
|
+
.row.between { justify-content: space-between; }
|
|
115
|
+
|
|
116
|
+
/* Schema section */
|
|
117
|
+
.schema { background: var(--code); border: 1px solid var(--panel-border); border-radius: 4px; padding: 12px; margin-top: 8px; }
|
|
118
|
+
.schema-title { font-size: 11px; color: var(--muted); text-transform: uppercase; margin-bottom: 8px; }
|
|
119
|
+
.schema-content { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; white-space: pre-wrap; }
|
|
120
|
+
|
|
121
|
+
/* WebSocket log */
|
|
122
|
+
#ws-log { height: 200px; overflow: auto; background: #0a0a0a; color: #e6e6e6; padding: 12px; border-radius: 4px; border: 1px solid var(--panel-border); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
|
|
123
|
+
|
|
124
|
+
/* Notes section */
|
|
125
|
+
.notes { background: var(--panel); border: 1px solid var(--panel-border); border-radius: 4px; padding: 16px; margin-top: 20px; }
|
|
126
|
+
.notes h3 { margin: 0 0 12px; font-size: 14px; }
|
|
127
|
+
.notes ul { margin: 0; padding-left: 20px; color: var(--muted); font-size: 13px; }
|
|
128
|
+
.notes li { margin-bottom: 4px; }
|
|
129
|
+
.notes code { background: var(--code); padding: 2px 6px; border-radius: 3px; font-size: 12px; }
|
|
130
|
+
|
|
131
|
+
/* Status indicator */
|
|
132
|
+
.status { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
|
|
133
|
+
.status .dot { width: 8px; height: 8px; border-radius: 50%; }
|
|
134
|
+
.status .dot.connected { background: #49cc90; box-shadow: 0 0 8px #49cc90; }
|
|
135
|
+
.status .dot.disconnected { background: #666; }
|
|
136
|
+
|
|
137
|
+
/* Curl box - Swagger style */
|
|
138
|
+
.curl-box { position: relative; background: #333; border-radius: 4px; }
|
|
139
|
+
.curl-box pre { background: #333; color: #fff; border: none; margin: 0; padding: 12px 70px 12px 12px; white-space: pre-wrap; word-break: break-all; }
|
|
140
|
+
.curl-box .copy-btn { position: absolute; top: 50%; right: 8px; transform: translateY(-50%); background: #444; border: 1px solid #555; color: #ccc; padding: 8px 12px; min-height: 36px; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; transition: all 0.15s ease; }
|
|
141
|
+
.curl-box .copy-btn:hover { background: #555; color: #fff; }
|
|
142
|
+
.curl-box .copy-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
143
|
+
</style>
|
|
144
|
+
</head>
|
|
145
|
+
<body>
|
|
146
|
+
<header>
|
|
147
|
+
<div class="container">
|
|
148
|
+
<div class="brand">
|
|
149
|
+
<div class="logo">CO</div>
|
|
150
|
+
<span class="title">ConnectOnion</span>
|
|
151
|
+
<span class="version" id="hdr-version">v0.0.0</span>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="server-form">
|
|
154
|
+
<input id="server-url" placeholder="Server URL (e.g. http://localhost:8000)" />
|
|
155
|
+
<button onclick="applyServerUrl()">Explore</button>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</header>
|
|
159
|
+
|
|
160
|
+
<main>
|
|
161
|
+
<!-- Agent Info Bar -->
|
|
162
|
+
<details class="info-bar" open>
|
|
163
|
+
<summary>
|
|
164
|
+
<span id="hdr-name">Agent</span>
|
|
165
|
+
<span class="trust-badge open" id="hdr-trust">open</span>
|
|
166
|
+
</summary>
|
|
167
|
+
<div class="content">
|
|
168
|
+
<div class="info-grid">
|
|
169
|
+
<div class="info-item">
|
|
170
|
+
<span class="label">Name</span>
|
|
171
|
+
<span class="value" id="agent-name">-</span>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="info-item">
|
|
174
|
+
<span class="label">Trust Level</span>
|
|
175
|
+
<span class="value" id="agent-trust">-</span>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="info-item">
|
|
178
|
+
<span class="label">Address</span>
|
|
179
|
+
<span class="value"><code id="agent-address">-</code> <button class="btn" style="padding:6px 10px;font-size:11px;min-height:32px;" onclick="copyText('agent-address')">Copy</button></span>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="info-item">
|
|
182
|
+
<span class="label">Tools</span>
|
|
183
|
+
<span class="value" id="agent-tools">-</span>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</details>
|
|
188
|
+
|
|
189
|
+
<!-- POST /input -->
|
|
190
|
+
<details class="endpoint" open>
|
|
191
|
+
<summary class="endpoint-header">
|
|
192
|
+
<span class="method post">POST</span>
|
|
193
|
+
<span class="endpoint-path">/input</span>
|
|
194
|
+
<span class="endpoint-desc">Send a prompt to the agent</span>
|
|
195
|
+
<span class="endpoint-expand">▾</span>
|
|
196
|
+
</summary>
|
|
197
|
+
<div class="endpoint-body">
|
|
198
|
+
<div class="endpoint-section">
|
|
199
|
+
<h4>Request Body</h4>
|
|
200
|
+
<label for="prompt">prompt <span style="color:var(--muted)">string</span></label>
|
|
201
|
+
<textarea id="prompt" placeholder="Type your prompt here..."></textarea>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<details style="margin-bottom:16px;">
|
|
205
|
+
<summary style="cursor:pointer;font-size:12px;color:var(--muted);">▶ Signed Request (optional)</summary>
|
|
206
|
+
<div style="padding-top:12px;">
|
|
207
|
+
<div class="schema">
|
|
208
|
+
<div class="schema-title">Payload Preview</div>
|
|
209
|
+
<pre id="payload-preview" style="border:none;padding:0;background:transparent;"></pre>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="row" style="margin:12px 0;">
|
|
212
|
+
<button class="btn" onclick="copyPayload()">Copy Payload</button>
|
|
213
|
+
<span style="font-size:11px;color:var(--muted);">Sign externally. Never paste private keys here.</span>
|
|
214
|
+
</div>
|
|
215
|
+
<label for="from">from <span style="color:var(--muted)">string - public key</span></label>
|
|
216
|
+
<input type="text" id="from" placeholder="0xPublicKey" style="margin-bottom:8px;" />
|
|
217
|
+
<label for="signature">signature <span style="color:var(--muted)">string</span></label>
|
|
218
|
+
<input type="text" id="signature" placeholder="0xSignature" />
|
|
219
|
+
</div>
|
|
220
|
+
</details>
|
|
221
|
+
|
|
222
|
+
<div class="row">
|
|
223
|
+
<button class="btn execute" onclick="submitHttp()">Execute</button>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div class="endpoint-section" style="margin-top:16px;">
|
|
227
|
+
<h4>Curl</h4>
|
|
228
|
+
<div class="curl-box">
|
|
229
|
+
<pre id="input-curl">curl -X POST "http://localhost:8000/input" \
|
|
230
|
+
-H "Content-Type: application/json" \
|
|
231
|
+
-d '{"prompt": "hello"}'</pre>
|
|
232
|
+
<button class="copy-btn" onclick="copyCurl('input-curl')">Copy</button>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div class="endpoint-section">
|
|
237
|
+
<h4>Response</h4>
|
|
238
|
+
<pre id="http-result">{ }</pre>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</details>
|
|
242
|
+
|
|
243
|
+
<!-- GET /sessions -->
|
|
244
|
+
<details class="endpoint">
|
|
245
|
+
<summary class="endpoint-header">
|
|
246
|
+
<span class="method get">GET</span>
|
|
247
|
+
<span class="endpoint-path">/sessions</span>
|
|
248
|
+
<span class="endpoint-desc">List all sessions</span>
|
|
249
|
+
<span class="endpoint-expand">▾</span>
|
|
250
|
+
</summary>
|
|
251
|
+
<div class="endpoint-body">
|
|
252
|
+
<div class="row between" style="margin-bottom:12px;">
|
|
253
|
+
<button class="btn execute" onclick="refreshSessions()">Execute</button>
|
|
254
|
+
<label class="row" style="gap:6px;margin:0;">
|
|
255
|
+
<input type="checkbox" id="auto" onchange="toggleAuto()" /> Auto-refresh
|
|
256
|
+
</label>
|
|
257
|
+
</div>
|
|
258
|
+
<div class="endpoint-section">
|
|
259
|
+
<h4>Curl</h4>
|
|
260
|
+
<div class="curl-box">
|
|
261
|
+
<pre id="sessions-curl">curl -X GET "http://localhost:8000/sessions"</pre>
|
|
262
|
+
<button class="copy-btn" onclick="copyCurl('sessions-curl')">Copy</button>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
<div class="endpoint-section">
|
|
266
|
+
<h4>Response</h4>
|
|
267
|
+
<pre id="sessions">{ }</pre>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</details>
|
|
271
|
+
|
|
272
|
+
<!-- GET /sessions/{session_id} -->
|
|
273
|
+
<details class="endpoint">
|
|
274
|
+
<summary class="endpoint-header">
|
|
275
|
+
<span class="method get">GET</span>
|
|
276
|
+
<span class="endpoint-path">/sessions/{session_id}</span>
|
|
277
|
+
<span class="endpoint-desc">Get single session by ID</span>
|
|
278
|
+
<span class="endpoint-expand">▾</span>
|
|
279
|
+
</summary>
|
|
280
|
+
<div class="endpoint-body">
|
|
281
|
+
<div class="endpoint-section">
|
|
282
|
+
<h4>Parameters</h4>
|
|
283
|
+
<label for="session-id">session_id <span style="color:var(--muted)">string (path)</span></label>
|
|
284
|
+
<input type="text" id="session-id" placeholder="Enter session ID..." style="margin-bottom:12px;" />
|
|
285
|
+
</div>
|
|
286
|
+
<button class="btn execute" onclick="fetchSession()">Execute</button>
|
|
287
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
288
|
+
<h4>Curl</h4>
|
|
289
|
+
<div class="curl-box">
|
|
290
|
+
<pre id="session-curl">curl -X GET "http://localhost:8000/sessions/{session_id}"</pre>
|
|
291
|
+
<button class="copy-btn" onclick="copyCurl('session-curl')">Copy</button>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="endpoint-section">
|
|
295
|
+
<h4>Response</h4>
|
|
296
|
+
<pre id="session-result">{ }</pre>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
</details>
|
|
300
|
+
|
|
301
|
+
<!-- GET /info -->
|
|
302
|
+
<details class="endpoint">
|
|
303
|
+
<summary class="endpoint-header">
|
|
304
|
+
<span class="method get">GET</span>
|
|
305
|
+
<span class="endpoint-path">/info</span>
|
|
306
|
+
<span class="endpoint-desc">Get agent metadata</span>
|
|
307
|
+
<span class="endpoint-expand">▾</span>
|
|
308
|
+
</summary>
|
|
309
|
+
<div class="endpoint-body">
|
|
310
|
+
<button class="btn execute" onclick="fetchInfo()">Execute</button>
|
|
311
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
312
|
+
<h4>Curl</h4>
|
|
313
|
+
<div class="curl-box">
|
|
314
|
+
<pre id="info-curl">curl -X GET "http://localhost:8000/info"</pre>
|
|
315
|
+
<button class="copy-btn" onclick="copyCurl('info-curl')">Copy</button>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
<div class="endpoint-section">
|
|
319
|
+
<h4>Response</h4>
|
|
320
|
+
<pre id="info-result">{ }</pre>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
</details>
|
|
324
|
+
|
|
325
|
+
<!-- GET /health -->
|
|
326
|
+
<details class="endpoint">
|
|
327
|
+
<summary class="endpoint-header">
|
|
328
|
+
<span class="method get">GET</span>
|
|
329
|
+
<span class="endpoint-path">/health</span>
|
|
330
|
+
<span class="endpoint-desc">Health check endpoint</span>
|
|
331
|
+
<span class="endpoint-expand">▾</span>
|
|
332
|
+
</summary>
|
|
333
|
+
<div class="endpoint-body">
|
|
334
|
+
<button class="btn execute" onclick="fetchHealth()">Execute</button>
|
|
335
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
336
|
+
<h4>Curl</h4>
|
|
337
|
+
<div class="curl-box">
|
|
338
|
+
<pre id="health-curl">curl -X GET "http://localhost:8000/health"</pre>
|
|
339
|
+
<button class="copy-btn" onclick="copyCurl('health-curl')">Copy</button>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="endpoint-section">
|
|
343
|
+
<h4>Response</h4>
|
|
344
|
+
<pre id="health-result">{ }</pre>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
</details>
|
|
348
|
+
|
|
349
|
+
<!-- GET /docs -->
|
|
350
|
+
<details class="endpoint">
|
|
351
|
+
<summary class="endpoint-header">
|
|
352
|
+
<span class="method get">GET</span>
|
|
353
|
+
<span class="endpoint-path">/docs</span>
|
|
354
|
+
<span class="endpoint-desc">This documentation page</span>
|
|
355
|
+
<span class="endpoint-expand">▾</span>
|
|
356
|
+
</summary>
|
|
357
|
+
<div class="endpoint-body">
|
|
358
|
+
<div class="endpoint-section">
|
|
359
|
+
<h4>Curl</h4>
|
|
360
|
+
<div class="curl-box">
|
|
361
|
+
<pre id="docs-curl">curl -X GET "http://localhost:8000/docs"</pre>
|
|
362
|
+
<button class="copy-btn" onclick="copyCurl('docs-curl')">Copy</button>
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
<p style="color:var(--muted);font-size:13px;margin:8px 0 0;">Returns this HTML page.</p>
|
|
366
|
+
</div>
|
|
367
|
+
</details>
|
|
368
|
+
|
|
369
|
+
<!-- Admin Endpoints Header -->
|
|
370
|
+
<div style="margin:24px 0 12px;padding:12px 16px;background:var(--panel);border:1px solid var(--panel-border);border-radius:4px;">
|
|
371
|
+
<div class="row between">
|
|
372
|
+
<div>
|
|
373
|
+
<h3 style="margin:0;font-size:14px;">Admin Endpoints</h3>
|
|
374
|
+
<p style="margin:4px 0 0;font-size:12px;color:var(--muted);">Requires OPENONION_API_KEY authorization</p>
|
|
375
|
+
</div>
|
|
376
|
+
<div class="row" style="gap:8px;">
|
|
377
|
+
<label for="api-key" style="font-size:12px;margin:0;">API Key:</label>
|
|
378
|
+
<input type="password" id="api-key" placeholder="Enter API key..." style="width:200px;height:36px;font-size:12px;" />
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
</div>
|
|
382
|
+
|
|
383
|
+
<!-- GET /admin/logs -->
|
|
384
|
+
<details class="endpoint">
|
|
385
|
+
<summary class="endpoint-header">
|
|
386
|
+
<span class="method get">GET</span>
|
|
387
|
+
<span class="endpoint-path">/admin/logs</span>
|
|
388
|
+
<span class="endpoint-desc">Get agent activity logs (auth required)</span>
|
|
389
|
+
<span class="endpoint-expand">▾</span>
|
|
390
|
+
</summary>
|
|
391
|
+
<div class="endpoint-body">
|
|
392
|
+
<button class="btn execute" onclick="fetchAdminLogs()">Execute</button>
|
|
393
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
394
|
+
<h4>Curl</h4>
|
|
395
|
+
<div class="curl-box">
|
|
396
|
+
<pre id="admin-logs-curl">curl -X GET "http://localhost:8000/admin/logs" \
|
|
397
|
+
-H "Authorization: Bearer YOUR_API_KEY"</pre>
|
|
398
|
+
<button class="copy-btn" onclick="copyCurl('admin-logs-curl')">Copy</button>
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
<div class="endpoint-section">
|
|
402
|
+
<h4>Response</h4>
|
|
403
|
+
<pre id="admin-logs-result" style="max-height:400px;">{ }</pre>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
</details>
|
|
407
|
+
|
|
408
|
+
<!-- GET /admin/sessions -->
|
|
409
|
+
<details class="endpoint">
|
|
410
|
+
<summary class="endpoint-header">
|
|
411
|
+
<span class="method get">GET</span>
|
|
412
|
+
<span class="endpoint-path">/admin/sessions</span>
|
|
413
|
+
<span class="endpoint-desc">Get all activity sessions (auth required)</span>
|
|
414
|
+
<span class="endpoint-expand">▾</span>
|
|
415
|
+
</summary>
|
|
416
|
+
<div class="endpoint-body">
|
|
417
|
+
<button class="btn execute" onclick="fetchAdminSessions()">Execute</button>
|
|
418
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
419
|
+
<h4>Curl</h4>
|
|
420
|
+
<div class="curl-box">
|
|
421
|
+
<pre id="admin-sessions-curl">curl -X GET "http://localhost:8000/admin/sessions" \
|
|
422
|
+
-H "Authorization: Bearer YOUR_API_KEY"</pre>
|
|
423
|
+
<button class="copy-btn" onclick="copyCurl('admin-sessions-curl')">Copy</button>
|
|
424
|
+
</div>
|
|
425
|
+
</div>
|
|
426
|
+
<div class="endpoint-section">
|
|
427
|
+
<h4>Response</h4>
|
|
428
|
+
<pre id="admin-sessions-result" style="max-height:400px;">{ }</pre>
|
|
429
|
+
</div>
|
|
430
|
+
</div>
|
|
431
|
+
</details>
|
|
432
|
+
|
|
433
|
+
<!-- WebSocket /ws -->
|
|
434
|
+
<details class="endpoint">
|
|
435
|
+
<summary class="endpoint-header">
|
|
436
|
+
<span class="method ws">WS</span>
|
|
437
|
+
<span class="endpoint-path">/ws</span>
|
|
438
|
+
<span class="endpoint-desc">WebSocket streaming connection</span>
|
|
439
|
+
<span class="endpoint-expand">▾</span>
|
|
440
|
+
</summary>
|
|
441
|
+
<div class="endpoint-body">
|
|
442
|
+
<div class="row between" style="margin-bottom:12px;">
|
|
443
|
+
<div class="row">
|
|
444
|
+
<button class="btn connect" onclick="openWs()" id="ws-open">Connect</button>
|
|
445
|
+
<button class="btn" onclick="closeWs()" id="ws-close" disabled>Disconnect</button>
|
|
446
|
+
</div>
|
|
447
|
+
<span class="status">
|
|
448
|
+
<span class="dot disconnected" id="ws-status"></span>
|
|
449
|
+
<span id="ws-status-text">Disconnected</span>
|
|
450
|
+
</span>
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<div class="endpoint-section">
|
|
454
|
+
<h4>Send Message</h4>
|
|
455
|
+
<div class="row">
|
|
456
|
+
<input type="text" id="ws-prompt" placeholder="Type message..." style="flex:1;" />
|
|
457
|
+
<button class="btn execute" onclick="sendWs()" id="ws-send" disabled>Send</button>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
462
|
+
<h4>Connection</h4>
|
|
463
|
+
<div class="curl-box">
|
|
464
|
+
<pre id="ws-curl">websocat ws://localhost:8000/ws</pre>
|
|
465
|
+
<button class="copy-btn" onclick="copyCurl('ws-curl')">Copy</button>
|
|
466
|
+
</div>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<div class="endpoint-section" style="margin-top:12px;">
|
|
470
|
+
<h4>Messages</h4>
|
|
471
|
+
<div id="ws-log"></div>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</details>
|
|
475
|
+
|
|
476
|
+
<!-- Notes -->
|
|
477
|
+
<div class="notes">
|
|
478
|
+
<h3>Trust Levels</h3>
|
|
479
|
+
<ul>
|
|
480
|
+
<li><code>open</code> - Unsigned requests accepted (development)</li>
|
|
481
|
+
<li><code>careful</code> - If signature present, must be valid</li>
|
|
482
|
+
<li><code>strict</code> - Signature required (production)</li>
|
|
483
|
+
</ul>
|
|
484
|
+
<p style="margin:12px 0 0;font-size:12px;color:var(--muted);">
|
|
485
|
+
For signed requests: <code>payload.to</code> should match agent address, <code>payload.timestamp</code> should be within 5 minutes.
|
|
486
|
+
</p>
|
|
487
|
+
</div>
|
|
488
|
+
</main>
|
|
489
|
+
|
|
490
|
+
<script>
|
|
491
|
+
let ws; let autoTimer; let BASE = '';
|
|
492
|
+
function $(id){ return document.getElementById(id); }
|
|
493
|
+
function now(){ return new Date().toLocaleTimeString(); }
|
|
494
|
+
function log(msg){ const el=$('ws-log'); el.textContent += `[${now()}] ${msg}\n`; el.scrollTop = el.scrollHeight; }
|
|
495
|
+
function copyText(id){ navigator.clipboard.writeText($(id).textContent); }
|
|
496
|
+
function copyPayload(){ navigator.clipboard.writeText($('payload-preview').textContent); }
|
|
497
|
+
function copyCurl(id){ navigator.clipboard.writeText($(id).textContent); }
|
|
498
|
+
|
|
499
|
+
function originBase(){ try { return location.origin; } catch { return ''; } }
|
|
500
|
+
|
|
501
|
+
async function loadInfo(){
|
|
502
|
+
try {
|
|
503
|
+
const res = await fetch(buildUrl('/info'));
|
|
504
|
+
const info = await res.json();
|
|
505
|
+
$('agent-name').textContent = info.name;
|
|
506
|
+
$('agent-trust').textContent = info.trust;
|
|
507
|
+
$('agent-address').textContent = info.address || '-';
|
|
508
|
+
$('agent-tools').textContent = (info.tools||[]).join(', ') || '-';
|
|
509
|
+
// Header
|
|
510
|
+
$('hdr-name').textContent = info.name;
|
|
511
|
+
$('hdr-version').textContent = 'v' + info.version;
|
|
512
|
+
const trustEl = $('hdr-trust');
|
|
513
|
+
trustEl.textContent = info.trust;
|
|
514
|
+
trustEl.className = 'trust-badge ' + (info.trust||'').toLowerCase();
|
|
515
|
+
updatePayloadPreview();
|
|
516
|
+
} catch(e) { console.error(e); }
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
async function fetchInfo(){
|
|
520
|
+
const res = await fetch(buildUrl('/info'));
|
|
521
|
+
const data = await res.json();
|
|
522
|
+
$('info-result').textContent = JSON.stringify(data, null, 2);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
async function fetchSession(){
|
|
526
|
+
const sessionId = $('session-id').value.trim();
|
|
527
|
+
if (!sessionId) {
|
|
528
|
+
$('session-result').textContent = '{"error": "Please enter a session ID"}';
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const res = await fetch(buildUrl('/sessions/' + sessionId));
|
|
532
|
+
const data = await res.json();
|
|
533
|
+
$('session-result').textContent = JSON.stringify(data, null, 2);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
async function fetchHealth(){
|
|
537
|
+
const res = await fetch(buildUrl('/health'));
|
|
538
|
+
const data = await res.json();
|
|
539
|
+
$('health-result').textContent = JSON.stringify(data, null, 2);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function updatePayloadPreview(){
|
|
543
|
+
const to = $('agent-address').textContent;
|
|
544
|
+
const payload = {
|
|
545
|
+
prompt: $('prompt').value || 'hello',
|
|
546
|
+
to: to && to !== '-' ? to : undefined,
|
|
547
|
+
timestamp: Math.floor(Date.now()/1000)
|
|
548
|
+
};
|
|
549
|
+
$('payload-preview').textContent = JSON.stringify(payload, null, 2);
|
|
550
|
+
updateCurlCommands();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function updateCurlCommands(){
|
|
554
|
+
const base = buildUrl('');
|
|
555
|
+
const prompt = $('prompt').value || 'hello';
|
|
556
|
+
const from = $('from').value.trim();
|
|
557
|
+
const signature = $('signature').value.trim();
|
|
558
|
+
|
|
559
|
+
// POST /input curl
|
|
560
|
+
let inputBody;
|
|
561
|
+
if (from && signature) {
|
|
562
|
+
const payload = JSON.parse($('payload-preview').textContent);
|
|
563
|
+
inputBody = JSON.stringify({ payload, from, signature });
|
|
564
|
+
} else {
|
|
565
|
+
inputBody = JSON.stringify({ prompt });
|
|
566
|
+
}
|
|
567
|
+
$('input-curl').textContent = `curl -X POST "${base}/input" \\
|
|
568
|
+
-H "Content-Type: application/json" \\
|
|
569
|
+
-d '${inputBody}'`;
|
|
570
|
+
|
|
571
|
+
// GET /sessions curl
|
|
572
|
+
$('sessions-curl').textContent = `curl -X GET "${base}/sessions"`;
|
|
573
|
+
|
|
574
|
+
// GET /sessions/{session_id} curl
|
|
575
|
+
const sessionId = $('session-id').value.trim() || '{session_id}';
|
|
576
|
+
$('session-curl').textContent = `curl -X GET "${base}/sessions/${sessionId}"`;
|
|
577
|
+
|
|
578
|
+
// GET /info curl
|
|
579
|
+
$('info-curl').textContent = `curl -X GET "${base}/info"`;
|
|
580
|
+
|
|
581
|
+
// GET /health curl
|
|
582
|
+
$('health-curl').textContent = `curl -X GET "${base}/health"`;
|
|
583
|
+
|
|
584
|
+
// GET /docs curl
|
|
585
|
+
$('docs-curl').textContent = `curl -X GET "${base}/docs"`;
|
|
586
|
+
|
|
587
|
+
// WebSocket connection
|
|
588
|
+
const wsBase = base.replace(/^http/, 'ws');
|
|
589
|
+
$('ws-curl').textContent = `websocat ${wsBase}/ws`;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
async function submitHttp(){
|
|
593
|
+
const from = $('from').value.trim();
|
|
594
|
+
const signature = $('signature').value.trim();
|
|
595
|
+
let body;
|
|
596
|
+
if (from && signature){
|
|
597
|
+
body = { payload: JSON.parse($('payload-preview').textContent), from, signature };
|
|
598
|
+
} else {
|
|
599
|
+
body = { prompt: $('prompt').value };
|
|
600
|
+
}
|
|
601
|
+
$('http-result').textContent = 'Loading...';
|
|
602
|
+
const res = await fetch(buildUrl('/input'), { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(body)});
|
|
603
|
+
const data = await res.json();
|
|
604
|
+
$('http-result').textContent = JSON.stringify(data, null, 2);
|
|
605
|
+
refreshSessions();
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function openWs(){
|
|
609
|
+
const u = new URL(BASE || originBase() || window.location.origin);
|
|
610
|
+
const wsScheme = u.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
611
|
+
ws = new WebSocket(wsScheme + '//' + u.host + '/ws');
|
|
612
|
+
ws.onopen = ()=>{
|
|
613
|
+
$('ws-open').disabled=true; $('ws-close').disabled=false; $('ws-send').disabled=false;
|
|
614
|
+
$('ws-status').className='dot connected'; $('ws-status-text').textContent='Connected';
|
|
615
|
+
log('Connected');
|
|
616
|
+
};
|
|
617
|
+
ws.onclose= ()=>{
|
|
618
|
+
$('ws-open').disabled=false; $('ws-close').disabled=true; $('ws-send').disabled=true;
|
|
619
|
+
$('ws-status').className='dot disconnected'; $('ws-status-text').textContent='Disconnected';
|
|
620
|
+
log('Disconnected');
|
|
621
|
+
};
|
|
622
|
+
ws.onmessage = (ev)=>{ log(ev.data); };
|
|
623
|
+
}
|
|
624
|
+
function closeWs(){ if(ws){ ws.close(); } }
|
|
625
|
+
function sendWs(){ if(!ws) return; const msg = { type:'INPUT', prompt: $('ws-prompt').value }; ws.send(JSON.stringify(msg)); log('→ ' + JSON.stringify(msg)); }
|
|
626
|
+
|
|
627
|
+
async function refreshSessions(){
|
|
628
|
+
const res = await fetch(buildUrl('/sessions'));
|
|
629
|
+
const data = await res.json();
|
|
630
|
+
$('sessions').textContent = JSON.stringify(data, null, 2);
|
|
631
|
+
}
|
|
632
|
+
function toggleAuto(){ if($('auto').checked){ autoTimer=setInterval(refreshSessions, 5000); } else { clearInterval(autoTimer); } }
|
|
633
|
+
|
|
634
|
+
function buildUrl(path){
|
|
635
|
+
const base = (BASE || originBase() || '').replace(/\/$/, '');
|
|
636
|
+
return base + path;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function applyServerUrl(){
|
|
640
|
+
const v = $('server-url').value.trim();
|
|
641
|
+
if(!v) { BASE = ''; $('server-url').value = originBase(); }
|
|
642
|
+
else { try { const u = new URL(v); BASE = u.origin; } catch { BASE = v; } }
|
|
643
|
+
updateCurlCommands();
|
|
644
|
+
loadInfo(); refreshSessions();
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
async function fetchAdminLogs(){
|
|
648
|
+
const apiKey = $('api-key').value.trim();
|
|
649
|
+
if (!apiKey) {
|
|
650
|
+
$('admin-logs-result').textContent = '{"error": "Please enter API key"}';
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
$('admin-logs-result').textContent = 'Loading...';
|
|
654
|
+
const res = await fetch(buildUrl('/admin/logs'), {
|
|
655
|
+
headers: { 'Authorization': 'Bearer ' + apiKey }
|
|
656
|
+
});
|
|
657
|
+
if (res.ok) {
|
|
658
|
+
const text = await res.text();
|
|
659
|
+
$('admin-logs-result').textContent = text || '(empty)';
|
|
660
|
+
} else {
|
|
661
|
+
const data = await res.json().catch(() => ({ error: res.statusText }));
|
|
662
|
+
$('admin-logs-result').textContent = JSON.stringify(data, null, 2);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
async function fetchAdminSessions(){
|
|
667
|
+
const apiKey = $('api-key').value.trim();
|
|
668
|
+
if (!apiKey) {
|
|
669
|
+
$('admin-sessions-result').textContent = '{"error": "Please enter API key"}';
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
$('admin-sessions-result').textContent = 'Loading...';
|
|
673
|
+
const res = await fetch(buildUrl('/admin/sessions'), {
|
|
674
|
+
headers: { 'Authorization': 'Bearer ' + apiKey }
|
|
675
|
+
});
|
|
676
|
+
const data = await res.json();
|
|
677
|
+
$('admin-sessions-result').textContent = JSON.stringify(data, null, 2);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
$('prompt').addEventListener('input', updatePayloadPreview);
|
|
681
|
+
$('from').addEventListener('input', updateCurlCommands);
|
|
682
|
+
$('signature').addEventListener('input', updateCurlCommands);
|
|
683
|
+
$('session-id').addEventListener('input', updateCurlCommands);
|
|
684
|
+
$('server-url').value = originBase();
|
|
685
|
+
applyServerUrl();
|
|
686
|
+
</script>
|
|
687
|
+
</body>
|
|
688
|
+
</html>
|