deepccc 0.2.25 → 0.2.27
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 +22 -7
- package/bin/deepccc-cli.mjs +17 -17
- package/bin/deepccc.mjs +32 -32
- package/dist/attachments.d.ts +1 -1
- package/dist/attachments.js +7 -5
- package/dist/cli.js +52 -7
- package/dist/completion-session.js +5 -3
- package/dist/config.d.ts +3 -1
- package/dist/config.js +4 -0
- package/dist/context.js +4 -1
- package/dist/decision-session.js +5 -3
- package/dist/file-tools.d.ts +3 -1
- package/dist/file-tools.js +5 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +39 -4
- package/dist/json-mode-fetch.d.ts +2 -0
- package/dist/json-mode-fetch.js +12 -0
- package/dist/multimodal.d.ts +51 -0
- package/dist/multimodal.js +291 -0
- package/dist/progress/reducer.js +2 -0
- package/dist/web-page.js +411 -411
- package/dist/web-runtime.d.ts +1 -1
- package/dist/web-runtime.js +3 -0
- package/dist/web-server.d.ts +1 -0
- package/dist/web-server.js +2 -0
- package/docs/completion-session.md +40 -36
- package/docs/decision-session.md +196 -192
- package/docs/workspace-understanding.md +41 -41
- package/os-prompts/darwin.md +8 -8
- package/os-prompts/linux.md +8 -8
- package/os-prompts/win32.md +11 -11
- package/package.json +68 -68
package/dist/web-runtime.d.ts
CHANGED
|
@@ -105,7 +105,7 @@ export declare class DeepCccWebRuntime {
|
|
|
105
105
|
deleteAttachment(sessionId: string, attachmentId: string): Promise<boolean>;
|
|
106
106
|
readArtifact(sessionId: string, value: string): Promise<{
|
|
107
107
|
path: string;
|
|
108
|
-
mimeType: "image/png" | "image/jpeg" | "image/webp";
|
|
108
|
+
mimeType: "image/png" | "image/jpeg" | "image/webp" | "image/gif";
|
|
109
109
|
size: number;
|
|
110
110
|
bytes: NonSharedBuffer;
|
|
111
111
|
} | null>;
|
package/dist/web-runtime.js
CHANGED
|
@@ -37,6 +37,7 @@ export class DeepCccWebRuntime {
|
|
|
37
37
|
baseURL: input.config.baseURL,
|
|
38
38
|
model: input.meta.model || input.config.model,
|
|
39
39
|
subModel: input.meta.subModel || input.config.subModel,
|
|
40
|
+
visionModel: input.config.visionModel,
|
|
40
41
|
effort: input.meta.effort || input.config.effort,
|
|
41
42
|
maxOutputTokens: input.config.maxOutputTokens,
|
|
42
43
|
streaming: input.config.streaming,
|
|
@@ -44,6 +45,8 @@ export class DeepCccWebRuntime {
|
|
|
44
45
|
cwd: input.meta.cwd,
|
|
45
46
|
persist: true,
|
|
46
47
|
sessionId: input.meta.sessionId,
|
|
48
|
+
contextDir: this.store.rootDir,
|
|
49
|
+
attachmentStore: this.attachmentStore,
|
|
47
50
|
contextWindow: input.config.contextWindow,
|
|
48
51
|
permissionMode: "ask",
|
|
49
52
|
permissionResolver: input.permissionResolver,
|
package/dist/web-server.d.ts
CHANGED
package/dist/web-server.js
CHANGED
|
@@ -23,6 +23,7 @@ function runtimeConfig() {
|
|
|
23
23
|
baseURL: config.baseURL,
|
|
24
24
|
model: config.model,
|
|
25
25
|
subModel: config.subModel,
|
|
26
|
+
visionModel: config.visionModel,
|
|
26
27
|
effort: config.effort,
|
|
27
28
|
maxOutputTokens: config.maxOutputTokens,
|
|
28
29
|
contextWindow: config.contextWindow,
|
|
@@ -35,6 +36,7 @@ export function toPublicConfig(config, defaultCwd = process.cwd()) {
|
|
|
35
36
|
baseURL: config.baseURL,
|
|
36
37
|
model: config.model,
|
|
37
38
|
subModel: config.subModel,
|
|
39
|
+
visionModel: config.visionModel,
|
|
38
40
|
effort: config.effort,
|
|
39
41
|
...(config.maxOutputTokens ? { maxOutputTokens: config.maxOutputTokens } : {}),
|
|
40
42
|
streaming: config.streaming,
|
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
# Caller-owned completions
|
|
2
|
-
|
|
3
|
-
`CompletionSession` is an opt-in stateless OpenAI-compatible transport. Pass the
|
|
4
|
-
entire `messages` array; no system guidance, workspace files, skills, tools,
|
|
5
|
-
history or compaction is injected. This is useful when comparing integrations
|
|
6
|
-
without rewriting their established prompt builders.
|
|
7
|
-
|
|
8
|
-
```js
|
|
9
|
-
import {CompletionSession} from 'deepccc';
|
|
10
|
-
const session = new CompletionSession({
|
|
11
|
-
apiKey: process.env.DEEPCCC_API_KEY,
|
|
12
|
-
baseURL: process.env.DEEPCCC_BASE_URL,
|
|
13
|
-
model: process.env.DEEPCCC_MODEL,
|
|
14
|
-
});
|
|
15
|
-
const result = await session.complete({
|
|
16
|
-
messages: [{role: 'system', content: 'Return JSON only.'},
|
|
17
|
-
{role: 'user', content: 'Return an object with ok=true.'}],
|
|
18
|
-
json: true, timeoutMs: 5000, maxOutputTokens: 256, temperature: 0.1,
|
|
19
|
-
});
|
|
20
|
-
if (result.status === 'success') console.log(result.content);
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
JSON mode sends `response_format: {type: 'json_object'}`; callers still parse,
|
|
24
|
-
validate and authorize results. No local syntax repair or automatic retry is
|
|
25
|
-
performed here. Completion is accepted only after a normal stop, never a length
|
|
26
|
-
limit or interrupted stream. Text mode preserves plain-text output. Parallel
|
|
27
|
-
calls do not share mutable history. `timeoutMs` covers stream consumption;
|
|
28
|
-
optional cancellation is the second argument. Context/response character limits
|
|
29
|
-
default to one million each. Oversize input and invalid options throw before
|
|
30
|
-
network activity; runtime failures return fixed diagnostics without raw errors.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
# Caller-owned completions
|
|
2
|
+
|
|
3
|
+
`CompletionSession` is an opt-in stateless OpenAI-compatible transport. Pass the
|
|
4
|
+
entire `messages` array; no system guidance, workspace files, skills, tools,
|
|
5
|
+
history or compaction is injected. This is useful when comparing integrations
|
|
6
|
+
without rewriting their established prompt builders.
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
import {CompletionSession} from 'deepccc';
|
|
10
|
+
const session = new CompletionSession({
|
|
11
|
+
apiKey: process.env.DEEPCCC_API_KEY,
|
|
12
|
+
baseURL: process.env.DEEPCCC_BASE_URL,
|
|
13
|
+
model: process.env.DEEPCCC_MODEL,
|
|
14
|
+
});
|
|
15
|
+
const result = await session.complete({
|
|
16
|
+
messages: [{role: 'system', content: 'Return JSON only.'},
|
|
17
|
+
{role: 'user', content: 'Return an object with ok=true.'}],
|
|
18
|
+
json: true, timeoutMs: 5000, maxOutputTokens: 256, temperature: 0.1,
|
|
19
|
+
});
|
|
20
|
+
if (result.status === 'success') console.log(result.content);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
JSON mode sends `response_format: {type: 'json_object'}`; callers still parse,
|
|
24
|
+
validate and authorize results. No local syntax repair or automatic retry is
|
|
25
|
+
performed here. Completion is accepted only after a normal stop, never a length
|
|
26
|
+
limit or interrupted stream. Text mode preserves plain-text output. Parallel
|
|
27
|
+
calls do not share mutable history. `timeoutMs` covers stream consumption;
|
|
28
|
+
optional cancellation is the second argument. Context/response character limits
|
|
29
|
+
default to one million each. Oversize input and invalid options throw before
|
|
30
|
+
network activity; runtime failures return fixed diagnostics without raw errors.
|
|
31
|
+
|
|
32
|
+
JSON responses are collected as text without constructing partial objects for
|
|
33
|
+
each streamed fragment. This avoids unnecessary parsing and allocation for large
|
|
34
|
+
responses. Ordinary ChatSession, CLI and Web streaming behavior is unchanged.
|
|
35
|
+
|
|
36
|
+
Optional `extensions` passes caller-supplied provider-specific JSON options.
|
|
37
|
+
It cannot override messages, model, streaming, tool settings, response format,
|
|
38
|
+
temperature or token limits. Keep credentials in config, not extensions. No
|
|
39
|
+
messages, headers or generated content are logged or persisted by this class.
|
|
40
|
+
Metrics include duration and request count. Remote cancellation is best effort.
|
package/docs/decision-session.md
CHANGED
|
@@ -1,192 +1,196 @@
|
|
|
1
|
-
# Bounded structured decisions
|
|
2
|
-
|
|
3
|
-
`DecisionSession` is an opt-in, programmatic, text-only API for integrations that
|
|
4
|
-
own their state and need a bounded decision loop. Existing `ChatSession`, CLI and
|
|
5
|
-
Web behavior is unchanged. The model client is reusable, but each `decide()` call
|
|
6
|
-
starts with exactly the supplied context. No conversation history, workspace
|
|
7
|
-
instructions, global skills, file tools, model-based compaction or raw stream
|
|
8
|
-
logging is loaded automatically.
|
|
9
|
-
|
|
10
|
-
This is not a simulator, a game-specific policy or a guarantee of model latency.
|
|
11
|
-
Use an adapter to provide observations, validate decisions against current state,
|
|
12
|
-
and execute actions. Keep application knowledge and private data outside the
|
|
13
|
-
package. Read any skill references at application setup, then pass the relevant
|
|
14
|
-
instructions through `systemPrompt`.
|
|
15
|
-
|
|
16
|
-
## Minimal integration
|
|
17
|
-
|
|
18
|
-
```js
|
|
19
|
-
import { DecisionSession } from 'deepccc';
|
|
20
|
-
import { jsonSchema } from 'ai';
|
|
21
|
-
|
|
22
|
-
const outputSchema = jsonSchema({
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: { action: { type: 'string', enum: ['left', 'right', 'wait'] } },
|
|
25
|
-
required: ['action'],
|
|
26
|
-
additionalProperties: false,
|
|
27
|
-
}, {
|
|
28
|
-
validate(value) {
|
|
29
|
-
if (value && typeof value === 'object' && !Array.isArray(value)
|
|
30
|
-
&& Object.keys(value).length === 1
|
|
31
|
-
&& ['left', 'right', 'wait'].includes(value.action)) {
|
|
32
|
-
return { success: true, value };
|
|
33
|
-
}
|
|
34
|
-
return { success: false, error: new Error('Invalid decision') };
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
const session = new DecisionSession({
|
|
39
|
-
model: process.env.DEEPCCC_MODEL,
|
|
40
|
-
effort: '', // Omit effort when the target service does not support it.
|
|
41
|
-
maxOutputTokens: 2048,
|
|
42
|
-
}, {
|
|
43
|
-
systemPrompt: 'Choose a safe action toward the supplied goal. Unknown data stays unknown.',
|
|
44
|
-
outputSchema,
|
|
45
|
-
maxSteps: 1,
|
|
46
|
-
maxContextChars: 32000,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const result = await session.decide({
|
|
50
|
-
requestId: 'example-request-1',
|
|
51
|
-
stateVersion: 3,
|
|
52
|
-
timeoutMs: 5000,
|
|
53
|
-
context: {
|
|
54
|
-
observation: { position: 1, blocked: [0] },
|
|
55
|
-
goal: { position: 4 },
|
|
56
|
-
plan: null,
|
|
57
|
-
memory: [],
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
if (result.status === 'success') {
|
|
62
|
-
// Re-check result.stateVersion and legality in the adapter before execution.
|
|
63
|
-
console.log(result.value);
|
|
64
|
-
} else {
|
|
65
|
-
console.log(result.status); // Never execute partial text as an action.
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
The default Provider/model/credentials are resolved in the same way as
|
|
70
|
-
`ChatSession`. This API always consumes a structured streaming response;
|
|
71
|
-
`streaming` and `subModel` from ChatSession configuration are not decision options.
|
|
72
|
-
There is no summarization call or hidden model switch.
|
|
73
|
-
|
|
74
|
-
`outputSchema` and allowed tool input schemas **must contain runtime validators**.
|
|
75
|
-
Use a Standard Schema supported by the AI SDK, or `jsonSchema(schema, {validate})`.
|
|
76
|
-
A JSON schema alone describes the model contract but is not a runtime safety
|
|
77
|
-
check, so the constructor rejects schemas without validators. Validators may be
|
|
78
|
-
asynchronous and share the request deadline. The provider must support tool calls.
|
|
79
|
-
The default `outputMode: 'tools'` uses the reserved `submit_result` tool; free-form
|
|
80
|
-
JSON text is not accepted as an alternative in that mode.
|
|
81
|
-
|
|
82
|
-
Since 0.2.24, `outputMode: 'json'` is available for OpenAI-compatible endpoints.
|
|
83
|
-
It sends `response_format: {type: 'json_object'}` with no tools or tool choice;
|
|
84
|
-
the schema is included in the system prompt and runtime validation is still
|
|
85
|
-
mandatory. Nonempty `allowedTools` and other provider protocols are rejected in
|
|
86
|
-
this mode. JSON syntax constraints do not guarantee semantic correctness.
|
|
87
|
-
One local fallback removes trailing commas outside quoted strings, preserving
|
|
88
|
-
values and escapes. Missing values, truncated streams, prose and invalid schemas
|
|
89
|
-
are rejected; no extra model request is made for syntax recovery. Optional
|
|
90
|
-
`metrics.jsonRepairs` counts repaired responses. Deadlines, cancellation, size
|
|
91
|
-
limits, freshness checks and caller-owned context remain unchanged.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
The
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
and
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
1
|
+
# Bounded structured decisions
|
|
2
|
+
|
|
3
|
+
`DecisionSession` is an opt-in, programmatic, text-only API for integrations that
|
|
4
|
+
own their state and need a bounded decision loop. Existing `ChatSession`, CLI and
|
|
5
|
+
Web behavior is unchanged. The model client is reusable, but each `decide()` call
|
|
6
|
+
starts with exactly the supplied context. No conversation history, workspace
|
|
7
|
+
instructions, global skills, file tools, model-based compaction or raw stream
|
|
8
|
+
logging is loaded automatically.
|
|
9
|
+
|
|
10
|
+
This is not a simulator, a game-specific policy or a guarantee of model latency.
|
|
11
|
+
Use an adapter to provide observations, validate decisions against current state,
|
|
12
|
+
and execute actions. Keep application knowledge and private data outside the
|
|
13
|
+
package. Read any skill references at application setup, then pass the relevant
|
|
14
|
+
instructions through `systemPrompt`.
|
|
15
|
+
|
|
16
|
+
## Minimal integration
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import { DecisionSession } from 'deepccc';
|
|
20
|
+
import { jsonSchema } from 'ai';
|
|
21
|
+
|
|
22
|
+
const outputSchema = jsonSchema({
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: { action: { type: 'string', enum: ['left', 'right', 'wait'] } },
|
|
25
|
+
required: ['action'],
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
}, {
|
|
28
|
+
validate(value) {
|
|
29
|
+
if (value && typeof value === 'object' && !Array.isArray(value)
|
|
30
|
+
&& Object.keys(value).length === 1
|
|
31
|
+
&& ['left', 'right', 'wait'].includes(value.action)) {
|
|
32
|
+
return { success: true, value };
|
|
33
|
+
}
|
|
34
|
+
return { success: false, error: new Error('Invalid decision') };
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const session = new DecisionSession({
|
|
39
|
+
model: process.env.DEEPCCC_MODEL,
|
|
40
|
+
effort: '', // Omit effort when the target service does not support it.
|
|
41
|
+
maxOutputTokens: 2048,
|
|
42
|
+
}, {
|
|
43
|
+
systemPrompt: 'Choose a safe action toward the supplied goal. Unknown data stays unknown.',
|
|
44
|
+
outputSchema,
|
|
45
|
+
maxSteps: 1,
|
|
46
|
+
maxContextChars: 32000,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const result = await session.decide({
|
|
50
|
+
requestId: 'example-request-1',
|
|
51
|
+
stateVersion: 3,
|
|
52
|
+
timeoutMs: 5000,
|
|
53
|
+
context: {
|
|
54
|
+
observation: { position: 1, blocked: [0] },
|
|
55
|
+
goal: { position: 4 },
|
|
56
|
+
plan: null,
|
|
57
|
+
memory: [],
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (result.status === 'success') {
|
|
62
|
+
// Re-check result.stateVersion and legality in the adapter before execution.
|
|
63
|
+
console.log(result.value);
|
|
64
|
+
} else {
|
|
65
|
+
console.log(result.status); // Never execute partial text as an action.
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The default Provider/model/credentials are resolved in the same way as
|
|
70
|
+
`ChatSession`. This API always consumes a structured streaming response;
|
|
71
|
+
`streaming` and `subModel` from ChatSession configuration are not decision options.
|
|
72
|
+
There is no summarization call or hidden model switch.
|
|
73
|
+
|
|
74
|
+
`outputSchema` and allowed tool input schemas **must contain runtime validators**.
|
|
75
|
+
Use a Standard Schema supported by the AI SDK, or `jsonSchema(schema, {validate})`.
|
|
76
|
+
A JSON schema alone describes the model contract but is not a runtime safety
|
|
77
|
+
check, so the constructor rejects schemas without validators. Validators may be
|
|
78
|
+
asynchronous and share the request deadline. The provider must support tool calls.
|
|
79
|
+
The default `outputMode: 'tools'` uses the reserved `submit_result` tool; free-form
|
|
80
|
+
JSON text is not accepted as an alternative in that mode.
|
|
81
|
+
|
|
82
|
+
Since 0.2.24, `outputMode: 'json'` is available for OpenAI-compatible endpoints.
|
|
83
|
+
It sends `response_format: {type: 'json_object'}` with no tools or tool choice;
|
|
84
|
+
the schema is included in the system prompt and runtime validation is still
|
|
85
|
+
mandatory. Nonempty `allowedTools` and other provider protocols are rejected in
|
|
86
|
+
this mode. JSON syntax constraints do not guarantee semantic correctness.
|
|
87
|
+
One local fallback removes trailing commas outside quoted strings, preserving
|
|
88
|
+
values and escapes. Missing values, truncated streams, prose and invalid schemas
|
|
89
|
+
are rejected; no extra model request is made for syntax recovery. Optional
|
|
90
|
+
`metrics.jsonRepairs` counts repaired responses. Deadlines, cancellation, size
|
|
91
|
+
limits, freshness checks and caller-owned context remain unchanged.
|
|
92
|
+
|
|
93
|
+
JSON mode collects streamed text and parses the completed response once, rather
|
|
94
|
+
than constructing intermediate partial objects. Final syntax recovery and schema
|
|
95
|
+
validation remain mandatory. Tools mode and ordinary ChatSession are unchanged.
|
|
96
|
+
|
|
97
|
+
## Explicit capabilities
|
|
98
|
+
|
|
99
|
+
Supply a `tools` record with `description`, `inputSchema` and `execute`, and list
|
|
100
|
+
the capabilities to expose in `allowedTools`. Supplying a tool does **not** enable
|
|
101
|
+
it. Both default to empty. Tool names must begin with a letter and use only
|
|
102
|
+
letters, digits or underscores (at most 64 characters); `submit_result` is reserved.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
const options = {
|
|
106
|
+
systemPrompt: 'Inspect relevant information only when needed, then submit a result.',
|
|
107
|
+
outputSchema,
|
|
108
|
+
maxSteps: 2, // one inspection step plus one final submission
|
|
109
|
+
maxToolCalls: 2,
|
|
110
|
+
allowedTools: ['inspect_state'],
|
|
111
|
+
tools: {
|
|
112
|
+
inspect_state: {
|
|
113
|
+
description: 'Return a compact observation for the supplied request.',
|
|
114
|
+
inputSchema: jsonSchema({ type: 'object', additionalProperties: false }, {
|
|
115
|
+
validate(value) {
|
|
116
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
117
|
+
&& Object.keys(value).length === 0
|
|
118
|
+
? { success: true, value }
|
|
119
|
+
: { success: false, error: new Error('Expected empty input') };
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
async execute(input, { signal, requestId, stateVersion }) {
|
|
123
|
+
// Your adapter must honor signal and return a small JSON-serializable value.
|
|
124
|
+
return adapter.observe({ signal, requestId, stateVersion });
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The entire model tool batch is checked before any tool runs. Unknown names,
|
|
132
|
+
invalid inputs, duplicate call IDs and mixing a final submission with other
|
|
133
|
+
calls fail closed. Tools execute sequentially and receive the same cancellation
|
|
134
|
+
signal and request identity. They are not given to the SDK for automatic execution.
|
|
135
|
+
The last permitted model step must submit a result; it cannot start more tools.
|
|
136
|
+
|
|
137
|
+
Prefer observation-only capabilities. A tool allowlist is not an OS sandbox.
|
|
138
|
+
Register trusted code only. Cancellation cannot undo effects of a tool that already
|
|
139
|
+
started. Idempotency, freshness and actual execution acknowledgements are adapter
|
|
140
|
+
responsibilities. Returned identity allows the adapter to reject stale decisions;
|
|
141
|
+
the core does not know whether external state has changed.
|
|
142
|
+
|
|
143
|
+
## Budgets and results
|
|
144
|
+
|
|
145
|
+
| Option | Default | Meaning |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| request `timeoutMs` | Required | One wall-clock budget across generation, tools and validation |
|
|
148
|
+
| `maxSteps` | 1 | Model requests, including final submission |
|
|
149
|
+
| `maxToolCalls` | 4 | Total non-submission calls in a decision |
|
|
150
|
+
| `maxContextChars` | 32000 | System prompt plus serialized messages |
|
|
151
|
+
| `maxToolResultChars` | 8000 | Each serialized observation |
|
|
152
|
+
| `maxResponseChars` | 32000 | Bounded streamed text/tool data; may count tool arguments twice |
|
|
153
|
+
| model `maxOutputTokens` | Configured value, otherwise 2048 | Per-request provider output budget, including reasoning where applicable |
|
|
154
|
+
|
|
155
|
+
Character budgets are protective size limits, not token estimates. Oversized
|
|
156
|
+
state/results fail with `context_limit`; they are never silently truncated or
|
|
157
|
+
summarized. Keep raw logs outside decision context. Assemble the latest state,
|
|
158
|
+
active plan and selected evidence before calling the API. Background summaries
|
|
159
|
+
should produce versioned memory snapshots rather than mutate an in-flight request.
|
|
160
|
+
|
|
161
|
+
`success` is the only status carrying a validated `value`. Other statuses are
|
|
162
|
+
`timed_out`, `cancelled`, `invalid_output`, `step_limit`, `tool_error`,
|
|
163
|
+
`context_limit` and `error`. Metrics report total/model/tool milliseconds, model
|
|
164
|
+
and tool call counts, and the last assembled context size. Provider/tool error
|
|
165
|
+
payloads and partial generated content are not copied into result messages.
|
|
166
|
+
Invalid configuration/request budgets throw before contacting the provider.
|
|
167
|
+
|
|
168
|
+
Since 0.2.23, failures also include a safe `diagnostic` object with a fixed `code`
|
|
169
|
+
and `stage`. Categories distinguish provider errors, invalid tool input, result
|
|
170
|
+
schema failures, truncated output, interrupted output, deadlines and cancellation.
|
|
171
|
+
Provider HTTP status is included when available, but error messages, raw tool
|
|
172
|
+
arguments, prompts, headers and response bodies are never copied into diagnostics.
|
|
173
|
+
The SDK's default raw error logging is disabled for this API. Integrations can
|
|
174
|
+
record their own schema issue paths inside their validators; keep values and raw
|
|
175
|
+
payloads out of those records. The original `status` remains the control-flow
|
|
176
|
+
contract. Diagnostics do not relax validation or trigger automatic retries.
|
|
177
|
+
|
|
178
|
+
Pass an optional `AbortSignal` as the second argument to `decide()`. Provider SDK
|
|
179
|
+
automatic retries are disabled; any future application retry needs a fresh,
|
|
180
|
+
explicit budget. Non-cooperative asynchronous tools/streams are raced against
|
|
181
|
+
cancellation, and late results do not continue the decision loop. Cleanup is
|
|
182
|
+
best-effort; it cannot guarantee remote inference billing stops or an external
|
|
183
|
+
side effect is rolled back. Synchronous code that blocks the Node event loop
|
|
184
|
+
cannot be preempted by a JavaScript timer: use a worker/process for heavy work.
|
|
185
|
+
|
|
186
|
+
A deadline bounds waiting, not the probability of receiving a good result.
|
|
187
|
+
Measure valid-result rate, median/p95 decision latency and application outcomes
|
|
188
|
+
on the actual endpoint. Do not count a timeout as a fast successful decision.
|
|
189
|
+
|
|
190
|
+
## Release checks
|
|
191
|
+
|
|
192
|
+
Tests use synthetic states and a loopback model endpoint, never production data.
|
|
193
|
+
For publication, inspect staged changes, outgoing commits and the actual packed
|
|
194
|
+
archive (including compiled output), and review public PR/release text. Never put
|
|
195
|
+
credentials, private endpoints, proprietary assets or application traces into
|
|
196
|
+
examples, tests, documentation or package files.
|