@opengeni/api-router 0.21.14 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +1 -0
- package/dist/app.js +1 -1
- package/dist/{chunk-R5PDSH2A.js → chunk-HWXJW5C7.js} +1034 -75
- package/dist/chunk-HWXJW5C7.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/routes/transcription-recordings.d.ts +3 -0
- package/dist/transcription/segmenter.d.ts +10 -0
- package/dist/transcription/service.d.ts +5 -0
- package/package.json +11 -11
- package/src/app.ts +36 -2
- package/src/mcp/server.ts +1 -1
- package/src/routes/transcription-recordings.ts +722 -0
- package/src/routes/transcriptions.ts +2 -0
- package/src/transcription/providers/azure-openai.ts +4 -3
- package/src/transcription/providers/codex-subscription.ts +4 -1
- package/src/transcription/providers/openai.ts +7 -2
- package/src/transcription/segmenter.ts +260 -0
- package/src/transcription/service.ts +111 -10
- package/dist/chunk-R5PDSH2A.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TranscriptionSegmenter } from "@opengeni/core";
|
|
2
|
+
export declare class TranscriptionSegmenterError extends Error {
|
|
3
|
+
readonly code: "unavailable" | "invalid_audio" | "cancelled" | "too_large" | "unknown";
|
|
4
|
+
readonly retryable: boolean;
|
|
5
|
+
readonly name = "TranscriptionSegmenterError";
|
|
6
|
+
constructor(message: string, code: "unavailable" | "invalid_audio" | "cancelled" | "too_large" | "unknown", retryable: boolean);
|
|
7
|
+
}
|
|
8
|
+
export declare function createFfmpegTranscriptionSegmenter(input: {
|
|
9
|
+
ffmpegPath: string;
|
|
10
|
+
}): TranscriptionSegmenter;
|
|
@@ -7,4 +7,9 @@ export declare function createTranscriptionService(input: {
|
|
|
7
7
|
fetch?: typeof fetch;
|
|
8
8
|
codexFetch?: typeof fetch;
|
|
9
9
|
probeCodex?: (context?: TranscriptionAvailabilityContext) => boolean | Promise<boolean>;
|
|
10
|
+
/** Test seam for exercising timeout and late-completion behavior quickly. */
|
|
11
|
+
providerRequestTimeoutMilliseconds?: number;
|
|
12
|
+
/** Test seam for evaluating persisted absolute deadlines after delayed setup. */
|
|
13
|
+
now?: () => Date;
|
|
10
14
|
}): TranscriptionService;
|
|
15
|
+
export declare function remainingTranscriptionProviderRequestMilliseconds(providerDeadlineAt: Date, now: Date): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/api-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.2",
|
|
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": {
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
45
45
|
"@opengeni/agent-proto": "^0.3.0",
|
|
46
46
|
"@opengeni/codex": "^0.2.11",
|
|
47
|
-
"@opengeni/config": "^0.
|
|
48
|
-
"@opengeni/contracts": "^0.
|
|
49
|
-
"@opengeni/core": "^0.
|
|
50
|
-
"@opengeni/db": "^0.
|
|
51
|
-
"@opengeni/documents": "^0.5.
|
|
52
|
-
"@opengeni/events": "^0.3.
|
|
53
|
-
"@opengeni/github": "^0.4.
|
|
47
|
+
"@opengeni/config": "^0.11.0",
|
|
48
|
+
"@opengeni/contracts": "^0.39.0",
|
|
49
|
+
"@opengeni/core": "^0.21.2",
|
|
50
|
+
"@opengeni/db": "^0.28.1",
|
|
51
|
+
"@opengeni/documents": "^0.5.10",
|
|
52
|
+
"@opengeni/events": "^0.3.80",
|
|
53
|
+
"@opengeni/github": "^0.4.31",
|
|
54
54
|
"@opengeni/network": "^0.2.0",
|
|
55
|
-
"@opengeni/observability": "^0.
|
|
56
|
-
"@opengeni/runtime": "^0.18.
|
|
57
|
-
"@opengeni/storage": "^0.2.
|
|
55
|
+
"@opengeni/observability": "^0.5.0",
|
|
56
|
+
"@opengeni/runtime": "^0.18.17",
|
|
57
|
+
"@opengeni/storage": "^0.2.68",
|
|
58
58
|
"@temporalio/client": "^1.17.0",
|
|
59
59
|
"better-auth": "^1.6.14",
|
|
60
60
|
"hono": "^4.12.18",
|
package/src/app.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
OPENGENI_CORRELATION_HEADER,
|
|
14
14
|
resolveWorkspaceMemoryEnabled,
|
|
15
15
|
VOICE_INPUT_ACCEPTED_MIME_TYPES,
|
|
16
|
+
TRANSCRIPTION_RECORDING_PROVIDER_SEGMENT_SECONDS,
|
|
16
17
|
type AccessGrant,
|
|
17
18
|
type ErrorCode,
|
|
18
19
|
} from "@opengeni/contracts";
|
|
@@ -77,6 +78,7 @@ import { registerInsightsRoutes } from "./routes/insights";
|
|
|
77
78
|
import { registerTranscriptionRoutes } from "./routes/transcriptions";
|
|
78
79
|
import { projectClientModel } from "./model-catalog";
|
|
79
80
|
import { createTranscriptionService } from "./transcription/service";
|
|
81
|
+
import { createFfmpegTranscriptionSegmenter } from "./transcription/segmenter";
|
|
80
82
|
import { registerSlackInteractionRoutes } from "./integrations/slack-interactions";
|
|
81
83
|
|
|
82
84
|
export type {
|
|
@@ -103,8 +105,15 @@ export { replaySessionEvents, sseSessionStream, sseWorkspaceControlStream } from
|
|
|
103
105
|
export const API_MAX_REQUEST_BODY_BYTES = 8 * 1024 * 1024;
|
|
104
106
|
|
|
105
107
|
/** Effective Hono bodyLimit — API JSON ceiling or voice multipart + multipart overhead. */
|
|
106
|
-
export function apiRequestBodyLimitBytes(settings: {
|
|
107
|
-
|
|
108
|
+
export function apiRequestBodyLimitBytes(settings: {
|
|
109
|
+
voiceInputMaxSizeBytes: number;
|
|
110
|
+
voiceInputResumableMaxChunkSizeBytes?: number;
|
|
111
|
+
}): number {
|
|
112
|
+
return Math.max(
|
|
113
|
+
API_MAX_REQUEST_BODY_BYTES,
|
|
114
|
+
settings.voiceInputMaxSizeBytes + 64 * 1024,
|
|
115
|
+
(settings.voiceInputResumableMaxChunkSizeBytes ?? 0) + 64 * 1024,
|
|
116
|
+
);
|
|
108
117
|
}
|
|
109
118
|
const API_PUBLIC_ERROR_MESSAGE_MAX_BYTES = 512;
|
|
110
119
|
|
|
@@ -204,6 +213,12 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
204
213
|
...(deps.codexFetch ? { codexFetch: deps.codexFetch } : {}),
|
|
205
214
|
})
|
|
206
215
|
: deps.transcription;
|
|
216
|
+
const transcriptionSegmenter =
|
|
217
|
+
deps.transcriptionSegmenter === undefined
|
|
218
|
+
? createFfmpegTranscriptionSegmenter({
|
|
219
|
+
ffmpegPath: deps.settings.voiceInputFfmpegPath,
|
|
220
|
+
})
|
|
221
|
+
: deps.transcriptionSegmenter;
|
|
207
222
|
const routeDeps: ApiRouteDeps = {
|
|
208
223
|
...deps,
|
|
209
224
|
observability,
|
|
@@ -214,6 +229,7 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
214
229
|
documentIndexer,
|
|
215
230
|
getDocumentServices,
|
|
216
231
|
transcription,
|
|
232
|
+
transcriptionSegmenter,
|
|
217
233
|
...(sandboxClient ? { sandboxClient } : {}),
|
|
218
234
|
resumeBoxById,
|
|
219
235
|
};
|
|
@@ -440,6 +456,24 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
440
456
|
maxDurationSeconds: deps.settings.voiceInputMaxDurationSeconds,
|
|
441
457
|
maxSizeBytes: deps.settings.voiceInputMaxSizeBytes,
|
|
442
458
|
acceptedMimeTypes: [...VOICE_INPUT_ACCEPTED_MIME_TYPES],
|
|
459
|
+
...(deps.settings.voiceInputResumableEnabled &&
|
|
460
|
+
objectStorage &&
|
|
461
|
+
transcription &&
|
|
462
|
+
transcriptionSegmenter &&
|
|
463
|
+
(await transcription.available()) &&
|
|
464
|
+
(await transcriptionSegmenter.available())
|
|
465
|
+
? {
|
|
466
|
+
resumable: {
|
|
467
|
+
maxDurationSeconds: deps.settings.voiceInputResumableMaxDurationSeconds,
|
|
468
|
+
maxSizeBytes: deps.settings.voiceInputResumableMaxSizeBytes,
|
|
469
|
+
maxChunkSizeBytes: deps.settings.voiceInputResumableMaxChunkSizeBytes,
|
|
470
|
+
providerSegmentSeconds: Math.min(
|
|
471
|
+
TRANSCRIPTION_RECORDING_PROVIDER_SEGMENT_SECONDS,
|
|
472
|
+
deps.settings.voiceInputMaxDurationSeconds,
|
|
473
|
+
),
|
|
474
|
+
},
|
|
475
|
+
}
|
|
476
|
+
: {}),
|
|
443
477
|
},
|
|
444
478
|
productAccessMode: deps.settings.productAccessMode,
|
|
445
479
|
auth: clientAuthConfig(deps.settings),
|
package/src/mcp/server.ts
CHANGED
|
@@ -1928,7 +1928,7 @@ function registerFleetTools(
|
|
|
1928
1928
|
"sandboxes_list",
|
|
1929
1929
|
{
|
|
1930
1930
|
description:
|
|
1931
|
-
"List the sandboxes this session can run on: its own session sandbox plus enrolled selfhosted machines. `liveness` is conservative: online requires observed provider existence and verified workspace readiness. Provider, lease, route, archive, restore, workspace, lease epoch, and route epoch are also reported separately. Use an entry `id` as an attach/swap/run_on target.",
|
|
1931
|
+
"List the sandboxes this session can run on: its own session sandbox plus enrolled selfhosted machines. `liveness` is conservative: online requires observed provider existence and verified workspace readiness. An idle session-home sandbox may report offline/cold/draining and still wake or restore on the next ordinary sandbox operation; never infer that shell/files are unavailable from list liveness alone—only a typed operation/attach failure proves that. Provider, lease, route, archive, restore, workspace, lease epoch, and route epoch are also reported separately. Use an entry `id` as an attach/swap/run_on target.",
|
|
1932
1932
|
inputSchema: {},
|
|
1933
1933
|
},
|
|
1934
1934
|
async () => json(await listFleet(services, await fleetContext())),
|