@sentry/junior 0.147.0 → 0.148.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.
- package/dist/{agent-hooks-HS6VGUPM.js → agent-hooks-VAUYT6PD.js} +10 -10
- package/dist/api/conversations/access.d.ts +2 -1
- package/dist/api/conversations/archive.d.ts +3 -5
- package/dist/api/conversations/create.d.ts +6 -0
- package/dist/api/conversations/detail.d.ts +2 -296
- package/dist/api/conversations/event-list.d.ts +2 -193
- package/dist/api/conversations/list.d.ts +4 -66
- package/dist/api/conversations/routes.d.ts +1 -1
- package/dist/api/conversations/stats.d.ts +0 -54
- package/dist/api/http.d.ts +2 -6
- package/dist/api/locations/detail.d.ts +3 -111
- package/dist/api/locations/list.d.ts +0 -45
- package/dist/api/locations/query.d.ts +2 -1
- package/dist/api/locations/routes.d.ts +1 -1
- package/dist/api/people/list.d.ts +0 -29
- package/dist/api/people/profile.d.ts +2 -106
- package/dist/api/people/profile.query.d.ts +2 -1
- package/dist/api/people/routes.d.ts +1 -1
- package/dist/api/people/shared.d.ts +1 -1
- package/dist/api/people/spend.d.ts +3 -4
- package/dist/api/personal-tokens/routes.d.ts +2 -2
- package/dist/api/route.d.ts +8 -14
- package/dist/api/schema/conversation.d.ts +60 -29
- package/dist/api/schema/location.d.ts +4 -0
- package/dist/api/schema/person.d.ts +7 -3
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +7 -1
- package/dist/api/stats.d.ts +0 -13
- package/dist/api/validation.d.ts +7 -0
- package/dist/api/viewer.d.ts +3 -0
- package/dist/api.d.ts +2 -1
- package/dist/api.js +624 -562
- package/dist/app.js +183 -105
- package/dist/{catalog-runtime-M6ZTPYRV.js → catalog-runtime-WADOZVTB.js} +5 -5
- package/dist/chat/actor.d.ts +4 -1
- package/dist/chat/agent/request.d.ts +2 -0
- package/dist/chat/agent/resume.d.ts +1 -0
- package/dist/chat/agent-dispatch/context.d.ts +2 -2
- package/dist/chat/agent-invocations/types.d.ts +52 -0
- package/dist/chat/api-turns/work.d.ts +103 -0
- package/dist/chat/conversations/history.d.ts +60 -0
- package/dist/chat/conversations/provenance.d.ts +6 -0
- package/dist/chat/conversations/sql/actor-identity.d.ts +19 -0
- package/dist/chat/conversations/store.d.ts +1 -1
- package/dist/chat/resource-events/store.d.ts +1 -1
- package/dist/chat/runtime/reply-executor.d.ts +1 -1
- package/dist/chat/runtime/slack-runtime.d.ts +2 -1
- package/dist/chat/runtime/turn-preparation.d.ts +9 -0
- package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
- package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
- package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
- package/dist/chat/slack/channel.d.ts +26 -0
- package/dist/chat/slack/dispatch-turn.d.ts +1 -0
- package/dist/chat/slack/timestamp-param.d.ts +0 -2
- package/dist/chat/slack/{tools → tool-support}/canvas/api.d.ts +1 -1
- package/dist/chat/slack/{tools → tool-support}/canvas/context.d.ts +3 -0
- package/dist/chat/slack/tool-support/channel-access.d.ts +42 -0
- package/dist/chat/slack/tool-support/channel-target.d.ts +27 -0
- package/dist/chat/slack/tool-support/list/params.d.ts +5 -0
- package/dist/chat/slack/tools/canvas/create.d.ts +1 -1
- package/dist/chat/slack/tools/channel-join.d.ts +28 -0
- package/dist/chat/slack/tools/channel-list-messages.d.ts +3 -2
- package/dist/chat/slack/tools/conversation-message-search.d.ts +2 -8
- package/dist/chat/slack/tools/message-add-reaction.d.ts +1 -1
- package/dist/chat/slack/tools/public-search.d.ts +63 -2
- package/dist/chat/slack/tools/send-files.d.ts +1 -1
- package/dist/chat/slack/tools/thread-read.d.ts +2 -5
- package/dist/chat/source.d.ts +2 -0
- package/dist/chat/task-execution/checkpoint.d.ts +1 -0
- package/dist/chat/task-execution/state.d.ts +9 -4
- package/dist/chat/task-execution/store.d.ts +3 -2
- package/dist/chat/task-execution/turn-cursor.d.ts +2 -0
- package/dist/chat/task-execution/worker.d.ts +2 -0
- package/dist/chat/tasks/read.d.ts +1 -1
- package/dist/chat/tools/search-conversation-events.d.ts +1 -1
- package/dist/chat/tools/types.d.ts +11 -4
- package/dist/chat/tools/watch-resource-events.d.ts +2 -2
- package/dist/{chunk-ORO3PWKQ.js → chunk-2B3PT3V2.js} +1 -1
- package/dist/{chunk-SVHUEHUL.js → chunk-45LOR4PU.js} +21 -4
- package/dist/{chunk-YBVXBNSV.js → chunk-4AQZYNHM.js} +2 -2
- package/dist/{chunk-Z4YU7Z4L.js → chunk-4EA2SFK2.js} +65 -4
- package/dist/{chunk-7NVJVJID.js → chunk-4GXJUYJV.js} +2 -2
- package/dist/{chunk-IIOOO4FQ.js → chunk-55F4QU2V.js} +2 -1
- package/dist/{chunk-745QJ3ZA.js → chunk-7OEIXFC3.js} +2 -2
- package/dist/{chunk-DU74WPIC.js → chunk-D3WPMGEX.js} +1 -1
- package/dist/{chunk-PVNG6UMU.js → chunk-D6YX4NNN.js} +22 -10
- package/dist/chunk-DUY5CDAM.js +36 -0
- package/dist/{chunk-4LJO56OJ.js → chunk-EAI67NTM.js} +1 -1
- package/dist/{chunk-X5UY34KT.js → chunk-EINWQFXI.js} +8 -8
- package/dist/chunk-GDFF3BQG.js +136 -0
- package/dist/{chunk-EFLJ2WJH.js → chunk-GXYDVZKM.js} +5 -5
- package/dist/{chunk-CWP5RHVX.js → chunk-HLPLT3NY.js} +8 -5
- package/dist/{chunk-JUUKWRBE.js → chunk-HWQGBIH7.js} +1 -1
- package/dist/{chunk-AZ7EAOBE.js → chunk-IL4EDBMV.js} +5 -5
- package/dist/{chunk-DLDRQHG5.js → chunk-LAZGHEYU.js} +1 -1
- package/dist/{chunk-RXBVB2JM.js → chunk-LE5H7LMT.js} +1 -1
- package/dist/chunk-LNVEIJ2L.js +48 -0
- package/dist/{chunk-YEO3VX72.js → chunk-OJCP3C3J.js} +8 -6
- package/dist/{chunk-GGB4WL5A.js → chunk-POSZWRGL.js} +1 -1
- package/dist/{chunk-YNTTROJT.js → chunk-QOWHHM3F.js} +1 -1
- package/dist/{chunk-6H5SZR24.js → chunk-RRJV5UR5.js} +302 -59
- package/dist/{chunk-AYU72WO7.js → chunk-ULAU5ZGU.js} +41 -64
- package/dist/{chunk-SGZO7UWH.js → chunk-V2FXMOEA.js} +2 -2
- package/dist/{chunk-AIOK6LAG.js → chunk-VCYSOXON.js} +272 -41
- package/dist/{chunk-7A4M7PCV.js → chunk-VMNRXKAH.js} +1166 -540
- package/dist/{chunk-YSB2N563.js → chunk-VRHTNBA6.js} +121 -87
- package/dist/{chunk-AVZDSUFB.js → chunk-VY6W3T43.js} +4 -4
- package/dist/{chunk-7UQIVT6G.js → chunk-WCN4YSH7.js} +6 -6
- package/dist/{chunk-CSZINQJ2.js → chunk-WOONT5ZP.js} +1 -1
- package/dist/{chunk-Q4R73I43.js → chunk-XJ42NBP5.js} +58 -28
- package/dist/{chunk-YHDERDRO.js → chunk-ZCHIC2GM.js} +91 -75
- package/dist/chunk-ZPL2RR7F.js +798 -0
- package/dist/cli/chat.js +33 -35
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/agent-invocations.d.ts +20 -0
- package/dist/db/schema/conversation-annotations.d.ts +2 -2
- package/dist/db/schema.d.ts +22 -2
- package/dist/{db-CSEW4RII.js → db-XUKZRFFK.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-FUEV5HNG.js → oauth-callback-server-LPZMMGFI.js} +25 -26
- package/dist/{runner-U3XHSKSH.js → runner-DGKUTMPX.js} +17 -18
- package/dist/{skills-AKE6W3WI.js → skills-P7YUFSXM.js} +6 -6
- package/dist/spawn-DSK3ZEVD.js +38 -0
- package/dist/{validation-WDTAULUF.js → validation-S7U5M5NR.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-C3HAO2BG.js → work-GAA7TVAD.js} +18 -19
- package/dist/{worker-LNP4YKBM.js → worker-JXPJH3QB.js} +11 -10
- package/package.json +5 -4
- package/dist/api/health.d.ts +0 -7
- package/dist/api/personal-tokens/create.d.ts +0 -11
- package/dist/api/personal-tokens/list.d.ts +0 -12
- package/dist/api/personal-tokens/revoke.d.ts +0 -5
- package/dist/api/plugin-reports.d.ts +0 -63
- package/dist/api/plugins.d.ts +0 -8
- package/dist/api/runtime.d.ts +0 -24
- package/dist/api/skills.d.ts +0 -6
- package/dist/chat/slack/tools/channel-access.d.ts +0 -30
- package/dist/chunk-34GS7B6L.js +0 -115
- package/dist/chunk-AVOCH2Z5.js +0 -285
- package/dist/chunk-HLXXQI5Q.js +0 -238
- package/dist/chunk-K4SZAP3K.js +0 -67
- package/dist/chunk-R776HKPK.js +0 -81
- package/dist/spawn-B6GDTWJ4.js +0 -39
- /package/dist/chat/slack/{tools → tool-support}/canvas/markdown.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/channel-capabilities.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/context.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/list/api.d.ts +0 -0
- /package/dist/chat/slack/{tools → tool-support}/slack-message-url.d.ts +0 -0
package/dist/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
acceptedConversationMessageSchema,
|
|
2
3
|
activityDays,
|
|
3
4
|
actorDirectoryReportSchema,
|
|
4
5
|
actorProfileReportSchema,
|
|
@@ -14,6 +15,8 @@ import {
|
|
|
14
15
|
conversationParamsSchema,
|
|
15
16
|
conversationReportEventSchema,
|
|
16
17
|
conversationStatsReportSchema,
|
|
18
|
+
createConversationBodySchema,
|
|
19
|
+
createConversationMessageBodySchema,
|
|
17
20
|
createPersonalTokenBodySchema,
|
|
18
21
|
createdPersonalTokenSchema,
|
|
19
22
|
locationDetailReportSchema,
|
|
@@ -29,15 +32,19 @@ import {
|
|
|
29
32
|
taskListSchema,
|
|
30
33
|
taskParamsSchema,
|
|
31
34
|
taskRunListSchema
|
|
32
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-45LOR4PU.js";
|
|
33
36
|
import {
|
|
37
|
+
appendAndEnqueueApiConversationMessage,
|
|
38
|
+
createAndEnqueueApiConversation,
|
|
34
39
|
formatSlackConversationRedactedLabel,
|
|
35
40
|
readHealthReport,
|
|
36
|
-
resolveSlackConversationContextFromThreadId
|
|
37
|
-
|
|
41
|
+
resolveSlackConversationContextFromThreadId,
|
|
42
|
+
webActorFromEmail
|
|
43
|
+
} from "./chunk-ZPL2RR7F.js";
|
|
38
44
|
import {
|
|
39
45
|
buildSentryConversationUrl
|
|
40
46
|
} from "./chunk-4CODA7P5.js";
|
|
47
|
+
import "./chunk-HLPLT3NY.js";
|
|
41
48
|
import {
|
|
42
49
|
readTaskExecutionByConversationId,
|
|
43
50
|
readTaskExecutionDays,
|
|
@@ -45,7 +52,8 @@ import {
|
|
|
45
52
|
readTaskExecutionSummaries,
|
|
46
53
|
readTaskExecutions,
|
|
47
54
|
readTaskRuns
|
|
48
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-RRJV5UR5.js";
|
|
56
|
+
import "./chunk-IL4EDBMV.js";
|
|
49
57
|
import {
|
|
50
58
|
healthReportSchema,
|
|
51
59
|
pluginOperationalReportFeedSchema,
|
|
@@ -53,6 +61,11 @@ import {
|
|
|
53
61
|
runtimeInfoReportSchema,
|
|
54
62
|
skillReportsSchema
|
|
55
63
|
} from "./chunk-UTL3MHPC.js";
|
|
64
|
+
import {
|
|
65
|
+
getVercelConversationWorkQueue
|
|
66
|
+
} from "./chunk-WR76IVA5.js";
|
|
67
|
+
import "./chunk-JAL3CH4G.js";
|
|
68
|
+
import "./chunk-5I6ORJUY.js";
|
|
56
69
|
import {
|
|
57
70
|
createSchedulerSqlStore,
|
|
58
71
|
deleteEventTask,
|
|
@@ -64,18 +77,19 @@ import {
|
|
|
64
77
|
listPublicEventTasksForTeams,
|
|
65
78
|
listPublicScheduledTasksForTeams,
|
|
66
79
|
readStats
|
|
67
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-GXYDVZKM.js";
|
|
68
81
|
import {
|
|
69
82
|
parseSlackThreadId
|
|
70
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-WOONT5ZP.js";
|
|
71
84
|
import {
|
|
72
85
|
fallbackShortTitle
|
|
73
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-4EA2SFK2.js";
|
|
74
87
|
import {
|
|
75
88
|
agentTurnUsageSchema,
|
|
76
89
|
hasAgentTurnUsage,
|
|
77
90
|
renderJuniorNativeConversationEvent
|
|
78
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-VCYSOXON.js";
|
|
92
|
+
import "./chunk-3Y47VMHV.js";
|
|
79
93
|
import "./chunk-PDO5BLNM.js";
|
|
80
94
|
import {
|
|
81
95
|
createPluginLogger,
|
|
@@ -83,56 +97,73 @@ import {
|
|
|
83
97
|
listConversationAnnotations,
|
|
84
98
|
renderPluginConversationEvent,
|
|
85
99
|
resolveViewerUser
|
|
86
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-ZCHIC2GM.js";
|
|
87
101
|
import {
|
|
88
102
|
getSlackClient,
|
|
89
103
|
withSlackRetries
|
|
90
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-V2FXMOEA.js";
|
|
91
105
|
import {
|
|
92
106
|
decodeStoredConversationEvent,
|
|
107
|
+
getConversationStore,
|
|
93
108
|
getDb,
|
|
94
109
|
getSqlExecutor,
|
|
95
110
|
locationFromRow,
|
|
96
111
|
parseSessionSource
|
|
97
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-VRHTNBA6.js";
|
|
98
113
|
import {
|
|
99
114
|
juniorApiTokens,
|
|
100
115
|
juniorConversationEvents,
|
|
101
116
|
juniorConversations,
|
|
102
117
|
juniorIdentities,
|
|
103
118
|
juniorUsers
|
|
104
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-D3WPMGEX.js";
|
|
105
120
|
import "./chunk-EM225ITJ.js";
|
|
106
|
-
import "./chunk-
|
|
107
|
-
import "./chunk-
|
|
121
|
+
import "./chunk-2B3PT3V2.js";
|
|
122
|
+
import "./chunk-4GXJUYJV.js";
|
|
108
123
|
import {
|
|
109
124
|
juniorDestinations
|
|
110
125
|
} from "./chunk-VFUK3X5B.js";
|
|
111
126
|
import {
|
|
112
127
|
canExposeConversationPayload
|
|
113
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-LE5H7LMT.js";
|
|
129
|
+
import "./chunk-RUIXF3YQ.js";
|
|
114
130
|
import "./chunk-HZF5P5UN.js";
|
|
115
131
|
import {
|
|
116
132
|
parseSlackChannelId,
|
|
117
133
|
parseSlackMessageTs,
|
|
118
134
|
parseSlackTeamId
|
|
119
135
|
} from "./chunk-F3B2YJ76.js";
|
|
120
|
-
import
|
|
136
|
+
import {
|
|
137
|
+
logException
|
|
138
|
+
} from "./chunk-EAI67NTM.js";
|
|
121
139
|
import "./chunk-6GWA276C.js";
|
|
122
|
-
import "./chunk-
|
|
123
|
-
import "./chunk-
|
|
140
|
+
import "./chunk-LAZGHEYU.js";
|
|
141
|
+
import "./chunk-55F4QU2V.js";
|
|
124
142
|
import "./chunk-MLKGABMK.js";
|
|
125
143
|
|
|
126
144
|
// src/api.ts
|
|
127
145
|
import { Hono as Hono7 } from "hono";
|
|
146
|
+
import { HTTPException as HTTPException2 } from "hono/http-exception";
|
|
128
147
|
|
|
129
148
|
// src/api/conversations/routes.ts
|
|
130
149
|
import { Hono } from "hono";
|
|
131
150
|
|
|
132
151
|
// src/api/http.ts
|
|
133
152
|
import { HTTPException } from "hono/http-exception";
|
|
153
|
+
var NO_STORE_HEADERS = { "cache-control": "no-store" };
|
|
154
|
+
function noStoreInit(init) {
|
|
155
|
+
if (!init) return { headers: NO_STORE_HEADERS };
|
|
156
|
+
const headers = new Headers(init.headers);
|
|
157
|
+
if (!headers.has("cache-control")) {
|
|
158
|
+
headers.set("cache-control", "no-store");
|
|
159
|
+
}
|
|
160
|
+
return { ...init, headers };
|
|
161
|
+
}
|
|
134
162
|
function jsonResponse(schema, value, init) {
|
|
135
|
-
return Response.json(schema.parse(value), init);
|
|
163
|
+
return Response.json(schema.parse(value), noStoreInit(init));
|
|
164
|
+
}
|
|
165
|
+
function emptyResponse(status = 204) {
|
|
166
|
+
return new Response(null, noStoreInit({ status }));
|
|
136
167
|
}
|
|
137
168
|
function throwApiError(status, message2, cause) {
|
|
138
169
|
throw new HTTPException(status, {
|
|
@@ -141,35 +172,25 @@ function throwApiError(status, message2, cause) {
|
|
|
141
172
|
res: jsonResponse(apiErrorSchema, { error: message2 }, { status })
|
|
142
173
|
});
|
|
143
174
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (result.success) return result.data;
|
|
152
|
-
return throwApiError(400, "Invalid query parameters.", result.error);
|
|
153
|
-
}
|
|
154
|
-
function parseBody(schema, body) {
|
|
155
|
-
const result = schema.safeParse(body);
|
|
156
|
-
if (result.success) return result.data;
|
|
157
|
-
return throwApiError(400, "Invalid request body.", result.error);
|
|
175
|
+
|
|
176
|
+
// src/api/validation.ts
|
|
177
|
+
import { zValidator } from "@hono/zod-validator";
|
|
178
|
+
function validateRequest(target, schema, message2) {
|
|
179
|
+
return zValidator(target, schema, (result) => {
|
|
180
|
+
if (!result.success) throwApiError(400, message2, result.error);
|
|
181
|
+
});
|
|
158
182
|
}
|
|
159
183
|
|
|
160
|
-
// src/api/
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
route.path,
|
|
169
|
-
async (context) => jsonResponse(route.responseSchema, await route.handler(context))
|
|
170
|
-
);
|
|
184
|
+
// src/api/viewer.ts
|
|
185
|
+
import { createMiddleware } from "hono/factory";
|
|
186
|
+
var requireViewer = createMiddleware(
|
|
187
|
+
async (context, next) => {
|
|
188
|
+
if (!context.get("viewer")) {
|
|
189
|
+
throwApiError(401, "Authentication required.");
|
|
190
|
+
}
|
|
191
|
+
await next();
|
|
171
192
|
}
|
|
172
|
-
|
|
193
|
+
);
|
|
173
194
|
|
|
174
195
|
// src/api/conversations/archive.ts
|
|
175
196
|
import { and, eq, isNotNull } from "drizzle-orm";
|
|
@@ -190,32 +211,133 @@ async function archiveIfUnchanged(args) {
|
|
|
190
211
|
if (!args.archived && existing.archivedAt === null) return "updated";
|
|
191
212
|
return "conflict";
|
|
192
213
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
214
|
+
async function archiveConversation(conversationId, body) {
|
|
215
|
+
const result = await archiveIfUnchanged({ ...body, conversationId });
|
|
216
|
+
if (result === "not_found") {
|
|
217
|
+
throwApiError(404, "Conversation not found.");
|
|
218
|
+
}
|
|
219
|
+
if (result === "conflict") {
|
|
220
|
+
throwApiError(409, "Conversation received new activity.");
|
|
221
|
+
}
|
|
222
|
+
return { archived: body.archived };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/api/conversations/access.ts
|
|
226
|
+
import { eq as eq2, inArray } from "drizzle-orm";
|
|
227
|
+
import { alias } from "drizzle-orm/pg-core";
|
|
228
|
+
var rootConversation = alias(juniorConversations, "access_root_conversation");
|
|
229
|
+
var rootDestination = alias(juniorDestinations, "access_root_destination");
|
|
230
|
+
var rootIdentity = alias(juniorIdentities, "access_root_identity");
|
|
231
|
+
async function readConversationAccessFromSql(db, conversationIds, viewer) {
|
|
232
|
+
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
233
|
+
const normalizedViewerEmail = viewer?.email.trim().toLowerCase() || void 0;
|
|
234
|
+
const rows = await db.select({
|
|
235
|
+
conversationId: juniorConversations.conversationId,
|
|
236
|
+
parentConversationId: juniorConversations.parentConversationId,
|
|
237
|
+
storedRootConversationId: juniorConversations.rootConversationId,
|
|
238
|
+
rootConversationId: rootConversation.conversationId,
|
|
239
|
+
rootParentConversationId: rootConversation.parentConversationId,
|
|
240
|
+
rootRootConversationId: rootConversation.rootConversationId,
|
|
241
|
+
visibility: rootDestination.visibility,
|
|
242
|
+
rootEmailNormalized: rootIdentity.emailNormalized,
|
|
243
|
+
rootEmailVerified: rootIdentity.emailVerified,
|
|
244
|
+
rootUserId: rootIdentity.userId
|
|
245
|
+
}).from(juniorConversations).leftJoin(
|
|
246
|
+
rootConversation,
|
|
247
|
+
eq2(
|
|
248
|
+
rootConversation.conversationId,
|
|
249
|
+
juniorConversations.rootConversationId
|
|
250
|
+
)
|
|
251
|
+
).leftJoin(
|
|
252
|
+
rootDestination,
|
|
253
|
+
eq2(rootDestination.id, rootConversation.destinationId)
|
|
254
|
+
).leftJoin(
|
|
255
|
+
rootIdentity,
|
|
256
|
+
eq2(rootIdentity.id, rootConversation.actorIdentityId)
|
|
257
|
+
).where(inArray(juniorConversations.conversationId, [...conversationIds]));
|
|
258
|
+
return new Map(
|
|
259
|
+
rows.map((row) => {
|
|
260
|
+
const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
|
|
261
|
+
const validRootConversationId = hasValidRoot ? row.rootConversationId ?? void 0 : void 0;
|
|
262
|
+
const visibility = validRootConversationId === void 0 ? null : row.visibility;
|
|
263
|
+
const isParticipant = validRootConversationId !== void 0 && viewer !== void 0 && (row.rootUserId === viewer.id || normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail);
|
|
264
|
+
const canViewPrivateContent = isParticipant || validRootConversationId !== void 0 && canExposeConversationPayload({
|
|
265
|
+
visibility: visibility ?? void 0
|
|
266
|
+
});
|
|
267
|
+
return [
|
|
268
|
+
row.conversationId,
|
|
269
|
+
{
|
|
270
|
+
canViewPrivateContent,
|
|
271
|
+
isParticipant,
|
|
272
|
+
visibility
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
})
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/api/conversations/create.ts
|
|
280
|
+
function actorFromViewer(viewer) {
|
|
281
|
+
const normalized = viewer.email.trim().toLowerCase();
|
|
282
|
+
return webActorFromEmail(normalized, {
|
|
283
|
+
...viewer.displayName ? { fullName: viewer.displayName } : {},
|
|
284
|
+
userName: normalized.split("@")[0] || normalized
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
async function createConversationForViewer(viewer, body) {
|
|
288
|
+
try {
|
|
289
|
+
return await createAndEnqueueApiConversation(
|
|
290
|
+
{
|
|
291
|
+
actor: actorFromViewer(viewer),
|
|
292
|
+
idempotencyKey: body.idempotencyKey,
|
|
293
|
+
message: body.message
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
conversationStore: getConversationStore(),
|
|
297
|
+
queue: getVercelConversationWorkQueue()
|
|
298
|
+
}
|
|
201
299
|
);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
input = await c.req.json();
|
|
205
|
-
} catch (error) {
|
|
206
|
-
throwApiError(400, "Invalid request body.", error);
|
|
207
|
-
}
|
|
208
|
-
const body = parseBody(archiveConversationBodySchema, input);
|
|
209
|
-
const result = await archiveIfUnchanged({ ...body, conversationId });
|
|
210
|
-
if (result === "not_found") {
|
|
211
|
-
throwApiError(404, "Conversation not found.");
|
|
212
|
-
}
|
|
213
|
-
if (result === "conflict") {
|
|
214
|
-
throwApiError(409, "Conversation received new activity.");
|
|
215
|
-
}
|
|
216
|
-
return { archived: body.archived };
|
|
300
|
+
} catch (error) {
|
|
301
|
+
throwApiError(500, "Unable to create conversation.", error);
|
|
217
302
|
}
|
|
218
|
-
}
|
|
303
|
+
}
|
|
304
|
+
async function appendConversationMessageForViewer(viewer, conversationId, body) {
|
|
305
|
+
const conversation = await getConversationStore().get({
|
|
306
|
+
conversationId
|
|
307
|
+
});
|
|
308
|
+
if (!conversation) {
|
|
309
|
+
throwApiError(404, "Conversation not found.");
|
|
310
|
+
}
|
|
311
|
+
const destinationPlatform = conversation.destination?.platform;
|
|
312
|
+
const acceptsApiMessages = destinationPlatform === "local" && conversationId.startsWith("local:web:") || destinationPlatform === "slack";
|
|
313
|
+
if (!acceptsApiMessages) {
|
|
314
|
+
throwApiError(409, "Conversation does not accept API messages.");
|
|
315
|
+
}
|
|
316
|
+
const access = await readConversationAccessFromSql(
|
|
317
|
+
getDb(),
|
|
318
|
+
[conversationId],
|
|
319
|
+
viewer
|
|
320
|
+
);
|
|
321
|
+
if (!access.get(conversationId)?.isParticipant) {
|
|
322
|
+
throwApiError(403, "Only conversation participants can add messages.");
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
return await appendAndEnqueueApiConversationMessage(
|
|
326
|
+
{
|
|
327
|
+
actor: actorFromViewer(viewer),
|
|
328
|
+
conversationId,
|
|
329
|
+
idempotencyKey: body.idempotencyKey,
|
|
330
|
+
message: body.message
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
conversationStore: getConversationStore(),
|
|
334
|
+
queue: getVercelConversationWorkQueue()
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
} catch (error) {
|
|
338
|
+
throwApiError(500, "Unable to append message.", error);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
219
341
|
|
|
220
342
|
// src/chat/slack/source-link.ts
|
|
221
343
|
function parseSlackTeamDomain(value) {
|
|
@@ -332,7 +454,7 @@ async function resolveSlackTeamDomains(teamIds) {
|
|
|
332
454
|
}
|
|
333
455
|
|
|
334
456
|
// src/chat/pi/sql-model-usage.ts
|
|
335
|
-
import { and as and2, eq as
|
|
457
|
+
import { and as and2, eq as eq3, sql } from "drizzle-orm";
|
|
336
458
|
var message = sql`${juniorConversationEvents.payload}`;
|
|
337
459
|
var usage = sql`${message}->'usage'`;
|
|
338
460
|
var cost = sql`${usage}->'cost'`;
|
|
@@ -426,14 +548,14 @@ async function readConversationModelUsageFromSql(executor, options) {
|
|
|
426
548
|
costTotal: summedCost(nonnegativeNumber(cost, "total"))
|
|
427
549
|
}).from(juniorConversationEvents).innerJoin(
|
|
428
550
|
juniorConversations,
|
|
429
|
-
|
|
551
|
+
eq3(
|
|
430
552
|
juniorConversations.conversationId,
|
|
431
553
|
juniorConversationEvents.conversationId
|
|
432
554
|
)
|
|
433
555
|
).where(
|
|
434
556
|
and2(
|
|
435
|
-
options.includeDescendants ?
|
|
436
|
-
|
|
557
|
+
options.includeDescendants ? eq3(juniorConversations.rootConversationId, options.conversationId) : eq3(juniorConversationEvents.conversationId, options.conversationId),
|
|
558
|
+
eq3(juniorConversationEvents.type, "assistant_message"),
|
|
437
559
|
sql`jsonb_typeof(${message}->'provider') = 'string'`,
|
|
438
560
|
sql`jsonb_typeof(${message}->'model') = 'string'`,
|
|
439
561
|
sql`coalesce(${message}->>'provider', '') <> ''`,
|
|
@@ -498,9 +620,9 @@ import {
|
|
|
498
620
|
and as and3,
|
|
499
621
|
asc,
|
|
500
622
|
desc,
|
|
501
|
-
eq as
|
|
623
|
+
eq as eq4,
|
|
502
624
|
getTableColumns,
|
|
503
|
-
inArray,
|
|
625
|
+
inArray as inArray2,
|
|
504
626
|
lt,
|
|
505
627
|
sql as sql2
|
|
506
628
|
} from "drizzle-orm";
|
|
@@ -912,17 +1034,17 @@ async function readConversationEventRows(executor, args) {
|
|
|
912
1034
|
end`
|
|
913
1035
|
}).from(juniorConversationEvents).where(
|
|
914
1036
|
and3(
|
|
915
|
-
|
|
1037
|
+
eq4(juniorConversationEvents.conversationId, args.conversationId),
|
|
916
1038
|
args.beforeSeq === void 0 ? void 0 : lt(juniorConversationEvents.seq, args.beforeSeq),
|
|
917
|
-
|
|
1039
|
+
inArray2(
|
|
918
1040
|
juniorConversationEvents.type,
|
|
919
1041
|
args.types ?? [...conversationReportSourceEventTypes]
|
|
920
1042
|
),
|
|
921
|
-
args.subagentInvocationIds === void 0 ? void 0 :
|
|
1043
|
+
args.subagentInvocationIds === void 0 ? void 0 : inArray2(
|
|
922
1044
|
sql2`${juniorConversationEvents.payload}->>'subagentInvocationId'`,
|
|
923
1045
|
args.subagentInvocationIds
|
|
924
1046
|
),
|
|
925
|
-
args.toolCallIds === void 0 ? void 0 :
|
|
1047
|
+
args.toolCallIds === void 0 ? void 0 : inArray2(
|
|
926
1048
|
sql2`${juniorConversationEvents.payload}->>'toolCallId'`,
|
|
927
1049
|
args.toolCallIds
|
|
928
1050
|
)
|
|
@@ -1043,8 +1165,8 @@ function surfaceFromConversationId(conversationId) {
|
|
|
1043
1165
|
return "internal";
|
|
1044
1166
|
}
|
|
1045
1167
|
function surfaceFromSource(source, conversationId) {
|
|
1046
|
-
if (source === "slack" || source === "api" || source === "scheduler") {
|
|
1047
|
-
return source;
|
|
1168
|
+
if (source === "slack" || source === "api" || source === "web" || source === "scheduler") {
|
|
1169
|
+
return source === "web" ? "api" : source;
|
|
1048
1170
|
}
|
|
1049
1171
|
return surfaceFromConversationId(conversationId);
|
|
1050
1172
|
}
|
|
@@ -1165,6 +1287,7 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
1165
1287
|
visibility
|
|
1166
1288
|
}),
|
|
1167
1289
|
isParticipant: args.access?.isParticipant ?? false,
|
|
1290
|
+
...visibility ? { visibility } : {},
|
|
1168
1291
|
lastProgressAt: new Date(
|
|
1169
1292
|
conversation.execution.updatedAtMs ?? conversation.updatedAtMs
|
|
1170
1293
|
).toISOString(),
|
|
@@ -1184,59 +1307,6 @@ function conversationSummaryFromStoredConversation(args) {
|
|
|
1184
1307
|
};
|
|
1185
1308
|
}
|
|
1186
1309
|
|
|
1187
|
-
// src/api/conversations/access.ts
|
|
1188
|
-
import { eq as eq4, inArray as inArray2 } from "drizzle-orm";
|
|
1189
|
-
import { alias } from "drizzle-orm/pg-core";
|
|
1190
|
-
var rootConversation = alias(juniorConversations, "access_root_conversation");
|
|
1191
|
-
var rootDestination = alias(juniorDestinations, "access_root_destination");
|
|
1192
|
-
var rootIdentity = alias(juniorIdentities, "access_root_identity");
|
|
1193
|
-
async function readConversationAccessFromSql(db, conversationIds, verifiedViewerEmail) {
|
|
1194
|
-
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
1195
|
-
const normalizedViewerEmail = verifiedViewerEmail?.trim().toLowerCase() || void 0;
|
|
1196
|
-
const rows = await db.select({
|
|
1197
|
-
conversationId: juniorConversations.conversationId,
|
|
1198
|
-
parentConversationId: juniorConversations.parentConversationId,
|
|
1199
|
-
storedRootConversationId: juniorConversations.rootConversationId,
|
|
1200
|
-
rootConversationId: rootConversation.conversationId,
|
|
1201
|
-
rootParentConversationId: rootConversation.parentConversationId,
|
|
1202
|
-
rootRootConversationId: rootConversation.rootConversationId,
|
|
1203
|
-
visibility: rootDestination.visibility,
|
|
1204
|
-
rootEmailNormalized: rootIdentity.emailNormalized,
|
|
1205
|
-
rootEmailVerified: rootIdentity.emailVerified
|
|
1206
|
-
}).from(juniorConversations).leftJoin(
|
|
1207
|
-
rootConversation,
|
|
1208
|
-
eq4(
|
|
1209
|
-
rootConversation.conversationId,
|
|
1210
|
-
juniorConversations.rootConversationId
|
|
1211
|
-
)
|
|
1212
|
-
).leftJoin(
|
|
1213
|
-
rootDestination,
|
|
1214
|
-
eq4(rootDestination.id, rootConversation.destinationId)
|
|
1215
|
-
).leftJoin(
|
|
1216
|
-
rootIdentity,
|
|
1217
|
-
eq4(rootIdentity.id, rootConversation.actorIdentityId)
|
|
1218
|
-
).where(inArray2(juniorConversations.conversationId, [...conversationIds]));
|
|
1219
|
-
return new Map(
|
|
1220
|
-
rows.map((row) => {
|
|
1221
|
-
const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
|
|
1222
|
-
const validRootConversationId = hasValidRoot ? row.rootConversationId ?? void 0 : void 0;
|
|
1223
|
-
const visibility = validRootConversationId === void 0 ? null : row.visibility;
|
|
1224
|
-
const isParticipant = validRootConversationId !== void 0 && normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail;
|
|
1225
|
-
const canViewPrivateContent = isParticipant || validRootConversationId !== void 0 && canExposeConversationPayload({
|
|
1226
|
-
visibility: visibility ?? void 0
|
|
1227
|
-
});
|
|
1228
|
-
return [
|
|
1229
|
-
row.conversationId,
|
|
1230
|
-
{
|
|
1231
|
-
canViewPrivateContent,
|
|
1232
|
-
isParticipant,
|
|
1233
|
-
visibility
|
|
1234
|
-
}
|
|
1235
|
-
];
|
|
1236
|
-
})
|
|
1237
|
-
);
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
1310
|
// src/api/conversations/usage.ts
|
|
1241
1311
|
import { and as and4, eq as eq5, inArray as inArray3, isNull, sql as sql3 } from "drizzle-orm";
|
|
1242
1312
|
import { alias as alias2 } from "drizzle-orm/pg-core";
|
|
@@ -1565,11 +1635,7 @@ async function readConversationFeedFromSql(options = {}) {
|
|
|
1565
1635
|
metricsByRoot,
|
|
1566
1636
|
teamDomainByTeamId
|
|
1567
1637
|
] = await Promise.all([
|
|
1568
|
-
readConversationAccessFromSql(
|
|
1569
|
-
db,
|
|
1570
|
-
conversationIds,
|
|
1571
|
-
options.verifiedViewerEmail
|
|
1572
|
-
),
|
|
1638
|
+
readConversationAccessFromSql(db, conversationIds, options.viewer),
|
|
1573
1639
|
readConversationAuxiliaryCostsFromSql(db, conversationIds, {
|
|
1574
1640
|
includeDescendants: true
|
|
1575
1641
|
}),
|
|
@@ -1603,22 +1669,6 @@ async function readConversationFeed(options = {}) {
|
|
|
1603
1669
|
await readConversationFeedFromSql(options)
|
|
1604
1670
|
);
|
|
1605
1671
|
}
|
|
1606
|
-
var list_default = defineApiRoute({
|
|
1607
|
-
method: "get",
|
|
1608
|
-
path: "/",
|
|
1609
|
-
responseSchema: conversationFeedSchema,
|
|
1610
|
-
handler: async (c) => {
|
|
1611
|
-
const { actorEmail } = parseQuery(
|
|
1612
|
-
conversationFeedQuerySchema,
|
|
1613
|
-
c.req.query()
|
|
1614
|
-
);
|
|
1615
|
-
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
1616
|
-
return readConversationFeed({
|
|
1617
|
-
...actorEmail ? { actorEmail } : {},
|
|
1618
|
-
...verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
1619
|
-
});
|
|
1620
|
-
}
|
|
1621
|
-
});
|
|
1622
1672
|
|
|
1623
1673
|
// src/chat/tasks/read.ts
|
|
1624
1674
|
import { and as and7, eq as eq8, or as or2 } from "drizzle-orm";
|
|
@@ -2086,12 +2136,9 @@ async function readConversationSourceTask(args) {
|
|
|
2086
2136
|
conversationId: args.conversationId
|
|
2087
2137
|
});
|
|
2088
2138
|
if (!execution) return void 0;
|
|
2089
|
-
|
|
2090
|
-
if (!email) return { kind: execution.kind };
|
|
2091
|
-
const user = await resolveViewerUser(email);
|
|
2092
|
-
if (!user) return { kind: execution.kind };
|
|
2139
|
+
if (!args.viewer) return { kind: execution.kind };
|
|
2093
2140
|
const candidate = await resolveViewerTaskCandidate(
|
|
2094
|
-
|
|
2141
|
+
args.viewer,
|
|
2095
2142
|
execution.kind,
|
|
2096
2143
|
execution.taskId
|
|
2097
2144
|
);
|
|
@@ -2199,11 +2246,7 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
2199
2246
|
sourceTask,
|
|
2200
2247
|
teamDomainByTeamId
|
|
2201
2248
|
] = await Promise.all([
|
|
2202
|
-
readConversationAccessFromSql(
|
|
2203
|
-
getDb(),
|
|
2204
|
-
[conversationId],
|
|
2205
|
-
options.verifiedViewerEmail
|
|
2206
|
-
),
|
|
2249
|
+
readConversationAccessFromSql(getDb(), [conversationId], options.viewer),
|
|
2207
2250
|
listConversationAnnotations(getDb(), conversationId),
|
|
2208
2251
|
readConversationAuxiliaryCostsFromSql(getDb(), [conversationId], {
|
|
2209
2252
|
includeDescendants: includeDescendantMetrics
|
|
@@ -2218,7 +2261,7 @@ async function readConversationDetailFromSql(conversationId, options) {
|
|
|
2218
2261
|
),
|
|
2219
2262
|
readConversationSourceTask({
|
|
2220
2263
|
conversationId,
|
|
2221
|
-
...options.
|
|
2264
|
+
...options.viewer ? { viewer: options.viewer } : {}
|
|
2222
2265
|
}),
|
|
2223
2266
|
resolveSlackTeamDomains(
|
|
2224
2267
|
record.conversation.sessionSource?.platform === "slack" ? [record.conversation.sessionSource.teamId] : []
|
|
@@ -2252,25 +2295,6 @@ async function readConversationDetail(conversationId, options = {}) {
|
|
|
2252
2295
|
});
|
|
2253
2296
|
return report ? conversationDetailReportSchema.parse(report) : void 0;
|
|
2254
2297
|
}
|
|
2255
|
-
var detail_default = defineApiRoute({
|
|
2256
|
-
method: "get",
|
|
2257
|
-
path: "/:conversationId",
|
|
2258
|
-
responseSchema: conversationDetailReportSchema,
|
|
2259
|
-
handler: async (c) => {
|
|
2260
|
-
const { conversationId } = parseParams(
|
|
2261
|
-
conversationParamsSchema,
|
|
2262
|
-
c.req.param()
|
|
2263
|
-
);
|
|
2264
|
-
const query = parseQuery(conversationDetailQuerySchema, c.req.query());
|
|
2265
|
-
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
2266
|
-
const report = await readConversationDetail(conversationId, {
|
|
2267
|
-
...query,
|
|
2268
|
-
...verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
2269
|
-
});
|
|
2270
|
-
if (!report) throwApiError(404, "Conversation not found.");
|
|
2271
|
-
return report;
|
|
2272
|
-
}
|
|
2273
|
-
});
|
|
2274
2298
|
|
|
2275
2299
|
// src/api/conversations/event-list.ts
|
|
2276
2300
|
async function readConversationEvents(conversationId, beforeValue, options = {}) {
|
|
@@ -2284,7 +2308,7 @@ async function readConversationEvents(conversationId, beforeValue, options = {})
|
|
|
2284
2308
|
const accessByConversation = await readConversationAccessFromSql(
|
|
2285
2309
|
getDb(),
|
|
2286
2310
|
[conversationId],
|
|
2287
|
-
options.
|
|
2311
|
+
options.viewer
|
|
2288
2312
|
);
|
|
2289
2313
|
const access = accessByConversation.get(conversationId);
|
|
2290
2314
|
const canExposePayload = access?.canViewPrivateContent ?? false;
|
|
@@ -2310,28 +2334,6 @@ async function readConversationEvents(conversationId, beforeValue, options = {})
|
|
|
2310
2334
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2311
2335
|
});
|
|
2312
2336
|
}
|
|
2313
|
-
var event_list_default = defineApiRoute({
|
|
2314
|
-
method: "get",
|
|
2315
|
-
path: "/:conversationId/events",
|
|
2316
|
-
responseSchema: conversationEventPageSchema,
|
|
2317
|
-
handler: async (c) => {
|
|
2318
|
-
const { conversationId } = parseParams(
|
|
2319
|
-
conversationParamsSchema,
|
|
2320
|
-
c.req.param()
|
|
2321
|
-
);
|
|
2322
|
-
const { before, limit } = parseQuery(
|
|
2323
|
-
conversationEventsQuerySchema,
|
|
2324
|
-
c.req.query()
|
|
2325
|
-
);
|
|
2326
|
-
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
2327
|
-
const report = await readConversationEvents(conversationId, before, {
|
|
2328
|
-
limit,
|
|
2329
|
-
...verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
2330
|
-
});
|
|
2331
|
-
if (!report) throwApiError(404, "Conversation not found.");
|
|
2332
|
-
return report;
|
|
2333
|
-
}
|
|
2334
|
-
});
|
|
2335
2337
|
|
|
2336
2338
|
// src/api/conversations/stats.query.ts
|
|
2337
2339
|
import { and as and8, eq as eq9, gte, isNull as isNull4, lte, sql as sql6 } from "drizzle-orm";
|
|
@@ -2432,7 +2434,7 @@ function actorLabel(row) {
|
|
|
2432
2434
|
}
|
|
2433
2435
|
function surfaceLabel(source) {
|
|
2434
2436
|
if (source === "scheduler") return "Scheduler";
|
|
2435
|
-
if (source === "api") return "
|
|
2437
|
+
if (source === "api" || source === "web") return "Web";
|
|
2436
2438
|
if (source === "internal" || source === "local") return "Internal";
|
|
2437
2439
|
return "Conversation";
|
|
2438
2440
|
}
|
|
@@ -2688,93 +2690,144 @@ async function readConversationStats() {
|
|
|
2688
2690
|
await readConversationStatsFromSql()
|
|
2689
2691
|
);
|
|
2690
2692
|
}
|
|
2691
|
-
var stats_default = defineApiRoute({
|
|
2692
|
-
method: "get",
|
|
2693
|
-
path: "/stats",
|
|
2694
|
-
responseSchema: conversationStatsReportSchema,
|
|
2695
|
-
handler: readConversationStats
|
|
2696
|
-
});
|
|
2697
2693
|
|
|
2698
2694
|
// src/api/conversations/routes.ts
|
|
2699
|
-
var routes = [
|
|
2700
|
-
list_default,
|
|
2701
|
-
stats_default,
|
|
2702
|
-
archive_default,
|
|
2703
|
-
event_list_default,
|
|
2704
|
-
detail_default
|
|
2705
|
-
];
|
|
2706
2695
|
function createConversationRoutes() {
|
|
2707
2696
|
const app = new Hono();
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
}
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
return skillReportsSchema.parse(
|
|
2727
|
-
skills.map((skill) => ({
|
|
2728
|
-
name: skill.name,
|
|
2729
|
-
pluginProvider: skill.pluginProvider
|
|
2730
|
-
}))
|
|
2697
|
+
app.get(
|
|
2698
|
+
"/",
|
|
2699
|
+
validateRequest(
|
|
2700
|
+
"query",
|
|
2701
|
+
conversationFeedQuerySchema,
|
|
2702
|
+
"Invalid query parameters."
|
|
2703
|
+
),
|
|
2704
|
+
async (context) => {
|
|
2705
|
+
const { actorEmail } = context.req.valid("query");
|
|
2706
|
+
const viewer = context.get("viewer");
|
|
2707
|
+
return jsonResponse(
|
|
2708
|
+
conversationFeedSchema,
|
|
2709
|
+
await readConversationFeed({
|
|
2710
|
+
...actorEmail ? { actorEmail } : {},
|
|
2711
|
+
...viewer ? { viewer } : {}
|
|
2712
|
+
})
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2731
2715
|
);
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
return pluginsSchema.parse(
|
|
2736
|
-
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
2737
|
-
configKeys: plugin.manifest.configKeys ?? [],
|
|
2738
|
-
description: plugin.manifest.description,
|
|
2739
|
-
displayName: plugin.manifest.displayName,
|
|
2740
|
-
name: plugin.manifest.name
|
|
2741
|
-
}))
|
|
2716
|
+
app.get(
|
|
2717
|
+
"/stats",
|
|
2718
|
+
async () => jsonResponse(conversationStatsReportSchema, await readConversationStats())
|
|
2742
2719
|
);
|
|
2720
|
+
app.post(
|
|
2721
|
+
"/",
|
|
2722
|
+
requireViewer,
|
|
2723
|
+
validateRequest(
|
|
2724
|
+
"json",
|
|
2725
|
+
createConversationBodySchema,
|
|
2726
|
+
"Invalid request body."
|
|
2727
|
+
),
|
|
2728
|
+
async (context) => {
|
|
2729
|
+
const viewer = context.get("viewer");
|
|
2730
|
+
const body = context.req.valid("json");
|
|
2731
|
+
return jsonResponse(
|
|
2732
|
+
acceptedConversationMessageSchema,
|
|
2733
|
+
await createConversationForViewer(viewer, body)
|
|
2734
|
+
);
|
|
2735
|
+
}
|
|
2736
|
+
);
|
|
2737
|
+
app.post(
|
|
2738
|
+
"/:conversationId/messages",
|
|
2739
|
+
requireViewer,
|
|
2740
|
+
validateRequest(
|
|
2741
|
+
"param",
|
|
2742
|
+
conversationParamsSchema,
|
|
2743
|
+
"Invalid route parameters."
|
|
2744
|
+
),
|
|
2745
|
+
validateRequest(
|
|
2746
|
+
"json",
|
|
2747
|
+
createConversationMessageBodySchema,
|
|
2748
|
+
"Invalid request body."
|
|
2749
|
+
),
|
|
2750
|
+
async (context) => {
|
|
2751
|
+
const viewer = context.get("viewer");
|
|
2752
|
+
const { conversationId } = context.req.valid("param");
|
|
2753
|
+
const body = context.req.valid("json");
|
|
2754
|
+
return jsonResponse(
|
|
2755
|
+
acceptedConversationMessageSchema,
|
|
2756
|
+
await appendConversationMessageForViewer(viewer, conversationId, body)
|
|
2757
|
+
);
|
|
2758
|
+
}
|
|
2759
|
+
);
|
|
2760
|
+
app.patch(
|
|
2761
|
+
"/:conversationId/archive",
|
|
2762
|
+
validateRequest(
|
|
2763
|
+
"param",
|
|
2764
|
+
conversationParamsSchema,
|
|
2765
|
+
"Invalid route parameters."
|
|
2766
|
+
),
|
|
2767
|
+
validateRequest(
|
|
2768
|
+
"json",
|
|
2769
|
+
archiveConversationBodySchema,
|
|
2770
|
+
"Invalid request body."
|
|
2771
|
+
),
|
|
2772
|
+
async (context) => {
|
|
2773
|
+
const { conversationId } = context.req.valid("param");
|
|
2774
|
+
const body = context.req.valid("json");
|
|
2775
|
+
return jsonResponse(
|
|
2776
|
+
archiveConversationResponseSchema,
|
|
2777
|
+
await archiveConversation(conversationId, body)
|
|
2778
|
+
);
|
|
2779
|
+
}
|
|
2780
|
+
);
|
|
2781
|
+
app.get(
|
|
2782
|
+
"/:conversationId/events",
|
|
2783
|
+
validateRequest(
|
|
2784
|
+
"param",
|
|
2785
|
+
conversationParamsSchema,
|
|
2786
|
+
"Invalid route parameters."
|
|
2787
|
+
),
|
|
2788
|
+
validateRequest(
|
|
2789
|
+
"query",
|
|
2790
|
+
conversationEventsQuerySchema,
|
|
2791
|
+
"Invalid query parameters."
|
|
2792
|
+
),
|
|
2793
|
+
async (context) => {
|
|
2794
|
+
const { conversationId } = context.req.valid("param");
|
|
2795
|
+
const { before, limit } = context.req.valid("query");
|
|
2796
|
+
const viewer = context.get("viewer");
|
|
2797
|
+
const report = await readConversationEvents(conversationId, before, {
|
|
2798
|
+
limit,
|
|
2799
|
+
...viewer ? { viewer } : {}
|
|
2800
|
+
});
|
|
2801
|
+
if (!report) throwApiError(404, "Conversation not found.");
|
|
2802
|
+
return jsonResponse(conversationEventPageSchema, report);
|
|
2803
|
+
}
|
|
2804
|
+
);
|
|
2805
|
+
app.get(
|
|
2806
|
+
"/:conversationId",
|
|
2807
|
+
validateRequest(
|
|
2808
|
+
"param",
|
|
2809
|
+
conversationParamsSchema,
|
|
2810
|
+
"Invalid route parameters."
|
|
2811
|
+
),
|
|
2812
|
+
validateRequest(
|
|
2813
|
+
"query",
|
|
2814
|
+
conversationDetailQuerySchema,
|
|
2815
|
+
"Invalid query parameters."
|
|
2816
|
+
),
|
|
2817
|
+
async (context) => {
|
|
2818
|
+
const { conversationId } = context.req.valid("param");
|
|
2819
|
+
const query = context.req.valid("query");
|
|
2820
|
+
const viewer = context.get("viewer");
|
|
2821
|
+
const report = await readConversationDetail(conversationId, {
|
|
2822
|
+
...query,
|
|
2823
|
+
...viewer ? { viewer } : {}
|
|
2824
|
+
});
|
|
2825
|
+
if (!report) throwApiError(404, "Conversation not found.");
|
|
2826
|
+
return jsonResponse(conversationDetailReportSchema, report);
|
|
2827
|
+
}
|
|
2828
|
+
);
|
|
2829
|
+
return app;
|
|
2743
2830
|
}
|
|
2744
|
-
async function readRuntimeInfoReport() {
|
|
2745
|
-
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
2746
|
-
import("./discovery-GUFTFBTL.js"),
|
|
2747
|
-
import("./catalog-runtime-M6ZTPYRV.js"),
|
|
2748
|
-
readPlugins(),
|
|
2749
|
-
readSkillReports()
|
|
2750
|
-
]);
|
|
2751
|
-
const home = homeDir();
|
|
2752
|
-
return runtimeInfoReportSchema.parse({
|
|
2753
|
-
cwd: process.cwd(),
|
|
2754
|
-
homeDir: home,
|
|
2755
|
-
descriptionText: readDescriptionText(home),
|
|
2756
|
-
providers: plugins.map((plugin) => plugin.name),
|
|
2757
|
-
skills,
|
|
2758
|
-
packagedContent: pluginCatalogRuntime.getPackageContent()
|
|
2759
|
-
});
|
|
2760
|
-
}
|
|
2761
|
-
async function readPluginOperationalReportFeed() {
|
|
2762
|
-
const nowMs = Date.now();
|
|
2763
|
-
const { getPluginOperationalReports } = await import("./agent-hooks-HS6VGUPM.js");
|
|
2764
|
-
return pluginOperationalReportFeedSchema.parse({
|
|
2765
|
-
source: "plugins",
|
|
2766
|
-
generatedAt: new Date(nowMs).toISOString(),
|
|
2767
|
-
reports: await getPluginOperationalReports(nowMs)
|
|
2768
|
-
});
|
|
2769
|
-
}
|
|
2770
|
-
|
|
2771
|
-
// src/api/health.ts
|
|
2772
|
-
var health_default = defineApiRoute({
|
|
2773
|
-
method: "get",
|
|
2774
|
-
path: "/api/health",
|
|
2775
|
-
responseSchema: healthReportSchema,
|
|
2776
|
-
handler: readHealthReport
|
|
2777
|
-
});
|
|
2778
2831
|
|
|
2779
2832
|
// src/api/locations/routes.ts
|
|
2780
2833
|
import { Hono as Hono2 } from "hono";
|
|
@@ -3175,7 +3228,7 @@ async function readLocationDetailFromSql(locationId, options = {}) {
|
|
|
3175
3228
|
readConversationAccessFromSql(
|
|
3176
3229
|
getDb(),
|
|
3177
3230
|
recentConversationIds,
|
|
3178
|
-
options.
|
|
3231
|
+
options.viewer
|
|
3179
3232
|
),
|
|
3180
3233
|
readRootConversationMetricsFromSql(getDb(), recentConversationIds)
|
|
3181
3234
|
]);
|
|
@@ -3203,21 +3256,6 @@ async function readLocationDetail(locationId, options = {}) {
|
|
|
3203
3256
|
const report = await readLocationDetailFromSql(locationId, options);
|
|
3204
3257
|
return report ? locationDetailReportSchema.parse(report) : void 0;
|
|
3205
3258
|
}
|
|
3206
|
-
var detail_default2 = defineApiRoute({
|
|
3207
|
-
method: "get",
|
|
3208
|
-
path: "/:locationId",
|
|
3209
|
-
responseSchema: locationDetailReportSchema,
|
|
3210
|
-
handler: async (c) => {
|
|
3211
|
-
const { locationId } = parseParams(locationParamsSchema, c.req.param());
|
|
3212
|
-
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
3213
|
-
const report = await readLocationDetail(
|
|
3214
|
-
locationId,
|
|
3215
|
-
verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
3216
|
-
);
|
|
3217
|
-
if (!report) throwApiError(404, "Location not found.");
|
|
3218
|
-
return report;
|
|
3219
|
-
}
|
|
3220
|
-
});
|
|
3221
3259
|
|
|
3222
3260
|
// src/api/locations/list.ts
|
|
3223
3261
|
async function readLocationDirectory() {
|
|
@@ -3225,18 +3263,32 @@ async function readLocationDirectory() {
|
|
|
3225
3263
|
await readLocationDirectoryFromSql()
|
|
3226
3264
|
);
|
|
3227
3265
|
}
|
|
3228
|
-
var list_default2 = defineApiRoute({
|
|
3229
|
-
method: "get",
|
|
3230
|
-
path: "/",
|
|
3231
|
-
responseSchema: locationDirectoryReportSchema,
|
|
3232
|
-
handler: readLocationDirectory
|
|
3233
|
-
});
|
|
3234
3266
|
|
|
3235
3267
|
// src/api/locations/routes.ts
|
|
3236
|
-
var routes2 = [list_default2, detail_default2];
|
|
3237
3268
|
function createLocationRoutes() {
|
|
3238
3269
|
const app = new Hono2();
|
|
3239
|
-
|
|
3270
|
+
app.get(
|
|
3271
|
+
"/",
|
|
3272
|
+
async () => jsonResponse(locationDirectoryReportSchema, await readLocationDirectory())
|
|
3273
|
+
);
|
|
3274
|
+
app.get(
|
|
3275
|
+
"/:locationId",
|
|
3276
|
+
validateRequest(
|
|
3277
|
+
"param",
|
|
3278
|
+
locationParamsSchema,
|
|
3279
|
+
"Invalid route parameters."
|
|
3280
|
+
),
|
|
3281
|
+
async (context) => {
|
|
3282
|
+
const { locationId } = context.req.valid("param");
|
|
3283
|
+
const viewer = context.get("viewer");
|
|
3284
|
+
const report = await readLocationDetail(
|
|
3285
|
+
locationId,
|
|
3286
|
+
viewer ? { viewer } : {}
|
|
3287
|
+
);
|
|
3288
|
+
if (!report) throwApiError(404, "Location not found.");
|
|
3289
|
+
return jsonResponse(locationDetailReportSchema, report);
|
|
3290
|
+
}
|
|
3291
|
+
);
|
|
3240
3292
|
return app;
|
|
3241
3293
|
}
|
|
3242
3294
|
|
|
@@ -3474,12 +3526,6 @@ async function readPeopleListFromSql() {
|
|
|
3474
3526
|
async function readPeopleList() {
|
|
3475
3527
|
return actorDirectoryReportSchema.parse(await readPeopleListFromSql());
|
|
3476
3528
|
}
|
|
3477
|
-
var list_default3 = defineApiRoute({
|
|
3478
|
-
method: "get",
|
|
3479
|
-
path: "/",
|
|
3480
|
-
responseSchema: actorDirectoryReportSchema,
|
|
3481
|
-
handler: readPeopleList
|
|
3482
|
-
});
|
|
3483
3529
|
|
|
3484
3530
|
// src/api/people/profile.query.ts
|
|
3485
3531
|
import { and as and12, eq as eq13, gte as gte4, sql as sql10 } from "drizzle-orm";
|
|
@@ -3631,7 +3677,7 @@ async function readPeopleProfileFromSql(email, options = {}) {
|
|
|
3631
3677
|
readConversationAccessFromSql(
|
|
3632
3678
|
getDb(),
|
|
3633
3679
|
recentConversationIds,
|
|
3634
|
-
options.
|
|
3680
|
+
options.viewer
|
|
3635
3681
|
),
|
|
3636
3682
|
readRootConversationMetricsFromSql(getDb(), recentConversationIds)
|
|
3637
3683
|
]);
|
|
@@ -3667,19 +3713,6 @@ async function readPeopleProfile(email, options = {}) {
|
|
|
3667
3713
|
await readPeopleProfileFromSql(email, options)
|
|
3668
3714
|
);
|
|
3669
3715
|
}
|
|
3670
|
-
var profile_default = defineApiRoute({
|
|
3671
|
-
method: "get",
|
|
3672
|
-
path: "/:email",
|
|
3673
|
-
responseSchema: actorProfileReportSchema,
|
|
3674
|
-
handler: async (c) => {
|
|
3675
|
-
const { email } = parseParams(personParamsSchema, c.req.param());
|
|
3676
|
-
const verifiedViewerEmail = c.get("verifiedViewerEmail");
|
|
3677
|
-
return readPeopleProfile(
|
|
3678
|
-
email,
|
|
3679
|
-
verifiedViewerEmail ? { verifiedViewerEmail } : {}
|
|
3680
|
-
);
|
|
3681
|
-
}
|
|
3682
|
-
});
|
|
3683
3716
|
|
|
3684
3717
|
// src/api/people/spend.query.ts
|
|
3685
3718
|
import { and as and13, eq as eq14, gte as gte5, lte as lte2, sql as sql11 } from "drizzle-orm";
|
|
@@ -3741,9 +3774,9 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
|
|
|
3741
3774
|
|
|
3742
3775
|
// src/api/people/spend.ts
|
|
3743
3776
|
var PERSONAL_SPEND_CACHE_TTL_MS = 5 * 6e4;
|
|
3744
|
-
function
|
|
3777
|
+
function createPersonalSpendReader() {
|
|
3745
3778
|
const cache = /* @__PURE__ */ new Map();
|
|
3746
|
-
async function
|
|
3779
|
+
return async function readPersonalSpend(email) {
|
|
3747
3780
|
const normalizedEmail = email.trim().toLowerCase();
|
|
3748
3781
|
const nowMs = Date.now();
|
|
3749
3782
|
const cached = cache.get(normalizedEmail);
|
|
@@ -3763,39 +3796,39 @@ function createPersonalSpendRoute() {
|
|
|
3763
3796
|
if (cache.get(normalizedEmail) === entry) cache.delete(normalizedEmail);
|
|
3764
3797
|
throw error;
|
|
3765
3798
|
}
|
|
3766
|
-
}
|
|
3767
|
-
return defineApiRoute({
|
|
3768
|
-
method: "get",
|
|
3769
|
-
path: "/me/spend",
|
|
3770
|
-
responseSchema: personalSpendReportSchema,
|
|
3771
|
-
handler: async (context) => {
|
|
3772
|
-
const email = context.get("verifiedViewerEmail");
|
|
3773
|
-
if (!email) throwApiError(403, "Verified viewer email required.");
|
|
3774
|
-
return read(email);
|
|
3775
|
-
}
|
|
3776
|
-
});
|
|
3799
|
+
};
|
|
3777
3800
|
}
|
|
3778
3801
|
|
|
3779
3802
|
// src/api/people/routes.ts
|
|
3780
3803
|
function createPeopleRoutes() {
|
|
3781
3804
|
const app = new Hono3();
|
|
3782
|
-
const
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3805
|
+
const readPersonalSpend = createPersonalSpendReader();
|
|
3806
|
+
app.get("/me/spend", requireViewer, async (context) => {
|
|
3807
|
+
const viewer = context.get("viewer");
|
|
3808
|
+
return jsonResponse(
|
|
3809
|
+
personalSpendReportSchema,
|
|
3810
|
+
await readPersonalSpend(viewer.email)
|
|
3811
|
+
);
|
|
3812
|
+
});
|
|
3813
|
+
app.get(
|
|
3814
|
+
"/",
|
|
3815
|
+
async () => jsonResponse(actorDirectoryReportSchema, await readPeopleList())
|
|
3816
|
+
);
|
|
3817
|
+
app.get(
|
|
3818
|
+
"/:email",
|
|
3819
|
+
validateRequest("param", personParamsSchema, "Invalid route parameters."),
|
|
3820
|
+
async (context) => {
|
|
3821
|
+
const { email } = context.req.valid("param");
|
|
3822
|
+
const viewer = context.get("viewer");
|
|
3823
|
+
return jsonResponse(
|
|
3824
|
+
actorProfileReportSchema,
|
|
3825
|
+
await readPeopleProfile(email, viewer ? { viewer } : {})
|
|
3826
|
+
);
|
|
3827
|
+
}
|
|
3828
|
+
);
|
|
3788
3829
|
return app;
|
|
3789
3830
|
}
|
|
3790
3831
|
|
|
3791
|
-
// src/api/plugin-reports.ts
|
|
3792
|
-
var plugin_reports_default = defineApiRoute({
|
|
3793
|
-
method: "get",
|
|
3794
|
-
path: "/api/plugin-reports",
|
|
3795
|
-
responseSchema: pluginOperationalReportFeedSchema,
|
|
3796
|
-
handler: readPluginOperationalReportFeed
|
|
3797
|
-
});
|
|
3798
|
-
|
|
3799
3832
|
// src/api/personal-tokens/routes.ts
|
|
3800
3833
|
import { Hono as Hono4 } from "hono";
|
|
3801
3834
|
|
|
@@ -3874,63 +3907,57 @@ async function authenticatePersonalToken(token2, now = /* @__PURE__ */ new Date(
|
|
|
3874
3907
|
return match.ownerEmailNormalized;
|
|
3875
3908
|
}
|
|
3876
3909
|
|
|
3877
|
-
// src/api/personal-tokens/create.ts
|
|
3878
|
-
var create_default = defineApiRoute({
|
|
3879
|
-
method: "post",
|
|
3880
|
-
path: "/",
|
|
3881
|
-
responseSchema: createdPersonalTokenSchema,
|
|
3882
|
-
handler: async (c) => {
|
|
3883
|
-
const email = c.get("verifiedViewerEmail");
|
|
3884
|
-
if (!email) throwApiError(403, "Verified viewer email required.");
|
|
3885
|
-
let input;
|
|
3886
|
-
try {
|
|
3887
|
-
input = await c.req.json();
|
|
3888
|
-
} catch (error) {
|
|
3889
|
-
throwApiError(400, "Invalid request body.", error);
|
|
3890
|
-
}
|
|
3891
|
-
const body = parseBody(createPersonalTokenBodySchema, input);
|
|
3892
|
-
return createPersonalToken({ email, name: body.name });
|
|
3893
|
-
}
|
|
3894
|
-
});
|
|
3895
|
-
|
|
3896
|
-
// src/api/personal-tokens/list.ts
|
|
3897
|
-
var list_default4 = defineApiRoute({
|
|
3898
|
-
method: "get",
|
|
3899
|
-
path: "/",
|
|
3900
|
-
responseSchema: personalTokenListSchema,
|
|
3901
|
-
handler: async (c) => {
|
|
3902
|
-
const email = c.get("verifiedViewerEmail");
|
|
3903
|
-
if (!email) throwApiError(403, "Verified viewer email required.");
|
|
3904
|
-
return { tokens: await listPersonalTokens(email) };
|
|
3905
|
-
}
|
|
3906
|
-
});
|
|
3907
|
-
|
|
3908
|
-
// src/api/personal-tokens/revoke.ts
|
|
3909
|
-
var revoke_default = defineApiRoute({
|
|
3910
|
-
method: "delete",
|
|
3911
|
-
path: "/:id",
|
|
3912
|
-
responseSchema: revokePersonalTokenResponseSchema,
|
|
3913
|
-
handler: async (c) => {
|
|
3914
|
-
const email = c.get("verifiedViewerEmail");
|
|
3915
|
-
if (!email) throwApiError(403, "Verified viewer email required.");
|
|
3916
|
-
const { id } = parseParams(personalTokenParamsSchema, c.req.param());
|
|
3917
|
-
if (!await revokePersonalToken({ email, id })) {
|
|
3918
|
-
throwApiError(404, "Personal API token not found.");
|
|
3919
|
-
}
|
|
3920
|
-
return { revoked: true };
|
|
3921
|
-
}
|
|
3922
|
-
});
|
|
3923
|
-
|
|
3924
3910
|
// src/api/personal-tokens/routes.ts
|
|
3925
|
-
var routes3 = [list_default4, create_default, revoke_default];
|
|
3926
3911
|
function createPersonalTokenRoutes() {
|
|
3927
3912
|
const app = new Hono4();
|
|
3928
|
-
|
|
3913
|
+
app.get("/", requireViewer, async (context) => {
|
|
3914
|
+
const viewer = context.get("viewer");
|
|
3915
|
+
return jsonResponse(personalTokenListSchema, {
|
|
3916
|
+
tokens: await listPersonalTokens(viewer.email)
|
|
3917
|
+
});
|
|
3918
|
+
});
|
|
3919
|
+
app.post(
|
|
3920
|
+
"/",
|
|
3921
|
+
requireViewer,
|
|
3922
|
+
validateRequest(
|
|
3923
|
+
"json",
|
|
3924
|
+
createPersonalTokenBodySchema,
|
|
3925
|
+
"Invalid request body."
|
|
3926
|
+
),
|
|
3927
|
+
async (context) => {
|
|
3928
|
+
const viewer = context.get("viewer");
|
|
3929
|
+
const body = context.req.valid("json");
|
|
3930
|
+
return jsonResponse(
|
|
3931
|
+
createdPersonalTokenSchema,
|
|
3932
|
+
await createPersonalToken({ email: viewer.email, name: body.name })
|
|
3933
|
+
);
|
|
3934
|
+
}
|
|
3935
|
+
);
|
|
3936
|
+
app.delete(
|
|
3937
|
+
"/:id",
|
|
3938
|
+
requireViewer,
|
|
3939
|
+
validateRequest(
|
|
3940
|
+
"param",
|
|
3941
|
+
personalTokenParamsSchema,
|
|
3942
|
+
"Invalid route parameters."
|
|
3943
|
+
),
|
|
3944
|
+
async (context) => {
|
|
3945
|
+
const viewer = context.get("viewer");
|
|
3946
|
+
const { id } = context.req.valid("param");
|
|
3947
|
+
if (!await revokePersonalToken({ email: viewer.email, id })) {
|
|
3948
|
+
throwApiError(404, "Personal API token not found.");
|
|
3949
|
+
}
|
|
3950
|
+
return jsonResponse(revokePersonalTokenResponseSchema, {
|
|
3951
|
+
revoked: true
|
|
3952
|
+
});
|
|
3953
|
+
}
|
|
3954
|
+
);
|
|
3929
3955
|
return app;
|
|
3930
3956
|
}
|
|
3931
3957
|
|
|
3932
3958
|
// src/api/user-pages/routes.ts
|
|
3933
3959
|
import { Hono as Hono5 } from "hono";
|
|
3960
|
+
import { z as z4 } from "zod";
|
|
3934
3961
|
import {
|
|
3935
3962
|
pluginUserPageContentSchema as pluginUserPageContentSchema2,
|
|
3936
3963
|
pluginUserPageInputSchema,
|
|
@@ -3968,8 +3995,8 @@ async function readPluginUserPage(input) {
|
|
|
3968
3995
|
(candidate) => candidate.id === input.pageId
|
|
3969
3996
|
);
|
|
3970
3997
|
if (!plugin || !page) return void 0;
|
|
3971
|
-
const
|
|
3972
|
-
if (!
|
|
3998
|
+
const viewer = await resolveViewerUser(input.email);
|
|
3999
|
+
if (!viewer) {
|
|
3973
4000
|
throw new Error("Authenticated viewer user could not be resolved");
|
|
3974
4001
|
}
|
|
3975
4002
|
const content = pluginUserPageContentSchema.parse(
|
|
@@ -3978,7 +4005,7 @@ async function readPluginUserPage(input) {
|
|
|
3978
4005
|
db: getDb(),
|
|
3979
4006
|
log: createPluginLogger(plugin.manifest.name),
|
|
3980
4007
|
plugin: { name: plugin.manifest.name },
|
|
3981
|
-
viewer
|
|
4008
|
+
viewer
|
|
3982
4009
|
},
|
|
3983
4010
|
input.query
|
|
3984
4011
|
)
|
|
@@ -3996,167 +4023,114 @@ async function readPluginUserPage(input) {
|
|
|
3996
4023
|
}
|
|
3997
4024
|
|
|
3998
4025
|
// src/api/user-pages/routes.ts
|
|
4026
|
+
var userPageQuerySchema = z4.object({
|
|
4027
|
+
cursor: z4.preprocess(
|
|
4028
|
+
(value) => value || void 0,
|
|
4029
|
+
pluginUserPageInputSchema.shape.cursor
|
|
4030
|
+
),
|
|
4031
|
+
filter: z4.preprocess(
|
|
4032
|
+
(value) => value || void 0,
|
|
4033
|
+
pluginUserPageInputSchema.shape.filter
|
|
4034
|
+
),
|
|
4035
|
+
limit: z4.preprocess(
|
|
4036
|
+
(value) => value === "" ? void 0 : value,
|
|
4037
|
+
z4.coerce.number().int().min(1).max(50).default(20)
|
|
4038
|
+
),
|
|
4039
|
+
q: z4.preprocess(
|
|
4040
|
+
(value) => value || void 0,
|
|
4041
|
+
pluginUserPageInputSchema.shape.query
|
|
4042
|
+
)
|
|
4043
|
+
});
|
|
3999
4044
|
function createUserPageRoutes() {
|
|
4000
4045
|
const app = new Hono5();
|
|
4001
4046
|
app.get(
|
|
4002
4047
|
"/",
|
|
4003
4048
|
() => jsonResponse(pluginUserPageLinksSchema2, readPluginUserPageLinks())
|
|
4004
4049
|
);
|
|
4005
|
-
app.get(
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
});
|
|
4020
|
-
if (!pageInput.success) {
|
|
4021
|
-
return jsonResponse(
|
|
4050
|
+
app.get(
|
|
4051
|
+
"/:pluginName/:pageId",
|
|
4052
|
+
requireViewer,
|
|
4053
|
+
validateRequest("query", userPageQuerySchema, "Invalid user page query."),
|
|
4054
|
+
async (context) => {
|
|
4055
|
+
const viewer = context.get("viewer");
|
|
4056
|
+
const { q, ...query } = context.req.valid("query");
|
|
4057
|
+
const page = await readPluginUserPage({
|
|
4058
|
+
email: viewer.email,
|
|
4059
|
+
pageId: context.req.param("pageId"),
|
|
4060
|
+
pluginName: context.req.param("pluginName"),
|
|
4061
|
+
query: { ...query, ...q === void 0 ? {} : { query: q } }
|
|
4062
|
+
});
|
|
4063
|
+
return page ? jsonResponse(pluginUserPageContentSchema2, page) : jsonResponse(
|
|
4022
4064
|
apiErrorSchema,
|
|
4023
|
-
{ error: "
|
|
4024
|
-
{ status:
|
|
4065
|
+
{ error: "User page not found." },
|
|
4066
|
+
{ status: 404 }
|
|
4025
4067
|
);
|
|
4026
4068
|
}
|
|
4027
|
-
|
|
4028
|
-
email,
|
|
4029
|
-
pageId: context.req.param("pageId"),
|
|
4030
|
-
pluginName: context.req.param("pluginName"),
|
|
4031
|
-
query: pageInput.data
|
|
4032
|
-
});
|
|
4033
|
-
return page ? jsonResponse(pluginUserPageContentSchema2, page) : jsonResponse(
|
|
4034
|
-
apiErrorSchema,
|
|
4035
|
-
{ error: "User page not found." },
|
|
4036
|
-
{ status: 404 }
|
|
4037
|
-
);
|
|
4038
|
-
});
|
|
4069
|
+
);
|
|
4039
4070
|
return app;
|
|
4040
4071
|
}
|
|
4041
4072
|
|
|
4042
4073
|
// src/api/tasks/routes.ts
|
|
4043
4074
|
import { Hono as Hono6 } from "hono";
|
|
4044
|
-
async function viewer(context) {
|
|
4045
|
-
const email = context.get("verifiedViewerEmail")?.trim();
|
|
4046
|
-
return email ? await resolveViewerUser(email) : void 0;
|
|
4047
|
-
}
|
|
4048
4075
|
function createTaskRoutes() {
|
|
4049
4076
|
const app = new Hono6();
|
|
4050
|
-
app.get("/", async (context) => {
|
|
4051
|
-
const user =
|
|
4052
|
-
return
|
|
4053
|
-
apiErrorSchema,
|
|
4054
|
-
{ error: "Authentication required." },
|
|
4055
|
-
{ status: 401 }
|
|
4056
|
-
);
|
|
4077
|
+
app.get("/", requireViewer, async (context) => {
|
|
4078
|
+
const user = context.get("viewer");
|
|
4079
|
+
return jsonResponse(taskListSchema, await readViewerTasks(user));
|
|
4057
4080
|
});
|
|
4058
|
-
app.get("/runs", async (context) => {
|
|
4059
|
-
const user =
|
|
4060
|
-
return
|
|
4061
|
-
apiErrorSchema,
|
|
4062
|
-
{ error: "Authentication required." },
|
|
4063
|
-
{ status: 401 }
|
|
4064
|
-
);
|
|
4081
|
+
app.get("/runs", requireViewer, async (context) => {
|
|
4082
|
+
const user = context.get("viewer");
|
|
4083
|
+
return jsonResponse(taskRunListSchema, await readViewerTaskRuns(user));
|
|
4065
4084
|
});
|
|
4066
|
-
app.get(
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
}
|
|
4075
|
-
const params = taskParamsSchema.safeParse(context.req.param());
|
|
4076
|
-
if (!params.success) {
|
|
4077
|
-
return jsonResponse(
|
|
4078
|
-
apiErrorSchema,
|
|
4079
|
-
{ error: "Invalid task." },
|
|
4080
|
-
{ status: 400 }
|
|
4081
|
-
);
|
|
4082
|
-
}
|
|
4083
|
-
try {
|
|
4084
|
-
return jsonResponse(
|
|
4085
|
-
taskExecutionListSchema,
|
|
4086
|
-
await readViewerTaskExecutions(user, params.data.kind, params.data.id)
|
|
4087
|
-
);
|
|
4088
|
-
} catch (error) {
|
|
4089
|
-
if (error instanceof ViewerTaskNotFoundError) {
|
|
4085
|
+
app.get(
|
|
4086
|
+
"/:kind/:id/executions",
|
|
4087
|
+
requireViewer,
|
|
4088
|
+
validateRequest("param", taskParamsSchema, "Invalid task."),
|
|
4089
|
+
async (context) => {
|
|
4090
|
+
const user = context.get("viewer");
|
|
4091
|
+
const params = context.req.valid("param");
|
|
4092
|
+
try {
|
|
4090
4093
|
return jsonResponse(
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
{ status: 404 }
|
|
4094
|
+
taskExecutionListSchema,
|
|
4095
|
+
await readViewerTaskExecutions(user, params.kind, params.id)
|
|
4094
4096
|
);
|
|
4097
|
+
} catch (error) {
|
|
4098
|
+
if (error instanceof ViewerTaskNotFoundError) {
|
|
4099
|
+
return jsonResponse(
|
|
4100
|
+
apiErrorSchema,
|
|
4101
|
+
{ error: error.message },
|
|
4102
|
+
{ status: 404 }
|
|
4103
|
+
);
|
|
4104
|
+
}
|
|
4105
|
+
throw error;
|
|
4095
4106
|
}
|
|
4096
|
-
throw error;
|
|
4097
4107
|
}
|
|
4098
|
-
|
|
4099
|
-
app.delete(
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
return new Response(null, {
|
|
4119
|
-
headers: { "cache-control": "no-store" },
|
|
4120
|
-
status: 204
|
|
4121
|
-
});
|
|
4122
|
-
} catch (error) {
|
|
4123
|
-
if (error instanceof ViewerTaskNotFoundError) {
|
|
4124
|
-
return jsonResponse(
|
|
4125
|
-
apiErrorSchema,
|
|
4126
|
-
{ error: error.message },
|
|
4127
|
-
{ status: 404 }
|
|
4128
|
-
);
|
|
4108
|
+
);
|
|
4109
|
+
app.delete(
|
|
4110
|
+
"/:kind/:id",
|
|
4111
|
+
requireViewer,
|
|
4112
|
+
validateRequest("param", taskParamsSchema, "Invalid task."),
|
|
4113
|
+
async (context) => {
|
|
4114
|
+
const user = context.get("viewer");
|
|
4115
|
+
const params = context.req.valid("param");
|
|
4116
|
+
try {
|
|
4117
|
+
await deleteViewerTask(user, params.kind, params.id);
|
|
4118
|
+
return emptyResponse();
|
|
4119
|
+
} catch (error) {
|
|
4120
|
+
if (error instanceof ViewerTaskNotFoundError) {
|
|
4121
|
+
return jsonResponse(
|
|
4122
|
+
apiErrorSchema,
|
|
4123
|
+
{ error: error.message },
|
|
4124
|
+
{ status: 404 }
|
|
4125
|
+
);
|
|
4126
|
+
}
|
|
4127
|
+
throw error;
|
|
4129
4128
|
}
|
|
4130
|
-
throw error;
|
|
4131
4129
|
}
|
|
4132
|
-
|
|
4130
|
+
);
|
|
4133
4131
|
return app;
|
|
4134
4132
|
}
|
|
4135
4133
|
|
|
4136
|
-
// src/api/plugins.ts
|
|
4137
|
-
var plugins_default = defineApiRoute({
|
|
4138
|
-
method: "get",
|
|
4139
|
-
path: "/api/plugins",
|
|
4140
|
-
responseSchema: pluginsSchema,
|
|
4141
|
-
handler: readPlugins
|
|
4142
|
-
});
|
|
4143
|
-
|
|
4144
|
-
// src/api/runtime.ts
|
|
4145
|
-
var runtime_default = defineApiRoute({
|
|
4146
|
-
method: "get",
|
|
4147
|
-
path: "/api/runtime",
|
|
4148
|
-
responseSchema: runtimeInfoReportSchema,
|
|
4149
|
-
handler: readRuntimeInfoReport
|
|
4150
|
-
});
|
|
4151
|
-
|
|
4152
|
-
// src/api/skills.ts
|
|
4153
|
-
var skills_default = defineApiRoute({
|
|
4154
|
-
method: "get",
|
|
4155
|
-
path: "/api/skills",
|
|
4156
|
-
responseSchema: skillReportsSchema,
|
|
4157
|
-
handler: readSkillReports
|
|
4158
|
-
});
|
|
4159
|
-
|
|
4160
4134
|
// src/api/stats.ts
|
|
4161
4135
|
var WINDOW_DAYS2 = 90;
|
|
4162
4136
|
async function readStatsReport() {
|
|
@@ -4173,25 +4147,96 @@ async function readStatsReport() {
|
|
|
4173
4147
|
windowStart: start
|
|
4174
4148
|
});
|
|
4175
4149
|
}
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4150
|
+
|
|
4151
|
+
// src/reporting.ts
|
|
4152
|
+
import { readFileSync } from "fs";
|
|
4153
|
+
import path from "path";
|
|
4154
|
+
function readDescriptionText(home) {
|
|
4155
|
+
try {
|
|
4156
|
+
const raw = readFileSync(path.join(home, "DESCRIPTION.md"), "utf8").trim();
|
|
4157
|
+
return raw || void 0;
|
|
4158
|
+
} catch {
|
|
4159
|
+
return void 0;
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
async function readSkillReports() {
|
|
4163
|
+
const { discoverSkills } = await import("./skills-P7YUFSXM.js");
|
|
4164
|
+
const skills = await discoverSkills();
|
|
4165
|
+
return skillReportsSchema.parse(
|
|
4166
|
+
skills.map((skill) => ({
|
|
4167
|
+
name: skill.name,
|
|
4168
|
+
pluginProvider: skill.pluginProvider
|
|
4169
|
+
}))
|
|
4170
|
+
);
|
|
4171
|
+
}
|
|
4172
|
+
async function readPlugins() {
|
|
4173
|
+
const { pluginCatalogRuntime } = await import("./catalog-runtime-WADOZVTB.js");
|
|
4174
|
+
return pluginsSchema.parse(
|
|
4175
|
+
pluginCatalogRuntime.getProviders().map((plugin) => ({
|
|
4176
|
+
configKeys: plugin.manifest.configKeys ?? [],
|
|
4177
|
+
description: plugin.manifest.description,
|
|
4178
|
+
displayName: plugin.manifest.displayName,
|
|
4179
|
+
name: plugin.manifest.name
|
|
4180
|
+
}))
|
|
4181
|
+
);
|
|
4182
|
+
}
|
|
4183
|
+
async function readRuntimeInfoReport() {
|
|
4184
|
+
const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
|
|
4185
|
+
import("./discovery-GUFTFBTL.js"),
|
|
4186
|
+
import("./catalog-runtime-WADOZVTB.js"),
|
|
4187
|
+
readPlugins(),
|
|
4188
|
+
readSkillReports()
|
|
4189
|
+
]);
|
|
4190
|
+
const home = homeDir();
|
|
4191
|
+
return runtimeInfoReportSchema.parse({
|
|
4192
|
+
cwd: process.cwd(),
|
|
4193
|
+
homeDir: home,
|
|
4194
|
+
descriptionText: readDescriptionText(home),
|
|
4195
|
+
providers: plugins.map((plugin) => plugin.name),
|
|
4196
|
+
skills,
|
|
4197
|
+
packagedContent: pluginCatalogRuntime.getPackageContent()
|
|
4198
|
+
});
|
|
4199
|
+
}
|
|
4200
|
+
async function readPluginOperationalReportFeed() {
|
|
4201
|
+
const nowMs = Date.now();
|
|
4202
|
+
const { getPluginOperationalReports } = await import("./agent-hooks-VAUYT6PD.js");
|
|
4203
|
+
return pluginOperationalReportFeedSchema.parse({
|
|
4204
|
+
source: "plugins",
|
|
4205
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
4206
|
+
reports: await getPluginOperationalReports(nowMs)
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4182
4209
|
|
|
4183
4210
|
// src/api.ts
|
|
4184
|
-
var routes4 = [
|
|
4185
|
-
health_default,
|
|
4186
|
-
runtime_default,
|
|
4187
|
-
plugins_default,
|
|
4188
|
-
skills_default,
|
|
4189
|
-
plugin_reports_default,
|
|
4190
|
-
stats_default2
|
|
4191
|
-
];
|
|
4192
4211
|
function createJuniorApi() {
|
|
4193
4212
|
const app = new Hono7();
|
|
4194
|
-
|
|
4213
|
+
app.get(
|
|
4214
|
+
"/api/health",
|
|
4215
|
+
async () => jsonResponse(healthReportSchema, readHealthReport())
|
|
4216
|
+
);
|
|
4217
|
+
app.get(
|
|
4218
|
+
"/api/runtime",
|
|
4219
|
+
async () => jsonResponse(runtimeInfoReportSchema, await readRuntimeInfoReport())
|
|
4220
|
+
);
|
|
4221
|
+
app.get(
|
|
4222
|
+
"/api/plugins",
|
|
4223
|
+
async () => jsonResponse(pluginsSchema, await readPlugins())
|
|
4224
|
+
);
|
|
4225
|
+
app.get(
|
|
4226
|
+
"/api/skills",
|
|
4227
|
+
async () => jsonResponse(skillReportsSchema, await readSkillReports())
|
|
4228
|
+
);
|
|
4229
|
+
app.get(
|
|
4230
|
+
"/api/plugin-reports",
|
|
4231
|
+
async () => jsonResponse(
|
|
4232
|
+
pluginOperationalReportFeedSchema,
|
|
4233
|
+
await readPluginOperationalReportFeed()
|
|
4234
|
+
)
|
|
4235
|
+
);
|
|
4236
|
+
app.get(
|
|
4237
|
+
"/api/stats",
|
|
4238
|
+
async () => jsonResponse(statsReportSchema, await readStatsReport())
|
|
4239
|
+
);
|
|
4195
4240
|
app.route("/api/conversations", createConversationRoutes());
|
|
4196
4241
|
app.route("/api/personal-tokens", createPersonalTokenRoutes());
|
|
4197
4242
|
app.route("/api/people", createPeopleRoutes());
|
|
@@ -4207,10 +4252,27 @@ function createJuniorApi() {
|
|
|
4207
4252
|
}
|
|
4208
4253
|
)
|
|
4209
4254
|
);
|
|
4255
|
+
app.onError((error, _context) => {
|
|
4256
|
+
if (error instanceof HTTPException2) {
|
|
4257
|
+
if (error.res) return error.res;
|
|
4258
|
+
return jsonResponse(
|
|
4259
|
+
apiErrorSchema,
|
|
4260
|
+
{ error: error.message || "Request failed." },
|
|
4261
|
+
{ status: error.status }
|
|
4262
|
+
);
|
|
4263
|
+
}
|
|
4264
|
+
logException(error, "api.unhandled.exception");
|
|
4265
|
+
return jsonResponse(
|
|
4266
|
+
apiErrorSchema,
|
|
4267
|
+
{ error: "Internal Server Error" },
|
|
4268
|
+
{ status: 500 }
|
|
4269
|
+
);
|
|
4270
|
+
});
|
|
4210
4271
|
return app;
|
|
4211
4272
|
}
|
|
4212
4273
|
export {
|
|
4213
4274
|
authenticatePersonalToken,
|
|
4214
4275
|
createJuniorApi,
|
|
4215
|
-
jsonResponse
|
|
4276
|
+
jsonResponse,
|
|
4277
|
+
resolveViewerUser
|
|
4216
4278
|
};
|