Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 621d953

Browse files
authored
refactor(skills): reuse preflight instructions
Generated-By: PostHog Code Task-Id: 73390913-7191-4450-9fd3-31dd12879508
1 parent 144938e commit 621d953

7 files changed

Lines changed: 22 additions & 35 deletions

File tree

packages/core/src/task-detail/taskCreationHost.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import type { ContentBlock } from "@agentclientprotocol/sdk";
22
import type { CloudSkillBundleRef } from "@posthog/core/sessions/cloudArtifactIdentifiers";
3-
import type {
4-
AlwaysOnSkillRef,
5-
Workspace,
6-
WorkspaceInfo,
7-
WorkspaceMode,
8-
} from "@posthog/shared";
3+
import type { Workspace, WorkspaceInfo, WorkspaceMode } from "@posthog/shared";
94
import type { TaskCreationApiClient } from "./taskCreationApiClient";
105

116
export interface CloudPromptTransport {
@@ -108,7 +103,6 @@ export interface ITaskCreationHost {
108103
* too, or a typed `/my-skill` reaches the sandbox with no bundle attached.
109104
*/
110105
resolveLocalSkillCommandPrompt(prompt: string): Promise<string>;
111-
renderAlwaysOnSkillInstructions(skills: AlwaysOnSkillRef[]): Promise<string>;
112106
/**
113107
* Return-and-clear the pre-warmed sandbox lease matching the composer
114108
* selection, if one was provisioned while the user typed. The saga uploads

packages/core/src/task-detail/taskCreationSaga.ts

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,17 @@ function addAlwaysOnSkills(
7474
transport: CloudPromptTransport,
7575
input: TaskCreationInput,
7676
): CloudPromptTransport {
77-
const refs = new Map(
78-
(transport.skillBundles ?? []).map((skill) => [
79-
`${skill.source}:${skill.path}`,
80-
skill,
81-
]),
82-
);
83-
for (const skill of input.alwaysOnSkills ?? []) {
84-
refs.set(`${skill.source}:${skill.path}`, {
77+
const refs = [
78+
...(transport.skillBundles ?? []),
79+
...(input.alwaysOnSkills ?? []).map((skill) => ({
8580
...skill,
8681
alwaysOn: true,
87-
});
88-
}
89-
return { ...transport, skillBundles: [...refs.values()] };
82+
})),
83+
];
84+
const deduplicated = new Map(
85+
refs.map((skill) => [`${skill.source}:${skill.path}`, skill]),
86+
);
87+
return { ...transport, skillBundles: [...deduplicated.values()] };
9088
}
9189

9290
export class TaskCreationSaga extends Saga<
@@ -506,13 +504,6 @@ export class TaskCreationSaga extends Saga<
506504
const shouldConnect = !isCloudCreate && (!!input.taskId || !!agentCwd);
507505

508506
if (shouldConnect) {
509-
const alwaysOnSkillInstructions = input.alwaysOnSkills?.length
510-
? await this.readOnlyStep("resolve_always_on_skills", () =>
511-
this.deps.host.renderAlwaysOnSkillInstructions(
512-
input.alwaysOnSkills ?? [],
513-
),
514-
)
515-
: undefined;
516507
const initialPrompt =
517508
!input.taskId && input.content
518509
? await this.readOnlyStep("build_prompt_blocks", () =>
@@ -550,8 +541,9 @@ export class TaskCreationSaga extends Saga<
550541
if (input.model) connectParams.model = input.model;
551542
if (input.reasoningLevel)
552543
connectParams.reasoningLevel = input.reasoningLevel;
553-
if (alwaysOnSkillInstructions)
554-
connectParams.alwaysOnSkillInstructions = alwaysOnSkillInstructions;
544+
if (input.alwaysOnSkillInstructions)
545+
connectParams.alwaysOnSkillInstructions =
546+
input.alwaysOnSkillInstructions;
555547
if (importedClaude) {
556548
connectParams.importedSessionId = importedClaude.importedSessionId;
557549
connectParams.adapter = "claude";

packages/core/src/task-detail/taskInput.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface PrepareTaskInputOptions {
3434
channelContextId?: string;
3535
customInstructions?: string;
3636
alwaysOnSkills?: TaskCreationInput["alwaysOnSkills"];
37+
alwaysOnSkillInstructions?: string;
3738
autoPublishCloudRuns?: boolean;
3839
rtkEnabledCloud?: boolean;
3940
allowNoRepo?: boolean;
@@ -83,6 +84,7 @@ export function prepareTaskInput(
8384
channelContextId: options.channelContextId,
8485
customInstructions: isCloud ? options.customInstructions : undefined,
8586
alwaysOnSkills: options.alwaysOnSkills,
87+
alwaysOnSkillInstructions: options.alwaysOnSkillInstructions,
8688
allowNoRepo: options.allowNoRepo,
8789
importedMcpServers: isCloud ? options.importedMcpServers : undefined,
8890
relayedMcpServers: isCloud ? options.relayedMcpServers : undefined,

packages/shared/src/task-creation-domain.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export interface TaskCreationInput {
8888
*/
8989
customInstructions?: string;
9090
alwaysOnSkills?: AlwaysOnSkillRef[];
91+
alwaysOnSkillInstructions?: string;
9192
/**
9293
* Local (~/.claude.json) MCP servers classified as importable, forwarded to
9394
* the cloud sandbox in the run-creation payload. Cloud-only; local sessions

packages/ui/src/features/settings/settingsStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export interface SyncedCustomInstructions {
100100
truncated: boolean;
101101
}
102102

103-
export type AlwaysOnSkillPreference = Omit<AlwaysOnSkillRef, "order">;
103+
export type AlwaysOnSkillPreference = AlwaysOnSkillRef;
104104

105105
// ---------- Store shape ----------
106106

packages/ui/src/features/task-detail/hooks/useTaskCreation.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,11 @@ export function useTaskCreation({
320320
const filePaths = extractFilePaths(content);
321321
const settings = useSettingsStore.getState();
322322
let alwaysOnSkills: AlwaysOnSkillRef[] = settings.alwaysOnSkills;
323+
let alwaysOnSkillInstructions: string | undefined;
323324
while (alwaysOnSkills.length > 0) {
324325
try {
325-
await hostClient.skills.renderAlwaysOn.query(alwaysOnSkills);
326+
alwaysOnSkillInstructions =
327+
await hostClient.skills.renderAlwaysOn.query(alwaysOnSkills);
326328
break;
327329
} catch (error) {
328330
const action = await useAlwaysOnSkillsFailureStore
@@ -342,6 +344,7 @@ export function useTaskCreation({
342344
}
343345
}
344346
alwaysOnSkills = [];
347+
alwaysOnSkillInstructions = undefined;
345348
}
346349
}
347350

@@ -410,6 +413,7 @@ export function useTaskCreation({
410413
channelContextId,
411414
customInstructions: getEffectiveCustomInstructions(settings),
412415
alwaysOnSkills,
416+
alwaysOnSkillInstructions,
413417
autoPublishCloudRuns: settings.autoPublishCloudRuns,
414418
rtkEnabledCloud: settings.rtkEnabledCloud,
415419
allowNoRepo,

packages/ui/src/features/task-detail/taskCreationHostImpl.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,6 @@ export class TrpcTaskCreationHost implements ITaskCreationHost {
156156
);
157157
}
158158

159-
renderAlwaysOnSkillInstructions(
160-
skills: Parameters<ITaskCreationHost["renderAlwaysOnSkillInstructions"]>[0],
161-
): Promise<string> {
162-
return hostClient().skills.renderAlwaysOn.query(skills);
163-
}
164-
165159
takeWarmTaskLease(args: {
166160
repository: string;
167161
branch?: string | null;

0 commit comments

Comments
 (0)