research-agent-ui 0.1.14 → 0.1.16
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.
- package/README.md +177 -177
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,177 +1,177 @@
|
|
|
1
|
-
# research-agent-ui
|
|
2
|
-
|
|
3
|
-
Chat research agent UI: conversation window, article reader, search config,
|
|
4
|
-
file uploads, and chat history for QwkSearch-style apps. Includes the shadcn
|
|
5
|
-
primitives and icons the components depend on, so it can be dropped into a
|
|
6
|
-
Next.js app with a single dependency.
|
|
7
|
-
|
|
8
|
-

|
|
9
|
-
|
|
10
|
-
## Usage
|
|
11
|
-
|
|
12
|
-
```tsx
|
|
13
|
-
import {
|
|
14
|
-
ChatProvider,
|
|
15
|
-
SessionProvider,
|
|
16
|
-
ExtractPanelProvider,
|
|
17
|
-
ChatWindow,
|
|
18
|
-
configureResearchAgentUI,
|
|
19
|
-
} from 'research-agent-ui';
|
|
20
|
-
|
|
21
|
-
configureResearchAgentUI({
|
|
22
|
-
appName: 'MyApp',
|
|
23
|
-
getAutoMediaSearch: () => true,
|
|
24
|
-
// ...see ResearchAgentUIConfig for the full list of overridable values
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
function App() {
|
|
28
|
-
return (
|
|
29
|
-
<SessionProvider authClient={myAuthClient}>
|
|
30
|
-
<ExtractPanelProvider>
|
|
31
|
-
<ChatProvider>
|
|
32
|
-
<ChatWindow />
|
|
33
|
-
</ChatProvider>
|
|
34
|
-
</ExtractPanelProvider>
|
|
35
|
-
</SessionProvider>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## API Routes (`research-agent-ui/api`)
|
|
41
|
-
|
|
42
|
-
All 25 Next.js route handlers are exported from the `research-agent-ui/api`
|
|
43
|
-
subpath as factory functions. Each factory accepts a **deps** object that
|
|
44
|
-
injects your app's database, auth helpers, and other services, so the same
|
|
45
|
-
handler logic works in any Next.js project without hard-coding any imports.
|
|
46
|
-
|
|
47
|
-
### How it works
|
|
48
|
-
|
|
49
|
-
The route logic lives in `packages/research-agent-ui/src/api/handlers/`.
|
|
50
|
-
Your app's `app/api/agent/*/route.ts` files become thin wrappers that call
|
|
51
|
-
the factory and re-export the HTTP method handlers.
|
|
52
|
-
|
|
53
|
-
### Step 1 — install / workspace link
|
|
54
|
-
|
|
55
|
-
If you are in this monorepo, `research-agent-ui` is already linked via the
|
|
56
|
-
`workspace:*` protocol. For an external project, install the published
|
|
57
|
-
package:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npm install research-agent-ui
|
|
61
|
-
# or
|
|
62
|
-
bun add research-agent-ui
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Step 2 — create your route files
|
|
66
|
-
|
|
67
|
-
For each API path, create a `route.ts` that calls the matching factory and
|
|
68
|
-
passes in your app's dependencies. Every factory is named
|
|
69
|
-
`create<RouteName>Handler` and is exported from `research-agent-ui/api`.
|
|
70
|
-
|
|
71
|
-
#### Example: `app/api/agent/chats/route.ts`
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
import { createChatsHandler } from "research-agent-ui/api";
|
|
75
|
-
import { getDB } from "@/lib/database";
|
|
76
|
-
import { chats, messages } from "@/lib/database/schema";
|
|
77
|
-
import { requireUserId } from "@/lib/auth/session";
|
|
78
|
-
|
|
79
|
-
const handler = createChatsHandler({
|
|
80
|
-
getDB,
|
|
81
|
-
requireUserId,
|
|
82
|
-
schema: { chats, messages },
|
|
83
|
-
});
|
|
84
|
-
export const { GET, DELETE } = handler;
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
#### Example: `app/api/agent/article-followups/route.ts`
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
import { createArticleFollowupsHandler } from "research-agent-ui/api";
|
|
91
|
-
import { getUserId } from "@/lib/auth/session";
|
|
92
|
-
import { getDB } from "@/lib/database";
|
|
93
|
-
import { user as userSchema } from "@/lib/database/schema";
|
|
94
|
-
import { getEnv } from "@/lib/env";
|
|
95
|
-
|
|
96
|
-
export const POST = createArticleFollowupsHandler({
|
|
97
|
-
getUserId,
|
|
98
|
-
requireUserId: async () => {
|
|
99
|
-
const id = await getUserId();
|
|
100
|
-
if (!id) throw new Error("Unauthorized");
|
|
101
|
-
return id;
|
|
102
|
-
},
|
|
103
|
-
getDB,
|
|
104
|
-
userSchema,
|
|
105
|
-
getEnv,
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### All available factories and their dep shapes
|
|
110
|
-
|
|
111
|
-
| Factory | File | Required deps |
|
|
112
|
-
|---|---|---|
|
|
113
|
-
| `createArticleFollowupsHandler` | `article-followups` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
114
|
-
| `createArticleQAHandler` | `article-qa` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
115
|
-
| `createChatsHandler` | `chats` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
116
|
-
| `createChatByIdHandler` | `chats/[id]` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
117
|
-
| `createChatsSearchHandler` | `chats/search` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
118
|
-
| `createChatsShareHandler` | `chats/share` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
119
|
-
| `createMessagesHandler` | `messages` | `getDB`, `requireUserId`, `messagesSchema` |
|
|
120
|
-
| `createProvidersHandler` | `providers` | `getSession` |
|
|
121
|
-
| `createProviderByIdHandler` | `providers/[id]` | _(none)_ |
|
|
122
|
-
| `createProviderModelsHandler` | `providers/[id]/models` | _(none)_ |
|
|
123
|
-
| `createMCPServersHandler` | `mcpservers` | `configManager`, `getConfiguredMCPServers` |
|
|
124
|
-
| `createMCPServerByIdHandler` | `mcpservers/[id]` | `configManager`, `getConfiguredMCPServers` |
|
|
125
|
-
| `createMCPServerToggleHandler` | `mcpservers/[id]/toggle` | `configManager`, `getConfiguredMCPServers` |
|
|
126
|
-
| `createSearchHandler` | `search` | `searxngDomain?` (default: `https://search.qwksearch.com`) |
|
|
127
|
-
| `createDiscoverHandler` | `discover` | _(none)_ |
|
|
128
|
-
| `createAutocompleteHandler` | `autocomplete` | _(none)_ |
|
|
129
|
-
| `createSuggestionsHandler` | `suggestions` | _(none)_ |
|
|
130
|
-
| `createAgentsHandler` | `agents` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
131
|
-
| `createRewriteHandler` | `rewrite` | `getEnv`, `generateText`, `createGroq` |
|
|
132
|
-
| `createVoiceHandler` | `voice` | `getUserId`, `checkTTSRateLimit`, `generateSpeech` |
|
|
133
|
-
| `createTranscriptHandler` | `transcript` | `getCloudflareContext` |
|
|
134
|
-
| `createTestModelsHandler` | `test-models` | _(none)_ |
|
|
135
|
-
| `createValidateOpenRouterHandler` | `validate-openrouter` | `validateOpenRouterModels` |
|
|
136
|
-
|
|
137
|
-
### Dep type definitions
|
|
138
|
-
|
|
139
|
-
All dep interfaces are exported from `research-agent-ui/api`:
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
import type {
|
|
143
|
-
ArticleDeps,
|
|
144
|
-
ChatsDeps,
|
|
145
|
-
MessagesDeps,
|
|
146
|
-
ProvidersDeps,
|
|
147
|
-
MCPServersDeps,
|
|
148
|
-
SearchDeps,
|
|
149
|
-
VoiceDeps,
|
|
150
|
-
TranscriptDeps,
|
|
151
|
-
RewriteDeps,
|
|
152
|
-
ValidateOpenRouterDeps,
|
|
153
|
-
AgentsDeps,
|
|
154
|
-
} from "research-agent-ui/api";
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### The chat route
|
|
158
|
-
|
|
159
|
-
`POST /api/agent/chat` is not migrated into this package because it delegates
|
|
160
|
-
to a full `handleChatRequest` orchestrator that is app-specific (streaming,
|
|
161
|
-
search integration, database writes). Keep it directly in your app:
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
// app/api/agent/chat/route.ts
|
|
165
|
-
import { handleChatRequest } from "@/lib/chat";
|
|
166
|
-
|
|
167
|
-
export const runtime = "nodejs";
|
|
168
|
-
export const dynamic = "force-dynamic";
|
|
169
|
-
export const POST = handleChatRequest;
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Configuration
|
|
173
|
-
|
|
174
|
-
`configureResearchAgentUI` overrides app-specific values (branding strings,
|
|
175
|
-
the Google API key used by the Drive picker, and the auto-media-search
|
|
176
|
-
toggle) that would otherwise couple this package to a specific app. See
|
|
177
|
-
`ResearchAgentUIConfig` in `src/config.ts` for the full list.
|
|
1
|
+
# research-agent-ui
|
|
2
|
+
|
|
3
|
+
Chat research agent UI: conversation window, article reader, search config,
|
|
4
|
+
file uploads, and chat history for QwkSearch-style apps. Includes the shadcn
|
|
5
|
+
primitives and icons the components depend on, so it can be dropped into a
|
|
6
|
+
Next.js app with a single dependency.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import {
|
|
14
|
+
ChatProvider,
|
|
15
|
+
SessionProvider,
|
|
16
|
+
ExtractPanelProvider,
|
|
17
|
+
ChatWindow,
|
|
18
|
+
configureResearchAgentUI,
|
|
19
|
+
} from 'research-agent-ui';
|
|
20
|
+
|
|
21
|
+
configureResearchAgentUI({
|
|
22
|
+
appName: 'MyApp',
|
|
23
|
+
getAutoMediaSearch: () => true,
|
|
24
|
+
// ...see ResearchAgentUIConfig for the full list of overridable values
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
function App() {
|
|
28
|
+
return (
|
|
29
|
+
<SessionProvider authClient={myAuthClient}>
|
|
30
|
+
<ExtractPanelProvider>
|
|
31
|
+
<ChatProvider>
|
|
32
|
+
<ChatWindow />
|
|
33
|
+
</ChatProvider>
|
|
34
|
+
</ExtractPanelProvider>
|
|
35
|
+
</SessionProvider>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API Routes (`research-agent-ui/api`)
|
|
41
|
+
|
|
42
|
+
All 25 Next.js route handlers are exported from the `research-agent-ui/api`
|
|
43
|
+
subpath as factory functions. Each factory accepts a **deps** object that
|
|
44
|
+
injects your app's database, auth helpers, and other services, so the same
|
|
45
|
+
handler logic works in any Next.js project without hard-coding any imports.
|
|
46
|
+
|
|
47
|
+
### How it works
|
|
48
|
+
|
|
49
|
+
The route logic lives in `packages/research-agent-ui/src/api/handlers/`.
|
|
50
|
+
Your app's `app/api/agent/*/route.ts` files become thin wrappers that call
|
|
51
|
+
the factory and re-export the HTTP method handlers.
|
|
52
|
+
|
|
53
|
+
### Step 1 — install / workspace link
|
|
54
|
+
|
|
55
|
+
If you are in this monorepo, `research-agent-ui` is already linked via the
|
|
56
|
+
`workspace:*` protocol. For an external project, install the published
|
|
57
|
+
package:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install research-agent-ui
|
|
61
|
+
# or
|
|
62
|
+
bun add research-agent-ui
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Step 2 — create your route files
|
|
66
|
+
|
|
67
|
+
For each API path, create a `route.ts` that calls the matching factory and
|
|
68
|
+
passes in your app's dependencies. Every factory is named
|
|
69
|
+
`create<RouteName>Handler` and is exported from `research-agent-ui/api`.
|
|
70
|
+
|
|
71
|
+
#### Example: `app/api/agent/chats/route.ts`
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createChatsHandler } from "research-agent-ui/api";
|
|
75
|
+
import { getDB } from "@/lib/database";
|
|
76
|
+
import { chats, messages } from "@/lib/database/schema";
|
|
77
|
+
import { requireUserId } from "@/lib/auth/session";
|
|
78
|
+
|
|
79
|
+
const handler = createChatsHandler({
|
|
80
|
+
getDB,
|
|
81
|
+
requireUserId,
|
|
82
|
+
schema: { chats, messages },
|
|
83
|
+
});
|
|
84
|
+
export const { GET, DELETE } = handler;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### Example: `app/api/agent/article-followups/route.ts`
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { createArticleFollowupsHandler } from "research-agent-ui/api";
|
|
91
|
+
import { getUserId } from "@/lib/auth/session";
|
|
92
|
+
import { getDB } from "@/lib/database";
|
|
93
|
+
import { user as userSchema } from "@/lib/database/schema";
|
|
94
|
+
import { getEnv } from "@/lib/env";
|
|
95
|
+
|
|
96
|
+
export const POST = createArticleFollowupsHandler({
|
|
97
|
+
getUserId,
|
|
98
|
+
requireUserId: async () => {
|
|
99
|
+
const id = await getUserId();
|
|
100
|
+
if (!id) throw new Error("Unauthorized");
|
|
101
|
+
return id;
|
|
102
|
+
},
|
|
103
|
+
getDB,
|
|
104
|
+
userSchema,
|
|
105
|
+
getEnv,
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### All available factories and their dep shapes
|
|
110
|
+
|
|
111
|
+
| Factory | File | Required deps |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `createArticleFollowupsHandler` | `article-followups` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
114
|
+
| `createArticleQAHandler` | `article-qa` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
115
|
+
| `createChatsHandler` | `chats` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
116
|
+
| `createChatByIdHandler` | `chats/[id]` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
117
|
+
| `createChatsSearchHandler` | `chats/search` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
118
|
+
| `createChatsShareHandler` | `chats/share` | `getDB`, `requireUserId`, `schema.chats`, `schema.messages` |
|
|
119
|
+
| `createMessagesHandler` | `messages` | `getDB`, `requireUserId`, `messagesSchema` |
|
|
120
|
+
| `createProvidersHandler` | `providers` | `getSession` |
|
|
121
|
+
| `createProviderByIdHandler` | `providers/[id]` | _(none)_ |
|
|
122
|
+
| `createProviderModelsHandler` | `providers/[id]/models` | _(none)_ |
|
|
123
|
+
| `createMCPServersHandler` | `mcpservers` | `configManager`, `getConfiguredMCPServers` |
|
|
124
|
+
| `createMCPServerByIdHandler` | `mcpservers/[id]` | `configManager`, `getConfiguredMCPServers` |
|
|
125
|
+
| `createMCPServerToggleHandler` | `mcpservers/[id]/toggle` | `configManager`, `getConfiguredMCPServers` |
|
|
126
|
+
| `createSearchHandler` | `search` | `searxngDomain?` (default: `https://search.qwksearch.com`) |
|
|
127
|
+
| `createDiscoverHandler` | `discover` | _(none)_ |
|
|
128
|
+
| `createAutocompleteHandler` | `autocomplete` | _(none)_ |
|
|
129
|
+
| `createSuggestionsHandler` | `suggestions` | _(none)_ |
|
|
130
|
+
| `createAgentsHandler` | `agents` | `getUserId`, `requireUserId`, `getDB`, `userSchema`, `getEnv` |
|
|
131
|
+
| `createRewriteHandler` | `rewrite` | `getEnv`, `generateText`, `createGroq` |
|
|
132
|
+
| `createVoiceHandler` | `voice` | `getUserId`, `checkTTSRateLimit`, `generateSpeech` |
|
|
133
|
+
| `createTranscriptHandler` | `transcript` | `getCloudflareContext` |
|
|
134
|
+
| `createTestModelsHandler` | `test-models` | _(none)_ |
|
|
135
|
+
| `createValidateOpenRouterHandler` | `validate-openrouter` | `validateOpenRouterModels` |
|
|
136
|
+
|
|
137
|
+
### Dep type definitions
|
|
138
|
+
|
|
139
|
+
All dep interfaces are exported from `research-agent-ui/api`:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import type {
|
|
143
|
+
ArticleDeps,
|
|
144
|
+
ChatsDeps,
|
|
145
|
+
MessagesDeps,
|
|
146
|
+
ProvidersDeps,
|
|
147
|
+
MCPServersDeps,
|
|
148
|
+
SearchDeps,
|
|
149
|
+
VoiceDeps,
|
|
150
|
+
TranscriptDeps,
|
|
151
|
+
RewriteDeps,
|
|
152
|
+
ValidateOpenRouterDeps,
|
|
153
|
+
AgentsDeps,
|
|
154
|
+
} from "research-agent-ui/api";
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### The chat route
|
|
158
|
+
|
|
159
|
+
`POST /api/agent/chat` is not migrated into this package because it delegates
|
|
160
|
+
to a full `handleChatRequest` orchestrator that is app-specific (streaming,
|
|
161
|
+
search integration, database writes). Keep it directly in your app:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// app/api/agent/chat/route.ts
|
|
165
|
+
import { handleChatRequest } from "@/lib/chat";
|
|
166
|
+
|
|
167
|
+
export const runtime = "nodejs";
|
|
168
|
+
export const dynamic = "force-dynamic";
|
|
169
|
+
export const POST = handleChatRequest;
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Configuration
|
|
173
|
+
|
|
174
|
+
`configureResearchAgentUI` overrides app-specific values (branding strings,
|
|
175
|
+
the Google API key used by the Drive picker, and the auto-media-search
|
|
176
|
+
toggle) that would otherwise couple this package to a specific app. See
|
|
177
|
+
`ResearchAgentUIConfig` in `src/config.ts` for the full list.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "research-agent-ui",
|
|
3
3
|
"description": "Chat research agent UI: conversation window, article reader, search config, file uploads, and chat history",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.16",
|
|
5
5
|
"author": "vtempest",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -60,16 +60,16 @@
|
|
|
60
60
|
"@radix-ui/react-slot": "^1.2.5",
|
|
61
61
|
"@radix-ui/react-tooltip": "^1.2.9",
|
|
62
62
|
"@ricky0123/vad-web": "^0.0.30",
|
|
63
|
-
"chat-agent-toolkit": "^1.2.
|
|
64
|
-
"domain-rank": "^0.1.
|
|
63
|
+
"chat-agent-toolkit": "^1.2.34",
|
|
64
|
+
"domain-rank": "^0.1.23",
|
|
65
65
|
"drizzle-orm": "^0.45.2",
|
|
66
66
|
"fuse.js": "^7.1.0",
|
|
67
67
|
"class-variance-authority": "^0.7.1",
|
|
68
68
|
"clsx": "^2.1.1",
|
|
69
69
|
"dompurify": "^3.4.9",
|
|
70
|
-
"extract-webpage": "^1.2.
|
|
70
|
+
"extract-webpage": "^1.2.36",
|
|
71
71
|
"framer-motion": "^12.40.0",
|
|
72
|
-
"qwksearch-api-client": "^0.0.
|
|
72
|
+
"qwksearch-api-client": "^0.0.28",
|
|
73
73
|
"html2canvas": "^1.4.1",
|
|
74
74
|
"lucide-react": "^1.17.0",
|
|
75
75
|
"markdown-to-jsx": "^9.8.2",
|