maka-agent 0.2.1-dev.84.20261014 → 0.2.1-dev.86.20261014
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/acp/session-configuration.js +1 -0
- package/dist/run-command-core.js +4 -7
- package/dist/runtime-host-session-driver.js +4 -4
- package/dist/tui-copy-catalog.js +3 -0
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/antigravity-acp-plugin/dist/plugin.mjs +2 -1
- package/node_modules/@maka/core/dist/image-delivery.js +83 -0
- package/node_modules/@maka/core/dist/image-markdown.js +44 -0
- package/node_modules/@maka/core/dist/model-metadata.js +8 -0
- package/node_modules/@maka/core/dist/model-thinking.js +10 -29
- package/node_modules/@maka/core/dist/recall.js +10 -2
- package/node_modules/@maka/core/dist/session.js +2 -0
- package/node_modules/@maka/core/dist/settings.js +2 -0
- package/node_modules/@maka/core/dist/subagent-settings.js +2 -1
- package/node_modules/@maka/core/package.json +4 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +23 -0
- package/node_modules/@maka/runtime/dist/filesystem-executor.js +2 -0
- package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +7 -3
- package/node_modules/@maka/runtime/dist/filesystem-worker/protocol.js +6 -4
- package/node_modules/@maka/runtime/dist/image-file-reader.js +83 -0
- package/node_modules/@maka/runtime/dist/image-file.js +43 -10
- package/node_modules/@maka/runtime/dist/model-adapter.js +3 -0
- package/node_modules/@maka/runtime/dist/model-factory.js +38 -98
- package/node_modules/@maka/runtime/dist/network/public-network-policy.js +97 -0
- package/node_modules/@maka/runtime/dist/network/scoped-fetch-transport.js +57 -4
- package/node_modules/@maka/runtime/dist/plugin-session-query-service.js +135 -0
- package/node_modules/@maka/runtime/dist/plugin-source-service.js +123 -0
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +3 -0
- package/node_modules/@maka/runtime/dist/plugin-turn-finish-service.js +63 -0
- package/node_modules/@maka/runtime/dist/system-prompt/main-session-prompt.js +3 -0
- package/node_modules/@maka/runtime/dist/tool-availability.js +3 -1
- package/node_modules/@maka/runtime/dist/tool-free-model-call.js +21 -3
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.mjs +69 -12
- package/node_modules/@maka/runtime/dist/workspace-executor.js +3 -3
- package/node_modules/@maka/runtime/package.json +4 -0
- package/node_modules/@maka/runtime-host/dist/assistant/background-sessions.js +32 -0
- package/node_modules/@maka/runtime-host/dist/assistant/execution-outcome.js +52 -0
- package/node_modules/@maka/runtime-host/dist/assistant/index-initiative/assistant.js +236 -0
- package/node_modules/@maka/runtime-host/dist/assistant/index-initiative/controller.js +192 -0
- package/node_modules/@maka/runtime-host/dist/assistant/index-initiative/host.js +71 -0
- package/node_modules/@maka/runtime-host/dist/assistant/index-initiative/prompt.js +26 -0
- package/node_modules/@maka/runtime-host/dist/assistant/index-initiative/store.js +228 -0
- package/node_modules/@maka/runtime-host/dist/assistant/memory-network/controller.js +1121 -0
- package/node_modules/@maka/runtime-host/dist/assistant/memory-network/corpus.js +431 -0
- package/node_modules/@maka/runtime-host/dist/assistant/memory-network/extractor.js +143 -0
- package/node_modules/@maka/runtime-host/dist/assistant/memory-network/host.js +402 -0
- package/node_modules/@maka/runtime-host/dist/assistant/memory-network/store.js +388 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/controller.js +316 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/delegation.js +232 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/delivery.js +250 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/files.js +103 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/host-types.js +19 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/host.js +135 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/matter.js +22 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/prompt.js +51 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/review.js +132 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/store.js +885 -0
- package/node_modules/@maka/runtime-host/dist/assistant/proactive-matters/tools.js +176 -0
- package/node_modules/@maka/runtime-host/dist/assistant/service.js +421 -0
- package/node_modules/@maka/runtime-host/dist/protocol/artifact.js +2 -0
- package/node_modules/@maka/runtime-host/dist/protocol/image-delivery.js +70 -0
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +7 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +4 -1
- package/node_modules/@maka/runtime-host/dist/protocol/personal-assistant.js +58 -0
- package/node_modules/@maka/runtime-host/dist/server/artifact-coordinator.js +10 -1
- package/node_modules/@maka/runtime-host/dist/server/chat-image-artifact.js +41 -0
- package/node_modules/@maka/runtime-host/dist/server/chat-image-delivery.js +232 -0
- package/node_modules/@maka/runtime-host/dist/server/chat-image-markdown.js +26 -0
- package/node_modules/@maka/runtime-host/dist/server/chat-image-source.js +121 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +257 -14
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +12 -2
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +12 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +40 -13
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +40 -0
- package/node_modules/@maka/storage/dist/artifact-image-storage.js +62 -0
- package/node_modules/@maka/storage/dist/artifact-metadata-codec.js +3 -0
- package/node_modules/@maka/storage/dist/artifact-store.js +67 -5
- package/node_modules/@maka/storage/dist/artifact-stores.js +14 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +2 -0
- package/node_modules/@maka/storage/dist/runtime-event-persistence.js +1 -0
- package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +44 -0
- package/node_modules/@maka/storage/dist/sqlite-artifact-schema.js +8 -1
- package/node_modules/@maka/storage/dist/sqlite-image-delivery.js +63 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +9 -0
- package/package.json +1 -1
package/dist/run-command-core.js
CHANGED
|
@@ -117,14 +117,13 @@ export function parseMakaRunArgs(argv) {
|
|
|
117
117
|
...(flags.get('cwd') !== undefined ? { cwd: flags.get('cwd') } : {}),
|
|
118
118
|
...(flags.get('connection') !== undefined ? { connection: flags.get('connection') } : {}),
|
|
119
119
|
...(flags.get('model') !== undefined ? { model: flags.get('model') } : {}),
|
|
120
|
-
...(thinking !== undefined
|
|
120
|
+
...(thinking !== undefined ? { thinking: thinking === 'default' ? null : thinking } : {}),
|
|
121
121
|
...(timeoutSeconds !== undefined ? { timeoutMs: Math.ceil(timeoutSeconds * 1_000) } : {}),
|
|
122
122
|
...(parsedMaxSteps !== undefined ? { maxSteps: parsedMaxSteps } : {}),
|
|
123
123
|
...(booleanFlags.has('yolo') ? { yolo: true } : {}),
|
|
124
124
|
...(resumeId !== undefined ? { resumeId } : {}),
|
|
125
125
|
...(continueLatest ? { continueLatest: true } : {}),
|
|
126
126
|
...(graph ? { graph: true } : {}),
|
|
127
|
-
...(thinking === 'default' ? { thinkingDefaultExplicit: true } : {}),
|
|
128
127
|
...(flags.get('host') !== undefined ? { hostProfileId: flags.get('host') } : {}),
|
|
129
128
|
...(flags.get('project') !== undefined ? { projectId: flags.get('project') } : {}),
|
|
130
129
|
},
|
|
@@ -159,10 +158,8 @@ export async function runMakaTextCliCore(argv, adapter, overrides = {}) {
|
|
|
159
158
|
? { explicitConnection: parsed.options.connection }
|
|
160
159
|
: {}),
|
|
161
160
|
...(parsed.options.model !== undefined ? { explicitModel: parsed.options.model } : {}),
|
|
162
|
-
thinkingSpecified: parsed.options.thinking !== undefined
|
|
163
|
-
...(parsed.options.thinking
|
|
164
|
-
? { explicitThinking: parsed.options.thinking }
|
|
165
|
-
: {}),
|
|
161
|
+
thinkingSpecified: parsed.options.thinking !== undefined,
|
|
162
|
+
...(parsed.options.thinking != null ? { explicitThinking: parsed.options.thinking } : {}),
|
|
166
163
|
}, {
|
|
167
164
|
canonicalizeDirectory: canonicalDirectory,
|
|
168
165
|
...(parsed.options.hostProfileId && parsed.options.hostProfileId !== 'local'
|
|
@@ -381,7 +378,7 @@ function makaRunHelpText(cliCommand) {
|
|
|
381
378
|
' --host <profile-id> Connect through a saved Runtime Host profile',
|
|
382
379
|
' --project <project-id> Select an existing Project on a remote Host',
|
|
383
380
|
' --model <id> Model to use',
|
|
384
|
-
' --thinking <level> off|minimal|low|medium|high|xhigh|max|default',
|
|
381
|
+
' --thinking <level> off|on|minimal|low|medium|high|xhigh|max|default',
|
|
385
382
|
' --timeout <seconds> Invocation timeout',
|
|
386
383
|
' --max-steps <count> Tool-step cap',
|
|
387
384
|
' --yolo Give this task full access to your files and network',
|
|
@@ -159,12 +159,12 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
159
159
|
this.#llmConnectionId = input.llmConnectionId;
|
|
160
160
|
this.#llmConnectionSlug = input.llmConnectionSlug;
|
|
161
161
|
this.#model = input.model;
|
|
162
|
-
this.#thinkingLevel = input.thinkingLevel;
|
|
162
|
+
this.#thinkingLevel = input.thinkingLevel ?? undefined;
|
|
163
163
|
// An omitted mode stays omitted: the Host applies its configured default.
|
|
164
164
|
// Substituting a literal `ask` here would make the CLI a second authority
|
|
165
165
|
// over the starting boundary and silently override that default.
|
|
166
166
|
this.#permissionMode = input.permissionMode;
|
|
167
|
-
const session = await this.#createSession(input.name ?? DEFAULT_SESSION_NAME);
|
|
167
|
+
const session = await this.#createSession(input.name ?? DEFAULT_SESSION_NAME, input.thinkingLevel);
|
|
168
168
|
return projectSessionCatalogSummary(session);
|
|
169
169
|
}
|
|
170
170
|
async listSessions(options = {}) {
|
|
@@ -1139,7 +1139,7 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
1139
1139
|
this.#sessionCreation = undefined;
|
|
1140
1140
|
}
|
|
1141
1141
|
}
|
|
1142
|
-
async #createSession(name) {
|
|
1142
|
+
async #createSession(name, thinkingLevel = this.#thinkingLevel) {
|
|
1143
1143
|
const workspace = this.#workspace.target;
|
|
1144
1144
|
if (!workspace) {
|
|
1145
1145
|
throw new Error('A remote Runtime Host Session requires an explicit Project');
|
|
@@ -1163,7 +1163,7 @@ class RuntimeHostMakaSessionDriverImpl {
|
|
|
1163
1163
|
...(this.#orchestrationMode === 'default'
|
|
1164
1164
|
? {}
|
|
1165
1165
|
: { orchestrationMode: this.#orchestrationMode }),
|
|
1166
|
-
...(
|
|
1166
|
+
...(thinkingLevel === undefined ? {} : { thinkingLevel }),
|
|
1167
1167
|
}));
|
|
1168
1168
|
this.#sessionGeneration += 1;
|
|
1169
1169
|
this.#sessionId = sessionId;
|
package/dist/tui-copy-catalog.js
CHANGED
|
@@ -178,6 +178,7 @@ const TUI_COPY_RESOURCES_PICKERS_EN = {
|
|
|
178
178
|
addAccount: 'add account',
|
|
179
179
|
thinkingLevels: {
|
|
180
180
|
off: 'Off',
|
|
181
|
+
on: 'On',
|
|
181
182
|
minimal: 'Minimal',
|
|
182
183
|
low: 'Low',
|
|
183
184
|
medium: 'Medium',
|
|
@@ -921,6 +922,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
921
922
|
addAccount: '添加账号',
|
|
922
923
|
thinkingLevels: {
|
|
923
924
|
off: '关',
|
|
925
|
+
on: '开',
|
|
924
926
|
minimal: '最小',
|
|
925
927
|
low: '低',
|
|
926
928
|
medium: '中',
|
|
@@ -1045,6 +1047,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
1045
1047
|
addAccount: '新增帳號',
|
|
1046
1048
|
thinkingLevels: {
|
|
1047
1049
|
off: '關',
|
|
1050
|
+
on: '開',
|
|
1048
1051
|
minimal: '最小',
|
|
1049
1052
|
low: '低',
|
|
1050
1053
|
medium: '中',
|
|
Binary file
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// ../core/dist/model-thinking.js
|
|
2
2
|
var THINKING_LEVELS = [
|
|
3
3
|
"off",
|
|
4
|
+
"on",
|
|
4
5
|
"minimal",
|
|
5
6
|
"low",
|
|
6
7
|
"medium",
|
|
@@ -8,7 +9,7 @@ var THINKING_LEVELS = [
|
|
|
8
9
|
"xhigh",
|
|
9
10
|
"max"
|
|
10
11
|
];
|
|
11
|
-
var DECLARABLE_RELAY_THINKING_LEVELS = THINKING_LEVELS.filter((level) => level !== "off");
|
|
12
|
+
var DECLARABLE_RELAY_THINKING_LEVELS = THINKING_LEVELS.filter((level) => level !== "off" && level !== "on");
|
|
12
13
|
|
|
13
14
|
// src/model-presentation.ts
|
|
14
15
|
function describeAntigravityModels(models) {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
/** Client-safe delivery contract. No filesystem or networking capabilities live here. */
|
|
20
|
+
export const IMAGE_DELIVERY_IDENTITY_MAX_LENGTH = 512;
|
|
21
|
+
export const IMAGE_DELIVERY_SOURCE_MAX_LENGTH = 4096;
|
|
22
|
+
/** JavaScript string length, shared by stream capture and Markdown consumers. */
|
|
23
|
+
export const IMAGE_MARKDOWN_MAX_LENGTH = 1024 * 1024;
|
|
24
|
+
export function isImageDeliverySource(value) {
|
|
25
|
+
return (typeof value === 'string' &&
|
|
26
|
+
value.length > 0 &&
|
|
27
|
+
value.length <= IMAGE_DELIVERY_SOURCE_MAX_LENGTH &&
|
|
28
|
+
!/[\x00-\x1f\x7f]/.test(value));
|
|
29
|
+
}
|
|
30
|
+
export function isRemoteImageSource(source) {
|
|
31
|
+
return /^https?:/i.test(source);
|
|
32
|
+
}
|
|
33
|
+
export function isImageDeliveryRequest(value) {
|
|
34
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
35
|
+
return false;
|
|
36
|
+
const v = value;
|
|
37
|
+
const identity = (s) => typeof s === 'string' &&
|
|
38
|
+
s.length > 0 &&
|
|
39
|
+
s.length <= IMAGE_DELIVERY_IDENTITY_MAX_LENGTH &&
|
|
40
|
+
!/[\x00-\x1f\x7f]/.test(s);
|
|
41
|
+
return (Object.keys(v).every((k) => ['turnId', 'messageId', 'source', 'retry', 'loadRemote'].includes(k)) &&
|
|
42
|
+
identity(v.turnId) &&
|
|
43
|
+
identity(v.messageId) &&
|
|
44
|
+
isImageDeliverySource(v.source) &&
|
|
45
|
+
(v.retry === undefined || typeof v.retry === 'boolean') &&
|
|
46
|
+
(v.loadRemote === undefined || typeof v.loadRemote === 'boolean'));
|
|
47
|
+
}
|
|
48
|
+
export const IMAGE_DELIVERY_FAILURES = [
|
|
49
|
+
'not_found',
|
|
50
|
+
'not_allowed',
|
|
51
|
+
'too_large',
|
|
52
|
+
'unsupported_mime',
|
|
53
|
+
'quota_exceeded',
|
|
54
|
+
'download_failed',
|
|
55
|
+
'read_failed',
|
|
56
|
+
'queue_full',
|
|
57
|
+
];
|
|
58
|
+
export function isImageDeliveryAttempt(value) {
|
|
59
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
60
|
+
return false;
|
|
61
|
+
const v = value;
|
|
62
|
+
return (Object.keys(v).every((k) => ['status', 'reason'].includes(k)) &&
|
|
63
|
+
(v.status === 'pending'
|
|
64
|
+
? v.reason === undefined
|
|
65
|
+
: v.status === 'failed' && IMAGE_DELIVERY_FAILURES.includes(v.reason)));
|
|
66
|
+
}
|
|
67
|
+
export const DEFAULT_IMAGE_ARCHIVE_LIMITS = Object.freeze({
|
|
68
|
+
sessionBytes: 100 * 1024 * 1024,
|
|
69
|
+
workspaceBytes: 1024 * 1024 * 1024,
|
|
70
|
+
});
|
|
71
|
+
export function isImageDeliveryMetadata(value) {
|
|
72
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
73
|
+
return false;
|
|
74
|
+
const v = value;
|
|
75
|
+
return (Object.keys(v).every((k) => ['messageId', 'source', 'status', 'contentSha256'].includes(k)) &&
|
|
76
|
+
typeof v.messageId === 'string' &&
|
|
77
|
+
v.messageId.length > 0 &&
|
|
78
|
+
v.messageId.length <= IMAGE_DELIVERY_IDENTITY_MAX_LENGTH &&
|
|
79
|
+
isImageDeliverySource(v.source) &&
|
|
80
|
+
v.status === 'ready' &&
|
|
81
|
+
typeof v.contentSha256 === 'string' &&
|
|
82
|
+
/^[a-f0-9]{64}$/.test(v.contentSha256));
|
|
83
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { Lexer, Marked } from 'marked';
|
|
20
|
+
import { IMAGE_MARKDOWN_MAX_LENGTH } from './image-delivery.js';
|
|
21
|
+
const parser = new Marked({ gfm: true });
|
|
22
|
+
/** Canonical image destinations in real Markdown nodes, including attachment refs.
|
|
23
|
+
* Consumers own their source policy; parsing grants no filesystem or network access.
|
|
24
|
+
*/
|
|
25
|
+
export function markdownImageSources(text) {
|
|
26
|
+
return [...new Set(markdownImages(text).map((image) => image.source))];
|
|
27
|
+
}
|
|
28
|
+
/** Original token spelling and canonical destination, including reference images. */
|
|
29
|
+
export function markdownImages(text) {
|
|
30
|
+
if (!text.includes('![') || text.length > IMAGE_MARKDOWN_MAX_LENGTH)
|
|
31
|
+
return [];
|
|
32
|
+
const images = [];
|
|
33
|
+
parser.walkTokens(parser.lexer(text), (token) => {
|
|
34
|
+
if (token.type === 'image')
|
|
35
|
+
images.push({ raw: token.raw, source: token.href });
|
|
36
|
+
});
|
|
37
|
+
return images;
|
|
38
|
+
}
|
|
39
|
+
/** Resolve a complete inline destination, rejecting trailing or partial syntax. */
|
|
40
|
+
export function parseMarkdownImageDestination(source) {
|
|
41
|
+
const markdown = ``;
|
|
42
|
+
const [token] = Lexer.lexInline(markdown, { gfm: true });
|
|
43
|
+
return token?.type === 'image' && token.raw === markdown ? token.href : undefined;
|
|
44
|
+
}
|
|
@@ -439,6 +439,14 @@ const COMMAND_CODE_MODEL_METADATA = {
|
|
|
439
439
|
function buildStaticModelMetadata(active) {
|
|
440
440
|
return {
|
|
441
441
|
anthropic: ANTHROPIC_MODEL_OVERRIDES,
|
|
442
|
+
opencode: {
|
|
443
|
+
'claude-sonnet-4-5': {
|
|
444
|
+
thinkingOptions: ANTHROPIC_MODEL_OVERRIDES['claude-sonnet-4-5'].thinkingOptions,
|
|
445
|
+
},
|
|
446
|
+
'claude-haiku-4-5': {
|
|
447
|
+
thinkingOptions: ANTHROPIC_MODEL_OVERRIDES['claude-haiku-4-5'].thinkingOptions,
|
|
448
|
+
},
|
|
449
|
+
},
|
|
442
450
|
openai: OPENAI_GPT6_MODEL_OVERRIDES,
|
|
443
451
|
'claude-subscription': claudeSubscriptionModelMetadata(active),
|
|
444
452
|
// The Command Code Provider-API plan rides the same effort table.
|
|
@@ -20,6 +20,7 @@ import { lookupModelMetadata } from './model-metadata.js';
|
|
|
20
20
|
import { isModelApiProtocol } from './provider-registry.js';
|
|
21
21
|
export const THINKING_LEVELS = [
|
|
22
22
|
'off',
|
|
23
|
+
'on',
|
|
23
24
|
'minimal',
|
|
24
25
|
'low',
|
|
25
26
|
'medium',
|
|
@@ -27,29 +28,12 @@ export const THINKING_LEVELS = [
|
|
|
27
28
|
'xhigh',
|
|
28
29
|
'max',
|
|
29
30
|
];
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
* settings surfaces offer and the one the data layer admits. `off` is the
|
|
33
|
-
* sole exclusion: it is not an intensity tier but a *disable* wire
|
|
34
|
-
* (`reasoning_effort: 'none'`), and no generic relay is presumed to honor
|
|
35
|
-
* that encoding; built-in providers that support it get `off` from their own
|
|
36
|
-
* metadata instead. `minimal` and every effort tier above are pure
|
|
37
|
-
* intensity values — the user declaring them is the authority on what the
|
|
38
|
-
* relay accepts.
|
|
39
|
-
*/
|
|
40
|
-
export const DECLARABLE_RELAY_THINKING_LEVELS = THINKING_LEVELS.filter((level) => level !== 'off');
|
|
31
|
+
/** Relay declarations contain effort tiers; switches require a provider-specific wire. */
|
|
32
|
+
export const DECLARABLE_RELAY_THINKING_LEVELS = THINKING_LEVELS.filter((level) => level !== 'off' && level !== 'on');
|
|
41
33
|
export function isThinkingLevel(value) {
|
|
42
34
|
return typeof value === 'string' && THINKING_LEVELS.includes(value);
|
|
43
35
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Derive the user-facing thinking-level choices from a model's declared
|
|
46
|
-
* `ThinkingOptions`. `none` (OpenAI's off effort) and declared `offBehavior`
|
|
47
|
-
* surface as `'off'`; other effort values map to the same-named
|
|
48
|
-
* `ThinkingLevel`. Raw `toggle` alone is intentionally not enough because some
|
|
49
|
-
* adapters have no real disabled wire. Unknown effort values (not in
|
|
50
|
-
* `ThinkingLevel`) are dropped. Returns `[]` for models with no declared
|
|
51
|
-
* options (miss → no thinking menu, fallback default).
|
|
52
|
-
*/
|
|
36
|
+
/** Only expose controls the adapter can encode; unknown effort values are ignored. */
|
|
53
37
|
function deriveThinkingChoices(options) {
|
|
54
38
|
if (!options)
|
|
55
39
|
return [];
|
|
@@ -59,10 +43,13 @@ function deriveThinkingChoices(options) {
|
|
|
59
43
|
for (const effort of options.efforts ?? []) {
|
|
60
44
|
if (effort === 'none')
|
|
61
45
|
choices.add('off');
|
|
62
|
-
else if (
|
|
46
|
+
else if (DECLARABLE_RELAY_THINKING_LEVELS.includes(effort)) {
|
|
63
47
|
choices.add(effort);
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Legacy Claude models need an explicit enabled request and have no effort knob.
|
|
51
|
+
if (options.offBehavior === 'anthropic-thinking-disabled' && choices.size === 1) {
|
|
52
|
+
choices.add('on');
|
|
66
53
|
}
|
|
67
54
|
return THINKING_LEVELS.filter((level) => choices.has(level));
|
|
68
55
|
}
|
|
@@ -108,12 +95,6 @@ function normalizeModelOverride(entry) {
|
|
|
108
95
|
return undefined;
|
|
109
96
|
const declared = {};
|
|
110
97
|
if (Array.isArray(entry.thinkingLevels)) {
|
|
111
|
-
// Declared levels are filtered to the declarable vocabulary, not merely
|
|
112
|
-
// the level vocabulary: `off` is a disable-wire encoding no generic
|
|
113
|
-
// relay is presumed to speak, and a declaration table has no business
|
|
114
|
-
// carrying it. The codec rejects it in persisted documents for the same
|
|
115
|
-
// reason; normalize silently drops it because it also sanitizes input
|
|
116
|
-
// that never passed a validator (settings drafts, hand-edited tables).
|
|
117
98
|
const declaredSet = new Set(entry.thinkingLevels.filter((level) => isThinkingLevel(level) &&
|
|
118
99
|
DECLARABLE_RELAY_THINKING_LEVELS.includes(level)));
|
|
119
100
|
if (declaredSet.size > 0) {
|
|
@@ -635,7 +635,15 @@ function optionalTimestamp(value) {
|
|
|
635
635
|
return null;
|
|
636
636
|
return value;
|
|
637
637
|
}
|
|
638
|
-
|
|
638
|
+
/** Complete read-only history corpus for plugin organizers; same privacy and
|
|
639
|
+
* revision rules as Recall, without the search query's scan-count cap. */
|
|
640
|
+
export async function listRecallHistorySessions(deps, activeSessionId) {
|
|
641
|
+
const privacy = validateWorkspacePrivacyContext(await deps.getPrivacyContext());
|
|
642
|
+
if (!privacy.ok || privacy.value.incognitoActive)
|
|
643
|
+
throw new Error('History is unavailable while workspace privacy cannot be verified or incognito is active');
|
|
644
|
+
return eligibleSessions(collapseSessionRevisions(await deps.listSessions(), activeSessionId), { includeArchived: false }, Number.POSITIVE_INFINITY);
|
|
645
|
+
}
|
|
646
|
+
function eligibleSessions(sessions, filter, limit = MAX_SESSIONS_SCANNED) {
|
|
639
647
|
return sessions
|
|
640
648
|
.filter((session) =>
|
|
641
649
|
// Retired simulator transcripts are task records, not real history;
|
|
@@ -647,7 +655,7 @@ function eligibleSessions(sessions, filter) {
|
|
|
647
655
|
const byTime = (right.lastMessageAt ?? 0) - (left.lastMessageAt ?? 0);
|
|
648
656
|
return byTime !== 0 ? byTime : left.id.localeCompare(right.id);
|
|
649
657
|
})
|
|
650
|
-
.slice(0,
|
|
658
|
+
.slice(0, limit);
|
|
651
659
|
}
|
|
652
660
|
async function readFacts(deps, terms, options) {
|
|
653
661
|
if (!deps.searchFacts)
|
|
@@ -965,3 +965,5 @@ function inferLegacyTurnStatus(messages) {
|
|
|
965
965
|
return 'failed';
|
|
966
966
|
return 'completed';
|
|
967
967
|
}
|
|
968
|
+
/** Durable provenance for assistant-created workers; visibility is a client preference. */
|
|
969
|
+
export const ASSISTANT_BACKGROUND_SESSION_LABEL = 'personal-assistant-background';
|
|
@@ -340,6 +340,7 @@ export function createDefaultSettings() {
|
|
|
340
340
|
activeTab: 'requests',
|
|
341
341
|
},
|
|
342
342
|
appearance: {
|
|
343
|
+
showAssistantBackgroundSessions: false,
|
|
343
344
|
workbarTogglePosition: 'titlebar',
|
|
344
345
|
theme: 'auto',
|
|
345
346
|
palette: 'default',
|
|
@@ -517,6 +518,7 @@ export function normalizeSettings(input) {
|
|
|
517
518
|
// position; UI density is no longer a product setting.
|
|
518
519
|
appearance: {
|
|
519
520
|
...appearanceWithoutLegacyFields,
|
|
521
|
+
showAssistantBackgroundSessions: base.appearance.showAssistantBackgroundSessions === true,
|
|
520
522
|
workbarTogglePosition: base.appearance.workbarTogglePosition === 'edge' ? 'edge' : 'titlebar',
|
|
521
523
|
palette: isThemePalette(base.appearance.palette) ? base.appearance.palette : 'default',
|
|
522
524
|
// Same fail-closed rule as `palette` above, for the same reason: an
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
"./context-offload": "./dist/context-offload.js",
|
|
64
64
|
"./tool-result-archive-evidence": "./dist/tool-result-archive-evidence.js",
|
|
65
65
|
"./attachments": "./dist/attachments.js",
|
|
66
|
+
"./image-delivery": "./dist/image-delivery.js",
|
|
67
|
+
"./image-markdown": "./dist/image-markdown.js",
|
|
66
68
|
"./artifacts": "./dist/artifacts.js",
|
|
67
69
|
"./pet": "./dist/pet.js",
|
|
68
70
|
"./skill-invocation": "./dist/skill-invocation.js",
|
|
@@ -169,6 +171,7 @@
|
|
|
169
171
|
"./workhub-routing": "./dist/workhub-routing.js"
|
|
170
172
|
},
|
|
171
173
|
"dependencies": {
|
|
172
|
-
"intl-messageformat": "11.2.15"
|
|
174
|
+
"intl-messageformat": "11.2.15",
|
|
175
|
+
"marked": "18.0.11"
|
|
173
176
|
}
|
|
174
177
|
}
|
|
@@ -1121,6 +1121,7 @@ export class AiSdkTurn {
|
|
|
1121
1121
|
const requestProjection = shapedProjection;
|
|
1122
1122
|
const completedProviderSteps = [];
|
|
1123
1123
|
let requestMessages = messages;
|
|
1124
|
+
let finishFeedback;
|
|
1124
1125
|
let result;
|
|
1125
1126
|
let providerOutcome;
|
|
1126
1127
|
let finishReason = 'stop';
|
|
@@ -1161,10 +1162,12 @@ export class AiSdkTurn {
|
|
|
1161
1162
|
}
|
|
1162
1163
|
const requestSystemPromptBase = joinPromptFragments([
|
|
1163
1164
|
systemPrompt,
|
|
1165
|
+
finishFeedback,
|
|
1164
1166
|
finalChildSummaryStep ? CHILD_STEP_BUDGET_FINALIZATION_PROMPT : undefined,
|
|
1165
1167
|
toolRuntime.hasSandboxBoundaryDenial() ? SANDBOX_BOUNDARY_DENIED_FOR_TURN : undefined,
|
|
1166
1168
|
sandboxBoundaryFinalizationStep ? SANDBOX_BOUNDARY_FINALIZATION_PROMPT : undefined,
|
|
1167
1169
|
]);
|
|
1170
|
+
finishFeedback = undefined;
|
|
1168
1171
|
const codeModeCatalogPrompt = toolMode === 'code_mode'
|
|
1169
1172
|
? renderCodeModeCatalogPrompt(toolRuntime.hasSandboxBoundaryDenial()
|
|
1170
1173
|
? new Map([...nestedTools].filter(([name]) => name !== REQUEST_SANDBOX_BOUNDARY_TOOL_NAME))
|
|
@@ -1929,6 +1932,26 @@ export class AiSdkTurn {
|
|
|
1929
1932
|
continue agentLoop;
|
|
1930
1933
|
}
|
|
1931
1934
|
}
|
|
1935
|
+
if (mayTakeAnotherStep &&
|
|
1936
|
+
returnedToolCalls.length === 0 &&
|
|
1937
|
+
this.deps.backend.beforeTurnFinish &&
|
|
1938
|
+
this.deps.backend.loadTurnRuntimeEvents &&
|
|
1939
|
+
this.deps.modelAdapter.mapFinishReason(finishReason) === 'end_turn') {
|
|
1940
|
+
const decision = await this.deps.backend.beforeTurnFinish({
|
|
1941
|
+
sessionId: this.deps.backend.sessionId,
|
|
1942
|
+
turnId,
|
|
1943
|
+
signal: turnAbortController.signal,
|
|
1944
|
+
});
|
|
1945
|
+
if (!decision.allow && !this.aborted && !this.loopStopRequested) {
|
|
1946
|
+
if ((await input.handoffBoundary?.(turnAbortController.signal, maxSteps === undefined ? null : maxSteps - runtimeSteps)) === 'pause') {
|
|
1947
|
+
this.handoffPaused = true;
|
|
1948
|
+
break agentLoop;
|
|
1949
|
+
}
|
|
1950
|
+
finishFeedback = decision.feedback;
|
|
1951
|
+
currentStepMessageId = this.deps.newId();
|
|
1952
|
+
continue agentLoop;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1932
1955
|
break agentLoop;
|
|
1933
1956
|
}
|
|
1934
1957
|
// Refine Tool Availability against the final active set. Deferred
|
|
@@ -270,6 +270,8 @@ function createWorkspaceFilesystemExecutor(workspace) {
|
|
|
270
270
|
const result = await workspace.readFile({
|
|
271
271
|
cwd,
|
|
272
272
|
path,
|
|
273
|
+
...(operation.imagePurpose ? { imagePurpose: operation.imagePurpose } : {}),
|
|
274
|
+
...(abortSignal ? { abortSignal } : {}),
|
|
273
275
|
});
|
|
274
276
|
if ('bytes' in result) {
|
|
275
277
|
return { kind: 'read_image', bytes: result.bytes, mimeType: result.mimeType };
|
|
@@ -30,7 +30,7 @@ import { readPage } from '../read-page.js';
|
|
|
30
30
|
import { formatJsonText } from '../format-json.js';
|
|
31
31
|
import { createEditUnifiedDiff, createUnifiedDiff } from '../unified-diff.js';
|
|
32
32
|
import { compareAndDeleteEntry, hostVisibilityAfterWrite, openStableTarget, readModifyWriteThroughHandle, StableWriteFailure, writeThroughHandle, } from '../file-stable-write.js';
|
|
33
|
-
import { readWorkspaceFile } from '../image-file.js';
|
|
33
|
+
import { ImageFileError, readWorkspaceFile } from '../image-file.js';
|
|
34
34
|
import { FILESYSTEM_WORKER_PROTOCOL_VERSION, operationAccess, operationUsesDirectoryEntry, } from './protocol.js';
|
|
35
35
|
import { isLikelySandboxDenial } from '../sandbox/detect.js';
|
|
36
36
|
// Canonicalisation must match the sandbox the worker runs in: realpath-based
|
|
@@ -61,8 +61,10 @@ export async function executeFilesystemOperation(operation, operationBoundary, d
|
|
|
61
61
|
switch (operation.kind) {
|
|
62
62
|
case 'read': {
|
|
63
63
|
const path = await resolveExistingAllowed(operation.cwd, operation.path, 'Read', 'read', operationBoundary);
|
|
64
|
-
const file = await readWorkspaceFile(path
|
|
65
|
-
|
|
64
|
+
const file = await readWorkspaceFile(path, {
|
|
65
|
+
...(operation.imagePurpose ? { imagePurpose: operation.imagePurpose } : {}),
|
|
66
|
+
}).catch((error) => {
|
|
67
|
+
throw operationError(normalizeOperationError(error).code, error instanceof Error ? error.message : 'File could not be read.');
|
|
66
68
|
});
|
|
67
69
|
if ('bytes' in file) {
|
|
68
70
|
return {
|
|
@@ -318,6 +320,8 @@ function operationError(code, message) {
|
|
|
318
320
|
function normalizeOperationError(error) {
|
|
319
321
|
if (error instanceof FilesystemOperationError)
|
|
320
322
|
return error;
|
|
323
|
+
if (error instanceof ImageFileError)
|
|
324
|
+
return operationError(error.code === 'ERR_IMAGE_TOO_LARGE' ? 'image_too_large' : 'invalid_image', error.message);
|
|
321
325
|
if (error instanceof StableWriteFailure) {
|
|
322
326
|
return operationError(error.code, error.message);
|
|
323
327
|
}
|
|
@@ -20,10 +20,9 @@ import { z } from 'zod';
|
|
|
20
20
|
import { readContinuationSchema, readPageSchema } from '../read-page.js';
|
|
21
21
|
import { validateSandboxBoundaryExpansion } from '@maka/core/sandbox-boundary';
|
|
22
22
|
import { GREP_MAX_LINES, GREP_MAX_LINES_PER_FILE, GREP_MAX_MATCH_BYTES } from '../grep-search.js';
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
export const FILESYSTEM_WORKER_PROTOCOL_VERSION = 11;
|
|
23
|
+
// v12 adds chat image reads with a bounded payload and no model dimension limit.
|
|
24
|
+
// Older workers cannot satisfy this read policy and must be rejected at the handshake.
|
|
25
|
+
export const FILESYSTEM_WORKER_PROTOCOL_VERSION = 12;
|
|
27
26
|
/** The single authority on which operation kinds are writes. Shared by the
|
|
28
27
|
* client (permission/identity decisions) and the worker (operation guards) so
|
|
29
28
|
* the set cannot drift. */
|
|
@@ -98,6 +97,7 @@ export const FilesystemWorkerOperationSchema = z.union([
|
|
|
98
97
|
kind: z.literal('read'),
|
|
99
98
|
cwd,
|
|
100
99
|
path,
|
|
100
|
+
imagePurpose: z.literal('chat').optional(),
|
|
101
101
|
offset: z.number().int().nonnegative().optional(),
|
|
102
102
|
limit: z.number().int().positive().optional(),
|
|
103
103
|
continuation: readContinuationSchema.optional(),
|
|
@@ -236,6 +236,8 @@ export const FilesystemWorkerErrorCodeSchema = z.enum([
|
|
|
236
236
|
'grep_unavailable',
|
|
237
237
|
'sandbox_denied',
|
|
238
238
|
'filesystem_denied',
|
|
239
|
+
'image_too_large',
|
|
240
|
+
'invalid_image',
|
|
239
241
|
'filesystem_error',
|
|
240
242
|
// The worker may have applied the mutation before it lost the ability to
|
|
241
243
|
// report back (e.g. it wrote the file then the post-write identity check
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { createBoundaryFilesystemExecutor, } from './filesystem-executor.js';
|
|
20
|
+
import { createLocalWorkspaceExecutor } from './workspace-executor.js';
|
|
21
|
+
import { ImageFileError, imageFileFailureReason } from './image-file.js';
|
|
22
|
+
import { FilesystemWorkerClientError } from './filesystem-worker/client.js';
|
|
23
|
+
import { SandboxCommandError } from './sandbox/errors.js';
|
|
24
|
+
/** Normalizes filesystem backends at the image reader boundary. */
|
|
25
|
+
export class ImageFileReadError extends Error {
|
|
26
|
+
reason;
|
|
27
|
+
constructor(reason, cause) {
|
|
28
|
+
super(cause instanceof Error ? cause.message : `Image read failed: ${reason}`, { cause });
|
|
29
|
+
this.reason = reason;
|
|
30
|
+
this.name = 'ImageFileReadError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function readFailure(error) {
|
|
34
|
+
if (error instanceof ImageFileError)
|
|
35
|
+
return imageFileFailureReason(error);
|
|
36
|
+
if (error instanceof SandboxCommandError)
|
|
37
|
+
return 'not_allowed';
|
|
38
|
+
const code = error instanceof FilesystemWorkerClientError
|
|
39
|
+
? error.reason
|
|
40
|
+
: error?.code;
|
|
41
|
+
switch (code) {
|
|
42
|
+
case 'image_too_large':
|
|
43
|
+
return 'too_large';
|
|
44
|
+
case 'invalid_image':
|
|
45
|
+
return 'unsupported_mime';
|
|
46
|
+
case 'ENOENT':
|
|
47
|
+
case 'ENOTDIR':
|
|
48
|
+
case 'not_found':
|
|
49
|
+
return 'not_found';
|
|
50
|
+
case 'EACCES':
|
|
51
|
+
case 'EPERM':
|
|
52
|
+
case 'filesystem_denied':
|
|
53
|
+
case 'path_denied':
|
|
54
|
+
case 'sandbox_denied':
|
|
55
|
+
case 'sandbox_required':
|
|
56
|
+
case 'sandbox_boundary_required':
|
|
57
|
+
return 'not_allowed';
|
|
58
|
+
default:
|
|
59
|
+
return 'read_failed';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** The same filesystem boundary as Read, without model snapshots or tool execution. */
|
|
63
|
+
export function createImageFileReader(options = {}) {
|
|
64
|
+
const filesystem = createBoundaryFilesystemExecutor({
|
|
65
|
+
workspace: options.executor ?? createLocalWorkspaceExecutor(),
|
|
66
|
+
...(options.filesystemWorker ? { worker: options.filesystemWorker } : {}),
|
|
67
|
+
...(options.permissionProfile ? { permissionProfile: options.permissionProfile } : {}),
|
|
68
|
+
});
|
|
69
|
+
return async (input) => {
|
|
70
|
+
const { path, ...context } = input;
|
|
71
|
+
const result = await filesystem
|
|
72
|
+
.execute({
|
|
73
|
+
...context,
|
|
74
|
+
operation: { kind: 'read', path, imagePurpose: 'chat' },
|
|
75
|
+
})
|
|
76
|
+
.catch((error) => {
|
|
77
|
+
throw new ImageFileReadError(readFailure(error), error);
|
|
78
|
+
});
|
|
79
|
+
if (result.kind !== 'read_image')
|
|
80
|
+
throw new ImageFileReadError('unsupported_mime');
|
|
81
|
+
return { bytes: result.bytes, mimeType: result.mimeType };
|
|
82
|
+
};
|
|
83
|
+
}
|