@actant/pi 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createPiAgent
4
- } from "./chunk-SNNF3S5S.js";
4
+ } from "./chunk-UHAWBMJN.js";
5
5
 
6
6
  // src/acp-bridge.ts
7
7
  import { Writable, Readable } from "stream";
@@ -30,7 +30,8 @@ function buildAgentHandler(conn) {
30
30
  workspaceDir: cwd,
31
31
  provider: process.env["ACTANT_PROVIDER"] ?? "anthropic",
32
32
  model: process.env["ACTANT_MODEL"] ?? "claude-sonnet-4-20250514",
33
- apiKey: process.env["ANTHROPIC_API_KEY"] ?? process.env["OPENAI_API_KEY"],
33
+ apiKey: process.env["ACTANT_API_KEY"] ?? process.env["ANTHROPIC_API_KEY"] ?? process.env["OPENAI_API_KEY"],
34
+ baseUrl: process.env["ACTANT_BASE_URL"] ?? void 0,
34
35
  thinkingLevel: process.env["ACTANT_THINKING_LEVEL"] ?? void 0,
35
36
  systemPrompt: "You are a helpful coding assistant. You have access to file and command tools."
36
37
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/acp-bridge.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Writable, Readable } from \"node:stream\";\nimport {\n AgentSideConnection,\n ndJsonStream,\n type Agent as AcpAgent,\n type InitializeResponse,\n type NewSessionResponse,\n type PromptResponse,\n} from \"@agentclientprotocol/sdk\";\nimport { Agent as PiAgent } from \"@mariozechner/pi-agent-core\";\n// @mariozechner/pi-ai imports removed — SDK API drift (#121)\nimport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\ninterface SessionState {\n agent: PiAgent;\n cwd: string;\n abortController: AbortController;\n}\n\nconst sessions = new Map<string, SessionState>();\nlet sessionCounter = 0;\n\nfunction buildAgentHandler(conn: AgentSideConnection): AcpAgent {\n return {\n initialize: async (_params): Promise<InitializeResponse> => {\n return {\n protocolVersion: 1,\n agentCapabilities: {},\n agentInfo: {\n name: \"pi-acp-bridge\",\n version: \"0.1.0\",\n },\n } as InitializeResponse;\n },\n\n newSession: async (params): Promise<NewSessionResponse> => {\n const sessionId = `pi-session-${++sessionCounter}`;\n const cwd = params.cwd ?? process.cwd();\n\n const agentOpts: PiAgentOptions = {\n workspaceDir: cwd,\n provider: process.env[\"ACTANT_PROVIDER\"] ?? \"anthropic\",\n model: process.env[\"ACTANT_MODEL\"] ?? \"claude-sonnet-4-20250514\",\n apiKey: process.env[\"ANTHROPIC_API_KEY\"] ?? process.env[\"OPENAI_API_KEY\"],\n thinkingLevel: (process.env[\"ACTANT_THINKING_LEVEL\"] as PiAgentOptions[\"thinkingLevel\"]) ?? undefined,\n systemPrompt: \"You are a helpful coding assistant. You have access to file and command tools.\",\n };\n\n const agent = createPiAgent(agentOpts);\n sessions.set(sessionId, {\n agent,\n cwd,\n abortController: new AbortController(),\n });\n\n return { sessionId } as NewSessionResponse;\n },\n\n prompt: async (params): Promise<PromptResponse> => {\n const session = sessions.get(params.sessionId);\n if (!session) {\n throw new Error(`Session \"${params.sessionId}\" not found`);\n }\n\n const promptText = params.prompt\n ?.filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? (b as { text: string }).text : \"\"))\n .join(\"\") ?? \"\";\n\n if (!promptText) {\n return { stopReason: \"end_turn\" } as PromptResponse;\n }\n\n session.abortController = new AbortController();\n const { agent } = session;\n\n const unsub = agent.subscribe((event: {\n type: string;\n assistantMessageEvent?: { type?: string; delta?: string };\n toolName?: string;\n message?: { role?: string; content?: unknown };\n }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: event.assistantMessageEvent.delta ?? \"\" },\n },\n } as never).catch(() => {});\n } else if (event.type === \"tool_execution_start\") {\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"tool_call\",\n content: { type: \"text\", text: `[Tool: ${event.toolName ?? \"unknown\"}]` },\n },\n } as never).catch(() => {});\n }\n });\n\n try {\n await agent.prompt(promptText);\n return { stopReason: \"end_turn\" } as PromptResponse;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: `[Error] ${message}` },\n },\n } as never).catch(() => {});\n return { stopReason: \"end_turn\" } as PromptResponse;\n } finally {\n unsub();\n }\n },\n\n cancel: async (params) => {\n const session = sessions.get(params.sessionId);\n if (session) {\n session.agent.abort();\n }\n },\n\n loadSession: async () => ({} as never),\n authenticate: async () => ({}),\n setSessionMode: async () => {},\n setSessionConfigOption: async () => ({} as never),\n };\n}\n\nconst webWritable = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>;\nconst webReadable = Readable.toWeb(process.stdin) as ReadableStream<Uint8Array>;\nconst stream = ndJsonStream(webWritable, webReadable);\n\nnew AgentSideConnection(\n (conn: AgentSideConnection): AcpAgent => buildAgentHandler(conn),\n stream,\n);\n\nprocess.on(\"SIGTERM\", () => {\n for (const session of sessions.values()) {\n session.agent.abort();\n }\n process.exit(0);\n});\n\nprocess.on(\"SIGINT\", () => {\n for (const session of sessions.values()) {\n session.agent.abort();\n }\n process.exit(0);\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/acp-bridge.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Writable, Readable } from \"node:stream\";\nimport {\n AgentSideConnection,\n ndJsonStream,\n type Agent as AcpAgent,\n type InitializeResponse,\n type NewSessionResponse,\n type PromptResponse,\n} from \"@agentclientprotocol/sdk\";\nimport { Agent as PiAgent } from \"@mariozechner/pi-agent-core\";\n// @mariozechner/pi-ai imports removed — SDK API drift (#121)\nimport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\ninterface SessionState {\n agent: PiAgent;\n cwd: string;\n abortController: AbortController;\n}\n\nconst sessions = new Map<string, SessionState>();\nlet sessionCounter = 0;\n\nfunction buildAgentHandler(conn: AgentSideConnection): AcpAgent {\n return {\n initialize: async (_params): Promise<InitializeResponse> => {\n return {\n protocolVersion: 1,\n agentCapabilities: {},\n agentInfo: {\n name: \"pi-acp-bridge\",\n version: \"0.1.0\",\n },\n } as InitializeResponse;\n },\n\n newSession: async (params): Promise<NewSessionResponse> => {\n const sessionId = `pi-session-${++sessionCounter}`;\n const cwd = params.cwd ?? process.cwd();\n\n const agentOpts: PiAgentOptions = {\n workspaceDir: cwd,\n provider: process.env[\"ACTANT_PROVIDER\"] ?? \"anthropic\",\n model: process.env[\"ACTANT_MODEL\"] ?? \"claude-sonnet-4-20250514\",\n apiKey: process.env[\"ACTANT_API_KEY\"] ?? process.env[\"ANTHROPIC_API_KEY\"] ?? process.env[\"OPENAI_API_KEY\"],\n baseUrl: process.env[\"ACTANT_BASE_URL\"] ?? undefined,\n thinkingLevel: (process.env[\"ACTANT_THINKING_LEVEL\"] as PiAgentOptions[\"thinkingLevel\"]) ?? undefined,\n systemPrompt: \"You are a helpful coding assistant. You have access to file and command tools.\",\n };\n\n const agent = createPiAgent(agentOpts);\n sessions.set(sessionId, {\n agent,\n cwd,\n abortController: new AbortController(),\n });\n\n return { sessionId } as NewSessionResponse;\n },\n\n prompt: async (params): Promise<PromptResponse> => {\n const session = sessions.get(params.sessionId);\n if (!session) {\n throw new Error(`Session \"${params.sessionId}\" not found`);\n }\n\n const promptText = params.prompt\n ?.filter((b) => b.type === \"text\")\n .map((b) => (\"text\" in b ? (b as { text: string }).text : \"\"))\n .join(\"\") ?? \"\";\n\n if (!promptText) {\n return { stopReason: \"end_turn\" } as PromptResponse;\n }\n\n session.abortController = new AbortController();\n const { agent } = session;\n\n const unsub = agent.subscribe((event: {\n type: string;\n assistantMessageEvent?: { type?: string; delta?: string };\n toolName?: string;\n message?: { role?: string; content?: unknown };\n }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: event.assistantMessageEvent.delta ?? \"\" },\n },\n } as never).catch(() => {});\n } else if (event.type === \"tool_execution_start\") {\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"tool_call\",\n content: { type: \"text\", text: `[Tool: ${event.toolName ?? \"unknown\"}]` },\n },\n } as never).catch(() => {});\n }\n });\n\n try {\n await agent.prompt(promptText);\n return { stopReason: \"end_turn\" } as PromptResponse;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n conn.sessionUpdate({\n sessionId: params.sessionId,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: `[Error] ${message}` },\n },\n } as never).catch(() => {});\n return { stopReason: \"end_turn\" } as PromptResponse;\n } finally {\n unsub();\n }\n },\n\n cancel: async (params) => {\n const session = sessions.get(params.sessionId);\n if (session) {\n session.agent.abort();\n }\n },\n\n loadSession: async () => ({} as never),\n authenticate: async () => ({}),\n setSessionMode: async () => {},\n setSessionConfigOption: async () => ({} as never),\n };\n}\n\nconst webWritable = Writable.toWeb(process.stdout) as WritableStream<Uint8Array>;\nconst webReadable = Readable.toWeb(process.stdin) as ReadableStream<Uint8Array>;\nconst stream = ndJsonStream(webWritable, webReadable);\n\nnew AgentSideConnection(\n (conn: AgentSideConnection): AcpAgent => buildAgentHandler(conn),\n stream,\n);\n\nprocess.on(\"SIGTERM\", () => {\n for (const session of sessions.values()) {\n session.agent.abort();\n }\n process.exit(0);\n});\n\nprocess.on(\"SIGINT\", () => {\n for (const session of sessions.values()) {\n session.agent.abort();\n }\n process.exit(0);\n});\n"],"mappings":";;;;;;AAEA,SAAS,UAAU,gBAAgB;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AAWP,IAAM,WAAW,oBAAI,IAA0B;AAC/C,IAAI,iBAAiB;AAErB,SAAS,kBAAkB,MAAqC;AAC9D,SAAO;AAAA,IACL,YAAY,OAAO,YAAyC;AAC1D,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,mBAAmB,CAAC;AAAA,QACpB,WAAW;AAAA,UACT,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,IAEA,YAAY,OAAO,WAAwC;AACzD,YAAM,YAAY,cAAc,EAAE,cAAc;AAChD,YAAM,MAAM,OAAO,OAAO,QAAQ,IAAI;AAEtC,YAAM,YAA4B;AAAA,QAChC,cAAc;AAAA,QACd,UAAU,QAAQ,IAAI,iBAAiB,KAAK;AAAA,QAC5C,OAAO,QAAQ,IAAI,cAAc,KAAK;AAAA,QACtC,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,QAAQ,IAAI,mBAAmB,KAAK,QAAQ,IAAI,gBAAgB;AAAA,QACzG,SAAS,QAAQ,IAAI,iBAAiB,KAAK;AAAA,QAC3C,eAAgB,QAAQ,IAAI,uBAAuB,KAAyC;AAAA,QAC5F,cAAc;AAAA,MAChB;AAEA,YAAM,QAAQ,cAAc,SAAS;AACrC,eAAS,IAAI,WAAW;AAAA,QACtB;AAAA,QACA;AAAA,QACA,iBAAiB,IAAI,gBAAgB;AAAA,MACvC,CAAC;AAED,aAAO,EAAE,UAAU;AAAA,IACrB;AAAA,IAEA,QAAQ,OAAO,WAAoC;AACjD,YAAM,UAAU,SAAS,IAAI,OAAO,SAAS;AAC7C,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,YAAY,OAAO,SAAS,aAAa;AAAA,MAC3D;AAEA,YAAM,aAAa,OAAO,QACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAChC,IAAI,CAAC,MAAO,UAAU,IAAK,EAAuB,OAAO,EAAG,EAC5D,KAAK,EAAE,KAAK;AAEf,UAAI,CAAC,YAAY;AACf,eAAO,EAAE,YAAY,WAAW;AAAA,MAClC;AAEA,cAAQ,kBAAkB,IAAI,gBAAgB;AAC9C,YAAM,EAAE,MAAM,IAAI;AAElB,YAAM,QAAQ,MAAM,UAAU,CAAC,UAKzB;AACJ,YAAI,MAAM,SAAS,oBAAoB,MAAM,uBAAuB,SAAS,cAAc;AACzF,eAAK,cAAc;AAAA,YACjB,WAAW,OAAO;AAAA,YAClB,QAAQ;AAAA,cACN,eAAe;AAAA,cACf,SAAS,EAAE,MAAM,QAAQ,MAAM,MAAM,sBAAsB,SAAS,GAAG;AAAA,YACzE;AAAA,UACF,CAAU,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QAC5B,WAAW,MAAM,SAAS,wBAAwB;AAChD,eAAK,cAAc;AAAA,YACjB,WAAW,OAAO;AAAA,YAClB,QAAQ;AAAA,cACN,eAAe;AAAA,cACf,SAAS,EAAE,MAAM,QAAQ,MAAM,UAAU,MAAM,YAAY,SAAS,IAAI;AAAA,YAC1E;AAAA,UACF,CAAU,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAAA,QAC5B;AAAA,MACF,CAAC;AAED,UAAI;AACF,cAAM,MAAM,OAAO,UAAU;AAC7B,eAAO,EAAE,YAAY,WAAW;AAAA,MAClC,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,aAAK,cAAc;AAAA,UACjB,WAAW,OAAO;AAAA,UAClB,QAAQ;AAAA,YACN,eAAe;AAAA,YACf,SAAS,EAAE,MAAM,QAAQ,MAAM,WAAW,OAAO,GAAG;AAAA,UACtD;AAAA,QACF,CAAU,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAC1B,eAAO,EAAE,YAAY,WAAW;AAAA,MAClC,UAAE;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,QAAQ,OAAO,WAAW;AACxB,YAAM,UAAU,SAAS,IAAI,OAAO,SAAS;AAC7C,UAAI,SAAS;AACX,gBAAQ,MAAM,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,aAAa,aAAa,CAAC;AAAA,IAC3B,cAAc,aAAa,CAAC;AAAA,IAC5B,gBAAgB,YAAY;AAAA,IAAC;AAAA,IAC7B,wBAAwB,aAAa,CAAC;AAAA,EACxC;AACF;AAEA,IAAM,cAAc,SAAS,MAAM,QAAQ,MAAM;AACjD,IAAM,cAAc,SAAS,MAAM,QAAQ,KAAK;AAChD,IAAM,SAAS,aAAa,aAAa,WAAW;AAEpD,IAAI;AAAA,EACF,CAAC,SAAwC,kBAAkB,IAAI;AAAA,EAC/D;AACF;AAEA,QAAQ,GAAG,WAAW,MAAM;AAC1B,aAAW,WAAW,SAAS,OAAO,GAAG;AACvC,YAAQ,MAAM,MAAM;AAAA,EACtB;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;AAED,QAAQ,GAAG,UAAU,MAAM;AACzB,aAAW,WAAW,SAAS,OAAO,GAAG;AACvC,YAAQ,MAAM,MAAM;AAAA,EACtB;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -122,4 +122,4 @@ function createPiAgent(options) {
122
122
  export {
123
123
  createPiAgent
124
124
  };
125
- //# sourceMappingURL=chunk-SNNF3S5S.js.map
125
+ //# sourceMappingURL=chunk-UHAWBMJN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pi-tool-bridge.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { readFile, writeFile, readdir } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Agent, type AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { getModel, Type } from \"@mariozechner/pi-ai\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface PiAgentOptions {\n workspaceDir: string;\n provider?: string;\n model?: string;\n apiKey?: string;\n /** Provider base URL (reserved for future use with custom endpoints). */\n baseUrl?: string;\n thinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n tools?: string[];\n systemPrompt?: string;\n}\n\nconst ALL_TOOLS = [\"read_file\", \"write_file\", \"list_directory\", \"run_command\"] as const;\n\nfunction resolvePath(workspaceDir: string, path: string): string {\n const abs = resolve(workspaceDir, path);\n const base = resolve(workspaceDir);\n if (!abs.startsWith(base)) {\n throw new Error(`Path \"${path}\" resolves outside workspace`);\n }\n return abs;\n}\n\nfunction buildTools(workspaceDir: string, toolNames?: string[]): AgentTool[] {\n const enabled = toolNames && toolNames.length > 0 ? toolNames : [...ALL_TOOLS];\n const tools: AgentTool[] = [];\n\n if (enabled.includes(\"read_file\")) {\n tools.push({\n name: \"read_file\",\n label: \"Read File\",\n description: \"Read the contents of a file. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"File path relative to workspace\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path } = params as { path: string };\n const absPath = resolvePath(workspaceDir, path);\n const content = await readFile(absPath, \"utf-8\");\n return { content: [{ type: \"text\" as const, text: content }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"write_file\")) {\n tools.push({\n name: \"write_file\",\n label: \"Write File\",\n description: \"Write content to a file. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"File path relative to workspace\" }),\n content: Type.String({ description: \"Content to write\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path, content } = params as { path: string; content: string };\n const absPath = resolvePath(workspaceDir, path);\n await writeFile(absPath, content, \"utf-8\");\n return { content: [{ type: \"text\" as const, text: `Wrote ${path}` }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"list_directory\")) {\n tools.push({\n name: \"list_directory\",\n label: \"List Directory\",\n description: \"List files and directories. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"Directory path relative to workspace\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path } = params as { path: string };\n const absPath = resolvePath(workspaceDir, path);\n const entries = await readdir(absPath, { withFileTypes: true });\n const lines = entries.map((e) => (e.isDirectory() ? `${e.name}/` : e.name));\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"run_command\")) {\n tools.push({\n name: \"run_command\",\n label: \"Run Command\",\n description: \"Execute a shell command. command is the executable, args are the arguments.\",\n parameters: Type.Object({\n command: Type.String({ description: \"Executable to run\" }),\n args: Type.Optional(Type.Array(Type.String(), { description: \"Command arguments\" })),\n }),\n execute: (async (_toolCallId, params, signal) => {\n const { command, args: argList } = params as { command: string; args?: string[] };\n const args = argList ?? [];\n const { stdout, stderr } = await execFileAsync(\n command,\n args,\n { cwd: workspaceDir, signal, encoding: \"utf-8\" },\n );\n const out = [stdout, stderr].filter(Boolean).join(\"\\n\").trim() || \"(no output)\";\n return { content: [{ type: \"text\" as const, text: out }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n return tools;\n}\n\nexport function createPiAgent(options: PiAgentOptions): Agent {\n const {\n workspaceDir,\n provider = \"anthropic\",\n model = \"claude-sonnet-4-20250514\",\n apiKey,\n thinkingLevel,\n tools: toolNames,\n systemPrompt = \"You are a helpful coding assistant. You have access to file and command tools.\",\n } = options;\n\n const modelInstance = getModel(provider as never, model);\n\n const agentOptions: Record<string, unknown> = {\n initialState: {\n systemPrompt,\n model: modelInstance,\n tools: buildTools(workspaceDir, toolNames),\n },\n };\n\n if (thinkingLevel) {\n (agentOptions.initialState as Record<string, unknown>).thinkingLevel = thinkingLevel;\n }\n\n if (apiKey) {\n agentOptions.getApiKey = async () => apiKey;\n }\n\n return new Agent(agentOptions as ConstructorParameters<typeof Agent>[0]);\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -39,6 +39,8 @@ interface PiAgentOptions {
39
39
  provider?: string;
40
40
  model?: string;
41
41
  apiKey?: string;
42
+ /** Provider base URL (reserved for future use with custom endpoints). */
43
+ baseUrl?: string;
42
44
  thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
43
45
  tools?: string[];
44
46
  systemPrompt?: string;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPiAgent
3
- } from "./chunk-SNNF3S5S.js";
3
+ } from "./chunk-UHAWBMJN.js";
4
4
 
5
5
  // src/index.ts
6
6
  import { fileURLToPath } from "url";
@@ -110,7 +110,7 @@ function configFromBackend(backendConfig) {
110
110
  return {
111
111
  provider: asString(backendConfig?.["provider"]) ?? process.env["ACTANT_PROVIDER"],
112
112
  model: asString(backendConfig?.["model"]) ?? process.env["ACTANT_MODEL"],
113
- apiKey: asString(backendConfig?.["apiKey"]),
113
+ apiKey: asString(backendConfig?.["apiKey"]) ?? process.env["ACTANT_API_KEY"],
114
114
  thinkingLevel: asString(backendConfig?.["thinkingLevel"]) ?? process.env["ACTANT_THINKING_LEVEL"],
115
115
  tools: Array.isArray(backendConfig?.["tools"]) ? backendConfig["tools"] : void 0
116
116
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/pi-builder.ts","../src/pi-communicator.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nexport { PiBuilder } from \"./pi-builder\";\nexport { PiCommunicator, configFromBackend, type PiCommunicatorConfig } from \"./pi-communicator\";\nexport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\nexport const ACP_BRIDGE_PATH = join(dirname(fileURLToPath(import.meta.url)), \"acp-bridge.js\");\n","import { writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n SkillDefinition,\n PromptDefinition,\n McpServerDefinition,\n WorkflowDefinition,\n PluginDefinition,\n PermissionsInput,\n} from \"@actant/shared\";\nimport { createLogger } from \"@actant/shared\";\nimport { resolvePermissions } from \"@actant/core\";\nimport type { BackendBuilder, VerifyResult } from \"@actant/core\";\n\nconst logger = createLogger(\"pi-builder\");\n\nexport class PiBuilder implements BackendBuilder {\n readonly backendType = \"pi\" as const;\n\n async scaffold(workspaceDir: string): Promise<void> {\n await mkdir(join(workspaceDir, \".pi\", \"skills\"), { recursive: true });\n await mkdir(join(workspaceDir, \".pi\", \"prompts\"), { recursive: true });\n await writeFile(join(workspaceDir, \"AGENTS.md\"), \"# Agent Skills\\n\", \"utf-8\");\n }\n\n async materializeSkills(workspaceDir: string, skills: SkillDefinition[]): Promise<void> {\n const skillsDir = join(workspaceDir, \".pi\", \"skills\");\n await mkdir(skillsDir, { recursive: true });\n const sections = skills.map((s) => {\n const header = `## ${s.name}`;\n const desc = s.description ? `\\n> ${s.description}\\n` : \"\";\n return `${header}${desc}\\n${s.content}`;\n });\n const agentsContent = `# Agent Skills\\n\\n${sections.join(\"\\n\\n---\\n\\n\")}\\n`;\n await writeFile(join(workspaceDir, \"AGENTS.md\"), agentsContent, \"utf-8\");\n for (const skill of skills) {\n const fileName = `${skill.name.replace(/[/\\\\]/g, \"-\")}.md`;\n const content = [\n skill.description ? `> ${skill.description}\\n` : \"\",\n skill.content,\n \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n await writeFile(join(skillsDir, fileName), content, \"utf-8\");\n }\n logger.debug({ workspaceDir, count: skills.length }, \"Skills materialized\");\n }\n\n async materializePrompts(workspaceDir: string, prompts: PromptDefinition[]): Promise<void> {\n const promptsDir = join(workspaceDir, \".pi\", \"prompts\");\n await mkdir(promptsDir, { recursive: true });\n for (const p of prompts) {\n const fileName = `${p.name.replace(/[/\\\\]/g, \"-\")}.md`;\n const lines = p.description ? [`> ${p.description}\\n`, p.content] : [p.content];\n await writeFile(join(promptsDir, fileName), lines.join(\"\\n\") + \"\\n\", \"utf-8\");\n }\n }\n\n async materializeMcpConfig(\n _workspaceDir: string,\n servers: McpServerDefinition[],\n ): Promise<void> {\n if (servers.length > 0) {\n logger.warn(\n { serverCount: servers.length },\n \"Pi does not support MCP; MCP config will be skipped\",\n );\n }\n }\n\n async materializePlugins(\n _workspaceDir: string,\n _plugins: PluginDefinition[],\n ): Promise<void> {}\n\n async materializeWorkflow(workspaceDir: string, workflow: WorkflowDefinition): Promise<void> {\n const trellisDir = join(workspaceDir, \".trellis\");\n await mkdir(trellisDir, { recursive: true });\n await writeFile(join(trellisDir, \"workflow.md\"), workflow.content + \"\\n\", \"utf-8\");\n }\n\n async injectPermissions(\n workspaceDir: string,\n _servers: McpServerDefinition[],\n permissions?: PermissionsInput,\n ): Promise<void> {\n if (!permissions) return;\n const resolved = resolvePermissions(permissions);\n const tools = resolved.allow ?? [];\n if (tools.length === 0) return;\n\n const piDir = join(workspaceDir, \".pi\");\n await mkdir(piDir, { recursive: true });\n const settings: { tools: string[] } = { tools };\n await writeFile(\n join(piDir, \"settings.json\"),\n JSON.stringify(settings, null, 2) + \"\\n\",\n \"utf-8\",\n );\n }\n\n async verify(workspaceDir: string): Promise<VerifyResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n try {\n const s = await stat(join(workspaceDir, \"AGENTS.md\"));\n if (!s.isFile()) {\n errors.push(\"Expected file: AGENTS.md\");\n }\n } catch {\n errors.push(\"Missing: AGENTS.md\");\n }\n\n return { valid: errors.length === 0, errors, warnings };\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AgentCommunicator,\n PromptResult,\n RunPromptOptions,\n StreamChunk,\n} from \"@actant/core\";\nimport { createLogger } from \"@actant/shared\";\nimport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\nconst logger = createLogger(\"pi-communicator\");\n\nexport interface PiCommunicatorConfig {\n provider?: string;\n model?: string;\n apiKey?: string;\n thinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n tools?: string[];\n}\n\n/**\n * Extract PiCommunicatorConfig from a template's backend.config record.\n * Falls back to ACTANT_* environment variables, then to pi-ai built-in env resolution.\n */\nexport function configFromBackend(backendConfig?: Record<string, unknown>): PiCommunicatorConfig {\n return {\n provider: asString(backendConfig?.[\"provider\"]) ?? process.env[\"ACTANT_PROVIDER\"],\n model: asString(backendConfig?.[\"model\"]) ?? process.env[\"ACTANT_MODEL\"],\n apiKey: asString(backendConfig?.[\"apiKey\"]),\n thinkingLevel: asString(backendConfig?.[\"thinkingLevel\"]) as PiCommunicatorConfig[\"thinkingLevel\"] ?? (process.env[\"ACTANT_THINKING_LEVEL\"] as PiCommunicatorConfig[\"thinkingLevel\"]),\n tools: Array.isArray(backendConfig?.[\"tools\"]) ? (backendConfig[\"tools\"] as string[]) : undefined,\n };\n}\n\nfunction asString(v: unknown): string | undefined {\n return typeof v === \"string\" && v.length > 0 ? v : undefined;\n}\n\nexport class PiCommunicator implements AgentCommunicator {\n private readonly config: PiCommunicatorConfig;\n\n constructor(config: PiCommunicatorConfig = {}) {\n this.config = config;\n }\n\n async runPrompt(\n workspaceDir: string,\n prompt: string,\n options?: RunPromptOptions,\n ): Promise<PromptResult> {\n logger.debug({ workspaceDir }, \"Running Pi prompt\");\n const agent = await this.buildAgent(workspaceDir, options);\n let text = \"\";\n\n const unsub = agent.subscribe((event: { type: string; assistantMessageEvent?: { type?: string; delta?: string } }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n text += event.assistantMessageEvent.delta ?? \"\";\n }\n });\n\n try {\n await agent.prompt(prompt);\n const messages = agent.state.messages;\n const last = messages[messages.length - 1];\n if (last?.role === \"assistant\" && last.content) {\n const fullText = last.content\n .filter((b): b is { type: \"text\"; text: string } => \"type\" in b && b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n text = fullText || text;\n }\n return { text, sessionId: agent.sessionId };\n } finally {\n unsub();\n }\n }\n\n async *streamPrompt(\n workspaceDir: string,\n prompt: string,\n options?: RunPromptOptions,\n ): AsyncIterable<StreamChunk> {\n logger.debug({ workspaceDir }, \"Streaming Pi prompt\");\n const agent = await this.buildAgent(workspaceDir, options);\n const queue: StreamChunk[] = [];\n let resolve: (() => void) | null = null;\n let done = false;\n let promptError: Error | null = null;\n\n const unsub = agent.subscribe((event: {\n type: string;\n assistantMessageEvent?: { type?: string; delta?: string };\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n result?: { content?: Array<{ text?: string }> };\n }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n queue.push({ type: \"text\", content: event.assistantMessageEvent.delta ?? \"\" });\n } else if (event.type === \"tool_execution_start\") {\n const content = event.toolName\n ? `[Tool: ${event.toolName}] ${JSON.stringify(event.args ?? {})}`\n : \"\";\n queue.push({ type: \"tool_use\", content });\n } else if (event.type === \"tool_execution_end\") {\n const parts = event.result?.content ?? [];\n const text = parts\n .filter((p) => p.text)\n .map((p) => p.text)\n .join(\"\");\n queue.push({ type: \"result\", content: text });\n } else if (event.type === \"agent_end\") {\n done = true;\n }\n if (resolve) {\n resolve();\n resolve = null;\n }\n });\n\n const promptPromise = agent\n .prompt(prompt)\n .then(() => {\n done = true;\n if (resolve) {\n resolve();\n resolve = null;\n }\n })\n .catch((err: unknown) => {\n promptError = err instanceof Error ? err : new Error(String(err));\n queue.push({ type: \"error\", content: promptError.message });\n done = true;\n if (resolve) {\n resolve();\n resolve = null;\n }\n });\n\n try {\n while (!done || queue.length > 0) {\n if (queue.length > 0) {\n yield queue.shift() as StreamChunk;\n } else {\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n await promptPromise;\n if (promptError) throw promptError;\n } finally {\n unsub();\n }\n }\n\n private async buildAgent(\n workspaceDir: string,\n options?: RunPromptOptions,\n ): Promise<ReturnType<typeof createPiAgent>> {\n let systemPrompt =\n \"You are a helpful coding assistant. You have access to file and command tools.\";\n\n if (options?.systemPromptFile) {\n const path = join(workspaceDir, options.systemPromptFile);\n systemPrompt = await readFile(path, \"utf-8\");\n }\n if (options?.appendSystemPrompt) {\n systemPrompt += \"\\n\\n\" + options.appendSystemPrompt;\n }\n\n const opts: PiAgentOptions = {\n workspaceDir,\n provider: this.config.provider,\n model: options?.model ?? this.config.model,\n apiKey: this.config.apiKey,\n thinkingLevel: this.config.thinkingLevel,\n tools: this.config.tools,\n systemPrompt,\n };\n\n const agent = createPiAgent(opts);\n if (options?.sessionId) {\n agent.sessionId = options.sessionId;\n }\n return agent;\n }\n}\n"],"mappings":"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","names":["join","join","createLogger","logger","createLogger","join","join"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/pi-builder.ts","../src/pi-communicator.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nexport { PiBuilder } from \"./pi-builder\";\nexport { PiCommunicator, configFromBackend, type PiCommunicatorConfig } from \"./pi-communicator\";\nexport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\nexport const ACP_BRIDGE_PATH = join(dirname(fileURLToPath(import.meta.url)), \"acp-bridge.js\");\n","import { writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n SkillDefinition,\n PromptDefinition,\n McpServerDefinition,\n WorkflowDefinition,\n PluginDefinition,\n PermissionsInput,\n} from \"@actant/shared\";\nimport { createLogger } from \"@actant/shared\";\nimport { resolvePermissions } from \"@actant/core\";\nimport type { BackendBuilder, VerifyResult } from \"@actant/core\";\n\nconst logger = createLogger(\"pi-builder\");\n\nexport class PiBuilder implements BackendBuilder {\n readonly backendType = \"pi\" as const;\n\n async scaffold(workspaceDir: string): Promise<void> {\n await mkdir(join(workspaceDir, \".pi\", \"skills\"), { recursive: true });\n await mkdir(join(workspaceDir, \".pi\", \"prompts\"), { recursive: true });\n await writeFile(join(workspaceDir, \"AGENTS.md\"), \"# Agent Skills\\n\", \"utf-8\");\n }\n\n async materializeSkills(workspaceDir: string, skills: SkillDefinition[]): Promise<void> {\n const skillsDir = join(workspaceDir, \".pi\", \"skills\");\n await mkdir(skillsDir, { recursive: true });\n const sections = skills.map((s) => {\n const header = `## ${s.name}`;\n const desc = s.description ? `\\n> ${s.description}\\n` : \"\";\n return `${header}${desc}\\n${s.content}`;\n });\n const agentsContent = `# Agent Skills\\n\\n${sections.join(\"\\n\\n---\\n\\n\")}\\n`;\n await writeFile(join(workspaceDir, \"AGENTS.md\"), agentsContent, \"utf-8\");\n for (const skill of skills) {\n const fileName = `${skill.name.replace(/[/\\\\]/g, \"-\")}.md`;\n const content = [\n skill.description ? `> ${skill.description}\\n` : \"\",\n skill.content,\n \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n await writeFile(join(skillsDir, fileName), content, \"utf-8\");\n }\n logger.debug({ workspaceDir, count: skills.length }, \"Skills materialized\");\n }\n\n async materializePrompts(workspaceDir: string, prompts: PromptDefinition[]): Promise<void> {\n const promptsDir = join(workspaceDir, \".pi\", \"prompts\");\n await mkdir(promptsDir, { recursive: true });\n for (const p of prompts) {\n const fileName = `${p.name.replace(/[/\\\\]/g, \"-\")}.md`;\n const lines = p.description ? [`> ${p.description}\\n`, p.content] : [p.content];\n await writeFile(join(promptsDir, fileName), lines.join(\"\\n\") + \"\\n\", \"utf-8\");\n }\n }\n\n async materializeMcpConfig(\n _workspaceDir: string,\n servers: McpServerDefinition[],\n ): Promise<void> {\n if (servers.length > 0) {\n logger.warn(\n { serverCount: servers.length },\n \"Pi does not support MCP; MCP config will be skipped\",\n );\n }\n }\n\n async materializePlugins(\n _workspaceDir: string,\n _plugins: PluginDefinition[],\n ): Promise<void> {}\n\n async materializeWorkflow(workspaceDir: string, workflow: WorkflowDefinition): Promise<void> {\n const trellisDir = join(workspaceDir, \".trellis\");\n await mkdir(trellisDir, { recursive: true });\n await writeFile(join(trellisDir, \"workflow.md\"), workflow.content + \"\\n\", \"utf-8\");\n }\n\n async injectPermissions(\n workspaceDir: string,\n _servers: McpServerDefinition[],\n permissions?: PermissionsInput,\n ): Promise<void> {\n if (!permissions) return;\n const resolved = resolvePermissions(permissions);\n const tools = resolved.allow ?? [];\n if (tools.length === 0) return;\n\n const piDir = join(workspaceDir, \".pi\");\n await mkdir(piDir, { recursive: true });\n const settings: { tools: string[] } = { tools };\n await writeFile(\n join(piDir, \"settings.json\"),\n JSON.stringify(settings, null, 2) + \"\\n\",\n \"utf-8\",\n );\n }\n\n async verify(workspaceDir: string): Promise<VerifyResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n try {\n const s = await stat(join(workspaceDir, \"AGENTS.md\"));\n if (!s.isFile()) {\n errors.push(\"Expected file: AGENTS.md\");\n }\n } catch {\n errors.push(\"Missing: AGENTS.md\");\n }\n\n return { valid: errors.length === 0, errors, warnings };\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n AgentCommunicator,\n PromptResult,\n RunPromptOptions,\n StreamChunk,\n} from \"@actant/core\";\nimport { createLogger } from \"@actant/shared\";\nimport { createPiAgent, type PiAgentOptions } from \"./pi-tool-bridge\";\n\nconst logger = createLogger(\"pi-communicator\");\n\nexport interface PiCommunicatorConfig {\n provider?: string;\n model?: string;\n apiKey?: string;\n thinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n tools?: string[];\n}\n\n/**\n * Extract PiCommunicatorConfig from a template's backend.config record.\n * Falls back to ACTANT_* environment variables, then to pi-ai built-in env resolution.\n */\nexport function configFromBackend(backendConfig?: Record<string, unknown>): PiCommunicatorConfig {\n return {\n provider: asString(backendConfig?.[\"provider\"]) ?? process.env[\"ACTANT_PROVIDER\"],\n model: asString(backendConfig?.[\"model\"]) ?? process.env[\"ACTANT_MODEL\"],\n apiKey: asString(backendConfig?.[\"apiKey\"]) ?? process.env[\"ACTANT_API_KEY\"],\n thinkingLevel: asString(backendConfig?.[\"thinkingLevel\"]) as PiCommunicatorConfig[\"thinkingLevel\"] ?? (process.env[\"ACTANT_THINKING_LEVEL\"] as PiCommunicatorConfig[\"thinkingLevel\"]),\n tools: Array.isArray(backendConfig?.[\"tools\"]) ? (backendConfig[\"tools\"] as string[]) : undefined,\n };\n}\n\nfunction asString(v: unknown): string | undefined {\n return typeof v === \"string\" && v.length > 0 ? v : undefined;\n}\n\nexport class PiCommunicator implements AgentCommunicator {\n private readonly config: PiCommunicatorConfig;\n\n constructor(config: PiCommunicatorConfig = {}) {\n this.config = config;\n }\n\n async runPrompt(\n workspaceDir: string,\n prompt: string,\n options?: RunPromptOptions,\n ): Promise<PromptResult> {\n logger.debug({ workspaceDir }, \"Running Pi prompt\");\n const agent = await this.buildAgent(workspaceDir, options);\n let text = \"\";\n\n const unsub = agent.subscribe((event: { type: string; assistantMessageEvent?: { type?: string; delta?: string } }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n text += event.assistantMessageEvent.delta ?? \"\";\n }\n });\n\n try {\n await agent.prompt(prompt);\n const messages = agent.state.messages;\n const last = messages[messages.length - 1];\n if (last?.role === \"assistant\" && last.content) {\n const fullText = last.content\n .filter((b): b is { type: \"text\"; text: string } => \"type\" in b && b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\");\n text = fullText || text;\n }\n return { text, sessionId: agent.sessionId };\n } finally {\n unsub();\n }\n }\n\n async *streamPrompt(\n workspaceDir: string,\n prompt: string,\n options?: RunPromptOptions,\n ): AsyncIterable<StreamChunk> {\n logger.debug({ workspaceDir }, \"Streaming Pi prompt\");\n const agent = await this.buildAgent(workspaceDir, options);\n const queue: StreamChunk[] = [];\n let resolve: (() => void) | null = null;\n let done = false;\n let promptError: Error | null = null;\n\n const unsub = agent.subscribe((event: {\n type: string;\n assistantMessageEvent?: { type?: string; delta?: string };\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n result?: { content?: Array<{ text?: string }> };\n }) => {\n if (event.type === \"message_update\" && event.assistantMessageEvent?.type === \"text_delta\") {\n queue.push({ type: \"text\", content: event.assistantMessageEvent.delta ?? \"\" });\n } else if (event.type === \"tool_execution_start\") {\n const content = event.toolName\n ? `[Tool: ${event.toolName}] ${JSON.stringify(event.args ?? {})}`\n : \"\";\n queue.push({ type: \"tool_use\", content });\n } else if (event.type === \"tool_execution_end\") {\n const parts = event.result?.content ?? [];\n const text = parts\n .filter((p) => p.text)\n .map((p) => p.text)\n .join(\"\");\n queue.push({ type: \"result\", content: text });\n } else if (event.type === \"agent_end\") {\n done = true;\n }\n if (resolve) {\n resolve();\n resolve = null;\n }\n });\n\n const promptPromise = agent\n .prompt(prompt)\n .then(() => {\n done = true;\n if (resolve) {\n resolve();\n resolve = null;\n }\n })\n .catch((err: unknown) => {\n promptError = err instanceof Error ? err : new Error(String(err));\n queue.push({ type: \"error\", content: promptError.message });\n done = true;\n if (resolve) {\n resolve();\n resolve = null;\n }\n });\n\n try {\n while (!done || queue.length > 0) {\n if (queue.length > 0) {\n yield queue.shift() as StreamChunk;\n } else {\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n }\n await promptPromise;\n if (promptError) throw promptError;\n } finally {\n unsub();\n }\n }\n\n private async buildAgent(\n workspaceDir: string,\n options?: RunPromptOptions,\n ): Promise<ReturnType<typeof createPiAgent>> {\n let systemPrompt =\n \"You are a helpful coding assistant. You have access to file and command tools.\";\n\n if (options?.systemPromptFile) {\n const path = join(workspaceDir, options.systemPromptFile);\n systemPrompt = await readFile(path, \"utf-8\");\n }\n if (options?.appendSystemPrompt) {\n systemPrompt += \"\\n\\n\" + options.appendSystemPrompt;\n }\n\n const opts: PiAgentOptions = {\n workspaceDir,\n provider: this.config.provider,\n model: options?.model ?? this.config.model,\n apiKey: this.config.apiKey,\n thinkingLevel: this.config.thinkingLevel,\n tools: this.config.tools,\n systemPrompt,\n };\n\n const agent = createPiAgent(opts);\n if (options?.sessionId) {\n agent.sessionId = options.sessionId;\n }\n return agent;\n }\n}\n"],"mappings":"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","names":["join","join","createLogger","logger","createLogger","join","join"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actant/pi",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Pi Agent backend for the Actant platform — built on pi-agent-core and pi-ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,8 +40,8 @@
40
40
  "@agentclientprotocol/sdk": "^0.14.1",
41
41
  "@mariozechner/pi-agent-core": "^0.54.2",
42
42
  "@mariozechner/pi-ai": "^0.54.2",
43
- "@actant/core": "0.2.0",
44
- "@actant/shared": "0.2.0"
43
+ "@actant/core": "0.2.2",
44
+ "@actant/shared": "0.2.2"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/pi-tool-bridge.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { readFile, writeFile, readdir } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Agent, type AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { getModel, Type } from \"@mariozechner/pi-ai\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface PiAgentOptions {\n workspaceDir: string;\n provider?: string;\n model?: string;\n apiKey?: string;\n thinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n tools?: string[];\n systemPrompt?: string;\n}\n\nconst ALL_TOOLS = [\"read_file\", \"write_file\", \"list_directory\", \"run_command\"] as const;\n\nfunction resolvePath(workspaceDir: string, path: string): string {\n const abs = resolve(workspaceDir, path);\n const base = resolve(workspaceDir);\n if (!abs.startsWith(base)) {\n throw new Error(`Path \"${path}\" resolves outside workspace`);\n }\n return abs;\n}\n\nfunction buildTools(workspaceDir: string, toolNames?: string[]): AgentTool[] {\n const enabled = toolNames && toolNames.length > 0 ? toolNames : [...ALL_TOOLS];\n const tools: AgentTool[] = [];\n\n if (enabled.includes(\"read_file\")) {\n tools.push({\n name: \"read_file\",\n label: \"Read File\",\n description: \"Read the contents of a file. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"File path relative to workspace\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path } = params as { path: string };\n const absPath = resolvePath(workspaceDir, path);\n const content = await readFile(absPath, \"utf-8\");\n return { content: [{ type: \"text\" as const, text: content }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"write_file\")) {\n tools.push({\n name: \"write_file\",\n label: \"Write File\",\n description: \"Write content to a file. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"File path relative to workspace\" }),\n content: Type.String({ description: \"Content to write\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path, content } = params as { path: string; content: string };\n const absPath = resolvePath(workspaceDir, path);\n await writeFile(absPath, content, \"utf-8\");\n return { content: [{ type: \"text\" as const, text: `Wrote ${path}` }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"list_directory\")) {\n tools.push({\n name: \"list_directory\",\n label: \"List Directory\",\n description: \"List files and directories. Path is relative to workspace.\",\n parameters: Type.Object({\n path: Type.String({ description: \"Directory path relative to workspace\" }),\n }),\n execute: (async (_toolCallId, params) => {\n const { path } = params as { path: string };\n const absPath = resolvePath(workspaceDir, path);\n const entries = await readdir(absPath, { withFileTypes: true });\n const lines = entries.map((e) => (e.isDirectory() ? `${e.name}/` : e.name));\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n if (enabled.includes(\"run_command\")) {\n tools.push({\n name: \"run_command\",\n label: \"Run Command\",\n description: \"Execute a shell command. command is the executable, args are the arguments.\",\n parameters: Type.Object({\n command: Type.String({ description: \"Executable to run\" }),\n args: Type.Optional(Type.Array(Type.String(), { description: \"Command arguments\" })),\n }),\n execute: (async (_toolCallId, params, signal) => {\n const { command, args: argList } = params as { command: string; args?: string[] };\n const args = argList ?? [];\n const { stdout, stderr } = await execFileAsync(\n command,\n args,\n { cwd: workspaceDir, signal, encoding: \"utf-8\" },\n );\n const out = [stdout, stderr].filter(Boolean).join(\"\\n\").trim() || \"(no output)\";\n return { content: [{ type: \"text\" as const, text: out }], details: undefined };\n }) as AgentTool[\"execute\"],\n });\n }\n\n return tools;\n}\n\nexport function createPiAgent(options: PiAgentOptions): Agent {\n const {\n workspaceDir,\n provider = \"anthropic\",\n model = \"claude-sonnet-4-20250514\",\n apiKey,\n thinkingLevel,\n tools: toolNames,\n systemPrompt = \"You are a helpful coding assistant. You have access to file and command tools.\",\n } = options;\n\n const modelInstance = getModel(provider as never, model);\n\n const agentOptions: Record<string, unknown> = {\n initialState: {\n systemPrompt,\n model: modelInstance,\n tools: buildTools(workspaceDir, toolNames),\n },\n };\n\n if (thinkingLevel) {\n (agentOptions.initialState as Record<string, unknown>).thinkingLevel = thinkingLevel;\n }\n\n if (apiKey) {\n agentOptions.getApiKey = async () => apiKey;\n }\n\n return new Agent(agentOptions as ConstructorParameters<typeof Agent>[0]);\n}\n"],"mappings":"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","names":[]}