chainlesschain 0.166.132 → 0.166.133
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/README.md +36 -18
- package/package.json +1 -1
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/data/changelog.json +13 -0
- package/src/gateways/ws/llm-chat-protocol.js +1 -1
- package/src/gateways/ws/personal-data-hub-protocol.js +27 -11
- package/src/gateways/ws/session-core-protocol.js +22 -17
- package/src/gateways/ws/session-protocol.js +19 -8
- package/src/gateways/ws/ws-agent-handler.js +30 -0
- package/src/lib/chat-core.js +40 -35
- package/src/lib/evolution/agent-model-projection.js +0 -1
- package/src/lib/evolution/governed-hub-llm.js +5 -1
- package/src/lib/evolution/governed-hub-resolver.js +15 -6
- package/src/lib/evolution/governed-hub-skill.js +2 -0
- package/src/lib/evolution/optional-ui-model-turn.js +13 -2
- package/src/lib/llm-config-defaults.js +17 -5
- package/src/lib/llm-connection-config.js +10 -2
- package/src/lib/llm-connection-probe.js +5 -2
- package/src/lib/llm-connection-resolution.js +7 -4
- package/src/lib/llm-providers.js +24 -11
- package/src/lib/openai-responses.js +2 -1
- package/src/lib/personal-data-hub-wiring.js +69 -36
- package/src/lib/provider-protocol.js +35 -3
- package/src/lib/provider-stream.js +6 -4
- package/src/lib/runnable-provider.js +4 -0
- package/src/lib/ws-chat-handler.js +22 -9
- package/src/runtime/agent-core.js +65 -6
|
@@ -14,7 +14,12 @@ export class WSChatHandler {
|
|
|
14
14
|
* @param {import("./ws-session-manager.js").Session} options.session
|
|
15
15
|
* @param {import("./interaction-adapter.js").WebSocketInteractionAdapter} options.interaction
|
|
16
16
|
*/
|
|
17
|
-
constructor({
|
|
17
|
+
constructor({
|
|
18
|
+
session,
|
|
19
|
+
interaction,
|
|
20
|
+
evolutionCompositionFactory = null,
|
|
21
|
+
prepareUiModelTurn = null,
|
|
22
|
+
}) {
|
|
18
23
|
if (
|
|
19
24
|
evolutionCompositionFactory !== null &&
|
|
20
25
|
typeof evolutionCompositionFactory !== "function"
|
|
@@ -22,6 +27,9 @@ export class WSChatHandler {
|
|
|
22
27
|
throw new TypeError("evolutionCompositionFactory must be a function");
|
|
23
28
|
}
|
|
24
29
|
this._evolutionCompositionFactory = evolutionCompositionFactory;
|
|
30
|
+
if (prepareUiModelTurn !== null && typeof prepareUiModelTurn !== "function")
|
|
31
|
+
throw new TypeError("prepareUiModelTurn must be a function");
|
|
32
|
+
this._prepareUiModelTurn = prepareUiModelTurn;
|
|
25
33
|
this.session = session;
|
|
26
34
|
this.interaction = interaction;
|
|
27
35
|
this._processing = false;
|
|
@@ -64,17 +72,22 @@ export class WSChatHandler {
|
|
|
64
72
|
});
|
|
65
73
|
runRecorded = true;
|
|
66
74
|
|
|
67
|
-
const turn = await
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
const turn = await (
|
|
76
|
+
this._prepareUiModelTurn ||
|
|
77
|
+
((context) =>
|
|
78
|
+
prepareGovernedModelTurn(this._evolutionCompositionFactory, context))
|
|
79
|
+
)({
|
|
80
|
+
mode: "ws-chat-session",
|
|
81
|
+
messages: session.messages,
|
|
82
|
+
});
|
|
74
83
|
const options = {
|
|
75
84
|
provider: session.provider,
|
|
76
85
|
model: session.model,
|
|
77
|
-
baseUrl:
|
|
86
|
+
baseUrl:
|
|
87
|
+
session.baseUrl ||
|
|
88
|
+
(session.provider === "ollama"
|
|
89
|
+
? "http://localhost:11434"
|
|
90
|
+
: undefined),
|
|
78
91
|
apiKey: session.apiKey,
|
|
79
92
|
// Phase J — pipe WS session id so chat-core records token_usage
|
|
80
93
|
// into the JSONL session store; visible via `cc session usage`.
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
normalizeProviderBaseUrl,
|
|
11
11
|
openAICompatibleBaseUrl,
|
|
12
12
|
} from "../lib/provider-protocol.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
BUILT_IN_PROVIDERS,
|
|
15
|
+
resolveProviderDefinition,
|
|
16
|
+
} from "../lib/llm-providers.js";
|
|
14
17
|
import { resolveLlmConnection } from "../lib/llm-connection-resolution.js";
|
|
15
18
|
/**
|
|
16
19
|
* Agent Core — transport-independent agentic logic
|
|
@@ -12122,11 +12125,65 @@ function getEffectiveToolDefinitions(options = {}) {
|
|
|
12122
12125
|
});
|
|
12123
12126
|
}
|
|
12124
12127
|
|
|
12128
|
+
function projectExactFileMutationToolSchemas(
|
|
12129
|
+
definitions,
|
|
12130
|
+
scope,
|
|
12131
|
+
externalToolExecutors,
|
|
12132
|
+
) {
|
|
12133
|
+
if (scope == null) return definitions;
|
|
12134
|
+
return definitions.map((tool) => {
|
|
12135
|
+
const name = tool?.function?.name;
|
|
12136
|
+
if (
|
|
12137
|
+
!["write_file", "edit_file", "edit_file_hashed"].includes(name) ||
|
|
12138
|
+
!AGENT_TOOLS.includes(tool) ||
|
|
12139
|
+
externalToolExecutors?.[name]
|
|
12140
|
+
) {
|
|
12141
|
+
return tool;
|
|
12142
|
+
}
|
|
12143
|
+
const parameters = tool.function.parameters;
|
|
12144
|
+
return {
|
|
12145
|
+
...tool,
|
|
12146
|
+
function: {
|
|
12147
|
+
...tool.function,
|
|
12148
|
+
parameters: {
|
|
12149
|
+
...parameters,
|
|
12150
|
+
properties: {
|
|
12151
|
+
...parameters.properties,
|
|
12152
|
+
path: {
|
|
12153
|
+
...parameters.properties.path,
|
|
12154
|
+
// Complete host-authorized set: never truncate this enum or
|
|
12155
|
+
// derive it from a read result. Normal tool context budgeting
|
|
12156
|
+
// sees the same schema that is sent to the provider.
|
|
12157
|
+
enum: [...scope.allowedPaths],
|
|
12158
|
+
description:
|
|
12159
|
+
"Use exactly one listed canonical repo-relative path. Read tools may return absolute paths; those are not valid mutation arguments in this run. Do not use an absolute path, ./ prefix, .. segment or backslash. This schema is guidance; all execution-time permission and file-identity checks still apply.",
|
|
12160
|
+
},
|
|
12161
|
+
},
|
|
12162
|
+
},
|
|
12163
|
+
},
|
|
12164
|
+
};
|
|
12165
|
+
});
|
|
12166
|
+
}
|
|
12167
|
+
|
|
12125
12168
|
function getProviderToolDefinitions(options = {}) {
|
|
12126
|
-
|
|
12169
|
+
const definitions = projectMcpToolDefinitions(
|
|
12127
12170
|
getEffectiveToolDefinitions(options),
|
|
12128
12171
|
options.externalToolExecutors,
|
|
12129
12172
|
);
|
|
12173
|
+
if (options.fileMutationScope == null) return definitions;
|
|
12174
|
+
if (options.exactToolNames !== true || options.hermeticExecution !== true) {
|
|
12175
|
+
throw new Error(
|
|
12176
|
+
"exact file mutation scope requires exactToolNames=true and hermeticExecution=true",
|
|
12177
|
+
);
|
|
12178
|
+
}
|
|
12179
|
+
const scope = normalizeExactFileMutationScope(options.fileMutationScope, {
|
|
12180
|
+
cwd: options.cwd || process.cwd(),
|
|
12181
|
+
});
|
|
12182
|
+
return projectExactFileMutationToolSchemas(
|
|
12183
|
+
definitions,
|
|
12184
|
+
scope,
|
|
12185
|
+
options.externalToolExecutors,
|
|
12186
|
+
);
|
|
12130
12187
|
}
|
|
12131
12188
|
|
|
12132
12189
|
const PROVIDER_REQUEST_ID_RE = /^[\x21-\x7e]{1,512}$/;
|
|
@@ -12540,7 +12597,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12540
12597
|
}
|
|
12541
12598
|
|
|
12542
12599
|
// OpenAI-compatible providers
|
|
12543
|
-
const providerDefinition =
|
|
12600
|
+
const providerDefinition = resolveProviderDefinition(provider);
|
|
12544
12601
|
const url = openAICompatibleBaseUrl(provider, baseUrl);
|
|
12545
12602
|
|
|
12546
12603
|
if (!providerDefinition || !url) {
|
|
@@ -12555,7 +12612,8 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12555
12612
|
|
|
12556
12613
|
const envKey = providerDefinition.apiKeyEnv;
|
|
12557
12614
|
const key = apiKey;
|
|
12558
|
-
if (!key
|
|
12615
|
+
if (!key && provider !== "custom")
|
|
12616
|
+
throw new Error(`${envKey} required for provider ${provider}`);
|
|
12559
12617
|
const effectiveModel = model || providerDefinition.models?.[0];
|
|
12560
12618
|
const modelProfile = resolveModelCapabilityProfile({
|
|
12561
12619
|
provider,
|
|
@@ -12695,7 +12753,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12695
12753
|
method: "POST",
|
|
12696
12754
|
headers: {
|
|
12697
12755
|
"Content-Type": "application/json",
|
|
12698
|
-
Authorization: `Bearer ${key}
|
|
12756
|
+
...(key ? { Authorization: `Bearer ${key}` } : {}),
|
|
12699
12757
|
...(supportsOpenAIRequestIdentity && providerRequestId
|
|
12700
12758
|
? { "X-Client-Request-Id": providerRequestId }
|
|
12701
12759
|
: {}),
|
|
@@ -13315,7 +13373,7 @@ async function _chatOpenAIStreaming(
|
|
|
13315
13373
|
method: "POST",
|
|
13316
13374
|
headers: {
|
|
13317
13375
|
"Content-Type": "application/json",
|
|
13318
|
-
Authorization: `Bearer ${apiKey}
|
|
13376
|
+
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
|
|
13319
13377
|
...(providerRequestId
|
|
13320
13378
|
? { "X-Client-Request-Id": providerRequestId }
|
|
13321
13379
|
: {}),
|
|
@@ -15018,6 +15076,7 @@ export async function* agentLoop(messages, options) {
|
|
|
15018
15076
|
let effectiveToolOptions = hermeticExecution
|
|
15019
15077
|
? {
|
|
15020
15078
|
...options,
|
|
15079
|
+
fileMutationScope,
|
|
15021
15080
|
hostManagedToolPolicy: null,
|
|
15022
15081
|
hostManagedToolPolicyAuthority: null,
|
|
15023
15082
|
extraToolDefinitions: [],
|