ydc-agent 1.0.0

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.
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Advanced Agent Version System
3
+ * Provides specialized configurations for different use cases
4
+ */
5
+
6
+ export const ADVANCED_VERSIONS = {
7
+ 'advanced-1.0-medium': {
8
+ verbosity: 'medium',
9
+ max_workflow_steps: 1,
10
+ timeout: 120000,
11
+ tools: []
12
+ },
13
+ 'advanced-1.0-high': {
14
+ verbosity: 'high',
15
+ max_workflow_steps: 1,
16
+ timeout: 120000,
17
+ tools: []
18
+ },
19
+ 'advanced-2.0-medium': {
20
+ verbosity: 'medium',
21
+ max_workflow_steps: 2,
22
+ timeout: 180000,
23
+ tools: []
24
+ },
25
+ 'advanced-2.0-high': {
26
+ verbosity: 'high',
27
+ max_workflow_steps: 2,
28
+ timeout: 180000,
29
+ tools: []
30
+ },
31
+ 'advanced-3.0-medium': {
32
+ verbosity: 'medium',
33
+ max_workflow_steps: 5,
34
+ timeout: 180000,
35
+ tools: [{ type: 'compute' }]
36
+ },
37
+ 'advanced-3.0-high': {
38
+ verbosity: 'high',
39
+ max_workflow_steps: 5,
40
+ timeout: 180000,
41
+ tools: [{ type: 'compute' }]
42
+ },
43
+ 'advanced-4.0-medium': {
44
+ verbosity: 'medium',
45
+ max_workflow_steps: 6,
46
+ timeout: 180000,
47
+ tools: [{ type: 'research', search_effort: 'medium', report_verbosity: 'medium' }]
48
+ },
49
+ 'advanced-4.0-high': {
50
+ verbosity: 'high',
51
+ max_workflow_steps: 6,
52
+ timeout: 180000,
53
+ tools: [{ type: 'research', search_effort: 'high', report_verbosity: 'high' }]
54
+ },
55
+ 'advanced-4.5-medium-research': {
56
+ verbosity: 'medium',
57
+ max_workflow_steps: 9,
58
+ timeout: 300000,
59
+ tools: [
60
+ { type: 'compute' },
61
+ { type: 'research', search_effort: 'medium', report_verbosity: 'medium' }
62
+ ]
63
+ },
64
+ 'advanced-4.5-high-research': {
65
+ verbosity: 'high',
66
+ max_workflow_steps: 9,
67
+ timeout: 300000,
68
+ tools: [
69
+ { type: 'compute' },
70
+ { type: 'research', search_effort: 'high', report_verbosity: 'high' }
71
+ ]
72
+ }
73
+ };
74
+
75
+ export function getAdvancedVersion(versionName) {
76
+ return ADVANCED_VERSIONS[versionName] || null;
77
+ }
78
+
79
+ export function isAdvancedVersion(modelName) {
80
+ return modelName in ADVANCED_VERSIONS;
81
+ }
82
+
83
+ export function getDefaultAdvancedVersion(temperature = 0.7) {
84
+ return temperature <= 0.5 ? 'advanced-3.0-medium' : 'advanced-3.0-high';
85
+ }
86
+
87
+ export function adjustWorkflowSteps(baseSteps, temperature) {
88
+ const adjustment = Math.round((temperature - 0.5) * 4);
89
+ return Math.max(1, Math.min(20, baseSteps + adjustment));
90
+ }
91
+
92
+ export function listAdvancedVersions() {
93
+ return Object.keys(ADVANCED_VERSIONS);
94
+ }
95
+
96
+ export function getVersionInfo(versionName) {
97
+ const config = ADVANCED_VERSIONS[versionName];
98
+ if (!config) return null;
99
+
100
+ const toolNames = config.tools.map(t => {
101
+ if (t.type === 'research') return `research(${t.search_effort})`;
102
+ return t.type;
103
+ }).join(', ') || 'none';
104
+
105
+ return {
106
+ name: versionName,
107
+ verbosity: config.verbosity,
108
+ max_workflow_steps: config.max_workflow_steps,
109
+ timeout_seconds: config.timeout / 1000,
110
+ tools: toolNames,
111
+ description: `${config.verbosity} verbosity, ${config.max_workflow_steps} steps, ${config.timeout/1000}s timeout`
112
+ };
113
+ }
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Anthropic/Claude Parameter Mapper Module
3
+ * Maps Anthropic API parameters to You.com API parameters
4
+ */
5
+
6
+ import {
7
+ getAdvancedVersion,
8
+ isAdvancedVersion,
9
+ getDefaultAdvancedVersion,
10
+ adjustWorkflowSteps
11
+ } from './advanced-versions.js';
12
+
13
+ /**
14
+ * Map Anthropic request parameters to You.com parameters
15
+ */
16
+ export function mapAnthropicToYouParams(anthropicRequest) {
17
+ const {
18
+ model = 'advanced-3.0-high',
19
+ messages,
20
+ system,
21
+ temperature = 0.7,
22
+ max_tokens = 1024,
23
+ stream = false
24
+ } = anthropicRequest;
25
+
26
+ let input = '';
27
+ const conversationHistory = [];
28
+
29
+ // Handle system prompt
30
+ if (system) {
31
+ input = `[System Instructions]\n${system}\n\n`;
32
+ }
33
+
34
+ // Process messages
35
+ messages.forEach(msg => {
36
+ if (msg.role === 'user') {
37
+ // Handle content as string or array
38
+ const content = typeof msg.content === 'string'
39
+ ? msg.content
40
+ : msg.content.filter(c => c.type === 'text').map(c => c.text).join('\n');
41
+ conversationHistory.push(`User: ${content}`);
42
+ } else if (msg.role === 'assistant') {
43
+ const content = typeof msg.content === 'string'
44
+ ? msg.content
45
+ : msg.content.filter(c => c.type === 'text').map(c => c.text).join('\n');
46
+ conversationHistory.push(`Assistant: ${content}`);
47
+ }
48
+ });
49
+
50
+ if (conversationHistory.length > 1) {
51
+ input += `[Conversation History]\n${conversationHistory.slice(0, -1).join('\n\n')}\n\n`;
52
+ input += `[Current Message]\n${conversationHistory[conversationHistory.length - 1].replace(/^User: /, '')}`;
53
+ } else if (conversationHistory.length === 1) {
54
+ input += conversationHistory[0].replace(/^User: /, '');
55
+ }
56
+
57
+ // Map model to You.com agent
58
+ const modelMapping = {
59
+ 'claude-3-opus-20240229': 'advanced-3.0-high',
60
+ 'claude-3-sonnet-20240229': 'advanced-3.0-medium',
61
+ 'claude-3-haiku-20240307': 'express',
62
+ 'claude-3-5-sonnet-20240620': 'advanced-3.0-high',
63
+ 'claude-3-5-sonnet-20241022': 'advanced-3.0-high',
64
+ 'claude-sonnet-4-20250514': 'advanced-3.0-high',
65
+ 'claude-sonnet-4-5-20250929': 'advanced-4.5-research'
66
+ };
67
+
68
+ const mappedModel = modelMapping[model] || model;
69
+
70
+ // Check if it's an advanced version model
71
+ if (isAdvancedVersion(mappedModel)) {
72
+ const versionConfig = getAdvancedVersion(mappedModel);
73
+ if (versionConfig) {
74
+ const adjustedSteps = adjustWorkflowSteps(versionConfig.max_workflow_steps, temperature);
75
+
76
+ return {
77
+ agent: 'advanced',
78
+ input,
79
+ stream,
80
+ verbosity: versionConfig.verbosity,
81
+ tools: versionConfig.tools,
82
+ workflow_config: {
83
+ max_workflow_steps: adjustedSteps
84
+ },
85
+ timeout: versionConfig.timeout
86
+ };
87
+ }
88
+ }
89
+
90
+ // Default handling
91
+ let agent = mappedModel;
92
+ let verbosity = 'medium';
93
+ let timeout = 300000;
94
+
95
+ if (temperature <= 0.3) verbosity = 'medium';
96
+ else if (temperature >= 0.8) verbosity = 'high';
97
+
98
+ const max_workflow_steps = Math.min(Math.max(Math.floor(max_tokens / 100), 1), 20);
99
+
100
+ const knownAgents = ['express', 'research', 'advanced'];
101
+ if (!knownAgents.includes(agent)) {
102
+ agent = 'advanced';
103
+ }
104
+
105
+ if (agent === 'advanced') {
106
+ timeout = 3000000;
107
+ }
108
+
109
+ return {
110
+ agent,
111
+ input,
112
+ stream,
113
+ verbosity,
114
+ tools: [
115
+ { type: 'research', search_effort: 'auto', report_verbosity: 'medium' },
116
+ { type: 'compute' }
117
+ ],
118
+ workflow_config: {
119
+ max_workflow_steps
120
+ },
121
+ timeout
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Convert You.com response to Anthropic format
127
+ */
128
+ export function convertToAnthropicResponse(youResponse, model, inputTokens = 100) {
129
+ const content = youResponse.output && Array.isArray(youResponse.output)
130
+ ? youResponse.output
131
+ .filter(item => item.type === 'message.answer')
132
+ .map(item => item.text)
133
+ .join('\n\n')
134
+ : 'No response content';
135
+
136
+ const outputTokens = Math.floor(content.length / 4);
137
+
138
+ return {
139
+ id: `msg_${Date.now()}`,
140
+ type: 'message',
141
+ role: 'assistant',
142
+ content: [
143
+ {
144
+ type: 'text',
145
+ text: content
146
+ }
147
+ ],
148
+ model: model,
149
+ stop_reason: 'end_turn',
150
+ stop_sequence: null,
151
+ usage: {
152
+ input_tokens: inputTokens,
153
+ output_tokens: outputTokens
154
+ }
155
+ };
156
+ }
157
+
158
+ /**
159
+ * Create streaming event in Anthropic format
160
+ */
161
+ export function createAnthropicStreamEvent(eventType, data) {
162
+ return `event: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`;
163
+ }
164
+
165
+ /**
166
+ * Create message_start event
167
+ */
168
+ export function createMessageStartEvent(model, conversationId = null) {
169
+ const message = {
170
+ id: `msg_${Date.now()}`,
171
+ type: 'message',
172
+ role: 'assistant',
173
+ content: [],
174
+ model: model,
175
+ stop_reason: null,
176
+ stop_sequence: null,
177
+ usage: {
178
+ input_tokens: 0,
179
+ output_tokens: 0
180
+ }
181
+ };
182
+
183
+ // Add conversation_id in metadata if provided
184
+ if (conversationId) {
185
+ message.metadata = { conversation_id: conversationId };
186
+ }
187
+
188
+ return createAnthropicStreamEvent('message_start', {
189
+ type: 'message_start',
190
+ message
191
+ });
192
+ }
193
+
194
+ /**
195
+ * Create content_block_start event
196
+ */
197
+ export function createContentBlockStartEvent(index = 0) {
198
+ return createAnthropicStreamEvent('content_block_start', {
199
+ type: 'content_block_start',
200
+ index: index,
201
+ content_block: {
202
+ type: 'text',
203
+ text: ''
204
+ }
205
+ });
206
+ }
207
+
208
+ /**
209
+ * Create content_block_delta event
210
+ */
211
+ export function createContentBlockDeltaEvent(text, index = 0) {
212
+ return createAnthropicStreamEvent('content_block_delta', {
213
+ type: 'content_block_delta',
214
+ index: index,
215
+ delta: {
216
+ type: 'text_delta',
217
+ text: text
218
+ }
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Create content_block_stop event
224
+ */
225
+ export function createContentBlockStopEvent(index = 0) {
226
+ return createAnthropicStreamEvent('content_block_stop', {
227
+ type: 'content_block_stop',
228
+ index: index
229
+ });
230
+ }
231
+
232
+ /**
233
+ * Create message_delta event
234
+ */
235
+ export function createMessageDeltaEvent(outputTokens = 0) {
236
+ return createAnthropicStreamEvent('message_delta', {
237
+ type: 'message_delta',
238
+ delta: {
239
+ stop_reason: 'end_turn',
240
+ stop_sequence: null
241
+ },
242
+ usage: {
243
+ output_tokens: outputTokens
244
+ }
245
+ });
246
+ }
247
+
248
+ /**
249
+ * Create message_stop event
250
+ */
251
+ export function createMessageStopEvent() {
252
+ return createAnthropicStreamEvent('message_stop', {
253
+ type: 'message_stop'
254
+ });
255
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * You.com API Client Module
3
+ * Shared API calling logic for MCP and OpenAI servers
4
+ */
5
+
6
+ const API_BASE = 'https://api.you.com/v1/agents/runs';
7
+
8
+ // Agent type configurations
9
+ export const AGENT_TYPES = {
10
+ 'express': { agent: 'express', description: 'Fast AI answers with web search (~2s, GPT-3 level)' },
11
+ 'research': { agent: 'research', description: 'In-depth research and analysis' },
12
+ 'advanced': { agent: 'advanced', description: 'Complex reasoning without tools (~10s, GPT-3.5 level)', tools: [] },
13
+ 'advanced-3.0-high': { agent: 'advanced', verbosity: 'high', max_workflow_steps: 15, tools: [] },
14
+ 'advanced-3.0-medium': { agent: 'advanced', verbosity: 'medium', max_workflow_steps: 10, tools: [] },
15
+ 'advanced-4.0-high': { agent: 'advanced', verbosity: 'high', max_workflow_steps: 20, tools: [{ type: 'compute' }] },
16
+ 'advanced-4.5-research': {
17
+ agent: 'advanced',
18
+ verbosity: 'high',
19
+ max_workflow_steps: 20,
20
+ tools: [{ type: 'research', search_effort: 'high', report_verbosity: 'high' }, { type: 'compute' }]
21
+ }
22
+ };
23
+
24
+ /**
25
+ * Call You.com API
26
+ */
27
+ export async function callYouApi(apiKey, requestBody, options = {}) {
28
+ const { timeout = 300000 } = options;
29
+
30
+ const controller = new AbortController();
31
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
32
+
33
+ try {
34
+ const response = await fetch(API_BASE, {
35
+ method: 'POST',
36
+ headers: {
37
+ 'Authorization': `Bearer ${apiKey}`,
38
+ 'Content-Type': 'application/json',
39
+ },
40
+ body: JSON.stringify(requestBody),
41
+ signal: controller.signal,
42
+ });
43
+
44
+ clearTimeout(timeoutId);
45
+
46
+ if (!response.ok) {
47
+ const errorText = await response.text();
48
+ throw new Error(`API error: ${response.status} ${errorText}`);
49
+ }
50
+
51
+ return response;
52
+ } catch (error) {
53
+ clearTimeout(timeoutId);
54
+ throw error;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Extract text from You.com response
60
+ */
61
+ export function extractText(data) {
62
+ if (data.output && Array.isArray(data.output)) {
63
+ return data.output
64
+ .filter(item => item.type === 'message.answer')
65
+ .map(item => item.text)
66
+ .join('\n\n');
67
+ }
68
+ return JSON.stringify(data, null, 2);
69
+ }
70
+
71
+ /**
72
+ * Build conversation input from messages
73
+ */
74
+ export function buildConversationInput(messages) {
75
+ let input = '';
76
+ let systemPrompt = '';
77
+ const conversationHistory = [];
78
+
79
+ messages.forEach(msg => {
80
+ if (msg.role === 'system') {
81
+ systemPrompt = msg.content;
82
+ } else if (msg.role === 'user') {
83
+ conversationHistory.push(`User: ${msg.content}`);
84
+ } else if (msg.role === 'assistant') {
85
+ conversationHistory.push(`Assistant: ${msg.content}`);
86
+ }
87
+ });
88
+
89
+ if (systemPrompt) {
90
+ input = `[System Instructions]\n${systemPrompt}\n\n`;
91
+ }
92
+
93
+ if (conversationHistory.length > 1) {
94
+ input += `[Conversation History]\n${conversationHistory.slice(0, -1).join('\n\n')}\n\n`;
95
+ input += `[Current Message]\n${conversationHistory[conversationHistory.length - 1].replace(/^User: /, '')}`;
96
+ } else if (conversationHistory.length === 1) {
97
+ input += conversationHistory[0].replace(/^User: /, '');
98
+ }
99
+
100
+ return input;
101
+ }
102
+
103
+ /**
104
+ * Build request body for agent call
105
+ */
106
+ export function buildAgentRequest(agentType, input, options = {}) {
107
+ const { tools, verbosity, max_workflow_steps, stream = false } = options;
108
+ const agentConfig = AGENT_TYPES[agentType] || AGENT_TYPES['advanced-3.0-high'];
109
+ const isExpressAgent = agentType === 'express' || agentConfig.agent === 'express';
110
+
111
+ if (isExpressAgent) {
112
+ return {
113
+ agent: 'express',
114
+ input,
115
+ stream,
116
+ };
117
+ }
118
+
119
+ // Use tools from options > agentConfig > empty array (no default tools)
120
+ const finalTools = tools !== undefined ? tools : (agentConfig.tools !== undefined ? agentConfig.tools : []);
121
+
122
+ const request = {
123
+ agent: agentConfig.agent || 'advanced',
124
+ input,
125
+ stream,
126
+ verbosity: verbosity || agentConfig.verbosity || 'high',
127
+ workflow_config: {
128
+ max_workflow_steps: max_workflow_steps || agentConfig.max_workflow_steps || 15
129
+ },
130
+ };
131
+
132
+ // Only add tools if not empty
133
+ if (finalTools.length > 0) {
134
+ request.tools = finalTools;
135
+ }
136
+
137
+ return request;
138
+ }
139
+
140
+ export { API_BASE };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Authentication Middleware Module
3
+ */
4
+
5
+ // Access token configuration
6
+ const ACCESS_TOKENS_RAW = process.env.YDC_OPENAI_ACCESS_TOKENS || '';
7
+ const ACCESS_TOKENS = ACCESS_TOKENS_RAW.split(',').map(t => t.trim()).filter(t => t);
8
+ const REQUIRE_TOKEN_AUTH = ACCESS_TOKENS.length > 0;
9
+
10
+ /**
11
+ * Authentication middleware for Express
12
+ */
13
+ export function authenticate(req, res, next) {
14
+ const authHeader = req.headers.authorization;
15
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
16
+ return res.status(401).json({
17
+ error: {
18
+ message: 'Invalid authentication credentials',
19
+ type: 'invalid_request_error',
20
+ code: 'invalid_api_key'
21
+ }
22
+ });
23
+ }
24
+
25
+ if (REQUIRE_TOKEN_AUTH) {
26
+ const token = authHeader.slice(7);
27
+ if (!ACCESS_TOKENS.includes(token)) {
28
+ return res.status(401).json({
29
+ error: {
30
+ message: 'Invalid access token',
31
+ type: 'invalid_request_error',
32
+ code: 'invalid_access_token'
33
+ }
34
+ });
35
+ }
36
+ }
37
+
38
+ next();
39
+ }
40
+
41
+ export const authConfig = {
42
+ REQUIRE_TOKEN_AUTH,
43
+ ACCESS_TOKENS_COUNT: ACCESS_TOKENS.length
44
+ };