@4onstudios/iris-agent 0.1.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +690 -0
  3. package/dist/api/acp/acpServer.d.ts +23 -0
  4. package/dist/api/acp/acpServer.js +814 -0
  5. package/dist/api/acp/index.d.ts +2 -0
  6. package/dist/api/acp/index.js +2 -0
  7. package/dist/api/acp/irisClient.d.ts +58 -0
  8. package/dist/api/acp/irisClient.js +214 -0
  9. package/dist/api/agent.d.ts +14 -0
  10. package/dist/api/agent.js +4171 -0
  11. package/dist/api/backendService.d.ts +4 -0
  12. package/dist/api/backendService.js +14 -0
  13. package/dist/api/core/agent/host/AgentContract.d.ts +82 -0
  14. package/dist/api/core/agent/host/AgentContract.js +1 -0
  15. package/dist/api/core/agent/host/AgentRegistry.d.ts +24 -0
  16. package/dist/api/core/agent/host/AgentRegistry.js +125 -0
  17. package/dist/api/core/agent/host/defaultRegistry.d.ts +15 -0
  18. package/dist/api/core/agent/host/defaultRegistry.js +46 -0
  19. package/dist/api/core/agent/host/externalAgentLifecycle.d.ts +65 -0
  20. package/dist/api/core/agent/host/externalAgentLifecycle.js +117 -0
  21. package/dist/api/core/agent/host/hostSessionManager.d.ts +111 -0
  22. package/dist/api/core/agent/host/hostSessionManager.js +352 -0
  23. package/dist/api/core/agent/host/index.d.ts +5 -0
  24. package/dist/api/core/agent/host/index.js +5 -0
  25. package/dist/api/core/agent/index.d.ts +87 -0
  26. package/dist/api/core/agent/index.js +1024 -0
  27. package/dist/api/core/agent/publicContracts.d.ts +35 -0
  28. package/dist/api/core/agent/publicContracts.js +103 -0
  29. package/dist/api/core/agent/tools/applyDiff.d.ts +51 -0
  30. package/dist/api/core/agent/tools/applyDiff.js +131 -0
  31. package/dist/api/core/agent/tools/backgroundTasks.d.ts +240 -0
  32. package/dist/api/core/agent/tools/backgroundTasks.js +313 -0
  33. package/dist/api/core/agent/tools/createDirectory.d.ts +43 -0
  34. package/dist/api/core/agent/tools/createDirectory.js +77 -0
  35. package/dist/api/core/agent/tools/deleteFile.d.ts +37 -0
  36. package/dist/api/core/agent/tools/deleteFile.js +66 -0
  37. package/dist/api/core/agent/tools/editFile.d.ts +73 -0
  38. package/dist/api/core/agent/tools/editFile.js +173 -0
  39. package/dist/api/core/agent/tools/executeCommand.d.ts +59 -0
  40. package/dist/api/core/agent/tools/executeCommand.js +250 -0
  41. package/dist/api/core/agent/tools/fileContent.d.ts +54 -0
  42. package/dist/api/core/agent/tools/fileContent.js +227 -0
  43. package/dist/api/core/agent/tools/findDefinition.d.ts +72 -0
  44. package/dist/api/core/agent/tools/findDefinition.js +109 -0
  45. package/dist/api/core/agent/tools/findReferences.d.ts +86 -0
  46. package/dist/api/core/agent/tools/findReferences.js +135 -0
  47. package/dist/api/core/agent/tools/formatDocument.d.ts +67 -0
  48. package/dist/api/core/agent/tools/formatDocument.js +90 -0
  49. package/dist/api/core/agent/tools/getCodeActions.d.ts +77 -0
  50. package/dist/api/core/agent/tools/getCodeActions.js +97 -0
  51. package/dist/api/core/agent/tools/getCodeCompletion.d.ts +77 -0
  52. package/dist/api/core/agent/tools/getCodeCompletion.js +174 -0
  53. package/dist/api/core/agent/tools/getCodeContext.d.ts +14 -0
  54. package/dist/api/core/agent/tools/getCodeContext.js +282 -0
  55. package/dist/api/core/agent/tools/getSignatureHelp.d.ts +61 -0
  56. package/dist/api/core/agent/tools/getSignatureHelp.js +85 -0
  57. package/dist/api/core/agent/tools/getSymbols.d.ts +50 -0
  58. package/dist/api/core/agent/tools/getSymbols.js +164 -0
  59. package/dist/api/core/agent/tools/getSymbolsLSP.d.ts +58 -0
  60. package/dist/api/core/agent/tools/getSymbolsLSP.js +147 -0
  61. package/dist/api/core/agent/tools/getTypeInfo.d.ts +70 -0
  62. package/dist/api/core/agent/tools/getTypeInfo.js +84 -0
  63. package/dist/api/core/agent/tools/getWorkspaceInfo.d.ts +80 -0
  64. package/dist/api/core/agent/tools/getWorkspaceInfo.js +281 -0
  65. package/dist/api/core/agent/tools/getWorkspaceSymbols.d.ts +53 -0
  66. package/dist/api/core/agent/tools/getWorkspaceSymbols.js +97 -0
  67. package/dist/api/core/agent/tools/grepSearch.d.ts +100 -0
  68. package/dist/api/core/agent/tools/grepSearch.js +211 -0
  69. package/dist/api/core/agent/tools/languageModelToolsIntegration.d.ts +13 -0
  70. package/dist/api/core/agent/tools/languageModelToolsIntegration.js +22 -0
  71. package/dist/api/core/agent/tools/listDirectory.d.ts +66 -0
  72. package/dist/api/core/agent/tools/listDirectory.js +161 -0
  73. package/dist/api/core/agent/tools/mcpTools.d.ts +48 -0
  74. package/dist/api/core/agent/tools/mcpTools.js +442 -0
  75. package/dist/api/core/agent/tools/queryKnowledgeGraph.d.ts +120 -0
  76. package/dist/api/core/agent/tools/queryKnowledgeGraph.js +306 -0
  77. package/dist/api/core/agent/tools/readFile.d.ts +92 -0
  78. package/dist/api/core/agent/tools/readFile.js +337 -0
  79. package/dist/api/core/agent/tools/renameFile.d.ts +49 -0
  80. package/dist/api/core/agent/tools/renameFile.js +86 -0
  81. package/dist/api/core/agent/tools/renameSymbol.d.ts +70 -0
  82. package/dist/api/core/agent/tools/renameSymbol.js +106 -0
  83. package/dist/api/core/agent/tools/runTerminalCommand.d.ts +72 -0
  84. package/dist/api/core/agent/tools/runTerminalCommand.js +69 -0
  85. package/dist/api/core/agent/tools/searchFiles.d.ts +82 -0
  86. package/dist/api/core/agent/tools/searchFiles.js +280 -0
  87. package/dist/api/core/agent/tools/terminalAutoApprove.d.ts +3 -0
  88. package/dist/api/core/agent/tools/terminalAutoApprove.js +676 -0
  89. package/dist/api/core/agent/tools/treeTraversal.d.ts +60 -0
  90. package/dist/api/core/agent/tools/treeTraversal.js +217 -0
  91. package/dist/api/core/agent/tools/webSearch.d.ts +37 -0
  92. package/dist/api/core/agent/tools/webSearch.js +80 -0
  93. package/dist/api/core/agent/tools/writeFile.d.ts +59 -0
  94. package/dist/api/core/agent/tools/writeFile.js +97 -0
  95. package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.d.ts +12 -0
  96. package/dist/api/core/agent/utils/capturedWorkspaceMutationBridge.js +67 -0
  97. package/dist/api/core/agent/utils/diffUtils.d.ts +14 -0
  98. package/dist/api/core/agent/utils/diffUtils.js +39 -0
  99. package/dist/api/core/agent/utils/environmentSnapshot.d.ts +42 -0
  100. package/dist/api/core/agent/utils/environmentSnapshot.js +213 -0
  101. package/dist/api/core/agent/utils/errorRecovery.d.ts +49 -0
  102. package/dist/api/core/agent/utils/errorRecovery.js +229 -0
  103. package/dist/api/core/agent/utils/multimodalTokenLimiter.d.ts +8 -0
  104. package/dist/api/core/agent/utils/multimodalTokenLimiter.js +238 -0
  105. package/dist/api/core/agent/utils/openRouterModelSettings.d.ts +12 -0
  106. package/dist/api/core/agent/utils/openRouterModelSettings.js +34 -0
  107. package/dist/api/core/agent/utils/pathRecovery.d.ts +1 -0
  108. package/dist/api/core/agent/utils/pathRecovery.js +29 -0
  109. package/dist/api/core/agent/utils/repoMapIndex.d.ts +3 -0
  110. package/dist/api/core/agent/utils/repoMapIndex.js +197 -0
  111. package/dist/api/core/agent/utils/skillsDiscovery.d.ts +10 -0
  112. package/dist/api/core/agent/utils/skillsDiscovery.js +50 -0
  113. package/dist/api/core/agent/utils/toolCallBudget.d.ts +9 -0
  114. package/dist/api/core/agent/utils/toolCallBudget.js +55 -0
  115. package/dist/api/core/agent/utils/toolLifecycle.d.ts +30 -0
  116. package/dist/api/core/agent/utils/toolLifecycle.js +361 -0
  117. package/dist/api/core/agent/utils/toolResultSafetyProcessor.d.ts +12 -0
  118. package/dist/api/core/agent/utils/toolResultSafetyProcessor.js +57 -0
  119. package/dist/api/core/agent/utils/workspaceMutationBridge.d.ts +13 -0
  120. package/dist/api/core/agent/utils/workspaceMutationBridge.js +149 -0
  121. package/dist/api/core/agent/utils/workspacePathGuard.d.ts +7 -0
  122. package/dist/api/core/agent/utils/workspacePathGuard.js +79 -0
  123. package/dist/api/core/containers/chat/toolResultSerialization.d.ts +8 -0
  124. package/dist/api/core/containers/chat/toolResultSerialization.js +71 -0
  125. package/dist/api/core/library/BrowserManager.d.ts +11 -0
  126. package/dist/api/core/library/BrowserManager.js +66 -0
  127. package/dist/api/core/library/desktopWorkspace.d.ts +1 -0
  128. package/dist/api/core/library/desktopWorkspace.js +3 -0
  129. package/dist/api/core/library/extensionManager.d.ts +10 -0
  130. package/dist/api/core/library/extensionManager.js +27 -0
  131. package/dist/api/core/library/knowledgeGraph.d.ts +268 -0
  132. package/dist/api/core/library/knowledgeGraph.js +989 -0
  133. package/dist/api/core/library/languageModelTools.d.ts +141 -0
  134. package/dist/api/core/library/languageModelTools.js +207 -0
  135. package/dist/api/core/library/localRuntime.d.ts +23 -0
  136. package/dist/api/core/library/localRuntime.js +144 -0
  137. package/dist/api/core/library/lsp/coreLsp.d.ts +367 -0
  138. package/dist/api/core/library/lsp/coreLsp.js +2076 -0
  139. package/dist/api/core/library/lsp/protocol.d.ts +25 -0
  140. package/dist/api/core/library/lsp/protocol.js +1 -0
  141. package/dist/api/core/library/lsp/serverManager.d.ts +37 -0
  142. package/dist/api/core/library/lsp/serverManager.js +427 -0
  143. package/dist/api/core/library/mcpServerProvider.d.ts +69 -0
  144. package/dist/api/core/library/mcpServerProvider.js +152 -0
  145. package/dist/api/core/library/mcpSettings.d.ts +20 -0
  146. package/dist/api/core/library/mcpSettings.js +131 -0
  147. package/dist/api/core/library/patternMatcher.d.ts +66 -0
  148. package/dist/api/core/library/patternMatcher.js +284 -0
  149. package/dist/api/core/library/regexEscape.d.ts +4 -0
  150. package/dist/api/core/library/regexEscape.js +4 -0
  151. package/dist/api/core/library/runtimeEventBus.d.ts +27 -0
  152. package/dist/api/core/library/runtimeEventBus.js +78 -0
  153. package/dist/api/core/library/safetyMiddleware.d.ts +98 -0
  154. package/dist/api/core/library/safetyMiddleware.js +215 -0
  155. package/dist/api/core/library/tauri.d.ts +71 -0
  156. package/dist/api/core/library/tauri.js +222 -0
  157. package/dist/api/core/library/tauriImport.d.ts +5 -0
  158. package/dist/api/core/library/tauriImport.js +7 -0
  159. package/dist/api/core/library/terminalAutoApproveSettings.d.ts +32 -0
  160. package/dist/api/core/library/terminalAutoApproveSettings.js +529 -0
  161. package/dist/api/core/library/workspaceIdentity.d.ts +10 -0
  162. package/dist/api/core/library/workspaceIdentity.js +49 -0
  163. package/dist/api/core/library/workspaceSummary.d.ts +19 -0
  164. package/dist/api/core/library/workspaceSummary.js +35 -0
  165. package/dist/api/core/skills/agent-customization/SKILL.md +27 -0
  166. package/dist/api/core/skills/bug-fix/SKILL.md +21 -0
  167. package/dist/api/core/skills/create-pr/SKILL.md +32 -0
  168. package/dist/api/core/skills/dev-server/SKILL.md +20 -0
  169. package/dist/api/core/skills/fix-suggestions/SKILL.md +21 -0
  170. package/dist/api/core/skills/github-search/SKILL.md +21 -0
  171. package/dist/api/core/skills/github-summary/SKILL.md +25 -0
  172. package/dist/api/core/skills/integration-tests/SKILL.md +29 -0
  173. package/dist/api/core/skills/pr-comments/SKILL.md +23 -0
  174. package/dist/api/core/skills/project-setup/SKILL.md +20 -0
  175. package/dist/api/core/skills/search-integration/SKILL.md +19 -0
  176. package/dist/api/core/skills/search-results/SKILL.md +19 -0
  177. package/dist/api/core/skills/typescript-upgrade/SKILL.md +21 -0
  178. package/dist/api/data/runStore.d.ts +46 -0
  179. package/dist/api/data/runStore.js +244 -0
  180. package/dist/api/helpers/agentUtils.d.ts +11 -0
  181. package/dist/api/helpers/agentUtils.js +23 -0
  182. package/dist/api/helpers/modelTokenLimits.d.ts +2 -0
  183. package/dist/api/helpers/modelTokenLimits.js +158 -0
  184. package/dist/api/helpers/observationalMemory.d.ts +10 -0
  185. package/dist/api/helpers/observationalMemory.js +36 -0
  186. package/dist/api/helpers/promptBudget.d.ts +30 -0
  187. package/dist/api/helpers/promptBudget.js +216 -0
  188. package/dist/api/helpers/resolveImageMessageParts.d.ts +9 -0
  189. package/dist/api/helpers/resolveImageMessageParts.js +140 -0
  190. package/dist/api/helpers/slashCommands.d.ts +31 -0
  191. package/dist/api/helpers/slashCommands.js +129 -0
  192. package/dist/api/helpers/tokenUsage.d.ts +19 -0
  193. package/dist/api/helpers/tokenUsage.js +81 -0
  194. package/dist/api/routes/fileRoutes.d.ts +2 -0
  195. package/dist/api/routes/fileRoutes.js +108 -0
  196. package/dist/api/routes/lspDocumentRoutes.d.ts +4 -0
  197. package/dist/api/routes/lspDocumentRoutes.js +84 -0
  198. package/dist/api/routes/lspHierarchyRoutes.d.ts +4 -0
  199. package/dist/api/routes/lspHierarchyRoutes.js +122 -0
  200. package/dist/api/routes/lspPositionRoutes.d.ts +4 -0
  201. package/dist/api/routes/lspPositionRoutes.js +263 -0
  202. package/dist/api/routes/lspQueryRoutes.d.ts +4 -0
  203. package/dist/api/routes/lspQueryRoutes.js +679 -0
  204. package/dist/api/routes/lspResolveRoutes.d.ts +4 -0
  205. package/dist/api/routes/lspResolveRoutes.js +143 -0
  206. package/dist/api/routes/lspSemanticDocumentRoutes.d.ts +4 -0
  207. package/dist/api/routes/lspSemanticDocumentRoutes.js +98 -0
  208. package/dist/api/routes/semanticRoutes.d.ts +2 -0
  209. package/dist/api/routes/semanticRoutes.js +126 -0
  210. package/dist/cli.d.ts +8 -0
  211. package/dist/cli.js +160 -0
  212. package/dist/index.d.ts +1 -0
  213. package/dist/index.js +1 -0
  214. package/dist/server.d.ts +2 -0
  215. package/dist/server.js +38 -0
  216. package/package.json +100 -0
@@ -0,0 +1,352 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { getToolCallSignature } from "../utils/toolLifecycle.js";
3
+ const asRecord = (value) => {
4
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
5
+ return undefined;
6
+ }
7
+ return value;
8
+ };
9
+ const toAgentTurnRequest = (sessionId, request) => ({
10
+ sessionId,
11
+ input: request.prompt,
12
+ conversation: request.conversation,
13
+ metadata: request.metadata,
14
+ });
15
+ const getDeclaredToolCalls = (metadata) => {
16
+ const declared = metadata?.declaredToolCalls;
17
+ if (!Array.isArray(declared)) {
18
+ return [];
19
+ }
20
+ const parsed = [];
21
+ for (const item of declared) {
22
+ const value = asRecord(item);
23
+ const toolName = typeof value?.toolName === "string" ? value.toolName.trim() : "";
24
+ if (!toolName)
25
+ continue;
26
+ const toolCallId = typeof value?.toolCallId === "string" ? value.toolCallId : undefined;
27
+ const toolArgs = asRecord(value?.toolArgs);
28
+ parsed.push({ toolName, toolCallId, toolArgs });
29
+ }
30
+ return parsed;
31
+ };
32
+ const extractFeedback = (result) => {
33
+ if ((result.kind === "reject" || result.kind === "ask") && typeof result.feedback === "string") {
34
+ return result.feedback;
35
+ }
36
+ return undefined;
37
+ };
38
+ const enforceDeclaredToolHooks = async (hooks, turnRequest, invocation) => {
39
+ const declaredToolCalls = getDeclaredToolCalls(turnRequest.metadata);
40
+ for (const declared of declaredToolCalls) {
41
+ await turnRequest.onPreToolUse?.({
42
+ toolName: declared.toolName,
43
+ toolCallId: declared.toolCallId,
44
+ toolArgs: declared.toolArgs,
45
+ });
46
+ }
47
+ };
48
+ const createPreToolUseHook = (hooks, turnRequest, invocation) => {
49
+ const hasArgumentDetails = (toolArgs) => Object.keys(toolArgs || {}).length > 0;
50
+ const identifiedSignaturesByTool = new Map();
51
+ const getIdentifiedToolKey = (toolCallId, toolName) => `${toolCallId}:${toolName}`;
52
+ const registerIdentifiedSignature = (toolName, toolCallId, toolArgs) => {
53
+ if (!hasArgumentDetails(toolArgs))
54
+ return;
55
+ const toolKey = getIdentifiedToolKey(toolCallId, toolName);
56
+ const signatures = identifiedSignaturesByTool.get(toolKey) || new Set();
57
+ signatures.add(getToolCallSignature(toolName, toolArgs || {}));
58
+ identifiedSignaturesByTool.set(toolKey, signatures);
59
+ };
60
+ const getResolutionKeys = (toolName, toolCallId, toolArgs) => {
61
+ const signature = getToolCallSignature(toolName, toolArgs || {});
62
+ if (!toolCallId) {
63
+ return [`anonymous:${signature}`];
64
+ }
65
+ const genericKey = `${toolCallId}:${toolName}:generic`;
66
+ if (hasArgumentDetails(toolArgs)) {
67
+ registerIdentifiedSignature(toolName, toolCallId, toolArgs);
68
+ return [`${toolCallId}:${signature}`, genericKey];
69
+ }
70
+ const signatures = identifiedSignaturesByTool.get(getIdentifiedToolKey(toolCallId, toolName));
71
+ if (signatures && signatures.size === 1) {
72
+ const [onlySignature] = Array.from(signatures);
73
+ return [`${toolCallId}:${onlySignature}`, genericKey];
74
+ }
75
+ return [genericKey];
76
+ };
77
+ for (const declared of getDeclaredToolCalls(turnRequest.metadata)) {
78
+ if (declared.toolCallId) {
79
+ registerIdentifiedSignature(declared.toolName, declared.toolCallId, declared.toolArgs);
80
+ }
81
+ }
82
+ const declaredRemainingByKey = new Map();
83
+ for (const declared of getDeclaredToolCalls(turnRequest.metadata)) {
84
+ const [key] = getResolutionKeys(declared.toolName, declared.toolCallId, declared.toolArgs);
85
+ declaredRemainingByKey.set(key, (declaredRemainingByKey.get(key) || 0) + 1);
86
+ }
87
+ const declaredInvocationsByKey = new Map();
88
+ const reconciledRuntimeInvocationsByKey = new Map();
89
+ const approvedIdentifiedInvocations = new Set();
90
+ const invokeHook = async ({ toolName, toolCallId, toolArgs, }) => {
91
+ const result = await Promise.resolve(hooks?.onPreToolUse?.({ toolName, toolCallId, toolArgs, turnRequest }, invocation));
92
+ if (result && result.permissionDecision === "deny") {
93
+ throw new Error(`Tool '${toolName}' denied by onPreToolUse hook`);
94
+ }
95
+ if (result && result.permissionDecision === "ask") {
96
+ throw new Error(`Tool '${toolName}' requires external approval`);
97
+ }
98
+ };
99
+ return async ({ toolName, toolCallId, toolArgs }) => {
100
+ const keys = getResolutionKeys(toolName, toolCallId, toolArgs);
101
+ const primaryKey = keys[0];
102
+ const genericResolutionKey = toolCallId ? `${toolCallId}:${toolName}:generic` : undefined;
103
+ const runtimeProvidedArgumentDetails = hasArgumentDetails(toolArgs);
104
+ const declaredKeyToConsume = keys.find((key) => (declaredRemainingByKey.get(key) || 0) > 0);
105
+ if (declaredKeyToConsume) {
106
+ const declaredRemaining = declaredRemainingByKey.get(declaredKeyToConsume) || 0;
107
+ declaredRemainingByKey.set(declaredKeyToConsume, declaredRemaining - 1);
108
+ await invokeHook({ toolName, toolCallId, toolArgs });
109
+ declaredInvocationsByKey.set(declaredKeyToConsume, (declaredInvocationsByKey.get(declaredKeyToConsume) || 0) + 1);
110
+ return;
111
+ }
112
+ const keyToReconcile = keys.find((key) => {
113
+ if (runtimeProvidedArgumentDetails &&
114
+ genericResolutionKey &&
115
+ key === genericResolutionKey) {
116
+ return false;
117
+ }
118
+ const declaredInvocations = declaredInvocationsByKey.get(key) || 0;
119
+ const reconciledInvocations = reconciledRuntimeInvocationsByKey.get(key) || 0;
120
+ return reconciledInvocations < declaredInvocations;
121
+ });
122
+ if (keyToReconcile) {
123
+ const reconciledInvocations = reconciledRuntimeInvocationsByKey.get(keyToReconcile) || 0;
124
+ reconciledRuntimeInvocationsByKey.set(keyToReconcile, reconciledInvocations + 1);
125
+ return;
126
+ }
127
+ if (toolCallId && approvedIdentifiedInvocations.has(primaryKey)) {
128
+ return;
129
+ }
130
+ await invokeHook({ toolName, toolCallId, toolArgs });
131
+ if (toolCallId) {
132
+ approvedIdentifiedInvocations.add(primaryKey);
133
+ }
134
+ };
135
+ };
136
+ const runPostToolHooks = async (hooks, result, invocation) => {
137
+ const toolCalls = Array.isArray(result.toolCalls) ? result.toolCalls : [];
138
+ const toolResults = Array.isArray(result.toolResults) ? result.toolResults : [];
139
+ for (let index = 0; index < toolCalls.length; index += 1) {
140
+ const toolCall = asRecord(toolCalls[index]);
141
+ const toolName = typeof toolCall?.name === "string" && toolCall.name.trim().length > 0
142
+ ? toolCall.name
143
+ : "unknown_tool";
144
+ const toolCallId = typeof toolCall?.toolCallId === "string" ? toolCall.toolCallId : undefined;
145
+ await Promise.resolve(hooks?.onPostToolUse?.({
146
+ toolName,
147
+ toolCallId,
148
+ toolResult: index < toolResults.length ? toolResults[index] : undefined,
149
+ turnResult: result,
150
+ }, invocation));
151
+ }
152
+ };
153
+ export class HostSessionManager {
154
+ runtimeFactory;
155
+ baseContext;
156
+ sessions = new Map();
157
+ pendingSessions = new Map();
158
+ stopping = false;
159
+ constructor(runtimeFactory, baseContext) {
160
+ this.runtimeFactory = runtimeFactory;
161
+ this.baseContext = baseContext;
162
+ }
163
+ async createSession(config = {}) {
164
+ const sessionId = config.sessionId?.trim() || randomUUID();
165
+ return this.openSession(sessionId, config);
166
+ }
167
+ async resumeSession(sessionId, config = {}) {
168
+ const normalized = sessionId.trim();
169
+ if (!normalized) {
170
+ throw new Error("resumeSession requires a non-empty sessionId");
171
+ }
172
+ if (this.sessions.has(normalized)) {
173
+ return this.toHandle(normalized);
174
+ }
175
+ return this.openSession(normalized, { ...config, sessionId: normalized });
176
+ }
177
+ async openSession(sessionId, config) {
178
+ if (this.stopping) {
179
+ throw new Error("Host session manager is stopping");
180
+ }
181
+ if (this.sessions.has(sessionId)) {
182
+ return this.toHandle(sessionId);
183
+ }
184
+ const pending = this.pendingSessions.get(sessionId);
185
+ if (pending) {
186
+ return pending;
187
+ }
188
+ const opening = this.startSession(sessionId, config);
189
+ this.pendingSessions.set(sessionId, opening);
190
+ try {
191
+ return await opening;
192
+ }
193
+ finally {
194
+ this.pendingSessions.delete(sessionId);
195
+ }
196
+ }
197
+ async startSession(sessionId, config) {
198
+ const runtime = await Promise.resolve(this.runtimeFactory());
199
+ const context = {
200
+ sessionId,
201
+ workspacePath: this.baseContext.workspacePath,
202
+ modelId: config.modelId || this.baseContext.modelId,
203
+ metadata: {
204
+ ...(this.baseContext.metadata || {}),
205
+ ...(config.metadata || {}),
206
+ },
207
+ };
208
+ const invocation = { sessionId };
209
+ const session = await runtime.startSession(context);
210
+ try {
211
+ await Promise.resolve(config.hooks?.onSessionStart?.({ context }, invocation));
212
+ this.sessions.set(sessionId, { runtime, session, context, config });
213
+ }
214
+ catch (error) {
215
+ await runtime.endSession(sessionId).catch(() => undefined);
216
+ throw error;
217
+ }
218
+ return this.toHandle(sessionId);
219
+ }
220
+ toHandle(sessionId) {
221
+ return {
222
+ sessionId,
223
+ sendAndWait: async (request) => this.sendAndWait(sessionId, request),
224
+ sendStream: async (request) => this.sendStream(sessionId, request),
225
+ cancel: async () => this.cancelSession(sessionId),
226
+ disconnect: async () => this.disconnectSession(sessionId),
227
+ };
228
+ }
229
+ getManagedSession(sessionId) {
230
+ const managed = this.sessions.get(sessionId);
231
+ if (!managed) {
232
+ throw new Error(`Unknown session '${sessionId}'`);
233
+ }
234
+ return managed;
235
+ }
236
+ async enforcePermission(sessionId, config, request) {
237
+ if (!request || !config.onPermissionRequest) {
238
+ return;
239
+ }
240
+ const result = await Promise.resolve(config.onPermissionRequest(request, {
241
+ sessionId,
242
+ }));
243
+ if (result.kind === "reject" || result.kind === "user-not-available") {
244
+ throw new Error(extractFeedback(result) || "Permission request rejected");
245
+ }
246
+ if (result.kind === "ask" || result.kind === "no-result") {
247
+ throw new Error(extractFeedback(result) || "Permission request requires external resolution");
248
+ }
249
+ }
250
+ async sendAndWait(sessionId, request) {
251
+ const managed = this.getManagedSession(sessionId);
252
+ const invocation = { sessionId };
253
+ const turnRequest = toAgentTurnRequest(sessionId, request);
254
+ turnRequest.onPreToolUse = createPreToolUseHook(managed.config.hooks, turnRequest, invocation);
255
+ await this.enforcePermission(sessionId, managed.config, request.permissionRequest);
256
+ await Promise.resolve(managed.config.hooks?.onPreTurn?.({ request: turnRequest }, invocation));
257
+ await enforceDeclaredToolHooks(managed.config.hooks, turnRequest, invocation);
258
+ const result = await managed.runtime.runTurn(turnRequest);
259
+ await runPostToolHooks(managed.config.hooks, result, invocation);
260
+ await Promise.resolve(managed.config.hooks?.onPostTurn?.({ request: turnRequest, result }, invocation));
261
+ return result;
262
+ }
263
+ async sendStream(sessionId, request) {
264
+ const managed = this.getManagedSession(sessionId);
265
+ if (!managed.runtime.runTurnStream) {
266
+ throw new Error(`Agent '${managed.runtime.descriptor.id}' does not support runTurnStream`);
267
+ }
268
+ const invocation = { sessionId };
269
+ const turnRequest = toAgentTurnRequest(sessionId, request);
270
+ turnRequest.onPreToolUse = createPreToolUseHook(managed.config.hooks, turnRequest, invocation);
271
+ await this.enforcePermission(sessionId, managed.config, request.permissionRequest);
272
+ await Promise.resolve(managed.config.hooks?.onPreTurn?.({ request: turnRequest }, invocation));
273
+ await enforceDeclaredToolHooks(managed.config.hooks, turnRequest, invocation);
274
+ const streamResult = await managed.runtime.runTurnStream(turnRequest);
275
+ let finalizedResultPromise;
276
+ return {
277
+ ...streamResult,
278
+ stream: streamResult.stream,
279
+ getFinalResult: async () => {
280
+ if (!finalizedResultPromise) {
281
+ finalizedResultPromise = (async () => {
282
+ const finalResult = await streamResult.getFinalResult();
283
+ await runPostToolHooks(managed.config.hooks, finalResult, invocation);
284
+ await Promise.resolve(managed.config.hooks?.onPostTurn?.({ request: turnRequest, result: finalResult }, invocation));
285
+ return finalResult;
286
+ })();
287
+ }
288
+ return finalizedResultPromise;
289
+ },
290
+ };
291
+ }
292
+ async disconnectSession(sessionId) {
293
+ const managed = this.sessions.get(sessionId);
294
+ if (!managed) {
295
+ return;
296
+ }
297
+ this.sessions.delete(sessionId);
298
+ const errors = [];
299
+ try {
300
+ if (managed.runtime.cancelTurn) {
301
+ await managed.runtime.cancelTurn(sessionId);
302
+ }
303
+ }
304
+ catch (error) {
305
+ errors.push(error);
306
+ }
307
+ try {
308
+ await Promise.resolve(managed.config.hooks?.onSessionEnd?.({ sessionId }, { sessionId }));
309
+ }
310
+ catch (error) {
311
+ errors.push(error);
312
+ }
313
+ finally {
314
+ try {
315
+ await managed.runtime.endSession(sessionId);
316
+ }
317
+ catch (error) {
318
+ errors.push(error);
319
+ }
320
+ }
321
+ if (errors.length === 1) {
322
+ throw errors[0];
323
+ }
324
+ if (errors.length > 1) {
325
+ throw new AggregateError(errors, `Failed to disconnect host session '${sessionId}'`);
326
+ }
327
+ }
328
+ async cancelSession(sessionId) {
329
+ const managed = this.sessions.get(sessionId);
330
+ if (managed?.runtime.cancelTurn) {
331
+ await managed.runtime.cancelTurn(sessionId);
332
+ }
333
+ }
334
+ async stopAll() {
335
+ this.stopping = true;
336
+ for (const [sessionId, pending] of this.pendingSessions) {
337
+ void pending
338
+ .then(() => this.disconnectSession(sessionId))
339
+ .catch((error) => {
340
+ console.error(`Failed to clean up host session '${sessionId}' during shutdown:`, error);
341
+ });
342
+ }
343
+ const sessionIds = Array.from(this.sessions.keys());
344
+ const results = await Promise.allSettled(sessionIds.map((sessionId) => this.disconnectSession(sessionId)));
345
+ const errors = results
346
+ .filter((result) => result.status === "rejected")
347
+ .map((result) => result.reason);
348
+ if (errors.length > 0) {
349
+ throw new AggregateError(errors, "Failed to stop one or more host sessions");
350
+ }
351
+ }
352
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./AgentContract.js";
2
+ export * from "./AgentRegistry.js";
3
+ export * from "./hostSessionManager.js";
4
+ export * from "./defaultRegistry.js";
5
+ export * from "./externalAgentLifecycle.js";
@@ -0,0 +1,5 @@
1
+ export * from "./AgentContract.js";
2
+ export * from "./AgentRegistry.js";
3
+ export * from "./hostSessionManager.js";
4
+ export * from "./defaultRegistry.js";
5
+ export * from "./externalAgentLifecycle.js";
@@ -0,0 +1,87 @@
1
+ import { type ToolHooks } from "@mastra/core/tools";
2
+ export declare const getSkillsDir: () => string;
3
+ import { RequestContext } from "@mastra/core/request-context";
4
+ import type { McpServerConfig } from "../library/mcpSettings.js";
5
+ import type { TerminalAutoApproveRules } from "../library/terminalAutoApproveSettings.js";
6
+ import { type ToolCallBudget } from "./utils/toolCallBudget.js";
7
+ export { CODING_AGENT_INSTRUCTIONS, createIrisWorkspaceToolsConfig, } from "./publicContracts.js";
8
+ export type AgentFactoryOptions = {
9
+ id?: string;
10
+ name?: string;
11
+ enableMemory?: boolean;
12
+ goalJudgeModelId?: string;
13
+ goalMaxRuns?: number;
14
+ useMastraObservationalMemory?: boolean;
15
+ observationalMemorySettings?: {
16
+ model?: string;
17
+ scope?: "resource" | "thread";
18
+ observationMessageTokens?: number;
19
+ reflectionObservationTokens?: number;
20
+ observationPreviousTokens?: number;
21
+ activateAfterIdle?: string;
22
+ activateOnProviderChange?: boolean;
23
+ };
24
+ storageId?: string;
25
+ dbUrl?: string;
26
+ vectorId?: string;
27
+ maxSteps?: number;
28
+ toolChoice?: "auto" | "none" | "required";
29
+ defaultOptions?: Record<string, unknown>;
30
+ mcpServers?: McpServerConfig[];
31
+ terminalAutoApproveRules?: TerminalAutoApproveRules;
32
+ hooks?: ToolHooks;
33
+ streamErrorRetry?: {
34
+ enabled?: boolean;
35
+ maxRetries?: number;
36
+ retryUnknownErrors?: boolean;
37
+ baseDelayMs?: number;
38
+ maxDelayMs?: number;
39
+ };
40
+ };
41
+ type AgentRequestContextValues = {
42
+ enabledSkills?: string[];
43
+ workspaceMutationGenerationId?: string;
44
+ toolCallBudget?: ToolCallBudget;
45
+ workspaceRoot?: string;
46
+ isWebWorkspace?: boolean;
47
+ gitDetected?: boolean;
48
+ modelId?: string;
49
+ contextFilesMeta?: Array<{
50
+ name?: string;
51
+ path?: string;
52
+ type?: string;
53
+ size?: number;
54
+ isImage?: boolean;
55
+ }>;
56
+ multimodalImageCount?: number;
57
+ onPreToolUse?: (input: {
58
+ toolName: string;
59
+ toolCallId?: string;
60
+ toolArgs?: Record<string, unknown>;
61
+ }) => Promise<void> | void;
62
+ };
63
+ export type AgentRequestValues = Omit<AgentRequestContextValues, "enabledSkills">;
64
+ /**
65
+ * Invalidate the in-process skills cache so that the next call to
66
+ * `loadAllSkills` / `buildSkillsBlock` re-reads the skills directory.
67
+ * Intended for use in tests and development hot-reload scenarios.
68
+ */
69
+ export declare function resetSkillsCache(): void;
70
+ export declare const createAgentRequestContext: (enabledSkills?: string[], requestValues?: AgentRequestValues) => RequestContext<AgentRequestContextValues>;
71
+ /**
72
+ * Return the canonical list of available skills for use by the
73
+ * `GET /api/agent/skills` endpoint. Each entry exposes the directory-name slug
74
+ * as `id` (matching what the client stores in preferences) and the description
75
+ * sourced directly from the SKILL.md frontmatter.
76
+ */
77
+ export declare function getSkillsList(): Promise<Array<{
78
+ id: string;
79
+ description: string;
80
+ }>>;
81
+ export declare const createCodingAgent: (modelId?: string, workspacePath?: string | null, options?: AgentFactoryOptions) => Promise<import("@mastra/core/agent").Agent<string, import("@mastra/core/agent").ToolsInput, undefined, any, import("@mastra/core/agent").AgentEditorConfig> & {
82
+ takeProcessedWorkspaceResults: (generationId: string, toolCallIds: string[]) => {
83
+ toolCallId: string;
84
+ result: Record<string, unknown>;
85
+ }[];
86
+ clearProcessedWorkspaceResults: (generationId: string) => void;
87
+ }>;