@kodizm/acp 0.5.2 → 0.5.4

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.
Files changed (2) hide show
  1. package/dist/index.js +94 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4646,6 +4646,17 @@ function mapAssistantMessage(sessionId, message) {
4646
4646
  if (skillName !== undefined) {
4647
4647
  events.push({ sessionId, type: "skill_activation", skillName, source: "invoked" });
4648
4648
  }
4649
+ const subagentType = extractSubagentType(block);
4650
+ if (subagentType !== undefined) {
4651
+ events.push({
4652
+ sessionId,
4653
+ type: "subagent_spawn",
4654
+ childId: block.id,
4655
+ parentSessionId: sessionId,
4656
+ model: subagentType,
4657
+ tools: []
4658
+ });
4659
+ }
4649
4660
  events.push({
4650
4661
  sessionId,
4651
4662
  type: "tool_call_begin",
@@ -4671,12 +4682,39 @@ function extractSkillName(block) {
4671
4682
  }
4672
4683
  return skill;
4673
4684
  }
4685
+ function extractSubagentType(block) {
4686
+ if (block.name !== "Task" && block.name !== "Agent") {
4687
+ return;
4688
+ }
4689
+ const input = block.input;
4690
+ if (typeof input !== "object" || input === null) {
4691
+ return "general-purpose";
4692
+ }
4693
+ const subagentType = input.subagent_type;
4694
+ if (typeof subagentType === "string" && subagentType.length > 0) {
4695
+ return subagentType;
4696
+ }
4697
+ return "general-purpose";
4698
+ }
4674
4699
  function mapUserMessage(sessionId, message) {
4675
4700
  const events = [];
4676
4701
  for (const block of message.message.content) {
4677
4702
  if (block.type === "tool_result") {
4678
4703
  const resultText = typeof block.content === "string" ? block.content : block.content.map((c) => c.text).join(`
4679
4704
  `);
4705
+ const subagentUsage = extractTaskToolUsage(resultText);
4706
+ if (subagentUsage !== undefined) {
4707
+ events.push({
4708
+ sessionId,
4709
+ type: "subagent_complete",
4710
+ childId: block.tool_use_id,
4711
+ inputTokens: subagentUsage.totalTokens,
4712
+ outputTokens: 0,
4713
+ cacheReadTokens: 0,
4714
+ cacheCreationTokens: 0,
4715
+ costUsd: 0
4716
+ });
4717
+ }
4680
4718
  events.push({
4681
4719
  sessionId,
4682
4720
  type: "tool_call_end",
@@ -4688,6 +4726,22 @@ function mapUserMessage(sessionId, message) {
4688
4726
  }
4689
4727
  return events;
4690
4728
  }
4729
+ function extractTaskToolUsage(resultText) {
4730
+ if (!resultText.includes("agentId:")) {
4731
+ return;
4732
+ }
4733
+ const usageMatch = resultText.match(/<usage>([\s\S]*?)<\/usage>/);
4734
+ if (usageMatch === null) {
4735
+ return;
4736
+ }
4737
+ const totalMatch = usageMatch[1]?.match(/total_tokens:\s*(\d+)/);
4738
+ if (totalMatch === null || totalMatch === undefined) {
4739
+ return;
4740
+ }
4741
+ return {
4742
+ totalTokens: Number.parseInt(totalMatch[1] ?? "0", 10)
4743
+ };
4744
+ }
4691
4745
  function mapResult(sessionId, message) {
4692
4746
  const events = [];
4693
4747
  const usage = message.usage;
@@ -4928,6 +4982,17 @@ class ClaudeDriver {
4928
4982
  });
4929
4983
  return { sessionId };
4930
4984
  }
4985
+ async compact(request, emit) {
4986
+ const state = this.sessions.get(request.sessionId);
4987
+ if (state === undefined) {
4988
+ throw new SessionNotFoundError(request.sessionId);
4989
+ }
4990
+ state.pendingManualCompact = true;
4991
+ await this.prompt(request.sessionId, {
4992
+ sessionId: request.sessionId,
4993
+ prompt: [{ type: "text", text: "/compact" }]
4994
+ }, emit);
4995
+ }
4931
4996
  async prompt(sessionId, params, emit) {
4932
4997
  const state = this.sessions.get(sessionId);
4933
4998
  if (state === undefined) {
@@ -5074,7 +5139,8 @@ class ClaudeDriver {
5074
5139
  }
5075
5140
  }
5076
5141
  tracker.observe(message);
5077
- const events = tracker.rewrite(mapSdkMessage(sessionId, message));
5142
+ const rawEvents = tracker.rewrite(mapSdkMessage(sessionId, message));
5143
+ const events = this.applyManualCompactLatch(state, rawEvents);
5078
5144
  for (const event of events) {
5079
5145
  emit.send(event);
5080
5146
  }
@@ -5271,6 +5337,21 @@ class ClaudeDriver {
5271
5337
  return text.join(`
5272
5338
  `);
5273
5339
  }
5340
+ applyManualCompactLatch(state, events) {
5341
+ if (state.pendingManualCompact !== true) {
5342
+ return events;
5343
+ }
5344
+ return events.map((event) => {
5345
+ if (event.type === "compaction_started") {
5346
+ return { ...event, trigger: "manual" };
5347
+ }
5348
+ if (event.type === "compaction_completed") {
5349
+ state.pendingManualCompact = false;
5350
+ return { ...event, trigger: "manual" };
5351
+ }
5352
+ return event;
5353
+ });
5354
+ }
5274
5355
  }
5275
5356
  var FULL_CAPABILITIES;
5276
5357
  var init_driver = __esm(() => {
@@ -28775,6 +28856,9 @@ var LoadSessionRequestSchema = exports_external.object({
28775
28856
  mcpServers: exports_external.array(McpServerSchema),
28776
28857
  _meta: MetaSchema.optional()
28777
28858
  }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] });
28859
+ var CompactSessionRequestSchema = exports_external.object({
28860
+ sessionId: exports_external.string().min(1)
28861
+ });
28778
28862
  var ForkSessionRequestSchema = exports_external.object({
28779
28863
  sourceSessionId: exports_external.string().min(1),
28780
28864
  cwd: AbsolutePathSchema,
@@ -28839,6 +28923,14 @@ function wireBackendHandlers(server, backend) {
28839
28923
  const validated = validateOrThrow(ForkSessionRequestSchema, params);
28840
28924
  return await backend.forkSession(validated);
28841
28925
  });
28926
+ server.on("session/compact", async (params) => {
28927
+ const validated = validateOrThrow(CompactSessionRequestSchema, params);
28928
+ const emit = {
28929
+ send: (event) => server.notify("sessionUpdate", event)
28930
+ };
28931
+ await backend.compact(validated, emit);
28932
+ return {};
28933
+ });
28842
28934
  }
28843
28935
  function createAcpServer(options) {
28844
28936
  const { transport, backend, debugSink } = options;
@@ -29197,7 +29289,7 @@ async function buildClaudeBackend() {
29197
29289
  const claudePath = process.env.CLAUDE_CODE_PATH ?? "/usr/local/bin/claude";
29198
29290
  const driver = new ClaudeDriver2({
29199
29291
  credentials: pickClaudeCredentials(process.env),
29200
- agentInfo: { version: "0.5.2" },
29292
+ agentInfo: { version: "0.5.4" },
29201
29293
  sdk: {
29202
29294
  async* query(args) {
29203
29295
  const optsIn = args.options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodizm/acp",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Custom ACP server bridging Claude Code, codex, and opencode CLIs through a single Kodizm-flavored protocol surface.",
5
5
  "type": "module",
6
6
  "bin": {