@klars/agentobs 0.1.0 → 0.1.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.
@@ -1,196 +1,212 @@
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
- <meta name="color-scheme" content="light dark" />
7
- <title>AgentObs</title>
8
- <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>&#128200;</text></svg>" />
9
- <link rel="stylesheet" href="/app.css" />
10
- </head>
11
- <body>
12
- <a class="skip-link" href="#main">Skip to content</a>
13
-
14
- <header class="topbar">
15
- <div class="brand">
16
- <span class="brand-mark" aria-hidden="true"></span>
17
- <div>
18
- <h1>AgentObs</h1>
19
- <p class="brand-sub">Agent observability &amp; control</p>
20
- </div>
21
- </div>
22
-
23
- <div class="topbar-actions">
24
- <div class="rangeset" role="group" aria-label="Time range">
25
- <button type="button" data-range="today">Today</button>
26
- <button type="button" data-range="7d" aria-pressed="true">7 days</button>
27
- <button type="button" data-range="30d">30 days</button>
28
- <button type="button" data-range="all">All</button>
29
- </div>
30
- <button type="button" id="theme-toggle" class="icon-btn" aria-label="Switch theme">
31
- <span aria-hidden="true">◐</span>
32
- </button>
33
- </div>
34
- </header>
35
-
36
- <main id="main">
37
- <!-- Hero: exactly one per view - the number this dashboard exists to report. -->
38
- <section class="hero" aria-labelledby="hero-label">
39
- <div>
40
- <p class="hero-label" id="hero-label">Spend <span data-range-label>this week</span></p>
41
- <p class="hero-figure" id="hero-cost">—</p>
42
- <p class="hero-note" id="hero-note">No activity recorded yet.</p>
43
- </div>
44
- <dl class="hero-side">
45
- <div><dt>Tokens in</dt><dd id="hero-tokens-in">—</dd></div>
46
- <div><dt>Tokens out</dt><dd id="hero-tokens-out">—</dd></div>
47
- <div><dt>Avg duration</dt><dd id="hero-duration">—</dd></div>
48
- </dl>
49
- </section>
50
-
51
- <section class="tiles" aria-label="Key metrics">
52
- <article class="tile">
53
- <p class="tile-label">Tool calls</p>
54
- <p class="tile-value" id="stat-calls">—</p>
55
- <p class="tile-sub" id="stat-calls-sub">&nbsp;</p>
56
- </article>
57
- <article class="tile">
58
- <p class="tile-label">Sessions</p>
59
- <p class="tile-value" id="stat-sessions">—</p>
60
- <p class="tile-sub" id="stat-sessions-sub">&nbsp;</p>
61
- </article>
62
- <article class="tile">
63
- <p class="tile-label">Error rate</p>
64
- <p class="tile-value" id="stat-errors">—</p>
65
- <p class="tile-sub" id="stat-errors-sub">&nbsp;</p>
66
- </article>
67
- <article class="tile">
68
- <p class="tile-label">Blocked</p>
69
- <p class="tile-value" id="stat-blocked">—</p>
70
- <p class="tile-sub" id="stat-blocked-sub">by policy</p>
71
- </article>
72
- </section>
73
-
74
- <section class="panel" aria-labelledby="timeline-title">
75
- <div class="panel-head">
76
- <div>
77
- <h2 id="timeline-title">Activity over time</h2>
78
- <p class="panel-sub">Tool calls per bucket, errors marked separately.</p>
79
- </div>
80
- <div class="legend" id="timeline-legend">
81
- <span class="legend-item"><i class="swatch swatch-calls"></i>Calls</span>
82
- <span class="legend-item"><i class="swatch swatch-errors"></i>Errors</span>
83
- </div>
84
- </div>
85
- <div class="chart-wrap">
86
- <canvas id="timeline" height="220" aria-describedby="timeline-table-note"></canvas>
87
- <div class="tooltip" id="timeline-tip" role="status" aria-live="polite"></div>
88
- </div>
89
- <p class="panel-note" id="timeline-table-note">
90
- <button type="button" class="linklike" data-toggle-table="timeline">
91
- Show data table
92
- </button>
93
- </p>
94
- <div class="table-wrap is-hidden" data-table="timeline">
95
- <table>
96
- <caption class="sr-only">Activity over time, as a table</caption>
97
- <thead>
98
- <tr><th scope="col">Bucket</th><th scope="col">Calls</th><th scope="col">Errors</th><th scope="col">Cost</th></tr>
99
- </thead>
100
- <tbody id="timeline-table-body"></tbody>
101
- </table>
102
- </div>
103
- </section>
104
-
105
- <div class="split">
106
- <section class="panel" aria-labelledby="tools-title">
107
- <div class="panel-head">
108
- <div>
109
- <h2 id="tools-title">Tools</h2>
110
- <p class="panel-sub">Where the calls and the money go.</p>
111
- </div>
112
- </div>
113
- <div class="table-wrap">
114
- <table>
115
- <thead>
116
- <tr>
117
- <th scope="col">Tool</th>
118
- <th scope="col" class="num">Calls</th>
119
- <th scope="col" class="num">Errors</th>
120
- <th scope="col" class="num">Avg ms</th>
121
- <th scope="col" class="num">Cost</th>
122
- </tr>
123
- </thead>
124
- <tbody id="tools-body">
125
- <tr><td colspan="5" class="empty">No tool calls recorded yet.</td></tr>
126
- </tbody>
127
- </table>
128
- </div>
129
- </section>
130
-
131
- <section class="panel" aria-labelledby="sessions-title">
132
- <div class="panel-head">
133
- <div>
134
- <h2 id="sessions-title">Sessions</h2>
135
- <p class="panel-sub">Coarse sessions show only duration and exit code.</p>
136
- </div>
137
- </div>
138
- <div class="table-wrap">
139
- <table>
140
- <thead>
141
- <tr>
142
- <th scope="col">Agent</th>
143
- <th scope="col">Started</th>
144
- <th scope="col" class="num">Calls</th>
145
- <th scope="col" class="num">Cost</th>
146
- </tr>
147
- </thead>
148
- <tbody id="sessions-body">
149
- <tr><td colspan="4" class="empty">No sessions yet.</td></tr>
150
- </tbody>
151
- </table>
152
- </div>
153
- </section>
154
- </div>
155
-
156
- <section class="panel" aria-labelledby="activity-title">
157
- <div class="panel-head">
158
- <div>
159
- <h2 id="activity-title">Recent activity</h2>
160
- <p class="panel-sub">Inputs are truncated and secret-redacted before storage.</p>
161
- </div>
162
- <div class="filterset" role="group" aria-label="Filter by status">
163
- <button type="button" data-status="" aria-pressed="true">All</button>
164
- <button type="button" data-status="success">Success</button>
165
- <button type="button" data-status="error">Errors</button>
166
- <button type="button" data-status="blocked">Blocked</button>
167
- </div>
168
- </div>
169
- <div class="table-wrap">
170
- <table>
171
- <thead>
172
- <tr>
173
- <th scope="col">Status</th>
174
- <th scope="col">Tool</th>
175
- <th scope="col">Input</th>
176
- <th scope="col">When</th>
177
- <th scope="col" class="num">ms</th>
178
- <th scope="col" class="num">Cost</th>
179
- </tr>
180
- </thead>
181
- <tbody id="activity-body">
182
- <tr><td colspan="6" class="empty">Nothing yet. Run an agent to see activity here.</td></tr>
183
- </tbody>
184
- </table>
185
- </div>
186
- </section>
187
- </main>
188
-
189
- <footer class="footer">
190
- <span id="conn-state" class="conn">Connecting…</span>
191
- <span>Local data only · <code>~/.agentobs/agentobs.db</code></span>
192
- </footer>
193
-
194
- <script type="module" src="/app.js"></script>
195
- </body>
196
- </html>
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
+ <meta name="color-scheme" content="light dark" />
7
+ <title>AgentObs</title>
8
+ <link rel="icon" type="image/svg+xml" href="/logo.svg" />
9
+ <link rel="stylesheet" href="/app.css" />
10
+ </head>
11
+ <body>
12
+ <a class="skip-link" href="#main">Skip to content</a>
13
+
14
+ <header class="topbar">
15
+ <div class="brand">
16
+ <span class="brand-mark" aria-hidden="true"><img src="/logo.svg" alt="" width="30" height="30" /></span>
17
+ <div>
18
+ <h1>AgentObs</h1>
19
+ <p class="brand-sub">Agent observability &amp; control</p>
20
+ </div>
21
+ </div>
22
+
23
+ <div class="topbar-actions">
24
+ <div class="rangeset" role="group" aria-label="Time range">
25
+ <button type="button" data-range="today">Today</button>
26
+ <button type="button" data-range="7d" aria-pressed="true">7 days</button>
27
+ <button type="button" data-range="30d">30 days</button>
28
+ <button type="button" data-range="all">All</button>
29
+ </div>
30
+ <button type="button" id="theme-toggle" class="icon-btn" aria-label="Switch theme">
31
+ <span aria-hidden="true">◐</span>
32
+ </button>
33
+ </div>
34
+ </header>
35
+
36
+ <main id="main">
37
+ <!-- Hero: exactly one per view - the number this dashboard exists to report. -->
38
+ <section class="hero" aria-labelledby="hero-label">
39
+ <div>
40
+ <p class="hero-label" id="hero-label">Spend <span data-range-label>this week</span></p>
41
+ <p class="hero-figure" id="hero-cost">—</p>
42
+ <p class="hero-note" id="hero-note">No activity recorded yet.</p>
43
+ </div>
44
+ <canvas class="hero-spark" id="hero-spark" aria-hidden="true"></canvas>
45
+ <dl class="hero-side">
46
+ <div><dt>Tokens in</dt><dd id="hero-tokens-in">—</dd></div>
47
+ <div><dt>Tokens out</dt><dd id="hero-tokens-out">—</dd></div>
48
+ <div><dt>Avg duration</dt><dd id="hero-duration">—</dd></div>
49
+ </dl>
50
+ </section>
51
+
52
+ <section class="tiles" aria-label="Key metrics">
53
+ <article class="tile" data-accent="calls">
54
+ <div class="tile-head">
55
+ <p class="tile-label"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><path d="M2 13V7m4 6V3m4 10V6m4 7V9" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" fill="none"/></svg>Tool calls</p>
56
+ <span class="delta" id="delta-calls" hidden></span>
57
+ </div>
58
+ <p class="tile-value" id="stat-calls">—</p>
59
+ <p class="tile-sub" id="stat-calls-sub">&nbsp;</p>
60
+ <canvas class="tile-spark" id="spark-calls" aria-hidden="true"></canvas>
61
+ </article>
62
+ <article class="tile" data-accent="sessions">
63
+ <div class="tile-head">
64
+ <p class="tile-label"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><rect x="2" y="3" width="12" height="10" rx="2" stroke="currentColor" stroke-width="1.6" fill="none"/><path d="M2 6h12" stroke="currentColor" stroke-width="1.6"/></svg>Sessions</p>
65
+ <span class="delta" id="delta-sessions" hidden></span>
66
+ </div>
67
+ <p class="tile-value" id="stat-sessions">—</p>
68
+ <p class="tile-sub" id="stat-sessions-sub">&nbsp;</p>
69
+ <canvas class="tile-spark" id="spark-sessions" aria-hidden="true"></canvas>
70
+ </article>
71
+ <article class="tile" data-accent="errors">
72
+ <div class="tile-head">
73
+ <p class="tile-label"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2.5 15 13.5H1L8 2.5Z" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linejoin="round"/><path d="M8 6.5v3M8 11.6v.01" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>Error rate</p>
74
+ <span class="delta" id="delta-errors" hidden></span>
75
+ </div>
76
+ <p class="tile-value" id="stat-errors">—</p>
77
+ <p class="tile-sub" id="stat-errors-sub">&nbsp;</p>
78
+ <canvas class="tile-spark" id="spark-errors" aria-hidden="true"></canvas>
79
+ </article>
80
+ <article class="tile" data-accent="blocked">
81
+ <div class="tile-head">
82
+ <p class="tile-label"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6" stroke="currentColor" stroke-width="1.6" fill="none"/><path d="M3.8 3.8l8.4 8.4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>Blocked</p>
83
+ </div>
84
+ <p class="tile-value" id="stat-blocked">—</p>
85
+ <p class="tile-sub" id="stat-blocked-sub">by policy</p>
86
+ <canvas class="tile-spark" id="spark-blocked" aria-hidden="true"></canvas>
87
+ </article>
88
+ </section>
89
+
90
+ <section class="panel" aria-labelledby="timeline-title">
91
+ <div class="panel-head">
92
+ <div>
93
+ <h2 id="timeline-title"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><path d="M1.5 11.5 5.5 7l3 2.5L14.5 4" stroke="currentColor" stroke-width="1.7" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="14.5" cy="4" r="1.6" fill="currentColor"/></svg>Activity over time</h2>
94
+ <p class="panel-sub">Tool calls per bucket, errors marked separately.</p>
95
+ </div>
96
+ <div class="legend" id="timeline-legend">
97
+ <span class="legend-item"><i class="swatch swatch-calls"></i>Calls</span>
98
+ <span class="legend-item"><i class="swatch swatch-errors"></i>Errors</span>
99
+ </div>
100
+ </div>
101
+ <div class="chart-wrap">
102
+ <canvas id="timeline" height="220" aria-describedby="timeline-table-note"></canvas>
103
+ <div class="tooltip" id="timeline-tip" role="status" aria-live="polite"></div>
104
+ </div>
105
+ <p class="panel-note" id="timeline-table-note">
106
+ <button type="button" class="linklike" data-toggle-table="timeline">
107
+ Show data table
108
+ </button>
109
+ </p>
110
+ <div class="table-wrap is-hidden" data-table="timeline">
111
+ <table>
112
+ <caption class="sr-only">Activity over time, as a table</caption>
113
+ <thead>
114
+ <tr><th scope="col">Bucket</th><th scope="col">Calls</th><th scope="col">Errors</th><th scope="col">Cost</th></tr>
115
+ </thead>
116
+ <tbody id="timeline-table-body"></tbody>
117
+ </table>
118
+ </div>
119
+ </section>
120
+
121
+ <div class="split">
122
+ <section class="panel" aria-labelledby="tools-title">
123
+ <div class="panel-head">
124
+ <div>
125
+ <h2 id="tools-title"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><path d="M10.6 2.2a3.6 3.6 0 0 0-4.3 4.6L2.3 10.8a1.4 1.4 0 0 0 2 2l4-4a3.6 3.6 0 0 0 4.6-4.3L11 6.3 9.7 5 10.6 2.2Z" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linejoin="round"/></svg>Tools</h2>
126
+ <p class="panel-sub">Where the calls and the money go.</p>
127
+ </div>
128
+ </div>
129
+ <div class="table-wrap">
130
+ <table>
131
+ <thead>
132
+ <tr>
133
+ <th scope="col">Tool</th>
134
+ <th scope="col" class="num">Calls</th>
135
+ <th scope="col" class="num">Errors</th>
136
+ <th scope="col" class="num">Avg ms</th>
137
+ <th scope="col" class="num">Cost</th>
138
+ </tr>
139
+ </thead>
140
+ <tbody id="tools-body">
141
+ <tr><td colspan="5" class="empty">No tool calls recorded yet.</td></tr>
142
+ </tbody>
143
+ </table>
144
+ </div>
145
+ </section>
146
+
147
+ <section class="panel" aria-labelledby="sessions-title">
148
+ <div class="panel-head">
149
+ <div>
150
+ <h2 id="sessions-title"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6.2" stroke="currentColor" stroke-width="1.6" fill="none"/><path d="M8 4.6V8l2.4 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" fill="none"/></svg>Sessions</h2>
151
+ <p class="panel-sub">Coarse sessions show only duration and exit code.</p>
152
+ </div>
153
+ </div>
154
+ <div class="table-wrap">
155
+ <table>
156
+ <thead>
157
+ <tr>
158
+ <th scope="col">Agent</th>
159
+ <th scope="col">Started</th>
160
+ <th scope="col" class="num">Calls</th>
161
+ <th scope="col" class="num">Cost</th>
162
+ </tr>
163
+ </thead>
164
+ <tbody id="sessions-body">
165
+ <tr><td colspan="4" class="empty">No sessions yet.</td></tr>
166
+ </tbody>
167
+ </table>
168
+ </div>
169
+ </section>
170
+ </div>
171
+
172
+ <section class="panel" aria-labelledby="activity-title">
173
+ <div class="panel-head">
174
+ <div>
175
+ <h2 id="activity-title"><svg class="i" viewBox="0 0 16 16" aria-hidden="true"><path d="M1.5 8h3l1.6-4 2.4 8 1.7-4h4.3" stroke="currentColor" stroke-width="1.7" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>Recent activity</h2>
176
+ <p class="panel-sub">Inputs are truncated and secret-redacted before storage.</p>
177
+ </div>
178
+ <div class="filterset" role="group" aria-label="Filter by status">
179
+ <button type="button" data-status="" aria-pressed="true">All</button>
180
+ <button type="button" data-status="success">Success</button>
181
+ <button type="button" data-status="error">Errors</button>
182
+ <button type="button" data-status="blocked">Blocked</button>
183
+ </div>
184
+ </div>
185
+ <div class="table-wrap">
186
+ <table>
187
+ <thead>
188
+ <tr>
189
+ <th scope="col">Status</th>
190
+ <th scope="col">Tool</th>
191
+ <th scope="col">Input</th>
192
+ <th scope="col">When</th>
193
+ <th scope="col" class="num">ms</th>
194
+ <th scope="col" class="num">Cost</th>
195
+ </tr>
196
+ </thead>
197
+ <tbody id="activity-body">
198
+ <tr><td colspan="6" class="empty">Nothing yet. Run an agent to see activity here.</td></tr>
199
+ </tbody>
200
+ </table>
201
+ </div>
202
+ </section>
203
+ </main>
204
+
205
+ <footer class="footer">
206
+ <span id="conn-state" class="conn">Connecting…</span>
207
+ <span>Local data only · <code>~/.agentobs/agentobs.db</code></span>
208
+ </footer>
209
+
210
+ <script type="module" src="/app.js"></script>
211
+ </body>
212
+ </html>
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none" role="img" aria-label="AgentObs">
2
+ <!--
3
+ The mark is the product in miniature: an ascending bar series (the activity
4
+ the tool records) with one bar stopped by a guardrail line. Observability
5
+ plus enforcement, which is exactly what distinguishes this from a dashboard.
6
+ -->
7
+ <defs>
8
+ <linearGradient id="ao-g" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
9
+ <stop offset="0" stop-color="#2a78d6" />
10
+ <stop offset="1" stop-color="#1baf7a" />
11
+ </linearGradient>
12
+ </defs>
13
+ <rect width="32" height="32" rx="8" fill="url(#ao-g)" />
14
+ <rect x="7" y="17" width="3.5" height="8" rx="1.75" fill="#fff" opacity=".95" />
15
+ <rect x="13.25" y="12" width="3.5" height="13" rx="1.75" fill="#fff" opacity=".95" />
16
+ <rect x="19.5" y="15" width="3.5" height="10" rx="1.75" fill="#fff" opacity=".55" />
17
+ <path d="M6 9.5h20" stroke="#fff" stroke-width="2" stroke-linecap="round" opacity=".9" />
18
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klars/agentobs",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Observability and control layer for AI coding agents - see every tool call, token, and dollar your agents spend, and stop them before they do something risky.",
5
5
  "license": "MIT",
6
6
  "author": "Klars AI",