{"slug": "pi-ds-anchor-ts", "title": "pi-ds-anchor.ts", "summary": "A developer released pi-ds-anchor.ts, an extension for the Pi coding agent that adds two commands—/new-ds-anchored-session and /ds-anchor—to send a tool-free 'who are you' probe with a minimal system prompt to DeepSeek models. The extension restricts the probe to DeepSeek v4 flash and pro models, rewrites the provider payload to strip tools, and stores anchoring state as a custom session entry for persistence.", "body_md": "| /** | |\n| * DS Anchored Session Extensions | |\n| * | |\n| * Provides two commands that send a single \"who are you\" probe with: | |\n| * - a minimal system prompt (\"You are a helpful software engineer assistant\") | |\n| * - no tools in the provider payload | |\n| * | |\n| * /new-ds-anchored-session | |\n| * Creates a new session, then runs the anchored probe as its first message. | |\n| * | |\n| * /ds-anchor | |\n| * Runs the anchored probe in the current session. Fails if the session | |\n| * already has conversation history or the current model is not supported. | |\n| * | |\n| * The anchoring state is stored as a custom session entry so it survives | |\n| * session persistence; before_provider_request rewrites only the probe turn. | |\n| */ | |\n| import type { | |\n| ExtensionAPI, | |\n| ExtensionCommandContext, | |\n| ExtensionContext, | |\n| SessionEntry, | |\n| } from \"@earendil-works/pi-coding-agent\"; | |\n| const ALLOWED_PROVIDER = \"deepseek\"; | |\n| const ALLOWED_MODEL_IDS = new Set([\"deepseek-v4-flash\", \"deepseek-v4-pro\"]); | |\n| const SINGLE_SYSTEM_PROMPT = \"You are a helpful software engineer assistant\"; | |\n| const ANCHOR_CUSTOM_TYPE = \"ds-anchored-session\"; | |\n| const ANCHOR_WIDGET_ID = \"ds-anchored-session\"; | |\n| interface AnchorState { | |\n| phase: \"anchoring\" | \"done\"; | |\n| } | |\n| interface ModelIdentity { | |\n| provider: string; | |\n| id: string; | |\n| } | |\n| function isAllowedModel(model: ModelIdentity | undefined | null): boolean { | |\n| return ( | |\n| model !== undefined && | |\n| model !== null && | |\n| model.provider === ALLOWED_PROVIDER && | |\n| ALLOWED_MODEL_IDS.has(model.id) | |\n| ); | |\n| } | |\n| function modelLabel(model: ModelIdentity): string { | |\n| return `${model.provider}/${model.id}`; | |\n| } | |\n| function findLatestAnchorEntry(entries: SessionEntry[]): AnchorState | undefined { | |\n| for (let i = entries.length - 1; i >= 0; i--) { | |\n| const entry = entries[i]; | |\n| if (entry.type === \"custom\" && entry.customType === ANCHOR_CUSTOM_TYPE) { | |\n| return entry.data as AnchorState; | |\n| } | |\n| } | |\n| return undefined; | |\n| } | |\n| function hasConversationHistory(entries: SessionEntry[]): boolean { | |\n| return entries.some((entry) => entry.type === \"message\" || entry.type === \"compaction\"); | |\n| } | |\n| function isAnchoring(entries: SessionEntry[]): boolean { | |\n| return findLatestAnchorEntry(entries)?.phase === \"anchoring\"; | |\n| } | |\n| function rewritePayloadForAnchoring(payload: unknown): unknown { | |\n| if (typeof payload !== \"object\" || payload === null) { | |\n| return payload; | |\n| } | |\n| const request = payload as Record<string, unknown>; | |\n| const messages = request.messages; | |\n| if (Array.isArray(messages)) { | |\n| const firstMessage = messages[0] as Record<string, unknown> | undefined; | |\n| if ( | |\n| firstMessage !== undefined && | |\n| (firstMessage.role === \"system\" || firstMessage.role === \"developer\") | |\n| ) { | |\n| firstMessage.content = SINGLE_SYSTEM_PROMPT; | |\n| } else { | |\n| messages.unshift({ role: \"system\", content: SINGLE_SYSTEM_PROMPT }); | |\n| } | |\n| } | |\n| // DeepSeek uses the OpenAI-compatible chat completions format. | |\n| delete request.tools; | |\n| delete request.tool_choice; | |\n| return request; | |\n| } | |\n| export default function (pi: ExtensionAPI) { | |\n| // Set by /new-ds-anchored-session before ctx.newSession() and consumed by | |\n| // the replacement session's session_start handler. Plain module state is | |\n| // safe to carry across the session replacement lifecycle. | |\n| let pendingNewSessionAnchor = false; | |\n| pi.registerCommand(\"ds-anchor\", { | |\n| description: | |\n| \"Send a tool-free 'who are you' probe with a minimal system prompt in the current session\", | |\n| handler: async (_args: string, ctx: ExtensionCommandContext) => { | |\n| if (ctx.model === undefined || !isAllowedModel(ctx.model)) { | |\n| ctx.ui.notify( | |\n| `ds-anchor requires model ${ALLOWED_PROVIDER}/[${[...ALLOWED_MODEL_IDS].join(\", \")}], current: ${ctx.model ? modelLabel(ctx.model) : \"none\"}`, | |\n| \"error\", | |\n| ); | |\n| return; | |\n| } | |\n| if (!ctx.modelRegistry.hasConfiguredAuth(ctx.model)) { | |\n| ctx.ui.notify(`ds-anchor: no API key configured for ${modelLabel(ctx.model)}`, \"error\"); | |\n| return; | |\n| } | |\n| if (hasConversationHistory(ctx.sessionManager.getEntries())) { | |\n| ctx.ui.notify(\"ds-anchor requires a session without conversation history\", \"error\"); | |\n| return; | |\n| } | |\n| pi.appendEntry(ANCHOR_CUSTOM_TYPE, { phase: \"anchoring\" }); | |\n| ctx.ui.setWidget(ANCHOR_WIDGET_ID, [\"Anchoring\"]); | |\n| pi.sendUserMessage(\"who are you\"); | |\n| }, | |\n| }); | |\n| pi.registerCommand(\"new-ds-anchored-session\", { | |\n| description: | |\n| \"Create a new session and send a tool-free 'who are you' probe with a minimal system prompt\", | |\n| handler: async (_args: string, ctx: ExtensionCommandContext) => { | |\n| pendingNewSessionAnchor = true; | |\n| const result = await ctx.newSession({ | |\n| withSession: async (newCtx) => { | |\n| // session_start already wrote the anchoring state when the | |\n| // replacement model is supported; this is the final check. | |\n| if (newCtx.model === undefined || !isAllowedModel(newCtx.model)) { | |\n| newCtx.ui.notify( | |\n| `new-ds-anchored-session requires model ${ALLOWED_PROVIDER}/[${[...ALLOWED_MODEL_IDS].join(\", \")}], current: ${newCtx.model ? modelLabel(newCtx.model) : \"none\"}`, | |\n| \"error\", | |\n| ); | |\n| return; | |\n| } | |\n| if (!newCtx.modelRegistry.hasConfiguredAuth(newCtx.model)) { | |\n| newCtx.ui.notify( | |\n| `new-ds-anchored-session: no API key configured for ${modelLabel(newCtx.model)}`, | |\n| \"error\", | |\n| ); | |\n| return; | |\n| } | |\n| await newCtx.sendUserMessage(\"who are you\"); | |\n| }, | |\n| }); | |\n| if (result.cancelled) { | |\n| pendingNewSessionAnchor = false; | |\n| } | |\n| }, | |\n| }); | |\n| pi.on(\"session_start\", (event, ctx: ExtensionContext) => { | |\n| if (event.reason !== \"new\" || !pendingNewSessionAnchor) { | |\n| return; | |\n| } | |\n| pendingNewSessionAnchor = false; | |\n| // Only write the anchoring state when the replacement session is usable. | |\n| if (ctx.model === undefined || !isAllowedModel(ctx.model)) { | |\n| return; | |\n| } | |\n| if (!ctx.modelRegistry.hasConfiguredAuth(ctx.model)) { | |\n| return; | |\n| } | |\n| pi.appendEntry(ANCHOR_CUSTOM_TYPE, { phase: \"anchoring\" }); | |\n| ctx.ui.setWidget(ANCHOR_WIDGET_ID, [\"Anchoring\"]); | |\n| }); | |\n| pi.on(\"before_provider_request\", (event, ctx: ExtensionContext) => { | |\n| if (!isAnchoring(ctx.sessionManager.getEntries())) { | |\n| return undefined; | |\n| } | |\n| // Safety net: never rewrite payloads for models outside the supported set. | |\n| if (!isAllowedModel(ctx.model)) { | |\n| return undefined; | |\n| } | |\n| return rewritePayloadForAnchoring(event.payload); | |\n| }); | |\n| pi.on(\"agent_settled\", (_event, ctx: ExtensionContext) => { | |\n| if (!isAnchoring(ctx.sessionManager.getEntries())) { | |\n| return; | |\n| } | |\n| pi.appendEntry(ANCHOR_CUSTOM_TYPE, { phase: \"done\" }); | |\n| ctx.ui.setWidget(ANCHOR_WIDGET_ID, [\"Anchored\"]); | |\n| }); | |\n| } |", "url": "https://wpnews.pro/news/pi-ds-anchor-ts", "canonical_source": "https://gist.github.com/LeoDT/185bdd88cf4f65b49fd9caafaef5f0f9", "published_at": "2026-08-16 01:22:25+00:00", "updated_at": "2026-08-16 03:11:09.444324+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools"], "entities": ["DeepSeek", "Pi coding agent"], "alternates": {"html": "https://wpnews.pro/news/pi-ds-anchor-ts", "markdown": "https://wpnews.pro/news/pi-ds-anchor-ts.md", "text": "https://wpnews.pro/news/pi-ds-anchor-ts.txt", "jsonld": "https://wpnews.pro/news/pi-ds-anchor-ts.jsonld"}}