@getpaseo/server 0.10.0-beta.1 → 0.10.1
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/dist/server/server/agent/agent-manager.js +1 -0
- package/dist/server/server/agent/provider-launch-config.d.ts +2 -2
- package/dist/server/server/agent/provider-launch-config.js +1 -1
- package/dist/server/server/agent/provider-registry.js +8 -0
- package/dist/server/server/agent/providers/claude/model-manifest.d.ts +9 -1
- package/dist/server/server/agent/providers/claude/model-manifest.js +10 -1
- package/dist/server/server/agent/providers/codex/rewind.d.ts +1 -0
- package/dist/server/server/agent/providers/codex/rewind.js +13 -14
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +3 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.js +14 -13
- package/dist/server/server/agent/providers/opencode/v2/agent.d.ts +1 -1
- package/dist/server/server/agent/providers/opencode/v2/agent.js +4 -1
- package/dist/server/server/agent/providers/opencode/v2/session.d.ts +2 -2
- package/dist/server/server/agent/providers/opencode/v2/session.js +37 -16
- package/dist/server/server/agent/providers/opencode-agent.js +24 -0
- package/dist/server/server/agent/tools/paseo-tools.js +6 -4
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-9da07adb97f5e0eb726f7762afee43f5.js → desktop-attachment-bridge-9b9ae7a48611e7619ae3dcfc5573a81d.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-9da07adb97f5e0eb726f7762afee43f5.js.br → desktop-attachment-bridge-9b9ae7a48611e7619ae3dcfc5573a81d.js.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-9da07adb97f5e0eb726f7762afee43f5.js.gz → desktop-attachment-bridge-9b9ae7a48611e7619ae3dcfc5573a81d.js.gz} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-store-d5d3402a752965d3037191484127123b.js → desktop-attachment-store-850db74e505f3e0b8091b8a319bf6d95.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-store-d5d3402a752965d3037191484127123b.js.br → desktop-attachment-store-850db74e505f3e0b8091b8a319bf6d95.js.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-850db74e505f3e0b8091b8a319bf6d95.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-69ce3c243032c3bedfc6f2ad379a4cdd.js → index-cefb3a051a5e61705f20366980a641f6.js} +464 -463
- package/dist/server/web-ui/_expo/static/js/web/index-cefb3a051a5e61705f20366980a641f6.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-cefb3a051a5e61705f20366980a641f6.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-3afc19e43c8152bd3c6d71b3ea8776dc.js → indexeddb-attachment-store-8233162f2e9e360c5680127250516411.js} +1 -1
- package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-3afc19e43c8152bd3c6d71b3ea8776dc.js.br → indexeddb-attachment-store-8233162f2e9e360c5680127250516411.js.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-8233162f2e9e360c5680127250516411.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-187a9d5c32188f357dbbf037a0f89073.js → native-file-attachment-store-eb2d324071f66d94742cf09a46103e22.js} +3 -3
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-eb2d324071f66d94742cf09a46103e22.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-eb2d324071f66d94742cf09a46103e22.js.gz +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/dist/src/server/agent/provider-launch-config.js +1 -1
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d5d3402a752965d3037191484127123b.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-69ce3c243032c3bedfc6f2ad379a4cdd.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-69ce3c243032c3bedfc6f2ad379a4cdd.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-3afc19e43c8152bd3c6d71b3ea8776dc.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-187a9d5c32188f357dbbf037a0f89073.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-187a9d5c32188f357dbbf037a0f89073.js.gz +0 -0
|
@@ -1204,6 +1204,7 @@ export class AgentManager {
|
|
|
1204
1204
|
if (agent.runtimeInfo) {
|
|
1205
1205
|
agent.runtimeInfo = { ...agent.runtimeInfo, model: normalizedModelId };
|
|
1206
1206
|
}
|
|
1207
|
+
this.refreshSessionPersistence(agent);
|
|
1207
1208
|
this.touchUpdatedAt(agent);
|
|
1208
1209
|
this.emitState(agent);
|
|
1209
1210
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ProcessEnvRecord } from "../paseo-env.js";
|
|
1
|
+
import { type ProcessEnvRecord, type ExternalProcessEnv } from "../paseo-env.js";
|
|
2
2
|
export { AgentProviderRuntimeSettingsMapSchema, ProviderCommandSchema, ProviderOverrideSchema, ProviderOverridesSchema, ProviderProfileModelSchema, ProviderRuntimeSettingsSchema, type AgentProviderRuntimeSettingsMap, type ProviderCommand, type ProviderOverride, type ProviderOverrides, type ProviderProfileModel, type ProviderRuntimeSettings, } from "@getpaseo/protocol/provider-config";
|
|
3
3
|
import { type ProviderCommand, type ProviderOverrides, type ProviderRuntimeSettings } from "@getpaseo/protocol/provider-config";
|
|
4
4
|
export interface ProviderCommandPrefix {
|
|
@@ -38,6 +38,6 @@ export interface ProviderEnvSpec {
|
|
|
38
38
|
envOverlay: ProcessEnvRecord;
|
|
39
39
|
}
|
|
40
40
|
export declare function createProviderEnvSpec(options?: ProviderEnvOptions): ProviderEnvSpec;
|
|
41
|
-
export declare function createProviderEnv(options?: ProviderEnvOptions):
|
|
41
|
+
export declare function createProviderEnv(options?: ProviderEnvOptions): ExternalProcessEnv;
|
|
42
42
|
export declare function isProviderCommandAvailable(commandConfig: ProviderCommand | undefined, resolveDefaultCommand: () => string | Promise<string>): Promise<boolean>;
|
|
43
43
|
//# sourceMappingURL=provider-launch-config.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isAbsolute } from "node:path";
|
|
2
2
|
import { executableExists, findExecutable, } from "../../executable-resolution/executable-resolution.js";
|
|
3
|
-
import { createExternalProcessEnv } from "../paseo-env.js";
|
|
3
|
+
import { createExternalProcessEnv, } from "../paseo-env.js";
|
|
4
4
|
export { AgentProviderRuntimeSettingsMapSchema, ProviderCommandSchema, ProviderOverrideSchema, ProviderOverridesSchema, ProviderProfileModelSchema, ProviderRuntimeSettingsSchema, } from "@getpaseo/protocol/provider-config";
|
|
5
5
|
import { ProviderOverrideSchema, ProviderOverridesSchema, ProviderRuntimeSettingsSchema, } from "@getpaseo/protocol/provider-config";
|
|
6
6
|
function normalizeLaunchDefault(defaultBinary) {
|
|
@@ -262,6 +262,8 @@ function wrapClientProvider(provider, inner, profileModels, additionalModels, pr
|
|
|
262
262
|
const listImportableSessions = inner.listImportableSessions?.bind(inner);
|
|
263
263
|
const importSession = inner.importSession?.bind(inner);
|
|
264
264
|
const listFeatures = inner.listFeatures?.bind(inner);
|
|
265
|
+
const archiveNativeSession = inner.archiveNativeSession?.bind(inner);
|
|
266
|
+
const unarchiveNativeSession = inner.unarchiveNativeSession?.bind(inner);
|
|
265
267
|
return {
|
|
266
268
|
provider,
|
|
267
269
|
capabilities: inner.capabilities,
|
|
@@ -332,6 +334,12 @@ function wrapClientProvider(provider, inner, profileModels, additionalModels, pr
|
|
|
332
334
|
};
|
|
333
335
|
}
|
|
334
336
|
: undefined,
|
|
337
|
+
archiveNativeSession: archiveNativeSession
|
|
338
|
+
? async (handle) => await archiveNativeSession({ ...handle, provider: inner.provider })
|
|
339
|
+
: undefined,
|
|
340
|
+
unarchiveNativeSession: unarchiveNativeSession
|
|
341
|
+
? async (handle) => await unarchiveNativeSession({ ...handle, provider: inner.provider })
|
|
342
|
+
: undefined,
|
|
335
343
|
getCatalogCacheKey: inner.getCatalogCacheKey?.bind(inner),
|
|
336
344
|
isAvailable: (signal, options) => inner.isAvailable(signal, options),
|
|
337
345
|
getDiagnostic: inner.getDiagnostic?.bind(inner),
|
|
@@ -53,10 +53,18 @@ export declare const CLAUDE_MODEL_MANIFEST: readonly [{
|
|
|
53
53
|
readonly effortLevels: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
54
54
|
readonly supportsThinkingDisabled: true;
|
|
55
55
|
readonly supportsFastMode: true;
|
|
56
|
+
}, {
|
|
57
|
+
readonly id: "claude-sonnet-5-5";
|
|
58
|
+
readonly label: "Sonnet 5.5";
|
|
59
|
+
readonly description: "Sonnet 5.5 · Best for everyday tasks";
|
|
60
|
+
readonly minimumClaudeCodeVersion: "2.1.284";
|
|
61
|
+
readonly defaultThinkingOptionId: "medium";
|
|
62
|
+
readonly contextWindowMaxTokens: 1000000;
|
|
63
|
+
readonly effortLevels: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
56
64
|
}, {
|
|
57
65
|
readonly id: "claude-sonnet-5";
|
|
58
66
|
readonly label: "Sonnet 5";
|
|
59
|
-
readonly description: "Sonnet 5 ·
|
|
67
|
+
readonly description: "Sonnet 5 · Previous release";
|
|
60
68
|
readonly contextWindowMaxTokens: 200000;
|
|
61
69
|
readonly effortLevels: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
62
70
|
readonly supportsThinkingDisabled: true;
|
|
@@ -71,10 +71,19 @@ export const CLAUDE_MODEL_MANIFEST = [
|
|
|
71
71
|
supportsThinkingDisabled: true,
|
|
72
72
|
supportsFastMode: true,
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
id: "claude-sonnet-5-5",
|
|
76
|
+
label: "Sonnet 5.5",
|
|
77
|
+
description: "Sonnet 5.5 · Best for everyday tasks",
|
|
78
|
+
minimumClaudeCodeVersion: "2.1.284",
|
|
79
|
+
defaultThinkingOptionId: "medium",
|
|
80
|
+
contextWindowMaxTokens: 1000000,
|
|
81
|
+
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
|
82
|
+
},
|
|
74
83
|
{
|
|
75
84
|
id: "claude-sonnet-5",
|
|
76
85
|
label: "Sonnet 5",
|
|
77
|
-
description: "Sonnet 5 ·
|
|
86
|
+
description: "Sonnet 5 · Previous release",
|
|
78
87
|
contextWindowMaxTokens: 200000,
|
|
79
88
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
|
80
89
|
supportsThinkingDisabled: true,
|
|
@@ -18,6 +18,7 @@ export declare function revertCodexConversation(input: {
|
|
|
18
18
|
cwd?: string | null;
|
|
19
19
|
model?: string | null;
|
|
20
20
|
serviceTier?: string | null;
|
|
21
|
+
config?: Record<string, unknown> | null;
|
|
21
22
|
userMessageTurns: CodexUserMessageTurnIndex;
|
|
22
23
|
setThreadId: (threadId: string) => void | Promise<void>;
|
|
23
24
|
}): Promise<void>;
|
|
@@ -38,33 +38,32 @@ export async function revertCodexConversation(input) {
|
|
|
38
38
|
if (numTurns < 0) {
|
|
39
39
|
throw new Error(`Codex user message ${input.messageId} is outside the current thread`);
|
|
40
40
|
}
|
|
41
|
+
// Codex does not carry the parent thread's config into a fork; without it the
|
|
42
|
+
// forked thread falls back to the default model provider.
|
|
43
|
+
const forkParams = {
|
|
44
|
+
threadId: input.threadId,
|
|
45
|
+
cwd: input.cwd ?? null,
|
|
46
|
+
model: input.model ?? null,
|
|
47
|
+
serviceTier: input.serviceTier ?? null,
|
|
48
|
+
...(input.config ? { config: input.config } : {}),
|
|
49
|
+
excludeTurns: false,
|
|
50
|
+
persistExtendedHistory: true,
|
|
51
|
+
};
|
|
41
52
|
const historyMode = await readCodexThreadHistoryMode(input.client, input.threadId);
|
|
42
53
|
if (historyMode === "paginated") {
|
|
43
54
|
if (!targetTurn.turnId) {
|
|
44
55
|
throw new Error(`Codex could not find the turn containing user message ${input.messageId}`);
|
|
45
56
|
}
|
|
46
57
|
const forked = await forkCodexThread(input.client, {
|
|
47
|
-
|
|
58
|
+
...forkParams,
|
|
48
59
|
beforeTurnId: targetTurn.turnId,
|
|
49
|
-
cwd: input.cwd ?? null,
|
|
50
|
-
model: input.model ?? null,
|
|
51
|
-
serviceTier: input.serviceTier ?? null,
|
|
52
|
-
excludeTurns: false,
|
|
53
|
-
persistExtendedHistory: true,
|
|
54
60
|
});
|
|
55
61
|
await input.setThreadId(forked.thread.id);
|
|
56
62
|
return;
|
|
57
63
|
}
|
|
58
64
|
// Fork is non-destructive: the old thread file stays on disk and remains
|
|
59
65
|
// recoverable with `codex resume <old-uuid>` if the rewind target was wrong.
|
|
60
|
-
const forked = await forkCodexThread(input.client,
|
|
61
|
-
threadId: input.threadId,
|
|
62
|
-
cwd: input.cwd ?? null,
|
|
63
|
-
model: input.model ?? null,
|
|
64
|
-
serviceTier: input.serviceTier ?? null,
|
|
65
|
-
excludeTurns: false,
|
|
66
|
-
persistExtendedHistory: true,
|
|
67
|
-
});
|
|
66
|
+
const forked = await forkCodexThread(input.client, forkParams);
|
|
68
67
|
const forkedThreadId = forked.thread.id;
|
|
69
68
|
// Codex rollback is chat-only by design. File edits from rewound turns stay
|
|
70
69
|
// on disk; a future file primitive would be a separate capability.
|
|
@@ -21,6 +21,7 @@ interface CodexAppServerAgentDeps {
|
|
|
21
21
|
extends: string;
|
|
22
22
|
};
|
|
23
23
|
customCodexConfig?: CodexCustomProviderConfig | null;
|
|
24
|
+
codexHome?: string;
|
|
24
25
|
_createCodexClient?: (child: ChildProcessWithoutNullStreams, logger: Logger, getTraceContext: () => CodexAppServerTraceContext) => CodexAppServerClientLike;
|
|
25
26
|
resolveSlashCommandInvocation?: (prompt: AgentPromptInput) => Promise<{
|
|
26
27
|
commandName: string;
|
|
@@ -31,7 +32,7 @@ export declare function normalizeCodexOutputSchema(schema: unknown): Record<stri
|
|
|
31
32
|
export declare function codexMicrosoftStoreBinaryCandidates(packageRoot: string, entries: Dirent[]): string[];
|
|
32
33
|
export declare function findCodexMicrosoftStoreBinary(): Promise<string | null>;
|
|
33
34
|
export declare function findDefaultCodexBinary(): Promise<string | null>;
|
|
34
|
-
export declare function listCodexSkills(cwd: string, workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">): Promise<AgentSlashCommand[]>;
|
|
35
|
+
export declare function listCodexSkills(cwd: string, codexHome: string, workspaceGitService?: Pick<WorkspaceGitService, "resolveRepoRoot">): Promise<AgentSlashCommand[]>;
|
|
35
36
|
export declare function toAgentUsage(tokenUsage: unknown): AgentUsage | undefined;
|
|
36
37
|
export declare function planStepsToMarkdown(steps: Array<{
|
|
37
38
|
step: string;
|
|
@@ -126,6 +127,7 @@ export declare class CodexAppServerAgentSession implements AgentSession {
|
|
|
126
127
|
private readonly logger;
|
|
127
128
|
private readonly config;
|
|
128
129
|
private readonly asyncQuestions;
|
|
130
|
+
private readonly codexHome;
|
|
129
131
|
private currentMode;
|
|
130
132
|
private hasWorkflowModeOverride;
|
|
131
133
|
private readonly providerOptions;
|
|
@@ -321,8 +321,8 @@ async function checkCodexLaunchAvailable(launch) {
|
|
|
321
321
|
resolvePath: findDefaultCodexBinary,
|
|
322
322
|
});
|
|
323
323
|
}
|
|
324
|
-
function resolveCodexHomeDir() {
|
|
325
|
-
return
|
|
324
|
+
function resolveCodexHomeDir(env) {
|
|
325
|
+
return env.CODEX_HOME ?? path.join(os.homedir(), ".codex");
|
|
326
326
|
}
|
|
327
327
|
function decodeEscapedChar(next) {
|
|
328
328
|
if (next === "n")
|
|
@@ -423,8 +423,7 @@ function parseFrontMatter(markdown) {
|
|
|
423
423
|
}
|
|
424
424
|
return { frontMatter, body };
|
|
425
425
|
}
|
|
426
|
-
async function listCodexCustomPrompts() {
|
|
427
|
-
const codexHome = resolveCodexHomeDir();
|
|
426
|
+
async function listCodexCustomPrompts(codexHome) {
|
|
428
427
|
const promptsDir = path.join(codexHome, "prompts");
|
|
429
428
|
let entries;
|
|
430
429
|
try {
|
|
@@ -457,7 +456,7 @@ async function listCodexCustomPrompts() {
|
|
|
457
456
|
const commands = parsedCommands.filter((cmd) => cmd !== null);
|
|
458
457
|
return commands.sort((a, b) => a.name.localeCompare(b.name));
|
|
459
458
|
}
|
|
460
|
-
export async function listCodexSkills(cwd, workspaceGitService) {
|
|
459
|
+
export async function listCodexSkills(cwd, codexHome, workspaceGitService) {
|
|
461
460
|
const candidates = [];
|
|
462
461
|
candidates.push(path.join(cwd, ".codex", "skills"));
|
|
463
462
|
const repoRoot = workspaceGitService
|
|
@@ -467,7 +466,7 @@ export async function listCodexSkills(cwd, workspaceGitService) {
|
|
|
467
466
|
candidates.push(path.join(path.dirname(cwd), ".codex", "skills"));
|
|
468
467
|
candidates.push(path.join(repoRoot, ".codex", "skills"));
|
|
469
468
|
}
|
|
470
|
-
candidates.push(path.join(
|
|
469
|
+
candidates.push(path.join(codexHome, "skills"));
|
|
471
470
|
const candidateReads = await Promise.all(candidates.map(async (dir) => {
|
|
472
471
|
let entries;
|
|
473
472
|
try {
|
|
@@ -2532,6 +2531,7 @@ export class CodexAppServerAgentSession {
|
|
|
2532
2531
|
this.providerOptions = CodexProviderOptionsSchema.parse(config.providerOptions ?? {});
|
|
2533
2532
|
this.config = config;
|
|
2534
2533
|
this.asyncQuestions = new CodexAsyncQuestions(resumeHandle?.metadata?.asyncQuestions);
|
|
2534
|
+
this.codexHome = deps.codexHome ?? resolveCodexHomeDir(process.env);
|
|
2535
2535
|
this.config.thinkingOptionId = normalizeCodexThinkingOptionId(this.config.thinkingOptionId);
|
|
2536
2536
|
if (this.config.featureValues?.fast_mode && codexModelSupportsFastMode(this.config.model)) {
|
|
2537
2537
|
this.serviceTier = "fast";
|
|
@@ -3023,8 +3023,7 @@ export class CodexAppServerAgentSession {
|
|
|
3023
3023
|
async buildCommandPromptInput(commandName, args) {
|
|
3024
3024
|
if (commandName.startsWith("prompts:")) {
|
|
3025
3025
|
const promptName = commandName.slice("prompts:".length);
|
|
3026
|
-
const
|
|
3027
|
-
const promptPath = path.join(codexHome, "prompts", `${promptName}.md`);
|
|
3026
|
+
const promptPath = path.join(this.codexHome, "prompts", `${promptName}.md`);
|
|
3028
3027
|
const raw = await fs.readFile(promptPath, "utf8");
|
|
3029
3028
|
const parsed = parseFrontMatter(raw);
|
|
3030
3029
|
return expandCodexCustomPrompt(parsed.body, args);
|
|
@@ -3688,6 +3687,7 @@ export class CodexAppServerAgentSession {
|
|
|
3688
3687
|
cwd: this.config.cwd ?? null,
|
|
3689
3688
|
model: this.config.model ?? null,
|
|
3690
3689
|
serviceTier: this.serviceTier,
|
|
3690
|
+
config: this.buildCodexInnerConfig(),
|
|
3691
3691
|
userMessageTurns: this.codexUserMessageTurns(),
|
|
3692
3692
|
setThreadId: async (threadId) => {
|
|
3693
3693
|
this.currentThreadId = threadId;
|
|
@@ -3783,7 +3783,7 @@ export class CodexAppServerAgentSession {
|
|
|
3783
3783
|
this.client = null;
|
|
3784
3784
|
}
|
|
3785
3785
|
async listCommands() {
|
|
3786
|
-
const prompts = await listCodexCustomPrompts();
|
|
3786
|
+
const prompts = await listCodexCustomPrompts(this.codexHome);
|
|
3787
3787
|
if (this.connectionState === "disconnected") {
|
|
3788
3788
|
await this.connect();
|
|
3789
3789
|
}
|
|
@@ -3797,7 +3797,7 @@ export class CodexAppServerAgentSession {
|
|
|
3797
3797
|
kind: "skill",
|
|
3798
3798
|
}));
|
|
3799
3799
|
const fallbackSkills = this.cachedSkills === null
|
|
3800
|
-
? await listCodexSkills(this.config.cwd, this.deps.workspaceGitService)
|
|
3800
|
+
? await listCodexSkills(this.config.cwd, this.codexHome, this.deps.workspaceGitService)
|
|
3801
3801
|
: [];
|
|
3802
3802
|
const builtin = [
|
|
3803
3803
|
{
|
|
@@ -5602,9 +5602,10 @@ export class CodexAppServerAgentClient {
|
|
|
5602
5602
|
this.goalsEnabledPromise = null;
|
|
5603
5603
|
this.autoReviewEnabledPromise = null;
|
|
5604
5604
|
}
|
|
5605
|
-
sessionDeps() {
|
|
5605
|
+
sessionDeps(launchEnv) {
|
|
5606
5606
|
return {
|
|
5607
5607
|
...this.deps,
|
|
5608
|
+
codexHome: resolveCodexHomeDir(buildCodexAppServerEnv(this.runtimeSettings, launchEnv)),
|
|
5608
5609
|
customCodexConfig: this.customProviderConfig(),
|
|
5609
5610
|
};
|
|
5610
5611
|
}
|
|
@@ -5690,7 +5691,7 @@ export class CodexAppServerAgentClient {
|
|
|
5690
5691
|
const sessionConfig = { ...config, provider: CODEX_PROVIDER };
|
|
5691
5692
|
const goalsEnabled = await this.resolveGoalsEnabled();
|
|
5692
5693
|
const autoReviewEnabled = await this.resolveAutoReviewEnabled();
|
|
5693
|
-
const session = new CodexAppServerAgentSession(sessionConfig, null, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled, agentId: launchContext?.agentId }), this.sessionDeps(), options?.persistSession === false, goalsEnabled, autoReviewEnabled, launchContext?.agentId);
|
|
5694
|
+
const session = new CodexAppServerAgentSession(sessionConfig, null, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled, agentId: launchContext?.agentId }), this.sessionDeps(launchContext?.env), options?.persistSession === false, goalsEnabled, autoReviewEnabled, launchContext?.agentId);
|
|
5694
5695
|
await session.connect();
|
|
5695
5696
|
return session;
|
|
5696
5697
|
}
|
|
@@ -5704,7 +5705,7 @@ export class CodexAppServerAgentClient {
|
|
|
5704
5705
|
};
|
|
5705
5706
|
const goalsEnabled = await this.resolveGoalsEnabled();
|
|
5706
5707
|
const autoReviewEnabled = await this.resolveAutoReviewEnabled();
|
|
5707
|
-
const session = new CodexAppServerAgentSession(merged, handle, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled, agentId: launchContext?.agentId }), this.sessionDeps(), false, goalsEnabled, autoReviewEnabled, launchContext?.agentId, options?.purpose ?? "interactive");
|
|
5708
|
+
const session = new CodexAppServerAgentSession(merged, handle, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled, agentId: launchContext?.agentId }), this.sessionDeps(launchContext?.env), false, goalsEnabled, autoReviewEnabled, launchContext?.agentId, options?.purpose ?? "interactive");
|
|
5708
5709
|
await session.connect();
|
|
5709
5710
|
return session;
|
|
5710
5711
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Logger } from "pino";
|
|
2
2
|
import type { AgentCapabilityFlags, AgentClient, AgentCreateSessionOptions, AgentFeature, AgentLaunchContext, AgentPersistenceHandle, AgentSession, AgentSessionConfig, FetchCatalogOptions, ImportableProviderSession, ImportProviderSessionInput, ImportProviderSessionContext, ListImportableSessionsOptions, ProviderRefreshContext } from "../../../agent-sdk-types.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type ProviderRuntimeSettings } from "../../../provider-launch-config.js";
|
|
4
4
|
import type { ManagedProcessRegistry } from "../../../../managed-processes/managed-processes.js";
|
|
5
5
|
import type { OpenCodeBridge } from "../bridge.js";
|
|
6
6
|
import { V2Runtime } from "./runtime.js";
|
|
@@ -3,6 +3,7 @@ import { V2_CAPABILITIES } from "./capabilities.js";
|
|
|
3
3
|
import { features, permissionRules, applyResumeOverrides, requiresDedicatedV2Server, } from "./configuration.js";
|
|
4
4
|
import { commands } from "./commands.js";
|
|
5
5
|
import { waitForLocationReady, awaitPaseoPlugin } from "./readiness.js";
|
|
6
|
+
import { createProviderEnv, } from "../../../provider-launch-config.js";
|
|
6
7
|
import { importSessionFromPersistence } from "../../../provider-session-import.js";
|
|
7
8
|
import { resolveOpenCodeHomeDir } from "../paths.js";
|
|
8
9
|
import { V2Runtime } from "./runtime.js";
|
|
@@ -134,7 +135,9 @@ export class OpenCodeV2AgentClient {
|
|
|
134
135
|
const location = { directory: config.cwd };
|
|
135
136
|
await awaitPaseoPlugin({ client: connection.client, location });
|
|
136
137
|
}
|
|
137
|
-
await session.initialize(launch
|
|
138
|
+
await session.initialize(launch?.env
|
|
139
|
+
? createProviderEnv({ runtimeSettings: this.options.settings, overlays: [launch.env] })
|
|
140
|
+
: undefined);
|
|
138
141
|
return session;
|
|
139
142
|
}
|
|
140
143
|
catch (error) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SessionInfo } from "@opencode/client";
|
|
2
2
|
import type { Logger } from "pino";
|
|
3
|
-
import type {
|
|
3
|
+
import type { AgentMode, AgentPermissionResponse, AgentPersistenceHandle, AgentPromptInput, AgentRunOptions, AgentSession, AgentSessionConfig, AgentStreamEvent, SteerActiveTurnOptions, SteerResult } from "../../../agent-sdk-types.js";
|
|
4
4
|
import { type V2Connection } from "./runtime.js";
|
|
5
5
|
export declare class OpenCodeV2Session implements AgentSession {
|
|
6
6
|
private connection;
|
|
@@ -35,7 +35,7 @@ export declare class OpenCodeV2Session implements AgentSession {
|
|
|
35
35
|
get id(): string;
|
|
36
36
|
get features(): import("../../../agent-sdk-types.js").AgentFeature[];
|
|
37
37
|
private get client();
|
|
38
|
-
initialize(
|
|
38
|
+
initialize(environment?: Record<string, string>): Promise<void>;
|
|
39
39
|
private watchExit;
|
|
40
40
|
private configureConnection;
|
|
41
41
|
private startStream;
|
|
@@ -72,8 +72,9 @@ export class OpenCodeV2Session {
|
|
|
72
72
|
get client() {
|
|
73
73
|
return this.connection.client;
|
|
74
74
|
}
|
|
75
|
-
async initialize(
|
|
76
|
-
|
|
75
|
+
async initialize(environment) {
|
|
76
|
+
// OpenCode replaces the whole local shell environment, rather than overlaying it.
|
|
77
|
+
this.launchEnv = environment;
|
|
77
78
|
this.watchExit(this.connection);
|
|
78
79
|
await this.configureConnection();
|
|
79
80
|
const location = { directory: this.config.cwd };
|
|
@@ -97,8 +98,6 @@ export class OpenCodeV2Session {
|
|
|
97
98
|
await waitForLocationReady({ client: this.client, location, signal: this.abort.signal });
|
|
98
99
|
if (this.requiresPaseoPlugin)
|
|
99
100
|
await awaitPaseoPlugin({ client: this.client, location, signal: this.abort.signal });
|
|
100
|
-
if (this.launchEnv)
|
|
101
|
-
await this.client.session.environment({ sessionID: this.id, variables: this.launchEnv });
|
|
102
101
|
for (const [server, config] of Object.entries(this.config.mcpServers ?? {})) {
|
|
103
102
|
await this.client.mcp.add({
|
|
104
103
|
server,
|
|
@@ -240,24 +239,42 @@ export class OpenCodeV2Session {
|
|
|
240
239
|
}
|
|
241
240
|
async setModel(model) {
|
|
242
241
|
await this.reconnectIfExited();
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
: (await this.client.model.default({ location: { directory: this.config.cwd } })).data;
|
|
242
|
+
const location = { directory: this.config.cwd };
|
|
243
|
+
const selected = model ? modelRef(model) : (await this.client.model.default({ location })).data;
|
|
246
244
|
if (!selected)
|
|
247
245
|
throw new Error("OpenCode has no default model");
|
|
248
|
-
await this.client.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
246
|
+
const catalog = await this.client.model.list({ location });
|
|
247
|
+
const target = catalog.data.find((entry) => entry.enabled && entry.providerID === selected.providerID && entry.id === selected.id);
|
|
248
|
+
if (!target)
|
|
249
|
+
throw new Error(`OpenCode model unavailable: ${selected.providerID}/${selected.id}`);
|
|
250
|
+
const retainedVariant = this.config.thinkingOptionId;
|
|
251
|
+
const variant = retainedVariant !== "default" && target.variants.some((entry) => entry.id === retainedVariant)
|
|
252
|
+
? retainedVariant
|
|
253
|
+
: undefined;
|
|
254
|
+
const nextModel = {
|
|
255
|
+
id: selected.id,
|
|
256
|
+
providerID: selected.providerID,
|
|
257
|
+
...(variant ? { variant } : {}),
|
|
258
|
+
};
|
|
259
|
+
await this.client.session.switchModel({ sessionID: this.id, model: nextModel });
|
|
260
|
+
this.info.model = nextModel;
|
|
256
261
|
this.config.model = model ?? undefined;
|
|
262
|
+
this.config.thinkingOptionId = variant;
|
|
263
|
+
this.emit({
|
|
264
|
+
type: "thinking_option_changed",
|
|
265
|
+
provider: "opencode",
|
|
266
|
+
thinkingOptionId: variant ?? null,
|
|
267
|
+
});
|
|
257
268
|
this.emit({
|
|
258
269
|
type: "model_changed",
|
|
259
270
|
provider: "opencode",
|
|
260
|
-
runtimeInfo:
|
|
271
|
+
runtimeInfo: {
|
|
272
|
+
provider: "opencode",
|
|
273
|
+
sessionId: this.id,
|
|
274
|
+
model: `${selected.providerID}/${selected.id}`,
|
|
275
|
+
modeId: this.info.agent ?? null,
|
|
276
|
+
thinkingOptionId: variant ?? null,
|
|
277
|
+
},
|
|
261
278
|
});
|
|
262
279
|
}
|
|
263
280
|
async setThinkingOption(variant) {
|
|
@@ -354,6 +371,10 @@ export class OpenCodeV2Session {
|
|
|
354
371
|
}
|
|
355
372
|
}
|
|
356
373
|
async reconcileConnection() {
|
|
374
|
+
// Session environments are process-local. Reapply this agent's snapshot before
|
|
375
|
+
// reconciling a new connection, including event-stream reconnections.
|
|
376
|
+
if (this.launchEnv)
|
|
377
|
+
await this.client.session.environment({ sessionID: this.id, variables: this.launchEnv });
|
|
357
378
|
await this.reconcile();
|
|
358
379
|
await this.children.reconcile(this.id);
|
|
359
380
|
const active = await this.client.session.active();
|
|
@@ -2529,12 +2529,36 @@ class OpenCodeAgentSession {
|
|
|
2529
2529
|
sessionId: this.sessionId,
|
|
2530
2530
|
model: this.config.model ?? null,
|
|
2531
2531
|
modeId: this.currentMode,
|
|
2532
|
+
thinkingOptionId: this.config.thinkingOptionId ?? null,
|
|
2532
2533
|
};
|
|
2533
2534
|
}
|
|
2534
2535
|
async setModel(modelId) {
|
|
2536
|
+
await this.reconnectIfServerExited();
|
|
2535
2537
|
const normalizedModelId = typeof modelId === "string" && modelId.trim().length > 0 ? modelId : null;
|
|
2538
|
+
let variant = this.config.thinkingOptionId;
|
|
2539
|
+
if (!normalizedModelId) {
|
|
2540
|
+
variant = undefined;
|
|
2541
|
+
}
|
|
2542
|
+
else if (variant) {
|
|
2543
|
+
const model = this.parseModel(normalizedModelId);
|
|
2544
|
+
const response = await this.client.provider.list({ directory: this.config.cwd });
|
|
2545
|
+
if (response.error)
|
|
2546
|
+
throw new Error(`Failed to fetch OpenCode providers: ${JSON.stringify(response.error)}`);
|
|
2547
|
+
const provider = response.data?.all.find((entry) => entry.id === model?.providerID);
|
|
2548
|
+
const target = model && provider?.models[model.modelID];
|
|
2549
|
+
if (!target)
|
|
2550
|
+
throw new Error(`OpenCode model unavailable: ${normalizedModelId}`);
|
|
2551
|
+
if (!Object.hasOwn(target.variants ?? {}, variant))
|
|
2552
|
+
variant = undefined;
|
|
2553
|
+
}
|
|
2536
2554
|
this.config.model = normalizedModelId ?? undefined;
|
|
2555
|
+
this.config.thinkingOptionId = variant;
|
|
2537
2556
|
this.selectedModelContextWindowMaxTokens = this.resolveConfiguredModelContextWindowMaxTokens(this.config.model);
|
|
2557
|
+
this.notifySubscribers({
|
|
2558
|
+
type: "thinking_option_changed",
|
|
2559
|
+
provider: "opencode",
|
|
2560
|
+
thinkingOptionId: variant ?? null,
|
|
2561
|
+
});
|
|
2538
2562
|
}
|
|
2539
2563
|
async setThinkingOption(thinkingOptionId) {
|
|
2540
2564
|
const normalizedThinkingOptionId = normalizeOpenCodeVariantId(thinkingOptionId);
|
|
@@ -14,7 +14,7 @@ import { everyMsToFiveFieldCron } from "@getpaseo/protocol/schedule/cadence";
|
|
|
14
14
|
import { expandUserPath, isSameOrDescendantPath, resolvePathFromBase } from "../../path-utils.js";
|
|
15
15
|
import { ScheduleRunSchema, ScheduleSummarySchema, StoredScheduleSchema, } from "@getpaseo/protocol/schedule/types";
|
|
16
16
|
import { AgentModelSchema, AgentProviderEnum, AgentStatusEnum, ProviderModeSchema, ProviderSummarySchema, parseDurationString, resolveRequiredProviderModel, sanitizePermissionRequest, serializeSnapshotWithMetadata, toScheduleSummary, waitForAgentWithTimeout, } from "../mcp-shared.js";
|
|
17
|
-
import { sendPromptToAgent, setupFinishNotification } from "../agent-prompt.js";
|
|
17
|
+
import { sendPromptToAgent, setupFinishNotification, waitForAgentRunStartWithTimeout, } from "../agent-prompt.js";
|
|
18
18
|
import { respondToAgentPermission } from "../permission-response.js";
|
|
19
19
|
import { archiveAgentCommand, cancelAgentRunCommand, closeAgentCommand, setAgentModeCommand, updateAgentCommand, } from "../lifecycle-command.js";
|
|
20
20
|
import { resolveWorktreeSourceCwd } from "../../workspace-source.js";
|
|
@@ -1420,7 +1420,7 @@ export function createPaseoToolCatalog(options) {
|
|
|
1420
1420
|
});
|
|
1421
1421
|
return true;
|
|
1422
1422
|
}
|
|
1423
|
-
await sendPromptToAgent({
|
|
1423
|
+
const { disposition } = await sendPromptToAgent({
|
|
1424
1424
|
agentManager,
|
|
1425
1425
|
agentStorage,
|
|
1426
1426
|
agentId,
|
|
@@ -1453,8 +1453,10 @@ export function createPaseoToolCatalog(options) {
|
|
|
1453
1453
|
return response;
|
|
1454
1454
|
}
|
|
1455
1455
|
const notifying = armFinishNotification();
|
|
1456
|
-
// Return
|
|
1457
|
-
|
|
1456
|
+
// Return once the provider has accepted the turn, so the status reports it running.
|
|
1457
|
+
if (disposition === "turn_started") {
|
|
1458
|
+
await waitForAgentRunStartWithTimeout(agentManager, agentId);
|
|
1459
|
+
}
|
|
1458
1460
|
const currentSnapshot = agentManager.getAgent(agentId);
|
|
1459
1461
|
const responseData = {
|
|
1460
1462
|
success: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},
|
|
1
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},5084,[4432,4433]);
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},
|
|
1
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},5083,[4426]);
|
|
Binary file
|