@geminixiang/mikan 1.0.0-beta.37 → 1.0.0-beta.39
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 +21 -0
- package/README.md +1 -1
- package/dist/adapter.js +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +3 -6
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +16 -39
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +2 -0
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +15 -11
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +1 -1
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +2 -1
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/repo.d.ts +2 -1
- package/dist/adapters/github/repo.d.ts.map +1 -1
- package/dist/adapters/github/repo.js +2 -3
- package/dist/adapters/github/repo.js.map +1 -1
- package/dist/adapters/github/types.d.ts +1 -1
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/intake.js +1 -1
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/shared.d.ts +17 -5
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +44 -8
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts +14 -0
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +34 -0
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +19 -6
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +88 -21
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +5 -6
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +29 -51
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/types.d.ts +19 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent.d.ts +0 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +79 -101
- package/dist/agent.js.map +1 -1
- package/dist/cli/ext-dev.d.ts.map +1 -1
- package/dist/cli/ext-dev.js +8 -8
- package/dist/cli/ext-dev.js.map +1 -1
- package/dist/cli/ext.js +3 -3
- package/dist/cli/ext.js.map +1 -1
- package/dist/cli/office.js +2 -2
- package/dist/cli/office.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +1 -2
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +3 -1
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +3 -7
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +7 -7
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.d.ts.map +1 -1
- package/dist/commands/session-view.js +1 -2
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +2 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +10 -18
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +16 -15
- package/dist/config.js.map +1 -1
- package/dist/execution-resolver.d.ts +4 -6
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +10 -19
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/extensions/loader.js +1 -1
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/skills.d.ts +8 -0
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +46 -4
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/types.d.ts +2 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +2 -0
- 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 +16 -16
- package/dist/main.js.map +1 -1
- package/dist/{office-address.d.ts → office/address.d.ts} +13 -14
- package/dist/office/address.d.ts.map +1 -0
- package/dist/{office-address.js → office/address.js} +13 -18
- package/dist/office/address.js.map +1 -0
- package/dist/office/index.d.ts +11 -0
- package/dist/office/index.d.ts.map +1 -0
- package/dist/office/index.js +11 -0
- package/dist/office/index.js.map +1 -0
- package/dist/office/layout.d.ts +20 -0
- package/dist/office/layout.d.ts.map +1 -0
- package/dist/office/layout.js +88 -0
- package/dist/office/layout.js.map +1 -0
- package/dist/{office-migration.d.ts → office/migration.d.ts} +3 -3
- package/dist/office/migration.d.ts.map +1 -0
- package/dist/{office-migration.js → office/migration.js} +8 -12
- package/dist/office/migration.js.map +1 -0
- package/dist/{office-registry.d.ts → office/registry.d.ts} +18 -24
- package/dist/office/registry.d.ts.map +1 -0
- package/dist/{office-registry.js → office/registry.js} +22 -83
- package/dist/office/registry.js.map +1 -0
- package/dist/office/types.d.ts +71 -0
- package/dist/office/types.d.ts.map +1 -0
- package/dist/office/types.js +2 -0
- package/dist/office/types.js.map +1 -0
- package/dist/packages/admin.js +5 -5
- package/dist/packages/admin.js.map +1 -1
- package/dist/packages/inspect.d.ts.map +1 -1
- package/dist/packages/inspect.js +3 -8
- package/dist/packages/inspect.js.map +1 -1
- package/dist/packages/materialize.js +1 -1
- package/dist/packages/materialize.js.map +1 -1
- package/dist/packages/resolve.js +5 -8
- package/dist/packages/resolve.js.map +1 -1
- package/dist/packages/types.d.ts +2 -5
- package/dist/packages/types.d.ts.map +1 -1
- package/dist/packages/types.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +13 -15
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.js +1 -1
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +3 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/identity.js +1 -1
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/settings-mutation.d.ts +3 -2
- package/dist/settings-mutation.d.ts.map +1 -1
- package/dist/settings-mutation.js +6 -7
- package/dist/settings-mutation.js.map +1 -1
- package/dist/tools/generate-image.d.ts +8 -2
- package/dist/tools/generate-image.d.ts.map +1 -1
- package/dist/tools/generate-image.js +5 -3
- package/dist/tools/generate-image.js.map +1 -1
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/trigger.d.ts +1 -1
- package/dist/trigger.d.ts.map +1 -1
- package/dist/trigger.js +5 -10
- package/dist/trigger.js.map +1 -1
- package/dist/types.d.ts +3 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.js +1 -1
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/injection.d.ts +3 -1
- package/dist/vault/injection.d.ts.map +1 -1
- package/dist/vault/injection.js +2 -2
- package/dist/vault/injection.js.map +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +67 -80
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +2 -1
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/server.d.ts +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +3 -3
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.js +1 -1
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/workspace-projection/index.d.ts +2 -4
- package/dist/workspace-projection/index.d.ts.map +1 -1
- package/dist/workspace-projection/index.js +21 -56
- package/dist/workspace-projection/index.js.map +1 -1
- package/dist/workspace-projection/types.d.ts +0 -2
- package/dist/workspace-projection/types.d.ts.map +1 -1
- package/dist/workspace-projection/types.js.map +1 -1
- package/package.json +41 -16
- package/dist/office-address.d.ts.map +0 -1
- package/dist/office-address.js.map +0 -1
- package/dist/office-migration.d.ts.map +0 -1
- package/dist/office-migration.js.map +0 -1
- package/dist/office-registry.d.ts.map +0 -1
- package/dist/office-registry.js.map +0 -1
- package/dist/store.d.ts +0 -51
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -185
- package/dist/store.js.map +0 -1
package/dist/agent.js
CHANGED
|
@@ -2,19 +2,17 @@
|
|
|
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";
|
|
6
5
|
import { DEFAULT_EVENT_BUDGET, formatSkillsForPrompt, loadExtensions, loadSkillsFromDir, MikanAgentSession, MikanModels, parseCommandInput, } from "./harness/index.js";
|
|
7
6
|
import { runSubagent } from "./harness/subagent-runner.js";
|
|
8
7
|
import { loadSubagentProfiles } from "./harness/subagent-profiles.js";
|
|
9
8
|
import { mergeSubagentProgress, parseSubagentProgressSnapshot, renderSubagentDashboard, settleSubagentProgress, } from "./subagent-progress.js";
|
|
10
9
|
import { createHash } from "crypto";
|
|
11
|
-
import { existsSync, lstatSync
|
|
10
|
+
import { existsSync, lstatSync } from "fs";
|
|
12
11
|
import { chmod, mkdtemp, mkdir, readFile, rm, writeFile } from "fs/promises";
|
|
13
12
|
import { tmpdir } from "os";
|
|
14
13
|
import { basename, isAbsolute, join, posix, relative, resolve, sep } from "path";
|
|
15
14
|
import { resolveConversationSettings } from "./config.js";
|
|
16
15
|
import { resolveWorkspaceProjection } from "./workspace-projection/index.js";
|
|
17
|
-
import { effectiveStateDir } from "./cli/arg-grammar.js";
|
|
18
16
|
import { packageSkillRuntimeDir, resolveConversationPackages } from "./packages/index.js";
|
|
19
17
|
import { ActorExecutionResolver } from "./execution-resolver.js";
|
|
20
18
|
import * as log from "./log.js";
|
|
@@ -191,12 +189,11 @@ function isRegularFile(path) {
|
|
|
191
189
|
return false;
|
|
192
190
|
}
|
|
193
191
|
}
|
|
194
|
-
function loadMikanSkills(
|
|
192
|
+
function loadMikanSkills(office, workspacePath, projection) {
|
|
195
193
|
const skillMap = new Map();
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
const hostWorkspacePath = join(conversationDir, "..");
|
|
194
|
+
// workspacePath is the runtime-side root (e.g. /workspace); host paths under
|
|
195
|
+
// the workspace root translate onto it for prompt references.
|
|
196
|
+
const hostWorkspacePath = office.workspace.root;
|
|
200
197
|
// Helper to translate host paths to container paths
|
|
201
198
|
const translatePath = (hostPath) => {
|
|
202
199
|
if (hostPath.startsWith(hostWorkspacePath)) {
|
|
@@ -214,11 +211,7 @@ function loadMikanSkills(address, conversationDir, workspacePath, projection) {
|
|
|
214
211
|
// so the agent can read the files — including any scripts or templates the
|
|
215
212
|
// skill ships alongside its SKILL.md, which inlining could never carry.
|
|
216
213
|
const mounted = workspacePath !== hostWorkspacePath;
|
|
217
|
-
for (const { slug, dir } of resolveConversationPackages({
|
|
218
|
-
address,
|
|
219
|
-
stateDir: effectiveStateDir(),
|
|
220
|
-
conversationDir,
|
|
221
|
-
}).skillDirs) {
|
|
214
|
+
for (const { slug, dir } of resolveConversationPackages({ office }).skillDirs) {
|
|
222
215
|
const runtimeDir = packageSkillRuntimeDir(slug);
|
|
223
216
|
for (const skill of loadSkillsFromDir({ dir, source: `package:${slug}` }).skills) {
|
|
224
217
|
// In host mode there is no mount, so the host path is already the path
|
|
@@ -242,58 +235,32 @@ function loadMikanSkills(address, conversationDir, workspacePath, projection) {
|
|
|
242
235
|
}
|
|
243
236
|
// Load conversation-specific skills (override workspace skills on collision).
|
|
244
237
|
// Host prompt construction must never follow an agent-created symlink out of
|
|
245
|
-
// the conversation office
|
|
238
|
+
// the conversation office, so this load rejects symlinks per entry — on
|
|
239
|
+
// exactly the paths it reads. Vendored node_modules and dot directories are
|
|
240
|
+
// never read and never disqualify anything.
|
|
246
241
|
const conversationSkillsDir = projection.promptSources.conversationSkillsDir;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
else if (existsSync(conversationSkillsDir)) {
|
|
256
|
-
log.logWarning("Ignoring unsafe conversation skill tree", conversationSkillsDir);
|
|
257
|
-
}
|
|
258
|
-
return Array.from(skillMap.values());
|
|
259
|
-
}
|
|
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())
|
|
242
|
+
const conversationSkills = loadSkillsFromDir({
|
|
243
|
+
dir: conversationSkillsDir,
|
|
244
|
+
source: "channel",
|
|
245
|
+
rejectSymlinks: true,
|
|
246
|
+
});
|
|
247
|
+
const skippedSkillLinks = [];
|
|
248
|
+
for (const diagnostic of conversationSkills.diagnostics) {
|
|
249
|
+
if (diagnostic.code !== "symlink")
|
|
278
250
|
continue;
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
}
|
|
251
|
+
log.logWarning("Skipping conversation skill entry (symlink)", diagnostic.path);
|
|
252
|
+
skippedSkillLinks.push(translatePath(diagnostic.path));
|
|
291
253
|
}
|
|
292
|
-
|
|
254
|
+
for (const skill of conversationSkills.skills) {
|
|
255
|
+
skill.filePath = translatePath(skill.filePath);
|
|
256
|
+
skill.baseDir = translatePath(skill.baseDir);
|
|
257
|
+
skillMap.set(skill.name, skill);
|
|
258
|
+
}
|
|
259
|
+
return { skills: Array.from(skillMap.values()), skippedSkillLinks };
|
|
293
260
|
}
|
|
294
|
-
function buildRuntimePaths(runtimeWorkspaceRoot,
|
|
261
|
+
function buildRuntimePaths(runtimeWorkspaceRoot, office) {
|
|
295
262
|
const workspaceRoot = runtimeWorkspaceRoot.replace(/\/+$/, "") || "/";
|
|
296
|
-
const conversationPath = posix.join(workspaceRoot,
|
|
263
|
+
const conversationPath = posix.join(workspaceRoot, office.key);
|
|
297
264
|
return {
|
|
298
265
|
workspaceRoot,
|
|
299
266
|
conversationPath,
|
|
@@ -344,8 +311,8 @@ export function resolveTriggerAttribution(message) {
|
|
|
344
311
|
return `@${message.userName}`;
|
|
345
312
|
return undefined;
|
|
346
313
|
}
|
|
347
|
-
function buildSystemPrompt(workspacePath,
|
|
348
|
-
const { workspaceRoot, conversationPath, scratchPath } = buildRuntimePaths(workspacePath,
|
|
314
|
+
function buildSystemPrompt(workspacePath, office, conversationKind, currentUserId, memory, sandboxConfig, platform, skills, projection, skippedSkillLinks = []) {
|
|
315
|
+
const { workspaceRoot, conversationPath, scratchPath } = buildRuntimePaths(workspacePath, office);
|
|
349
316
|
const sandboxType = sandboxConfig.type;
|
|
350
317
|
const isContainerLike = sandboxType === "container" || sandboxType === "image";
|
|
351
318
|
const isFirecracker = sandboxType === "firecracker";
|
|
@@ -403,7 +370,7 @@ Channels: ${channelMappings}
|
|
|
403
370
|
|
|
404
371
|
Users: ${userMappings}
|
|
405
372
|
|
|
406
|
-
When mentioning users,
|
|
373
|
+
When mentioning users, write <@userName> using the exact userName from the Users table above (e.g., <@mario>). Never invent handles from other platforms (GitHub, email); the platform adapter converts <@userName> to the platform's native mention form.
|
|
407
374
|
|
|
408
375
|
## Environment
|
|
409
376
|
${envDescription}
|
|
@@ -417,7 +384,7 @@ ${projection.layout === "conversation"
|
|
|
417
384
|
: `${workspaceRoot}/
|
|
418
385
|
├── MEMORY.md # Global memory (all conversations)
|
|
419
386
|
├── skills/ # Global CLI tools you create
|
|
420
|
-
└── ${
|
|
387
|
+
└── ${office.key}/ # This conversation`}
|
|
421
388
|
├── MEMORY.md # Conversation-specific memory
|
|
422
389
|
├── log.jsonl # Human-readable message history (no tool results)
|
|
423
390
|
├── sessions/ # Structured session history used for context reconstruction
|
|
@@ -450,7 +417,9 @@ Scripts are in: {baseDir}/
|
|
|
450
417
|
\`name\` and \`description\` are required. Use \`{baseDir}\` as placeholder for the skill's directory path.
|
|
451
418
|
|
|
452
419
|
### Available Skills
|
|
453
|
-
${skills.length > 0 ? formatSkillsForPrompt(skills) : "(no skills installed yet)"}
|
|
420
|
+
${skills.length > 0 ? formatSkillsForPrompt(skills) : "(no skills installed yet)"}${skippedSkillLinks.length > 0
|
|
421
|
+
? `\n\nNote: these skill entries were skipped because they are symlinks, which the host never follows when reading this conversation's skills: ${skippedSkillLinks.join(", ")}. Replace each with a real file or directory (for example \`cp -rL\`) to load it.`
|
|
422
|
+
: ""}
|
|
454
423
|
|
|
455
424
|
## Events
|
|
456
425
|
Use the \`event\` tool to schedule immediate, one-shot, or periodic follow-ups. It writes to the host-side mikan control plane and fills routing fields for the current conversation automatically.
|
|
@@ -912,9 +881,9 @@ function buildThreadSessionName(message) {
|
|
|
912
881
|
const userLabel = message?.userName || message?.user || "unknown";
|
|
913
882
|
return `[${userLabel}]: ${text}`;
|
|
914
883
|
}
|
|
915
|
-
function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
|
|
884
|
+
function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspace) {
|
|
916
885
|
const executionResolver = vaultManager && sandboxConfig.type !== "host"
|
|
917
|
-
? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner,
|
|
886
|
+
? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspace)
|
|
918
887
|
: undefined;
|
|
919
888
|
// activeExecutor is replaced at the start of each run() call when executionResolver
|
|
920
889
|
// is present, so the stable `executor` wrapper always delegates to the latest resolved value.
|
|
@@ -947,7 +916,7 @@ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
|
|
|
947
916
|
return {
|
|
948
917
|
executionResolver,
|
|
949
918
|
executor,
|
|
950
|
-
getPathContext: () => executor.getPathContext(
|
|
919
|
+
getPathContext: () => executor.getPathContext(workspace.root),
|
|
951
920
|
async resolveExecutorForRun(context) {
|
|
952
921
|
if (!executionResolver)
|
|
953
922
|
return;
|
|
@@ -962,10 +931,10 @@ function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
|
|
|
962
931
|
* notify posts through the platform bots when main.ts provides a notifier.
|
|
963
932
|
*/
|
|
964
933
|
function buildExtensionHostServices(params) {
|
|
965
|
-
const {
|
|
966
|
-
const eventStore = HostEventStore.fromWorkspaceDir(
|
|
934
|
+
const { workspace, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, runSubagentService, } = params;
|
|
935
|
+
const eventStore = HostEventStore.fromWorkspaceDir(workspace.root);
|
|
967
936
|
return {
|
|
968
|
-
stateDir:
|
|
937
|
+
stateDir: workspace.stateDir,
|
|
969
938
|
scheduleStore: {
|
|
970
939
|
write: async (filename, payload) => {
|
|
971
940
|
await eventStore.write(filename, payload);
|
|
@@ -988,7 +957,10 @@ function buildExtensionHostServices(params) {
|
|
|
988
957
|
};
|
|
989
958
|
}
|
|
990
959
|
async function createConfiguredAgentSession(params) {
|
|
991
|
-
const {
|
|
960
|
+
const { office, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, } = params;
|
|
961
|
+
const { address } = office;
|
|
962
|
+
const conversationId = address.conversationId;
|
|
963
|
+
const workspaceDir = office.workspace.root;
|
|
992
964
|
// Host-only dirs under the state dir: extension code runs in the mikan
|
|
993
965
|
// process, so it must never load from workspace paths — those are mounted
|
|
994
966
|
// into sandbox containers and agent-writable (sandbox escape otherwise).
|
|
@@ -1004,11 +976,7 @@ async function createConfiguredAgentSession(params) {
|
|
|
1004
976
|
// contributed theirs. Both subagent entry points read this at call time, so
|
|
1005
977
|
// they always agree on which profiles are launchable.
|
|
1006
978
|
let runnableSubagentProfiles = loadedProfiles.profiles;
|
|
1007
|
-
const resolvedPackages = resolveConversationPackages({
|
|
1008
|
-
address,
|
|
1009
|
-
stateDir: effectiveStateDir(),
|
|
1010
|
-
conversationDir,
|
|
1011
|
-
});
|
|
979
|
+
const resolvedPackages = resolveConversationPackages({ office });
|
|
1012
980
|
for (const error of resolvedPackages.errors) {
|
|
1013
981
|
log.logWarning(`Package unavailable: ${error.source}`, error.message);
|
|
1014
982
|
}
|
|
@@ -1017,7 +985,7 @@ async function createConfiguredAgentSession(params) {
|
|
|
1017
985
|
roots: resolvedPackages.extensionRoots,
|
|
1018
986
|
context: { address, conversationId, workspaceDir, model, thinkingLevel },
|
|
1019
987
|
services: buildExtensionHostServices({
|
|
1020
|
-
|
|
988
|
+
workspace: office.workspace,
|
|
1021
989
|
vaultManager,
|
|
1022
990
|
platformNotifier,
|
|
1023
991
|
platformReactor,
|
|
@@ -1094,10 +1062,11 @@ function reloadSessionMessages(session, conversationId) {
|
|
|
1094
1062
|
}
|
|
1095
1063
|
}
|
|
1096
1064
|
async function prepareRunContext(params) {
|
|
1097
|
-
const { message, responder, platform,
|
|
1065
|
+
const { message, responder, platform, office, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, session, setEventContext, setSandboxContext, setUploadFunction, setImageUploadFunction, setReactFunction, bindPlatformToolPacks, } = params;
|
|
1066
|
+
const conversationId = office.address.conversationId;
|
|
1098
1067
|
let pathContext = params.pathContext;
|
|
1099
1068
|
const sessionConversation = conversationIdOf(message.sessionKey);
|
|
1100
|
-
await mkdir(join(
|
|
1069
|
+
await mkdir(join(office.dir, "scratch"), { recursive: true });
|
|
1101
1070
|
if (executionResolver) {
|
|
1102
1071
|
await resolveExecutorForRun({
|
|
1103
1072
|
address: message.address,
|
|
@@ -1107,11 +1076,12 @@ async function prepareRunContext(params) {
|
|
|
1107
1076
|
pathContext = getPathContext();
|
|
1108
1077
|
}
|
|
1109
1078
|
reloadSessionMessages(session, conversationId);
|
|
1110
|
-
const projection = resolveWorkspaceProjection(
|
|
1079
|
+
const projection = resolveWorkspaceProjection(office);
|
|
1111
1080
|
const memory = await getMemory(projection);
|
|
1112
|
-
const
|
|
1081
|
+
const conversationSkillLoad = loadMikanSkills(office, pathContext.runtimeWorkspaceRoot, projection);
|
|
1082
|
+
const skills = mergeExtensionSkills(conversationSkillLoad.skills, params.extensionSkills ?? []);
|
|
1113
1083
|
const triggerAttribution = resolveTriggerAttribution(message);
|
|
1114
|
-
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot,
|
|
1084
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, office, message.conversationKind, message.userId, memory, executor.getSandboxConfig(), platform, skills, projection, conversationSkillLoad.skippedSkillLinks);
|
|
1115
1085
|
session.agent.state.systemPrompt = systemPrompt;
|
|
1116
1086
|
// Cache diagnosis: a byte-stable system prompt is the precondition for
|
|
1117
1087
|
// provider prompt caching. If this hash changes between turns of one
|
|
@@ -1133,6 +1103,11 @@ async function prepareRunContext(params) {
|
|
|
1133
1103
|
const runtimePath = normalizeAttachRuntimePath(filePath, pathContext.runtimeWorkspaceRoot);
|
|
1134
1104
|
await withStagedRuntimeFile(executor, runtimePath, (stagedPath) => responder.uploadFile(stagedPath, title));
|
|
1135
1105
|
});
|
|
1106
|
+
// generate_image writes its file host-side, so it uploads by host path —
|
|
1107
|
+
// no staging through the sandbox, where the file may not be mounted.
|
|
1108
|
+
setImageUploadFunction(async (hostPath, title) => {
|
|
1109
|
+
await responder.uploadFile(hostPath, title);
|
|
1110
|
+
});
|
|
1136
1111
|
// The react tool is available only when the responder supports reactions
|
|
1137
1112
|
// (interactive turns on platforms with reaction support); otherwise unset
|
|
1138
1113
|
// so the tool reports it is unavailable rather than silently no-op'ing.
|
|
@@ -1526,26 +1501,32 @@ function attachSessionEventHandlers(params) {
|
|
|
1526
1501
|
* This is a stateless factory function.
|
|
1527
1502
|
*/
|
|
1528
1503
|
export async function createRunner(options) {
|
|
1529
|
-
const { sandboxConfig, sessionKey,
|
|
1530
|
-
const
|
|
1531
|
-
const
|
|
1532
|
-
const
|
|
1504
|
+
const { sandboxConfig, sessionKey, office, sessionScope, vaultManager, provisioner, resourceController, sessionView, platformNotifier, platformReactor, platformUploader, platformBlockKit, platformToolPackFactories, } = options;
|
|
1505
|
+
const conversationId = office.address.conversationId;
|
|
1506
|
+
const conversationDir = office.dir;
|
|
1507
|
+
const workspaceDir = office.workspace.root;
|
|
1508
|
+
const agentConfig = resolveConversationSettings(office);
|
|
1509
|
+
const projection = resolveWorkspaceProjection(office);
|
|
1533
1510
|
assertSandboxSupportsWorkspacePolicy(sandboxConfig, projection.doorPolicy);
|
|
1534
|
-
const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner,
|
|
1535
|
-
let pathContext = getUnresolvedSandboxPathContext(sandboxConfig,
|
|
1511
|
+
const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, office.workspace);
|
|
1512
|
+
let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceDir);
|
|
1536
1513
|
const modelRegistry = options.models ?? MikanModels.create();
|
|
1537
1514
|
if (modelRegistry.getError()) {
|
|
1538
1515
|
log.logWarning("models.json load error", modelRegistry.getError());
|
|
1539
1516
|
}
|
|
1540
1517
|
const model = modelRegistry.resolve(agentConfig.provider, agentConfig.model);
|
|
1541
1518
|
// Create tools (per-runner, with per-runner upload function setter)
|
|
1542
|
-
const { tools, setUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, resourceController: resourceController ?? provisioner }, platformToolPackFactories ?? [], {
|
|
1519
|
+
const { tools, setUploadFunction, setImageUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, resourceController: resourceController ?? provisioner }, platformToolPackFactories ?? [], {
|
|
1543
1520
|
model,
|
|
1544
1521
|
getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),
|
|
1522
|
+
// The conversation's own office dir: mounted into the sandbox, unlike
|
|
1523
|
+
// the workspace base — generated images must land somewhere the agent
|
|
1524
|
+
// (and a future run) can still reach.
|
|
1525
|
+
outputDir: conversationDir,
|
|
1545
1526
|
});
|
|
1546
1527
|
// Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
|
|
1547
1528
|
const memory = await getMemory(projection);
|
|
1548
|
-
const skills = loadMikanSkills(
|
|
1529
|
+
const { skills, skippedSkillLinks } = loadMikanSkills(office, pathContext.runtimeWorkspaceRoot, projection);
|
|
1549
1530
|
const emptyPlatform = {
|
|
1550
1531
|
name: "chat",
|
|
1551
1532
|
formattingGuide: "",
|
|
@@ -1553,7 +1534,7 @@ export async function createRunner(options) {
|
|
|
1553
1534
|
users: [],
|
|
1554
1535
|
trustModel: "membership",
|
|
1555
1536
|
};
|
|
1556
|
-
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot,
|
|
1537
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, office, "shared", undefined, memory, sandboxConfig, emptyPlatform, skills, projection, skippedSkillLinks);
|
|
1557
1538
|
// Create session manager and settings manager. Top-level/private sessions
|
|
1558
1539
|
// use the conversation's current pointer; scoped sessions use fixed files.
|
|
1559
1540
|
// Platform-specific scope behavior is resolved before runner creation.
|
|
@@ -1567,10 +1548,7 @@ export async function createRunner(options) {
|
|
|
1567
1548
|
const sessionUuid = extractSessionUuid(contextFile);
|
|
1568
1549
|
const chatSessionManager = new ChatHistorySync();
|
|
1569
1550
|
const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
|
|
1570
|
-
|
|
1571
|
-
conversationId,
|
|
1572
|
-
conversationDir,
|
|
1573
|
-
workspaceDir,
|
|
1551
|
+
office,
|
|
1574
1552
|
systemPrompt,
|
|
1575
1553
|
model,
|
|
1576
1554
|
thinkingLevel: agentConfig.thinkingLevel,
|
|
@@ -1600,8 +1578,7 @@ export async function createRunner(options) {
|
|
|
1600
1578
|
message,
|
|
1601
1579
|
responder,
|
|
1602
1580
|
platform,
|
|
1603
|
-
|
|
1604
|
-
conversationDir,
|
|
1581
|
+
office,
|
|
1605
1582
|
sessionUuid,
|
|
1606
1583
|
runState,
|
|
1607
1584
|
executor,
|
|
@@ -1613,6 +1590,7 @@ export async function createRunner(options) {
|
|
|
1613
1590
|
setEventContext,
|
|
1614
1591
|
setSandboxContext,
|
|
1615
1592
|
setUploadFunction,
|
|
1593
|
+
setImageUploadFunction,
|
|
1616
1594
|
setReactFunction,
|
|
1617
1595
|
bindPlatformToolPacks,
|
|
1618
1596
|
pathContext,
|
|
@@ -1724,8 +1702,7 @@ export async function createRunner(options) {
|
|
|
1724
1702
|
message,
|
|
1725
1703
|
responder,
|
|
1726
1704
|
platform,
|
|
1727
|
-
|
|
1728
|
-
conversationDir,
|
|
1705
|
+
office,
|
|
1729
1706
|
sessionUuid,
|
|
1730
1707
|
runState,
|
|
1731
1708
|
executor,
|
|
@@ -1737,13 +1714,14 @@ export async function createRunner(options) {
|
|
|
1737
1714
|
setEventContext,
|
|
1738
1715
|
setSandboxContext,
|
|
1739
1716
|
setUploadFunction,
|
|
1717
|
+
setImageUploadFunction,
|
|
1740
1718
|
setReactFunction,
|
|
1741
1719
|
bindPlatformToolPacks,
|
|
1742
1720
|
pathContext,
|
|
1743
1721
|
});
|
|
1744
1722
|
pathContext = prepared.pathContext;
|
|
1745
1723
|
try {
|
|
1746
|
-
const conversationMemoryPath = posix.join(prepared.pathContext.runtimeWorkspaceRoot,
|
|
1724
|
+
const conversationMemoryPath = posix.join(prepared.pathContext.runtimeWorkspaceRoot, office.key, "MEMORY.md");
|
|
1747
1725
|
const dreamTools = sessionDreamTools(session.agent.state.tools, conversationMemoryPath);
|
|
1748
1726
|
const outcome = await session.prompt(sessionDreamPrompt(conversationMemoryPath, dreamTools.map((tool) => tool.name)), {
|
|
1749
1727
|
origin: {
|