@puku-ai/sdk 4.0.3 → 4.0.4
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 +24 -7
- package/dist/index.cjs +85 -0
- package/dist/vendor/_vendor/partial-json-parser/parser.cjs +225 -0
- package/dist/vendor/api-promise.cjs +18 -0
- package/dist/vendor/client.cjs +1013 -0
- package/dist/vendor/core/api-promise.cjs +80 -0
- package/dist/vendor/core/api.cjs +2 -0
- package/dist/vendor/core/credentials.cjs +313 -0
- package/dist/vendor/core/error.cjs +156 -0
- package/dist/vendor/core/middleware.cjs +173 -0
- package/dist/vendor/core/pagination.cjs +215 -0
- package/dist/vendor/core/resource.cjs +11 -0
- package/dist/vendor/core/streaming.cjs +346 -0
- package/dist/vendor/core/uploads.cjs +5 -0
- package/dist/vendor/error.cjs +18 -0
- package/dist/vendor/helpers/beta/environments.cjs +30 -0
- package/dist/vendor/helpers/beta/json-schema.cjs +56 -0
- package/dist/vendor/helpers/beta/mcp.cjs +418 -0
- package/dist/vendor/helpers/beta/memory.cjs +17 -0
- package/dist/vendor/helpers/beta/standard-schema.cjs +57 -0
- package/dist/vendor/helpers/beta/zod.cjs +88 -0
- package/dist/vendor/helpers/index.cjs +7 -0
- package/dist/vendor/helpers/json-schema.cjs +36 -0
- package/dist/vendor/helpers/zod.cjs +77 -0
- package/dist/vendor/index.cjs +54 -0
- package/dist/vendor/internal/builtin-types.cjs +3 -0
- package/dist/vendor/internal/constants.cjs +12 -0
- package/dist/vendor/internal/decoders/jsonl.cjs +40 -0
- package/dist/vendor/internal/decoders/line.cjs +109 -0
- package/dist/vendor/internal/detect-platform.cjs +159 -0
- package/dist/vendor/internal/errors.cjs +42 -0
- package/dist/vendor/internal/file-store.cjs +535 -0
- package/dist/vendor/internal/headers.cjs +119 -0
- package/dist/vendor/internal/message-stream-utils.cjs +33 -0
- package/dist/vendor/internal/node.browser.cjs +21 -0
- package/dist/vendor/internal/node.cjs +55 -0
- package/dist/vendor/internal/parse.cjs +65 -0
- package/dist/vendor/internal/qs/formats.cjs +12 -0
- package/dist/vendor/internal/qs/index.cjs +13 -0
- package/dist/vendor/internal/qs/stringify.cjs +276 -0
- package/dist/vendor/internal/qs/types.cjs +2 -0
- package/dist/vendor/internal/qs/utils.cjs +229 -0
- package/dist/vendor/internal/request-options.cjs +31 -0
- package/dist/vendor/internal/request-signal.cjs +49 -0
- package/dist/vendor/internal/shim-types.cjs +3 -0
- package/dist/vendor/internal/shims.cjs +91 -0
- package/dist/vendor/internal/stainless-helper-header.cjs +90 -0
- package/dist/vendor/internal/stream-utils.cjs +37 -0
- package/dist/vendor/internal/to-file.cjs +95 -0
- package/dist/vendor/internal/types.cjs +3 -0
- package/dist/vendor/internal/uploads.cjs +148 -0
- package/dist/vendor/internal/utils/abort.cjs +24 -0
- package/dist/vendor/internal/utils/async-queue.cjs +69 -0
- package/dist/vendor/internal/utils/backoff.cjs +43 -0
- package/dist/vendor/internal/utils/base64.cjs +37 -0
- package/dist/vendor/internal/utils/bytes.cjs +30 -0
- package/dist/vendor/internal/utils/env.cjs +21 -0
- package/dist/vendor/internal/utils/log.cjs +111 -0
- package/dist/vendor/internal/utils/path.cjs +78 -0
- package/dist/vendor/internal/utils/promise.cjs +17 -0
- package/dist/vendor/internal/utils/query.cjs +41 -0
- package/dist/vendor/internal/utils/sleep.cjs +27 -0
- package/dist/vendor/internal/utils/time.cjs +7 -0
- package/dist/vendor/internal/utils/uuid.cjs +18 -0
- package/dist/vendor/internal/utils/values.cjs +125 -0
- package/dist/vendor/internal/utils.cjs +24 -0
- package/dist/vendor/lib/BetaMessageStream.cjs +665 -0
- package/dist/vendor/lib/MessageStream.cjs +612 -0
- package/dist/vendor/lib/beta-parser.cjs +78 -0
- package/dist/vendor/lib/credentials/credential-chain.cjs +244 -0
- package/dist/vendor/lib/credentials/identity-token.cjs +71 -0
- package/dist/vendor/lib/credentials/oidc-federation.cjs +81 -0
- package/dist/vendor/lib/credentials/token-cache.cjs +113 -0
- package/dist/vendor/lib/credentials/types.cjs +267 -0
- package/dist/vendor/lib/credentials/user-oauth.cjs +129 -0
- package/dist/vendor/lib/credentials.cjs +7 -0
- package/dist/vendor/lib/environments/index.cjs +17 -0
- package/dist/vendor/lib/environments/poller.cjs +226 -0
- package/dist/vendor/lib/environments/worker.cjs +609 -0
- package/dist/vendor/lib/helper-client.cjs +57 -0
- package/dist/vendor/lib/middleware.cjs +779 -0
- package/dist/vendor/lib/parser.cjs +65 -0
- package/dist/vendor/lib/sessions/accumulate.cjs +44 -0
- package/dist/vendor/lib/standard-schema.cjs +44 -0
- package/dist/vendor/lib/tools/BetaRunnableTool.cjs +30 -0
- package/dist/vendor/lib/tools/BetaToolRunner.cjs +500 -0
- package/dist/vendor/lib/tools/CompactionControl.cjs +27 -0
- package/dist/vendor/lib/tools/SessionToolRunner.cjs +740 -0
- package/dist/vendor/lib/tools/ToolError.cjs +46 -0
- package/dist/vendor/lib/transform-json-schema.cjs +113 -0
- package/dist/vendor/pagination.cjs +18 -0
- package/dist/vendor/resource.cjs +18 -0
- package/dist/vendor/resources/beta/agents/agents.cjs +159 -0
- package/dist/vendor/resources/beta/agents/index.cjs +8 -0
- package/dist/vendor/resources/beta/agents/versions.cjs +35 -0
- package/dist/vendor/resources/beta/agents.cjs +18 -0
- package/dist/vendor/resources/beta/beta.cjs +105 -0
- package/dist/vendor/resources/beta/deployment-runs.cjs +54 -0
- package/dist/vendor/resources/beta/deployments.cjs +195 -0
- package/dist/vendor/resources/beta/dreams.cjs +115 -0
- package/dist/vendor/resources/beta/environments/environments.cjs +178 -0
- package/dist/vendor/resources/beta/environments/index.cjs +8 -0
- package/dist/vendor/resources/beta/environments/work.cjs +256 -0
- package/dist/vendor/resources/beta/environments.cjs +18 -0
- package/dist/vendor/resources/beta/files.cjs +123 -0
- package/dist/vendor/resources/beta/index.cjs +38 -0
- package/dist/vendor/resources/beta/memory-stores/index.cjs +10 -0
- package/dist/vendor/resources/beta/memory-stores/memories.cjs +129 -0
- package/dist/vendor/resources/beta/memory-stores/memory-stores.cjs +173 -0
- package/dist/vendor/resources/beta/memory-stores/memory-versions.cjs +80 -0
- package/dist/vendor/resources/beta/memory-stores.cjs +18 -0
- package/dist/vendor/resources/beta/messages/batches.cjs +206 -0
- package/dist/vendor/resources/beta/messages/index.cjs +11 -0
- package/dist/vendor/resources/beta/messages/messages.cjs +189 -0
- package/dist/vendor/resources/beta/messages.cjs +18 -0
- package/dist/vendor/resources/beta/models.cjs +59 -0
- package/dist/vendor/resources/beta/organization/api-keys.cjs +55 -0
- package/dist/vendor/resources/beta/organization/compliance-settings.cjs +51 -0
- package/dist/vendor/resources/beta/organization/external-keys.cjs +118 -0
- package/dist/vendor/resources/beta/organization/federation/federation.cjs +49 -0
- package/dist/vendor/resources/beta/organization/federation/index.cjs +10 -0
- package/dist/vendor/resources/beta/organization/federation/issuers.cjs +168 -0
- package/dist/vendor/resources/beta/organization/federation/rules/index.cjs +8 -0
- package/dist/vendor/resources/beta/organization/federation/rules/rules.cjs +226 -0
- package/dist/vendor/resources/beta/organization/federation/rules/workspaces.cjs +113 -0
- package/dist/vendor/resources/beta/organization/federation/rules.cjs +18 -0
- package/dist/vendor/resources/beta/organization/federation.cjs +18 -0
- package/dist/vendor/resources/beta/organization/index.cjs +24 -0
- package/dist/vendor/resources/beta/organization/invites.cjs +75 -0
- package/dist/vendor/resources/beta/organization/organization.cjs +90 -0
- package/dist/vendor/resources/beta/organization/rate-limits.cjs +30 -0
- package/dist/vendor/resources/beta/organization/service-accounts/index.cjs +8 -0
- package/dist/vendor/resources/beta/organization/service-accounts/service-accounts.cjs +202 -0
- package/dist/vendor/resources/beta/organization/service-accounts/workspaces.cjs +124 -0
- package/dist/vendor/resources/beta/organization/service-accounts.cjs +18 -0
- package/dist/vendor/resources/beta/organization/users.cjs +66 -0
- package/dist/vendor/resources/beta/organization/workspaces/index.cjs +12 -0
- package/dist/vendor/resources/beta/organization/workspaces/members.cjs +101 -0
- package/dist/vendor/resources/beta/organization/workspaces/rate-limits.cjs +33 -0
- package/dist/vendor/resources/beta/organization/workspaces/service-accounts.cjs +188 -0
- package/dist/vendor/resources/beta/organization/workspaces/workspaces.cjs +140 -0
- package/dist/vendor/resources/beta/organization/workspaces.cjs +18 -0
- package/dist/vendor/resources/beta/organization.cjs +18 -0
- package/dist/vendor/resources/beta/sessions/events.cjs +119 -0
- package/dist/vendor/resources/beta/sessions/index.cjs +12 -0
- package/dist/vendor/resources/beta/sessions/resources.cjs +131 -0
- package/dist/vendor/resources/beta/sessions/sessions.cjs +186 -0
- package/dist/vendor/resources/beta/sessions/threads/events.cjs +60 -0
- package/dist/vendor/resources/beta/sessions/threads/index.cjs +8 -0
- package/dist/vendor/resources/beta/sessions/threads/threads.cjs +116 -0
- package/dist/vendor/resources/beta/sessions/threads.cjs +18 -0
- package/dist/vendor/resources/beta/sessions.cjs +18 -0
- package/dist/vendor/resources/beta/skills/index.cjs +8 -0
- package/dist/vendor/resources/beta/skills/skills.cjs +132 -0
- package/dist/vendor/resources/beta/skills/versions.cjs +128 -0
- package/dist/vendor/resources/beta/skills.cjs +18 -0
- package/dist/vendor/resources/beta/tunnels/certificates.cjs +128 -0
- package/dist/vendor/resources/beta/tunnels/index.cjs +8 -0
- package/dist/vendor/resources/beta/tunnels/tunnels.cjs +209 -0
- package/dist/vendor/resources/beta/tunnels.cjs +18 -0
- package/dist/vendor/resources/beta/user-profiles.cjs +117 -0
- package/dist/vendor/resources/beta/vaults/credentials.cjs +176 -0
- package/dist/vendor/resources/beta/vaults/index.cjs +8 -0
- package/dist/vendor/resources/beta/vaults/vaults.cjs +177 -0
- package/dist/vendor/resources/beta/vaults.cjs +18 -0
- package/dist/vendor/resources/beta/webhooks.cjs +32 -0
- package/dist/vendor/resources/beta.cjs +18 -0
- package/dist/vendor/resources/completions.cjs +22 -0
- package/dist/vendor/resources/files.cjs +51 -0
- package/dist/vendor/resources/index.cjs +31 -0
- package/dist/vendor/resources/messages/batches.cjs +160 -0
- package/dist/vendor/resources/messages/index.cjs +8 -0
- package/dist/vendor/resources/messages/messages.cjs +159 -0
- package/dist/vendor/resources/messages.cjs +18 -0
- package/dist/vendor/resources/models.cjs +44 -0
- package/dist/vendor/resources/shared.cjs +3 -0
- package/dist/vendor/resources/skills/index.cjs +8 -0
- package/dist/vendor/resources/skills/skills.cjs +72 -0
- package/dist/vendor/resources/skills/versions.cjs +40 -0
- package/dist/vendor/resources/skills.cjs +18 -0
- package/dist/vendor/resources/top-level.cjs +3 -0
- package/dist/vendor/resources.cjs +17 -0
- package/dist/vendor/streaming.cjs +18 -0
- package/dist/vendor/tools/agent-toolset/fs-util.cjs +193 -0
- package/dist/vendor/tools/agent-toolset/memories.cjs +916 -0
- package/dist/vendor/tools/agent-toolset/node.browser.cjs +147 -0
- package/dist/vendor/tools/agent-toolset/node.cjs +939 -0
- package/dist/vendor/tools/agent-toolset/skills.cjs +325 -0
- package/dist/vendor/tools/agent-toolset/sync-interval.cjs +28 -0
- package/dist/vendor/tools/memory/node.browser.cjs +48 -0
- package/dist/vendor/tools/memory/node.cjs +364 -0
- package/dist/vendor/uploads.cjs +18 -0
- package/dist/vendor/version.cjs +4 -0
- package/package.json +12 -13
- package/sdk.cjs +0 -14271
- package/sdk.cjs.map +0 -149
- package/sdk.d.ts +0 -10866
- package/sdk.mjs +0 -68
- package/sdk.mjs.map +0 -149
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maybeParseMessage = maybeParseMessage;
|
|
4
|
+
exports.parseMessage = parseMessage;
|
|
5
|
+
const error_1 = require("../core/error");
|
|
6
|
+
function getOutputFormat(params) {
|
|
7
|
+
return params?.output_config?.format;
|
|
8
|
+
}
|
|
9
|
+
function maybeParseMessage(message, params, opts) {
|
|
10
|
+
const outputFormat = getOutputFormat(params);
|
|
11
|
+
if (!params || !('parse' in (outputFormat ?? {}))) {
|
|
12
|
+
return {
|
|
13
|
+
...message,
|
|
14
|
+
content: message.content.map((block) => {
|
|
15
|
+
if (block.type === 'text') {
|
|
16
|
+
const parsedBlock = Object.defineProperty({ ...block }, 'parsed_output', {
|
|
17
|
+
value: null,
|
|
18
|
+
enumerable: false,
|
|
19
|
+
});
|
|
20
|
+
return parsedBlock;
|
|
21
|
+
}
|
|
22
|
+
return block;
|
|
23
|
+
}),
|
|
24
|
+
parsed_output: null,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return parseMessage(message, params, opts);
|
|
28
|
+
}
|
|
29
|
+
function parseMessage(message, params, opts) {
|
|
30
|
+
let firstParsedOutput = null;
|
|
31
|
+
const content = message.content.map((block) => {
|
|
32
|
+
if (block.type === 'text') {
|
|
33
|
+
const parsedOutput = parseOutputFormat(params, block.text);
|
|
34
|
+
if (firstParsedOutput === null) {
|
|
35
|
+
firstParsedOutput = parsedOutput;
|
|
36
|
+
}
|
|
37
|
+
const parsedBlock = Object.defineProperty({ ...block }, 'parsed_output', {
|
|
38
|
+
value: parsedOutput,
|
|
39
|
+
enumerable: false,
|
|
40
|
+
});
|
|
41
|
+
return parsedBlock;
|
|
42
|
+
}
|
|
43
|
+
return block;
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
...message,
|
|
47
|
+
content,
|
|
48
|
+
parsed_output: firstParsedOutput,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function parseOutputFormat(params, content) {
|
|
52
|
+
const outputFormat = getOutputFormat(params);
|
|
53
|
+
if (outputFormat?.type !== 'json_schema') {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
if ('parse' in outputFormat) {
|
|
58
|
+
return outputFormat.parse(content);
|
|
59
|
+
}
|
|
60
|
+
return JSON.parse(content);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
throw new error_1.PukuError(`Failed to parse structured output: ${error}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.accumulateManagedAgentsEvent = accumulateManagedAgentsEvent;
|
|
4
|
+
const error_1 = require("../../core/error");
|
|
5
|
+
function accumulateManagedAgentsEvent(accumulated, event) {
|
|
6
|
+
switch (event.type) {
|
|
7
|
+
case 'event_start': {
|
|
8
|
+
if (event.event.type === 'agent.message') {
|
|
9
|
+
return { id: event.event.id, type: 'agent.message', content: [], processed_at: '' };
|
|
10
|
+
}
|
|
11
|
+
return accumulated;
|
|
12
|
+
}
|
|
13
|
+
case 'agent.message': {
|
|
14
|
+
return { ...event, content: event.content.map((block) => ({ ...block })) };
|
|
15
|
+
}
|
|
16
|
+
case 'event_delta': {
|
|
17
|
+
if (accumulated === undefined) {
|
|
18
|
+
throw new error_1.PukuError(`event_delta for ${event.event_id} received before its event_start`);
|
|
19
|
+
}
|
|
20
|
+
const idx = event.delta.index ?? 0;
|
|
21
|
+
const fragment = event.delta.content;
|
|
22
|
+
// Indices arrive in order — the first delta at a new index opens the slot.
|
|
23
|
+
// A gap means deltas arrived out of order or were mis-routed.
|
|
24
|
+
if (idx > accumulated.content.length) {
|
|
25
|
+
throw new error_1.PukuError(`event_delta index ${idx} is beyond the end of content (length ${accumulated.content.length})`);
|
|
26
|
+
}
|
|
27
|
+
const existing = accumulated.content[idx];
|
|
28
|
+
if (existing === undefined) {
|
|
29
|
+
// New index: pass the fragment through as a fresh block.
|
|
30
|
+
return { ...accumulated, content: [...accumulated.content, { ...fragment }] };
|
|
31
|
+
}
|
|
32
|
+
let updated = existing;
|
|
33
|
+
if (fragment.type === 'text' && existing.type === 'text') {
|
|
34
|
+
updated = { ...existing, text: existing.text + fragment.text };
|
|
35
|
+
}
|
|
36
|
+
const content = accumulated.content.slice();
|
|
37
|
+
content[idx] = updated;
|
|
38
|
+
return { ...accumulated, content };
|
|
39
|
+
}
|
|
40
|
+
default:
|
|
41
|
+
// Any other event, including types newer than this SDK, leaves the snapshot unchanged.
|
|
42
|
+
return accumulated;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.standardSchemaToJSONSchema = standardSchemaToJSONSchema;
|
|
4
|
+
exports.parseWithStandardSchema = parseWithStandardSchema;
|
|
5
|
+
const error_1 = require("../core/error");
|
|
6
|
+
/**
|
|
7
|
+
* Returns `jsonSchema` if given, otherwise the schema's Standard JSON Schema `input`
|
|
8
|
+
* representation (the model produces the value that the validator consumes).
|
|
9
|
+
*/
|
|
10
|
+
function standardSchemaToJSONSchema(schema, jsonSchema) {
|
|
11
|
+
if (jsonSchema) {
|
|
12
|
+
return jsonSchema;
|
|
13
|
+
}
|
|
14
|
+
const std = schema['~standard'];
|
|
15
|
+
if (std.jsonSchema) {
|
|
16
|
+
return std.jsonSchema.input({ target: 'draft-2020-12' });
|
|
17
|
+
}
|
|
18
|
+
throw new error_1.PukuError(`Could not derive a JSON Schema from this ${std.vendor} schema as it does not implement Standard JSON Schema (\`~standard.jsonSchema\`). Pass the \`jsonSchema\` option, or use a library version that implements it (e.g. zod >= 4.2, or valibot via \`toStandardJsonSchema()\`).`);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validates `value` with `~standard.validate` and returns the typed output, throwing an
|
|
22
|
+
* `PukuError` on issues. Validation must be synchronous because `parse` hooks are.
|
|
23
|
+
*/
|
|
24
|
+
function parseWithStandardSchema(schema, value) {
|
|
25
|
+
const result = schema['~standard'].validate(value);
|
|
26
|
+
if (result instanceof Promise) {
|
|
27
|
+
// avoid an unhandled rejection from the discarded result
|
|
28
|
+
result.catch(() => { });
|
|
29
|
+
throw new error_1.PukuError(`Async validation is not supported: the ${schema['~standard'].vendor} schema's \`~standard.validate()\` returned a Promise.`);
|
|
30
|
+
}
|
|
31
|
+
if (result.issues) {
|
|
32
|
+
const formattedIssues = result.issues.slice(0, 5).map(formatIssue).join('\n');
|
|
33
|
+
const issueCount = result.issues.length;
|
|
34
|
+
const suffix = issueCount > 5 ? `\n ... and ${issueCount - 5} more issue(s)` : '';
|
|
35
|
+
throw new error_1.PukuError(`Schema validation failed with ${issueCount} issue(s):\n${formattedIssues}${suffix}`);
|
|
36
|
+
}
|
|
37
|
+
return result.value;
|
|
38
|
+
}
|
|
39
|
+
function formatIssue(issue) {
|
|
40
|
+
const path = (issue.path ?? [])
|
|
41
|
+
.map((segment) => String(typeof segment === 'object' ? segment.key : segment))
|
|
42
|
+
.join('.');
|
|
43
|
+
return path ? ` - ${path}: ${issue.message}` : ` - ${issue.message}`;
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toolName = toolName;
|
|
4
|
+
exports.toolErrorContent = toolErrorContent;
|
|
5
|
+
exports.runRunnableTool = runRunnableTool;
|
|
6
|
+
const ToolError_1 = require("./ToolError");
|
|
7
|
+
/**
|
|
8
|
+
* The name the model calls a tool by: `mcp_server_name` for MCP toolsets, `type` for nameless server
|
|
9
|
+
* toolsets (browser/computer), `name` for everything else.
|
|
10
|
+
*/
|
|
11
|
+
function toolName(tool) {
|
|
12
|
+
return ('name' in tool ? tool.name
|
|
13
|
+
: 'mcp_server_name' in tool ? tool.mcp_server_name
|
|
14
|
+
: tool.type);
|
|
15
|
+
}
|
|
16
|
+
/** Tool-result content for a thrown value: a {@link ToolError}'s own content, otherwise `Error: <message>`. */
|
|
17
|
+
function toolErrorContent(e) {
|
|
18
|
+
return e instanceof ToolError_1.ToolError ? e.content : `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
19
|
+
}
|
|
20
|
+
/** Parse the input, run the tool, and turn anything thrown into an error result. */
|
|
21
|
+
async function runRunnableTool(tool, rawInput, context) {
|
|
22
|
+
try {
|
|
23
|
+
const input = tool.parse ? tool.parse(rawInput) : rawInput;
|
|
24
|
+
const content = await tool.run(input, context);
|
|
25
|
+
return { content, isError: false };
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return { content: toolErrorContent(e), isError: true };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BetaToolRunner = void 0;
|
|
4
|
+
const ToolError_1 = require("./ToolError");
|
|
5
|
+
const error_1 = require("../../core/error");
|
|
6
|
+
const headers_1 = require("../../internal/headers");
|
|
7
|
+
const promise_1 = require("../../internal/utils/promise");
|
|
8
|
+
const values_1 = require("../../internal/utils/values");
|
|
9
|
+
const CompactionControl_1 = require("./CompactionControl");
|
|
10
|
+
const stainless_helper_header_1 = require("../../internal/stainless-helper-header");
|
|
11
|
+
/**
|
|
12
|
+
* A ToolRunner handles the automatic conversation loop between the assistant and tools.
|
|
13
|
+
*
|
|
14
|
+
* A ToolRunner is an async iterable that yields either BetaMessage or BetaMessageStream objects
|
|
15
|
+
* depending on the streaming configuration.
|
|
16
|
+
*/
|
|
17
|
+
class BetaToolRunner {
|
|
18
|
+
client;
|
|
19
|
+
/** Whether the async iterator has been consumed */
|
|
20
|
+
#consumed = false;
|
|
21
|
+
/** Whether parameters have been mutated since the last API call */
|
|
22
|
+
#mutated = false;
|
|
23
|
+
/** Current state containing the request parameters */
|
|
24
|
+
#state;
|
|
25
|
+
#options;
|
|
26
|
+
/** Promise for the last message received from the assistant */
|
|
27
|
+
#message;
|
|
28
|
+
/** Cached tool response to avoid redundant executions */
|
|
29
|
+
#toolResponse;
|
|
30
|
+
/** Promise resolvers for waiting on completion */
|
|
31
|
+
#completion;
|
|
32
|
+
/** Number of iterations (API requests) made so far */
|
|
33
|
+
#iterationCount = 0;
|
|
34
|
+
constructor(client, params, options) {
|
|
35
|
+
this.client = client;
|
|
36
|
+
this.#state = {
|
|
37
|
+
params: {
|
|
38
|
+
// You can't clone the entire params since there are functions as handlers.
|
|
39
|
+
// You also don't really need to clone params.messages, but it probably will prevent a foot gun
|
|
40
|
+
// somewhere.
|
|
41
|
+
...params,
|
|
42
|
+
messages: structuredClone(params.messages),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
// structuredClone drops symbol-keyed properties, so collect helper marks
|
|
46
|
+
// from the original params here — the create()-side collector won't see
|
|
47
|
+
// them on the cloned messages.
|
|
48
|
+
const collected = (0, stainless_helper_header_1.collectStainlessHelpers)(params.tools, params.messages);
|
|
49
|
+
this.#options = {
|
|
50
|
+
...options,
|
|
51
|
+
headers: (0, headers_1.buildHeaders)([
|
|
52
|
+
(0, stainless_helper_header_1.helperHeader)('BetaToolRunner'),
|
|
53
|
+
collected.length ? { [stainless_helper_header_1.STAINLESS_HELPER_HEADER]: collected.join(', ') } : undefined,
|
|
54
|
+
options?.headers,
|
|
55
|
+
]),
|
|
56
|
+
};
|
|
57
|
+
this.#completion = (0, promise_1.promiseWithResolvers)();
|
|
58
|
+
if (params.compactionControl?.enabled) {
|
|
59
|
+
console.warn('Puku: The `compactionControl` parameter is deprecated and will be removed in a future version. ' +
|
|
60
|
+
'Use server-side compaction instead by passing `edits: [{ type: "compact_20260112" }]` in the params passed to `toolRunner()`. ' +
|
|
61
|
+
'See https://puku.sh/docs/');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async #checkAndCompact() {
|
|
65
|
+
const compactionControl = this.#state.params.compactionControl;
|
|
66
|
+
if (!compactionControl || !compactionControl.enabled) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
let tokensUsed = 0;
|
|
70
|
+
if (this.#message !== undefined) {
|
|
71
|
+
try {
|
|
72
|
+
const message = await this.#message;
|
|
73
|
+
const totalInputTokens = message.usage.input_tokens +
|
|
74
|
+
(message.usage.cache_creation_input_tokens ?? 0) +
|
|
75
|
+
(message.usage.cache_read_input_tokens ?? 0);
|
|
76
|
+
tokensUsed = totalInputTokens + message.usage.output_tokens;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// If we can't get the message, skip compaction
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const threshold = compactionControl.contextTokenThreshold ?? CompactionControl_1.DEFAULT_TOKEN_THRESHOLD;
|
|
84
|
+
if (tokensUsed < threshold) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const model = compactionControl.model ?? this.#state.params.model;
|
|
88
|
+
const summaryPrompt = compactionControl.summaryPrompt ?? CompactionControl_1.DEFAULT_SUMMARY_PROMPT;
|
|
89
|
+
const messages = this.#state.params.messages;
|
|
90
|
+
if (messages[messages.length - 1].role === 'assistant') {
|
|
91
|
+
// Remove tool_use blocks from the last message to avoid 400 error
|
|
92
|
+
// (tool_use requires tool_result, which we don't have yet)
|
|
93
|
+
const lastMessage = messages[messages.length - 1];
|
|
94
|
+
if (Array.isArray(lastMessage.content)) {
|
|
95
|
+
const nonToolBlocks = lastMessage.content.filter((block) => block.type !== 'tool_use');
|
|
96
|
+
if (nonToolBlocks.length === 0) {
|
|
97
|
+
// If all blocks were tool_use, just remove the message entirely
|
|
98
|
+
messages.pop();
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lastMessage.content = nonToolBlocks;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const response = await this.client.beta.messages.create({
|
|
106
|
+
model,
|
|
107
|
+
messages: [
|
|
108
|
+
...messages,
|
|
109
|
+
{
|
|
110
|
+
role: 'user',
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: 'text',
|
|
114
|
+
text: summaryPrompt,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
max_tokens: this.#state.params.max_tokens,
|
|
120
|
+
}, {
|
|
121
|
+
signal: this.#options.signal,
|
|
122
|
+
headers: (0, headers_1.buildHeaders)([this.#options.headers, (0, stainless_helper_header_1.helperHeader)('compaction')]),
|
|
123
|
+
});
|
|
124
|
+
if (response.content[0]?.type !== 'text') {
|
|
125
|
+
throw new error_1.PukuError('Expected text response for compaction');
|
|
126
|
+
}
|
|
127
|
+
this.#state.params.messages = [
|
|
128
|
+
{
|
|
129
|
+
role: 'user',
|
|
130
|
+
content: response.content,
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
async *[Symbol.asyncIterator]() {
|
|
136
|
+
if (this.#consumed) {
|
|
137
|
+
throw new error_1.PukuError('Cannot iterate over a consumed stream');
|
|
138
|
+
}
|
|
139
|
+
this.#consumed = true;
|
|
140
|
+
this.#mutated = true;
|
|
141
|
+
this.#toolResponse = undefined;
|
|
142
|
+
try {
|
|
143
|
+
while (true) {
|
|
144
|
+
let stream;
|
|
145
|
+
try {
|
|
146
|
+
if (this.#state.params.max_iterations &&
|
|
147
|
+
this.#iterationCount >= this.#state.params.max_iterations) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
this.#mutated = false;
|
|
151
|
+
this.#toolResponse = undefined;
|
|
152
|
+
this.#iterationCount++;
|
|
153
|
+
this.#message = undefined;
|
|
154
|
+
const { max_iterations, compactionControl, ...params } = this.#state.params;
|
|
155
|
+
if (params.stream) {
|
|
156
|
+
stream = this.client.beta.messages.stream({ ...params }, this.#options);
|
|
157
|
+
this.#message = stream.finalMessage();
|
|
158
|
+
// Make sure that this promise doesn't throw before we get the option to do something about it.
|
|
159
|
+
// Error will be caught when we call await this.#message ultimately
|
|
160
|
+
this.#message.catch(() => { });
|
|
161
|
+
yield stream;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
this.#message = this.client.beta.messages.create({ ...params, stream: false }, this.#options);
|
|
165
|
+
yield this.#message;
|
|
166
|
+
}
|
|
167
|
+
const isCompacted = await this.#checkAndCompact();
|
|
168
|
+
if (!isCompacted) {
|
|
169
|
+
if (!this.#mutated) {
|
|
170
|
+
const message = await this.#message;
|
|
171
|
+
const nextStep = determineNextStepFromStopReason(message.stop_reason);
|
|
172
|
+
this.#state.params.messages.push({ role: message.role, content: message.content });
|
|
173
|
+
// Container-bound server tools reject a follow-up request that omits the container the
|
|
174
|
+
// previous turn ran in, so carry its id forward unless the caller pinned one themselves.
|
|
175
|
+
const { container } = this.#state.params;
|
|
176
|
+
if (message.container) {
|
|
177
|
+
if (container == null) {
|
|
178
|
+
this.#state.params.container = message.container.id;
|
|
179
|
+
}
|
|
180
|
+
else if (typeof container === 'object' && container.id == null) {
|
|
181
|
+
this.#state.params.container = { ...container, id: message.container.id };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (nextStep === 'stop') {
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
if (nextStep === 'resume') {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const toolMessage = await this.#generateToolResponse(this.#state.params.messages.at(-1));
|
|
192
|
+
if (toolMessage) {
|
|
193
|
+
this.#state.params.messages.push(toolMessage);
|
|
194
|
+
}
|
|
195
|
+
else if (!this.#mutated) {
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
if (stream) {
|
|
202
|
+
stream.abort();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!this.#message) {
|
|
207
|
+
throw new error_1.PukuError('ToolRunner concluded without a message from the server');
|
|
208
|
+
}
|
|
209
|
+
this.#completion.resolve(await this.#message);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
this.#consumed = false;
|
|
213
|
+
// Silence unhandled promise errors
|
|
214
|
+
this.#completion.promise.catch(() => { });
|
|
215
|
+
this.#completion.reject(error);
|
|
216
|
+
this.#completion = (0, promise_1.promiseWithResolvers)();
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
setMessagesParams(paramsOrMutator) {
|
|
221
|
+
if (typeof paramsOrMutator === 'function') {
|
|
222
|
+
this.#state.params = paramsOrMutator(this.#state.params);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this.#state.params = paramsOrMutator;
|
|
226
|
+
}
|
|
227
|
+
this.#mutated = true;
|
|
228
|
+
// Invalidate cached tool response since parameters changed
|
|
229
|
+
this.#toolResponse = undefined;
|
|
230
|
+
}
|
|
231
|
+
setRequestOptions(optionsOrMutator) {
|
|
232
|
+
if (typeof optionsOrMutator === 'function') {
|
|
233
|
+
this.#options = optionsOrMutator(this.#options);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.#options = { ...this.#options, ...optionsOrMutator };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get the tool response for the last message from the assistant.
|
|
241
|
+
* Avoids redundant tool executions by caching results.
|
|
242
|
+
*
|
|
243
|
+
* @returns A promise that resolves to a BetaMessageParam containing tool results, or null if no tools need to be executed
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* const toolResponse = await runner.generateToolResponse();
|
|
247
|
+
* if (toolResponse) {
|
|
248
|
+
* console.log('Tool results:', toolResponse.content);
|
|
249
|
+
* }
|
|
250
|
+
*/
|
|
251
|
+
async generateToolResponse(signal = this.#options.signal) {
|
|
252
|
+
const message = (await this.#message) ?? this.params.messages.at(-1);
|
|
253
|
+
if (!message) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
return this.#generateToolResponse(message, signal);
|
|
257
|
+
}
|
|
258
|
+
async #generateToolResponse(lastMessage, signal = this.#options.signal) {
|
|
259
|
+
if (this.#toolResponse !== undefined) {
|
|
260
|
+
return this.#toolResponse;
|
|
261
|
+
}
|
|
262
|
+
this.#toolResponse = generateToolResponse(this.#state.params, lastMessage, {
|
|
263
|
+
...this.#options,
|
|
264
|
+
signal,
|
|
265
|
+
});
|
|
266
|
+
return this.#toolResponse;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Wait for the async iterator to complete. This works even if the async iterator hasn't yet started, and
|
|
270
|
+
* will wait for an instance to start and go to completion.
|
|
271
|
+
*
|
|
272
|
+
* @returns A promise that resolves to the final BetaMessage when the iterator completes
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* // Start consuming the iterator
|
|
276
|
+
* for await (const message of runner) {
|
|
277
|
+
* console.log('Message:', message.content);
|
|
278
|
+
* }
|
|
279
|
+
*
|
|
280
|
+
* // Meanwhile, wait for completion from another part of the code
|
|
281
|
+
* const finalMessage = await runner.done();
|
|
282
|
+
* console.log('Final response:', finalMessage.content);
|
|
283
|
+
*/
|
|
284
|
+
done() {
|
|
285
|
+
return this.#completion.promise;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Returns a promise indicating that the stream is done. Unlike .done(), this will eagerly read the stream:
|
|
289
|
+
* * If the iterator has not been consumed, consume the entire iterator and return the final message from the
|
|
290
|
+
* assistant.
|
|
291
|
+
* * If the iterator has been consumed, waits for it to complete and returns the final message.
|
|
292
|
+
*
|
|
293
|
+
* @returns A promise that resolves to the final BetaMessage from the conversation
|
|
294
|
+
* @throws {PukuError} If no messages were processed during the conversation
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* const finalMessage = await runner.runUntilDone();
|
|
298
|
+
* console.log('Final response:', finalMessage.content);
|
|
299
|
+
*/
|
|
300
|
+
async runUntilDone() {
|
|
301
|
+
// If not yet consumed, start consuming and wait for completion
|
|
302
|
+
if (!this.#consumed) {
|
|
303
|
+
for await (const _ of this) {
|
|
304
|
+
// Iterator naturally populates this.#message
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// If consumed but not completed, wait for completion
|
|
308
|
+
return this.done();
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get the current parameters being used by the ToolRunner.
|
|
312
|
+
*
|
|
313
|
+
* @returns A readonly view of the current ToolRunnerParams
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* const currentParams = runner.params;
|
|
317
|
+
* console.log('Current model:', currentParams.model);
|
|
318
|
+
* console.log('Message count:', currentParams.messages.length);
|
|
319
|
+
*/
|
|
320
|
+
get params() {
|
|
321
|
+
return this.#state.params;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Add one or more messages to the conversation history.
|
|
325
|
+
*
|
|
326
|
+
* @param messages - One or more BetaMessageParam objects to add to the conversation
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* runner.pushMessages(
|
|
330
|
+
* { role: 'user', content: 'Also, what about the weather in NYC?' }
|
|
331
|
+
* );
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* // Adding multiple messages
|
|
335
|
+
* runner.pushMessages(
|
|
336
|
+
* { role: 'user', content: 'What about NYC?' },
|
|
337
|
+
* { role: 'user', content: 'And Boston?' }
|
|
338
|
+
* );
|
|
339
|
+
*/
|
|
340
|
+
pushMessages(...messages) {
|
|
341
|
+
this.setMessagesParams((params) => ({
|
|
342
|
+
...params,
|
|
343
|
+
messages: [...params.messages, ...messages],
|
|
344
|
+
}));
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Makes the ToolRunner directly awaitable, equivalent to calling .runUntilDone()
|
|
348
|
+
* This allows using `await runner` instead of `await runner.runUntilDone()`
|
|
349
|
+
*/
|
|
350
|
+
then(onfulfilled, onrejected) {
|
|
351
|
+
return this.runUntilDone().then(onfulfilled, onrejected);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
exports.BetaToolRunner = BetaToolRunner;
|
|
355
|
+
async function generateToolResponse(params, lastMessage = params.messages.at(-1), requestOptions) {
|
|
356
|
+
// Only process if the last message is from the assistant and has tool use blocks
|
|
357
|
+
if (!lastMessage ||
|
|
358
|
+
lastMessage.role !== 'assistant' ||
|
|
359
|
+
!lastMessage.content ||
|
|
360
|
+
typeof lastMessage.content === 'string') {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
const toolUseBlocks = lastMessage.content.filter((content) => content.type === 'tool_use');
|
|
364
|
+
if (toolUseBlocks.length === 0) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
const available = availableToolNames(params);
|
|
368
|
+
const toolResults = await Promise.all(toolUseBlocks.map(async (toolUse) => {
|
|
369
|
+
const tool = params.tools.find((t) => ('name' in t ? t.name
|
|
370
|
+
: 'mcp_server_name' in t ? t.mcp_server_name
|
|
371
|
+
: t.type) === toolUse.name);
|
|
372
|
+
// A `tool_removal` is only a hint to the model, which may still emit a tool_use for a
|
|
373
|
+
// withdrawn tool — treat those exactly like a tool that was never defined.
|
|
374
|
+
if (!tool || !('run' in tool) || !available.has(toolUse.name)) {
|
|
375
|
+
return toolNotFoundResult(toolUse);
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
let input = toolUse.input;
|
|
379
|
+
if ('parse' in tool && tool.parse) {
|
|
380
|
+
input = tool.parse(input);
|
|
381
|
+
}
|
|
382
|
+
const result = await tool.run(input, {
|
|
383
|
+
toolUse: toolUse,
|
|
384
|
+
toolUseBlock: toolUse,
|
|
385
|
+
signal: requestOptions?.signal,
|
|
386
|
+
});
|
|
387
|
+
return {
|
|
388
|
+
type: 'tool_result',
|
|
389
|
+
tool_use_id: toolUse.id,
|
|
390
|
+
content: result,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
return {
|
|
395
|
+
type: 'tool_result',
|
|
396
|
+
tool_use_id: toolUse.id,
|
|
397
|
+
content: error instanceof ToolError_1.ToolError ?
|
|
398
|
+
error.content
|
|
399
|
+
: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
400
|
+
is_error: true,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
}));
|
|
404
|
+
return {
|
|
405
|
+
role: 'user',
|
|
406
|
+
content: toolResults,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function toolNotFoundResult(toolUse) {
|
|
410
|
+
return {
|
|
411
|
+
type: 'tool_result',
|
|
412
|
+
tool_use_id: toolUse.id,
|
|
413
|
+
content: `Error: Tool '${toolUse.name}' not found`,
|
|
414
|
+
is_error: true,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Computes the names of locally runnable tools that are still available for the assistant
|
|
419
|
+
* turn being answered, by folding `tool_removal` / `tool_addition` blocks from the
|
|
420
|
+
* `role: "system"` messages over the runnable tools. The assistant turn being answered is
|
|
421
|
+
* terminal-or-absent and only `system` messages are inspected, so folding the whole current
|
|
422
|
+
* history is exactly folding the messages preceding that turn — call this before appending
|
|
423
|
+
* anything after it. MCP references are ignored — those tools are executed server-side and
|
|
424
|
+
* never dispatched by this runner.
|
|
425
|
+
*/
|
|
426
|
+
function availableToolNames(params) {
|
|
427
|
+
const available = new Set();
|
|
428
|
+
for (const tool of params.tools) {
|
|
429
|
+
if ('run' in tool) {
|
|
430
|
+
available.add(tool.name);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
for (const message of params.messages) {
|
|
434
|
+
if (message.role !== 'system' || typeof message.content === 'string') {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
for (const block of message.content) {
|
|
438
|
+
applyToolChange(block, available);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return available;
|
|
442
|
+
}
|
|
443
|
+
function applyToolChange(block, available) {
|
|
444
|
+
switch (block.type) {
|
|
445
|
+
case 'tool_removal':
|
|
446
|
+
case 'tool_addition':
|
|
447
|
+
applyToolReference(block, available);
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function applyToolReference(block, available) {
|
|
452
|
+
const name = referencedToolName(block.tool);
|
|
453
|
+
if (name === undefined)
|
|
454
|
+
return;
|
|
455
|
+
if (block.type === 'tool_removal') {
|
|
456
|
+
available.delete(name);
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
available.add(name);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function referencedToolName(ref) {
|
|
463
|
+
switch (ref.type) {
|
|
464
|
+
case 'tool_reference':
|
|
465
|
+
return ref.name;
|
|
466
|
+
default:
|
|
467
|
+
// mcp_tool_reference / mcp_toolset_reference run server-side; unknown reference
|
|
468
|
+
// types are ignored rather than rejected.
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Sorts every stop reason into one of three buckets: `run_tools` turns run their client tool
|
|
474
|
+
* calls and continue the loop; `resume` turns are sent back unchanged so the server continues
|
|
475
|
+
* them; `stop` turns end the loop without running any tool calls.
|
|
476
|
+
*/
|
|
477
|
+
function determineNextStepFromStopReason(stopReason) {
|
|
478
|
+
if (stopReason === null)
|
|
479
|
+
return 'stop';
|
|
480
|
+
switch (stopReason) {
|
|
481
|
+
case 'tool_use':
|
|
482
|
+
return 'run_tools';
|
|
483
|
+
case 'pause_turn':
|
|
484
|
+
// pause_after_compaction hands the turn back before the model answers; sending it back
|
|
485
|
+
// unchanged continues it.
|
|
486
|
+
case 'compaction':
|
|
487
|
+
return 'resume';
|
|
488
|
+
case 'end_turn':
|
|
489
|
+
case 'stop_sequence':
|
|
490
|
+
case 'max_tokens':
|
|
491
|
+
case 'model_context_window_exceeded':
|
|
492
|
+
case 'refusal':
|
|
493
|
+
return 'stop';
|
|
494
|
+
default:
|
|
495
|
+
// The union is forward-compatible, so a stop reason this SDK doesn't know yet ends the
|
|
496
|
+
// loop rather than throwing; the `never` check makes tsc reject an unclassified member.
|
|
497
|
+
(0, values_1.checkNever)(stopReason);
|
|
498
|
+
return 'stop';
|
|
499
|
+
}
|
|
500
|
+
}
|