@opengeni/api-router 0.16.5 → 0.17.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/app.js +1 -1
- package/dist/{chunk-FGNCK7HE.js → chunk-MWBF2GXL.js} +1849 -58
- package/dist/chunk-MWBF2GXL.js.map +1 -0
- package/dist/codex-realtime.d.ts +43 -0
- package/dist/gateway-realtime.d.ts +24 -0
- package/dist/index.js +1 -1
- package/dist/integrations/slack-bot.d.ts +122 -0
- package/dist/integrations/slack-interactions.d.ts +5 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/session-realtime-context.d.ts +19 -0
- package/package.json +12 -12
- package/src/codex-realtime.ts +367 -0
- package/src/gateway-realtime.ts +143 -0
- package/src/integrations/google-drive.ts +22 -12
- package/src/integrations/slack-bot.ts +536 -0
- package/src/integrations/slack-interactions.ts +467 -2
- package/src/routes/connections.ts +2 -2
- package/src/routes/sessions.ts +622 -11
- package/src/routes/workspaces.ts +56 -1
- package/src/session-realtime-context.ts +134 -0
- package/dist/chunk-FGNCK7HE.js.map +0 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Settings } from "@opengeni/config";
|
|
2
|
+
import type { CodexRealtimeWebrtcRequest, CodexRealtimeWebrtcResponse } from "@opengeni/contracts";
|
|
3
|
+
import { type CodexAuthHeaders, type CodexFetch, type CodexRealtimeInitialItem, type CodexRealtimeCallInput } from "@opengeni/codex";
|
|
4
|
+
import { type Database } from "@opengeni/db";
|
|
5
|
+
export type CodexRealtimeBrokerFailureReason = "subscription_disabled" | "credential_unavailable" | "reconnect_required" | "invalid_request" | "incompatible" | "entitlement_denied" | "rate_limited" | "provider_error" | "invalid_provider_response" | "network_error" | "timeout" | "cancelled";
|
|
6
|
+
export declare class CodexRealtimeBrokerError extends Error {
|
|
7
|
+
readonly reason: CodexRealtimeBrokerFailureReason;
|
|
8
|
+
readonly providerStatus: number | null;
|
|
9
|
+
constructor(reason: CodexRealtimeBrokerFailureReason, message: string, providerStatus?: number | null);
|
|
10
|
+
}
|
|
11
|
+
type CodexTokenResolver = {
|
|
12
|
+
getToken(): Promise<Omit<CodexAuthHeaders, "clientVersion">>;
|
|
13
|
+
refresh(): Promise<Omit<CodexAuthHeaders, "clientVersion">>;
|
|
14
|
+
};
|
|
15
|
+
export type CodexRealtimeBrokerDependencies = {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
loadSelection(): Promise<{
|
|
18
|
+
pinnedCredentialId: string | null;
|
|
19
|
+
activeCredentialId: string | null;
|
|
20
|
+
connectedCredentialIds: ReadonlySet<string>;
|
|
21
|
+
}>;
|
|
22
|
+
loadInitialItems(): Promise<CodexRealtimeInitialItem[]>;
|
|
23
|
+
tokenResolver(credentialId: string): CodexTokenResolver;
|
|
24
|
+
createCall(auth: CodexAuthHeaders, input: CodexRealtimeCallInput, options: {
|
|
25
|
+
signal?: AbortSignal | undefined;
|
|
26
|
+
}): Promise<CodexRealtimeProviderAnswer>;
|
|
27
|
+
};
|
|
28
|
+
export type CodexRealtimeProviderAnswer = Pick<CodexRealtimeWebrtcResponse, "sdp" | "version" | "model">;
|
|
29
|
+
export type CodexRealtimeBrokerInput = {
|
|
30
|
+
sessionId: string;
|
|
31
|
+
request: Pick<CodexRealtimeWebrtcRequest, "sdp" | "version" | "instructions" | "voice">;
|
|
32
|
+
signal?: AbortSignal | undefined;
|
|
33
|
+
};
|
|
34
|
+
export declare const OPENGENI_REALTIME_BASE_INSTRUCTIONS = "## Identity, tone, and role\n\nYou are the realtime conversational interface for the current session.\n\nBe concise, clear, and efficient. Keep responses tight and useful, with no fluff. Talk naturally like a trusted collaborator: warm, supportive, and easy to follow.\n\n## Interface and operating model\n\nThe backend handles execution and produces durable output and artifacts. You are the conversational surface of the same system.\n\nTreat the system as one unified assistant. Do not mention the backend, delegation, or that the system is composed of separate parts. Present execution work and results as work done by you.\n\nPass execution work to the backend. Do not block, filter, or withhold an execution request that should instead be passed through. Never refuse an execution request at the conversational layer: the backend makes the final judgment about feasibility, safety, permissions, approvals, and available tools.\n\nTreat backend outputs as authoritative. Do not override, contradict, embellish, or invent them.\n\nUse conversation to support execution: clarify briefly when necessary, acknowledge meaningful progress, answer succinctly, and make the next step clear. Do not use conversation as a substitute for execution or artifact generation.\n\n## Session context\n\nThe initial conversation items are authoritative context from the current session. Respect their roles and instruction hierarchy, use them for continuity, and continue naturally. Do not announce, summarize, or read the context aloud merely because it was added.\n\nLive context wrapped in <session_user_message> is an authoritative user message already routed to the current session. A status of queued_for_execution means it is waiting behind existing work; accepted_for_execution means it is next with no existing work ahead; accepted_for_steering means it was given priority as a change of direction, while any prior work may still be yielding. Incorporate it immediately as conversation context, but never delegate it again or treat the wrapper metadata as user-authored text.\n\nLive session updates may describe work that started before this realtime conversation, work sent directly by the user, or work delegated during an earlier realtime connection. Treat those updates as part of this same session even when they have no current delegation identity.\n\n## Backend use\n\nFor actions or tasks, always use the backend. If it is unclear whether backend use would help, use it.\n\nRespond directly only when the request is clearly self-contained and backend use would not meaningfully help.\n\nDo not claim that you cannot perform an action or lack access to tools, session state, workspace state, files, code, terminals, deployments, connected services, or other execution capabilities. Pass the request to the backend and let it determine what is available.\n\nAsk a clarifying question only when needed to avoid a materially harmful mistake or when essential information cannot reasonably be inferred. Otherwise, make a reasonable assumption and use the backend.\n\nGive the backend a complete standalone task containing the user's requested outcome, constraints, and all relevant context already established in the conversation. Do not make the user repeat information you already have.\n\nCreate only one delegation for one execution request. Do not submit duplicates while waiting. If the user supplies corrections, constraints, or updated context while work is running, immediately pass the update to the backend and identify the affected work.\n\n## Progress and completion\n\nBackend messages may be intermediate progress or final output. A completion result or error indicates that the delegated work has finished.\n\nDo not claim success, completion, or a changed state until authoritative backend output confirms it. If execution fails, explain the failure briefly and give the clearest supported next step without exposing raw internal errors.\n\nUse at most one short spoken acknowledgement before work that may take noticeable time. After that, speak only when a progress update is genuinely useful or the user explicitly asks for frequent updates. Do not fill waiting time with repeated reassurance.\n\n## Presenting results\n\nTreat backend output and artifacts as the authoritative execution record. Briefly tell the user the key takeaway, status, or next step without unnecessarily repeating detailed content unless asked.\n\nDo not read out or recreate tables, diffs, plots, code blocks, structured data, or other heavily formatted content by default. Present detailed backend content only when the user explicitly asks. If the user wants substantial output reformatted, transformed, or presented differently, use the backend.\n\n## Task-level user preferences\n\nTreat instructions about update frequency, verbosity, pacing, detail level, and presentation style as active task-level preferences. Continue following them until the task completes or the user changes them.\n\n## Voice behavior\n\nKeep direct answers to one or two short sentences by default. Ask one clarification question at a time. Give tool or execution results as the outcome first, followed only by the next useful action.\n\nOnly act on audio you understand with sufficient confidence. If speech is unclear, incomplete, ambiguous, or likely background conversation, ask for a brief clarification instead of guessing, reasoning from missing words, or using the backend.\n\n## Communication style\n\nWhen the user makes a clear request, proceed directly. Do not paraphrase the request, announce a plan, or add unnecessary framing.\n\nAvoid repetitive confirmation, filler, re-acknowledgement, and obvious play-by-play. By default, share progress only when it is brief, grounded, and genuinely useful.";
|
|
35
|
+
export declare function openGeniRealtimeInstructions(additional?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Credential-bound server broker. Selection is identical to a turn (pin then
|
|
38
|
+
* workspace active), and only a provider 401 permits one forced refresh/retry.
|
|
39
|
+
*/
|
|
40
|
+
export declare function brokerSessionCodexRealtime(deps: CodexRealtimeBrokerDependencies, input: CodexRealtimeBrokerInput): Promise<CodexRealtimeProviderAnswer>;
|
|
41
|
+
/** Bind the pure broker to OpenGeni's encrypted DB credential lifecycle. */
|
|
42
|
+
export declare function buildSessionCodexRealtimeBroker(db: Database, settings: Settings, workspaceId: string, sessionId: string, fetchImpl?: CodexFetch): (input: Omit<CodexRealtimeBrokerInput, "sessionId">) => Promise<CodexRealtimeProviderAnswer>;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Settings } from "@opengeni/config";
|
|
2
|
+
import type { GatewayRealtimeInitialItem, SessionRealtimeModel } from "@opengeni/contracts";
|
|
3
|
+
import { type Database } from "@opengeni/db";
|
|
4
|
+
export declare class GatewayRealtimeBrokerError extends Error {
|
|
5
|
+
readonly code: "model_unavailable" | "credential_unavailable" | "provider_error" | "invalid_provider_response";
|
|
6
|
+
readonly providerStatus: number | null;
|
|
7
|
+
constructor(code: "model_unavailable" | "credential_unavailable" | "provider_error" | "invalid_provider_response", message: string, providerStatus?: number | null);
|
|
8
|
+
}
|
|
9
|
+
export type GatewayRealtimeConnectionSecret = {
|
|
10
|
+
token: string;
|
|
11
|
+
url: string;
|
|
12
|
+
upstreamModelId: string;
|
|
13
|
+
expiresAt: number | null;
|
|
14
|
+
initialItems: GatewayRealtimeInitialItem[];
|
|
15
|
+
instructions: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function createGatewayRealtimeConnectionSecret(input: {
|
|
18
|
+
db: Database;
|
|
19
|
+
settings: Settings;
|
|
20
|
+
workspaceId: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
model: SessionRealtimeModel;
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
}): Promise<GatewayRealtimeConnectionSecret>;
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { OPENGENI_SLACK_BOT_CREDENTIAL_LABEL, OPENGENI_SLACK_BOT_CREDENTIAL_ROLE
|
|
|
3
3
|
import { type Database } from "@opengeni/db";
|
|
4
4
|
import { type FetchLike } from "@opengeni/network";
|
|
5
5
|
import { HTTPException } from "hono/http-exception";
|
|
6
|
+
declare const SLACK_REACTION_CONTEXT_CHECKPOINT_VERSION = 1;
|
|
6
7
|
type SlackPayload = Record<string, unknown> & {
|
|
7
8
|
ok?: unknown;
|
|
8
9
|
error?: unknown;
|
|
@@ -42,6 +43,44 @@ type SlackBotContext = {
|
|
|
42
43
|
sessionId?: string | null;
|
|
43
44
|
scheduledTaskId?: string | null;
|
|
44
45
|
};
|
|
46
|
+
export type SlackReactionContextCheckpointBinding = {
|
|
47
|
+
inboxId: string;
|
|
48
|
+
accountId: string;
|
|
49
|
+
workspaceId: string;
|
|
50
|
+
connectionId: string;
|
|
51
|
+
providerEventId: string;
|
|
52
|
+
providerMessageId: string;
|
|
53
|
+
slackTeamId: string;
|
|
54
|
+
slackChannelId: string;
|
|
55
|
+
slackMessageTs: string;
|
|
56
|
+
};
|
|
57
|
+
type SlackReactionCheckpointMessage = {
|
|
58
|
+
timestamp: string;
|
|
59
|
+
userId: string;
|
|
60
|
+
botId: string;
|
|
61
|
+
threadTimestamp: string;
|
|
62
|
+
text: string;
|
|
63
|
+
files: Array<{
|
|
64
|
+
id: string;
|
|
65
|
+
label: string;
|
|
66
|
+
}>;
|
|
67
|
+
};
|
|
68
|
+
type SlackReactionContextCheckpointUnsigned = {
|
|
69
|
+
version: typeof SLACK_REACTION_CONTEXT_CHECKPOINT_VERSION;
|
|
70
|
+
binding: SlackReactionContextCheckpointBinding;
|
|
71
|
+
state: {
|
|
72
|
+
createdAtMs: number;
|
|
73
|
+
pageCount: number;
|
|
74
|
+
nextCursor: string;
|
|
75
|
+
seenCursors: string[];
|
|
76
|
+
seenMessageTimestamps: string[];
|
|
77
|
+
threadTimestamp: string | null;
|
|
78
|
+
messages: SlackReactionCheckpointMessage[];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export type SlackReactionContextCheckpoint = SlackReactionContextCheckpointUnsigned & {
|
|
82
|
+
signature: string;
|
|
83
|
+
};
|
|
45
84
|
export declare class SlackBotProviderError extends Error {
|
|
46
85
|
readonly code: string;
|
|
47
86
|
readonly retryAfterMs: number | null;
|
|
@@ -89,6 +128,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
89
128
|
isMember: boolean;
|
|
90
129
|
isDirectMessage: boolean;
|
|
91
130
|
isArchived: boolean;
|
|
131
|
+
isShared: boolean;
|
|
132
|
+
isExternallyShared: boolean;
|
|
133
|
+
isOrgShared: boolean;
|
|
92
134
|
topic: string;
|
|
93
135
|
purpose: string;
|
|
94
136
|
numMembers: number | null;
|
|
@@ -104,6 +146,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
104
146
|
isMember: boolean;
|
|
105
147
|
isDirectMessage: boolean;
|
|
106
148
|
isArchived: boolean;
|
|
149
|
+
isShared: boolean;
|
|
150
|
+
isExternallyShared: boolean;
|
|
151
|
+
isOrgShared: boolean;
|
|
107
152
|
topic: string;
|
|
108
153
|
purpose: string;
|
|
109
154
|
numMembers: number | null;
|
|
@@ -120,6 +165,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
120
165
|
isMember: boolean;
|
|
121
166
|
isDirectMessage: boolean;
|
|
122
167
|
isArchived: boolean;
|
|
168
|
+
isShared: boolean;
|
|
169
|
+
isExternallyShared: boolean;
|
|
170
|
+
isOrgShared: boolean;
|
|
123
171
|
topic: string;
|
|
124
172
|
purpose: string;
|
|
125
173
|
numMembers: number | null;
|
|
@@ -159,6 +207,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
159
207
|
isMember: boolean;
|
|
160
208
|
isDirectMessage: boolean;
|
|
161
209
|
isArchived: boolean;
|
|
210
|
+
isShared: boolean;
|
|
211
|
+
isExternallyShared: boolean;
|
|
212
|
+
isOrgShared: boolean;
|
|
162
213
|
topic: string;
|
|
163
214
|
purpose: string;
|
|
164
215
|
numMembers: number | null;
|
|
@@ -186,6 +237,68 @@ export declare class OpenGeniSlackBotClient {
|
|
|
186
237
|
} & {
|
|
187
238
|
receipt: SlackBotReceipt;
|
|
188
239
|
}>;
|
|
240
|
+
reactionMessageContext(input: {
|
|
241
|
+
channelId: string;
|
|
242
|
+
messageTimestamp: string;
|
|
243
|
+
checkpoint: unknown | null;
|
|
244
|
+
checkpointBinding: SlackReactionContextCheckpointBinding;
|
|
245
|
+
saveCheckpoint: (checkpoint: SlackReactionContextCheckpoint) => Promise<void>;
|
|
246
|
+
}): Promise<{
|
|
247
|
+
channel: {
|
|
248
|
+
id: string;
|
|
249
|
+
name: string;
|
|
250
|
+
isPrivate: boolean;
|
|
251
|
+
isMember: boolean;
|
|
252
|
+
isDirectMessage: boolean;
|
|
253
|
+
isArchived: boolean;
|
|
254
|
+
isShared: boolean;
|
|
255
|
+
isExternallyShared: boolean;
|
|
256
|
+
isOrgShared: boolean;
|
|
257
|
+
topic: string;
|
|
258
|
+
purpose: string;
|
|
259
|
+
numMembers: number | null;
|
|
260
|
+
};
|
|
261
|
+
threadTimestamp: string;
|
|
262
|
+
reactedMessage: {
|
|
263
|
+
timestamp: string;
|
|
264
|
+
userId: string;
|
|
265
|
+
botId: string;
|
|
266
|
+
threadTimestamp: string;
|
|
267
|
+
text: string;
|
|
268
|
+
files: {
|
|
269
|
+
id: string;
|
|
270
|
+
name: string;
|
|
271
|
+
title: string;
|
|
272
|
+
mimetype: string;
|
|
273
|
+
filetype: string;
|
|
274
|
+
mode: string;
|
|
275
|
+
size: number | null;
|
|
276
|
+
originatingHuddleId: string;
|
|
277
|
+
huddleTranscriptFileId: string;
|
|
278
|
+
}[];
|
|
279
|
+
};
|
|
280
|
+
messages: {
|
|
281
|
+
timestamp: string;
|
|
282
|
+
userId: string;
|
|
283
|
+
botId: string;
|
|
284
|
+
threadTimestamp: string;
|
|
285
|
+
text: string;
|
|
286
|
+
files: {
|
|
287
|
+
id: string;
|
|
288
|
+
name: string;
|
|
289
|
+
title: string;
|
|
290
|
+
mimetype: string;
|
|
291
|
+
filetype: string;
|
|
292
|
+
mode: string;
|
|
293
|
+
size: number | null;
|
|
294
|
+
originatingHuddleId: string;
|
|
295
|
+
huddleTranscriptFileId: string;
|
|
296
|
+
}[];
|
|
297
|
+
}[];
|
|
298
|
+
truncated: boolean;
|
|
299
|
+
} & {
|
|
300
|
+
receipt: SlackBotReceipt;
|
|
301
|
+
}>;
|
|
189
302
|
listUsers(input?: {
|
|
190
303
|
limit?: number;
|
|
191
304
|
cursor?: string;
|
|
@@ -214,6 +327,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
214
327
|
isMember: boolean;
|
|
215
328
|
isDirectMessage: boolean;
|
|
216
329
|
isArchived: boolean;
|
|
330
|
+
isShared: boolean;
|
|
331
|
+
isExternallyShared: boolean;
|
|
332
|
+
isOrgShared: boolean;
|
|
217
333
|
topic: string;
|
|
218
334
|
purpose: string;
|
|
219
335
|
numMembers: number | null;
|
|
@@ -245,6 +361,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
245
361
|
isMember: boolean;
|
|
246
362
|
isDirectMessage: boolean;
|
|
247
363
|
isArchived: boolean;
|
|
364
|
+
isShared: boolean;
|
|
365
|
+
isExternallyShared: boolean;
|
|
366
|
+
isOrgShared: boolean;
|
|
248
367
|
topic: string;
|
|
249
368
|
purpose: string;
|
|
250
369
|
numMembers: number | null;
|
|
@@ -276,6 +395,9 @@ export declare class OpenGeniSlackBotClient {
|
|
|
276
395
|
isMember: boolean;
|
|
277
396
|
isDirectMessage: boolean;
|
|
278
397
|
isArchived: boolean;
|
|
398
|
+
isShared: boolean;
|
|
399
|
+
isExternallyShared: boolean;
|
|
400
|
+
isOrgShared: boolean;
|
|
279
401
|
topic: string;
|
|
280
402
|
purpose: string;
|
|
281
403
|
numMembers: number | null;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { type WorkspaceSlackReactionSummonSettings } from "@opengeni/contracts";
|
|
1
2
|
import { type SlackInstallationRoute, type SlackInteractionInboxEntry, type SlackInteractionTriggerKind } from "@opengeni/db";
|
|
2
3
|
import { type ApiRouteDeps } from "@opengeni/core";
|
|
3
4
|
import type { Hono } from "hono";
|
|
5
|
+
import { type OpenGeniSlackBotClient } from "./slack-bot";
|
|
4
6
|
export declare const SLACK_INTERACTION_MAX_BODY_BYTES: number;
|
|
5
7
|
export declare const SLACK_SIGNATURE_REPLAY_WINDOW_SECONDS = 300;
|
|
6
8
|
export declare const SLACK_DELIVERY_EVENT_TYPES: readonly ["agent.message.completed", "session.humanInput.requested", "turn.completed", "turn.failed", "turn.cancelled", "session.status.changed"];
|
|
@@ -29,12 +31,15 @@ export declare function verifySlackRequestSignature(input: {
|
|
|
29
31
|
rawBody: string;
|
|
30
32
|
}, signingSecret: string, nowMs?: number): boolean;
|
|
31
33
|
export declare function slackEventInboxEntry(payload: unknown, bot: Pick<SlackInstallationRoute, "botId" | "botUserId">): NormalizedSlackInteraction | null;
|
|
34
|
+
export declare function slackReactionInboxEntry(payload: unknown, bot: Pick<SlackInstallationRoute, "botUserId">, settings: WorkspaceSlackReactionSummonSettings): NormalizedSlackInteraction | null;
|
|
32
35
|
export declare function registerSlackInteractionRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
33
36
|
export declare function drainSlackInteractionsOnce(deps: ApiRouteDeps): Promise<boolean>;
|
|
34
37
|
export declare function startSlackInteractionPump(deps: ApiRouteDeps, options?: {
|
|
35
38
|
intervalMs?: number;
|
|
36
39
|
maxPerTick?: number;
|
|
37
40
|
}): () => void;
|
|
41
|
+
type SlackReactionMessageContext = Awaited<ReturnType<OpenGeniSlackBotClient["reactionMessageContext"]>>;
|
|
42
|
+
export declare function slackReactionTaskText(context: SlackReactionMessageContext): string;
|
|
38
43
|
type SlackUserLinkToken = {
|
|
39
44
|
workspaceId: string;
|
|
40
45
|
connectionId: string;
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export declare function capSessionDiscoveryPage(page: Awaited<ReturnType<typeof
|
|
|
70
70
|
truncated: boolean;
|
|
71
71
|
};
|
|
72
72
|
latestMessage?: {
|
|
73
|
-
type: "agent.message.completed" | "agent.message.delta" | "agent.model.request" | "agent.model.usage" | "agent.reasoning.delta" | "agent.toolCall.created" | "agent.toolCall.output" | "agent.updated" | "artifact.created" | "codex.account.switched" | "codex.capacity.resumed" | "codex.capacity.superseded" | "codex.capacity.waiting" | "codex.credential.selected" | "codex.fleet.decision" | "credential.auth_needed" | "fs.changed" | "git.changed" | "goal.cleared" | "goal.completed" | "goal.continuation" | "goal.paused" | "goal.resumed" | "goal.set" | "goal.updated" | "machine.link.lost" | "machine.link.restored" | "machine.op.failed" | "machine.op.recovered" | "machine.runner.restarted" | "memory.corrected" | "memory.saved" | "recording.available" | "recording.failed" | "recording.started" | "rig.setup.completed" | "rig.setup.failed" | "rig.setup.skipped" | "rig.setup.started" | "sandbox.box.created" | "sandbox.box.lost" | "sandbox.box.snapshot" | "sandbox.box.terminated" | "sandbox.command.output.delta" | "sandbox.env.drift" | "sandbox.operation.completed" | "sandbox.operation.failed" | "sandbox.operation.started" | "session.context.cleared" | "session.context.compacted" | "session.context.compaction.requested" | "session.context.compaction.skipped" | "session.context.compaction.started" | "session.control.paused" | "session.control.resumed" | "session.control.steer_requested" | "session.created" | "session.event.envelope_omitted" | "session.humanInput.requested" | "session.mcp.approval_policy.updated" | "session.queue.changed" | "session.queue.history" | "session.queue.prompt.cancelled" | "session.requiresAction" | "session.route.reconciled" | "session.status.changed" | "session.title_set" | "session.tool_policy.updated" | "stream.closed" | "stream.opened" | "stream.revoked" | "stream.url.rotated" | "system.update.cancelled" | "system.update.delivered" | "system.update.pending" | "system.update.settled" | "system.update.superseded" | "terminal.pty.exited" | "terminal.pty.output.delta" | "terminal.pty.started" | "tool.auth_needed" | "turn.cancelled" | "turn.capacity_waiting" | "turn.completed" | "turn.event.rejected_late" | "turn.failed" | "turn.queued" | "turn.recovery.requested" | "turn.started" | "turn.superseded" | "user.approvalDecision" | "user.humanInputResponse" | "user.message" | "user.pause" | "workspace.inference.paused" | "workspace.inference.resumed" | "workspace.revision.captured" | "workspace.revision.degraded";
|
|
73
|
+
type: "agent.message.completed" | "agent.message.delta" | "agent.model.request" | "agent.model.usage" | "agent.reasoning.delta" | "agent.toolCall.created" | "agent.toolCall.output" | "agent.updated" | "artifact.created" | "codex.account.switched" | "codex.capacity.resumed" | "codex.capacity.superseded" | "codex.capacity.waiting" | "codex.credential.selected" | "codex.fleet.decision" | "credential.auth_needed" | "fs.changed" | "git.changed" | "goal.cleared" | "goal.completed" | "goal.continuation" | "goal.paused" | "goal.resumed" | "goal.set" | "goal.updated" | "machine.link.lost" | "machine.link.restored" | "machine.op.failed" | "machine.op.recovered" | "machine.runner.restarted" | "memory.corrected" | "memory.saved" | "recording.available" | "recording.failed" | "recording.started" | "rig.setup.completed" | "rig.setup.failed" | "rig.setup.skipped" | "rig.setup.started" | "sandbox.box.created" | "sandbox.box.lost" | "sandbox.box.snapshot" | "sandbox.box.terminated" | "sandbox.command.output.delta" | "sandbox.env.drift" | "sandbox.operation.completed" | "sandbox.operation.failed" | "sandbox.operation.started" | "session.context.cleared" | "session.context.compacted" | "session.context.compaction.requested" | "session.context.compaction.skipped" | "session.context.compaction.started" | "session.control.paused" | "session.control.resumed" | "session.control.steer_requested" | "session.created" | "session.event.envelope_omitted" | "session.humanInput.requested" | "session.mcp.approval_policy.updated" | "session.queue.changed" | "session.queue.history" | "session.queue.prompt.cancelled" | "session.realtime.ended" | "session.realtime.started" | "session.requiresAction" | "session.route.reconciled" | "session.status.changed" | "session.title_set" | "session.tool_policy.updated" | "stream.closed" | "stream.opened" | "stream.revoked" | "stream.url.rotated" | "system.update.cancelled" | "system.update.delivered" | "system.update.pending" | "system.update.settled" | "system.update.superseded" | "terminal.pty.exited" | "terminal.pty.output.delta" | "terminal.pty.started" | "tool.auth_needed" | "turn.cancelled" | "turn.capacity_waiting" | "turn.completed" | "turn.event.rejected_late" | "turn.failed" | "turn.queued" | "turn.recovery.requested" | "turn.started" | "turn.superseded" | "user.approvalDecision" | "user.humanInputResponse" | "user.message" | "user.pause" | "workspace.inference.paused" | "workspace.inference.resumed" | "workspace.revision.captured" | "workspace.revision.degraded";
|
|
74
74
|
preview: string | null;
|
|
75
75
|
previewTruncated: boolean;
|
|
76
76
|
} | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CodexRealtimeInitialItem } from "@opengeni/codex";
|
|
2
|
+
export type SessionRealtimeHistoryRow = {
|
|
3
|
+
position: number;
|
|
4
|
+
item: Record<string, unknown>;
|
|
5
|
+
};
|
|
6
|
+
export type SessionRealtimeContinuityEntry = {
|
|
7
|
+
role: "user" | "assistant";
|
|
8
|
+
text: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Project ordinary model-facing conversation truth into Frameless V3 startup
|
|
12
|
+
* items. Only complete role-bearing messages are legal V3 initial items;
|
|
13
|
+
* reasoning, tool protocol records, images, and raw provider metadata are never
|
|
14
|
+
* copied into the browser-owned call bootstrap.
|
|
15
|
+
*
|
|
16
|
+
* The newest complete tail wins deterministically. This mirrors Codex's exact
|
|
17
|
+
* byte/4 token estimate and hard 128-item/8,192-token limits.
|
|
18
|
+
*/
|
|
19
|
+
export declare function projectSessionRealtimeInitialItems(rows: readonly SessionRealtimeHistoryRow[], continuityEntries?: readonly SessionRealtimeContinuityEntry[]): CodexRealtimeInitialItem[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/api-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "OpenGeni HTTP surface: the Hono adapter/router (createApp), routes, MCP HTTP transport, and HTTP access adapters over @opengeni/core. An engine-distribution surface — its runtime closure includes engine-internal packages.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -43,18 +43,18 @@
|
|
|
43
43
|
"@hono/zod-validator": "^0.7.6",
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
45
45
|
"@opengeni/agent-proto": "^0.3.0",
|
|
46
|
-
"@opengeni/codex": "^0.2.
|
|
47
|
-
"@opengeni/config": "^0.10.
|
|
48
|
-
"@opengeni/contracts": "^0.
|
|
49
|
-
"@opengeni/core": "^0.
|
|
50
|
-
"@opengeni/db": "^0.
|
|
51
|
-
"@opengeni/documents": "^0.2.
|
|
52
|
-
"@opengeni/events": "^0.3.
|
|
53
|
-
"@opengeni/github": "^0.4.
|
|
46
|
+
"@opengeni/codex": "^0.2.10",
|
|
47
|
+
"@opengeni/config": "^0.10.3",
|
|
48
|
+
"@opengeni/contracts": "^0.32.0",
|
|
49
|
+
"@opengeni/core": "^0.19.0",
|
|
50
|
+
"@opengeni/db": "^0.23.0",
|
|
51
|
+
"@opengeni/documents": "^0.2.72",
|
|
52
|
+
"@opengeni/events": "^0.3.62",
|
|
53
|
+
"@opengeni/github": "^0.4.19",
|
|
54
54
|
"@opengeni/network": "^0.1.1",
|
|
55
|
-
"@opengeni/observability": "^0.4.
|
|
56
|
-
"@opengeni/runtime": "^0.
|
|
57
|
-
"@opengeni/storage": "^0.2.
|
|
55
|
+
"@opengeni/observability": "^0.4.6",
|
|
56
|
+
"@opengeni/runtime": "^0.18.0",
|
|
57
|
+
"@opengeni/storage": "^0.2.56",
|
|
58
58
|
"@temporalio/client": "^1.17.0",
|
|
59
59
|
"better-auth": "^1.6.14",
|
|
60
60
|
"hono": "^4.12.18",
|