@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,441 @@
|
|
|
1
|
+
import { DEFAULT_EVENT_BUDGET, MikanModels, parseCommandInput, } from "../harness/index.js";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { mkdir } from "node:fs/promises";
|
|
4
|
+
import { join, posix } from "node:path";
|
|
5
|
+
import { resolveConversationSettings } from "../config.js";
|
|
6
|
+
import { resolveWorkspaceProjection } from "../workspace-projection/index.js";
|
|
7
|
+
import * as log from "../log.js";
|
|
8
|
+
import { loadMcpTools } from "../mcp/loader.js";
|
|
9
|
+
import { assertSandboxSupportsWorkspacePolicy, getUnresolvedSandboxPathContext, } from "../sandbox/index.js";
|
|
10
|
+
import { addLifecycleBreadcrumb, updateActiveSpanAttribution } from "../observability/sentry.js";
|
|
11
|
+
import { ChatHistorySync } from "../sessions/chat-history-sync.js";
|
|
12
|
+
import { conversationIdOf, isThreadSessionKey } from "../sessions/session-key.js";
|
|
13
|
+
import { extractSessionUuid, openManagedSession, } from "../sessions/store.js";
|
|
14
|
+
import { createMikanTools } from "../tools/index.js";
|
|
15
|
+
import { createConfiguredAgentSession, loadMikanSkills, mergeExtensionSkills } from "./catalog.js";
|
|
16
|
+
import { createRunnerExecutionContext, normalizeAttachRuntimePath, withStagedRuntimeFile, } from "./execution.js";
|
|
17
|
+
import { buildPromptPayload, buildSystemPrompt, buildTurnInstructions, getMemory, resolveTriggerAttribution, SESSION_DREAM_BUDGET, sessionDreamPrompt, sessionDreamTools, } from "./prompt.js";
|
|
18
|
+
import { attachSessionEventHandlers, createNoopResponder, createRunQueue, createRunState, finalizeRunResponse, formatAgentActorName, isEventTriggerAttribution, reportUsageSummary, resetRunState, sendAgentEvent, } from "./presenter.js";
|
|
19
|
+
function buildThreadSessionName(message) {
|
|
20
|
+
const text = message?.text?.trim();
|
|
21
|
+
if (!text)
|
|
22
|
+
return undefined;
|
|
23
|
+
const userLabel = message?.userName || message?.user || "unknown";
|
|
24
|
+
return `[${userLabel}]: ${text}`;
|
|
25
|
+
}
|
|
26
|
+
async function reloadSessionMessages(session, conversationId) {
|
|
27
|
+
const reloaded = await session.reloadFromSession();
|
|
28
|
+
if (reloaded > 0) {
|
|
29
|
+
log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from context`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function prepareRunContext(params) {
|
|
33
|
+
const { message, responder, platform, office, sessionUuid, runState, executor, executionResolver, resolveExecutorForRun, getPathContext, session, setEventContext, setSandboxContext, setUploadFunction, setImageUploadFunction, setReactFunction, bindPlatformToolPacks, } = params;
|
|
34
|
+
const conversationId = office.address.conversationId;
|
|
35
|
+
let pathContext = params.pathContext;
|
|
36
|
+
const sessionConversation = conversationIdOf(message.sessionKey);
|
|
37
|
+
await mkdir(join(office.dir, "scratch"), { recursive: true });
|
|
38
|
+
if (executionResolver) {
|
|
39
|
+
await resolveExecutorForRun({
|
|
40
|
+
address: message.address,
|
|
41
|
+
userId: message.userId,
|
|
42
|
+
trustModel: platform.trustModel,
|
|
43
|
+
});
|
|
44
|
+
pathContext = getPathContext();
|
|
45
|
+
}
|
|
46
|
+
await reloadSessionMessages(session, conversationId);
|
|
47
|
+
const projection = resolveWorkspaceProjection(office);
|
|
48
|
+
const memory = await getMemory(projection);
|
|
49
|
+
const conversationSkillLoad = loadMikanSkills(office, pathContext.runtimeWorkspaceRoot, projection);
|
|
50
|
+
const skills = mergeExtensionSkills(conversationSkillLoad.skills, params.extensionSkills ?? []);
|
|
51
|
+
const triggerAttribution = resolveTriggerAttribution(message);
|
|
52
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, office, message.conversationKind, message.userId, memory, executor.getSandboxConfig(), platform, skills, projection, conversationSkillLoad.skippedSkillLinks);
|
|
53
|
+
session.agent.state.systemPrompt = systemPrompt;
|
|
54
|
+
// Cache diagnosis: a byte-stable system prompt is the precondition for
|
|
55
|
+
// provider prompt caching. If this hash changes between turns of one
|
|
56
|
+
// conversation, something turn-varying leaked into the prompt; if it is
|
|
57
|
+
// stable and cacheRead stays 0, the miss is provider-side (e.g. OpenRouter
|
|
58
|
+
// routing the model across upstream hosts). This is the base prompt mikan
|
|
59
|
+
// builds; a `before_agent_start` extension may still rewrite it per turn
|
|
60
|
+
// (logged separately by the runner).
|
|
61
|
+
const promptHash = createHash("sha256").update(systemPrompt).digest("hex").slice(0, 8);
|
|
62
|
+
log.logInfo(`[${conversationId}] System prompt (base): ${systemPrompt.length} chars, sha ${promptHash}`);
|
|
63
|
+
setEventContext({
|
|
64
|
+
platform: platform.name,
|
|
65
|
+
conversationId,
|
|
66
|
+
conversationKind: message.conversationKind,
|
|
67
|
+
userId: message.userId,
|
|
68
|
+
});
|
|
69
|
+
setSandboxContext({ address: message.address, userId: message.userId });
|
|
70
|
+
setUploadFunction(async (filePath, title) => {
|
|
71
|
+
const runtimePath = normalizeAttachRuntimePath(filePath, pathContext.runtimeWorkspaceRoot);
|
|
72
|
+
await withStagedRuntimeFile(executor, runtimePath, (stagedPath) => responder.uploadFile(stagedPath, title));
|
|
73
|
+
});
|
|
74
|
+
// generate_image writes its file host-side, so it uploads by host path —
|
|
75
|
+
// no staging through the sandbox, where the file may not be mounted.
|
|
76
|
+
setImageUploadFunction(async (hostPath, title) => {
|
|
77
|
+
await responder.uploadFile(hostPath, title);
|
|
78
|
+
});
|
|
79
|
+
// The react tool is available only when the responder supports reactions
|
|
80
|
+
// (interactive turns on platforms with reaction support); otherwise unset
|
|
81
|
+
// so the tool reports it is unavailable rather than silently no-op'ing.
|
|
82
|
+
setReactFunction(responder.react ? async (emoji) => responder.react(emoji) : null);
|
|
83
|
+
// Platform capability packs (e.g. GitHub PR/CI) enable themselves per run;
|
|
84
|
+
// core does not branch on platform name here.
|
|
85
|
+
bindPlatformToolPacks({
|
|
86
|
+
conversationId,
|
|
87
|
+
platformName: platform.name,
|
|
88
|
+
threadTs: message.threadTs,
|
|
89
|
+
});
|
|
90
|
+
resetRunState(runState, responder, sessionConversation, message.userName, sessionUuid, triggerAttribution);
|
|
91
|
+
const runQueue = createRunQueue(responder, runState);
|
|
92
|
+
runState.queue = runQueue.queue;
|
|
93
|
+
log.logInfo(`Context sizes - system: ${systemPrompt.length} chars, memory: ${memory.length} chars`);
|
|
94
|
+
log.logInfo(`Channels: ${platform.channels.length}, Users: ${platform.users.length}`);
|
|
95
|
+
const { userMessage, imageAttachments } = await buildPromptPayload(message, pathContext.runtimeWorkspaceRoot, pathContext, (runtimePath) => executor.readFileBase64(runtimePath));
|
|
96
|
+
const turnInstructions = buildTurnInstructions(message.id.startsWith("event:"), triggerAttribution, platform.name);
|
|
97
|
+
const finalUserMessage = turnInstructions ? `${turnInstructions}\n\n${userMessage}` : userMessage;
|
|
98
|
+
return {
|
|
99
|
+
sessionConversation,
|
|
100
|
+
runQueue,
|
|
101
|
+
userMessage: finalUserMessage,
|
|
102
|
+
imageAttachments,
|
|
103
|
+
triggerAttribution,
|
|
104
|
+
pathContext,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The dream run reads a transcript in which the agent held its full tool set,
|
|
109
|
+
* but `sessionDreamTools` has since narrowed it. Left to infer its grant from
|
|
110
|
+
* the transcript, the model calls a tool it no longer holds and burns one of
|
|
111
|
+
* its five turns on the failure — so the grant is stated, and derived from the
|
|
112
|
+
* tools actually handed to the run rather than restated by hand.
|
|
113
|
+
*/
|
|
114
|
+
export async function createRunner(options) {
|
|
115
|
+
const { sandboxConfig, sessionKey, office, sessionScope, vaultManager, provisioner, resourceController, sessionView, platformNotifier, platformReactor, platformUploader, platformBlockKit, platformDmOpener, platformHistoryFetcher, platformUserLister, extensionScheduleEngine, platformToolPackFactories, } = options;
|
|
116
|
+
const conversationId = office.address.conversationId;
|
|
117
|
+
const conversationDir = office.dir;
|
|
118
|
+
const workspaceDir = office.workspace.root;
|
|
119
|
+
const agentConfig = resolveConversationSettings(office);
|
|
120
|
+
const projection = resolveWorkspaceProjection(office);
|
|
121
|
+
assertSandboxSupportsWorkspacePolicy(sandboxConfig, projection.doorPolicy);
|
|
122
|
+
const { executionResolver, executor, getPathContext, resolveExecutorForRun } = createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, office.workspace);
|
|
123
|
+
let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceDir);
|
|
124
|
+
const modelRegistry = options.models ?? MikanModels.create();
|
|
125
|
+
if (modelRegistry.getError()) {
|
|
126
|
+
log.logWarning("models.json load error", modelRegistry.getError());
|
|
127
|
+
}
|
|
128
|
+
const model = modelRegistry.resolve(agentConfig.provider, agentConfig.model);
|
|
129
|
+
// Create tools (per-runner, with per-runner upload function setter)
|
|
130
|
+
const { tools, setUploadFunction, setImageUploadFunction, setReactFunction, bindPlatformToolPacks, setEventContext, setSandboxContext, } = createMikanTools(executor, workspaceDir, { sandbox: sandboxConfig, resourceController: resourceController ?? provisioner }, platformToolPackFactories ?? [], {
|
|
131
|
+
model,
|
|
132
|
+
getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),
|
|
133
|
+
// The conversation's own office dir: mounted into the sandbox, unlike
|
|
134
|
+
// the workspace base — generated images must land somewhere the agent
|
|
135
|
+
// (and a future run) can still reach.
|
|
136
|
+
outputDir: conversationDir,
|
|
137
|
+
});
|
|
138
|
+
// Initial system prompt (will be updated each run with fresh memory/channels/users/skills)
|
|
139
|
+
const memory = await getMemory(projection);
|
|
140
|
+
const { skills, skippedSkillLinks } = loadMikanSkills(office, pathContext.runtimeWorkspaceRoot, projection);
|
|
141
|
+
const emptyPlatform = {
|
|
142
|
+
name: "chat",
|
|
143
|
+
formattingGuide: "",
|
|
144
|
+
channels: [],
|
|
145
|
+
users: [],
|
|
146
|
+
trustModel: "membership",
|
|
147
|
+
};
|
|
148
|
+
const systemPrompt = buildSystemPrompt(pathContext.runtimeWorkspaceRoot, office, "shared", undefined, memory, sandboxConfig, emptyPlatform, skills, projection, skippedSkillLinks);
|
|
149
|
+
// Create session manager and settings manager. Top-level/private sessions
|
|
150
|
+
// use the conversation's current pointer; scoped sessions use fixed files.
|
|
151
|
+
// Platform-specific scope behavior is resolved before runner creation.
|
|
152
|
+
const isThread = isThreadSessionKey(sessionKey);
|
|
153
|
+
const { contextFile, threadRootMessage } = sessionScope;
|
|
154
|
+
const sessionManager = await openManagedSession(contextFile, pathContext.runtimeWorkspaceRoot);
|
|
155
|
+
const threadSessionName = buildThreadSessionName(threadRootMessage);
|
|
156
|
+
if (isThread &&
|
|
157
|
+
threadSessionName &&
|
|
158
|
+
(await sessionManager.getSessionName()) !== threadSessionName) {
|
|
159
|
+
await sessionManager.setSessionName(threadSessionName);
|
|
160
|
+
}
|
|
161
|
+
const sessionUuid = extractSessionUuid(contextFile);
|
|
162
|
+
const chatSessionManager = new ChatHistorySync();
|
|
163
|
+
// MCP tools run host-side: credentials live in server config (settings) and
|
|
164
|
+
// the server process, never in the sandbox or the model's context. Loaded
|
|
165
|
+
// per-runner so a settings change is picked up on the next runner build.
|
|
166
|
+
const mcpResult = await loadMcpTools(agentConfig.mcpServers ?? {});
|
|
167
|
+
for (const mcpError of mcpResult.errors) {
|
|
168
|
+
log.logWarning(`[${conversationId}] MCP server unavailable: ${mcpError.server}`, mcpError.error);
|
|
169
|
+
}
|
|
170
|
+
if (mcpResult.tools.length > 0) {
|
|
171
|
+
log.logInfo(`[${conversationId}] Loaded ${mcpResult.tools.length} MCP tool(s)`);
|
|
172
|
+
}
|
|
173
|
+
const toolsWithMcp = [...tools, ...mcpResult.tools];
|
|
174
|
+
const { session, extensionSkills, extensionRegistry, disposeExtensions } = await createConfiguredAgentSession({
|
|
175
|
+
office,
|
|
176
|
+
systemPrompt,
|
|
177
|
+
model,
|
|
178
|
+
thinkingLevel: agentConfig.thinkingLevel,
|
|
179
|
+
tools: toolsWithMcp,
|
|
180
|
+
sessionStore: sessionManager,
|
|
181
|
+
models: modelRegistry,
|
|
182
|
+
vaultManager,
|
|
183
|
+
platformNotifier,
|
|
184
|
+
platformReactor,
|
|
185
|
+
platformUploader,
|
|
186
|
+
platformBlockKit,
|
|
187
|
+
platformDmOpener,
|
|
188
|
+
platformHistoryFetcher,
|
|
189
|
+
platformUserLister,
|
|
190
|
+
extensionScheduleEngine,
|
|
191
|
+
});
|
|
192
|
+
// Mutable per-run state - event handler references this
|
|
193
|
+
const runState = createRunState();
|
|
194
|
+
attachSessionEventHandlers({ session, runState, model, agentConfig });
|
|
195
|
+
return {
|
|
196
|
+
async syncChatHistory(currentMessageId) {
|
|
197
|
+
await chatSessionManager.syncSessionManager({
|
|
198
|
+
conversationDir,
|
|
199
|
+
sessionKey,
|
|
200
|
+
sessionManager,
|
|
201
|
+
currentMessageId,
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
async run(message, responder, platform) {
|
|
205
|
+
const prepared = await prepareRunContext({
|
|
206
|
+
message,
|
|
207
|
+
responder,
|
|
208
|
+
platform,
|
|
209
|
+
office,
|
|
210
|
+
sessionUuid,
|
|
211
|
+
runState,
|
|
212
|
+
executor,
|
|
213
|
+
executionResolver,
|
|
214
|
+
resolveExecutorForRun,
|
|
215
|
+
getPathContext,
|
|
216
|
+
session,
|
|
217
|
+
extensionSkills,
|
|
218
|
+
setEventContext,
|
|
219
|
+
setSandboxContext,
|
|
220
|
+
setUploadFunction,
|
|
221
|
+
setImageUploadFunction,
|
|
222
|
+
setReactFunction,
|
|
223
|
+
bindPlatformToolPacks,
|
|
224
|
+
pathContext,
|
|
225
|
+
});
|
|
226
|
+
pathContext = prepared.pathContext;
|
|
227
|
+
try {
|
|
228
|
+
return await runPreparedTurn();
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
// Ownership must return to the pool on every exit — a throw anywhere
|
|
232
|
+
// in the turn (dreamSessionMemory already does this) would otherwise
|
|
233
|
+
// leave the runner permanently "busy" with a stale responder.
|
|
234
|
+
runState.responder = null;
|
|
235
|
+
runState.logCtx = null;
|
|
236
|
+
runState.queue = null;
|
|
237
|
+
}
|
|
238
|
+
async function runPreparedTurn() {
|
|
239
|
+
if (runState.logCtx) {
|
|
240
|
+
log.logAgentRunStart(runState.logCtx, model.provider, model.id, model.name);
|
|
241
|
+
}
|
|
242
|
+
updateActiveSpanAttribution({
|
|
243
|
+
provider: model.provider,
|
|
244
|
+
model: agentConfig.model,
|
|
245
|
+
channel_id: prepared.sessionConversation,
|
|
246
|
+
session_id: sessionUuid,
|
|
247
|
+
});
|
|
248
|
+
addLifecycleBreadcrumb("agent.prompt.sent", {
|
|
249
|
+
provider: model.provider,
|
|
250
|
+
model: agentConfig.model,
|
|
251
|
+
channel_id: prepared.sessionConversation,
|
|
252
|
+
session_id: sessionUuid,
|
|
253
|
+
attachment_count: message.attachments?.length ?? 0,
|
|
254
|
+
image_attachment_count: prepared.imageAttachments.length,
|
|
255
|
+
});
|
|
256
|
+
sendAgentEvent({
|
|
257
|
+
sessionId: sessionUuid,
|
|
258
|
+
actorName: formatAgentActorName(message.userName, prepared.sessionConversation),
|
|
259
|
+
event: { kind: "sessionStart" },
|
|
260
|
+
});
|
|
261
|
+
// Autonomous (event/trigger) runs get an explicit resource ceiling since
|
|
262
|
+
// no human is watching the loop; interactive turns stay human-gated.
|
|
263
|
+
const isEventRun = message.id.startsWith("event:");
|
|
264
|
+
// Event runs have no triggering platform message, so identity fields
|
|
265
|
+
// stay unset and extensions must null-check them.
|
|
266
|
+
const origin = isEventRun
|
|
267
|
+
? { kind: "event", platform: platform.name }
|
|
268
|
+
: {
|
|
269
|
+
kind: "interactive",
|
|
270
|
+
platform: platform.name,
|
|
271
|
+
messageTs: message.id,
|
|
272
|
+
userId: message.userId,
|
|
273
|
+
userName: message.userName,
|
|
274
|
+
threadTs: message.threadTs,
|
|
275
|
+
attachments: message.attachments,
|
|
276
|
+
};
|
|
277
|
+
const outcome = await session.prompt(prepared.userMessage, {
|
|
278
|
+
origin,
|
|
279
|
+
...(prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : {}),
|
|
280
|
+
...(isEventRun ? { budget: DEFAULT_EVENT_BUDGET } : {}),
|
|
281
|
+
});
|
|
282
|
+
if (outcome?.blocked) {
|
|
283
|
+
const text = outcome.reason
|
|
284
|
+
? `_Turn blocked by an extension: ${outcome.reason}_`
|
|
285
|
+
: "_Turn blocked by an extension._";
|
|
286
|
+
sendAgentEvent({
|
|
287
|
+
sessionId: sessionUuid,
|
|
288
|
+
actorName: formatAgentActorName(message.userName, prepared.sessionConversation),
|
|
289
|
+
event: { kind: "diagnostic", text },
|
|
290
|
+
});
|
|
291
|
+
await responder.respondDiagnostic(text, { style: "muted" });
|
|
292
|
+
return { stopReason: "blocked" };
|
|
293
|
+
}
|
|
294
|
+
// Wait for queued messages
|
|
295
|
+
await prepared.runQueue.wait();
|
|
296
|
+
const sessionViewTokenStore = sessionView?.tokenStore;
|
|
297
|
+
const sessionViewPortalBaseUrl = sessionView?.portalBaseUrl;
|
|
298
|
+
let sessionViewLink;
|
|
299
|
+
const createSessionViewLink = sessionViewTokenStore && sessionViewPortalBaseUrl
|
|
300
|
+
? () => {
|
|
301
|
+
if (!sessionViewLink) {
|
|
302
|
+
const token = sessionViewTokenStore.create(platform.name, message.userId, conversationId, message.sessionKey, contextFile, message.userName);
|
|
303
|
+
sessionViewLink = `${sessionViewPortalBaseUrl}/session?token=${token.token}`;
|
|
304
|
+
}
|
|
305
|
+
return sessionViewLink;
|
|
306
|
+
}
|
|
307
|
+
: undefined;
|
|
308
|
+
await finalizeRunResponse(responder, session, runState, {
|
|
309
|
+
triggerAttribution: prepared.triggerAttribution,
|
|
310
|
+
triggerSessionLink: isEventTriggerAttribution(prepared.triggerAttribution)
|
|
311
|
+
? createSessionViewLink?.()
|
|
312
|
+
: undefined,
|
|
313
|
+
createOverflowLink: createSessionViewLink,
|
|
314
|
+
platform: platform.name,
|
|
315
|
+
model,
|
|
316
|
+
sessionConversation: prepared.sessionConversation,
|
|
317
|
+
sessionUuid,
|
|
318
|
+
});
|
|
319
|
+
await reportUsageSummary({
|
|
320
|
+
session,
|
|
321
|
+
runState,
|
|
322
|
+
responder,
|
|
323
|
+
platform,
|
|
324
|
+
model,
|
|
325
|
+
agentConfig,
|
|
326
|
+
sessionConversation: prepared.sessionConversation,
|
|
327
|
+
sessionUuid,
|
|
328
|
+
waitForQueue: () => prepared.runQueue.wait(),
|
|
329
|
+
});
|
|
330
|
+
return { stopReason: runState.stopReason, errorMessage: runState.errorMessage };
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
async dreamSessionMemory(message, platform) {
|
|
334
|
+
const responder = createNoopResponder();
|
|
335
|
+
const prepared = await prepareRunContext({
|
|
336
|
+
message,
|
|
337
|
+
responder,
|
|
338
|
+
platform,
|
|
339
|
+
office,
|
|
340
|
+
sessionUuid,
|
|
341
|
+
runState,
|
|
342
|
+
executor,
|
|
343
|
+
executionResolver,
|
|
344
|
+
resolveExecutorForRun,
|
|
345
|
+
getPathContext,
|
|
346
|
+
session,
|
|
347
|
+
extensionSkills,
|
|
348
|
+
setEventContext,
|
|
349
|
+
setSandboxContext,
|
|
350
|
+
setUploadFunction,
|
|
351
|
+
setImageUploadFunction,
|
|
352
|
+
setReactFunction,
|
|
353
|
+
bindPlatformToolPacks,
|
|
354
|
+
pathContext,
|
|
355
|
+
});
|
|
356
|
+
pathContext = prepared.pathContext;
|
|
357
|
+
try {
|
|
358
|
+
const conversationMemoryPath = posix.join(prepared.pathContext.runtimeWorkspaceRoot, office.key, "MEMORY.md");
|
|
359
|
+
const dreamTools = sessionDreamTools(session.agent.state.tools, conversationMemoryPath);
|
|
360
|
+
const outcome = await session.prompt(sessionDreamPrompt(conversationMemoryPath, dreamTools.map((tool) => tool.name)), {
|
|
361
|
+
origin: {
|
|
362
|
+
kind: "interactive",
|
|
363
|
+
platform: platform.name,
|
|
364
|
+
messageTs: message.id,
|
|
365
|
+
userId: message.userId,
|
|
366
|
+
userName: message.userName,
|
|
367
|
+
threadTs: message.threadTs,
|
|
368
|
+
attachments: message.attachments,
|
|
369
|
+
},
|
|
370
|
+
budget: SESSION_DREAM_BUDGET,
|
|
371
|
+
tools: dreamTools,
|
|
372
|
+
});
|
|
373
|
+
if (outcome?.blocked) {
|
|
374
|
+
return { stopReason: "blocked", errorMessage: outcome.reason };
|
|
375
|
+
}
|
|
376
|
+
await prepared.runQueue.wait();
|
|
377
|
+
// A budget abort carries its reason in the tally, not in errorMessage,
|
|
378
|
+
// and that reason is the only thing that tells the user why memory was
|
|
379
|
+
// not preserved.
|
|
380
|
+
return {
|
|
381
|
+
stopReason: runState.stopReason,
|
|
382
|
+
errorMessage: runState.errorMessage ?? session.getLastRunStats().budgetExceededReason,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
finally {
|
|
386
|
+
runState.responder = null;
|
|
387
|
+
runState.logCtx = null;
|
|
388
|
+
runState.queue = null;
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
abort() {
|
|
392
|
+
session.abort();
|
|
393
|
+
},
|
|
394
|
+
async tryExtensionCommand(message, responder, parseOptions = {}) {
|
|
395
|
+
const parsed = parseCommandInput(message.text, parseOptions);
|
|
396
|
+
if (!parsed)
|
|
397
|
+
return false;
|
|
398
|
+
return extensionRegistry.dispatchCommand(parsed.name, {
|
|
399
|
+
args: parsed.args,
|
|
400
|
+
conversationId,
|
|
401
|
+
userId: message.userId,
|
|
402
|
+
userName: message.userName,
|
|
403
|
+
threadTs: message.threadTs,
|
|
404
|
+
respond: (text) => responder.respond(text),
|
|
405
|
+
});
|
|
406
|
+
},
|
|
407
|
+
async tryExtensionAction(slug, action) {
|
|
408
|
+
return extensionRegistry.dispatchAction(slug, action);
|
|
409
|
+
},
|
|
410
|
+
async tryExtensionScheduleCallback(slug, callback, event) {
|
|
411
|
+
return extensionRegistry.dispatchScheduleCallback(slug, callback, event);
|
|
412
|
+
},
|
|
413
|
+
async dispose() {
|
|
414
|
+
try {
|
|
415
|
+
await disposeExtensions();
|
|
416
|
+
}
|
|
417
|
+
finally {
|
|
418
|
+
try {
|
|
419
|
+
await mcpResult.dispose();
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
await sessionManager.close();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
getCurrentStep() {
|
|
427
|
+
const pending = runState.pendingTools;
|
|
428
|
+
if (pending.size === 0)
|
|
429
|
+
return undefined;
|
|
430
|
+
// Get the first pending tool
|
|
431
|
+
const first = pending.values().next().value;
|
|
432
|
+
if (!first)
|
|
433
|
+
return undefined;
|
|
434
|
+
return {
|
|
435
|
+
toolName: first.toolName,
|
|
436
|
+
label: first.args?.label,
|
|
437
|
+
};
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EAGpB,WAAW,EAEX,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAQxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAE9E,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACL,oCAAoC,EACpC,+BAA+B,GAGhC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACnG,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,EACT,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EAClB,aAAa,EACb,cAAc,GACf,MAAM,gBAAgB,CAAC;AAIxB,SAAS,sBAAsB,CAAC,OAAiC;IAC/D,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,IAAI,IAAI,SAAS,CAAC;IAClE,OAAO,IAAI,SAAS,MAAM,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,OAA0B,EAC1B,cAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC;IACnD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,cAAc,QAAQ,wBAAwB,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,MAyBhC;IACC,MAAM,EACJ,OAAO,EACP,SAAS,EACT,QAAQ,EACR,MAAM,EACN,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,OAAO,EACP,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,GACtB,GAAG,MAAM,CAAC;IACX,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;IACrD,IAAI,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACrC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjE,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9D,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,qBAAqB,CAAC;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QACH,WAAW,GAAG,cAAc,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAErD,MAAM,UAAU,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,qBAAqB,GAAG,eAAe,CAC3C,MAAM,EACN,WAAW,CAAC,oBAAoB,EAChC,UAAU,CACX,CAAC;IACF,MAAM,MAAM,GAAG,oBAAoB,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;IAChG,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,iBAAiB,CACpC,WAAW,CAAC,oBAAoB,EAChC,MAAM,EACN,OAAO,CAAC,gBAAgB,EACxB,OAAO,CAAC,MAAM,EACd,MAAM,EACN,QAAQ,CAAC,gBAAgB,EAAE,EAC3B,QAAQ,EACR,MAAM,EACN,UAAU,EACV,qBAAqB,CAAC,iBAAiB,CACxC,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;IAChD,uEAAuE;IACvE,qEAAqE;IACrE,wEAAwE;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,yEAAyE;IACzE,qCAAqC;IACrC,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,GAAG,CAAC,OAAO,CACT,IAAI,cAAc,2BAA2B,YAAY,CAAC,MAAM,eAAe,UAAU,EAAE,CAC5F,CAAC;IAEF,eAAe,CAAC;QACd,QAAQ,EAAE,QAAQ,CAAC,IAAI;QACvB,cAAc;QACd,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAExE,iBAAiB,CAAC,KAAK,EAAE,QAAgB,EAAE,KAAc,EAAE,EAAE;QAC3D,MAAM,WAAW,GAAG,0BAA0B,CAAC,QAAQ,EAAE,WAAW,CAAC,oBAAoB,CAAC,CAAC;QAC3F,MAAM,qBAAqB,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,UAAU,EAAE,EAAE,CAChE,SAAS,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,qEAAqE;IACrE,sBAAsB,CAAC,KAAK,EAAE,QAAgB,EAAE,KAAc,EAAE,EAAE;QAChE,MAAM,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE,CAAC,SAAS,CAAC,KAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE5F,2EAA2E;IAC3E,8CAA8C;IAC9C,qBAAqB,CAAC;QACpB,cAAc;QACd,YAAY,EAAE,QAAQ,CAAC,IAAI;QAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,aAAa,CACX,QAAQ,EACR,SAAS,EACT,mBAAmB,EACnB,OAAO,CAAC,QAAQ,EAChB,WAAW,EACX,kBAAkB,CACnB,CAAC;IACF,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEhC,GAAG,CAAC,OAAO,CACT,2BAA2B,YAAY,CAAC,MAAM,mBAAmB,MAAM,CAAC,MAAM,QAAQ,CACvF,CAAC;IACF,GAAG,CAAC,OAAO,CAAC,aAAa,QAAQ,CAAC,QAAQ,CAAC,MAAM,YAAY,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtF,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,MAAM,kBAAkB,CAChE,OAAO,EACP,WAAW,CAAC,oBAAoB,EAChC,WAAW,EACX,CAAC,WAAW,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CACtD,CAAC;IACF,MAAM,gBAAgB,GAAG,qBAAqB,CAC5C,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAC/B,kBAAkB,EAClB,QAAQ,CAAC,IAAI,CACd,CAAC;IACF,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,OAAO,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAClG,OAAO;QACL,mBAAmB;QACnB,QAAQ;QACR,WAAW,EAAE,gBAAgB;QAC7B,gBAAgB;QAChB,kBAAkB;QAClB,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,EACJ,aAAa,EACb,UAAU,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,GAC1B,GAAG,OAAO,CAAC;IACZ,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC;IACnC,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IAC3C,MAAM,WAAW,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAExD,MAAM,UAAU,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACtD,oCAAoC,CAAC,aAAa,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3E,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,qBAAqB,EAAE,GAC1E,4BAA4B,CAAC,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3F,IAAI,WAAW,GAAG,+BAA+B,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAE/E,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;IAC7D,IAAI,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC7B,GAAG,CAAC,UAAU,CAAC,wBAAwB,EAAE,aAAa,CAAC,QAAQ,EAAG,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IAE7E,oEAAoE;IACpE,MAAM,EACJ,KAAK,EACL,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,GAAG,gBAAgB,CAClB,QAAQ,EACR,YAAY,EACZ,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,WAAW,EAAE,EACjF,yBAAyB,IAAI,EAAE,EAC/B;QACE,KAAK;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC;QACnE,sEAAsE;QACtE,sEAAsE;QACtE,sCAAsC;QACtC,SAAS,EAAE,eAAe;KAC3B,CACF,CAAC;IAEF,2FAA2F;IAC3F,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,eAAe,CACnD,MAAM,EACN,WAAW,CAAC,oBAAoB,EAChC,UAAU,CACX,CAAC;IACF,MAAM,aAAa,GAAkB;QACnC,IAAI,EAAE,MAAM;QACZ,eAAe,EAAE,EAAE;QACnB,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,UAAU,EAAE,YAAY;KACzB,CAAC;IACF,MAAM,YAAY,GAAG,iBAAiB,CACpC,WAAW,CAAC,oBAAoB,EAChC,MAAM,EACN,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAa,EACb,aAAa,EACb,MAAM,EACN,UAAU,EACV,iBAAiB,CAClB,CAAC;IAEF,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,GAAG,YAAY,CAAC;IACxD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAC/F,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IACpE,IACE,QAAQ;QACR,iBAAiB;QACjB,CAAC,MAAM,cAAc,CAAC,cAAc,EAAE,CAAC,KAAK,iBAAiB,EAC7D,CAAC;QACD,MAAM,cAAc,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,IAAI,eAAe,EAAE,CAAC;IAEjD,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACnE,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACxC,GAAG,CAAC,UAAU,CACZ,IAAI,cAAc,6BAA6B,QAAQ,CAAC,MAAM,EAAE,EAChE,QAAQ,CAAC,KAAK,CACf,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,YAAY,SAAS,CAAC,KAAK,CAAC,MAAM,cAAc,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GACtE,MAAM,4BAA4B,CAAC;QACjC,MAAM;QACN,YAAY;QACZ,KAAK;QACL,aAAa,EAAE,WAAW,CAAC,aAAa;QACxC,KAAK,EAAE,YAAY;QACnB,YAAY,EAAE,cAAc;QAC5B,MAAM,EAAE,aAAa;QACrB,YAAY;QACZ,gBAAgB;QAChB,eAAe;QACf,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,sBAAsB;QACtB,kBAAkB;QAClB,uBAAuB;KACxB,CAAC,CAAC;IAEL,wDAAwD;IACxD,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,0BAA0B,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAEtE,OAAO;QACL,KAAK,CAAC,eAAe,CAAC,gBAAyB;YAC7C,MAAM,kBAAkB,CAAC,kBAAkB,CAAC;gBAC1C,eAAe;gBACf,UAAU;gBACV,cAAc;gBACd,gBAAgB;aACjB,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,GAAG,CACP,OAA4B,EAC5B,SAAgC,EAChC,QAAuB;YAEvB,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC;gBACvC,OAAO;gBACP,SAAS;gBACT,QAAQ;gBACR,MAAM;gBACN,WAAW;gBACX,QAAQ;gBACR,QAAQ;gBACR,iBAAiB;gBACjB,qBAAqB;gBACrB,cAAc;gBACd,OAAO;gBACP,eAAe;gBACf,eAAe;gBACf,iBAAiB;gBACjB,iBAAiB;gBACjB,sBAAsB;gBACtB,gBAAgB;gBAChB,qBAAqB;gBACrB,WAAW;aACZ,CAAC,CAAC;YACH,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;YAEnC,IAAI,CAAC;gBACH,OAAO,MAAM,eAAe,EAAE,CAAC;YACjC,CAAC;oBAAS,CAAC;gBACT,qEAAqE;gBACrE,qEAAqE;gBACrE,8DAA8D;gBAC9D,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;gBAC1B,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;gBACvB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACxB,CAAC;YAED,KAAK,UAAU,eAAe;gBAC5B,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACpB,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9E,CAAC;gBAED,2BAA2B,CAAC;oBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,UAAU,EAAE,QAAQ,CAAC,mBAAmB;oBACxC,UAAU,EAAE,WAAW;iBACxB,CAAC,CAAC;gBACH,sBAAsB,CAAC,mBAAmB,EAAE;oBAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,UAAU,EAAE,QAAQ,CAAC,mBAAmB;oBACxC,UAAU,EAAE,WAAW;oBACvB,gBAAgB,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;oBAClD,sBAAsB,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM;iBACzD,CAAC,CAAC;gBACH,cAAc,CAAC;oBACb,SAAS,EAAE,WAAW;oBACtB,SAAS,EAAE,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,mBAAmB,CAAC;oBAC/E,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;iBAChC,CAAC,CAAC;gBAEH,yEAAyE;gBACzE,qEAAqE;gBACrE,MAAM,UAAU,GAAG,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACnD,qEAAqE;gBACrE,kDAAkD;gBAClD,MAAM,MAAM,GAAc,UAAU;oBAClC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;oBAC5C,CAAC,CAAC;wBACE,IAAI,EAAE,aAAa;wBACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI;wBACvB,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,MAAM,EAAE,OAAO,CAAC,MAAM;wBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;qBACjC,CAAC;gBACN,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE;oBACzD,MAAM;oBACN,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtF,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxD,CAAC,CAAC;gBAEH,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;oBACrB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM;wBACzB,CAAC,CAAC,kCAAkC,OAAO,CAAC,MAAM,GAAG;wBACrD,CAAC,CAAC,iCAAiC,CAAC;oBACtC,cAAc,CAAC;wBACb,SAAS,EAAE,WAAW;wBACtB,SAAS,EAAE,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,mBAAmB,CAAC;wBAC/E,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;qBACpC,CAAC,CAAC;oBACH,MAAM,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC5D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;gBACnC,CAAC;gBAED,2BAA2B;gBAC3B,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAE/B,MAAM,qBAAqB,GAAG,WAAW,EAAE,UAAU,CAAC;gBACtD,MAAM,wBAAwB,GAAG,WAAW,EAAE,aAAa,CAAC;gBAC5D,IAAI,eAAmC,CAAC;gBACxC,MAAM,qBAAqB,GACzB,qBAAqB,IAAI,wBAAwB;oBAC/C,CAAC,CAAC,GAAG,EAAE;wBACH,IAAI,CAAC,eAAe,EAAE,CAAC;4BACrB,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,CACxC,QAAQ,CAAC,IAAoB,EAC7B,OAAO,CAAC,MAAM,EACd,cAAc,EACd,OAAO,CAAC,UAAU,EAClB,WAAW,EACX,OAAO,CAAC,QAAQ,CACjB,CAAC;4BACF,eAAe,GAAG,GAAG,wBAAwB,kBAAkB,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC/E,CAAC;wBACD,OAAO,eAAe,CAAC;oBACzB,CAAC;oBACH,CAAC,CAAC,SAAS,CAAC;gBAEhB,MAAM,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE;oBACtD,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;oBAC/C,kBAAkB,EAAE,yBAAyB,CAAC,QAAQ,CAAC,kBAAkB,CAAC;wBACxE,CAAC,CAAC,qBAAqB,EAAE,EAAE;wBAC3B,CAAC,CAAC,SAAS;oBACb,kBAAkB,EAAE,qBAAqB;oBACzC,QAAQ,EAAE,QAAQ,CAAC,IAAI;oBACvB,KAAK;oBACL,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB;oBACjD,WAAW;iBACZ,CAAC,CAAC;gBAEH,MAAM,kBAAkB,CAAC;oBACvB,OAAO;oBACP,QAAQ;oBACR,SAAS;oBACT,QAAQ;oBACR,KAAK;oBACL,WAAW;oBACX,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB;oBACjD,WAAW;oBACX,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;iBAC7C,CAAC,CAAC;gBAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,CAAC;YAClF,CAAC;QACH,CAAC;QAED,KAAK,CAAC,kBAAkB,CACtB,OAA4B,EAC5B,QAAuB;YAEvB,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC;gBACvC,OAAO;gBACP,SAAS;gBACT,QAAQ;gBACR,MAAM;gBACN,WAAW;gBACX,QAAQ;gBACR,QAAQ;gBACR,iBAAiB;gBACjB,qBAAqB;gBACrB,cAAc;gBACd,OAAO;gBACP,eAAe;gBACf,eAAe;gBACf,iBAAiB;gBACjB,iBAAiB;gBACjB,sBAAsB;gBACtB,gBAAgB;gBAChB,qBAAqB;gBACrB,WAAW;aACZ,CAAC,CAAC;YACH,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;YAEnC,IAAI,CAAC;gBACH,MAAM,sBAAsB,GAAG,KAAK,CAAC,IAAI,CACvC,QAAQ,CAAC,WAAW,CAAC,oBAAoB,EACzC,MAAM,CAAC,GAAG,EACV,WAAW,CACZ,CAAC;gBACF,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;gBACxF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAClC,kBAAkB,CAChB,sBAAsB,EACtB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CACpC,EACD;oBACE,MAAM,EAAE;wBACN,IAAI,EAAE,aAAa;wBACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI;wBACvB,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,MAAM,EAAE,OAAO,CAAC,MAAM;wBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;qBACjC;oBACD,MAAM,EAAE,oBAAoB;oBAC5B,KAAK,EAAE,UAAU;iBAClB,CACF,CAAC;gBACF,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;oBACrB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBACjE,CAAC;gBACD,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC/B,uEAAuE;gBACvE,uEAAuE;gBACvE,iBAAiB;gBACjB,OAAO;oBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,oBAAoB;iBACtF,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;gBAC1B,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC;gBACvB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;YACxB,CAAC;QACH,CAAC;QAED,KAAK;YACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,mBAAmB,CACvB,OAA4B,EAC5B,SAAgC,EAChC,YAAY,GAA2B,EAAE;YAEzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;YAC1B,OAAO,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE;gBACpD,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,cAAc;gBACd,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,IAAY,EAAE,MAA4B;YACjE,OAAO,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxD,CAAC;QAED,KAAK,CAAC,4BAA4B,CAChC,IAAY,EACZ,QAAgB,EAChB,KAAqC;YAErC,OAAO,iBAAiB,CAAC,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;QAED,KAAK,CAAC,OAAO;YACX,IAAI,CAAC;gBACH,MAAM,iBAAiB,EAAE,CAAC;YAC5B,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC5B,CAAC;wBAAS,CAAC;oBACT,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;QAED,cAAc;YACZ,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACzC,6BAA6B;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC5C,IAAI,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC7B,OAAO;gBACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,KAAK,EAAG,KAAK,CAAC,IAA2B,EAAE,KAAK;aACjD,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { CreateRunnerOptions, OfficeAddress, PiAgentWrapper } from \"../types.js\";\nimport type { Office } from \"../office/index.js\";\nimport type { MikanAgentSession } from \"../harness/index.js\";\nimport {\n DEFAULT_EVENT_BUDGET,\n type ExtensionBlockAction,\n type ExtensionScheduleCallbackEvent,\n MikanModels,\n type MikanSkill,\n parseCommandInput,\n type RunOrigin,\n} from \"../harness/index.js\";\nimport { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\nimport type {\n ConversationKind,\n ConversationMessage,\n ConversationResponder,\n MessagingInfo,\n PlatformName,\n} from \"../adapter.js\";\nimport { resolveConversationSettings } from \"../config.js\";\nimport { resolveWorkspaceProjection } from \"../workspace-projection/index.js\";\nimport type { ActorExecutionResolver } from \"../execution-resolver.js\";\nimport * as log from \"../log.js\";\nimport { loadMcpTools } from \"../mcp/loader.js\";\nimport {\n assertSandboxSupportsWorkspacePolicy,\n getUnresolvedSandboxPathContext,\n type Executor,\n type RuntimePathContext,\n} from \"../sandbox/index.js\";\nimport { addLifecycleBreadcrumb, updateActiveSpanAttribution } from \"../observability/sentry.js\";\nimport { ChatHistorySync } from \"../sessions/chat-history-sync.js\";\nimport { conversationIdOf, isThreadSessionKey } from \"../sessions/session-key.js\";\nimport {\n extractSessionUuid,\n openManagedSession,\n type ThreadRootMessage,\n} from \"../sessions/store.js\";\nimport { createMikanTools } from \"../tools/index.js\";\nimport type { PlatformToolRunContext } from \"../tools/types.js\";\nimport { createConfiguredAgentSession, loadMikanSkills, mergeExtensionSkills } from \"./catalog.js\";\nimport {\n createRunnerExecutionContext,\n normalizeAttachRuntimePath,\n withStagedRuntimeFile,\n} from \"./execution.js\";\nimport {\n buildPromptPayload,\n buildSystemPrompt,\n buildTurnInstructions,\n getMemory,\n resolveTriggerAttribution,\n SESSION_DREAM_BUDGET,\n sessionDreamPrompt,\n sessionDreamTools,\n} from \"./prompt.js\";\nimport {\n attachSessionEventHandlers,\n createNoopResponder,\n createRunQueue,\n createRunState,\n finalizeRunResponse,\n formatAgentActorName,\n isEventTriggerAttribution,\n reportUsageSummary,\n resetRunState,\n sendAgentEvent,\n} from \"./presenter.js\";\n\nimport type { PreparedRunContext, RunnerExecutionContext, RunnerSessionState } from \"./types.js\";\n\nfunction buildThreadSessionName(message: ThreadRootMessage | null): string | undefined {\n const text = message?.text?.trim();\n if (!text) return undefined;\n const userLabel = message?.userName || message?.user || \"unknown\";\n return `[${userLabel}]: ${text}`;\n}\n\nasync function reloadSessionMessages(\n session: MikanAgentSession,\n conversationId: string,\n): Promise<void> {\n const reloaded = await session.reloadFromSession();\n if (reloaded > 0) {\n log.logInfo(`[${conversationId}] Reloaded ${reloaded} messages from context`);\n }\n}\n\nasync function prepareRunContext(params: {\n message: ConversationMessage;\n responder: ConversationResponder;\n platform: MessagingInfo;\n office: Office;\n sessionUuid: string;\n runState: RunnerSessionState;\n executor: Executor;\n executionResolver?: ActorExecutionResolver;\n resolveExecutorForRun: RunnerExecutionContext[\"resolveExecutorForRun\"];\n getPathContext: () => RuntimePathContext;\n session: MikanAgentSession;\n extensionSkills?: MikanSkill[];\n setEventContext: (context: {\n platform: string;\n conversationId: string;\n conversationKind: ConversationKind;\n userId: string;\n }) => void;\n setSandboxContext: (context: { address: OfficeAddress; userId: string }) => void;\n setUploadFunction: (fn: (filePath: string, title?: string) => Promise<void>) => void;\n setImageUploadFunction: (fn: (hostPath: string, title?: string) => Promise<void>) => void;\n setReactFunction: (fn: ((emoji: string) => Promise<void>) | null) => void;\n bindPlatformToolPacks: (ctx: PlatformToolRunContext) => void;\n pathContext: RuntimePathContext;\n}): Promise<PreparedRunContext & { pathContext: RuntimePathContext }> {\n const {\n message,\n responder,\n platform,\n office,\n sessionUuid,\n runState,\n executor,\n executionResolver,\n resolveExecutorForRun,\n getPathContext,\n session,\n setEventContext,\n setSandboxContext,\n setUploadFunction,\n setImageUploadFunction,\n setReactFunction,\n bindPlatformToolPacks,\n } = params;\n const conversationId = office.address.conversationId;\n let pathContext = params.pathContext;\n const sessionConversation = conversationIdOf(message.sessionKey);\n\n await mkdir(join(office.dir, \"scratch\"), { recursive: true });\n\n if (executionResolver) {\n await resolveExecutorForRun({\n address: message.address,\n userId: message.userId,\n trustModel: platform.trustModel,\n });\n pathContext = getPathContext();\n }\n\n await reloadSessionMessages(session, conversationId);\n\n const projection = resolveWorkspaceProjection(office);\n const memory = await getMemory(projection);\n const conversationSkillLoad = loadMikanSkills(\n office,\n pathContext.runtimeWorkspaceRoot,\n projection,\n );\n const skills = mergeExtensionSkills(conversationSkillLoad.skills, params.extensionSkills ?? []);\n const triggerAttribution = resolveTriggerAttribution(message);\n const systemPrompt = buildSystemPrompt(\n pathContext.runtimeWorkspaceRoot,\n office,\n message.conversationKind,\n message.userId,\n memory,\n executor.getSandboxConfig(),\n platform,\n skills,\n projection,\n conversationSkillLoad.skippedSkillLinks,\n );\n session.agent.state.systemPrompt = systemPrompt;\n // Cache diagnosis: a byte-stable system prompt is the precondition for\n // provider prompt caching. If this hash changes between turns of one\n // conversation, something turn-varying leaked into the prompt; if it is\n // stable and cacheRead stays 0, the miss is provider-side (e.g. OpenRouter\n // routing the model across upstream hosts). This is the base prompt mikan\n // builds; a `before_agent_start` extension may still rewrite it per turn\n // (logged separately by the runner).\n const promptHash = createHash(\"sha256\").update(systemPrompt).digest(\"hex\").slice(0, 8);\n log.logInfo(\n `[${conversationId}] System prompt (base): ${systemPrompt.length} chars, sha ${promptHash}`,\n );\n\n setEventContext({\n platform: platform.name,\n conversationId,\n conversationKind: message.conversationKind,\n userId: message.userId,\n });\n setSandboxContext({ address: message.address, userId: message.userId });\n\n setUploadFunction(async (filePath: string, title?: string) => {\n const runtimePath = normalizeAttachRuntimePath(filePath, pathContext.runtimeWorkspaceRoot);\n await withStagedRuntimeFile(executor, runtimePath, (stagedPath) =>\n responder.uploadFile(stagedPath, title),\n );\n });\n\n // generate_image writes its file host-side, so it uploads by host path —\n // no staging through the sandbox, where the file may not be mounted.\n setImageUploadFunction(async (hostPath: string, title?: string) => {\n await responder.uploadFile(hostPath, title);\n });\n\n // The react tool is available only when the responder supports reactions\n // (interactive turns on platforms with reaction support); otherwise unset\n // so the tool reports it is unavailable rather than silently no-op'ing.\n setReactFunction(responder.react ? async (emoji: string) => responder.react!(emoji) : null);\n\n // Platform capability packs (e.g. GitHub PR/CI) enable themselves per run;\n // core does not branch on platform name here.\n bindPlatformToolPacks({\n conversationId,\n platformName: platform.name,\n threadTs: message.threadTs,\n });\n\n resetRunState(\n runState,\n responder,\n sessionConversation,\n message.userName,\n sessionUuid,\n triggerAttribution,\n );\n const runQueue = createRunQueue(responder, runState);\n runState.queue = runQueue.queue;\n\n log.logInfo(\n `Context sizes - system: ${systemPrompt.length} chars, memory: ${memory.length} chars`,\n );\n log.logInfo(`Channels: ${platform.channels.length}, Users: ${platform.users.length}`);\n\n const { userMessage, imageAttachments } = await buildPromptPayload(\n message,\n pathContext.runtimeWorkspaceRoot,\n pathContext,\n (runtimePath) => executor.readFileBase64(runtimePath),\n );\n const turnInstructions = buildTurnInstructions(\n message.id.startsWith(\"event:\"),\n triggerAttribution,\n platform.name,\n );\n const finalUserMessage = turnInstructions ? `${turnInstructions}\\n\\n${userMessage}` : userMessage;\n return {\n sessionConversation,\n runQueue,\n userMessage: finalUserMessage,\n imageAttachments,\n triggerAttribution,\n pathContext,\n };\n}\n\n/**\n * The dream run reads a transcript in which the agent held its full tool set,\n * but `sessionDreamTools` has since narrowed it. Left to infer its grant from\n * the transcript, the model calls a tool it no longer holds and burns one of\n * its five turns on the failure — so the grant is stated, and derived from the\n * tools actually handed to the run rather than restated by hand.\n */\nexport async function createRunner(options: CreateRunnerOptions): Promise<PiAgentWrapper> {\n const {\n sandboxConfig,\n sessionKey,\n office,\n sessionScope,\n vaultManager,\n provisioner,\n resourceController,\n sessionView,\n platformNotifier,\n platformReactor,\n platformUploader,\n platformBlockKit,\n platformDmOpener,\n platformHistoryFetcher,\n platformUserLister,\n extensionScheduleEngine,\n platformToolPackFactories,\n } = options;\n const conversationId = office.address.conversationId;\n const conversationDir = office.dir;\n const workspaceDir = office.workspace.root;\n const agentConfig = resolveConversationSettings(office);\n\n const projection = resolveWorkspaceProjection(office);\n assertSandboxSupportsWorkspacePolicy(sandboxConfig, projection.doorPolicy);\n const { executionResolver, executor, getPathContext, resolveExecutorForRun } =\n createRunnerExecutionContext(sandboxConfig, vaultManager, provisioner, office.workspace);\n let pathContext = getUnresolvedSandboxPathContext(sandboxConfig, workspaceDir);\n\n const modelRegistry = options.models ?? MikanModels.create();\n if (modelRegistry.getError()) {\n log.logWarning(\"models.json load error\", modelRegistry.getError()!);\n }\n const model = modelRegistry.resolve(agentConfig.provider, agentConfig.model);\n\n // Create tools (per-runner, with per-runner upload function setter)\n const {\n tools,\n setUploadFunction,\n setImageUploadFunction,\n setReactFunction,\n bindPlatformToolPacks,\n setEventContext,\n setSandboxContext,\n } = createMikanTools(\n executor,\n workspaceDir,\n { sandbox: sandboxConfig, resourceController: resourceController ?? provisioner },\n platformToolPackFactories ?? [],\n {\n model,\n getApiKey: () => modelRegistry.getApiKeyForProvider(model.provider),\n // The conversation's own office dir: mounted into the sandbox, unlike\n // the workspace base — generated images must land somewhere the agent\n // (and a future run) can still reach.\n outputDir: conversationDir,\n },\n );\n\n // Initial system prompt (will be updated each run with fresh memory/channels/users/skills)\n const memory = await getMemory(projection);\n const { skills, skippedSkillLinks } = loadMikanSkills(\n office,\n pathContext.runtimeWorkspaceRoot,\n projection,\n );\n const emptyPlatform: MessagingInfo = {\n name: \"chat\",\n formattingGuide: \"\",\n channels: [],\n users: [],\n trustModel: \"membership\",\n };\n const systemPrompt = buildSystemPrompt(\n pathContext.runtimeWorkspaceRoot,\n office,\n \"shared\",\n undefined,\n memory,\n sandboxConfig,\n emptyPlatform,\n skills,\n projection,\n skippedSkillLinks,\n );\n\n // Create session manager and settings manager. Top-level/private sessions\n // use the conversation's current pointer; scoped sessions use fixed files.\n // Platform-specific scope behavior is resolved before runner creation.\n const isThread = isThreadSessionKey(sessionKey);\n const { contextFile, threadRootMessage } = sessionScope;\n const sessionManager = await openManagedSession(contextFile, pathContext.runtimeWorkspaceRoot);\n const threadSessionName = buildThreadSessionName(threadRootMessage);\n if (\n isThread &&\n threadSessionName &&\n (await sessionManager.getSessionName()) !== threadSessionName\n ) {\n await sessionManager.setSessionName(threadSessionName);\n }\n\n const sessionUuid = extractSessionUuid(contextFile);\n const chatSessionManager = new ChatHistorySync();\n\n // MCP tools run host-side: credentials live in server config (settings) and\n // the server process, never in the sandbox or the model's context. Loaded\n // per-runner so a settings change is picked up on the next runner build.\n const mcpResult = await loadMcpTools(agentConfig.mcpServers ?? {});\n for (const mcpError of mcpResult.errors) {\n log.logWarning(\n `[${conversationId}] MCP server unavailable: ${mcpError.server}`,\n mcpError.error,\n );\n }\n if (mcpResult.tools.length > 0) {\n log.logInfo(`[${conversationId}] Loaded ${mcpResult.tools.length} MCP tool(s)`);\n }\n const toolsWithMcp = [...tools, ...mcpResult.tools];\n\n const { session, extensionSkills, extensionRegistry, disposeExtensions } =\n await createConfiguredAgentSession({\n office,\n systemPrompt,\n model,\n thinkingLevel: agentConfig.thinkingLevel,\n tools: toolsWithMcp,\n sessionStore: sessionManager,\n models: modelRegistry,\n vaultManager,\n platformNotifier,\n platformReactor,\n platformUploader,\n platformBlockKit,\n platformDmOpener,\n platformHistoryFetcher,\n platformUserLister,\n extensionScheduleEngine,\n });\n\n // Mutable per-run state - event handler references this\n const runState = createRunState();\n attachSessionEventHandlers({ session, runState, model, agentConfig });\n\n return {\n async syncChatHistory(currentMessageId?: string): Promise<void> {\n await chatSessionManager.syncSessionManager({\n conversationDir,\n sessionKey,\n sessionManager,\n currentMessageId,\n });\n },\n\n async run(\n message: ConversationMessage,\n responder: ConversationResponder,\n platform: MessagingInfo,\n ): Promise<{ stopReason: string; errorMessage?: string }> {\n const prepared = await prepareRunContext({\n message,\n responder,\n platform,\n office,\n sessionUuid,\n runState,\n executor,\n executionResolver,\n resolveExecutorForRun,\n getPathContext,\n session,\n extensionSkills,\n setEventContext,\n setSandboxContext,\n setUploadFunction,\n setImageUploadFunction,\n setReactFunction,\n bindPlatformToolPacks,\n pathContext,\n });\n pathContext = prepared.pathContext;\n\n try {\n return await runPreparedTurn();\n } finally {\n // Ownership must return to the pool on every exit — a throw anywhere\n // in the turn (dreamSessionMemory already does this) would otherwise\n // leave the runner permanently \"busy\" with a stale responder.\n runState.responder = null;\n runState.logCtx = null;\n runState.queue = null;\n }\n\n async function runPreparedTurn(): Promise<{ stopReason: string; errorMessage?: string }> {\n if (runState.logCtx) {\n log.logAgentRunStart(runState.logCtx, model.provider, model.id, model.name);\n }\n\n updateActiveSpanAttribution({\n provider: model.provider,\n model: agentConfig.model,\n channel_id: prepared.sessionConversation,\n session_id: sessionUuid,\n });\n addLifecycleBreadcrumb(\"agent.prompt.sent\", {\n provider: model.provider,\n model: agentConfig.model,\n channel_id: prepared.sessionConversation,\n session_id: sessionUuid,\n attachment_count: message.attachments?.length ?? 0,\n image_attachment_count: prepared.imageAttachments.length,\n });\n sendAgentEvent({\n sessionId: sessionUuid,\n actorName: formatAgentActorName(message.userName, prepared.sessionConversation),\n event: { kind: \"sessionStart\" },\n });\n\n // Autonomous (event/trigger) runs get an explicit resource ceiling since\n // no human is watching the loop; interactive turns stay human-gated.\n const isEventRun = message.id.startsWith(\"event:\");\n // Event runs have no triggering platform message, so identity fields\n // stay unset and extensions must null-check them.\n const origin: RunOrigin = isEventRun\n ? { kind: \"event\", platform: platform.name }\n : {\n kind: \"interactive\",\n platform: platform.name,\n messageTs: message.id,\n userId: message.userId,\n userName: message.userName,\n threadTs: message.threadTs,\n attachments: message.attachments,\n };\n const outcome = await session.prompt(prepared.userMessage, {\n origin,\n ...(prepared.imageAttachments.length > 0 ? { images: prepared.imageAttachments } : {}),\n ...(isEventRun ? { budget: DEFAULT_EVENT_BUDGET } : {}),\n });\n\n if (outcome?.blocked) {\n const text = outcome.reason\n ? `_Turn blocked by an extension: ${outcome.reason}_`\n : \"_Turn blocked by an extension._\";\n sendAgentEvent({\n sessionId: sessionUuid,\n actorName: formatAgentActorName(message.userName, prepared.sessionConversation),\n event: { kind: \"diagnostic\", text },\n });\n await responder.respondDiagnostic(text, { style: \"muted\" });\n return { stopReason: \"blocked\" };\n }\n\n // Wait for queued messages\n await prepared.runQueue.wait();\n\n const sessionViewTokenStore = sessionView?.tokenStore;\n const sessionViewPortalBaseUrl = sessionView?.portalBaseUrl;\n let sessionViewLink: string | undefined;\n const createSessionViewLink =\n sessionViewTokenStore && sessionViewPortalBaseUrl\n ? () => {\n if (!sessionViewLink) {\n const token = sessionViewTokenStore.create(\n platform.name as PlatformName,\n message.userId,\n conversationId,\n message.sessionKey,\n contextFile,\n message.userName,\n );\n sessionViewLink = `${sessionViewPortalBaseUrl}/session?token=${token.token}`;\n }\n return sessionViewLink;\n }\n : undefined;\n\n await finalizeRunResponse(responder, session, runState, {\n triggerAttribution: prepared.triggerAttribution,\n triggerSessionLink: isEventTriggerAttribution(prepared.triggerAttribution)\n ? createSessionViewLink?.()\n : undefined,\n createOverflowLink: createSessionViewLink,\n platform: platform.name,\n model,\n sessionConversation: prepared.sessionConversation,\n sessionUuid,\n });\n\n await reportUsageSummary({\n session,\n runState,\n responder,\n platform,\n model,\n agentConfig,\n sessionConversation: prepared.sessionConversation,\n sessionUuid,\n waitForQueue: () => prepared.runQueue.wait(),\n });\n\n return { stopReason: runState.stopReason, errorMessage: runState.errorMessage };\n }\n },\n\n async dreamSessionMemory(\n message: ConversationMessage,\n platform: MessagingInfo,\n ): Promise<{ stopReason: string; errorMessage?: string }> {\n const responder = createNoopResponder();\n const prepared = await prepareRunContext({\n message,\n responder,\n platform,\n office,\n sessionUuid,\n runState,\n executor,\n executionResolver,\n resolveExecutorForRun,\n getPathContext,\n session,\n extensionSkills,\n setEventContext,\n setSandboxContext,\n setUploadFunction,\n setImageUploadFunction,\n setReactFunction,\n bindPlatformToolPacks,\n pathContext,\n });\n pathContext = prepared.pathContext;\n\n try {\n const conversationMemoryPath = posix.join(\n prepared.pathContext.runtimeWorkspaceRoot,\n office.key,\n \"MEMORY.md\",\n );\n const dreamTools = sessionDreamTools(session.agent.state.tools, conversationMemoryPath);\n const outcome = await session.prompt(\n sessionDreamPrompt(\n conversationMemoryPath,\n dreamTools.map((tool) => tool.name),\n ),\n {\n origin: {\n kind: \"interactive\",\n platform: platform.name,\n messageTs: message.id,\n userId: message.userId,\n userName: message.userName,\n threadTs: message.threadTs,\n attachments: message.attachments,\n },\n budget: SESSION_DREAM_BUDGET,\n tools: dreamTools,\n },\n );\n if (outcome?.blocked) {\n return { stopReason: \"blocked\", errorMessage: outcome.reason };\n }\n await prepared.runQueue.wait();\n // A budget abort carries its reason in the tally, not in errorMessage,\n // and that reason is the only thing that tells the user why memory was\n // not preserved.\n return {\n stopReason: runState.stopReason,\n errorMessage: runState.errorMessage ?? session.getLastRunStats().budgetExceededReason,\n };\n } finally {\n runState.responder = null;\n runState.logCtx = null;\n runState.queue = null;\n }\n },\n\n abort(): void {\n session.abort();\n },\n\n async tryExtensionCommand(\n message: ConversationMessage,\n responder: ConversationResponder,\n parseOptions: { bareName?: boolean } = {},\n ): Promise<boolean> {\n const parsed = parseCommandInput(message.text, parseOptions);\n if (!parsed) return false;\n return extensionRegistry.dispatchCommand(parsed.name, {\n args: parsed.args,\n conversationId,\n userId: message.userId,\n userName: message.userName,\n threadTs: message.threadTs,\n respond: (text: string) => responder.respond(text),\n });\n },\n\n async tryExtensionAction(slug: string, action: ExtensionBlockAction): Promise<boolean> {\n return extensionRegistry.dispatchAction(slug, action);\n },\n\n async tryExtensionScheduleCallback(\n slug: string,\n callback: string,\n event: ExtensionScheduleCallbackEvent,\n ): Promise<boolean> {\n return extensionRegistry.dispatchScheduleCallback(slug, callback, event);\n },\n\n async dispose(): Promise<void> {\n try {\n await disposeExtensions();\n } finally {\n try {\n await mcpResult.dispose();\n } finally {\n await sessionManager.close();\n }\n }\n },\n\n getCurrentStep(): { toolName?: string; label?: string } | undefined {\n const pending = runState.pendingTools;\n if (pending.size === 0) return undefined;\n // Get the first pending tool\n const first = pending.values().next().value;\n if (!first) return undefined;\n return {\n toolName: first.toolName,\n label: (first.args as { label?: string })?.label,\n };\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { OfficeAddress } from "../types.js";
|
|
2
|
+
import { type Api, type ImageContent, type Model } from "@earendil-works/pi-ai";
|
|
3
|
+
import type { MikanAgentSession } from "../harness/index.js";
|
|
4
|
+
import { type ExtensionRegistry, type MikanSkill } from "../harness/index.js";
|
|
5
|
+
import type { ConversationResponder, MessagingInfo, SubagentProgressSnapshot } from "../adapter.js";
|
|
6
|
+
import type { PlatformTrustModel } from "../types.js";
|
|
7
|
+
import type { resolveConversationSettings } from "../config.js";
|
|
8
|
+
import type { ActorExecutionResolver } from "../execution-resolver.js";
|
|
9
|
+
import { type Executor, type RuntimePathContext } from "../sandbox/index.js";
|
|
10
|
+
export interface RunnerSessionState {
|
|
11
|
+
responder: ConversationResponder | null;
|
|
12
|
+
logCtx: {
|
|
13
|
+
conversationId: string;
|
|
14
|
+
userName?: string;
|
|
15
|
+
conversationName?: string;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
} | null;
|
|
18
|
+
queue: {
|
|
19
|
+
enqueue(fn: () => Promise<void>, errorContext: string): void;
|
|
20
|
+
} | null;
|
|
21
|
+
pendingTools: Map<string, {
|
|
22
|
+
toolName: string;
|
|
23
|
+
args: unknown;
|
|
24
|
+
startTime: number;
|
|
25
|
+
}>;
|
|
26
|
+
toolProgress: Map<string, {
|
|
27
|
+
label: string;
|
|
28
|
+
status: "running" | "done" | "error";
|
|
29
|
+
}>;
|
|
30
|
+
subagentProgress: Map<string, SubagentProgressSnapshot>;
|
|
31
|
+
completedSubagentProgress: SubagentProgressSnapshot[];
|
|
32
|
+
subagentToolCalls: Set<string>;
|
|
33
|
+
subagentProgressShown: boolean;
|
|
34
|
+
suppressResponseDeltas: boolean;
|
|
35
|
+
lastSubagentProgressAt: number;
|
|
36
|
+
toolProgressTimer: ReturnType<typeof setTimeout> | undefined;
|
|
37
|
+
totalUsage: {
|
|
38
|
+
input: number;
|
|
39
|
+
output: number;
|
|
40
|
+
cacheRead: number;
|
|
41
|
+
cacheWrite: number;
|
|
42
|
+
cost: {
|
|
43
|
+
input: number;
|
|
44
|
+
output: number;
|
|
45
|
+
cacheRead: number;
|
|
46
|
+
cacheWrite: number;
|
|
47
|
+
total: number;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
llmCallCount: number;
|
|
51
|
+
stopReason: string;
|
|
52
|
+
errorMessage: string | undefined;
|
|
53
|
+
reportedLlmError: boolean;
|
|
54
|
+
finalResponseHandledByTool: boolean;
|
|
55
|
+
triggerAttribution?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface UsageReportContext {
|
|
58
|
+
session: MikanAgentSession;
|
|
59
|
+
runState: RunnerSessionState;
|
|
60
|
+
responder: ConversationResponder;
|
|
61
|
+
platform: MessagingInfo;
|
|
62
|
+
model: Model<Api>;
|
|
63
|
+
agentConfig: ReturnType<typeof resolveConversationSettings>;
|
|
64
|
+
sessionConversation: string;
|
|
65
|
+
sessionUuid: string;
|
|
66
|
+
waitForQueue: () => Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
export interface RunnerExecutionContext {
|
|
69
|
+
executionResolver?: ActorExecutionResolver;
|
|
70
|
+
executor: Executor;
|
|
71
|
+
getPathContext: () => RuntimePathContext;
|
|
72
|
+
resolveExecutorForRun(context: {
|
|
73
|
+
address: OfficeAddress;
|
|
74
|
+
userId: string;
|
|
75
|
+
trustModel?: PlatformTrustModel;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export interface PreparedRunContext {
|
|
79
|
+
sessionConversation: string;
|
|
80
|
+
runQueue: {
|
|
81
|
+
queue: {
|
|
82
|
+
enqueue(fn: () => Promise<void>, errorContext: string): void;
|
|
83
|
+
};
|
|
84
|
+
wait: () => Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
userMessage: string;
|
|
87
|
+
imageAttachments: ImageContent[];
|
|
88
|
+
triggerAttribution?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface ConfiguredAgentSession {
|
|
91
|
+
session: MikanAgentSession;
|
|
92
|
+
/** Skills contributed by extensions, merged into each run's system prompt. */
|
|
93
|
+
extensionSkills: MikanSkill[];
|
|
94
|
+
/** Registry backing extension command dispatch for this harness instance. */
|
|
95
|
+
extensionRegistry: ExtensionRegistry;
|
|
96
|
+
/** Runs extension disposers; call once when the runner is discarded. */
|
|
97
|
+
disposeExtensions: () => Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,MAAM,uBAAuB,CAAC;AAEhF,OAAO,EAA2C,MAAM,qBAAqB,CAAC;AAK9E,OAAO,EAA0C,MAAM,qBAAqB,CAAC","sourcesContent":["import type { OfficeAddress } from \"../types.js\";\nimport { type Api, type ImageContent, type Model } from \"@earendil-works/pi-ai\";\nimport type { MikanAgentSession } from \"../harness/index.js\";\nimport { type ExtensionRegistry, type MikanSkill } from \"../harness/index.js\";\nimport type { ConversationResponder, MessagingInfo, SubagentProgressSnapshot } from \"../adapter.js\";\nimport type { PlatformTrustModel } from \"../types.js\";\nimport type { resolveConversationSettings } from \"../config.js\";\nimport type { ActorExecutionResolver } from \"../execution-resolver.js\";\nimport { type Executor, type RuntimePathContext } from \"../sandbox/index.js\";\n\nexport interface RunnerSessionState {\n responder: ConversationResponder | null;\n logCtx: {\n conversationId: string;\n userName?: string;\n conversationName?: string;\n sessionId?: string;\n } | null;\n queue: {\n enqueue(fn: () => Promise<void>, errorContext: string): void;\n } | null;\n pendingTools: Map<string, { toolName: string; args: unknown; startTime: number }>;\n toolProgress: Map<string, { label: string; status: \"running\" | \"done\" | \"error\" }>;\n subagentProgress: Map<string, SubagentProgressSnapshot>;\n completedSubagentProgress: SubagentProgressSnapshot[];\n subagentToolCalls: Set<string>;\n subagentProgressShown: boolean;\n suppressResponseDeltas: boolean;\n lastSubagentProgressAt: number;\n toolProgressTimer: ReturnType<typeof setTimeout> | undefined;\n totalUsage: {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n };\n llmCallCount: number;\n stopReason: string;\n errorMessage: string | undefined;\n reportedLlmError: boolean;\n finalResponseHandledByTool: boolean;\n triggerAttribution?: string;\n}\n\nexport interface UsageReportContext {\n session: MikanAgentSession;\n runState: RunnerSessionState;\n responder: ConversationResponder;\n platform: MessagingInfo;\n model: Model<Api>;\n agentConfig: ReturnType<typeof resolveConversationSettings>;\n sessionConversation: string;\n sessionUuid: string;\n waitForQueue: () => Promise<void>;\n}\n\nexport interface RunnerExecutionContext {\n executionResolver?: ActorExecutionResolver;\n executor: Executor;\n getPathContext: () => RuntimePathContext;\n resolveExecutorForRun(context: {\n address: OfficeAddress;\n userId: string;\n trustModel?: PlatformTrustModel;\n }): Promise<void>;\n}\n\nexport interface PreparedRunContext {\n sessionConversation: string;\n runQueue: {\n queue: { enqueue(fn: () => Promise<void>, errorContext: string): void };\n wait: () => Promise<void>;\n };\n userMessage: string;\n imageAttachments: ImageContent[];\n triggerAttribution?: string;\n}\n\nexport interface ConfiguredAgentSession {\n session: MikanAgentSession;\n /** Skills contributed by extensions, merged into each run's system prompt. */\n extensionSkills: MikanSkill[];\n /** Registry backing extension command dispatch for this harness instance. */\n extensionRegistry: ExtensionRegistry;\n /** Runs extension disposers; call once when the runner is discarded. */\n disposeExtensions: () => Promise<void>;\n}\n"]}
|