| @@ -12,7 +12,7 @@ import { · 11 unmodified lines |
| 12 | type CompiledToolSourceArtifact, | 12 | type CompiledToolSourceArtifact, |
| 13 | type WorkspaceToolSnapshot, | 13 | type WorkspaceToolSnapshot, |
| 14 | } from "../../core/src/tool-sources"; | 14 | } from "../../core/src/tool-sources"; |
| 15 | import { serializeTools } from "../../core/src/tool/source-serialization"; | 15 | import type { SerializedTool } from "../../core/src/tool/source-serialization"; |
| 16 | import type { ExternalToolSourceConfig } from "../../core/src/tool/source-types"; | 16 | import type { ExternalToolSourceConfig } from "../../core/src/tool/source-types"; |
| 17 | import type { | 17 | import type { |
| 18 | AccessPolicyRecord, | 18 | AccessPolicyRecord, |
| @@ -370,20 +370,18 @@ async function buildWorkspaceToolRegistry( · 351 unmodified lines |
| 370 | ctx: ActionCtx, | 370 | ctx: ActionCtx, |
| 371 | args: { | 371 | args: { |
| 372 | workspaceId: Id<"workspaces">; | 372 | workspaceId: Id<"workspaces">; |
| 373 | signature: string; | 373 | registrySignature: string; |
| 374 | tools: ToolDefinition[]; | 374 | serializedTools: SerializedTool[]; |
| 375 | }, | 375 | }, |
| 376 | ): Promise<{ buildId: string }> { | 376 | ): Promise<{ buildId: string }> { |
| 377 | const buildId = `toolreg_${crypto.randomUUID()}`; | 377 | const buildId = `toolreg_${crypto.randomUUID()}`; |
| 378 | await ctx.runMutation(internal.toolRegistry.beginBuild, { | 378 | await ctx.runMutation(internal.toolRegistry.beginBuild, { |
| 379 | workspaceId: args.workspaceId, | 379 | workspaceId: args.workspaceId, |
| 380 | signature: args.signature, | 380 | signature: args.registrySignature, |
| 381 | buildId, | 381 | buildId, |
| 382 | }); | 382 | }); |
| 383 | | 383 | |
| 384 | const serialized = serializeTools(args.tools); | 384 | const entries = args.serializedTools.map((st) => { |
| 385 | | | |
| 386 | const entries = serialized.map((st) => { | | |
| 387 | if (st.path === "discover" || st.path.startsWith("catalog.")) { | 385 | if (st.path === "discover" || st.path.startsWith("catalog.")) { |
| 388 | return null; | 386 | return null; |
| 389 | } | 387 | } |
| @@ -487,6 +485,25 @@ async function buildWorkspaceToolRegistry( · 97 unmodified lines |
| 487 | return { buildId }; | 485 | return { buildId }; |
| 488 | } | 486 | } |
| 489 | | 487 | |
| | 488 | async function maybeBuildWorkspaceToolRegistry( |
| | 489 | ctx: ActionCtx, |
| | 490 | args: { |
| | 491 | workspaceId: Id<"workspaces">; |
| | 492 | registrySignature: string; |
| | 493 | serializedTools: SerializedTool[]; |
| | 494 | }, |
| | 495 | ): Promise<void> { |
| | 496 | const state = await ctx.runQuery(internal.toolRegistry.getState, { workspaceId: args.workspaceId }) as |
| | 497 | | null |
| | 498 | | { signature: string; readyBuildId?: string }; |
| | 499 | |
| | 500 | if (state?.readyBuildId && state.signature === args.registrySignature) { |
| | 501 | return; |
| | 502 | } |
| | 503 | |
| | 504 | await buildWorkspaceToolRegistry(ctx, args); |
| | 505 | } |
| | 506 | |
| 490 | export async function getWorkspaceTools( | 507 | export async function getWorkspaceTools( |
| 491 | ctx: ActionCtx, | 508 | ctx: ActionCtx, |
| 492 | workspaceId: Id<"workspaces">, | 509 | workspaceId: Id<"workspaces">, |
| @@ -517,6 +534,7 @@ export async function getWorkspaceTools( · 24 unmodified lines |
| 517 | traceStep("listToolSources", listSourcesStartedAt); | 534 | traceStep("listToolSources", listSourcesStartedAt); |
| 518 | const hasOpenApiSource = sources.some((source: { type: string }) => source.type === "openapi"); | 535 | const hasOpenApiSource = sources.some((source: { type: string }) => source.type === "openapi"); |
| 519 | const signature = sourceSignature(workspaceId, sources); | 536 | const signature = sourceSignature(workspaceId, sources); |
| | 537 | const registrySignature = `toolreg_v1|${signature}`; |
| 520 | const debugBase: Omit<WorkspaceToolsDebug, "mode" | "normalizedSourceCount" | "cacheHit" | "cacheFresh" | "timedOutSources" | "durationMs" | "trace"> = { | 538 | const debugBase: Omit<WorkspaceToolsDebug, "mode" | "normalizedSourceCount" | "cacheHit" | "cacheFresh" | "timedOutSources" | "durationMs" | "trace"> = { |
| 521 | includeDts, | 539 | includeDts, |
| 522 | sourceTimeoutMs: sourceTimeoutMs ?? null, | 540 | sourceTimeoutMs: sourceTimeoutMs ?? null, |
| @@ -545,6 +563,17 @@ export async function getWorkspaceTools( · 22 unmodified lines |
| 545 | const typesStorageId = cacheEntry.typesStorageId as Id<"_storage"> | undefined; | 563 | const typesStorageId = cacheEntry.typesStorageId as Id<"_storage"> | undefined; |
| 546 | if (cacheEntry.isFresh) { | 564 | if (cacheEntry.isFresh) { |
| 547 | if (typesStorageId) { | 565 | if (typesStorageId) { |
| | 566 | // Registry is derived from the cached snapshot. Keep it in sync. |
| | 567 | try { |
| | 568 | await maybeBuildWorkspaceToolRegistry(ctx, { |
| | 569 | workspaceId, |
| | 570 | registrySignature, |
| | 571 | serializedTools: snapshot.externalArtifacts.flatMap((artifact) => artifact.tools), |
| | 572 | }); |
| | 573 | } catch (error) { |
| | 574 | const msg = error instanceof Error ? error.message : String(error); |
| | 575 | console.warn(`[executor] workspace tool registry build failed for '${workspaceId}': ${msg}`); |
| | 576 | } |
| 548 | return { | 577 | return { |
| 549 | tools: merged, | 578 | tools: merged, |
| 550 | warnings: snapshot.warnings, | 579 | warnings: snapshot.warnings, |
| @@ -677,10 +706,10 @@ export async function getWorkspaceTools( · 126 unmodified lines |
| 677 | | 706 | |
| 678 | // Build a per-tool registry for fast discover + invocation. | 707 | // Build a per-tool registry for fast discover + invocation. |
| 679 | const registryStartedAt = Date.now(); | 708 | const registryStartedAt = Date.now(); |
| 680 | await buildWorkspaceToolRegistry(ctx, { | 709 | await maybeBuildWorkspaceToolRegistry(ctx, { |
| 681 | workspaceId, | 710 | workspaceId, |
| 682 | signature, | 711 | registrySignature, |
| 683 | tools: allTools, | 712 | serializedTools: externalArtifacts.flatMap((artifact) => artifact.tools), |
| 684 | }); | 713 | }); |
| 685 | traceStep("toolRegistryWrite", registryStartedAt); | 714 | traceStep("toolRegistryWrite", registryStartedAt); |
| 686 | | 715 | |