@lowire/loop 0.0.1 → 0.0.3
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/LICENSE +201 -0
- package/README.md +1 -0
- package/githubAuth.js +17 -0
- package/index.d.ts +19 -0
- package/index.js +18 -0
- package/index.mjs +18 -0
- package/lib/auth/githubAuth.d.ts +16 -0
- package/lib/auth/githubAuth.js +81 -0
- package/lib/cache.d.ts +23 -0
- package/lib/cache.js +57 -0
- package/lib/jsx/jsx-runtime.d.ts +17 -0
- package/lib/jsx/jsx-runtime.js +33 -0
- package/lib/loop.d.ts +38 -0
- package/lib/loop.js +138 -0
- package/lib/mcp/index.d.ts +34 -0
- package/lib/mcp/index.js +109 -0
- package/lib/providers/anthropic.d.ts +23 -0
- package/lib/providers/anthropic.js +195 -0
- package/lib/providers/github.d.ts +33 -0
- package/lib/providers/github.js +229 -0
- package/lib/providers/google.d.ts +23 -0
- package/lib/providers/google.js +204 -0
- package/lib/providers/openai.d.ts +23 -0
- package/lib/providers/openai.js +186 -0
- package/lib/providers/registry.d.ts +17 -0
- package/lib/providers/registry.js +33 -0
- package/lib/summary.d.ts +20 -0
- package/lib/summary.js +56 -0
- package/lib/types.d.ts +114 -0
- package/lib/types.js +17 -0
- package/package.json +21 -7
package/lib/loop.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.Loop = void 0;
|
|
19
|
+
const registry_1 = require("./providers/registry");
|
|
20
|
+
const cache_1 = require("./cache");
|
|
21
|
+
const summary_1 = require("./summary");
|
|
22
|
+
class Loop {
|
|
23
|
+
_provider;
|
|
24
|
+
_loopOptions;
|
|
25
|
+
_cacheOutput = {};
|
|
26
|
+
constructor(loopName, options) {
|
|
27
|
+
this._provider = (0, registry_1.getProvider)(loopName);
|
|
28
|
+
this._loopOptions = options;
|
|
29
|
+
}
|
|
30
|
+
async run(task, runOptions = {}) {
|
|
31
|
+
const options = { ...this._loopOptions, ...runOptions };
|
|
32
|
+
const allTools = [...options.tools || []];
|
|
33
|
+
allTools.push({
|
|
34
|
+
name: 'report_result',
|
|
35
|
+
description: 'Report the result of the task.',
|
|
36
|
+
inputSchema: options.resultSchema ?? defaultResultSchema,
|
|
37
|
+
});
|
|
38
|
+
const conversation = {
|
|
39
|
+
systemPrompt,
|
|
40
|
+
messages: [
|
|
41
|
+
{ role: 'user', content: task },
|
|
42
|
+
],
|
|
43
|
+
tools: allTools,
|
|
44
|
+
};
|
|
45
|
+
const debug = options.debug;
|
|
46
|
+
const totalUsage = { input: 0, output: 0 };
|
|
47
|
+
debug?.('lowire:loop')(`Starting ${this._provider.name} loop`, task);
|
|
48
|
+
const maxTurns = options.maxTurns || 100;
|
|
49
|
+
for (let turn = 0; turn < maxTurns; ++turn) {
|
|
50
|
+
debug?.('lowire:loop')(`Turn ${turn + 1} of (max ${maxTurns})`);
|
|
51
|
+
const caches = options.cache ? {
|
|
52
|
+
input: options.cache.messages,
|
|
53
|
+
output: this._cacheOutput,
|
|
54
|
+
secrets: options.cache.secrets
|
|
55
|
+
} : undefined;
|
|
56
|
+
const summarizedConversation = options.summarize ? this._summarizeConversation(task, conversation, options) : conversation;
|
|
57
|
+
debug?.('lowire:loop')(`Request`, JSON.stringify({ ...summarizedConversation, tools: `${summarizedConversation.tools.length} tools` }, null, 2));
|
|
58
|
+
const { result: assistantMessage, usage } = await (0, cache_1.cachedComplete)(this._provider, summarizedConversation, caches, options);
|
|
59
|
+
const text = assistantMessage.content.filter(part => part.type === 'text').map(part => part.text).join('\n');
|
|
60
|
+
debug?.('lowire:loop')('Usage', `input: ${usage.input}, output: ${usage.output}`);
|
|
61
|
+
debug?.('lowire:loop')('Assistant', text, JSON.stringify(assistantMessage.content, null, 2));
|
|
62
|
+
totalUsage.input += usage.input;
|
|
63
|
+
totalUsage.output += usage.output;
|
|
64
|
+
conversation.messages.push(assistantMessage);
|
|
65
|
+
const toolCalls = assistantMessage.content.filter(part => part.type === 'tool_call');
|
|
66
|
+
if (toolCalls.length === 0) {
|
|
67
|
+
assistantMessage.toolError = 'Error: tool call is expected in every assistant message. Call the "report_result" tool when the task is complete.';
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
for (const toolCall of toolCalls) {
|
|
71
|
+
const { name, arguments: args } = toolCall;
|
|
72
|
+
debug?.('lowire:loop')('Call tool', name, JSON.stringify(args, null, 2));
|
|
73
|
+
if (name === 'report_result')
|
|
74
|
+
return args;
|
|
75
|
+
try {
|
|
76
|
+
const result = await options.callTool({
|
|
77
|
+
name,
|
|
78
|
+
arguments: {
|
|
79
|
+
...args,
|
|
80
|
+
_meta: {
|
|
81
|
+
'dev.lowire/history': true,
|
|
82
|
+
'dev.lowire/state': true,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const text = result.content.filter(part => part.type === 'text').map(part => part.text).join('\n');
|
|
87
|
+
debug?.('lowire:loop')('Tool result', text, JSON.stringify(result, null, 2));
|
|
88
|
+
toolCall.result = result;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const errorMessage = `Error while executing tool "${name}": ${error instanceof Error ? error.message : String(error)}\n\nPlease try to recover and complete the task.`;
|
|
92
|
+
debug?.('lowire:loop')('Tool error', errorMessage, String(error));
|
|
93
|
+
toolCall.result = {
|
|
94
|
+
content: [{ type: 'text', text: errorMessage }],
|
|
95
|
+
isError: true,
|
|
96
|
+
};
|
|
97
|
+
// Skip remaining tool calls for this iteration
|
|
98
|
+
for (const remainingToolCall of toolCalls.slice(toolCalls.indexOf(toolCall) + 1)) {
|
|
99
|
+
remainingToolCall.result = {
|
|
100
|
+
content: [{ type: 'text', text: `This tool call is skipped due to previous error.` }],
|
|
101
|
+
isError: true,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (options.summarize)
|
|
109
|
+
return this._summarizeConversation(task, conversation, options);
|
|
110
|
+
throw new Error('Failed to perform step, max attempts reached');
|
|
111
|
+
}
|
|
112
|
+
_summarizeConversation(task, conversation, options) {
|
|
113
|
+
const { summary, lastMessage } = (0, summary_1.summarizeConversation)(task, conversation, options);
|
|
114
|
+
return {
|
|
115
|
+
...conversation,
|
|
116
|
+
messages: [
|
|
117
|
+
{ role: 'user', content: summary },
|
|
118
|
+
...lastMessage ? [lastMessage] : [],
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
cache() {
|
|
123
|
+
return this._cacheOutput;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.Loop = Loop;
|
|
127
|
+
const defaultResultSchema = {
|
|
128
|
+
type: 'object',
|
|
129
|
+
properties: {
|
|
130
|
+
result: {
|
|
131
|
+
type: 'string',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
required: ['result'],
|
|
135
|
+
};
|
|
136
|
+
const systemPrompt = `
|
|
137
|
+
You are an autonomous agent designed to complete tasks by interacting with tools. Perform the user task.
|
|
138
|
+
`;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type * as types from '../types';
|
|
17
|
+
export type McpServer = {
|
|
18
|
+
command: string;
|
|
19
|
+
args?: string[];
|
|
20
|
+
cwd?: string;
|
|
21
|
+
stderr?: 'pipe' | 'inherit' | 'ignore';
|
|
22
|
+
env?: Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
type ToolFilter = (string | RegExp)[];
|
|
25
|
+
type ToolSupport = {
|
|
26
|
+
close: () => Promise<void>;
|
|
27
|
+
tools: types.Tool[];
|
|
28
|
+
callTool: types.ToolCallback;
|
|
29
|
+
};
|
|
30
|
+
export declare function createMcpTools(servers: Record<string, McpServer>, options?: {
|
|
31
|
+
rootDir?: string;
|
|
32
|
+
toolFilter?: ToolFilter;
|
|
33
|
+
}): Promise<ToolSupport>;
|
|
34
|
+
export {};
|
package/lib/mcp/index.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
51
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
52
|
+
};
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.createMcpTools = createMcpTools;
|
|
55
|
+
const url_1 = __importDefault(require("url"));
|
|
56
|
+
async function connectToMcpServer(server, options) {
|
|
57
|
+
const { Client } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/client/index.js')));
|
|
58
|
+
const { StdioClientTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/client/stdio.js')));
|
|
59
|
+
const { ListRootsRequestSchema } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
60
|
+
const transport = new StdioClientTransport(server);
|
|
61
|
+
const capabilities = {};
|
|
62
|
+
if (options?.rootDir)
|
|
63
|
+
capabilities['roots'] = {};
|
|
64
|
+
const client = new Client({ name: 'test', version: '1.0.0' }, { capabilities });
|
|
65
|
+
if (options?.rootDir) {
|
|
66
|
+
client.setRequestHandler(ListRootsRequestSchema, async () => {
|
|
67
|
+
return {
|
|
68
|
+
roots: [{ name: 'workspace', uri: url_1.default.pathToFileURL(options.rootDir).toString() }],
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
await client.connect(transport);
|
|
73
|
+
return client;
|
|
74
|
+
}
|
|
75
|
+
async function mcpTools(server, options) {
|
|
76
|
+
const client = await connectToMcpServer(server, options);
|
|
77
|
+
const { tools } = await client.listTools();
|
|
78
|
+
const filteredTools = options?.toolFilter ? tools.filter(tool => options.toolFilter.some(filter => typeof filter === 'string' ? tool.name === filter : filter.test(tool.name))) : tools;
|
|
79
|
+
const callTool = async (params) => {
|
|
80
|
+
return await client.callTool({ name: params.name, arguments: params.arguments });
|
|
81
|
+
};
|
|
82
|
+
return { tools: filteredTools, callTool, close: () => client.close() };
|
|
83
|
+
}
|
|
84
|
+
async function createMcpTools(servers, options) {
|
|
85
|
+
const allTools = [];
|
|
86
|
+
const callTools = new Map();
|
|
87
|
+
const closes = [];
|
|
88
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
89
|
+
const { tools, callTool, close } = await mcpTools(server, options);
|
|
90
|
+
for (const tool of tools) {
|
|
91
|
+
const fullName = `${name}__${tool.name}`;
|
|
92
|
+
allTools.push({ ...tool, name: fullName });
|
|
93
|
+
callTools.set(fullName, params => callTool({ name: tool.name, arguments: params.arguments }));
|
|
94
|
+
}
|
|
95
|
+
closes.push(close);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
close: async () => {
|
|
99
|
+
await Promise.all(closes.map(c => c()));
|
|
100
|
+
},
|
|
101
|
+
tools: allTools,
|
|
102
|
+
callTool: async (params) => {
|
|
103
|
+
const callTool = callTools.get(params.name);
|
|
104
|
+
if (!callTool)
|
|
105
|
+
throw new Error(`Tool not found: ${params.name}`);
|
|
106
|
+
return callTool(params);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type * as types from '../types';
|
|
17
|
+
export declare class Anthropic implements types.Provider {
|
|
18
|
+
readonly name = "anthropic";
|
|
19
|
+
complete(conversation: types.Conversation, options: types.CompletionOptions): Promise<{
|
|
20
|
+
result: types.AssistantMessage;
|
|
21
|
+
usage: types.Usage;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Microsoft Corporation.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.Anthropic = void 0;
|
|
19
|
+
class Anthropic {
|
|
20
|
+
name = 'anthropic';
|
|
21
|
+
async complete(conversation, options) {
|
|
22
|
+
const response = await create({
|
|
23
|
+
model: options.model,
|
|
24
|
+
max_tokens: options.maxTokens ?? 32768,
|
|
25
|
+
temperature: options.temperature,
|
|
26
|
+
system: systemPrompt(conversation.systemPrompt),
|
|
27
|
+
messages: conversation.messages.map(toAnthropicMessageParts).flat(),
|
|
28
|
+
tools: conversation.tools.map(toAnthropicTool),
|
|
29
|
+
thinking: options.reasoning ? {
|
|
30
|
+
type: 'enabled',
|
|
31
|
+
budget_tokens: options.maxTokens ? Math.round(options.maxTokens / 10) : 1024,
|
|
32
|
+
} : undefined,
|
|
33
|
+
}, options);
|
|
34
|
+
const result = toAssistantMessage(response);
|
|
35
|
+
const usage = {
|
|
36
|
+
input: response.usage.input_tokens,
|
|
37
|
+
output: response.usage.output_tokens,
|
|
38
|
+
};
|
|
39
|
+
return { result, usage };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.Anthropic = Anthropic;
|
|
43
|
+
async function create(createParams, options) {
|
|
44
|
+
const headers = {
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
'x-api-key': process.env.ANTHROPIC_API_KEY,
|
|
47
|
+
'anthropic-version': '2023-06-01',
|
|
48
|
+
};
|
|
49
|
+
const debugBody = { ...createParams, tools: `${createParams.tools?.length ?? 0} tools` };
|
|
50
|
+
options.debug?.('lowire:anthropic')('Request:', JSON.stringify(debugBody, null, 2));
|
|
51
|
+
const response = await fetch(`https://api.anthropic.com/v1/messages`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers,
|
|
54
|
+
body: JSON.stringify(createParams)
|
|
55
|
+
});
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
options.debug?.('lowire:anthropic')('Response:', response.status);
|
|
58
|
+
throw new Error(`API error: ${response.status} ${response.statusText} ${await response.text()}`);
|
|
59
|
+
}
|
|
60
|
+
const responseBody = await response.json();
|
|
61
|
+
options.debug?.('lowire:anthropic')('Response:', JSON.stringify(responseBody, null, 2));
|
|
62
|
+
return responseBody;
|
|
63
|
+
}
|
|
64
|
+
function toContentPart(block) {
|
|
65
|
+
if (block.type === 'text') {
|
|
66
|
+
return {
|
|
67
|
+
type: 'text',
|
|
68
|
+
text: block.text,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (block.type === 'tool_use') {
|
|
72
|
+
return {
|
|
73
|
+
type: 'tool_call',
|
|
74
|
+
name: block.name,
|
|
75
|
+
arguments: block.input,
|
|
76
|
+
id: block.id,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (block.type === 'thinking') {
|
|
80
|
+
return {
|
|
81
|
+
type: 'thinking',
|
|
82
|
+
thinking: block.thinking,
|
|
83
|
+
signature: block.signature,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
function toAnthropicResultParam(part) {
|
|
89
|
+
if (part.type === 'text') {
|
|
90
|
+
return {
|
|
91
|
+
type: 'text',
|
|
92
|
+
text: part.text,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (part.type === 'image') {
|
|
96
|
+
return {
|
|
97
|
+
type: 'image',
|
|
98
|
+
source: {
|
|
99
|
+
type: 'base64',
|
|
100
|
+
data: part.data,
|
|
101
|
+
media_type: part.mimeType
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`Unsupported content part type: ${part.type}`);
|
|
106
|
+
}
|
|
107
|
+
function toAssistantMessage(message) {
|
|
108
|
+
return {
|
|
109
|
+
role: 'assistant',
|
|
110
|
+
content: message.content.map(toContentPart).filter(Boolean),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function toAnthropicTool(tool) {
|
|
114
|
+
return {
|
|
115
|
+
name: tool.name,
|
|
116
|
+
description: tool.description,
|
|
117
|
+
input_schema: tool.inputSchema,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function toAnthropicAssistantMessageParam(message) {
|
|
121
|
+
const content = [];
|
|
122
|
+
const toolResults = [];
|
|
123
|
+
for (const part of message.content) {
|
|
124
|
+
if (part.type === 'text') {
|
|
125
|
+
content.push({ ...part, citations: [] });
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (part.type === 'tool_call') {
|
|
129
|
+
content.push({
|
|
130
|
+
type: 'tool_use',
|
|
131
|
+
id: part.id,
|
|
132
|
+
name: part.name,
|
|
133
|
+
input: part.arguments
|
|
134
|
+
});
|
|
135
|
+
if (part.result)
|
|
136
|
+
toolResults.push(toAnthropicToolResultMessage(part, part.result));
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (part.type === 'thinking') {
|
|
140
|
+
content.push({
|
|
141
|
+
type: 'thinking',
|
|
142
|
+
thinking: part.thinking,
|
|
143
|
+
signature: part.signature,
|
|
144
|
+
});
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (message.toolError) {
|
|
149
|
+
toolResults.push({
|
|
150
|
+
role: 'user',
|
|
151
|
+
content: [{
|
|
152
|
+
type: 'text',
|
|
153
|
+
text: message.toolError,
|
|
154
|
+
}]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return [{
|
|
158
|
+
role: 'assistant',
|
|
159
|
+
content
|
|
160
|
+
}, ...toolResults];
|
|
161
|
+
}
|
|
162
|
+
function toAnthropicToolResultMessage(call, result) {
|
|
163
|
+
const toolResult = {
|
|
164
|
+
type: 'tool_result',
|
|
165
|
+
tool_use_id: call.id,
|
|
166
|
+
content: result.content.map(toAnthropicResultParam),
|
|
167
|
+
is_error: result.isError,
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
role: 'user',
|
|
171
|
+
content: [toolResult]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function toAnthropicMessageParts(message) {
|
|
175
|
+
if (message.role === 'user') {
|
|
176
|
+
return [{
|
|
177
|
+
role: 'user',
|
|
178
|
+
content: message.content
|
|
179
|
+
}];
|
|
180
|
+
}
|
|
181
|
+
if (message.role === 'assistant')
|
|
182
|
+
return toAnthropicAssistantMessageParam(message);
|
|
183
|
+
throw new Error(`Unsupported message role: ${message.role}`);
|
|
184
|
+
}
|
|
185
|
+
const systemPrompt = (prompt) => `
|
|
186
|
+
### System instructions
|
|
187
|
+
|
|
188
|
+
${prompt}
|
|
189
|
+
|
|
190
|
+
### Tool calling instructions
|
|
191
|
+
- Make sure every message contains a tool call.
|
|
192
|
+
- When you use a tool, you may provide a brief thought or explanation in the content field
|
|
193
|
+
immediately before the tool_call. Do not split this into separate messages.
|
|
194
|
+
- Every reply must include a tool call.
|
|
195
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type * as types from '../types';
|
|
17
|
+
export declare class Github implements types.Provider {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
private _apiKey;
|
|
20
|
+
private _bearer;
|
|
21
|
+
complete(conversation: types.Conversation, options: types.CompletionOptions): Promise<{
|
|
22
|
+
result: types.AssistantMessage;
|
|
23
|
+
usage: types.Usage;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export declare const kEditorHeaders: {
|
|
27
|
+
'Editor-Version': string;
|
|
28
|
+
'Editor-Plugin-Version': string;
|
|
29
|
+
'User-Agent': string;
|
|
30
|
+
Accept: string;
|
|
31
|
+
'Content-Type': string;
|
|
32
|
+
'Copilot-Vision-Request': string;
|
|
33
|
+
};
|