@opengeni/api-router 2.13.0-canary.1 → 2.13.0-canary.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.js +1 -1
- package/dist/{chunk-V4IDX7VJ.js → chunk-K2NU4KRK.js} +3138 -3635
- package/dist/{chunk-V4IDX7VJ.js.map → chunk-K2NU4KRK.js.map} +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/integrations/github-lens-connect.d.ts +1 -1
- package/dist/integrations/slack-interactions.d.ts +1 -1
- package/dist/mcp/documents.d.ts +5 -13
- package/dist/mcp/files.d.ts +2 -2
- package/dist/mcp/first-party-tool-permissions.d.ts +36 -0
- package/dist/mcp/knowledge-entries.d.ts +5 -0
- package/dist/mcp/server.d.ts +4 -4
- package/dist/routes/host-mcp-resolvers.d.ts +3 -0
- package/dist/routes/knowledge.d.ts +3 -0
- package/dist/sandbox-file-artifacts.d.ts +6 -2
- package/dist/workspace-state-projection.d.ts +3 -5
- package/package.json +19 -19
- package/src/access-grant-rls.ts +13 -1
- package/src/app.ts +4 -11
- package/src/index.ts +4 -3
- package/src/integrations/atlassian.ts +31 -28
- package/src/integrations/google-drive.ts +33 -30
- package/src/integrations/marketplace-plugin.ts +1 -1
- package/src/integrations/provider-oauth.ts +11 -2
- package/src/mcp/documents.ts +57 -428
- package/src/mcp/files.ts +76 -58
- package/src/mcp/first-party-tool-permissions.ts +9 -0
- package/src/mcp/knowledge-entries.ts +276 -0
- package/src/mcp/server.ts +7 -361
- package/src/routes/company-brain.ts +58 -107
- package/src/routes/documents.ts +78 -294
- package/src/routes/files.ts +68 -3
- package/src/routes/host-mcp-resolvers.ts +41 -0
- package/src/routes/knowledge.ts +386 -0
- package/src/routes/organization-memberships.ts +33 -0
- package/src/routes/scheduled-tasks.ts +9 -1
- package/src/routes/sessions.ts +20 -3
- package/src/routes/skill-content.ts +8 -2
- package/src/routes/video-generation.ts +7 -5
- package/src/routes/workspace-learning.ts +12 -82
- package/src/routes/workspace-state.ts +34 -25
- package/src/routes/workspaces.ts +20 -10
- package/src/sandbox-file-artifacts.ts +54 -2
- package/src/scheduled-task-deletion.ts +3 -2
- package/src/workspace-state-projection.ts +18 -148
- package/src/workspace-tool-gateway.ts +3 -15
- package/dist/mcp/company-brain-governed-writes.d.ts +0 -26
- package/dist/mcp/remember.d.ts +0 -28
- package/src/mcp/company-brain-governed-writes.ts +0 -271
- package/src/mcp/remember.ts +0 -191
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scheduledTaskKnowledgeSource,
|
|
3
|
+
requireScheduledTaskKnowledgeSource,
|
|
4
|
+
knowledgeSourceAgentConfig,
|
|
5
|
+
} from "@opengeni/contracts";
|
|
1
6
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
7
|
import { ExternalActorContinuation } from "@opengeni/contracts/external-identities";
|
|
3
8
|
import { requireConnectOwnerAuthority } from "./connect-authority";
|
|
@@ -188,7 +193,7 @@ export async function wakeGoogleDriveSourcesFromWorkspaceEvent(
|
|
|
188
193
|
);
|
|
189
194
|
let triggered = 0;
|
|
190
195
|
for (const task of tasks) {
|
|
191
|
-
if (task
|
|
196
|
+
if (!scheduledTaskKnowledgeSource(task) || task.status !== "active") continue;
|
|
192
197
|
const externalSourceId =
|
|
193
198
|
typeof task.metadata.externalSourceId === "string" ? task.metadata.externalSourceId : null;
|
|
194
199
|
const selectedSource = externalSourceId ? selectedById.get(externalSourceId) : null;
|
|
@@ -808,20 +813,20 @@ async function deauthorizeGoogleDriveConnectionSources(
|
|
|
808
813
|
connection.workspaceId,
|
|
809
814
|
connection.id,
|
|
810
815
|
async (task) => {
|
|
811
|
-
if (task.
|
|
816
|
+
if (requireScheduledTaskKnowledgeSource(task).initiatingSubjectId !== subjectId) return;
|
|
812
817
|
const resolved = await getKnowledgeSourceForSyncAuthority(deps.db, {
|
|
813
818
|
accountId: task.accountId,
|
|
814
819
|
workspaceId: task.workspaceId,
|
|
815
|
-
sourceId: task.
|
|
820
|
+
sourceId: requireScheduledTaskKnowledgeSource(task).sourceId,
|
|
816
821
|
initiatingSubjectId: subjectId,
|
|
817
822
|
});
|
|
818
823
|
if (!resolved || resolved.source.lifecycleState !== "active") return;
|
|
819
824
|
await deauthorizeKnowledgeSourceRetrieval(deps.db, {
|
|
820
825
|
accountId: task.accountId,
|
|
821
826
|
workspaceId: task.workspaceId,
|
|
822
|
-
sourceId: task.
|
|
823
|
-
audience: task.
|
|
824
|
-
operationId: `google-drive-deauthorize:${connection.id}:${authorityVersion}:${task.
|
|
827
|
+
sourceId: requireScheduledTaskKnowledgeSource(task).sourceId,
|
|
828
|
+
audience: requireScheduledTaskKnowledgeSource(task).destination,
|
|
829
|
+
operationId: `google-drive-deauthorize:${connection.id}:${authorityVersion}:${requireScheduledTaskKnowledgeSource(task).sourceId}:${reasonCode}`,
|
|
825
830
|
reasonCode,
|
|
826
831
|
actor: {
|
|
827
832
|
kind: "human",
|
|
@@ -837,7 +842,7 @@ async function forEachGoogleDriveConnectionTask(
|
|
|
837
842
|
deps: ApiRouteDeps,
|
|
838
843
|
workspaceId: string,
|
|
839
844
|
connectionId: string,
|
|
840
|
-
fn: (task: ScheduledTask
|
|
845
|
+
fn: (task: ScheduledTask) => Promise<void>,
|
|
841
846
|
): Promise<void> {
|
|
842
847
|
const tasks = await listKnowledgeSourceSyncTasksForConnection(deps.db, workspaceId, connectionId);
|
|
843
848
|
for (const task of tasks) {
|
|
@@ -1393,11 +1398,11 @@ async function materializeGoogleDriveKnowledgeSchedules(
|
|
|
1393
1398
|
let source = null as Awaited<ReturnType<typeof upsertKnowledgeSource>> | null;
|
|
1394
1399
|
let existingTask = null as (typeof connectionTasks)[number] | null;
|
|
1395
1400
|
for (const task of connectionTasks) {
|
|
1396
|
-
if (task
|
|
1401
|
+
if (!scheduledTaskKnowledgeSource(task)) continue;
|
|
1397
1402
|
const resolved = await getKnowledgeSourceForSyncAuthority(deps.db, {
|
|
1398
1403
|
accountId: input.accountId,
|
|
1399
1404
|
workspaceId: input.workspaceId,
|
|
1400
|
-
sourceId: task.
|
|
1405
|
+
sourceId: requireScheduledTaskKnowledgeSource(task).sourceId,
|
|
1401
1406
|
initiatingSubjectId: input.subjectId,
|
|
1402
1407
|
});
|
|
1403
1408
|
if (resolved?.source.externalSourceId !== identity.externalSourceId) continue;
|
|
@@ -1499,7 +1504,10 @@ async function materializeGoogleDriveKnowledgeSchedules(
|
|
|
1499
1504
|
task = await updateScheduledTask(deps.db, input.workspaceId, existingTask.id, {
|
|
1500
1505
|
name: `Sync Google Drive: ${selectedSource.name}`,
|
|
1501
1506
|
overlapPolicy: "buffer_one",
|
|
1502
|
-
action,
|
|
1507
|
+
action: { kind: "agent_turn" },
|
|
1508
|
+
agentConfig: knowledgeSourceAgentConfig(action, existingTask.agentConfig),
|
|
1509
|
+
refreshPersonalResourceAuthority: true,
|
|
1510
|
+
authorityUpdatedBy: { kind: "subject", subjectId: input.subjectId },
|
|
1503
1511
|
metadata: {
|
|
1504
1512
|
...existingTask.metadata,
|
|
1505
1513
|
connectorKind: "google_drive",
|
|
@@ -1531,16 +1539,11 @@ async function materializeGoogleDriveKnowledgeSchedules(
|
|
|
1531
1539
|
status: "active",
|
|
1532
1540
|
schedule,
|
|
1533
1541
|
overlapPolicy: "buffer_one",
|
|
1534
|
-
action,
|
|
1542
|
+
action: { kind: "agent_turn" },
|
|
1535
1543
|
runMode: "new_session_per_run",
|
|
1536
1544
|
targetSessionId: null,
|
|
1537
1545
|
connectionAuthorities: [],
|
|
1538
|
-
agentConfig:
|
|
1539
|
-
prompt: "Knowledge source synchronization",
|
|
1540
|
-
resources: [],
|
|
1541
|
-
tools: [],
|
|
1542
|
-
metadata: {},
|
|
1543
|
-
},
|
|
1546
|
+
agentConfig: knowledgeSourceAgentConfig(action),
|
|
1544
1547
|
variableSetId: null,
|
|
1545
1548
|
environmentId: null,
|
|
1546
1549
|
rigId: null,
|
|
@@ -1565,11 +1568,11 @@ async function materializeGoogleDriveKnowledgeSchedules(
|
|
|
1565
1568
|
}
|
|
1566
1569
|
|
|
1567
1570
|
for (const task of connectionTasks) {
|
|
1568
|
-
if (task
|
|
1571
|
+
if (!scheduledTaskKnowledgeSource(task)) continue;
|
|
1569
1572
|
const resolved = await getKnowledgeSourceForSyncAuthority(deps.db, {
|
|
1570
1573
|
accountId: input.accountId,
|
|
1571
1574
|
workspaceId: input.workspaceId,
|
|
1572
|
-
sourceId: task.
|
|
1575
|
+
sourceId: requireScheduledTaskKnowledgeSource(task).sourceId,
|
|
1573
1576
|
initiatingSubjectId: input.subjectId,
|
|
1574
1577
|
});
|
|
1575
1578
|
if (!resolved || enabledIds.has(resolved.source.externalSourceId)) continue;
|
|
@@ -1613,10 +1616,10 @@ export async function preflightKnowledgeSourceScheduleAuthorization(
|
|
|
1613
1616
|
input: { task: ScheduledTask; subjectId: string },
|
|
1614
1617
|
): Promise<void> {
|
|
1615
1618
|
const { task } = input;
|
|
1616
|
-
if (task
|
|
1619
|
+
if (!scheduledTaskKnowledgeSource(task)) return;
|
|
1617
1620
|
if (
|
|
1618
|
-
task.
|
|
1619
|
-
task.
|
|
1621
|
+
requireScheduledTaskKnowledgeSource(task).initiatingSubjectId !== input.subjectId ||
|
|
1622
|
+
requireScheduledTaskKnowledgeSource(task).connection.ownerSubjectId !== input.subjectId
|
|
1620
1623
|
) {
|
|
1621
1624
|
throw new HTTPException(403, {
|
|
1622
1625
|
message: "knowledge source schedule requires the exact initiating subject",
|
|
@@ -1642,10 +1645,10 @@ export async function revokeKnowledgeSourceScheduleAuthorization(
|
|
|
1642
1645
|
input: { task: ScheduledTask; subjectId: string },
|
|
1643
1646
|
): Promise<void> {
|
|
1644
1647
|
const { task } = input;
|
|
1645
|
-
if (task
|
|
1648
|
+
if (!scheduledTaskKnowledgeSource(task)) return;
|
|
1646
1649
|
if (
|
|
1647
|
-
task.
|
|
1648
|
-
task.
|
|
1650
|
+
requireScheduledTaskKnowledgeSource(task).initiatingSubjectId !== input.subjectId ||
|
|
1651
|
+
requireScheduledTaskKnowledgeSource(task).connection.ownerSubjectId !== input.subjectId
|
|
1649
1652
|
) {
|
|
1650
1653
|
throw new HTTPException(403, {
|
|
1651
1654
|
message: "knowledge source schedule requires the exact initiating subject",
|
|
@@ -1665,11 +1668,11 @@ export async function revokeKnowledgeSourceScheduleAuthorization(
|
|
|
1665
1668
|
taskId: task.id,
|
|
1666
1669
|
accountId: task.accountId,
|
|
1667
1670
|
workspaceId: task.workspaceId,
|
|
1668
|
-
connectionId: task.
|
|
1669
|
-
connectionVersion: task.
|
|
1670
|
-
sourceId: task.
|
|
1671
|
-
sourceLifecycleGeneration: task.
|
|
1672
|
-
sourceConfigGeneration: task.
|
|
1671
|
+
connectionId: requireScheduledTaskKnowledgeSource(task).connection.connectionId,
|
|
1672
|
+
connectionVersion: requireScheduledTaskKnowledgeSource(task).connection.connectionVersion,
|
|
1673
|
+
sourceId: requireScheduledTaskKnowledgeSource(task).sourceId,
|
|
1674
|
+
sourceLifecycleGeneration: requireScheduledTaskKnowledgeSource(task).sourceLifecycleGeneration,
|
|
1675
|
+
sourceConfigGeneration: requireScheduledTaskKnowledgeSource(task).sourceConfigGeneration,
|
|
1673
1676
|
externalSourceId,
|
|
1674
1677
|
subjectId: input.subjectId,
|
|
1675
1678
|
});
|
|
@@ -5,7 +5,7 @@ import { HTTPException } from "hono/http-exception";
|
|
|
5
5
|
/** Adapt only indexed portable components. Never silently drop required components. */
|
|
6
6
|
export function marketplacePlugin(url: string) {
|
|
7
7
|
const source = snapshot.sources.find((candidate) =>
|
|
8
|
-
candidate.entries.some((
|
|
8
|
+
candidate.entries.some((entry) => entry.sourceUrl === url),
|
|
9
9
|
);
|
|
10
10
|
const item = source?.entries.find((candidate) => candidate.sourceUrl === url);
|
|
11
11
|
if (!item || !source) return null;
|
|
@@ -375,7 +375,7 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
375
375
|
if (!providerScopesInclude(definition, token.scopes, state.authorizeScopes)) {
|
|
376
376
|
throw new ProviderOAuthCallbackError("scope_not_granted");
|
|
377
377
|
}
|
|
378
|
-
|
|
378
|
+
let grantedScopes = token.scopes.length > 0 ? token.scopes : state.authorizeScopes;
|
|
379
379
|
const identity = await verifyProviderIdentity(deps, definition, token);
|
|
380
380
|
if (
|
|
381
381
|
state.expectedProviderPrincipalId &&
|
|
@@ -415,6 +415,11 @@ export async function completeApiIntegrationProviderOAuth(
|
|
|
415
415
|
if (!refreshToken) {
|
|
416
416
|
throw new ProviderOAuthCallbackError("refresh_token_missing");
|
|
417
417
|
}
|
|
418
|
+
// Microsoft omits offline_access from access-token scopes. The new or
|
|
419
|
+
// previously verified refresh token proves this capability instead.
|
|
420
|
+
if (definition.provider.id === "microsoft") {
|
|
421
|
+
grantedScopes = uniqueStrings([...grantedScopes, "offline_access"]);
|
|
422
|
+
}
|
|
418
423
|
const credentialEncrypted = encryptEnvironmentValue(
|
|
419
424
|
key,
|
|
420
425
|
JSON.stringify({
|
|
@@ -926,7 +931,11 @@ function providerScopesInclude(
|
|
|
926
931
|
return value;
|
|
927
932
|
};
|
|
928
933
|
const granted = new Set(effective.map(normalize));
|
|
929
|
-
return definition.authentication.scopes.every(
|
|
934
|
+
return definition.authentication.scopes.every(
|
|
935
|
+
(scope) =>
|
|
936
|
+
(definition.provider.id === "microsoft" && normalize(scope) === "offline_access") ||
|
|
937
|
+
granted.has(normalize(scope)),
|
|
938
|
+
);
|
|
930
939
|
}
|
|
931
940
|
|
|
932
941
|
function providerOAuthReturnUrl(
|