@geminixiang/mikan 1.0.0-beta.42 → 1.0.0-beta.44
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 +45 -0
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +3 -17
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +2 -7
- package/dist/adapters/discord/components.d.ts.map +1 -1
- package/dist/adapters/discord/components.js.map +1 -1
- package/dist/adapters/discord/types.d.ts +7 -0
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +8 -0
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +39 -3
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/types.d.ts +5 -0
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/github/webhook.d.ts +20 -0
- package/dist/adapters/github/webhook.d.ts.map +1 -0
- package/dist/adapters/github/webhook.js +78 -0
- package/dist/adapters/github/webhook.js.map +1 -0
- package/dist/adapters/markdown-tables.d.ts +2 -7
- package/dist/adapters/markdown-tables.d.ts.map +1 -1
- package/dist/adapters/markdown-tables.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +2 -30
- package/dist/adapters/slack/assistant.d.ts.map +1 -1
- package/dist/adapters/slack/assistant.js +1 -0
- package/dist/adapters/slack/assistant.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +3 -4
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +19 -64
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +29 -0
- 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.map +1 -1
- package/dist/adapters/telegram/bot.js +39 -65
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent/catalog.d.ts +34 -0
- package/dist/agent/catalog.d.ts.map +1 -0
- package/dist/agent/catalog.js +236 -0
- package/dist/agent/catalog.js.map +1 -0
- package/dist/agent/execution.d.ts +32 -0
- package/dist/agent/execution.d.ts.map +1 -0
- package/dist/agent/execution.js +169 -0
- package/dist/agent/execution.js.map +1 -0
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/presenter.d.ts +46 -0
- package/dist/agent/presenter.d.ts.map +1 -0
- package/dist/agent/presenter.js +673 -0
- package/dist/agent/presenter.js.map +1 -0
- package/dist/agent/prompt.d.ts +30 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +355 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/runner.d.ts +10 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +441 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/types.d.ts +99 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +4 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +5 -2
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/sessions.d.ts +2 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +78 -0
- package/dist/cli/sessions.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/login.d.ts.map +1 -1
- package/dist/commands/login.js +12 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +3 -0
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +25 -10
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.js +1 -1
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/types.d.ts +6 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -1
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +6 -1
- package/dist/env-manifest.js.map +1 -1
- package/dist/execution-resolver.js +1 -1
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/event-format.d.ts +7 -0
- package/dist/harness/event-format.d.ts.map +1 -1
- package/dist/harness/event-format.js +17 -0
- package/dist/harness/event-format.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +12 -2
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +14 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +49 -3
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/index.d.ts +3 -3
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +2 -2
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/runner.d.ts +1 -2
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +27 -40
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +50 -51
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +439 -271
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +1 -1
- package/dist/harness/subagent-runner.d.ts.map +1 -1
- package/dist/harness/subagent-runner.js +9 -5
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/harness/subagent-slots.d.ts.map +1 -0
- package/dist/harness/subagent-slots.js.map +1 -0
- package/dist/harness/types.d.ts +29 -16
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +9 -4
- package/dist/harness/usage.d.ts.map +1 -1
- package/dist/harness/usage.js +9 -3
- package/dist/harness/usage.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.js +18 -0
- package/dist/main.js.map +1 -1
- package/dist/mcp/loader.d.ts +11 -0
- package/dist/mcp/loader.d.ts.map +1 -0
- package/dist/mcp/loader.js +126 -0
- package/dist/mcp/loader.js.map +1 -0
- package/dist/mcp/types.d.ts +38 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/provisioner.d.ts +1 -0
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +22 -3
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +99 -58
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +13 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +62 -1
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/identity.d.ts +12 -5
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +14 -5
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +2 -2
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +48 -50
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +18 -0
- package/dist/sessions/migrate-v3.d.ts.map +1 -0
- package/dist/sessions/migrate-v3.js +359 -0
- package/dist/sessions/migrate-v3.js.map +1 -0
- package/dist/sessions/rotation.js +4 -2
- package/dist/sessions/rotation.js.map +1 -1
- package/dist/sessions/store.d.ts +1 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +19 -36
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +1 -2
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings-mutation.d.ts.map +1 -1
- package/dist/settings-mutation.js +6 -1
- package/dist/settings-mutation.js.map +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +2 -12
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/index.d.ts +2 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +0 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +1 -1
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +323 -27
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/server.d.ts +2 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +5 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.js +6 -6
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts +2 -2
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +51 -75
- package/dist/web/session-view/service.js.map +1 -1
- package/package.json +4 -3
- package/dist/agent.d.ts +0 -34
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -1820
- package/dist/agent.js.map +0 -1
- package/dist/tools/subagent-slots.d.ts.map +0 -1
- package/dist/tools/subagent-slots.js.map +0 -1
- /package/dist/{tools → harness}/subagent-slots.d.ts +0 -0
- /package/dist/{tools → harness}/subagent-slots.js +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import {} from "@earendil-works/pi-ai";
|
|
2
|
+
import { loadExtensions, loadSkillsFromDir, MikanAgentSession, } from "../harness/index.js";
|
|
3
|
+
import { runSubagent } from "../harness/subagent-runner.js";
|
|
4
|
+
import { loadSubagentProfiles } from "../harness/subagent-profiles.js";
|
|
5
|
+
import { packageSkillRuntimeDir, resolveConversationPackages } from "../packages/index.js";
|
|
6
|
+
import * as log from "../log.js";
|
|
7
|
+
import { HostEventStore } from "../tools/event.js";
|
|
8
|
+
import { createSubagentTool } from "../tools/index.js";
|
|
9
|
+
import { DEFAULT_GLOBAL_SUBAGENT_SLOTS, SubagentSlotPool } from "../harness/subagent-slots.js";
|
|
10
|
+
// One process-wide fan-out account: per-conversation queues serialize runs,
|
|
11
|
+
// but each run can fan out up to the per-run cap — without this shared
|
|
12
|
+
// ceiling, N busy conversations hold N × cap live subagent sessions.
|
|
13
|
+
const globalSubagentSlots = new SubagentSlotPool(DEFAULT_GLOBAL_SUBAGENT_SLOTS);
|
|
14
|
+
export function loadMikanSkills(office, workspacePath, projection) {
|
|
15
|
+
const skillMap = new Map();
|
|
16
|
+
// workspacePath is the runtime-side root (e.g. /workspace); host paths under
|
|
17
|
+
// the workspace root translate onto it for prompt references.
|
|
18
|
+
const hostWorkspacePath = office.workspace.root;
|
|
19
|
+
// Helper to translate host paths to container paths
|
|
20
|
+
const translatePath = (hostPath) => {
|
|
21
|
+
if (hostPath.startsWith(hostWorkspacePath)) {
|
|
22
|
+
return workspacePath + hostPath.slice(hostWorkspacePath.length);
|
|
23
|
+
}
|
|
24
|
+
return hostPath;
|
|
25
|
+
};
|
|
26
|
+
// Package skills first: they are the lowest precedence, so a workspace or
|
|
27
|
+
// conversation skill of the same name below overwrites them. A package can
|
|
28
|
+
// offer a capability without taking the name away from whoever wants to
|
|
29
|
+
// replace it locally.
|
|
30
|
+
//
|
|
31
|
+
// Unlike extension-shipped skills, these are NOT inlined into the prompt:
|
|
32
|
+
// conversationPackageSkillMounts exposes them read-only at a runtime path,
|
|
33
|
+
// so the agent can read the files — including any scripts or templates the
|
|
34
|
+
// skill ships alongside its SKILL.md, which inlining could never carry.
|
|
35
|
+
const mounted = workspacePath !== hostWorkspacePath;
|
|
36
|
+
for (const { slug, dir } of resolveConversationPackages({ office }).skillDirs) {
|
|
37
|
+
const runtimeDir = packageSkillRuntimeDir(slug);
|
|
38
|
+
for (const skill of loadSkillsFromDir({ dir, source: `package:${slug}` }).skills) {
|
|
39
|
+
// In host mode there is no mount, so the host path is already the path
|
|
40
|
+
// the agent will use.
|
|
41
|
+
if (mounted) {
|
|
42
|
+
skill.filePath = runtimeDir + skill.filePath.slice(dir.length);
|
|
43
|
+
skill.baseDir = runtimeDir + skill.baseDir.slice(dir.length);
|
|
44
|
+
}
|
|
45
|
+
skillMap.set(skill.name, skill);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Load workspace-level skills only when the office projection authorizes it.
|
|
49
|
+
const workspaceSkillsDir = projection.promptSources.globalSkillsDir;
|
|
50
|
+
if (workspaceSkillsDir) {
|
|
51
|
+
for (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: "workspace" })
|
|
52
|
+
.skills) {
|
|
53
|
+
skill.filePath = translatePath(skill.filePath);
|
|
54
|
+
skill.baseDir = translatePath(skill.baseDir);
|
|
55
|
+
skillMap.set(skill.name, skill);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Load conversation-specific skills (override workspace skills on collision).
|
|
59
|
+
// Host prompt construction must never follow an agent-created symlink out of
|
|
60
|
+
// the conversation office, so this load rejects symlinks per entry — on
|
|
61
|
+
// exactly the paths it reads. Vendored node_modules and dot directories are
|
|
62
|
+
// never read and never disqualify anything.
|
|
63
|
+
const conversationSkillsDir = projection.promptSources.conversationSkillsDir;
|
|
64
|
+
const conversationSkills = loadSkillsFromDir({
|
|
65
|
+
dir: conversationSkillsDir,
|
|
66
|
+
source: "channel",
|
|
67
|
+
rejectSymlinks: true,
|
|
68
|
+
});
|
|
69
|
+
const skippedSkillLinks = [];
|
|
70
|
+
for (const diagnostic of conversationSkills.diagnostics) {
|
|
71
|
+
if (diagnostic.code !== "symlink")
|
|
72
|
+
continue;
|
|
73
|
+
log.logWarning("Skipping conversation skill entry (symlink)", diagnostic.path);
|
|
74
|
+
skippedSkillLinks.push(translatePath(diagnostic.path));
|
|
75
|
+
}
|
|
76
|
+
for (const skill of conversationSkills.skills) {
|
|
77
|
+
skill.filePath = translatePath(skill.filePath);
|
|
78
|
+
skill.baseDir = translatePath(skill.baseDir);
|
|
79
|
+
skillMap.set(skill.name, skill);
|
|
80
|
+
}
|
|
81
|
+
return { skills: Array.from(skillMap.values()), skippedSkillLinks };
|
|
82
|
+
}
|
|
83
|
+
export function mergeExtensionSkills(local, extension) {
|
|
84
|
+
if (extension.length === 0)
|
|
85
|
+
return local;
|
|
86
|
+
const byName = new Map();
|
|
87
|
+
for (const skill of extension)
|
|
88
|
+
byName.set(skill.name, skill);
|
|
89
|
+
for (const skill of local)
|
|
90
|
+
byName.set(skill.name, skill);
|
|
91
|
+
return [...byName.values()];
|
|
92
|
+
}
|
|
93
|
+
function buildExtensionHostServices(params) {
|
|
94
|
+
const { workspace, address, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, platformDmOpener, platformHistoryFetcher, platformUserLister, extensionScheduleEngine, runSubagentService, } = params;
|
|
95
|
+
const eventStore = HostEventStore.fromWorkspaceDir(workspace.root);
|
|
96
|
+
return {
|
|
97
|
+
stateDir: workspace.stateDir,
|
|
98
|
+
scheduleStore: {
|
|
99
|
+
write: async (filename, payload) => {
|
|
100
|
+
await eventStore.write(filename, payload);
|
|
101
|
+
},
|
|
102
|
+
delete: async (filename) => (await eventStore.delete(filename)).deleted,
|
|
103
|
+
list: async () => (await eventStore.list()).flatMap((entry) => entry.payload ? [{ filename: entry.filename, payload: entry.payload }] : []),
|
|
104
|
+
},
|
|
105
|
+
...(platformNotifier ? { postMessage: platformNotifier } : {}),
|
|
106
|
+
...(platformReactor ? { addReaction: platformReactor } : {}),
|
|
107
|
+
...(platformUploader ? { uploadFile: platformUploader } : {}),
|
|
108
|
+
...(platformDmOpener ? { openDirectConversation: platformDmOpener } : {}),
|
|
109
|
+
...(platformHistoryFetcher ? { fetchHistory: platformHistoryFetcher } : {}),
|
|
110
|
+
...(platformUserLister ? { listUsers: platformUserLister } : {}),
|
|
111
|
+
...(extensionScheduleEngine
|
|
112
|
+
? {
|
|
113
|
+
callbackScheduleStore: {
|
|
114
|
+
upsert: (slug, name, spec) => extensionScheduleEngine.upsert(address, slug, name, spec),
|
|
115
|
+
delete: (slug, name) => extensionScheduleEngine.delete(address, slug, name),
|
|
116
|
+
list: (slug) => extensionScheduleEngine.list(address, slug),
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
: {}),
|
|
120
|
+
...(platformBlockKit
|
|
121
|
+
? { postBlocks: platformBlockKit.postBlocks, updateBlocks: platformBlockKit.updateBlocks }
|
|
122
|
+
: {}),
|
|
123
|
+
...(runSubagentService ? { runSubagent: runSubagentService } : {}),
|
|
124
|
+
...(vaultManager
|
|
125
|
+
? {
|
|
126
|
+
resolveSecrets: (slug) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},
|
|
127
|
+
}
|
|
128
|
+
: {}),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export async function createConfiguredAgentSession(params) {
|
|
132
|
+
const { office, systemPrompt, model, thinkingLevel, tools, sessionStore, models, vaultManager, platformNotifier, platformReactor, platformUploader, platformBlockKit, platformDmOpener, platformHistoryFetcher, platformUserLister, extensionScheduleEngine, } = params;
|
|
133
|
+
const { address } = office;
|
|
134
|
+
const conversationId = address.conversationId;
|
|
135
|
+
const workspaceDir = office.workspace.root;
|
|
136
|
+
// Host-only dirs under the state dir: extension code runs in the mikan
|
|
137
|
+
// process, so it must never load from workspace paths — those are mounted
|
|
138
|
+
// into sandbox containers and agent-writable (sandbox escape otherwise).
|
|
139
|
+
// resolveConversationPackages only ever returns state-dir paths (and host
|
|
140
|
+
// paths an administrator named explicitly in settings); it never reaches
|
|
141
|
+
// the network on this path, so a slow remote cannot delay a reply.
|
|
142
|
+
let session;
|
|
143
|
+
const loadedProfiles = loadSubagentProfiles(workspaceDir);
|
|
144
|
+
for (const diagnostic of loadedProfiles.diagnostics) {
|
|
145
|
+
log.logWarning(`[${conversationId}] Subagent profile ignored: ${diagnostic.path}`, diagnostic.message);
|
|
146
|
+
}
|
|
147
|
+
// Narrowed to the profiles whose tools actually exist once extensions have
|
|
148
|
+
// contributed theirs. Both subagent entry points read this at call time, so
|
|
149
|
+
// they always agree on which profiles are launchable.
|
|
150
|
+
let runnableSubagentProfiles = loadedProfiles.profiles;
|
|
151
|
+
const resolvedPackages = resolveConversationPackages({ office });
|
|
152
|
+
for (const error of resolvedPackages.errors) {
|
|
153
|
+
log.logWarning(`Package unavailable: ${error.source}`, error.message);
|
|
154
|
+
}
|
|
155
|
+
const extensionsResult = await loadExtensions({
|
|
156
|
+
dirs: resolvedPackages.extensionDirs,
|
|
157
|
+
roots: resolvedPackages.extensionRoots,
|
|
158
|
+
context: { address, conversationId, workspaceDir, model, thinkingLevel },
|
|
159
|
+
services: buildExtensionHostServices({
|
|
160
|
+
workspace: office.workspace,
|
|
161
|
+
address,
|
|
162
|
+
vaultManager,
|
|
163
|
+
platformNotifier,
|
|
164
|
+
platformReactor,
|
|
165
|
+
platformUploader,
|
|
166
|
+
platformBlockKit,
|
|
167
|
+
platformDmOpener,
|
|
168
|
+
platformHistoryFetcher,
|
|
169
|
+
platformUserLister,
|
|
170
|
+
extensionScheduleEngine,
|
|
171
|
+
runSubagentService: (request, extensionTools) => {
|
|
172
|
+
const activeParent = session?.isActiveRun ? session : undefined;
|
|
173
|
+
return runSubagent({
|
|
174
|
+
request,
|
|
175
|
+
defaultModel: model,
|
|
176
|
+
thinkingLevel,
|
|
177
|
+
models,
|
|
178
|
+
workspaceDir,
|
|
179
|
+
availableTools: [...tools, ...extensionTools],
|
|
180
|
+
profiles: runnableSubagentProfiles,
|
|
181
|
+
slots: globalSubagentSlots,
|
|
182
|
+
...(activeParent
|
|
183
|
+
? {
|
|
184
|
+
parentMessages: [...activeParent.messages],
|
|
185
|
+
onUsage: activeParent.captureExternalUsageSink(),
|
|
186
|
+
}
|
|
187
|
+
: {}),
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
}),
|
|
191
|
+
});
|
|
192
|
+
const contributedTools = extensionsResult.registry.getContributedTools();
|
|
193
|
+
const subagentAvailableTools = [...tools, ...contributedTools];
|
|
194
|
+
const availableToolNames = new Set(subagentAvailableTools.map((tool) => tool.name));
|
|
195
|
+
runnableSubagentProfiles = new Map([...loadedProfiles.profiles].filter(([, profile]) => profile.tools.every((tool) => availableToolNames.has(tool))));
|
|
196
|
+
for (const err of extensionsResult.errors) {
|
|
197
|
+
log.logWarning(`[${conversationId}] Extension load error: ${err.path}`, err.error);
|
|
198
|
+
}
|
|
199
|
+
if (extensionsResult.extensions.length > 0) {
|
|
200
|
+
log.logInfo(`[${conversationId}] Loaded ${extensionsResult.extensions.length} extension(s): ${extensionsResult.extensions.map((extension) => extension.name).join(", ")}`);
|
|
201
|
+
}
|
|
202
|
+
const subagentTool = createSubagentTool((request, hooks) => runSubagent({
|
|
203
|
+
request,
|
|
204
|
+
...(hooks?.onActivity ? { onActivity: hooks.onActivity } : {}),
|
|
205
|
+
defaultModel: model,
|
|
206
|
+
thinkingLevel,
|
|
207
|
+
models,
|
|
208
|
+
workspaceDir,
|
|
209
|
+
availableTools: subagentAvailableTools,
|
|
210
|
+
profiles: runnableSubagentProfiles,
|
|
211
|
+
slots: globalSubagentSlots,
|
|
212
|
+
parentMessages: [...session.messages],
|
|
213
|
+
onUsage: session.captureExternalUsageSink(),
|
|
214
|
+
}), runnableSubagentProfiles);
|
|
215
|
+
session = new MikanAgentSession({
|
|
216
|
+
systemPrompt,
|
|
217
|
+
model,
|
|
218
|
+
thinkingLevel,
|
|
219
|
+
tools: [...tools, subagentTool],
|
|
220
|
+
models,
|
|
221
|
+
sessionStore,
|
|
222
|
+
extensions: extensionsResult.registry,
|
|
223
|
+
});
|
|
224
|
+
const activeSession = session;
|
|
225
|
+
const reloaded = await activeSession.reloadFromSession();
|
|
226
|
+
if (reloaded > 0) {
|
|
227
|
+
log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
session: activeSession,
|
|
231
|
+
extensionSkills: extensionsResult.skills,
|
|
232
|
+
extensionRegistry: extensionsResult.registry,
|
|
233
|
+
disposeExtensions: extensionsResult.dispose,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/agent/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OfficeAddress } from \"../types.js\";\nimport type { Office, Workspace } from \"../office/index.js\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { type Api, type Model } from \"@earendil-works/pi-ai\";\nimport type { MikanModels } from \"../harness/index.js\";\nimport {\n type ExtensionHostServices,\n type ExtensionScheduleEngine,\n loadExtensions,\n loadSkillsFromDir,\n MikanAgentSession,\n type MikanSkill,\n type SessionStore,\n} from \"../harness/index.js\";\nimport { runSubagent } from \"../harness/subagent-runner.js\";\nimport { loadSubagentProfiles } from \"../harness/subagent-profiles.js\";\nimport type {\n PlatformBlockKit,\n PlatformDmOpener,\n PlatformHistoryFetcher,\n PlatformNotifier,\n PlatformReactor,\n PlatformUploader,\n PlatformUserLister,\n} from \"../types.js\";\nimport type { WorkspaceProjection } from \"../workspace-projection/types.js\";\nimport { packageSkillRuntimeDir, resolveConversationPackages } from \"../packages/index.js\";\nimport * as log from \"../log.js\";\nimport type { VaultManager } from \"../vault/index.js\";\nimport { HostEventStore } from \"../tools/event.js\";\nimport type { createMikanTools } from \"../tools/index.js\";\nimport { createSubagentTool } from \"../tools/index.js\";\nimport { DEFAULT_GLOBAL_SUBAGENT_SLOTS, SubagentSlotPool } from \"../harness/subagent-slots.js\";\nimport type { ConfiguredAgentSession } from \"./types.js\";\n\n// One process-wide fan-out account: per-conversation queues serialize runs,\n// but each run can fan out up to the per-run cap — without this shared\n// ceiling, N busy conversations hold N × cap live subagent sessions.\nconst globalSubagentSlots = new SubagentSlotPool(DEFAULT_GLOBAL_SUBAGENT_SLOTS);\n\nexport function loadMikanSkills(\n office: Office,\n workspacePath: string,\n projection: WorkspaceProjection,\n): { skills: MikanSkill[]; skippedSkillLinks: string[] } {\n const skillMap = new Map<string, MikanSkill>();\n\n // workspacePath is the runtime-side root (e.g. /workspace); host paths under\n // the workspace root translate onto it for prompt references.\n const hostWorkspacePath = office.workspace.root;\n\n // Helper to translate host paths to container paths\n const translatePath = (hostPath: string): string => {\n if (hostPath.startsWith(hostWorkspacePath)) {\n return workspacePath + hostPath.slice(hostWorkspacePath.length);\n }\n return hostPath;\n };\n\n // Package skills first: they are the lowest precedence, so a workspace or\n // conversation skill of the same name below overwrites them. A package can\n // offer a capability without taking the name away from whoever wants to\n // replace it locally.\n //\n // Unlike extension-shipped skills, these are NOT inlined into the prompt:\n // conversationPackageSkillMounts exposes them read-only at a runtime path,\n // so the agent can read the files — including any scripts or templates the\n // skill ships alongside its SKILL.md, which inlining could never carry.\n const mounted = workspacePath !== hostWorkspacePath;\n for (const { slug, dir } of resolveConversationPackages({ office }).skillDirs) {\n const runtimeDir = packageSkillRuntimeDir(slug);\n for (const skill of loadSkillsFromDir({ dir, source: `package:${slug}` }).skills) {\n // In host mode there is no mount, so the host path is already the path\n // the agent will use.\n if (mounted) {\n skill.filePath = runtimeDir + skill.filePath.slice(dir.length);\n skill.baseDir = runtimeDir + skill.baseDir.slice(dir.length);\n }\n skillMap.set(skill.name, skill);\n }\n }\n\n // Load workspace-level skills only when the office projection authorizes it.\n const workspaceSkillsDir = projection.promptSources.globalSkillsDir;\n if (workspaceSkillsDir) {\n for (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: \"workspace\" })\n .skills) {\n skill.filePath = translatePath(skill.filePath);\n skill.baseDir = translatePath(skill.baseDir);\n skillMap.set(skill.name, skill);\n }\n }\n\n // Load conversation-specific skills (override workspace skills on collision).\n // Host prompt construction must never follow an agent-created symlink out of\n // the conversation office, so this load rejects symlinks per entry — on\n // exactly the paths it reads. Vendored node_modules and dot directories are\n // never read and never disqualify anything.\n const conversationSkillsDir = projection.promptSources.conversationSkillsDir;\n const conversationSkills = loadSkillsFromDir({\n dir: conversationSkillsDir,\n source: \"channel\",\n rejectSymlinks: true,\n });\n const skippedSkillLinks: string[] = [];\n for (const diagnostic of conversationSkills.diagnostics) {\n if (diagnostic.code !== \"symlink\") continue;\n log.logWarning(\"Skipping conversation skill entry (symlink)\", diagnostic.path);\n skippedSkillLinks.push(translatePath(diagnostic.path));\n }\n for (const skill of conversationSkills.skills) {\n skill.filePath = translatePath(skill.filePath);\n skill.baseDir = translatePath(skill.baseDir);\n skillMap.set(skill.name, skill);\n }\n\n return { skills: Array.from(skillMap.values()), skippedSkillLinks };\n}\n\nexport function mergeExtensionSkills(local: MikanSkill[], extension: MikanSkill[]): MikanSkill[] {\n if (extension.length === 0) return local;\n const byName = new Map<string, MikanSkill>();\n for (const skill of extension) byName.set(skill.name, skill);\n for (const skill of local) byName.set(skill.name, skill);\n return [...byName.values()];\n}\n\nfunction buildExtensionHostServices(params: {\n workspace: Workspace;\n address: OfficeAddress;\n vaultManager?: VaultManager;\n platformNotifier?: PlatformNotifier;\n platformReactor?: PlatformReactor;\n platformUploader?: PlatformUploader;\n platformBlockKit?: PlatformBlockKit;\n platformDmOpener?: PlatformDmOpener;\n platformHistoryFetcher?: PlatformHistoryFetcher;\n platformUserLister?: PlatformUserLister;\n extensionScheduleEngine?: ExtensionScheduleEngine;\n runSubagentService?: ExtensionHostServices[\"runSubagent\"];\n}): ExtensionHostServices {\n const {\n workspace,\n address,\n vaultManager,\n platformNotifier,\n platformReactor,\n platformUploader,\n platformBlockKit,\n platformDmOpener,\n platformHistoryFetcher,\n platformUserLister,\n extensionScheduleEngine,\n runSubagentService,\n } = params;\n const eventStore = HostEventStore.fromWorkspaceDir(workspace.root);\n return {\n stateDir: workspace.stateDir,\n scheduleStore: {\n write: async (filename, payload) => {\n await eventStore.write(filename, payload);\n },\n delete: async (filename) => (await eventStore.delete(filename)).deleted,\n list: async () =>\n (await eventStore.list()).flatMap((entry) =>\n entry.payload ? [{ filename: entry.filename, payload: entry.payload }] : [],\n ),\n },\n ...(platformNotifier ? { postMessage: platformNotifier } : {}),\n ...(platformReactor ? { addReaction: platformReactor } : {}),\n ...(platformUploader ? { uploadFile: platformUploader } : {}),\n ...(platformDmOpener ? { openDirectConversation: platformDmOpener } : {}),\n ...(platformHistoryFetcher ? { fetchHistory: platformHistoryFetcher } : {}),\n ...(platformUserLister ? { listUsers: platformUserLister } : {}),\n ...(extensionScheduleEngine\n ? {\n callbackScheduleStore: {\n upsert: (slug, name, spec) => extensionScheduleEngine.upsert(address, slug, name, spec),\n delete: (slug, name) => extensionScheduleEngine.delete(address, slug, name),\n list: (slug) => extensionScheduleEngine.list(address, slug),\n },\n }\n : {}),\n ...(platformBlockKit\n ? { postBlocks: platformBlockKit.postBlocks, updateBlocks: platformBlockKit.updateBlocks }\n : {}),\n ...(runSubagentService ? { runSubagent: runSubagentService } : {}),\n ...(vaultManager\n ? {\n resolveSecrets: (slug: string) => vaultManager.resolve(`extensions/${slug}`)?.env ?? {},\n }\n : {}),\n };\n}\n\nexport async function createConfiguredAgentSession(params: {\n office: Office;\n systemPrompt: string;\n model: Model<Api>;\n thinkingLevel: ThinkingLevel;\n tools: Awaited<ReturnType<typeof createMikanTools>>[\"tools\"];\n sessionStore: SessionStore;\n models: MikanModels;\n vaultManager?: VaultManager;\n platformNotifier?: PlatformNotifier;\n platformReactor?: PlatformReactor;\n platformUploader?: PlatformUploader;\n platformBlockKit?: PlatformBlockKit;\n platformDmOpener?: PlatformDmOpener;\n platformHistoryFetcher?: PlatformHistoryFetcher;\n platformUserLister?: PlatformUserLister;\n extensionScheduleEngine?: ExtensionScheduleEngine;\n}): Promise<ConfiguredAgentSession> {\n const {\n office,\n systemPrompt,\n model,\n thinkingLevel,\n tools,\n sessionStore,\n models,\n vaultManager,\n platformNotifier,\n platformReactor,\n platformUploader,\n platformBlockKit,\n platformDmOpener,\n platformHistoryFetcher,\n platformUserLister,\n extensionScheduleEngine,\n } = params;\n const { address } = office;\n const conversationId = address.conversationId;\n const workspaceDir = office.workspace.root;\n\n // Host-only dirs under the state dir: extension code runs in the mikan\n // process, so it must never load from workspace paths — those are mounted\n // into sandbox containers and agent-writable (sandbox escape otherwise).\n // resolveConversationPackages only ever returns state-dir paths (and host\n // paths an administrator named explicitly in settings); it never reaches\n // the network on this path, so a slow remote cannot delay a reply.\n let session: MikanAgentSession | undefined;\n const loadedProfiles = loadSubagentProfiles(workspaceDir);\n for (const diagnostic of loadedProfiles.diagnostics) {\n log.logWarning(\n `[${conversationId}] Subagent profile ignored: ${diagnostic.path}`,\n diagnostic.message,\n );\n }\n // Narrowed to the profiles whose tools actually exist once extensions have\n // contributed theirs. Both subagent entry points read this at call time, so\n // they always agree on which profiles are launchable.\n let runnableSubagentProfiles = loadedProfiles.profiles;\n const resolvedPackages = resolveConversationPackages({ office });\n for (const error of resolvedPackages.errors) {\n log.logWarning(`Package unavailable: ${error.source}`, error.message);\n }\n const extensionsResult = await loadExtensions({\n dirs: resolvedPackages.extensionDirs,\n roots: resolvedPackages.extensionRoots,\n context: { address, conversationId, workspaceDir, model, thinkingLevel },\n services: buildExtensionHostServices({\n workspace: office.workspace,\n address,\n vaultManager,\n platformNotifier,\n platformReactor,\n platformUploader,\n platformBlockKit,\n platformDmOpener,\n platformHistoryFetcher,\n platformUserLister,\n extensionScheduleEngine,\n runSubagentService: (request, extensionTools) => {\n const activeParent = session?.isActiveRun ? session : undefined;\n return runSubagent({\n request,\n defaultModel: model,\n thinkingLevel,\n models,\n workspaceDir,\n availableTools: [...tools, ...extensionTools],\n profiles: runnableSubagentProfiles,\n slots: globalSubagentSlots,\n ...(activeParent\n ? {\n parentMessages: [...activeParent.messages],\n onUsage: activeParent.captureExternalUsageSink(),\n }\n : {}),\n });\n },\n }),\n });\n const contributedTools = extensionsResult.registry.getContributedTools();\n const subagentAvailableTools = [...tools, ...contributedTools];\n const availableToolNames = new Set(subagentAvailableTools.map((tool) => tool.name));\n runnableSubagentProfiles = new Map(\n [...loadedProfiles.profiles].filter(([, profile]) =>\n profile.tools.every((tool) => availableToolNames.has(tool)),\n ),\n );\n for (const err of extensionsResult.errors) {\n log.logWarning(`[${conversationId}] Extension load error: ${err.path}`, err.error);\n }\n if (extensionsResult.extensions.length > 0) {\n log.logInfo(\n `[${conversationId}] Loaded ${extensionsResult.extensions.length} extension(s): ${extensionsResult.extensions.map((extension) => extension.name).join(\", \")}`,\n );\n }\n\n const subagentTool = createSubagentTool(\n (request, hooks) =>\n runSubagent({\n request,\n ...(hooks?.onActivity ? { onActivity: hooks.onActivity } : {}),\n defaultModel: model,\n thinkingLevel,\n models,\n workspaceDir,\n availableTools: subagentAvailableTools,\n profiles: runnableSubagentProfiles,\n slots: globalSubagentSlots,\n parentMessages: [...session!.messages],\n onUsage: session!.captureExternalUsageSink(),\n }),\n runnableSubagentProfiles,\n );\n\n session = new MikanAgentSession({\n systemPrompt,\n model,\n thinkingLevel,\n tools: [...tools, subagentTool],\n models,\n sessionStore,\n extensions: extensionsResult.registry,\n });\n\n const activeSession = session;\n const reloaded = await activeSession.reloadFromSession();\n if (reloaded > 0) {\n log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from session context`);\n }\n return {\n session: activeSession,\n extensionSkills: extensionsResult.skills,\n extensionRegistry: extensionsResult.registry,\n disposeExtensions: extensionsResult.dispose,\n };\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Office, Workspace } from "../office/index.js";
|
|
2
|
+
import { type ImageContent } from "@earendil-works/pi-ai";
|
|
3
|
+
import type { ConversationMessage } from "../adapter.js";
|
|
4
|
+
import type { DockerContainerManager } from "../provisioner.js";
|
|
5
|
+
import { type Executor, type RuntimePathContext, type SandboxConfig } from "../sandbox/index.js";
|
|
6
|
+
import type { VaultManager } from "../vault/index.js";
|
|
7
|
+
import type { RunnerExecutionContext } from "./types.js";
|
|
8
|
+
export declare function translateRuntimePathToHost(runtimePath: string, pathContext: RuntimePathContext): string;
|
|
9
|
+
export declare function translateAttachPathToHost(filePath: string, pathContext: RuntimePathContext): string;
|
|
10
|
+
/**
|
|
11
|
+
* Normalize an attachment path using runtime lexical semantics only. The
|
|
12
|
+
* executor remains the authority for reading the resulting runtime path.
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeAttachRuntimePath(filePath: string, runtimeWorkspaceRoot: string): string;
|
|
15
|
+
export declare function withStagedRuntimeFile(executor: Executor, runtimePath: string, upload: (stagedPath: string) => Promise<void>): Promise<void>;
|
|
16
|
+
export declare function collectMessageAttachments(message: ConversationMessage, workspacePath: string, pathContext?: RuntimePathContext, readAttachment?: (runtimePath: string) => Promise<string>): Promise<{
|
|
17
|
+
imageAttachments: ImageContent[];
|
|
18
|
+
nonImagePaths: string[];
|
|
19
|
+
}>;
|
|
20
|
+
export declare function buildRuntimePaths(runtimeWorkspaceRoot: string, office: Office): {
|
|
21
|
+
workspaceRoot: string;
|
|
22
|
+
conversationPath: string;
|
|
23
|
+
scratchPath: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function createRunnerExecutionContext(sandboxConfig: SandboxConfig, vaultManager: VaultManager | undefined, provisioner: DockerContainerManager | undefined, workspace: Workspace): RunnerExecutionContext;
|
|
26
|
+
/**
|
|
27
|
+
* Extension host services over mikan's runtime infrastructure: schedules
|
|
28
|
+
* become event files under `<workspaceDir>/events` (picked up live by
|
|
29
|
+
* EventsWatcher), secrets come from `vaults/extensions/<slug>/env`, and
|
|
30
|
+
* notify posts through the platform bots when main.ts provides a notifier.
|
|
31
|
+
*/
|
|
32
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/agent/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAK1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,kBAAkB,GAC9B,MAAM,CAER;AAcD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,kBAAkB,GAC9B,MAAM,CA2BR;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAgBjG;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAaf;AAcD,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,mBAAmB,EAC5B,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,kBAAkB,EAChC,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACxD,OAAO,CAAC;IAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyBxE;AAED,wBAAgB,iBAAiB,CAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;EAQ7E;AAED,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,WAAW,EAAE,sBAAsB,GAAG,SAAS,EAC/C,SAAS,EAAE,SAAS,GACnB,sBAAsB,CA6CxB;AAED;;;;;GAKG"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {} from "@earendil-works/pi-ai";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { chmod, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { basename, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
6
|
+
import { ActorExecutionResolver } from "../execution-resolver.js";
|
|
7
|
+
import { createExecutor, } from "../sandbox/index.js";
|
|
8
|
+
export function translateRuntimePathToHost(runtimePath, pathContext) {
|
|
9
|
+
return pathContext.runtimeToHostPath?.(runtimePath) ?? runtimePath;
|
|
10
|
+
}
|
|
11
|
+
function isWithinPathRoot(path, root) {
|
|
12
|
+
const pathRelative = relative(root, path);
|
|
13
|
+
return (pathRelative === "" ||
|
|
14
|
+
(pathRelative !== ".." && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative)));
|
|
15
|
+
}
|
|
16
|
+
function hasParentTraversal(path) {
|
|
17
|
+
return path.split(/[\\/]/).some((segment) => segment === "..");
|
|
18
|
+
}
|
|
19
|
+
export function translateAttachPathToHost(filePath, pathContext) {
|
|
20
|
+
if (!pathContext.runtimeToHostPath) {
|
|
21
|
+
throw new Error("Cannot attach files: this sandbox has no host-backed runtime path mapping; attachments are unavailable for remote sandboxes such as Cloudflare or Firecracker");
|
|
22
|
+
}
|
|
23
|
+
if (hasParentTraversal(filePath)) {
|
|
24
|
+
throw new Error("Cannot attach files: parent-directory traversal is not allowed");
|
|
25
|
+
}
|
|
26
|
+
const runtimeRoot = resolve(pathContext.runtimeWorkspaceRoot);
|
|
27
|
+
const runtimePath = posix.isAbsolute(filePath)
|
|
28
|
+
? filePath
|
|
29
|
+
: posix.join(pathContext.runtimeWorkspaceRoot, filePath);
|
|
30
|
+
const normalizedRuntimePath = resolve(runtimePath);
|
|
31
|
+
if (!isWithinPathRoot(normalizedRuntimePath, runtimeRoot)) {
|
|
32
|
+
throw new Error("Cannot attach files: path must be within the runtime workspace");
|
|
33
|
+
}
|
|
34
|
+
const hostRoot = resolve(pathContext.hostWorkspaceRoot);
|
|
35
|
+
const translatedPath = pathContext.runtimeToHostPath(runtimePath);
|
|
36
|
+
const hostPath = resolve(translatedPath);
|
|
37
|
+
if (!isWithinPathRoot(hostPath, hostRoot)) {
|
|
38
|
+
throw new Error("Cannot attach files: path must be within the host workspace");
|
|
39
|
+
}
|
|
40
|
+
return hostPath;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalize an attachment path using runtime lexical semantics only. The
|
|
44
|
+
* executor remains the authority for reading the resulting runtime path.
|
|
45
|
+
*/
|
|
46
|
+
export function normalizeAttachRuntimePath(filePath, runtimeWorkspaceRoot) {
|
|
47
|
+
if (hasParentTraversal(filePath)) {
|
|
48
|
+
throw new Error("Cannot attach files: parent-directory traversal is not allowed");
|
|
49
|
+
}
|
|
50
|
+
const runtimeRoot = posix.resolve(runtimeWorkspaceRoot);
|
|
51
|
+
const runtimePath = posix.resolve(runtimeRoot, filePath);
|
|
52
|
+
const runtimeRelativePath = posix.relative(runtimeRoot, runtimePath);
|
|
53
|
+
if (runtimeRelativePath === ".." ||
|
|
54
|
+
runtimeRelativePath.startsWith("../") ||
|
|
55
|
+
posix.isAbsolute(runtimeRelativePath)) {
|
|
56
|
+
throw new Error("Cannot attach files: path must be within the runtime workspace");
|
|
57
|
+
}
|
|
58
|
+
return runtimePath;
|
|
59
|
+
}
|
|
60
|
+
export async function withStagedRuntimeFile(executor, runtimePath, upload) {
|
|
61
|
+
const content = Buffer.from(await executor.readFileBase64(runtimePath), "base64");
|
|
62
|
+
let stagingDir;
|
|
63
|
+
try {
|
|
64
|
+
stagingDir = await mkdtemp(join(tmpdir(), "mikan-upload-"));
|
|
65
|
+
await chmod(stagingDir, 0o700);
|
|
66
|
+
const stagedPath = join(stagingDir, basename(runtimePath));
|
|
67
|
+
await writeFile(stagedPath, content, { mode: 0o600, flag: "wx" });
|
|
68
|
+
await chmod(stagedPath, 0o600);
|
|
69
|
+
await upload(stagedPath);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
if (stagingDir)
|
|
73
|
+
await rm(stagingDir, { recursive: true, force: true });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const IMAGE_MIME_TYPES = {
|
|
77
|
+
jpg: "image/jpeg",
|
|
78
|
+
jpeg: "image/jpeg",
|
|
79
|
+
png: "image/png",
|
|
80
|
+
gif: "image/gif",
|
|
81
|
+
webp: "image/webp",
|
|
82
|
+
};
|
|
83
|
+
function getImageMimeType(filename) {
|
|
84
|
+
return IMAGE_MIME_TYPES[filename.toLowerCase().split(".").pop() || ""];
|
|
85
|
+
}
|
|
86
|
+
export async function collectMessageAttachments(message, workspacePath, pathContext, readAttachment) {
|
|
87
|
+
const imageAttachments = [];
|
|
88
|
+
const nonImagePaths = [];
|
|
89
|
+
for (const attachment of message.attachments || []) {
|
|
90
|
+
const runtimePath = `${workspacePath}/${attachment.localPath}`;
|
|
91
|
+
const hostPath = pathContext?.runtimeToHostPath?.(runtimePath) ?? runtimePath;
|
|
92
|
+
const mimeType = getImageMimeType(attachment.localPath);
|
|
93
|
+
if (mimeType && existsSync(hostPath) && readAttachment) {
|
|
94
|
+
try {
|
|
95
|
+
imageAttachments.push({
|
|
96
|
+
type: "image",
|
|
97
|
+
mimeType,
|
|
98
|
+
data: await readAttachment(runtimePath),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
nonImagePaths.push(runtimePath);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
nonImagePaths.push(runtimePath);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { imageAttachments, nonImagePaths };
|
|
110
|
+
}
|
|
111
|
+
export function buildRuntimePaths(runtimeWorkspaceRoot, office) {
|
|
112
|
+
const workspaceRoot = runtimeWorkspaceRoot.replace(/\/+$/, "") || "/";
|
|
113
|
+
const conversationPath = posix.join(workspaceRoot, office.key);
|
|
114
|
+
return {
|
|
115
|
+
workspaceRoot,
|
|
116
|
+
conversationPath,
|
|
117
|
+
scratchPath: posix.join(conversationPath, "scratch"),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, workspace) {
|
|
121
|
+
const executionResolver = vaultManager && sandboxConfig.type !== "host"
|
|
122
|
+
? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspace)
|
|
123
|
+
: undefined;
|
|
124
|
+
// activeExecutor is replaced at the start of each run() call when executionResolver
|
|
125
|
+
// is present, so the stable `executor` wrapper always delegates to the latest resolved value.
|
|
126
|
+
let activeExecutor = executionResolver !== undefined
|
|
127
|
+
? createExecutor({ type: "host" })
|
|
128
|
+
: createExecutor(sandboxConfig);
|
|
129
|
+
const executor = {
|
|
130
|
+
exec(command, options) {
|
|
131
|
+
return activeExecutor.exec(command, options);
|
|
132
|
+
},
|
|
133
|
+
readFile(path, options) {
|
|
134
|
+
return activeExecutor.readFile(path, options);
|
|
135
|
+
},
|
|
136
|
+
readFileBase64(path, options) {
|
|
137
|
+
return activeExecutor.readFileBase64(path, options);
|
|
138
|
+
},
|
|
139
|
+
writeFile(path, content, options) {
|
|
140
|
+
return activeExecutor.writeFile(path, content, options);
|
|
141
|
+
},
|
|
142
|
+
getWorkspacePath(hostPath) {
|
|
143
|
+
return activeExecutor.getWorkspacePath(hostPath);
|
|
144
|
+
},
|
|
145
|
+
getSandboxConfig() {
|
|
146
|
+
return activeExecutor.getSandboxConfig();
|
|
147
|
+
},
|
|
148
|
+
getPathContext(hostWorkspaceRoot) {
|
|
149
|
+
return activeExecutor.getPathContext(hostWorkspaceRoot);
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
executionResolver,
|
|
154
|
+
executor,
|
|
155
|
+
getPathContext: () => executor.getPathContext(workspace.root),
|
|
156
|
+
async resolveExecutorForRun(context) {
|
|
157
|
+
if (!executionResolver)
|
|
158
|
+
return;
|
|
159
|
+
activeExecutor = await executionResolver.resolve(context);
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Extension host services over mikan's runtime infrastructure: schedules
|
|
165
|
+
* become event files under `<workspaceDir>/events` (picked up live by
|
|
166
|
+
* EventsWatcher), secrets come from `vaults/extensions/<slug>/env`, and
|
|
167
|
+
* notify posts through the platform bots when main.ts provides a notifier.
|
|
168
|
+
*/
|
|
169
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/agent/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Office, Workspace } from \"../office/index.js\";\nimport { type ImageContent } from \"@earendil-works/pi-ai\";\nimport { existsSync } from \"node:fs\";\nimport { chmod, mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { basename, isAbsolute, join, posix, relative, resolve, sep } from \"node:path\";\nimport type { ConversationMessage } from \"../adapter.js\";\nimport { ActorExecutionResolver } from \"../execution-resolver.js\";\nimport type { DockerContainerManager } from \"../provisioner.js\";\nimport {\n createExecutor,\n type Executor,\n type RuntimePathContext,\n type SandboxConfig,\n} from \"../sandbox/index.js\";\nimport type { VaultManager } from \"../vault/index.js\";\nimport type { RunnerExecutionContext } from \"./types.js\";\n\nexport function translateRuntimePathToHost(\n runtimePath: string,\n pathContext: RuntimePathContext,\n): string {\n return pathContext.runtimeToHostPath?.(runtimePath) ?? runtimePath;\n}\n\nfunction isWithinPathRoot(path: string, root: string): boolean {\n const pathRelative = relative(root, path);\n return (\n pathRelative === \"\" ||\n (pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative))\n );\n}\n\nfunction hasParentTraversal(path: string): boolean {\n return path.split(/[\\\\/]/).some((segment) => segment === \"..\");\n}\n\nexport function translateAttachPathToHost(\n filePath: string,\n pathContext: RuntimePathContext,\n): string {\n if (!pathContext.runtimeToHostPath) {\n throw new Error(\n \"Cannot attach files: this sandbox has no host-backed runtime path mapping; attachments are unavailable for remote sandboxes such as Cloudflare or Firecracker\",\n );\n }\n if (hasParentTraversal(filePath)) {\n throw new Error(\"Cannot attach files: parent-directory traversal is not allowed\");\n }\n\n const runtimeRoot = resolve(pathContext.runtimeWorkspaceRoot);\n const runtimePath = posix.isAbsolute(filePath)\n ? filePath\n : posix.join(pathContext.runtimeWorkspaceRoot, filePath);\n const normalizedRuntimePath = resolve(runtimePath);\n if (!isWithinPathRoot(normalizedRuntimePath, runtimeRoot)) {\n throw new Error(\"Cannot attach files: path must be within the runtime workspace\");\n }\n\n const hostRoot = resolve(pathContext.hostWorkspaceRoot);\n const translatedPath = pathContext.runtimeToHostPath(runtimePath);\n const hostPath = resolve(translatedPath);\n if (!isWithinPathRoot(hostPath, hostRoot)) {\n throw new Error(\"Cannot attach files: path must be within the host workspace\");\n }\n\n return hostPath;\n}\n\n/**\n * Normalize an attachment path using runtime lexical semantics only. The\n * executor remains the authority for reading the resulting runtime path.\n */\nexport function normalizeAttachRuntimePath(filePath: string, runtimeWorkspaceRoot: string): string {\n if (hasParentTraversal(filePath)) {\n throw new Error(\"Cannot attach files: parent-directory traversal is not allowed\");\n }\n\n const runtimeRoot = posix.resolve(runtimeWorkspaceRoot);\n const runtimePath = posix.resolve(runtimeRoot, filePath);\n const runtimeRelativePath = posix.relative(runtimeRoot, runtimePath);\n if (\n runtimeRelativePath === \"..\" ||\n runtimeRelativePath.startsWith(\"../\") ||\n posix.isAbsolute(runtimeRelativePath)\n ) {\n throw new Error(\"Cannot attach files: path must be within the runtime workspace\");\n }\n return runtimePath;\n}\n\nexport async function withStagedRuntimeFile(\n executor: Executor,\n runtimePath: string,\n upload: (stagedPath: string) => Promise<void>,\n): Promise<void> {\n const content = Buffer.from(await executor.readFileBase64(runtimePath), \"base64\");\n let stagingDir: string | undefined;\n try {\n stagingDir = await mkdtemp(join(tmpdir(), \"mikan-upload-\"));\n await chmod(stagingDir, 0o700);\n const stagedPath = join(stagingDir, basename(runtimePath));\n await writeFile(stagedPath, content, { mode: 0o600, flag: \"wx\" });\n await chmod(stagedPath, 0o600);\n await upload(stagedPath);\n } finally {\n if (stagingDir) await rm(stagingDir, { recursive: true, force: true });\n }\n}\n\nconst IMAGE_MIME_TYPES: Record<string, string> = {\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n};\n\nfunction getImageMimeType(filename: string): string | undefined {\n return IMAGE_MIME_TYPES[filename.toLowerCase().split(\".\").pop() || \"\"];\n}\n\nexport async function collectMessageAttachments(\n message: ConversationMessage,\n workspacePath: string,\n pathContext?: RuntimePathContext,\n readAttachment?: (runtimePath: string) => Promise<string>,\n): Promise<{ imageAttachments: ImageContent[]; nonImagePaths: string[] }> {\n const imageAttachments: ImageContent[] = [];\n const nonImagePaths: string[] = [];\n\n for (const attachment of message.attachments || []) {\n const runtimePath = `${workspacePath}/${attachment.localPath}`;\n const hostPath = pathContext?.runtimeToHostPath?.(runtimePath) ?? runtimePath;\n const mimeType = getImageMimeType(attachment.localPath);\n\n if (mimeType && existsSync(hostPath) && readAttachment) {\n try {\n imageAttachments.push({\n type: \"image\",\n mimeType,\n data: await readAttachment(runtimePath),\n });\n } catch {\n nonImagePaths.push(runtimePath);\n }\n } else {\n nonImagePaths.push(runtimePath);\n }\n }\n\n return { imageAttachments, nonImagePaths };\n}\n\nexport function buildRuntimePaths(runtimeWorkspaceRoot: string, office: Office) {\n const workspaceRoot = runtimeWorkspaceRoot.replace(/\\/+$/, \"\") || \"/\";\n const conversationPath = posix.join(workspaceRoot, office.key);\n return {\n workspaceRoot,\n conversationPath,\n scratchPath: posix.join(conversationPath, \"scratch\"),\n };\n}\n\nexport function createRunnerExecutionContext(\n sandboxConfig: SandboxConfig,\n vaultManager: VaultManager | undefined,\n provisioner: DockerContainerManager | undefined,\n workspace: Workspace,\n): RunnerExecutionContext {\n const executionResolver =\n vaultManager && sandboxConfig.type !== \"host\"\n ? new ActorExecutionResolver(sandboxConfig, vaultManager, provisioner, workspace)\n : undefined;\n\n // activeExecutor is replaced at the start of each run() call when executionResolver\n // is present, so the stable `executor` wrapper always delegates to the latest resolved value.\n let activeExecutor: Executor =\n executionResolver !== undefined\n ? createExecutor({ type: \"host\" })\n : createExecutor(sandboxConfig);\n const executor: Executor = {\n exec(command, options) {\n return activeExecutor.exec(command, options);\n },\n readFile(path, options) {\n return activeExecutor.readFile(path, options);\n },\n readFileBase64(path, options) {\n return activeExecutor.readFileBase64(path, options);\n },\n writeFile(path, content, options) {\n return activeExecutor.writeFile(path, content, options);\n },\n getWorkspacePath(hostPath) {\n return activeExecutor.getWorkspacePath(hostPath);\n },\n getSandboxConfig() {\n return activeExecutor.getSandboxConfig();\n },\n getPathContext(hostWorkspaceRoot) {\n return activeExecutor.getPathContext(hostWorkspaceRoot);\n },\n };\n\n return {\n executionResolver,\n executor,\n getPathContext: () => executor.getPathContext(workspace.root),\n async resolveExecutorForRun(context): Promise<void> {\n if (!executionResolver) return;\n activeExecutor = await executionResolver.resolve(context);\n },\n };\n}\n\n/**\n * Extension host services over mikan's runtime infrastructure: schedules\n * become event files under `<workspaceDir>/events` (picked up live by\n * EventsWatcher), secrets come from `vaults/extensions/<slug>/env`, and\n * notify posts through the platform bots when main.ts provides a notifier.\n */\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent runner: prompt construction, path translation, run lifecycle, and createRunner.
|
|
3
|
+
* Split by authority; this barrel preserves the former public surface.
|
|
4
|
+
*/
|
|
5
|
+
export { translateRuntimePathToHost, translateAttachPathToHost } from "./execution.js";
|
|
6
|
+
export { buildPromptPayload, resolveTriggerAttribution, buildTurnInstructions, appendTriggerAttribution, } from "./prompt.js";
|
|
7
|
+
export { createRunner } from "./runner.js";
|
|
8
|
+
export type { PiAgentWrapper } from "../types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent runner: prompt construction, path translation, run lifecycle, and createRunner.
|
|
3
|
+
* Split by authority; this barrel preserves the former public surface.
|
|
4
|
+
*/
|
|
5
|
+
export { translateRuntimePathToHost, translateAttachPathToHost } from "./execution.js";
|
|
6
|
+
export { buildPromptPayload, resolveTriggerAttribution, buildTurnInstructions, appendTriggerAttribution, } from "./prompt.js";
|
|
7
|
+
export { createRunner } from "./runner.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC","sourcesContent":["/**\n * Agent runner: prompt construction, path translation, run lifecycle, and createRunner.\n * Split by authority; this barrel preserves the former public surface.\n */\nexport { translateRuntimePathToHost, translateAttachPathToHost } from \"./execution.js\";\nexport {\n buildPromptPayload,\n resolveTriggerAttribution,\n buildTurnInstructions,\n appendTriggerAttribution,\n} from \"./prompt.js\";\nexport { createRunner } from \"./runner.js\";\nexport type { PiAgentWrapper } from \"../types.js\";\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Api, type Model } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { MikanAgentSession } from "../harness/index.js";
|
|
3
|
+
import type { ConversationResponder } from "../adapter.js";
|
|
4
|
+
import type { AgentEventPayload } from "../types.js";
|
|
5
|
+
import type { resolveConversationSettings } from "../config.js";
|
|
6
|
+
import type { RunnerSessionState, UsageReportContext } from "./types.js";
|
|
7
|
+
export declare function createRunState(): RunnerSessionState;
|
|
8
|
+
export declare function resetRunState(runState: RunnerSessionState, responder: ConversationResponder, sessionConversation: string, userName: string | undefined, sessionUuid: string, triggerAttribution: string | undefined): void;
|
|
9
|
+
export declare function createRunQueue(responder: ConversationResponder, runState: RunnerSessionState): {
|
|
10
|
+
queue: {
|
|
11
|
+
enqueue(fn: () => Promise<void>, errorContext: string): void;
|
|
12
|
+
};
|
|
13
|
+
wait: () => Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
export declare function isEventTriggerAttribution(triggerAttribution: string | undefined): boolean;
|
|
16
|
+
export declare function finalizeRunResponse(responder: ConversationResponder, session: MikanAgentSession, runState: RunnerSessionState, options?: {
|
|
17
|
+
triggerAttribution?: string;
|
|
18
|
+
triggerSessionLink?: string;
|
|
19
|
+
createOverflowLink?: () => string;
|
|
20
|
+
platform?: string;
|
|
21
|
+
model?: Model<Api>;
|
|
22
|
+
sessionConversation?: string;
|
|
23
|
+
sessionUuid?: string;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
export declare function reportUsageSummary(ctx: UsageReportContext): Promise<void>;
|
|
26
|
+
export declare function createNoopResponder(): ConversationResponder;
|
|
27
|
+
export declare function formatAgentActorName(userName: string | undefined, fallback: string): string;
|
|
28
|
+
export declare function sendAgentEvent(payload: {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
actorName: string;
|
|
31
|
+
event: AgentEventPayload;
|
|
32
|
+
}): void;
|
|
33
|
+
export declare function attachSessionEventHandlers(params: {
|
|
34
|
+
session: MikanAgentSession;
|
|
35
|
+
runState: RunnerSessionState;
|
|
36
|
+
model: Model<Api>;
|
|
37
|
+
agentConfig: ReturnType<typeof resolveConversationSettings>;
|
|
38
|
+
}): void;
|
|
39
|
+
/**
|
|
40
|
+
* Create a new PiAgentWrapper for a channel.
|
|
41
|
+
* Sets up the session and subscribes to events once.
|
|
42
|
+
*
|
|
43
|
+
* Runner caching is handled by the caller (channelStates in main.ts).
|
|
44
|
+
* This is a stateless factory function.
|
|
45
|
+
*/
|
|
46
|
+
//# sourceMappingURL=presenter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../../src/agent/presenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAO7D,OAAO,KAAK,EAAE,qBAAqB,EAA4B,MAAM,eAAe,CAAC;AACrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAUhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAYzE,wBAAgB,cAAc,IAAI,kBAAkB,CAsBnD;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,qBAAqB,EAChC,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC,IAAI,CAyBN;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,qBAAqB,EAChC,QAAQ,EAAE,kBAAkB,GAC3B;IACD,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACxE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAuBA;AAYD,wBAAgB,yBAAyB,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEzF;AA+GD,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,qBAAqB,EAChC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE;IACR,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsE/E;AA8BD,wBAAgB,mBAAmB,IAAI,qBAAqB,CAW3D;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,IAAI,CAEP;AAGD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;CAC7D,GAAG,IAAI,CAqUP;AAED;;;;;;GAMG"}
|