@geminixiang/mikan 1.0.0-beta.32 → 1.0.0-beta.34
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.
- package/CHANGELOG.md +42 -0
- package/dist/adapter.d.ts +11 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +18 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +1 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +26 -20
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +2 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +7 -3
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +1 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +10 -5
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/context.d.ts +2 -1
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +7 -4
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/repo.d.ts.map +1 -1
- package/dist/adapters/github/repo.js +2 -1
- package/dist/adapters/github/repo.js.map +1 -1
- package/dist/adapters/intake.js +5 -4
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/shared.d.ts +8 -7
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +18 -16
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +4 -1
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +76 -54
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +2 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +7 -3
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +2 -1
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +1 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +17 -10
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +1 -0
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +7 -3
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +3 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent.d.ts +1 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +122 -50
- package/dist/agent.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +4 -1
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/ext-dev.d.ts.map +1 -1
- package/dist/cli/ext-dev.js +22 -14
- package/dist/cli/ext-dev.js.map +1 -1
- package/dist/cli/ext.d.ts.map +1 -1
- package/dist/cli/ext.js +5 -3
- package/dist/cli/ext.js.map +1 -1
- package/dist/cli/office.d.ts +2 -0
- package/dist/cli/office.d.ts.map +1 -0
- package/dist/cli/office.js +89 -0
- package/dist/cli/office.js.map +1 -0
- package/dist/cli/types.d.ts +3 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +2 -1
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/extensions.js +1 -1
- package/dist/commands/extensions.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +6 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +7 -4
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +6 -2
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +5 -20
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +2 -1
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +5 -4
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +15 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +55 -24
- package/dist/config.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +4 -2
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +22 -13
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts +2 -1
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +5 -3
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/types.d.ts +3 -0
- package/dist/harness/extensions/types.d.ts.map +1 -1
- package/dist/harness/extensions/types.js.map +1 -1
- package/dist/harness/session-store.d.ts +2 -0
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +2 -0
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts.map +1 -1
- package/dist/harness/subagent-profiles.js +9 -0
- package/dist/harness/subagent-profiles.js.map +1 -1
- package/dist/harness/subagent-runner.js +6 -4
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/harness/types.d.ts +4 -2
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +47 -0
- package/dist/main.js.map +1 -1
- package/dist/observability/sentry.d.ts +2 -0
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +7 -0
- package/dist/observability/sentry.js.map +1 -1
- package/dist/office-address.d.ts +32 -0
- package/dist/office-address.d.ts.map +1 -0
- package/dist/office-address.js +118 -0
- package/dist/office-address.js.map +1 -0
- package/dist/office-migration.d.ts +38 -0
- package/dist/office-migration.d.ts.map +1 -0
- package/dist/office-migration.js +213 -0
- package/dist/office-migration.js.map +1 -0
- package/dist/office-registry.d.ts +81 -0
- package/dist/office-registry.d.ts.map +1 -0
- package/dist/office-registry.js +705 -0
- package/dist/office-registry.js.map +1 -0
- package/dist/packages/admin.js +5 -3
- package/dist/packages/admin.js.map +1 -1
- package/dist/packages/inspect.d.ts.map +1 -1
- package/dist/packages/inspect.js +5 -2
- package/dist/packages/inspect.js.map +1 -1
- package/dist/packages/materialize.d.ts +2 -1
- package/dist/packages/materialize.d.ts.map +1 -1
- package/dist/packages/materialize.js +6 -16
- package/dist/packages/materialize.js.map +1 -1
- package/dist/packages/resolve.d.ts.map +1 -1
- package/dist/packages/resolve.js +8 -9
- package/dist/packages/resolve.js.map +1 -1
- package/dist/packages/types.d.ts +3 -2
- package/dist/packages/types.d.ts.map +1 -1
- package/dist/packages/types.js.map +1 -1
- package/dist/provisioner.d.ts +7 -0
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +17 -0
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +88 -67
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +22 -12
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +85 -53
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +14 -4
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +1 -0
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +1 -0
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/firecracker.d.ts.map +1 -1
- package/dist/sandbox/firecracker.js +1 -0
- package/dist/sandbox/firecracker.js.map +1 -1
- package/dist/sandbox/gondolin.d.ts.map +1 -1
- package/dist/sandbox/gondolin.js +1 -0
- package/dist/sandbox/gondolin.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +1 -0
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +35 -7
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +31 -5
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/image.d.ts.map +1 -1
- package/dist/sandbox/image.js +1 -0
- package/dist/sandbox/image.js.map +1 -1
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +12 -0
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +6 -0
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +33 -4
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/store.d.ts +13 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +78 -9
- package/dist/sessions/store.js.map +1 -1
- package/dist/settings-mutation.d.ts +3 -3
- package/dist/settings-mutation.d.ts.map +1 -1
- package/dist/settings-mutation.js +4 -4
- package/dist/settings-mutation.js.map +1 -1
- package/dist/store.d.ts +5 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +13 -5
- package/dist/store.js.map +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +5 -2
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +6 -3
- package/dist/tools/subagent.js.map +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +6 -3
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +78 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +16 -0
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +31 -1
- package/dist/vault/index.js.map +1 -1
- package/dist/web/admin/portal.d.ts +13 -0
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +156 -173
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +3 -3
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +24 -14
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts +1 -1
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +48 -11
- package/dist/web/session-view/service.js.map +1 -1
- package/dist/workspace-projection/index.d.ts +10 -3
- package/dist/workspace-projection/index.d.ts.map +1 -1
- package/dist/workspace-projection/index.js +129 -45
- package/dist/workspace-projection/index.js.map +1 -1
- package/dist/workspace-projection/types.d.ts +14 -3
- package/dist/workspace-projection/types.d.ts.map +1 -1
- package/dist/workspace-projection/types.js.map +1 -1
- package/package.json +2 -1
package/dist/agent.js
CHANGED
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
* Agent runner: prompt construction, path translation, run lifecycle, and createRunner.
|
|
3
3
|
* Single module — do not split helpers that only this file uses.
|
|
4
4
|
*/
|
|
5
|
+
import { officeDirName } from "./office-address.js";
|
|
5
6
|
import { DEFAULT_EVENT_BUDGET, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, parseCommandInput, } from "./harness/index.js";
|
|
6
7
|
import { runSubagent } from "./harness/subagent-runner.js";
|
|
7
8
|
import { loadSubagentProfiles } from "./harness/subagent-profiles.js";
|
|
8
9
|
import { mergeSubagentProgress, parseSubagentProgressSnapshot, renderSubagentDashboard, settleSubagentProgress, } from "./subagent-progress.js";
|
|
9
10
|
import { createHash } from "crypto";
|
|
10
|
-
import { existsSync } from "fs";
|
|
11
|
+
import { existsSync, lstatSync, readdirSync } from "fs";
|
|
11
12
|
import { chmod, mkdtemp, mkdir, readFile, rm, writeFile } from "fs/promises";
|
|
12
13
|
import { tmpdir } from "os";
|
|
13
14
|
import { basename, isAbsolute, join, posix, relative, resolve, sep } from "path";
|
|
14
15
|
import { resolveConversationSettings } from "./config.js";
|
|
16
|
+
import { resolveWorkspaceProjection } from "./workspace-projection/index.js";
|
|
15
17
|
import { effectiveStateDir } from "./cli/arg-grammar.js";
|
|
16
18
|
import { packageSkillRuntimeDir, resolveConversationPackages } from "./packages/index.js";
|
|
17
19
|
import { ActorExecutionResolver } from "./execution-resolver.js";
|
|
18
20
|
import * as log from "./log.js";
|
|
19
|
-
import { createExecutor, getUnresolvedSandboxPathContext, } from "./sandbox/index.js";
|
|
21
|
+
import { assertSandboxSupportsWorkspacePolicy, createExecutor, getUnresolvedSandboxPathContext, } from "./sandbox/index.js";
|
|
20
22
|
import { addLifecycleBreadcrumb, metricAttributes, reportUserFacingError, updateActiveSpanAttribution, } from "./observability/sentry.js";
|
|
21
23
|
import { ChatHistorySync } from "./sessions/chat-history-sync.js";
|
|
22
24
|
import { formatHistoryLine } from "./sessions/history-line.js";
|
|
@@ -149,11 +151,10 @@ export async function buildPromptPayload(message, workspacePath, pathContext, re
|
|
|
149
151
|
}
|
|
150
152
|
return { userMessage, imageAttachments };
|
|
151
153
|
}
|
|
152
|
-
async function getMemory(
|
|
154
|
+
async function getMemory(projection) {
|
|
153
155
|
const parts = [];
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (existsSync(workspaceMemoryPath)) {
|
|
156
|
+
const workspaceMemoryPath = projection.promptSources.globalMemoryPath;
|
|
157
|
+
if (workspaceMemoryPath && isRegularFile(workspaceMemoryPath)) {
|
|
157
158
|
try {
|
|
158
159
|
const content = (await readFile(workspaceMemoryPath, "utf-8")).trim();
|
|
159
160
|
if (content) {
|
|
@@ -164,9 +165,8 @@ async function getMemory(conversationDir) {
|
|
|
164
165
|
log.logWarning("Failed to read workspace memory", `${workspaceMemoryPath}: ${error}`);
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (existsSync(conversationMemoryPath)) {
|
|
168
|
+
const conversationMemoryPath = projection.promptSources.conversationMemoryPath;
|
|
169
|
+
if (isRegularFile(conversationMemoryPath)) {
|
|
170
170
|
try {
|
|
171
171
|
const content = (await readFile(conversationMemoryPath, "utf-8")).trim();
|
|
172
172
|
if (content) {
|
|
@@ -182,7 +182,16 @@ async function getMemory(conversationDir) {
|
|
|
182
182
|
}
|
|
183
183
|
return parts.join("\n\n");
|
|
184
184
|
}
|
|
185
|
-
function
|
|
185
|
+
function isRegularFile(path) {
|
|
186
|
+
try {
|
|
187
|
+
const stats = lstatSync(path);
|
|
188
|
+
return stats.isFile() && !stats.isSymbolicLink();
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function loadMikanSkills(address, conversationDir, workspacePath, projection) {
|
|
186
195
|
const skillMap = new Map();
|
|
187
196
|
// conversationDir is the host path (e.g., /Users/.../data/C0A34FL8PMH)
|
|
188
197
|
// hostWorkspacePath is the parent directory on host
|
|
@@ -206,7 +215,7 @@ function loadMikanSkills(conversationDir, workspacePath) {
|
|
|
206
215
|
// skill ships alongside its SKILL.md, which inlining could never carry.
|
|
207
216
|
const mounted = workspacePath !== hostWorkspacePath;
|
|
208
217
|
for (const { slug, dir } of resolveConversationPackages({
|
|
209
|
-
|
|
218
|
+
address,
|
|
210
219
|
stateDir: effectiveStateDir(),
|
|
211
220
|
conversationDir,
|
|
212
221
|
}).skillDirs) {
|
|
@@ -221,26 +230,70 @@ function loadMikanSkills(conversationDir, workspacePath) {
|
|
|
221
230
|
skillMap.set(skill.name, skill);
|
|
222
231
|
}
|
|
223
232
|
}
|
|
224
|
-
// Load workspace-level skills
|
|
225
|
-
const workspaceSkillsDir =
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
// Load workspace-level skills only when the office projection authorizes it.
|
|
234
|
+
const workspaceSkillsDir = projection.promptSources.globalSkillsDir;
|
|
235
|
+
if (workspaceSkillsDir) {
|
|
236
|
+
for (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: "workspace" })
|
|
237
|
+
.skills) {
|
|
238
|
+
skill.filePath = translatePath(skill.filePath);
|
|
239
|
+
skill.baseDir = translatePath(skill.baseDir);
|
|
240
|
+
skillMap.set(skill.name, skill);
|
|
241
|
+
}
|
|
231
242
|
}
|
|
232
|
-
// Load conversation-specific skills (override workspace skills on collision)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
243
|
+
// Load conversation-specific skills (override workspace skills on collision).
|
|
244
|
+
// Host prompt construction must never follow an agent-created symlink out of
|
|
245
|
+
// the conversation office.
|
|
246
|
+
const conversationSkillsDir = projection.promptSources.conversationSkillsDir;
|
|
247
|
+
if (isSafePromptSkillTree(conversationSkillsDir, projection.promptSources.conversationDir)) {
|
|
248
|
+
for (const skill of loadSkillsFromDir({ dir: conversationSkillsDir, source: "channel" })
|
|
249
|
+
.skills) {
|
|
250
|
+
skill.filePath = translatePath(skill.filePath);
|
|
251
|
+
skill.baseDir = translatePath(skill.baseDir);
|
|
252
|
+
skillMap.set(skill.name, skill);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else if (existsSync(conversationSkillsDir)) {
|
|
256
|
+
log.logWarning("Ignoring unsafe conversation skill tree", conversationSkillsDir);
|
|
238
257
|
}
|
|
239
258
|
return Array.from(skillMap.values());
|
|
240
259
|
}
|
|
241
|
-
function
|
|
260
|
+
export function isSafePromptSkillTree(dir, conversationDir) {
|
|
261
|
+
if (!existsSync(dir))
|
|
262
|
+
return true;
|
|
263
|
+
if (dir !== conversationDir && !dir.startsWith(`${conversationDir}${sep}`))
|
|
264
|
+
return false;
|
|
265
|
+
const stack = [dir];
|
|
266
|
+
while (stack.length > 0) {
|
|
267
|
+
const current = stack.pop();
|
|
268
|
+
let stats;
|
|
269
|
+
try {
|
|
270
|
+
stats = lstatSync(current);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
if (stats.isSymbolicLink())
|
|
276
|
+
return false;
|
|
277
|
+
if (!stats.isDirectory())
|
|
278
|
+
continue;
|
|
279
|
+
let entries;
|
|
280
|
+
try {
|
|
281
|
+
entries = readdirSync(current, { withFileTypes: true });
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
for (const entry of entries) {
|
|
287
|
+
if (entry.isSymbolicLink())
|
|
288
|
+
return false;
|
|
289
|
+
stack.push(join(current, entry.name));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
function buildRuntimePaths(runtimeWorkspaceRoot, address) {
|
|
242
295
|
const workspaceRoot = runtimeWorkspaceRoot.replace(/\/+$/, "") || "/";
|
|
243
|
-
const conversationPath = posix.join(workspaceRoot,
|
|
296
|
+
const conversationPath = posix.join(workspaceRoot, officeDirName(address));
|
|
244
297
|
return {
|
|
245
298
|
workspaceRoot,
|
|
246
299
|
conversationPath,
|
|
@@ -291,8 +344,8 @@ export function resolveTriggerAttribution(message) {
|
|
|
291
344
|
return `@${message.userName}`;
|
|
292
345
|
return undefined;
|
|
293
346
|
}
|
|
294
|
-
function buildSystemPrompt(workspacePath,
|
|
295
|
-
const { workspaceRoot, conversationPath, scratchPath } = buildRuntimePaths(workspacePath,
|
|
347
|
+
function buildSystemPrompt(workspacePath, address, conversationKind, currentUserId, memory, sandboxConfig, platform, skills, projection) {
|
|
348
|
+
const { workspaceRoot, conversationPath, scratchPath } = buildRuntimePaths(workspacePath, address);
|
|
296
349
|
const sandboxType = sandboxConfig.type;
|
|
297
350
|
const isContainerLike = sandboxType === "container" || sandboxType === "image";
|
|
298
351
|
const isFirecracker = sandboxType === "firecracker";
|
|
@@ -310,6 +363,20 @@ function buildSystemPrompt(workspacePath, conversationId, conversationKind, curr
|
|
|
310
363
|
// system prompt stays byte-stable across a conversation's turns and keeps the
|
|
311
364
|
// provider prompt cache warm (a changing system prefix invalidates the cache
|
|
312
365
|
// for the whole request, including the far larger conversation history).
|
|
366
|
+
const workspaceLayout = projection.layout === "full"
|
|
367
|
+
? `${workspaceRoot}/ contains the complete trusted workspace.`
|
|
368
|
+
: projection.layout === "shared-support"
|
|
369
|
+
? `${workspaceRoot}/ contains shared MEMORY.md, skills/, events/, and this conversation's directory.`
|
|
370
|
+
: `${conversationPath}/ is the only conversation workspace mounted; global memory, skills, and events are not available.`;
|
|
371
|
+
const skillStorageGuidance = projection.doorPolicy === "trusted"
|
|
372
|
+
? `Store shared skills in \`${workspaceRoot}/skills/<name>/\` or conversation-specific skills in \`${conversationPath}/skills/<name>/\`.`
|
|
373
|
+
: `Store skills in \`${conversationPath}/skills/<name>/\`; this office cannot access workspace-global skills.`;
|
|
374
|
+
const memoryGuidance = projection.doorPolicy === "trusted"
|
|
375
|
+
? `Write important shared knowledge to \`${workspaceRoot}/MEMORY.md\` and conversation-specific knowledge to \`${conversationPath}/MEMORY.md\`.`
|
|
376
|
+
: `Write durable knowledge only to \`${conversationPath}/MEMORY.md\`; this office cannot access workspace-global memory.`;
|
|
377
|
+
const systemLogPath = projection.layout === "conversation"
|
|
378
|
+
? `${conversationPath}/SYSTEM.md`
|
|
379
|
+
: `${workspaceRoot}/SYSTEM.md`;
|
|
313
380
|
const slackBlockKitInstructions = platform.name === "slack"
|
|
314
381
|
? `
|
|
315
382
|
## Slack Rendering
|
|
@@ -344,10 +411,13 @@ ${envDescription}
|
|
|
344
411
|
- Do not use host-only paths unless you are running in host mode and verified they exist.
|
|
345
412
|
|
|
346
413
|
## Workspace Layout
|
|
347
|
-
${
|
|
414
|
+
${workspaceLayout}
|
|
415
|
+
${projection.layout === "conversation"
|
|
416
|
+
? `${conversationPath}/ # This conversation`
|
|
417
|
+
: `${workspaceRoot}/
|
|
348
418
|
├── MEMORY.md # Global memory (all conversations)
|
|
349
419
|
├── skills/ # Global CLI tools you create
|
|
350
|
-
└── ${
|
|
420
|
+
└── ${officeDirName(address)}/ # This conversation`}
|
|
351
421
|
├── MEMORY.md # Conversation-specific memory
|
|
352
422
|
├── log.jsonl # Human-readable message history (no tool results)
|
|
353
423
|
├── sessions/ # Structured session history used for context reconstruction
|
|
@@ -362,7 +432,7 @@ ${workspaceRoot}/
|
|
|
362
432
|
You can create reusable CLI tools for recurring tasks (email, APIs, data processing, etc.).
|
|
363
433
|
|
|
364
434
|
### Creating Skills
|
|
365
|
-
|
|
435
|
+
${skillStorageGuidance}
|
|
366
436
|
Each skill directory needs a \`SKILL.md\` with YAML frontmatter:
|
|
367
437
|
|
|
368
438
|
\`\`\`markdown
|
|
@@ -394,16 +464,14 @@ When events trigger, messages are prefixed like \`[EVENT:filename:type:time]\`.
|
|
|
394
464
|
For periodic events where there's nothing to report, respond with exactly \`[SILENT]\`. Debounce external triggers; prefer one summarized event over many.
|
|
395
465
|
|
|
396
466
|
## Memory
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
- Conversation (${conversationPath}/MEMORY.md): conversation-specific decisions, ongoing work
|
|
400
|
-
Update when you learn something important or when asked to remember something.
|
|
467
|
+
${memoryGuidance}
|
|
468
|
+
Update it when you learn something important or when asked to remember something.
|
|
401
469
|
|
|
402
470
|
### Current Memory
|
|
403
471
|
${memory}
|
|
404
472
|
|
|
405
473
|
## System Configuration Log
|
|
406
|
-
Maintain ${
|
|
474
|
+
Maintain ${systemLogPath} to log all environment modifications:
|
|
407
475
|
- Installed packages (apt install, npm install, uv pip install)
|
|
408
476
|
- Environment variables set
|
|
409
477
|
- Config files modified (~/.gitconfig, cron jobs, etc.)
|
|
@@ -920,7 +988,7 @@ function buildExtensionHostServices(params) {
|
|
|
920
988
|
};
|
|
921
989
|
}
|
|
922
990
|
async function createConfiguredAgentSession(params) {
|
|
923
|
-
const { conversationId, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, } = params;
|
|
991
|
+
const { address, conversationId, conversationDir, workspaceDir, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, } = params;
|
|
924
992
|
// Host-only dirs under the state dir: extension code runs in the mikan
|
|
925
993
|
// process, so it must never load from workspace paths — those are mounted
|
|
926
994
|
// into sandbox containers and agent-writable (sandbox escape otherwise).
|
|
@@ -937,9 +1005,9 @@ async function createConfiguredAgentSession(params) {
|
|
|
937
1005
|
// they always agree on which profiles are launchable.
|
|
938
1006
|
let runnableSubagentProfiles = loadedProfiles.profiles;
|
|
939
1007
|
const resolvedPackages = resolveConversationPackages({
|
|
940
|
-
|
|
1008
|
+
address,
|
|
941
1009
|
stateDir: effectiveStateDir(),
|
|
942
|
-
conversationDir
|
|
1010
|
+
conversationDir,
|
|
943
1011
|
});
|
|
944
1012
|
for (const error of resolvedPackages.errors) {
|
|
945
1013
|
log.logWarning(`Package unavailable: ${error.source}`, error.message);
|
|
@@ -947,7 +1015,7 @@ async function createConfiguredAgentSession(params) {
|
|
|
947
1015
|
const extensionsResult = await loadExtensions({
|
|
948
1016
|
dirs: resolvedPackages.extensionDirs,
|
|
949
1017
|
roots: resolvedPackages.extensionRoots,
|
|
950
|
-
context: { conversationId, workspaceDir, model, thinkingLevel },
|
|
1018
|
+
context: { address, conversationId, workspaceDir, model, thinkingLevel },
|
|
951
1019
|
services: buildExtensionHostServices({
|
|
952
1020
|
workspaceDir,
|
|
953
1021
|
vaultManager,
|
|
@@ -1032,18 +1100,18 @@ async function prepareRunContext(params) {
|
|
|
1032
1100
|
await mkdir(join(conversationDir, "scratch"), { recursive: true });
|
|
1033
1101
|
if (executionResolver) {
|
|
1034
1102
|
await resolveExecutorForRun({
|
|
1035
|
-
|
|
1103
|
+
address: message.address,
|
|
1036
1104
|
userId: message.userId,
|
|
1037
|
-
conversationId,
|
|
1038
1105
|
trustModel: platform.trustModel,
|
|
1039
1106
|
});
|
|
1040
1107
|
pathContext = getPathContext();
|
|
1041
1108
|
}
|
|
1042
1109
|
reloadSessionMessages(session, conversationId);
|
|
1043
|
-
const
|
|
1044
|
-
const
|
|
1110
|
+
const projection = resolveWorkspaceProjection(join(conversationDir, ".."), message.address);
|
|
1111
|
+
const memory = await getMemory(projection);
|
|
1112
|
+
const skills = mergeExtensionSkills(loadMikanSkills(message.address, conversationDir, pathContext.runtimeWorkspaceRoot, projection), params.extensionSkills ?? []);
|
|
1045
1113
|
const triggerAttribution = resolveTriggerAttribution(message);
|
|
1046
|
-
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot,
|
|
1114
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, message.address, message.conversationKind, message.userId, memory, executor.getSandboxConfig(), platform, skills, projection);
|
|
1047
1115
|
session.agent.state.systemPrompt = systemPrompt;
|
|
1048
1116
|
// Cache diagnosis: a byte-stable system prompt is the precondition for
|
|
1049
1117
|
// provider prompt caching. If this hash changes between turns of one
|
|
@@ -1459,8 +1527,10 @@ function attachSessionEventHandlers(params) {
|
|
|
1459
1527
|
*/
|
|
1460
1528
|
export async function createRunner(options) {
|
|
1461
1529
|
const { sandboxConfig, sessionKey, conversationId, conversationDir, workspaceDir, sessionScope, vaultManager, provisioner, resourceController, sessionView, platformNotifier, platformReactor, platformUploader, platformBlockKit, platformToolPackFactories, } = options;
|
|
1462
|
-
const agentConfig = resolveConversationSettings(conversationDir);
|
|
1530
|
+
const agentConfig = resolveConversationSettings({ address: options.address, conversationDir });
|
|
1463
1531
|
const workspaceBase = join(conversationDir, "..");
|
|
1532
|
+
const projection = resolveWorkspaceProjection(workspaceBase, options.address);
|
|
1533
|
+
assertSandboxSupportsWorkspacePolicy(sandboxConfig, projection.doorPolicy);
|
|
1464
1534
|
const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspaceDir, workspaceBase);
|
|
1465
1535
|
let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceBase);
|
|
1466
1536
|
const modelRegistry = options.models ?? MikanModels.create();
|
|
@@ -1474,8 +1544,8 @@ export async function createRunner(options) {
|
|
|
1474
1544
|
getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),
|
|
1475
1545
|
});
|
|
1476
1546
|
// Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
|
|
1477
|
-
const memory = await getMemory(
|
|
1478
|
-
const skills = loadMikanSkills(conversationDir, pathContext.runtimeWorkspaceRoot);
|
|
1547
|
+
const memory = await getMemory(projection);
|
|
1548
|
+
const skills = loadMikanSkills(options.address, conversationDir, pathContext.runtimeWorkspaceRoot, projection);
|
|
1479
1549
|
const emptyPlatform = {
|
|
1480
1550
|
name: "chat",
|
|
1481
1551
|
formattingGuide: "",
|
|
@@ -1483,7 +1553,7 @@ export async function createRunner(options) {
|
|
|
1483
1553
|
users: [],
|
|
1484
1554
|
trustModel: "membership",
|
|
1485
1555
|
};
|
|
1486
|
-
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot,
|
|
1556
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, options.address, "shared", undefined, memory, sandboxConfig, emptyPlatform, skills, projection);
|
|
1487
1557
|
// Create session manager and settings manager. Top-level/private sessions
|
|
1488
1558
|
// use the conversation's current pointer; scoped sessions use fixed files.
|
|
1489
1559
|
// Platform-specific scope behavior is resolved before runner creation.
|
|
@@ -1497,7 +1567,9 @@ export async function createRunner(options) {
|
|
|
1497
1567
|
const sessionUuid = extractSessionUuid(contextFile);
|
|
1498
1568
|
const chatSessionManager = new ChatHistorySync();
|
|
1499
1569
|
const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
|
|
1570
|
+
address: options.address,
|
|
1500
1571
|
conversationId,
|
|
1572
|
+
conversationDir,
|
|
1501
1573
|
workspaceDir,
|
|
1502
1574
|
systemPrompt,
|
|
1503
1575
|
model,
|
|
@@ -1671,7 +1743,7 @@ export async function createRunner(options) {
|
|
|
1671
1743
|
});
|
|
1672
1744
|
pathContext = prepared.pathContext;
|
|
1673
1745
|
try {
|
|
1674
|
-
const conversationMemoryPath = posix.join(prepared.pathContext.runtimeWorkspaceRoot,
|
|
1746
|
+
const conversationMemoryPath = posix.join(prepared.pathContext.runtimeWorkspaceRoot, officeDirName(message.address), "MEMORY.md");
|
|
1675
1747
|
const dreamTools = sessionDreamTools(session.agent.state.tools, conversationMemoryPath);
|
|
1676
1748
|
const outcome = await session.prompt(sessionDreamPrompt(conversationMemoryPath, dreamTools.map((tool) => tool.name)), {
|
|
1677
1749
|
origin: {
|