@agentex/agent 0.0.23 → 0.0.26

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 (177) hide show
  1. package/CHANGELOG.md +338 -0
  2. package/LICENSE +21 -0
  3. package/README.md +110 -0
  4. package/dist/derived.d.ts +5 -3
  5. package/dist/derived.d.ts.map +1 -1
  6. package/dist/derived.js +11 -7
  7. package/dist/derived.js.map +1 -1
  8. package/dist/index.d.ts +7 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/providers/acp/index.d.ts +1 -1
  13. package/dist/providers/acp/index.d.ts.map +1 -1
  14. package/dist/providers/acp/index.js +5 -97
  15. package/dist/providers/acp/index.js.map +1 -1
  16. package/dist/providers/acp/session.d.ts +8 -1
  17. package/dist/providers/acp/session.d.ts.map +1 -1
  18. package/dist/providers/acp/session.js +94 -0
  19. package/dist/providers/acp/session.js.map +1 -1
  20. package/dist/providers/claude/attach.d.ts +8 -0
  21. package/dist/providers/claude/attach.d.ts.map +1 -0
  22. package/dist/providers/claude/attach.js +113 -0
  23. package/dist/providers/claude/attach.js.map +1 -0
  24. package/dist/providers/claude/execute.d.ts.map +1 -1
  25. package/dist/providers/claude/execute.js +17 -2
  26. package/dist/providers/claude/execute.js.map +1 -1
  27. package/dist/providers/claude/goal-capability.d.ts +15 -0
  28. package/dist/providers/claude/goal-capability.d.ts.map +1 -0
  29. package/dist/providers/claude/goal-capability.js +20 -0
  30. package/dist/providers/claude/goal-capability.js.map +1 -0
  31. package/dist/providers/claude/index.d.ts.map +1 -1
  32. package/dist/providers/claude/index.js +8 -4
  33. package/dist/providers/claude/index.js.map +1 -1
  34. package/dist/providers/claude/session.d.ts +11 -9
  35. package/dist/providers/claude/session.d.ts.map +1 -1
  36. package/dist/providers/claude/session.js +36 -14
  37. package/dist/providers/claude/session.js.map +1 -1
  38. package/dist/providers/codex/attach.d.ts +9 -0
  39. package/dist/providers/codex/attach.d.ts.map +1 -0
  40. package/dist/providers/codex/attach.js +93 -0
  41. package/dist/providers/codex/attach.js.map +1 -0
  42. package/dist/providers/codex/execute.d.ts.map +1 -1
  43. package/dist/providers/codex/execute.js +17 -3
  44. package/dist/providers/codex/execute.js.map +1 -1
  45. package/dist/providers/codex/goal-capability.d.ts +13 -0
  46. package/dist/providers/codex/goal-capability.d.ts.map +1 -0
  47. package/dist/providers/codex/goal-capability.js +18 -0
  48. package/dist/providers/codex/goal-capability.js.map +1 -0
  49. package/dist/providers/codex/index.d.ts +1 -0
  50. package/dist/providers/codex/index.d.ts.map +1 -1
  51. package/dist/providers/codex/index.js +9 -6
  52. package/dist/providers/codex/index.js.map +1 -1
  53. package/dist/providers/codex/session.d.ts +11 -7
  54. package/dist/providers/codex/session.d.ts.map +1 -1
  55. package/dist/providers/codex/session.js +37 -12
  56. package/dist/providers/codex/session.js.map +1 -1
  57. package/dist/providers/codex/transcript-normalize.d.ts +28 -0
  58. package/dist/providers/codex/transcript-normalize.d.ts.map +1 -0
  59. package/dist/providers/codex/transcript-normalize.js +191 -0
  60. package/dist/providers/codex/transcript-normalize.js.map +1 -0
  61. package/dist/providers/cursor/index.d.ts.map +1 -1
  62. package/dist/providers/cursor/index.js +2 -2
  63. package/dist/providers/cursor/index.js.map +1 -1
  64. package/dist/providers/openclaw/index.d.ts.map +1 -1
  65. package/dist/providers/openclaw/index.js +2 -2
  66. package/dist/providers/openclaw/index.js.map +1 -1
  67. package/dist/providers/opencode/index.d.ts.map +1 -1
  68. package/dist/providers/opencode/index.js +3 -5
  69. package/dist/providers/opencode/index.js.map +1 -1
  70. package/dist/providers/pi/index.d.ts.map +1 -1
  71. package/dist/providers/pi/index.js +3 -5
  72. package/dist/providers/pi/index.js.map +1 -1
  73. package/dist/providers/process/index.d.ts.map +1 -1
  74. package/dist/providers/process/index.js +2 -2
  75. package/dist/providers/process/index.js.map +1 -1
  76. package/dist/registry.d.ts +0 -1
  77. package/dist/registry.d.ts.map +1 -1
  78. package/dist/registry.js +0 -4
  79. package/dist/registry.js.map +1 -1
  80. package/dist/sessions/index.d.ts +3 -0
  81. package/dist/sessions/index.d.ts.map +1 -0
  82. package/dist/sessions/index.js +2 -0
  83. package/dist/sessions/index.js.map +1 -0
  84. package/dist/sessions/record.d.ts +43 -0
  85. package/dist/sessions/record.d.ts.map +1 -0
  86. package/dist/sessions/record.js +85 -0
  87. package/dist/sessions/record.js.map +1 -0
  88. package/dist/types.d.ts +176 -0
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js.map +1 -1
  91. package/dist/utils/endpoint.d.ts +38 -0
  92. package/dist/utils/endpoint.d.ts.map +1 -0
  93. package/dist/utils/endpoint.js +151 -0
  94. package/dist/utils/endpoint.js.map +1 -0
  95. package/dist/utils/env.d.ts.map +1 -1
  96. package/dist/utils/env.js +5 -1
  97. package/dist/utils/env.js.map +1 -1
  98. package/dist/utils/uuid.d.ts +7 -1
  99. package/dist/utils/uuid.d.ts.map +1 -1
  100. package/dist/utils/uuid.js +21 -1
  101. package/dist/utils/uuid.js.map +1 -1
  102. package/package.json +64 -7
  103. package/src/derived.ts +311 -0
  104. package/src/goals/controller.ts +442 -0
  105. package/src/goals/index.ts +21 -0
  106. package/src/goals/normalize.ts +173 -0
  107. package/src/goals/sentinel.ts +90 -0
  108. package/src/index.ts +270 -0
  109. package/src/providers/_shared/http-agent.ts +304 -0
  110. package/src/providers/acp/index.ts +103 -0
  111. package/src/providers/acp/parse.ts +131 -0
  112. package/src/providers/acp/session.ts +744 -0
  113. package/src/providers/claude/attach.ts +147 -0
  114. package/src/providers/claude/codec.ts +43 -0
  115. package/src/providers/claude/execute.ts +300 -0
  116. package/src/providers/claude/goal-capability.ts +21 -0
  117. package/src/providers/claude/index.ts +72 -0
  118. package/src/providers/claude/mcp.ts +82 -0
  119. package/src/providers/claude/parse.ts +824 -0
  120. package/src/providers/claude/session.ts +1192 -0
  121. package/src/providers/claude/transcript.ts +555 -0
  122. package/src/providers/codex/attach.ts +123 -0
  123. package/src/providers/codex/codec.ts +50 -0
  124. package/src/providers/codex/execute.ts +337 -0
  125. package/src/providers/codex/goal-capability.ts +19 -0
  126. package/src/providers/codex/index.ts +57 -0
  127. package/src/providers/codex/modes.ts +159 -0
  128. package/src/providers/codex/parse.ts +691 -0
  129. package/src/providers/codex/plan-mode.ts +49 -0
  130. package/src/providers/codex/session.ts +1287 -0
  131. package/src/providers/codex/transcript-normalize.ts +197 -0
  132. package/src/providers/codex/transcript.ts +487 -0
  133. package/src/providers/codex/usage-scanner.ts +178 -0
  134. package/src/providers/copilot/index.ts +19 -0
  135. package/src/providers/cursor/codec.ts +44 -0
  136. package/src/providers/cursor/execute.ts +271 -0
  137. package/src/providers/cursor/index.ts +25 -0
  138. package/src/providers/cursor/parse.ts +288 -0
  139. package/src/providers/gemini/index.ts +21 -0
  140. package/src/providers/openclaw/codec.ts +40 -0
  141. package/src/providers/openclaw/execute.ts +19 -0
  142. package/src/providers/openclaw/index.ts +29 -0
  143. package/src/providers/opencode/codec.ts +50 -0
  144. package/src/providers/opencode/event-parse.ts +141 -0
  145. package/src/providers/opencode/execute.ts +251 -0
  146. package/src/providers/opencode/http-session.ts +427 -0
  147. package/src/providers/opencode/index.ts +30 -0
  148. package/src/providers/opencode/parse.ts +203 -0
  149. package/src/providers/opencode/server.ts +0 -0
  150. package/src/providers/pi/codec.ts +44 -0
  151. package/src/providers/pi/execute.ts +297 -0
  152. package/src/providers/pi/index.ts +30 -0
  153. package/src/providers/pi/parse.ts +231 -0
  154. package/src/providers/pi/session.ts +381 -0
  155. package/src/providers/process/execute.ts +148 -0
  156. package/src/providers/process/index.ts +52 -0
  157. package/src/registry.ts +40 -0
  158. package/src/sessions/index.ts +8 -0
  159. package/src/sessions/record.ts +108 -0
  160. package/src/types.ts +1638 -0
  161. package/src/utils/ask-user-question.ts +57 -0
  162. package/src/utils/auth.ts +661 -0
  163. package/src/utils/binary.ts +179 -0
  164. package/src/utils/endpoint.ts +172 -0
  165. package/src/utils/env.ts +63 -0
  166. package/src/utils/execute-all.ts +68 -0
  167. package/src/utils/exit-plan-mode.ts +40 -0
  168. package/src/utils/instructions.ts +427 -0
  169. package/src/utils/process.ts +223 -0
  170. package/src/utils/runtime-config.ts +100 -0
  171. package/src/utils/runtime-homes.ts +49 -0
  172. package/src/utils/skill-commands.ts +493 -0
  173. package/src/utils/skills.ts +500 -0
  174. package/src/utils/template.ts +16 -0
  175. package/src/utils/tool-names.ts +51 -0
  176. package/src/utils/uuid.ts +21 -0
  177. package/src/utils/workspace.ts +156 -0
@@ -0,0 +1,103 @@
1
+ import type {
2
+ AuthReport,
3
+ AuthResolveContext,
4
+ ListModesOptions,
5
+ ProviderModel,
6
+ ProviderModule,
7
+ SessionContext,
8
+ } from "../../types.js";
9
+ import { ensureCommandResolvable } from "../../utils/binary.js";
10
+ import type { AcpSessionDeps, AcpTransformers } from "./session.js";
11
+
12
+ /**
13
+ * Configuration for a generic ACP-backed provider. The canonical use is the
14
+ * config-extend `extends: "acp"` form, but any code can build one directly:
15
+ *
16
+ * ```ts
17
+ * registerProvider(acpProvider({ id: "gemini", command: ["gemini", "--acp"] }));
18
+ * ```
19
+ */
20
+ export interface AcpProviderConfig {
21
+ /** Unique provider id. */
22
+ id: string;
23
+ /** Command to spawn the ACP agent: [binary, ...args]. */
24
+ command: string[];
25
+ /** Environment overlay applied to every spawn. */
26
+ env?: Record<string, string>;
27
+ /** Display label (informational). */
28
+ label?: string;
29
+ /** Static model list surfaced via listModels(). */
30
+ models?: ProviderModel[];
31
+ /** Default mode id applied on session creation. */
32
+ modeId?: string;
33
+ /** Per-agent quirk transformers (modes / modeId). */
34
+ transformers?: AcpTransformers;
35
+ }
36
+
37
+ async function resolveAcpAuth(
38
+ config: AcpProviderConfig,
39
+ authCtx?: AuthResolveContext,
40
+ ): Promise<AuthReport> {
41
+ const binary = authCtx?.command ?? config.command[0]!;
42
+ try {
43
+ const resolved = await ensureCommandResolvable(binary);
44
+ return {
45
+ providerType: config.id,
46
+ binary: { installed: true, resolvedPath: resolved.bin },
47
+ options: [],
48
+ source: "filesystem",
49
+ };
50
+ } catch (err) {
51
+ return {
52
+ providerType: config.id,
53
+ binary: { installed: false, error: err instanceof Error ? err.message : String(err) },
54
+ options: [],
55
+ source: "filesystem",
56
+ };
57
+ }
58
+ }
59
+
60
+ /** Build a generic ACP-backed `ProviderModule`. */
61
+ export function acpProvider(config: AcpProviderConfig): ProviderModule {
62
+ const deps: AcpSessionDeps = {
63
+ provider: config.id,
64
+ command: config.command,
65
+ ...(config.env ? { env: config.env } : {}),
66
+ ...(config.modeId ? { modeId: config.modeId } : {}),
67
+ ...(config.transformers ? { transformers: config.transformers } : {}),
68
+ };
69
+
70
+ const provider: ProviderModule = {
71
+ type: config.id,
72
+ capabilities: {
73
+ sessions: true,
74
+ modelDiscovery: Boolean(config.models),
75
+ quotaProbing: false,
76
+ mcp: false,
77
+ skills: false,
78
+ instructions: false,
79
+ workspace: true,
80
+ planMode: false,
81
+ concurrentSend: false,
82
+ cancelQueuedMessage: false,
83
+ stopTask: false,
84
+ modes: true,
85
+ // Real capability set is negotiated at the ACP initialize handshake.
86
+ dynamicCapabilities: true,
87
+ },
88
+ // Session machinery (+ the ACP SDK it dynamically imports) loads only when
89
+ // an ACP provider is actually invoked — index.ts stays a light leaf.
90
+ execute: async (ctx) => (await import("./session.js")).runAcpExecute(deps, ctx),
91
+ createSession: async (ctx) => (await import("./session.js")).createAcpSession(deps, ctx),
92
+ resolveAuth: (authCtx) => resolveAcpAuth(config, authCtx),
93
+ listModes: async (opts?: ListModesOptions) =>
94
+ (await import("./session.js")).listAcpModes(deps, opts as SessionContext | undefined),
95
+ };
96
+
97
+ if (config.models) {
98
+ const models = config.models;
99
+ provider.listModels = async () => models;
100
+ }
101
+
102
+ return provider;
103
+ }
@@ -0,0 +1,131 @@
1
+ import type { BaseStreamEventFields, StreamEvent } from "../../types.js";
2
+
3
+ function str(v: unknown): string | null {
4
+ return typeof v === "string" && v.length > 0 ? v : null;
5
+ }
6
+
7
+ /** Extract text from an ACP `ContentBlock` (a chunk update's `content`). */
8
+ export function extractContentText(content: unknown): string | null {
9
+ if (!content || typeof content !== "object") return null;
10
+ const c = content as Record<string, unknown>;
11
+ if (c["type"] === "text" && typeof c["text"] === "string") return c["text"];
12
+ return null;
13
+ }
14
+
15
+ /** Extract displayable text from a tool call's `content` (ToolCallContent[]). */
16
+ export function extractToolContentText(content: unknown): string | null {
17
+ if (!Array.isArray(content)) return null;
18
+ const parts: string[] = [];
19
+ for (const item of content) {
20
+ if (!item || typeof item !== "object") continue;
21
+ const c = item as Record<string, unknown>;
22
+ if (c["type"] === "content") {
23
+ const inner = extractContentText(c["content"]);
24
+ if (inner) parts.push(inner);
25
+ } else if (c["type"] === "diff") {
26
+ const nd = c["newText"] ?? c["new_text"];
27
+ if (typeof nd === "string") parts.push(nd);
28
+ }
29
+ // Note: a "terminal" ToolCallContent carries only a `terminalId` (its output
30
+ // must be fetched via the ACP terminal/* methods, which we don't implement),
31
+ // so there's no inline text to extract here.
32
+ }
33
+ return parts.length ? parts.join("\n") : null;
34
+ }
35
+
36
+ export interface AcpBaseInfo {
37
+ provider: string;
38
+ sessionId: string | null;
39
+ timestamp: string;
40
+ }
41
+
42
+ function makeBase(update: Record<string, unknown>, info: AcpBaseInfo): BaseStreamEventFields {
43
+ // ACP doesn't expose per-event/message/turn ids, so those stay null; the
44
+ // tool callId IS available, so tool_call/tool_result correlate properly.
45
+ return {
46
+ timestamp: info.timestamp,
47
+ providerType: info.provider,
48
+ sessionId: info.sessionId,
49
+ messageId: null,
50
+ eventId: null,
51
+ turnId: null,
52
+ parentToolCallId: null,
53
+ raw: update,
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Map an ACP `session/update` payload (`params.update`) to an agentex
59
+ * `StreamEvent`. Returns null for updates with no agentex equivalent (user
60
+ * echoes, in-progress tool ticks). Unknown update kinds surface as
61
+ * `type: "unknown"` for forward-compat.
62
+ */
63
+ export function mapAcpUpdate(update: Record<string, unknown>, info: AcpBaseInfo): StreamEvent | null {
64
+ const kind = update["sessionUpdate"];
65
+ const base = makeBase(update, info);
66
+ switch (kind) {
67
+ case "agent_message_chunk": {
68
+ const text = extractContentText(update["content"]);
69
+ return text != null ? { type: "assistant", text, ...base } : null;
70
+ }
71
+ case "agent_thought_chunk": {
72
+ const text = extractContentText(update["content"]);
73
+ return text != null ? { type: "thinking", text, ...base } : null;
74
+ }
75
+ case "user_message_chunk":
76
+ return null;
77
+ case "tool_call":
78
+ return {
79
+ type: "tool_call",
80
+ toolCallId: str(update["toolCallId"]),
81
+ name: str(update["title"]) ?? str(update["kind"]) ?? "tool",
82
+ input: update["rawInput"] ?? null,
83
+ ...base,
84
+ };
85
+ case "tool_call_update": {
86
+ const status = str(update["status"]);
87
+ // Only emit a result once the tool reaches a terminal state.
88
+ if (status === "completed" || status === "failed") {
89
+ const content =
90
+ extractToolContentText(update["content"]) ??
91
+ (typeof update["rawOutput"] === "string" ? (update["rawOutput"] as string) : "");
92
+ return {
93
+ type: "tool_result",
94
+ toolCallId: str(update["toolCallId"]),
95
+ toolName: str(update["title"]),
96
+ content,
97
+ isError: status === "failed",
98
+ exitCode: null,
99
+ ...base,
100
+ };
101
+ }
102
+ return null;
103
+ }
104
+ default:
105
+ return { type: "unknown", subtype: str(kind) ?? "unknown", ...base };
106
+ }
107
+ }
108
+
109
+ // NOTE: ACP's `usage_update` reports context-window `{ size, used }` rather than
110
+ // the input/output token split agentex's `TokenUsage` models, so we intentionally
111
+ // don't synthesize usage from ACP — `TurnResult.usage` stays undefined.
112
+
113
+ /** Map an ACP `stopReason` to an agentex TurnResult status. */
114
+ export function mapAcpStopReason(stopReason: string | undefined): TurnStatus {
115
+ switch (stopReason) {
116
+ case "end_turn":
117
+ return "completed";
118
+ case "cancelled":
119
+ return "aborted";
120
+ case "refusal":
121
+ return "failed";
122
+ case "max_tokens":
123
+ return "max_budget";
124
+ case "max_turn_requests":
125
+ return "max_turns";
126
+ default:
127
+ return "completed";
128
+ }
129
+ }
130
+
131
+ type TurnStatus = "completed" | "failed" | "max_turns" | "max_budget" | "aborted" | "timeout";