@jini-ai/agent-runtime 0.3.10 → 0.4.0

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 (200) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/README.md +34 -17
  3. package/dist/acp-model-probe.d.ts +6 -4
  4. package/dist/acp-model-probe.js +3 -3
  5. package/dist/agent-protocol/acp/account-failure.d.ts +4 -2
  6. package/dist/agent-protocol/acp/account-failure.js +1 -1
  7. package/dist/agent-protocol/acp/json.d.ts +6 -6
  8. package/dist/agent-protocol/acp/json.js +3 -3
  9. package/dist/agent-protocol/acp/models.d.ts +10 -5
  10. package/dist/agent-protocol/acp/models.js +32 -31
  11. package/dist/agent-protocol/acp/session-params.d.ts +3 -1
  12. package/dist/agent-protocol/acp/session-params.js +2 -1
  13. package/dist/agent-protocol/acp/session.d.ts +28 -22
  14. package/dist/agent-protocol/acp/session.js +181 -147
  15. package/dist/agent-protocol/acp/text-suppression.d.ts +1 -1
  16. package/dist/agent-protocol/acp/text-suppression.js +1 -1
  17. package/dist/agent-protocol/acp/types.d.ts +3 -2
  18. package/dist/agent-protocol/acp/updates.d.ts +11 -11
  19. package/dist/agent-protocol/acp/updates.js +2 -2
  20. package/dist/agent-protocol/core/json-line-stream.d.ts +24 -8
  21. package/dist/agent-protocol/core/json-line-stream.js +8 -8
  22. package/dist/agent-protocol/pi-rpc/events.d.ts +5 -1
  23. package/dist/agent-protocol/pi-rpc/events.js +36 -36
  24. package/dist/agent-protocol/pi-rpc/internal.d.ts +4 -1
  25. package/dist/agent-protocol/pi-rpc/models.d.ts +3 -1
  26. package/dist/agent-protocol/pi-rpc/models.js +1 -1
  27. package/dist/agent-protocol/pi-rpc/session.d.ts +1 -1
  28. package/dist/agent-protocol/pi-rpc/session.js +33 -32
  29. package/dist/amr-model-cache.d.ts +12 -4
  30. package/dist/amr-model-cache.js +17 -21
  31. package/dist/amr-profile-resolver.d.ts +3 -1
  32. package/dist/anthropic-live-models.js +0 -0
  33. package/dist/artifact-taxonomy.d.ts +6 -2
  34. package/dist/auth.d.ts +52 -15
  35. package/dist/auth.js +36 -36
  36. package/dist/claude-code-models.js +2 -2
  37. package/dist/claude-stream.d.ts +22 -3
  38. package/dist/claude-stream.js +24 -8
  39. package/dist/copilot-stream.d.ts +7 -3
  40. package/dist/copilot-stream.js +3 -3
  41. package/dist/defs/aider.d.ts +8 -1
  42. package/dist/defs/aider.js +2 -2
  43. package/dist/defs/amp.d.ts +8 -1
  44. package/dist/defs/amp.js +2 -2
  45. package/dist/defs/amr.d.ts +22 -6
  46. package/dist/defs/amr.js +23 -23
  47. package/dist/defs/antigravity.d.ts +15 -4
  48. package/dist/defs/antigravity.js +9 -8
  49. package/dist/defs/auggie.d.ts +4 -1
  50. package/dist/defs/auggie.js +1 -1
  51. package/dist/defs/claude.d.ts +12 -2
  52. package/dist/defs/claude.js +5 -5
  53. package/dist/defs/cline.d.ts +4 -1
  54. package/dist/defs/cline.js +1 -1
  55. package/dist/defs/codebuddy.d.ts +8 -1
  56. package/dist/defs/codebuddy.js +2 -2
  57. package/dist/defs/codex.d.ts +18 -4
  58. package/dist/defs/codex.js +7 -7
  59. package/dist/defs/copilot.d.ts +8 -1
  60. package/dist/defs/copilot.js +2 -2
  61. package/dist/defs/crush.d.ts +8 -1
  62. package/dist/defs/crush.js +1 -1
  63. package/dist/defs/cursor-agent.d.ts +14 -3
  64. package/dist/defs/cursor-agent.js +5 -5
  65. package/dist/defs/deepseek.d.ts +8 -1
  66. package/dist/defs/deepseek.js +2 -2
  67. package/dist/defs/devin.d.ts +12 -2
  68. package/dist/defs/devin.js +3 -3
  69. package/dist/defs/droid.d.ts +8 -1
  70. package/dist/defs/droid.js +1 -1
  71. package/dist/defs/gemini.d.ts +8 -1
  72. package/dist/defs/gemini.js +1 -1
  73. package/dist/defs/goose.d.ts +4 -1
  74. package/dist/defs/goose.js +1 -1
  75. package/dist/defs/grok-build.d.ts +11 -2
  76. package/dist/defs/grok-build.js +3 -3
  77. package/dist/defs/hermes.d.ts +4 -1
  78. package/dist/defs/hermes.js +2 -2
  79. package/dist/defs/kilo.d.ts +4 -1
  80. package/dist/defs/kilo.js +2 -2
  81. package/dist/defs/kimi.d.ts +4 -1
  82. package/dist/defs/kimi.js +2 -2
  83. package/dist/defs/kiro.d.ts +4 -1
  84. package/dist/defs/kiro.js +2 -2
  85. package/dist/defs/mimo.d.ts +8 -1
  86. package/dist/defs/mimo.js +2 -2
  87. package/dist/defs/opencode.d.ts +9 -2
  88. package/dist/defs/opencode.js +2 -2
  89. package/dist/defs/pi.d.ts +12 -2
  90. package/dist/defs/pi.js +9 -9
  91. package/dist/defs/qoder.d.ts +8 -1
  92. package/dist/defs/qoder.js +2 -2
  93. package/dist/defs/qwen.d.ts +8 -1
  94. package/dist/defs/qwen.js +2 -2
  95. package/dist/defs/reasonix.d.ts +4 -1
  96. package/dist/defs/reasonix.js +3 -3
  97. package/dist/defs/shared.d.ts +4 -2
  98. package/dist/defs/shared.js +2 -2
  99. package/dist/defs/trae-cli.d.ts +12 -2
  100. package/dist/defs/trae-cli.js +3 -3
  101. package/dist/defs/vibe.d.ts +4 -1
  102. package/dist/defs/vibe.js +2 -2
  103. package/dist/detection.d.ts +19 -4
  104. package/dist/detection.js +33 -33
  105. package/dist/diagnostics.d.ts +14 -3
  106. package/dist/diagnostics.js +5 -5
  107. package/dist/env.d.ts +16 -4
  108. package/dist/env.js +7 -7
  109. package/dist/executables.d.ts +24 -8
  110. package/dist/executables.js +13 -13
  111. package/dist/index.d.ts +228 -4
  112. package/dist/index.js +230 -6
  113. package/dist/invocation.d.ts +6 -1
  114. package/dist/invocation.js +2 -2
  115. package/dist/json-event-stream.d.ts +7 -2
  116. package/dist/json-event-stream.js +3 -3
  117. package/dist/launch.d.ts +12 -2
  118. package/dist/launch.js +3 -3
  119. package/dist/log-file.d.ts +4 -1
  120. package/dist/log-file.js +2 -2
  121. package/dist/mcp.d.ts +6 -3
  122. package/dist/mcp.js +1 -1
  123. package/dist/metadata.d.ts +7 -3
  124. package/dist/metadata.js +1 -1
  125. package/dist/mmd-routes.d.ts +22 -6
  126. package/dist/mmd-routes.js +14 -14
  127. package/dist/model-catalog-cache.d.ts +50 -0
  128. package/dist/model-catalog-cache.js +61 -0
  129. package/dist/model-loading-state.d.ts +10 -0
  130. package/dist/model-loading-state.js +23 -0
  131. package/dist/model-registry.d.ts +28 -7
  132. package/dist/model-registry.js +11 -8
  133. package/dist/models.d.ts +31 -6
  134. package/dist/models.js +6 -6
  135. package/dist/opencode-log.d.ts +12 -4
  136. package/dist/opencode-log.js +8 -8
  137. package/dist/paths.d.ts +6 -2
  138. package/dist/paths.js +3 -3
  139. package/dist/pi-models.d.ts +3 -1
  140. package/dist/pi-models.js +2 -2
  141. package/dist/prompt-budget.d.ts +17 -4
  142. package/dist/prompt-budget.js +3 -3
  143. package/dist/prompt-file.d.ts +5 -1
  144. package/dist/prompt-file.js +1 -1
  145. package/dist/providers/aihubmix.d.ts +34 -9
  146. package/dist/providers/aihubmix.js +26 -26
  147. package/dist/providers/anthropic-messages.d.ts +77 -20
  148. package/dist/providers/anthropic-messages.js +53 -50
  149. package/dist/providers/azure-chat.d.ts +21 -7
  150. package/dist/providers/azure-chat.js +18 -16
  151. package/dist/providers/connection-guard.d.ts +45 -31
  152. package/dist/providers/connection-guard.js +40 -143
  153. package/dist/providers/connection-test.d.ts +1 -1
  154. package/dist/providers/connection-test.js +13 -30
  155. package/dist/providers/elevenlabs.d.ts +7 -2
  156. package/dist/providers/elevenlabs.js +4 -4
  157. package/dist/providers/google-messages.d.ts +44 -10
  158. package/dist/providers/google-messages.js +36 -34
  159. package/dist/providers/google-schema.d.ts +26 -0
  160. package/dist/providers/google-schema.js +253 -0
  161. package/dist/providers/google.d.ts +21 -6
  162. package/dist/providers/google.js +10 -10
  163. package/dist/providers/index.d.ts +3 -2
  164. package/dist/providers/index.js +3 -2
  165. package/dist/providers/model-catalog.d.ts +1 -1
  166. package/dist/providers/model-catalog.js +14 -27
  167. package/dist/providers/oauth-callback-server.d.ts +1 -1
  168. package/dist/providers/oauth-callback-server.js +3 -2
  169. package/dist/providers/oauth-credentials.d.ts +7 -1
  170. package/dist/providers/oauth-credentials.js +5 -5
  171. package/dist/providers/oauth-provider.d.ts +2 -2
  172. package/dist/providers/oauth-provider.js +20 -25
  173. package/dist/providers/oauth-tokens.d.ts +26 -6
  174. package/dist/providers/oauth-tokens.js +9 -9
  175. package/dist/providers/ollama-chat.d.ts +66 -31
  176. package/dist/providers/ollama-chat.js +64 -61
  177. package/dist/providers/openai-chat.d.ts +77 -22
  178. package/dist/providers/openai-chat.js +71 -67
  179. package/dist/providers/pkce.d.ts +33 -20
  180. package/dist/providers/pkce.js +75 -146
  181. package/dist/providers/sse-decode.d.ts +3 -1
  182. package/dist/providers/sse-decode.js +1 -1
  183. package/dist/providers/token-params.d.ts +16 -5
  184. package/dist/providers/token-params.js +6 -6
  185. package/dist/providers/tool-turn-types.d.ts +89 -0
  186. package/dist/providers/tool-turn-types.js +2 -0
  187. package/dist/providers/tool-turn.d.ts +10 -0
  188. package/dist/providers/tool-turn.js +252 -0
  189. package/dist/qoder-stream.d.ts +7 -3
  190. package/dist/qoder-stream.js +3 -3
  191. package/dist/registry.d.ts +6 -2
  192. package/dist/registry.js +4 -4
  193. package/dist/resolution.d.ts +5 -1
  194. package/dist/resolution.js +3 -3
  195. package/dist/role-marker-guard.d.ts +9 -5
  196. package/dist/role-marker-guard.js +5 -5
  197. package/dist/terminal-launch.d.ts +6 -1
  198. package/dist/terminal-launch.js +2 -2
  199. package/dist/types.d.ts +22 -6
  200. package/package.json +43 -4
@@ -0,0 +1,252 @@
1
+ import { runAnthropicToolTurn } from './anthropic-messages.js';
2
+ import { runAzureToolTurn } from './azure-chat.js';
3
+ import { runGoogleToolTurn } from './google-messages.js';
4
+ import { runOpenAiToolTurn } from './openai-chat.js';
5
+ import { googleParametersOf, findNumericEnumPaths, coerceNumericEnumStringsToNumbers } from './google-schema.js';
6
+ export { googleParametersOf, sanitizeGoogleSchema, findNumericEnumPaths, coerceNumericEnumStringsToNumbers } from './google-schema.js';
7
+ /** Existing provider loops, ready for host composition; callers may replace any adapter. */
8
+ export const providerTurnAdapters = Object.freeze({ anthropic: runAnthropicToolTurn, openai: runOpenAiToolTurn, azure: runAzureToolTurn, google: runGoogleToolTurn });
9
+ const TOOL_ERROR_PREFIX = "[tool error] ";
10
+ function toAnthropicToolContent(content) {
11
+ if (typeof content === "string")
12
+ return content;
13
+ return content.map((block) => block.type === "text"
14
+ ? { type: "text", text: block.text }
15
+ : { type: "image", source: { type: "base64", media_type: block.mimeType, data: block.data } });
16
+ }
17
+ function toOpenAiToolContent(content) {
18
+ if (typeof content === "string")
19
+ return content;
20
+ return content.map((block) => block.type === "text" ? { type: "text", text: block.text } : { type: "image_url", image_url: { url: `data:${block.mimeType};base64,${block.data}` } });
21
+ }
22
+ function toGoogleToolContent(content) {
23
+ if (typeof content === "string")
24
+ return content;
25
+ return content.map((block) => (block.type === "text" ? { text: block.text } : { inlineData: { mimeType: block.mimeType, data: block.data } }));
26
+ }
27
+ function foldToolError(content, isError) {
28
+ if (!isError)
29
+ return content;
30
+ return typeof content === "string" ? `${TOOL_ERROR_PREFIX}${content}` : [{ type: "text", text: TOOL_ERROR_PREFIX.trimEnd() }, ...content];
31
+ }
32
+ function imagePartMimeType(part) {
33
+ const source = part.source;
34
+ if (part.type === "image" && typeof source?.media_type === "string")
35
+ return source.media_type;
36
+ const imageUrl = part.image_url;
37
+ if (part.type === "image_url" && typeof imageUrl?.url === "string")
38
+ return /^data:([^;,]+)/.exec(imageUrl.url)?.[1] ?? "url";
39
+ const inlineData = part.inlineData;
40
+ if (typeof inlineData?.mimeType === "string")
41
+ return inlineData.mimeType;
42
+ return null;
43
+ }
44
+ function describeToolResultContent(content) {
45
+ if (typeof content === "string")
46
+ return content;
47
+ if (!Array.isArray(content))
48
+ return JSON.stringify(content);
49
+ return content
50
+ .map((part) => {
51
+ if (typeof part.text === "string")
52
+ return part.text;
53
+ const mimeType = imagePartMimeType(part);
54
+ return mimeType === null ? JSON.stringify(part) : `[image: ${mimeType}]`;
55
+ })
56
+ .join("\n");
57
+ }
58
+ function inputSchemaOf(descriptor) {
59
+ return descriptor.inputSchema && typeof descriptor.inputSchema === "object"
60
+ ? descriptor.inputSchema
61
+ : { type: "object", additionalProperties: false, required: [], properties: {} };
62
+ }
63
+ function normalizeTurnResult(result, capturedEndReason = null) {
64
+ return { stopReason: capturedEndReason ?? result.stopReason ?? result.finishReason ?? null, toolTurns: result.toolTurns };
65
+ }
66
+ async function runAnthropicTurn(input) {
67
+ const tools = input.tools.map((d) => ({
68
+ name: d.id,
69
+ ...(d.description !== undefined ? { description: d.description } : {}),
70
+ input_schema: inputSchemaOf(d),
71
+ }));
72
+ const messages = input.messages.map((m) => ({ role: m.role, content: m.content }));
73
+ const executeTool = async (call) => {
74
+ const result = await input.executeTool({ id: call.id, name: call.name, input: call.input });
75
+ return { content: toAnthropicToolContent(result.content), ...(result.isError !== undefined ? { isError: result.isError } : {}) };
76
+ };
77
+ let capturedEndReason = null;
78
+ const result = await (({ apiKey, model, messages, maxTokens, onEvent, ...optionalArgs }) => input.adapters.anthropic({ apiKey, model, messages, maxTokens, onEvent }, optionalArgs))({
79
+ apiKey: input.apiKey,
80
+ ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),
81
+ model: input.model,
82
+ system: input.system,
83
+ messages,
84
+ tools,
85
+ maxTokens: input.maxTokens ?? 8192,
86
+ ...(input.maxToolTurns !== undefined ? { maxToolTurns: input.maxToolTurns } : {}),
87
+ executeTool,
88
+ ...(input.signal ? { signal: input.signal } : {}),
89
+ onEvent: (event) => {
90
+ if (event.type === "fabricated_role_marker")
91
+ return;
92
+ if (event.type === "end")
93
+ capturedEndReason = event.reason;
94
+ if (event.type === "tool_result") {
95
+ input.onEvent({
96
+ type: "tool_result",
97
+ toolUseId: event.toolUseId,
98
+ content: describeToolResultContent(event.content),
99
+ isError: event.isError,
100
+ });
101
+ return;
102
+ }
103
+ input.onEvent(event);
104
+ },
105
+ });
106
+ return normalizeTurnResult(result, capturedEndReason);
107
+ }
108
+ async function runOpenAiTurn(input) {
109
+ const tools = input.tools.map((d) => ({
110
+ type: "function",
111
+ function: { name: d.id, ...(d.description !== undefined ? { description: d.description } : {}), parameters: inputSchemaOf(d) },
112
+ }));
113
+ const messages = [
114
+ { role: "system", content: input.system },
115
+ ...input.messages.map((m) => ({ role: m.role, content: m.content })),
116
+ ];
117
+ const executeTool = async (call) => {
118
+ const result = await input.executeTool({ id: call.id, name: call.name, input: call.input });
119
+ return { content: foldToolError(toOpenAiToolContent(result.content), result.isError) };
120
+ };
121
+ let capturedEndReason = null;
122
+ const result = await (({ apiKey, model, messages, onEvent, ...optionalArgs }) => input.adapters.openai({ apiKey, model, messages, onEvent }, optionalArgs))({
123
+ apiKey: input.apiKey,
124
+ ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),
125
+ model: input.model,
126
+ messages,
127
+ tools,
128
+ ...(input.maxTokens !== undefined ? { maxTokens: input.maxTokens } : {}),
129
+ ...(input.maxToolTurns !== undefined ? { maxToolTurns: input.maxToolTurns } : {}),
130
+ executeTool,
131
+ ...(input.signal ? { signal: input.signal } : {}),
132
+ onEvent: (event) => {
133
+ if (event.type === "fabricated_role_marker")
134
+ return;
135
+ if (event.type === "end")
136
+ capturedEndReason = event.reason;
137
+ if (event.type === "tool_result") {
138
+ const content = describeToolResultContent(event.content);
139
+ input.onEvent({ type: "tool_result", toolUseId: event.toolUseId, content, isError: event.isError || content.startsWith(TOOL_ERROR_PREFIX.trimEnd()) });
140
+ return;
141
+ }
142
+ input.onEvent(event);
143
+ },
144
+ });
145
+ return normalizeTurnResult(result, capturedEndReason);
146
+ }
147
+ async function runAzureTurn(input) {
148
+ if (!input.baseUrl) {
149
+ input.onEvent({ type: "error", message: "the azure protocol requires a base URL (each Azure OpenAI resource has its own endpoint)" });
150
+ input.onEvent({ type: "end", reason: "error" });
151
+ return { stopReason: "error", toolTurns: 0 };
152
+ }
153
+ const tools = input.tools.map((d) => ({
154
+ type: "function",
155
+ function: { name: d.id, ...(d.description !== undefined ? { description: d.description } : {}), parameters: inputSchemaOf(d) },
156
+ }));
157
+ const messages = [
158
+ { role: "system", content: input.system },
159
+ ...input.messages.map((m) => ({ role: m.role, content: m.content })),
160
+ ];
161
+ const executeTool = async (call) => {
162
+ const result = await input.executeTool({ id: call.id, name: call.name, input: call.input });
163
+ return { content: foldToolError(toOpenAiToolContent(result.content), result.isError) };
164
+ };
165
+ let capturedEndReason = null;
166
+ const result = await (({ apiKey, baseUrl, model, messages, onEvent, ...optionalArgs }) => input.adapters.azure({ apiKey, baseUrl, model, messages, onEvent }, optionalArgs))({
167
+ apiKey: input.apiKey,
168
+ baseUrl: input.baseUrl,
169
+ model: input.model,
170
+ messages,
171
+ tools,
172
+ ...(input.maxTokens !== undefined ? { maxTokens: input.maxTokens } : {}),
173
+ ...(input.maxToolTurns !== undefined ? { maxToolTurns: input.maxToolTurns } : {}),
174
+ executeTool,
175
+ ...(input.signal ? { signal: input.signal } : {}),
176
+ onEvent: (event) => {
177
+ if (event.type === "fabricated_role_marker")
178
+ return;
179
+ if (event.type === "end")
180
+ capturedEndReason = event.reason;
181
+ if (event.type === "tool_result") {
182
+ const content = describeToolResultContent(event.content);
183
+ input.onEvent({ type: "tool_result", toolUseId: event.toolUseId, content, isError: event.isError || content.startsWith(TOOL_ERROR_PREFIX.trimEnd()) });
184
+ return;
185
+ }
186
+ input.onEvent(event);
187
+ },
188
+ });
189
+ return normalizeTurnResult(result, capturedEndReason);
190
+ }
191
+ async function runGoogleTurn(input) {
192
+ const tools = [
193
+ { functionDeclarations: input.tools.map((d) => ({ name: d.id, ...(d.description !== undefined ? { description: d.description } : {}), parameters: googleParametersOf({ descriptor: d }) })) },
194
+ ];
195
+ const numericEnumPathsByToolName = new Map(input.tools.map((d) => [d.id, findNumericEnumPaths({ schema: inputSchemaOf(d) })]));
196
+ const contents = input.messages.map((m) => ({
197
+ role: m.role === "assistant" ? "model" : "user",
198
+ parts: [{ text: m.content }],
199
+ }));
200
+ const executeTool = async (call) => {
201
+ const coercedInput = coerceNumericEnumStringsToNumbers({ input: call.input, paths: numericEnumPathsByToolName.get(call.name) ?? [] });
202
+ const result = await input.executeTool({ id: call.id, name: call.name, input: coercedInput });
203
+ return { content: toGoogleToolContent(result.content), ...(result.isError !== undefined ? { isError: result.isError } : {}) };
204
+ };
205
+ let capturedEndReason = null;
206
+ const result = await (({ apiKey, model, contents, onEvent, ...optionalArgs }) => input.adapters.google({ apiKey, model, contents, onEvent }, optionalArgs))({
207
+ apiKey: input.apiKey,
208
+ ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),
209
+ model: input.model,
210
+ system: input.system,
211
+ contents,
212
+ tools,
213
+ ...(input.maxTokens !== undefined ? { maxOutputTokens: input.maxTokens } : {}),
214
+ ...(input.maxToolTurns !== undefined ? { maxToolTurns: input.maxToolTurns } : {}),
215
+ executeTool,
216
+ ...(input.signal ? { signal: input.signal } : {}),
217
+ onEvent: (event) => {
218
+ if (event.type === "fabricated_role_marker")
219
+ return;
220
+ if (event.type === "end")
221
+ capturedEndReason = event.reason;
222
+ if (event.type === "tool_result") {
223
+ input.onEvent({
224
+ type: "tool_result",
225
+ toolUseId: event.toolUseId,
226
+ content: describeToolResultContent(event.content),
227
+ isError: event.isError,
228
+ });
229
+ return;
230
+ }
231
+ input.onEvent(event);
232
+ },
233
+ });
234
+ return normalizeTurnResult(result, capturedEndReason);
235
+ }
236
+ /** Runs one provider-neutral turn through the supplied adapters. The adapter end event takes precedence over a raw provider stop code.
237
+ * Local mapping is proportional to the descriptors, expanded schemas and emitted result parts; request and loop cost belongs to the adapter ports.
238
+ */
239
+ export async function runProviderToolTurn(required, optional = {}) {
240
+ const input = { ...optional, ...required };
241
+ switch (input.protocol) {
242
+ case "anthropic":
243
+ return runAnthropicTurn(input);
244
+ case "openai":
245
+ return runOpenAiTurn(input);
246
+ case "azure":
247
+ return runAzureTurn(input);
248
+ case "google":
249
+ return runGoogleTurn(input);
250
+ }
251
+ }
252
+ //# sourceMappingURL=tool-turn.js.map
@@ -2,7 +2,7 @@
2
2
  * @module qoder-stream
3
3
  *
4
4
  * Ported verbatim from OD's `apps/daemon/src/runtimes/qoder-stream.ts`
5
- * (only `node:buffer` as a dependency). See `source-map.md`.
5
+ * (only `node:buffer` as a dependency). See `archived provenance ledger`.
6
6
  *
7
7
  * Parses Qoder CLI's `--output-format stream-json` JSONL stream into the
8
8
  * small event set consumed by the chat UI. Qoder's top-level records are
@@ -38,8 +38,12 @@ export type QoderEvent = {
38
38
  line: string;
39
39
  };
40
40
  type QoderEventSink = (event: QoderEvent) => void;
41
- export declare function createQoderStreamHandler(onEvent: QoderEventSink): {
42
- feed: (chunk: unknown) => void;
41
+ export declare function createQoderStreamHandler({ onEvent }: {
42
+ onEvent: QoderEventSink;
43
+ }): {
44
+ feed: ({ chunk }: {
45
+ chunk: unknown;
46
+ }) => void;
43
47
  flush: () => void;
44
48
  };
45
49
  export {};
@@ -2,7 +2,7 @@
2
2
  * @module qoder-stream
3
3
  *
4
4
  * Ported verbatim from OD's `apps/daemon/src/runtimes/qoder-stream.ts`
5
- * (only `node:buffer` as a dependency). See `source-map.md`.
5
+ * (only `node:buffer` as a dependency). See `archived provenance ledger`.
6
6
  *
7
7
  * Parses Qoder CLI's `--output-format stream-json` JSONL stream into the
8
8
  * small event set consumed by the chat UI. Qoder's top-level records are
@@ -60,7 +60,7 @@ function messageFromResult(obj) {
60
60
  }
61
61
  return 'Qoder run failed';
62
62
  }
63
- export function createQoderStreamHandler(onEvent) {
63
+ export function createQoderStreamHandler({ onEvent }) {
64
64
  let buffer = '';
65
65
  let emittedThinkingStart = false;
66
66
  function handleObject(obj, rawLine) {
@@ -144,7 +144,7 @@ export function createQoderStreamHandler(onEvent) {
144
144
  onEvent({ type: 'raw', line });
145
145
  }
146
146
  }
147
- function feed(chunk) {
147
+ function feed({ chunk }) {
148
148
  buffer += stringifyContent(chunk);
149
149
  let nl;
150
150
  while ((nl = buffer.indexOf('\n')) !== -1) {
@@ -1,7 +1,9 @@
1
1
  import type { RuntimeAgentDef } from './types.js';
2
2
  export declare const BASE_AGENT_DEFS: RuntimeAgentDef[];
3
3
  export declare const AGENT_DEFS: RuntimeAgentDef[];
4
- export declare function getAgentDef(id: string): RuntimeAgentDef | null;
4
+ export declare function getAgentDef({ id }: {
5
+ id: string;
6
+ }): RuntimeAgentDef | null;
5
7
  /**
6
8
  * Whether a caller can inject external MCP servers (the host application's or this engine's own
7
9
  * tools) into a session run by this
@@ -18,5 +20,7 @@ export declare function getAgentDef(id: string): RuntimeAgentDef | null;
18
20
  *
19
21
  * @complexity Time/space: O(1).
20
22
  */
21
- export declare function runtimeSupportsExternalTools(def: Pick<RuntimeAgentDef, 'externalMcpInjection'>): boolean;
23
+ export declare function runtimeSupportsExternalTools({ def }: {
24
+ def: Pick<RuntimeAgentDef, 'externalMcpInjection'>;
25
+ }): boolean;
22
26
  //# sourceMappingURL=registry.d.ts.map
package/dist/registry.js CHANGED
@@ -12,10 +12,10 @@
12
12
  * product-branded default path under the user's home dir, reads a
13
13
  * product-prefixed data-dir env var, and depends on OD's daemon-level
14
14
  * sandbox-runtime-config subsystem (out of this package's charter
15
- * entirely; see `source-map.md` for the exact original names). `AGENT_DEFS`
15
+ * entirely; see `archived provenance ledger` for the exact original names). `AGENT_DEFS`
16
16
  * here is exactly `BASE_AGENT_DEFS` (no local-profile merge). A future task
17
17
  * can reintroduce a de-branded, sandbox-free local-profile loader as an
18
- * injected port if a consumer needs it. See `source-map.md`.
18
+ * injected port if a consumer needs it. See `archived provenance ledger`.
19
19
  */
20
20
  import { aiderAgentDef, ampAgentDef, amrAgentDef, antigravityAgentDef, auggieAgentDef, claudeAgentDef, clineAgentDef, codebuddyAgentDef, codexAgentDef, copilotAgentDef, crushAgentDef, cursorAgentDef, deepseekAgentDef, devinAgentDef, droidAgentDef, geminiAgentDef, gooseAgentDef, grokBuildAgentDef, hermesAgentDef, kiloAgentDef, kimiAgentDef, kiroAgentDef, mimoAgentDef, opencodeAgentDef, piAgentDef, qoderAgentDef, qwenAgentDef, reasonixAgentDef, traeCliAgentDef, vibeAgentDef, } from './defs/index.js';
21
21
  export const BASE_AGENT_DEFS = [
@@ -58,7 +58,7 @@ for (const def of AGENT_DEFS) {
58
58
  }
59
59
  ids.add(def.id);
60
60
  }
61
- export function getAgentDef(id) {
61
+ export function getAgentDef({ id }) {
62
62
  return AGENT_DEFS.find((a) => a.id === id) || null;
63
63
  }
64
64
  /**
@@ -77,7 +77,7 @@ export function getAgentDef(id) {
77
77
  *
78
78
  * @complexity Time/space: O(1).
79
79
  */
80
- export function runtimeSupportsExternalTools(def) {
80
+ export function runtimeSupportsExternalTools({ def }) {
81
81
  return def.externalMcpInjection !== undefined;
82
82
  }
83
83
  //# sourceMappingURL=registry.js.map
@@ -1,2 +1,6 @@
1
- export declare function resolveAgentBin(id: string, configuredEnv?: Record<string, string>): string | null;
1
+ export declare function resolveAgentBin({ id }: {
2
+ id: string;
3
+ }, { configuredEnv }?: {
4
+ configuredEnv?: Record<string, string>;
5
+ }): string | null;
2
6
  //# sourceMappingURL=resolution.d.ts.map
@@ -10,10 +10,10 @@ import { resolveAgentExecutable } from './executables.js';
10
10
  // Used by the chat handler so spawn() gets the same executable that
11
11
  // detection reported as available — fixes Windows ENOENT when the bare
12
12
  // bin name isn't on the child process's PATH.
13
- export function resolveAgentBin(id, configuredEnv = {}) {
14
- const def = getAgentDef(id);
13
+ export function resolveAgentBin({ id }, { configuredEnv = {} } = {}) {
14
+ const def = getAgentDef({ id: id });
15
15
  if (!def?.bin)
16
16
  return null;
17
- return resolveAgentExecutable(def, configuredEnv);
17
+ return resolveAgentExecutable({ def: def }, { configuredEnv: configuredEnv });
18
18
  }
19
19
  //# sourceMappingURL=resolution.js.map
@@ -13,7 +13,7 @@
13
13
  * Ported verbatim from OD's `apps/daemon/src/role-marker-guard.ts` (a
14
14
  * top-level daemon file, not under `runtimes/`, but consumed by
15
15
  * `claude-stream.ts` and self-contained with no product coupling — see
16
- * `source-map.md`).
16
+ * `archived provenance ledger`).
17
17
  */
18
18
  export declare const FABRICATED_ROLE_MARKER_RE: RegExp;
19
19
  export type RoleMarkerWarningEvent = {
@@ -25,7 +25,9 @@ export interface RoleMarkerGuard {
25
25
  /** Feed a text delta for the current message. Returns the safe portion
26
26
  * to emit (may be shorter than `text` if a marker was found mid-chunk,
27
27
  * or empty string if the entire chunk is past the cut point). */
28
- feedText(text: string): string;
28
+ feedText(requiredArgs: {
29
+ text: string;
30
+ }): string;
29
31
  /** Whether a fabricated marker was detected (further text is dropped). */
30
32
  readonly contaminated: boolean;
31
33
  /** If contaminated, the warning event to emit. `null` if clean. */
@@ -40,9 +42,9 @@ export interface RoleMarkerGuard {
40
42
  *
41
43
  * Usage in a stream handler:
42
44
  *
43
- * const guard = createRoleMarkerGuard(messageId);
45
+ * const guard = createRoleMarkerGuard({ messageId });
44
46
  * for (const delta of deltas) {
45
- * const safe = guard.feedText(delta.text);
47
+ * const safe = guard.feedText({ text: delta.text });
46
48
  * if (safe.length > 0) onEvent({ type: 'text_delta', delta: safe });
47
49
  * if (guard.contaminated) {
48
50
  * onEvent(guard.warningEvent()!);
@@ -50,5 +52,7 @@ export interface RoleMarkerGuard {
50
52
  * }
51
53
  * }
52
54
  */
53
- export declare function createRoleMarkerGuard(messageId: string): RoleMarkerGuard;
55
+ export declare function createRoleMarkerGuard({ messageId }: {
56
+ messageId: string;
57
+ }): RoleMarkerGuard;
54
58
  //# sourceMappingURL=role-marker-guard.d.ts.map
@@ -13,7 +13,7 @@
13
13
  * Ported verbatim from OD's `apps/daemon/src/role-marker-guard.ts` (a
14
14
  * top-level daemon file, not under `runtimes/`, but consumed by
15
15
  * `claude-stream.ts` and self-contained with no product coupling — see
16
- * `source-map.md`).
16
+ * `archived provenance ledger`).
17
17
  */
18
18
  // Regex matching fabricated role-marker lines injected by the model into
19
19
  // its own output. Anchored to start-of-line via (?:^|\n) so we don't
@@ -140,9 +140,9 @@ const TAIL_BUFFER_SIZE = 64;
140
140
  *
141
141
  * Usage in a stream handler:
142
142
  *
143
- * const guard = createRoleMarkerGuard(messageId);
143
+ * const guard = createRoleMarkerGuard({ messageId });
144
144
  * for (const delta of deltas) {
145
- * const safe = guard.feedText(delta.text);
145
+ * const safe = guard.feedText({ text: delta.text });
146
146
  * if (safe.length > 0) onEvent({ type: 'text_delta', delta: safe });
147
147
  * if (guard.contaminated) {
148
148
  * onEvent(guard.warningEvent()!);
@@ -150,7 +150,7 @@ const TAIL_BUFFER_SIZE = 64;
150
150
  * }
151
151
  * }
152
152
  */
153
- export function createRoleMarkerGuard(messageId) {
153
+ export function createRoleMarkerGuard({ messageId }) {
154
154
  // Rolling tail of the bytes we have ALREADY EMITTED, capped at
155
155
  // TAIL_BUFFER_SIZE. Used as the prefix when matching against new
156
156
  // text so we catch markers that straddle a chunk boundary.
@@ -186,7 +186,7 @@ export function createRoleMarkerGuard(messageId) {
186
186
  get contaminated() {
187
187
  return _contaminated;
188
188
  },
189
- feedText(text) {
189
+ feedText({ text }) {
190
190
  if (_contaminated)
191
191
  return '';
192
192
  if (text.length === 0)
@@ -7,5 +7,10 @@ export type TerminalLaunchResult = {
7
7
  platform: NodeJS.Platform;
8
8
  reason: string;
9
9
  };
10
- export declare function launchAgentInSystemTerminal(command: string, platform?: NodeJS.Platform, windowTitle?: string): Promise<TerminalLaunchResult>;
10
+ export declare function launchAgentInSystemTerminal({ command }: {
11
+ command: string;
12
+ }, { platform, windowTitle }?: {
13
+ platform?: NodeJS.Platform;
14
+ windowTitle?: string;
15
+ }): Promise<TerminalLaunchResult>;
11
16
  //# sourceMappingURL=terminal-launch.d.ts.map
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * Ported from OD's `apps/daemon/src/runtimes/terminal-launch.ts`
12
12
  * with one de-branding change: the Windows path opened a `cmd.exe` window
13
- * titled literally with the product's own name (see `source-map.md` for
13
+ * titled literally with the product's own name (see `archived provenance ledger` for
14
14
  * the exact original string). `launchAgentInSystemTerminal` now takes an
15
15
  * optional `windowTitle` (default `'Agent Sign-in'`).
16
16
  *
@@ -104,7 +104,7 @@ async function launchOnWindows(command, windowTitle) {
104
104
  };
105
105
  }
106
106
  }
107
- export async function launchAgentInSystemTerminal(command, platform = process.platform, windowTitle = 'Agent Sign-in') {
107
+ export async function launchAgentInSystemTerminal({ command }, { platform = process.platform, windowTitle = 'Agent Sign-in' } = {}) {
108
108
  switch (platform) {
109
109
  case 'darwin':
110
110
  return launchOnDarwin(command);
package/dist/types.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * runtime-probed sibling.
10
10
  *
11
11
  * Ported from OD's `apps/daemon/src/runtimes/types.ts`. Product-neutral
12
- * as found — see `source-map.md` for the full provenance table.
12
+ * as found — see `archived provenance ledger` for the full provenance table.
13
13
  */
14
14
  import type { ExecFileOptions } from 'node:child_process';
15
15
  import type { AgentDiagnostic } from '@jini-ai/protocol';
@@ -124,7 +124,9 @@ export type RuntimeCapabilityMap = Record<string, boolean>;
124
124
  export type RuntimeListModels = {
125
125
  args: string[];
126
126
  timeoutMs: number;
127
- parse: (stdout: string) => RuntimeModelOption[] | null;
127
+ parse: (requiredArgs: {
128
+ stdout: string;
129
+ }) => RuntimeModelOption[] | null;
128
130
  };
129
131
  export type RuntimePromptBudgetError = {
130
132
  code: 'AGENT_PROMPT_TOO_LARGE';
@@ -173,7 +175,9 @@ export type RuntimeStdoutPolicy =
173
175
  * nothing better to fall back on than the unsanitized text, so a
174
176
  * throwing sanitizer is the leak it was added to prevent.
175
177
  */
176
- readonly sanitize?: (fullText: string) => string;
178
+ readonly sanitize?: (requiredArgs: {
179
+ fullText: string;
180
+ }) => string;
177
181
  };
178
182
  /**
179
183
  * Context for {@link RuntimeLock.acquire}, so a def can decide whether the
@@ -273,7 +277,14 @@ export type RuntimeAgentDef = {
273
277
  * does that comparison for you whenever the relevant CLI is installed.
274
278
  */
275
279
  fallbackModelsAssertedAt?: string;
276
- buildArgs: (prompt: string, imagePaths: string[], extraAllowedDirs?: string[], options?: RuntimeBuildOptions, runtimeContext?: RuntimeContext) => string[];
280
+ buildArgs: (requiredArgs: {
281
+ prompt: string;
282
+ imagePaths: string[];
283
+ }, optionalArgs?: {
284
+ extraAllowedDirs?: string[];
285
+ options?: RuntimeBuildOptions;
286
+ runtimeContext?: RuntimeContext;
287
+ }) => string[];
277
288
  streamFormat: string;
278
289
  fallbackBins?: string[];
279
290
  versionProbeTimeoutMs?: number;
@@ -285,7 +296,10 @@ export type RuntimeAgentDef = {
285
296
  eventParser?: string;
286
297
  env?: Record<string, string>;
287
298
  listModels?: RuntimeListModels;
288
- fetchModels?: (resolvedBin: string, env: RuntimeEnv) => Promise<RuntimeModelOption[] | null>;
299
+ fetchModels?: (requiredArgs: {
300
+ resolvedBin: string;
301
+ env: RuntimeEnv;
302
+ }) => Promise<RuntimeModelOption[] | null>;
289
303
  reasoningOptions?: RuntimeReasoningOption[];
290
304
  /**
291
305
  * Narrows `reasoningOptions` to what the runtime's LIVE model list actually supports.
@@ -303,7 +317,9 @@ export type RuntimeAgentDef = {
303
317
  *
304
318
  * Stripped from `DetectedAgent` alongside the other closures — see `detection.ts#stripFns`.
305
319
  */
306
- deriveReasoningOptions?: (models: readonly RuntimeModelOption[]) => RuntimeReasoningOption[] | null;
320
+ deriveReasoningOptions?: (requiredArgs: {
321
+ models: readonly RuntimeModelOption[];
322
+ }) => RuntimeReasoningOption[] | null;
307
323
  /**
308
324
  * See {@link RuntimeReasoningInModelId}. Mutually exclusive with
309
325
  * `reasoningOptions` in practice: a def declaring both would tell a picker
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/agent-runtime",
3
- "version": "0.3.10",
3
+ "version": "0.4.0",
4
4
  "description": "Coding-agent runtime adapters: runtime registry, detection, launch, stream parsers, and the ACP/pi-rpc subprocess transport.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -11,7 +11,13 @@
11
11
  "jini": {
12
12
  "domain": "agent",
13
13
  "kind": "runtime",
14
- "runtime": "node"
14
+ "runtime": "node",
15
+ "entries": {
16
+ ".": "node",
17
+ "./providers/tool-turn": "node",
18
+ "./model-catalog/cache": "universal",
19
+ "./providers/sse-decode": "universal"
20
+ }
15
21
  },
16
22
  "type": "module",
17
23
  "sideEffects": false,
@@ -22,10 +28,41 @@
22
28
  "types": "./dist/index.d.ts",
23
29
  "import": "./dist/index.js",
24
30
  "default": "./dist/index.js"
31
+ },
32
+ "./providers/tool-turn": {
33
+ "types": "./dist/providers/tool-turn.d.ts",
34
+ "import": "./dist/providers/tool-turn.js",
35
+ "default": "./dist/providers/tool-turn.js"
36
+ },
37
+ "./model-catalog/cache": {
38
+ "types": "./dist/model-catalog-cache.d.ts",
39
+ "import": "./dist/model-catalog-cache.js",
40
+ "default": "./dist/model-catalog-cache.js"
41
+ },
42
+ "./providers/sse-decode": {
43
+ "types": "./dist/providers/sse-decode.d.ts",
44
+ "import": "./dist/providers/sse-decode.js",
45
+ "default": "./dist/providers/sse-decode.js"
46
+ }
47
+ },
48
+ "typesVersions": {
49
+ "*": {
50
+ "providers/tool-turn": [
51
+ "./dist/providers/tool-turn.d.ts"
52
+ ],
53
+ "model-catalog/cache": [
54
+ "./dist/model-catalog-cache.d.ts"
55
+ ],
56
+ "providers/sse-decode": [
57
+ "./dist/providers/sse-decode.d.ts"
58
+ ]
25
59
  }
26
60
  },
27
61
  "files": [
28
62
  "dist",
63
+ "README.md",
64
+ "CHANGELOG.md",
65
+ "LICENSE",
29
66
  "!dist/**/*.test.js",
30
67
  "!dist/**/*.test.d.ts",
31
68
  "!dist/**/*.test.js.map",
@@ -38,8 +75,10 @@
38
75
  "registry": "https://registry.npmjs.org"
39
76
  },
40
77
  "dependencies": {
41
- "@jini-ai/platform": "0.3.0",
42
- "@jini-ai/protocol": "0.3.1"
78
+ "@jini-ai/core": "^0.4.0",
79
+ "@jini-ai/platform": "0.5.0",
80
+ "@jini-ai/oauth": "0.2.0",
81
+ "@jini-ai/protocol": "0.4.0"
43
82
  },
44
83
  "devDependencies": {
45
84
  "@vitest/coverage-v8": "^2.1.9"