Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/api-client/src/posthog-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4964,14 +4964,21 @@ export class PostHogAPIClient {
ingressBaseUrl: string,
message: string,
previewToken?: string | null,
supportedClientTools?: readonly string[],
): Promise<{ session_id: string; resumed?: boolean }> {
const url = new URL(`${ingressBaseUrl.replace(/\/$/, "")}/run`);
// `supported_client_tools`: the kind:'client' tool ids this client can
// execute this session, so the runner exposes only those to the model.
const body: Record<string, unknown> = { message };
if (supportedClientTools && supportedClientTools.length > 0) {
body.supported_client_tools = supportedClientTools;
}
const response = await this.api.fetcher.fetch({
method: "post",
url,
path: url.pathname,
parameters: previewTokenHeader(previewToken),
overrides: { body: JSON.stringify({ message }) },
overrides: { body: JSON.stringify(body) },
});
return (await response.json()) as { session_id: string; resumed?: boolean };
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/agent-chat/agentChatService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ export class AgentChatService {
session.ingressBaseUrl,
session.buildWireText(text),
token,
session.supportedClientTools,
),
);
agentChatStore.getState().setSessionId(session.chatId, session_id);
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/agent-chat/identifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export interface AgentChatSession {
ingressBaseUrl: string;
/** Non-null targets a specific draft revision (preview token attached per call). */
revisionId: string | null;
/** `kind:'client'` tool ids this client can fulfil; sent to the runner at /run. */
supportedClientTools?: readonly string[];
createMapper(): AgentChatMapper;
/** Resolve a client-tool call; `defer`/null ⇒ the service won't post a result. */
resolveClientTool(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import {
useAgentBuilderStore,
} from "./agentBuilderStore";
import { suggestionsForPage } from "./agentBuilderSuggestions";
import { useAgentBuilderClientTools } from "./useAgentBuilderClientTools";
import {
AGENT_BUILDER_CLIENT_TOOLS,
useAgentBuilderClientTools,
} from "./useAgentBuilderClientTools";

const CHAT_ID = AGENT_BUILDER_CHAT_ID;

Expand Down Expand Up @@ -118,6 +121,7 @@ export function AgentBuilderDock() {
orgId: currentOrgId,
}),
clientTools,
supportedClientTools: AGENT_BUILDER_CLIENT_TOOLS,
});
const pendingApproval = useAgentChatPendingApproval(CHAT_ID);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ import { useCallback, useRef } from "react";
import type { ClientToolHandler } from "../hooks/useAgentChat";
import { useAgentBuilderStore } from "./agentBuilderStore";

/**
* The `kind:'client'` tool ids the agent-builder dock can fulfil — sent to the
* runner as `supported_client_tools` at /run so it exposes only these to the
* model. Keep in sync with the handler below plus the built-in toast/get_context.
*/
export const AGENT_BUILDER_CLIENT_TOOLS = [
"set_secret",
"focus_tab",
"focus_file",
"focus_spec_section",
"focus_revision",
"focus_session",
"toast",
"get_context",
] as const;

/**
* The agent builder's UI-driving client tools. The agent calls these to steer the
* user's screen (`focus_*`, which navigate code's agent routes and report back
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface UseAgentChatOptions {
contextProvider?: () => unknown;
/** AgentBuilder UI-driving tools (focus_*, set_secret); null → built-in handling. */
clientTools?: ClientToolHandler;
/** `kind:'client'` tool ids this client can fulfil; sent to the runner at /run. */
supportedClientTools?: readonly string[];
}

/**
Expand All @@ -68,6 +70,7 @@ export function useAgentChat({
recordHistory = false,
contextProvider,
clientTools,
supportedClientTools,
}: UseAgentChatOptions) {
const client = useAuthenticatedClient();
const service = useService<AgentChatService>(AGENT_CHAT_SERVICE);
Expand All @@ -88,6 +91,7 @@ export function useAgentChat({
agentSlug,
ingressBaseUrl: ingressBaseUrl ?? "",
revisionId,
supportedClientTools,
createMapper: createAgentChatMapper,
resolveClientTool: (data) =>
resolveClientTool(
Expand All @@ -113,7 +117,15 @@ export function useAgentChat({
})
: undefined,
}),
[chatId, agentSlug, ingressBaseUrl, revisionId, recordHistory, recordChat],
[
chatId,
agentSlug,
ingressBaseUrl,
revisionId,
supportedClientTools,
recordHistory,
recordChat,
],
);

const send = useCallback(
Expand Down
Loading