hermes-agent-web-chat 0.1.0 → 0.2.0

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,4 +1,4 @@
1
- import type { AttachedFile, HermesConfig, StreamEvent } from './types';
1
+ import type { AttachedFile, HermesConfig, SessionInfo, SessionMessage, StreamEvent } from './types';
2
2
  /** 通用请求:返回状态码与原始文本,供 API 调试台使用 */
3
3
  export declare function apiRequest(cfg: HermesConfig, method: string, subPath: string, body?: unknown, signal?: AbortSignal): Promise<{
4
4
  status: number;
@@ -24,5 +24,23 @@ interface SendParams {
24
24
  signal?: AbortSignal;
25
25
  onEvent: (ev: StreamEvent) => void;
26
26
  }
27
- export declare function streamResponse(p: SendParams): Promise<void>;
27
+ export declare function streamResponse(p: SendParams): Promise<string | undefined>;
28
+ export declare function listSessions(cfg: HermesConfig, limit?: number, offset?: number): Promise<SessionInfo[]>;
29
+ export declare function createSession(cfg: HermesConfig, title?: string): Promise<SessionInfo>;
30
+ export declare function getSession(cfg: HermesConfig, id: string): Promise<SessionInfo>;
31
+ export declare function deleteSession(cfg: HermesConfig, id: string): Promise<void>;
32
+ export declare function updateSession(cfg: HermesConfig, id: string, patch: {
33
+ title?: string;
34
+ }): Promise<void>;
35
+ export declare function getSessionMessages(cfg: HermesConfig, id: string): Promise<SessionMessage[]>;
36
+ interface SessionChatParams {
37
+ cfg: HermesConfig;
38
+ sessionId: string;
39
+ input: string;
40
+ instructions?: string;
41
+ files?: AttachedFile[];
42
+ signal?: AbortSignal;
43
+ onEvent: (ev: StreamEvent) => void;
44
+ }
45
+ export declare function streamSessionChat(p: SessionChatParams): Promise<void>;
28
46
  export {};
@@ -1,10 +1,3 @@
1
- import type { Plugin } from 'vue';
2
- import HermesChat from './components/HermesChat.vue';
3
-
4
- export { HermesChat };
5
- export { createHermesStore } from './store';
6
- export type { HermesStore, HermesStoreOptions } from './store';
7
- export { useHermes, HermesKey } from './inject';
1
+ export { HermesChat } from './sdk';
2
+ export type { HermesChatOptions } from './sdk';
8
3
  export type { HermesChatProps, HermesConfig, Conversation, ChatMessage, UserMessage, AssistantMessage, AttachedFile, FileMeta, StreamEvent, } from './types';
9
- declare const HermesChatPlugin: Plugin;
10
- export default HermesChatPlugin;
@@ -0,0 +1,35 @@
1
+ import type { HermesChatProps } from './types';
2
+ /** SDK 初始化选项 */
3
+ export interface HermesChatOptions extends HermesChatProps {
4
+ /** 挂载容器:CSS 选择器字符串或 DOM 元素 */
5
+ container: string | Element;
6
+ }
7
+ /**
8
+ * Hermes Agent Web Chat SDK。
9
+ *
10
+ * 不依赖任何外部框架,内部自带 Vue 运行时。
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { HermesChat } from 'hermes-agent-web-chat';
15
+ *
16
+ * const chat = new HermesChat({
17
+ * container: '#app',
18
+ * baseUrl: 'http://localhost:8642',
19
+ * token: 'hms-xxx',
20
+ * });
21
+ *
22
+ * chat.update({ title: '新标题' });
23
+ * chat.destroy();
24
+ * ```
25
+ */
26
+ export declare class HermesChat {
27
+ private app;
28
+ private container;
29
+ private props;
30
+ constructor(options: HermesChatOptions);
31
+ /** 响应式更新配置(baseUrl/token/model/title/instructions/uploadHandler 等) */
32
+ update(patch: Partial<HermesChatProps>): void;
33
+ /** 销毁实例,卸载组件并清理监听 */
34
+ destroy(): void;
35
+ }
@@ -9,6 +9,7 @@ interface State {
9
9
  systemInstructions: string;
10
10
  health: HealthState;
11
11
  ready: boolean;
12
+ loadingMessages: boolean;
12
13
  }
13
14
  export interface HermesStoreOptions {
14
15
  baseUrl: string;
@@ -25,9 +26,9 @@ export interface HermesStore {
25
26
  uploadHandler?: (file: File) => Promise<string>;
26
27
  init(): Promise<void>;
27
28
  checkHealth(): Promise<void>;
28
- newConversation(): void;
29
- deleteConversation(id: string): void;
30
- selectConversation(id: string): void;
29
+ newConversation(): Promise<void>;
30
+ deleteConversation(id: string): Promise<void>;
31
+ selectConversation(id: string): Promise<void>;
31
32
  setSystemInstructions(v: string): void;
32
33
  sendMessage(text: string, files?: AttachedFile[]): Promise<void>;
33
34
  stopStreaming(): void;
@@ -0,0 +1 @@
1
+ export declare function mountStyles(): void;
@@ -73,10 +73,45 @@ export interface AssistantMessage {
73
73
  export type ChatMessage = UserMessage | AssistantMessage;
74
74
  export interface Conversation {
75
75
  id: string;
76
+ sessionId: string;
76
77
  title: string;
77
78
  createdAt: number;
78
79
  updatedAt: number;
79
80
  messages: ChatMessage[];
81
+ messagesLoaded?: boolean;
82
+ }
83
+ /** 后端 /api/sessions 返回的会话信息 */
84
+ export interface SessionInfo {
85
+ id: string;
86
+ source: string;
87
+ title: string | null;
88
+ model: string;
89
+ started_at: number;
90
+ ended_at: number | null;
91
+ end_reason: string | null;
92
+ message_count: number;
93
+ tool_call_count: number;
94
+ input_tokens: number;
95
+ output_tokens: number;
96
+ last_active: number;
97
+ preview: string | null;
98
+ has_system_prompt: boolean;
99
+ has_model_config: boolean;
100
+ }
101
+ /** 后端 /api/sessions/{id}/messages 返回的消息 */
102
+ export interface SessionMessage {
103
+ id: number;
104
+ session_id: string;
105
+ role: 'user' | 'assistant' | 'tool';
106
+ content: string;
107
+ tool_call_id: string | null;
108
+ tool_calls: any[] | null;
109
+ tool_name: string | null;
110
+ timestamp: number;
111
+ token_count: number | null;
112
+ finish_reason: string | null;
113
+ reasoning: string | null;
114
+ reasoning_content: string | null;
80
115
  }
81
116
  export type StreamEvent = {
82
117
  kind: 'created';
@@ -96,10 +131,12 @@ export type StreamEvent = {
96
131
  kind: 'tool_result';
97
132
  callId: string;
98
133
  output: string;
134
+ name?: string;
99
135
  } | {
100
136
  kind: 'completed';
101
137
  responseId?: string;
102
138
  usage?: Record<string, unknown>;
139
+ messages?: any[];
103
140
  } | {
104
141
  kind: 'error';
105
142
  message: string;
package/package.json CHANGED
@@ -1,9 +1,16 @@
1
1
  {
2
2
  "name": "hermes-agent-web-chat",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Vue 3 组件包:接入 Hermes 适配智能体的对话界面与 HTTP API 调试台",
6
- "keywords": ["vue", "vue3", "hermes", "agent", "chat", "component"],
6
+ "keywords": [
7
+ "vue",
8
+ "vue3",
9
+ "hermes",
10
+ "agent",
11
+ "chat",
12
+ "component"
13
+ ],
7
14
  "license": "MIT",
8
15
  "main": "./dist/hermes-agent-web-chat.umd.cjs",
9
16
  "module": "./dist/hermes-agent-web-chat.js",
@@ -13,30 +20,27 @@
13
20
  "types": "./dist/types/index.d.ts",
14
21
  "import": "./dist/hermes-agent-web-chat.js",
15
22
  "require": "./dist/hermes-agent-web-chat.umd.cjs"
16
- },
17
- "./style.css": "./dist/hermes-agent-web-chat.css"
23
+ }
18
24
  },
19
25
  "files": [
20
26
  "dist"
21
27
  ],
22
- "sideEffects": ["**/*.css"],
28
+ "sideEffects": false,
23
29
  "scripts": {
24
30
  "dev": "vite",
25
- "build": "vue-tsc -b && vite build && vue-tsc -p tsconfig.build.json && node scripts/strip-css-imports.mjs",
31
+ "build": "vue-tsc -b && vite build && node scripts/minify.mjs && vue-tsc -p tsconfig.build.json && node scripts/strip-css-imports.mjs",
26
32
  "preview": "vite preview",
27
33
  "typecheck": "vue-tsc -b",
28
34
  "prepublishOnly": "npm run build"
29
35
  },
30
- "peerDependencies": {
31
- "vue": "^3.4.0"
32
- },
33
- "dependencies": {},
34
36
  "devDependencies": {
35
37
  "@types/node": "^20.12.12",
36
38
  "@vitejs/plugin-vue": "^5.0.4",
39
+ "css-render": "^0.15.14",
37
40
  "dompurify": "^3.1.5",
38
41
  "highlight.js": "^11.9.0",
39
42
  "marked": "^12.0.2",
43
+ "terser": "^5.49.0",
40
44
  "typescript": "^5.4.5",
41
45
  "vite": "^5.2.11",
42
46
  "vue": "^3.4.27",
@@ -1,10 +0,0 @@
1
- :root{--bg: #ffffff;--bg-2: #f6f8fa;--bg-3: #eef1f5;--bg-hover: #e7ebf1;--border: #e2e6ed;--text: #1a1d23;--text-dim: #565d6b;--text-mute: #8a93a3;--accent: #2563eb;--accent-2: #3b82f6;--green: #16a34a;--amber: #d97706;--red: #dc2626;--radius: 10px;--sidebar-w: 260px}*{box-sizing:border-box}.hermes-chat{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Microsoft YaHei,Roboto,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.6;-webkit-font-smoothing:antialiased}.hermes-chat button{font-family:inherit;cursor:pointer}.app{display:flex;flex-direction:column;height:100%}.topbar{height:46px;flex-shrink:0;display:flex;align-items:center;gap:16px;padding:0 16px;border-bottom:1px solid var(--border);background:var(--bg-2)}.topbar-brand{font-weight:700;font-size:14px;letter-spacing:.3px}.tabs{display:flex;gap:4px}.tab{padding:6px 16px;background:transparent;border:none;color:var(--text-dim);font-size:13px;border-radius:8px;font-weight:500}.tab:hover{background:var(--bg-hover);color:var(--text)}.tab.active{background:var(--accent);color:#fff}.topbar-spacer{flex:1}.menu-btn{display:none;background:none;border:none;color:var(--text);font-size:20px;padding:4px 8px;border-radius:6px;line-height:1}.menu-btn:hover{background:var(--bg-hover)}.app-body{flex:1;display:flex;min-height:0}.main{flex:1;min-width:0;display:flex}.chat-layout{flex:1;display:flex;min-width:0;position:relative}.sidebar-backdrop{display:none}.sidebar{width:var(--sidebar-w);flex-shrink:0;background:var(--bg-2);border-right:1px solid var(--border);display:flex;flex-direction:column;height:100%}.sidebar-head{padding:16px 14px 12px;border-bottom:1px solid var(--border)}.brand{font-weight:700;font-size:16px;margin-bottom:10px;letter-spacing:.3px}.profile-select{width:100%;padding:8px 10px;background:var(--bg-3);color:var(--text);border:1px solid var(--border);border-radius:8px;font-size:13px;outline:none}.profile-select:focus{border-color:var(--accent)}.new-btn{margin:12px 14px 8px;padding:9px;background:var(--accent);color:#fff;border:none;border-radius:8px;font-weight:600;font-size:13px}.new-btn:hover{background:var(--accent-2)}.new-btn:disabled{opacity:.5;cursor:not-allowed}.conv-list{flex:1;overflow-y:auto;padding:4px 8px}.conv-item{display:flex;align-items:center;gap:6px;padding:9px 10px;border-radius:8px;cursor:pointer;color:var(--text-dim);font-size:13px;margin:2px 0}.conv-item:hover{background:var(--bg-hover);color:var(--text)}.conv-item.active{background:var(--bg-3);color:var(--text)}.conv-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.conv-del{background:none;border:none;color:var(--text-mute);font-size:16px;line-height:1;padding:0 4px;border-radius:4px;opacity:0}.conv-item:hover .conv-del{opacity:1}.conv-del:hover{color:var(--red);background:#f871711f}.conv-empty{color:var(--text-mute);font-size:13px;text-align:center;padding:20px 0}.sidebar-foot{padding:10px 14px;border-top:1px solid var(--border)}.instr-btn{width:100%;padding:8px;background:var(--bg-3);color:var(--text-dim);border:1px solid var(--border);border-radius:8px;font-size:13px}.instr-btn:hover{color:var(--text);border-color:var(--accent)}.chat-view{flex:1;display:flex;flex-direction:column;min-width:0;height:100%}.chat-header{display:flex;align-items:center;gap:12px;padding:14px 22px;border-bottom:1px solid var(--border);background:var(--bg)}.chat-title{font-weight:600;font-size:15px}.chat-sub{color:var(--text-mute);font-size:12px}.health-badge{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12px;padding:4px 10px;border-radius:999px;cursor:pointer;-webkit-user-select:none;user-select:none;border:1px solid var(--border);background:var(--bg-2);color:var(--text-dim)}.health-badge:hover{border-color:var(--accent)}.health-dot{width:8px;height:8px;border-radius:50%;background:var(--text-mute);flex-shrink:0}.health-online .health-dot,.health-dot.online{background:var(--green)}.health-online{color:var(--green)}.health-offline .health-dot,.health-dot.offline{background:var(--red)}.health-offline{color:var(--red)}.health-checking .health-dot,.health-dot.checking{background:var(--amber)}.health-unknown .health-dot,.health-dot.unknown{background:var(--text-mute)}.banner{margin:10px 22px 0;padding:10px 14px;background:#f871711a;border:1px solid rgba(248,113,113,.4);color:var(--red);border-radius:8px;font-size:13px}.messages{flex:1;overflow-y:auto;padding:22px;display:flex;flex-direction:column;gap:20px}.empty{margin:auto;text-align:center;color:var(--text-mute)}.empty-icon{width:56px;height:56px;margin:0 auto 14px;border-radius:14px;background:linear-gradient(135deg,var(--accent),#8b5cf6);color:#fff;font-size:26px;font-weight:700;display:flex;align-items:center;justify-content:center}.empty-text{font-size:16px;color:var(--text-dim)}.empty-hint{font-size:13px;margin-top:6px}.msg{display:flex;gap:12px;max-width:880px;width:100%;margin:0 auto}.msg-user{flex-direction:row-reverse}.avatar{width:32px;height:32px;flex-shrink:0;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:#fff}.msg-user .avatar{background:#475569}.msg-asst .avatar{background:linear-gradient(135deg,var(--accent),#8b5cf6)}.bubble{min-width:0;display:flex;flex-direction:column;gap:8px}.msg-user .bubble{align-items:flex-end}.msg-asst .bubble{flex:1;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px}.user-text{background:var(--bg-3);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px;white-space:pre-wrap;word-break:break-word;max-width:100%}.file-chips{display:flex;flex-wrap:wrap;gap:6px}.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;background:var(--bg-3);border:1px solid var(--border);border-radius:6px;font-size:12px;color:var(--text-dim);max-width:220px}.chip-icon{font-size:13px;flex-shrink:0}.chip-name{min-width:0;flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chip-size{color:var(--text-mute);white-space:nowrap;flex-shrink:0}.chip-remove{background:none;border:none;color:var(--text-mute);font-size:15px;line-height:1;padding:0;margin-left:2px;flex-shrink:0}.chip-remove:hover{color:var(--red)}.chip-status{font-size:11px;color:var(--text-mute)}.chip-loading{border-color:var(--amber)}.chip-error{border-color:var(--red)}.chip-err{color:var(--red)}a.chip{text-decoration:none;color:var(--text-dim)}a.chip:hover{border-color:var(--accent);color:var(--text)}.typing{display:inline-flex;gap:4px;padding:4px 0}.typing span{width:7px;height:7px;border-radius:50%;background:var(--text-mute);animation:blink 1.2s infinite ease-in-out}.typing span:nth-child(2){animation-delay:.2s}.typing span:nth-child(3){animation-delay:.4s}@keyframes blink{0%,80%,to{opacity:.3}40%{opacity:1}}.meta{display:flex;gap:12px;font-size:11px;color:var(--text-mute)}.usage{color:var(--text-mute)}.token-pills{display:inline-flex;flex-wrap:wrap;gap:6px;align-items:center}.tok{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;background:var(--bg-2);border:1px solid var(--border);color:var(--text-dim);font-size:11px;line-height:1.6}.tok-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.tok-in .tok-dot{background:var(--accent)}.tok-out .tok-dot{background:var(--green)}.tok-total .tok-dot{background:#8b5cf6}.tok-val{font-weight:700;color:var(--text);font-variant-numeric:tabular-nums}.status-live{color:var(--green)}.error-box{color:var(--red);background:#f8717114;border:1px solid rgba(248,113,113,.3);border-radius:6px;padding:6px 10px;font-size:13px}.aborted-box{color:var(--text-mute);font-size:12px;font-style:italic}.process{border:1px solid var(--border);border-radius:8px;background:var(--bg-3);margin-bottom:4px;overflow:hidden}.process-head{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:13px}.process-head:hover{background:var(--bg-hover)}.caret{color:var(--text-mute);width:10px;display:inline-block}.process-title{font-weight:600;color:var(--text-dim)}.process-count{color:var(--text-mute);font-size:12px}.live-dot{width:7px;height:7px;border-radius:50%;background:var(--green);animation:pulse 1s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.3}}.process-body{padding:4px 12px 12px;display:flex;flex-direction:column;gap:10px}.reasoning{border-left:2px solid #8b5cf6;padding:4px 0 4px 10px}.step-label{font-size:12px;color:var(--text-mute);margin-bottom:4px}.reasoning-text{margin:0;font-size:12.5px;color:var(--text-dim);white-space:pre-wrap;word-break:break-word;font-family:inherit}.step{border-left:2px solid var(--accent);padding:2px 0 2px 10px}.step-head{display:flex;align-items:center;gap:8px;font-size:13px}.step-icon{font-size:13px}.step-name{font-weight:600;color:var(--accent-2)}.step-status{font-size:11px;color:var(--text-mute);margin-left:auto}.step-status.running{color:var(--amber)}.step-status.done{color:var(--green)}.step-detail{margin:6px 0 0;font-size:12px}.step-detail summary{cursor:pointer;color:var(--text-mute);-webkit-user-select:none;user-select:none}.step-detail summary:hover{color:var(--text-dim)}.step-detail pre{margin:6px 0 0;padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:6px;font-size:12px;color:var(--text-dim);overflow-x:auto;white-space:pre-wrap;word-break:break-word;font-family:JetBrains Mono,Fira Code,Consolas,monospace;max-height:320px;overflow-y:auto}.markdown{word-break:break-word}.markdown :first-child{margin-top:0}.markdown :last-child{margin-bottom:0}.markdown p{margin:8px 0}.markdown h1,.markdown h2,.markdown h3,.markdown h4{margin:16px 0 8px;font-weight:600;line-height:1.3}.markdown h1{font-size:20px}.markdown h2{font-size:17px}.markdown h3{font-size:15px}.markdown ul,.markdown ol{margin:8px 0;padding-left:22px}.markdown li{margin:3px 0}.markdown a{color:var(--accent-2);text-decoration:none}.markdown a:hover{text-decoration:underline}.markdown blockquote{margin:8px 0;padding:4px 12px;border-left:3px solid var(--border);color:var(--text-dim)}.markdown code{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12.5px;background:var(--bg);border:1px solid var(--border);border-radius:4px;padding:1px 5px}.markdown pre{margin:10px 0;border-radius:8px;overflow:hidden;border:1px solid var(--border)}.markdown pre code{display:block;padding:12px 14px;background:#f6f8fa;border:none;border-radius:0;font-size:12.5px;line-height:1.5;overflow-x:auto}.markdown table{border-collapse:collapse;margin:10px 0;font-size:13px}.markdown th,.markdown td{border:1px solid var(--border);padding:6px 10px}.markdown th{background:var(--bg-3)}.markdown hr{border:none;border-top:1px solid var(--border);margin:14px 0}.chat-input{border-top:1px solid var(--border);background:var(--bg);padding:12px 22px 16px}.file-error{max-width:880px;margin:0 auto 8px;padding:8px 12px;background:#f871711a;border:1px solid rgba(248,113,113,.4);color:var(--red);border-radius:8px;font-size:13px}.chat-input .file-chips{margin-bottom:8px}.input-row{display:flex;align-items:flex-end;gap:8px;background:var(--bg-2);border:1px solid var(--border);border-radius:var(--radius);padding:8px 8px 8px 10px;max-width:880px;margin:0 auto}.input-row:focus-within{border-color:var(--accent)}.icon-btn{background:none;border:none;color:var(--text-dim);font-size:18px;padding:4px 6px;border-radius:6px}.icon-btn:hover{color:var(--text);background:var(--bg-hover)}.icon-btn:disabled{opacity:.4;cursor:not-allowed}textarea{flex:1;background:transparent;border:none;outline:none;resize:none;color:var(--text);font-size:14px;line-height:1.5;font-family:inherit;max-height:200px;padding:4px 0}textarea::placeholder{color:var(--text-mute)}.send-btn,.stop-btn{padding:8px 16px;border:none;border-radius:8px;font-weight:600;font-size:13px}.send-btn{background:var(--accent);color:#fff}.send-btn:hover{background:var(--accent-2)}.send-btn:disabled{opacity:.5;cursor:not-allowed}.stop-btn{background:#f8717126;color:var(--red);border:1px solid rgba(248,113,113,.4)}.stop-btn:hover{background:#f8717140}.modal-mask{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000008c;display:flex;align-items:center;justify-content:center;z-index:100}.modal{width:480px;max-width:92vw;background:var(--bg-2);border:1px solid var(--border);border-radius:12px;padding:20px;box-shadow:0 20px 60px #00000080}.modal-title{font-weight:600;margin-bottom:12px}.modal-input{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);padding:10px 12px;font-size:13px;font-family:inherit;resize:vertical;outline:none}.modal-input:focus{border-color:var(--accent)}.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:14px}.btn-ghost,.btn-primary{padding:8px 16px;border-radius:8px;font-size:13px;border:1px solid var(--border)}.btn-ghost{background:var(--bg-3);color:var(--text-dim)}.btn-ghost:hover{color:var(--text)}.btn-primary{background:var(--accent);color:#fff;border-color:var(--accent)}.btn-primary:hover{background:var(--accent-2)}.m-badge{display:inline-block;font-size:10px;font-weight:700;padding:2px 6px;border-radius:4px;min-width:46px;text-align:center;color:#fff;letter-spacing:.3px;flex-shrink:0}.m-GET{background:var(--accent)}.m-POST{background:var(--green)}.m-DELETE{background:var(--red)}.m-PATCH{background:var(--amber)}.explorer{flex:1;display:flex;flex-direction:column;min-width:0;height:100%}.ex-header{display:flex;align-items:center;justify-content:space-between;padding:10px 18px;border-bottom:1px solid var(--border);flex-shrink:0}.ex-title{font-weight:700;font-size:15px}.ex-profile{display:flex;align-items:center;gap:8px}.ex-baseurl{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:12px;color:var(--text-mute);max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ex-refresh{background:var(--bg-3);border:1px solid var(--border);border-radius:6px;padding:4px 9px;cursor:pointer;color:var(--text-dim);font-size:14px}.ex-refresh:hover{color:var(--text);border-color:var(--accent)}.ex-nav-toggle{display:none;background:var(--bg-3);border:1px solid var(--border);border-radius:6px;padding:4px 9px;color:var(--text-dim);font-size:16px;cursor:pointer}.ex-nav-toggle:hover{color:var(--text);border-color:var(--accent)}.ex-nav-backdrop{display:none}.ex-body{flex:1;display:flex;min-height:0}.ex-nav{width:232px;flex-shrink:0;overflow-y:auto;border-right:1px solid var(--border);background:var(--bg-2);padding:8px 6px}.ex-group{margin-bottom:6px}.ex-group-title{font-size:11px;color:var(--text-mute);padding:8px 10px 4px;text-transform:uppercase;letter-spacing:.5px}.ex-item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 10px;background:transparent;border:none;border-radius:6px;text-align:left;color:var(--text-dim);font-size:12.5px}.ex-item:hover{background:var(--bg-hover);color:var(--text)}.ex-item.active{background:var(--bg-3);color:var(--text)}.ex-item-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ex-main{flex:1;display:flex;flex-direction:column;min-width:0;overflow-y:auto;padding:18px 22px;gap:16px}.ex-endpoint{background:var(--bg-2);border:1px solid var(--border);border-radius:10px;padding:16px}.ex-endpoint-head{display:flex;align-items:center;gap:10px}.ex-path{font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:13px;color:var(--text);word-break:break-all}.ex-desc{margin-top:8px;font-size:12.5px;color:var(--text-dim);line-height:1.5}.ex-params{display:flex;flex-wrap:wrap;gap:12px;margin-top:14px}.ex-field{display:flex;flex-direction:column;gap:4px}.ex-field label{font-size:11px;color:var(--text-mute)}.ex-field input{padding:6px 10px;border:1px solid var(--border);border-radius:6px;font-size:13px;background:var(--bg);min-width:180px;outline:none;color:var(--text);font-family:JetBrains Mono,Fira Code,Consolas,monospace}.ex-field input:focus{border-color:var(--accent)}.ex-body-editor{margin-top:14px}.ex-label{font-size:12px;color:var(--text-mute);display:block;margin-bottom:6px}.ex-textarea{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:8px;color:var(--text);padding:10px 12px;font-size:12.5px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;resize:vertical;outline:none;line-height:1.5}.ex-textarea:focus{border-color:var(--accent)}.ex-actions{display:flex;align-items:center;gap:10px;margin-top:14px;flex-wrap:wrap}.ex-status{font-size:12px;color:var(--text-dim);font-family:JetBrains Mono,Fira Code,Consolas,monospace}.ex-status.ok{color:var(--green)}.ex-status.err{color:var(--red)}.ex-status.warn{color:var(--amber)}.ex-err{font-size:12px;color:var(--red)}.ex-response{background:var(--bg-2);border:1px solid var(--border);border-radius:10px;padding:16px;flex:1;min-height:220px;display:flex;flex-direction:column}.ex-resp-head{font-weight:600;font-size:13px;margin-bottom:8px;display:flex;align-items:center;gap:8px}.ex-stream-tag{font-size:10px;background:#8b5cf6;color:#fff;padding:1px 6px;border-radius:4px}.ex-pre{flex:1;margin:0;padding:12px;background:var(--bg);border:1px solid var(--border);border-radius:8px;font-size:12px;font-family:JetBrains Mono,Fira Code,Consolas,monospace;overflow:auto;white-space:pre-wrap;word-break:break-word;color:var(--text-dim)}::-webkit-scrollbar{width:9px;height:9px}::-webkit-scrollbar-thumb{background:#c8ced8;border-radius:6px}::-webkit-scrollbar-thumb:hover{background:#aab2bf}::-webkit-scrollbar-track{background:transparent}@media (max-width: 768px){.topbar{height:44px;padding:0 10px;gap:10px}.topbar-brand{font-size:13px}.menu-btn{display:inline-flex;align-items:center;justify-content:center}.tab{padding:6px 12px;font-size:12px}.chat-layout .sidebar{position:fixed;top:44px;bottom:0;left:0;width:80vw;max-width:300px;z-index:60;transform:translate(-100%);transition:transform .25s ease;box-shadow:2px 0 12px #00000026}.chat-layout.drawer-open .sidebar{transform:translate(0)}.sidebar-backdrop{display:block;position:fixed;top:44px;left:0;right:0;bottom:0;background:#0006;z-index:55;opacity:0;pointer-events:none;transition:opacity .25s ease}.chat-layout.drawer-open .sidebar-backdrop{opacity:1;pointer-events:auto}.chat-header{padding:10px 12px;gap:8px}.chat-title{font-size:14px}.chat-sub{display:none}.health-badge{font-size:11px;padding:3px 8px}.messages{padding:14px 12px;gap:16px}.msg{gap:8px}.avatar{width:28px;height:28px;font-size:12px}.msg-asst .bubble{padding:12px}.user-text{padding:8px 12px}.chat-input{padding:10px 12px 12px}.input-row{padding:6px 6px 6px 8px}.send-btn,.stop-btn{padding:8px 12px;font-size:12px}.modal{width:92vw;padding:16px}.ex-header{padding:8px 12px}.ex-title{font-size:14px}.ex-baseurl{max-width:140px}.ex-nav-toggle{display:inline-flex;align-items:center;justify-content:center}.ex-nav{position:fixed;top:44px;bottom:0;left:0;width:80vw;max-width:300px;z-index:60;transform:translate(-100%);transition:transform .25s ease;box-shadow:2px 0 12px #00000026}.ex-nav.drawer-open{transform:translate(0)}.ex-nav-backdrop{display:block;position:fixed;top:44px;left:0;right:0;bottom:0;background:#0006;z-index:55;opacity:0;pointer-events:none;transition:opacity .25s ease}.ex-nav-backdrop.show{opacity:1;pointer-events:auto}.ex-main{padding:14px 12px}.ex-endpoint,.ex-response{padding:12px}.ex-params{gap:8px}.ex-field input{min-width:0;flex:1}.conv-del{opacity:1}}@media (max-width: 480px){.topbar-brand{display:none}.chip{max-width:100%}.ex-baseurl{display:none}}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
2
- Theme: GitHub
3
- Description: Light theme as seen on github.com
4
- Author: github.com
5
- Maintainer: @Hirse
6
- Updated: 2021-05-15
7
-
8
- Outdated base version: https://github.com/primer/github-syntax-light
9
- Current colors taken from GitHub's CSS
10
- */.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}