diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..b89a59a44 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# Agent Stack + +## GitHub Operations + +Use `gh` command for GitHub operations. + +Repo: `i-am-bee/agentstack` diff --git a/apps/agentstack-sdk-ts/src/client/a2a/create-authenticated-fetch.ts b/apps/agentstack-sdk-ts/src/client/a2a/create-authenticated-fetch.ts new file mode 100644 index 000000000..4ebad1c26 --- /dev/null +++ b/apps/agentstack-sdk-ts/src/client/a2a/create-authenticated-fetch.ts @@ -0,0 +1,21 @@ +/** + * Copyright 2025 © BeeAI a Series of LF Projects, LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +export function createAuthenticatedFetch(token: string, baseFetch?: typeof fetch): typeof fetch { + const fetchImpl = baseFetch ?? (typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : undefined); + + if (!fetchImpl) { + throw new Error( + 'fetch is not available. In Node.js < 18 or environments without global fetch, ' + + 'provide a fetch implementation via the baseFetch parameter.', + ); + } + + return async (input: RequestInfo | URL, init?: RequestInit) => { + const headers = new Headers(init?.headers); + headers.set('Authorization', `Bearer ${token}`); + return fetchImpl(input, { ...init, headers }); + }; +} diff --git a/apps/agentstack-sdk-ts/src/client/a2a/extensions/handle-agent-card.ts b/apps/agentstack-sdk-ts/src/client/a2a/extensions/handle-agent-card.ts index 940610394..6a788af10 100644 --- a/apps/agentstack-sdk-ts/src/client/a2a/extensions/handle-agent-card.ts +++ b/apps/agentstack-sdk-ts/src/client/a2a/extensions/handle-agent-card.ts @@ -33,6 +33,9 @@ export interface Fulfillments { secrets: (demand: SecretDemands) => Promise; form: (demand: FormDemands) => Promise; oauthRedirectUri: () => string | null; + /** + * @deprecated - keeping this for backwards compatibility, context token is now passed via A2A client headers + */ getContextToken: () => ContextToken; } diff --git a/apps/agentstack-sdk-ts/src/client/api/build-api-client.ts b/apps/agentstack-sdk-ts/src/client/api/build-api-client.ts index f27cbb31e..4f19f6687 100644 --- a/apps/agentstack-sdk-ts/src/client/api/build-api-client.ts +++ b/apps/agentstack-sdk-ts/src/client/api/build-api-client.ts @@ -6,7 +6,14 @@ import type { z } from 'zod'; import type { ContextPermissionsGrant, GlobalPermissionsGrant, ModelCapability } from './types'; -import { contextSchema, contextTokenSchema, listConnectorsResponseSchema, modelProviderMatchSchema } from './types'; +import { + contextPermissionsGrantSchema, + contextSchema, + contextTokenSchema, + globalPermissionsGrantSchema, + listConnectorsResponseSchema, + modelProviderMatchSchema, +} from './types'; export interface MatchProvidersParams { suggestedModels: string[] | null; @@ -79,16 +86,15 @@ export const buildApiClient = ( await callApi('POST', '/api/v1/contexts', { metadata: {}, provider_id: providerId }, contextSchema); const createContextToken = async ({ contextId, globalPermissions, contextPermissions }: CreateContextTokenParams) => { - if (!globalPermissions.a2a_proxy?.includes('*') && globalPermissions.a2a_proxy?.length === 0) { - throw new Error("Invalid audience: You must specify providers or use '*' in globalPermissions.a2a_proxy."); - } + const validatedGlobalPerms = globalPermissionsGrantSchema.parse(globalPermissions); + const validatedContextPerms = contextPermissionsGrantSchema.parse(contextPermissions); const token = await callApi( 'POST', `/api/v1/contexts/${contextId}/token`, { - grant_global_permissions: globalPermissions, - grant_context_permissions: contextPermissions, + grant_global_permissions: validatedGlobalPerms, + grant_context_permissions: validatedContextPerms, }, contextTokenSchema, ); diff --git a/apps/agentstack-sdk-ts/src/client/api/types.ts b/apps/agentstack-sdk-ts/src/client/api/types.ts index 1ff19a522..b2b8640e3 100644 --- a/apps/agentstack-sdk-ts/src/client/api/types.ts +++ b/apps/agentstack-sdk-ts/src/client/api/types.ts @@ -58,26 +58,50 @@ export const contextPermissionsGrantSchema = z.object({ export type ContextPermissionsGrant = z.infer; -export const globalPermissionsGrantSchema = contextPermissionsGrantSchema.extend({ - feedback: z.array(z.literal('write')).optional(), - - llm: z.array(z.union([z.literal('*'), resourceIdPermissionSchema])).optional(), - embeddings: z.array(z.union([z.literal('*'), resourceIdPermissionSchema])).optional(), - model_providers: z.array(z.literal(['read', 'write', '*'])).optional(), - - a2a_proxy: z.array(z.union([z.literal('*'), z.string()])).optional(), - - providers: z.array(z.literal(['read', 'write', '*'])).optional(), - provider_variables: z.array(z.literal(['read', 'write', '*'])).optional(), - - contexts: z.array(z.literal(['read', 'write', '*'])).optional(), - - mcp_providers: z.array(z.literal(['read', 'write', '*'])).optional(), - mcp_tools: z.array(z.literal(['read', '*'])).optional(), - mcp_proxy: z.array(z.literal('*')).optional(), - - connectors: z.array(z.literal(['read', 'write', 'proxy', '*'])).optional(), -}); +export const globalPermissionsGrantSchema = contextPermissionsGrantSchema + .extend({ + feedback: z.array(z.literal('write')).optional(), + + llm: z.array(z.union([z.literal('*'), resourceIdPermissionSchema])).optional(), + embeddings: z.array(z.union([z.literal('*'), resourceIdPermissionSchema])).optional(), + model_providers: z.array(z.literal(['read', 'write', '*'])).optional(), + + a2a_proxy: z.array(z.union([z.literal('*'), z.string()])).optional(), + + providers: z.array(z.literal(['read', 'write', '*'])).optional(), + provider_variables: z.array(z.literal(['read', 'write', '*'])).optional(), + + contexts: z.array(z.literal(['read', 'write', '*'])).optional(), + + mcp_providers: z.array(z.literal(['read', 'write', '*'])).optional(), + mcp_tools: z.array(z.literal(['read', '*'])).optional(), + mcp_proxy: z.array(z.literal('*')).optional(), + + connectors: z.array(z.literal(['read', 'write', 'proxy', '*'])).optional(), + }) + .superRefine((val, ctx) => { + if (!val.a2a_proxy) return; + + if (val.a2a_proxy.length === 0) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'a2a_proxy cannot be empty array', + path: ['a2a_proxy'], + }); + return; + } + + const hasWildcard = val.a2a_proxy.includes('*'); + const hasOthers = val.a2a_proxy.some((v) => v !== '*'); + + if (hasWildcard && hasOthers) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "a2a_proxy cannot mix '*' with specific providers", + path: ['a2a_proxy'], + }); + } + }); export type GlobalPermissionsGrant = z.infer; diff --git a/apps/agentstack-sdk-ts/src/index.ts b/apps/agentstack-sdk-ts/src/index.ts index 1ef9a528d..838c48f99 100644 --- a/apps/agentstack-sdk-ts/src/index.ts +++ b/apps/agentstack-sdk-ts/src/index.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +export { createAuthenticatedFetch } from './client/a2a/create-authenticated-fetch'; export * from './client/a2a/extensions/common/form'; export * from './client/a2a/extensions/fulfillment-resolvers/build-llm-extension-fulfillment-resolver'; export { type Fulfillments, handleAgentCard } from './client/a2a/extensions/handle-agent-card'; diff --git a/apps/agentstack-ui/src/api/a2a/agent-card.ts b/apps/agentstack-ui/src/api/a2a/agent-card.ts index fd1aa8c44..76cdd758a 100644 --- a/apps/agentstack-ui/src/api/a2a/agent-card.ts +++ b/apps/agentstack-ui/src/api/a2a/agent-card.ts @@ -4,6 +4,7 @@ */ import { A2AClient } from '@a2a-js/sdk/client'; +import { createAuthenticatedFetch } from 'agentstack-sdk'; import { UnauthenticatedError } from '#api/errors.ts'; import { getBaseUrl } from '#utils/api/getBaseUrl.ts'; @@ -11,13 +12,7 @@ import { getBaseUrl } from '#utils/api/getBaseUrl.ts'; export async function getAgentClient(providerId: string, token?: string) { const agentCardUrl = `${getBaseUrl()}/api/v1/a2a/${providerId}/.well-known/agent-card.json`; - const fetchImpl = token - ? async (input: RequestInfo, init?: RequestInit) => { - const headers = new Headers(init?.headers); - headers.set('Authorization', `Bearer ${token}`); - return clientFetch(input, { ...init, headers }); - } - : clientFetch; + const fetchImpl = token ? createAuthenticatedFetch(token, clientFetch) : clientFetch; return await A2AClient.fromCardUrl(agentCardUrl, { fetchImpl }); } diff --git a/apps/agentstack-ui/src/app/api/[...path]/route.ts b/apps/agentstack-ui/src/app/api/[...path]/route.ts index ad9a26c44..41525e820 100644 --- a/apps/agentstack-ui/src/app/api/[...path]/route.ts +++ b/apps/agentstack-ui/src/app/api/[...path]/route.ts @@ -19,6 +19,8 @@ type RouteContext = { }>; }; +const isA2AEndpoint = (path: string[]) => path[0] === 'v1' && path[1] === 'a2a'; + async function handler(request: NextRequest, context: RouteContext) { const { isAuthEnabled } = runtimeConfig; const { method, headers, body, nextUrl } = request; @@ -31,10 +33,12 @@ async function handler(request: NextRequest, context: RouteContext) { targetUrl += '/'; } targetUrl += search; - if (request.url.includes('/api/v1/a2a')) { - console.log(path, headers); - } - if (isAuthEnabled && !(path[0] == 'v1' && path[1] == 'a2a')) { + if (isAuthEnabled && !isA2AEndpoint(path)) { + if (isA2AEndpoint(path)) { + // Skip JWT auth for A2A endpoints - they use context tokens passed via A2A client + return; + } + const token = await ensureToken(request); if (!token?.accessToken) { diff --git a/apps/agentstack-ui/src/modules/platform-context/api/index.ts b/apps/agentstack-ui/src/modules/platform-context/api/index.ts index 9e95bac0c..6294acd0d 100644 --- a/apps/agentstack-ui/src/modules/platform-context/api/index.ts +++ b/apps/agentstack-ui/src/modules/platform-context/api/index.ts @@ -54,7 +54,6 @@ export async function matchProviders(matchProvidersParams: MatchProvidersParams) } export async function createContextToken(createContextTokenParams: CreateContextTokenParams) { - console.log(createContextTokenParams); const result = await agentstackClient.createContextToken(createContextTokenParams); return result.token; } diff --git a/apps/agentstack-ui/src/modules/platform-context/api/keys.ts b/apps/agentstack-ui/src/modules/platform-context/api/keys.ts index 04ae83372..b4833e55a 100644 --- a/apps/agentstack-ui/src/modules/platform-context/api/keys.ts +++ b/apps/agentstack-ui/src/modules/platform-context/api/keys.ts @@ -12,4 +12,6 @@ export const contextKeys = { histories: () => [...contextKeys.all(), 'history'] as const, history: ({ contextId, query = {} }: ListContextHistoryParams) => [...contextKeys.histories(), contextId, query] as const, + tokens: () => [...contextKeys.all(), 'token'] as const, + token: (contextId: string, providerId: string) => [...contextKeys.tokens(), contextId, providerId] as const, }; diff --git a/apps/agentstack-ui/src/modules/platform-context/api/queries/useContextToken.ts b/apps/agentstack-ui/src/modules/platform-context/api/queries/useContextToken.ts new file mode 100644 index 000000000..0f5ef7c07 --- /dev/null +++ b/apps/agentstack-ui/src/modules/platform-context/api/queries/useContextToken.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2025 © BeeAI a Series of LF Projects, LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { useQuery } from '@tanstack/react-query'; +import type { ContextToken } from 'agentstack-sdk'; + +import { useApp } from '#contexts/App/index.ts'; +import type { Agent } from '#modules/agents/api/types.ts'; + +import { usePlatformContext } from '../../contexts'; +import { createContextToken } from '..'; +import { contextKeys } from '../keys'; + +export function useContextToken(agent: Agent) { + const { + config: { contextTokenPermissions }, + } = useApp(); + const { contextId } = usePlatformContext(); + + return useQuery({ + queryKey: contextKeys.token(contextId ?? '', agent.provider.id), + queryFn: async () => { + if (!contextId) { + throw new Error('Context ID is not set.'); + } + + const token = await createContextToken({ + contextId, + contextPermissions: contextTokenPermissions.grant_context_permissions ?? {}, + globalPermissions: contextTokenPermissions.grant_global_permissions ?? {}, + }); + + if (!token) { + throw new Error('Could not generate context token'); + } + + return token; + }, + enabled: !!contextId, + staleTime: Infinity, + }); +} diff --git a/apps/agentstack-ui/src/modules/platform-context/constants.ts b/apps/agentstack-ui/src/modules/platform-context/constants.ts index a3b32b432..0eeeff6ea 100644 --- a/apps/agentstack-ui/src/modules/platform-context/constants.ts +++ b/apps/agentstack-ui/src/modules/platform-context/constants.ts @@ -15,7 +15,7 @@ export const contextTokenPermissionsDefaults: DeepRequired) { + const { data: contextToken } = useContextToken(agent); + const { agentClient } = useBuildA2AClient({ + providerId: agent.provider.id, + authToken: contextToken, + }); + + const contextValue = useMemo(() => { + if (!contextToken || !agentClient) { + return null; + } + + return { + contextToken, + agentClient, + }; + }, [contextToken, agentClient]); + + if (!contextValue) { + return null; + } + + return {children}; +} diff --git a/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/a2a-client-context.ts b/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/a2a-client-context.ts new file mode 100644 index 000000000..4d2d532b4 --- /dev/null +++ b/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/a2a-client-context.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2025 © BeeAI a Series of LF Projects, LLC + * SPDX-License-Identifier: Apache-2.0 + */ +'use client'; +import type { ContextToken } from 'agentstack-sdk'; +import { createContext } from 'react'; + +import type { AgentA2AClient } from '#api/a2a/types.ts'; + +export const A2AClientContext = createContext(null); + +export interface A2AClientContextValue { + contextToken: ContextToken; + agentClient: AgentA2AClient; +} diff --git a/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/index.ts b/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/index.ts new file mode 100644 index 000000000..4d2b6fe76 --- /dev/null +++ b/apps/agentstack-ui/src/modules/runs/contexts/a2a-client/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright 2025 © BeeAI a Series of LF Projects, LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { use } from 'react'; + +import { A2AClientContext } from './a2a-client-context'; + +export function useA2AClient() { + const context = use(A2AClientContext); + + if (!context) { + throw new Error('useA2AClient must be used within A2AClientProvider'); + } + + return context; +} + +export { A2AClientProvider } from './A2AClientProvider'; diff --git a/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/AgentDemandsProvider.tsx b/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/AgentDemandsProvider.tsx index 8f42db21b..2ecd11bc2 100644 --- a/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/AgentDemandsProvider.tsx +++ b/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/AgentDemandsProvider.tsx @@ -3,31 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { ContextToken } from 'agentstack-sdk'; import { type AgentSettings, type FormFulfillments, ModelCapability } from 'agentstack-sdk'; import { type PropsWithChildren, useCallback, useRef, useState } from 'react'; -import type { AgentA2AClient } from '#api/a2a/types.ts'; import { useListConnectors } from '#modules/connectors/api/queries/useListConnectors.ts'; import type { RunFormValues } from '#modules/form/types.ts'; import { useMatchProviders } from '#modules/platform-context/api/mutations/useMatchProviders.ts'; import { getSettingsDemandsDefaultValues } from '#modules/runs/settings/utils.ts'; +import { useA2AClient } from '../a2a-client'; import { useAgentSecrets } from '../agent-secrets'; import type { FulfillmentsContext } from './agent-demands-context'; import { AgentDemandsContext } from './agent-demands-context'; import { buildFulfillments } from './build-fulfillments'; -interface Props { - agentClient: AgentA2AClient; - contextToken: ContextToken; -} - -export function AgentDemandsProvider({ - agentClient, - contextToken, - children, -}: PropsWithChildren>) { +export function AgentDemandsProvider({ children }: PropsWithChildren) { + const { agentClient, contextToken } = useA2AClient(); const { demandedSecrets } = useAgentSecrets(); const [selectedEmbeddingProviders, setSelectedEmbeddingProviders] = useState>({}); diff --git a/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/build-fulfillments.ts b/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/build-fulfillments.ts index 46aeb231a..8d8b90462 100644 --- a/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/build-fulfillments.ts +++ b/apps/agentstack-ui/src/modules/runs/contexts/agent-demands/build-fulfillments.ts @@ -38,6 +38,7 @@ export const buildFulfillments = ({ connectors, }: BuildFulfillmentsParams): Fulfillments => { return { + // @deprecated - token now passed via A2A client headers getContextToken: () => contextToken, settings: async () => { diff --git a/apps/agentstack-ui/src/modules/runs/contexts/agent-run/AgentRunProvider.tsx b/apps/agentstack-ui/src/modules/runs/contexts/agent-run/AgentRunProvider.tsx index 46c30742c..f54714374 100644 --- a/apps/agentstack-ui/src/modules/runs/contexts/agent-run/AgentRunProvider.tsx +++ b/apps/agentstack-ui/src/modules/runs/contexts/agent-run/AgentRunProvider.tsx @@ -5,16 +5,14 @@ 'use client'; import { useQueryClient } from '@tanstack/react-query'; -import type { ContextToken } from 'agentstack-sdk'; import { TaskStatusUpdateType } from 'agentstack-sdk'; import type { PropsWithChildren } from 'react'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import { v4 as uuid } from 'uuid'; -import type { AgentA2AClient, ChatRun } from '#api/a2a/types.ts'; +import type { ChatRun } from '#api/a2a/types.ts'; import { createTextPart } from '#api/a2a/utils.ts'; import { getErrorCode } from '#api/utils.ts'; -import { useApp } from '#contexts/App/index.ts'; import { useHandleError } from '#hooks/useHandleError.ts'; import type { Agent } from '#modules/agents/api/types.ts'; import { CanvasProvider } from '#modules/canvas/contexts/CanvasProvider.tsx'; @@ -30,10 +28,8 @@ import type { UIAgentMessage, UIMessageForm, UIUserMessage } from '#modules/mess import { UIMessagePartKind, UIMessageStatus } from '#modules/messages/types.ts'; import { addMessagePart, isAgentMessage } from '#modules/messages/utils.ts'; import { contextKeys } from '#modules/platform-context/api/keys.ts'; -import { useCreateContextToken } from '#modules/platform-context/api/mutations/useCreateContextToken.ts'; import { usePlatformContext } from '#modules/platform-context/contexts/index.ts'; import { useEnsurePlatformContext } from '#modules/platform-context/hooks/useEnsurePlatformContext.ts'; -import { useBuildA2AClient } from '#modules/runs/api/queries/useBuildA2AClient.ts'; import { useStartOAuth } from '#modules/runs/hooks/useStartOAuth.ts'; import type { RunStats } from '#modules/runs/types.ts'; import { SourcesProvider } from '#modules/sources/contexts/SourcesProvider.tsx'; @@ -41,6 +37,7 @@ import { getMessagesSourcesMap } from '#modules/sources/utils.ts'; import type { TaskId } from '#modules/tasks/api/types.ts'; import { isNotNull } from '#utils/helpers.ts'; +import { A2AClientProvider, useA2AClient } from '../a2a-client'; import { useAgentDemands } from '../agent-demands'; import type { FulfillmentsContext } from '../agent-demands/agent-demands-context'; import { AgentDemandsProvider } from '../agent-demands/AgentDemandsProvider'; @@ -54,70 +51,28 @@ interface Props { export function AgentRunProviders({ agent, children }: PropsWithChildren) { useEnsurePlatformContext(agent); - const { - config: { contextTokenPermissions }, - } = useApp(); - - const { contextId } = usePlatformContext(); - const { mutateAsync: createContextToken } = useCreateContextToken(); - const [contextToken, setContextToken] = useState(null); - - useEffect(() => { - const createToken = async () => { - if (contextId === null) { - // todo uncaught error - throw new Error('Illegal State - Context ID is not set.'); - } - - const token = await createContextToken({ - contextId, - contextPermissions: contextTokenPermissions.grant_context_permissions ?? {}, - globalPermissions: { - ...(contextTokenPermissions.grant_global_permissions ?? {}), - a2a_proxy: [...(contextTokenPermissions.grant_global_permissions?.a2a_proxy ?? []), agent.provider.id], - }, - }); - if (!token) { - throw new Error('Could not generate context token'); - } - setContextToken(token); - }; - createToken(); - }, [contextId, contextTokenPermissions, createContextToken, agent.provider.id]); - - const { agentClient } = useBuildA2AClient({ - providerId: agent.provider.id, - authToken: contextToken, - }); - - if (!agentClient || !contextToken) { - return null; - } return ( - - - - - - - {children} - - - - - - + + + + + + + {children} + + + + + + ); } -interface AgentRunProviderProps extends Props { - agentClient?: AgentA2AClient; -} - -function AgentRunProvider({ agent, agentClient, children }: PropsWithChildren) { +function AgentRunProvider({ agent, children }: PropsWithChildren) { const queryClient = useQueryClient(); const errorHandler = useHandleError(); + const { agentClient } = useA2AClient(); const { messages, getMessages, setMessages } = useMessages(); diff --git a/apps/agentstack-ui/src/modules/runs/contexts/agent-secrets/AgentSecretsProvider.tsx b/apps/agentstack-ui/src/modules/runs/contexts/agent-secrets/AgentSecretsProvider.tsx index ce5b6dfb1..c144f4bce 100644 --- a/apps/agentstack-ui/src/modules/runs/contexts/agent-secrets/AgentSecretsProvider.tsx +++ b/apps/agentstack-ui/src/modules/runs/contexts/agent-secrets/AgentSecretsProvider.tsx @@ -8,17 +8,16 @@ import { useCallback, useMemo } from 'react'; import { useLocalStorage } from 'usehooks-ts'; import z from 'zod'; -import type { AgentA2AClient } from '#api/a2a/types.ts'; import type { Agent } from '#modules/agents/api/types.ts'; import { useListVariables } from '#modules/variables/api/queries/useListVariables.ts'; import { AGENT_SECRETS_SETTINGS_STORAGE_KEY } from '#utils/constants.ts'; +import { useA2AClient } from '../a2a-client'; import { AgentSecretsContext } from './agent-secrets-context'; import type { NonReadySecretDemand, ReadySecretDemand } from './types'; interface Props { agent: Agent; - agentClient?: AgentA2AClient; } const secretsSchema = z.record( @@ -41,7 +40,8 @@ const secretsLocalStorageOptions = { }, }; -export function AgentSecretsProvider({ agent, agentClient, children }: PropsWithChildren) { +export function AgentSecretsProvider({ agent, children }: PropsWithChildren) { + const { agentClient } = useA2AClient(); const [agentSecrets, setAgentSecrets] = useLocalStorage( AGENT_SECRETS_SETTINGS_STORAGE_KEY, {}, @@ -56,7 +56,7 @@ export function AgentSecretsProvider({ agent, agentClient, children }: PropsWith }, [agentSecrets, agent.provider.id]); const secretDemands = useMemo(() => { - return agentClient?.demands.secretDemands ?? null; + return agentClient.demands.secretDemands ?? null; }, [agentClient]); const markModalAsSeen = useCallback(() => { diff --git a/helm/values.yaml b/helm/values.yaml index c5c06e63d..562e3128c 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -70,7 +70,7 @@ contextTokenPermissions: llm: ["*"] embeddings: ["*"] model_providers: [] - a2a_proxy: [] + a2a_proxy: ["*"] providers: [] provider_variables: [] contexts: []