agentic-api 2.0.646 → 2.0.885

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.
Files changed (59) hide show
  1. package/dist/src/agents/prompts.d.ts +2 -3
  2. package/dist/src/agents/prompts.js +21 -118
  3. package/dist/src/agents/reducer.loaders.d.ts +103 -1
  4. package/dist/src/agents/reducer.loaders.js +164 -2
  5. package/dist/src/agents/reducer.types.d.ts +34 -3
  6. package/dist/src/agents/simulator.d.ts +32 -2
  7. package/dist/src/agents/simulator.executor.d.ts +15 -5
  8. package/dist/src/agents/simulator.executor.js +134 -67
  9. package/dist/src/agents/simulator.js +251 -8
  10. package/dist/src/agents/simulator.prompts.d.ts +55 -10
  11. package/dist/src/agents/simulator.prompts.js +305 -61
  12. package/dist/src/agents/simulator.types.d.ts +62 -1
  13. package/dist/src/agents/simulator.types.js +5 -0
  14. package/dist/src/agents/subagent.d.ts +128 -0
  15. package/dist/src/agents/subagent.js +231 -0
  16. package/dist/src/agents/worker.executor.d.ts +48 -0
  17. package/dist/src/agents/worker.executor.js +152 -0
  18. package/dist/src/execute/helpers.d.ts +3 -0
  19. package/dist/src/execute/helpers.js +222 -16
  20. package/dist/src/execute/responses.js +81 -55
  21. package/dist/src/execute/shared.d.ts +5 -0
  22. package/dist/src/execute/shared.js +27 -0
  23. package/dist/src/index.d.ts +2 -1
  24. package/dist/src/index.js +3 -1
  25. package/dist/src/llm/openai.js +8 -1
  26. package/dist/src/llm/pricing.js +2 -0
  27. package/dist/src/llm/xai.js +11 -6
  28. package/dist/src/prompts.d.ts +14 -0
  29. package/dist/src/prompts.js +41 -1
  30. package/dist/src/rag/rag.manager.d.ts +18 -3
  31. package/dist/src/rag/rag.manager.js +114 -12
  32. package/dist/src/rag/types.d.ts +3 -1
  33. package/dist/src/rules/git/git.e2e.helper.js +51 -4
  34. package/dist/src/rules/git/git.health.js +89 -56
  35. package/dist/src/rules/git/index.d.ts +2 -2
  36. package/dist/src/rules/git/index.js +22 -5
  37. package/dist/src/rules/git/repo.d.ts +64 -6
  38. package/dist/src/rules/git/repo.js +572 -141
  39. package/dist/src/rules/git/repo.pr.d.ts +11 -18
  40. package/dist/src/rules/git/repo.pr.js +82 -94
  41. package/dist/src/rules/git/repo.tools.d.ts +5 -0
  42. package/dist/src/rules/git/repo.tools.js +6 -1
  43. package/dist/src/rules/types.d.ts +0 -2
  44. package/dist/src/rules/utils.matter.js +1 -5
  45. package/dist/src/scrapper.d.ts +138 -25
  46. package/dist/src/scrapper.js +538 -160
  47. package/dist/src/stategraph/stategraph.d.ts +6 -2
  48. package/dist/src/stategraph/stategraph.js +21 -6
  49. package/dist/src/stategraph/types.d.ts +14 -6
  50. package/dist/src/types.d.ts +22 -0
  51. package/dist/src/utils.d.ts +24 -0
  52. package/dist/src/utils.js +84 -86
  53. package/package.json +3 -2
  54. package/dist/src/agents/semantic.d.ts +0 -4
  55. package/dist/src/agents/semantic.js +0 -19
  56. package/dist/src/execute/legacy.d.ts +0 -46
  57. package/dist/src/execute/legacy.js +0 -460
  58. package/dist/src/pricing.llm.d.ts +0 -5
  59. package/dist/src/pricing.llm.js +0 -14
@@ -1,4 +1,4 @@
1
- import { SimulatorConfig, SimulationOptions, SimulationResult, TestScenario, TestCaseInput } from './simulator.types';
1
+ import { SimulatorConfig, SimulationOptions, SimulationResult, TestScenario, TestCaseInput, WorkerJobInput, WorkerResult } from './simulator.types';
2
2
  export declare class AgentSimulator {
3
3
  private config;
4
4
  private executor;
@@ -27,6 +27,33 @@ export declare class AgentSimulator {
27
27
  * ```
28
28
  */
29
29
  testCase(scenario: TestScenario, testCase: TestCaseInput): Promise<SimulationResult>;
30
+ /**
31
+ * Exécuter un WorkerJob — boucle Worker LLM ↔ Agent LLM
32
+ *
33
+ * Parallèle à testCase() mais pour des missions de production :
34
+ * - Le Worker LLM formule des questions pour l'Agent
35
+ * - L'Agent répond avec ses tools (RAG, DB, emails, calendar...)
36
+ * - Le Worker LLM évalue et continue ou termine avec [WORKER_COMPLETE]
37
+ *
38
+ * @param input - Paramètres du job (query, maxIterations, agentContext)
39
+ * @returns WorkerResult
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const worker = new AgentSimulator({
44
+ * agents: [...], start: 'PR-knowledge', verbose: false,
45
+ * mode: 'worker',
46
+ * positionDescription: 'Consulter tous les mails du jour et résumer les actions'
47
+ * });
48
+ *
49
+ * const result = await worker.runJob({
50
+ * query: 'Commence par lister les mails du jour',
51
+ * maxIterations: 10,
52
+ * agentContext: realContext
53
+ * });
54
+ * ```
55
+ */
56
+ runJob(input: WorkerJobInput): Promise<WorkerResult>;
30
57
  /**
31
58
  * @deprecated Utiliser testCase(scenario, case) à la place
32
59
  *
@@ -47,7 +74,7 @@ export declare class AgentSimulator {
47
74
  executeSimulation(options: SimulationOptions): Promise<SimulationResult>;
48
75
  /**
49
76
  * Compter les occurrences d'une action dans le dernier ExecutionResult
50
- * @param name Nom exact de l'action (ex: 'lookupMfilesIntervenant', 'lookupKnowledge', 'sendInternalEmail')
77
+ * @param name Nom exact de l'action (ex: 'resolveLocataire', 'lookupKnowledge', 'sendInternalEmail')
51
78
  * @returns { firstPos, count, total } où:
52
79
  * - firstPos: index de la première occurrence (ou -1 si absente)
53
80
  * - count: nombre d'occurrences de cette action
@@ -67,6 +94,9 @@ export declare class AgentSimulator {
67
94
  execution: any;
68
95
  };
69
96
  private isSimulationComplete;
97
+ private isWorkerComplete;
98
+ private isWorkerCompletionValid;
99
+ private parseWorkerResult;
70
100
  private parseSimulationResult;
71
101
  private extractConversationalPart;
72
102
  /**
@@ -1,17 +1,21 @@
1
+ import { AgenticContext } from '../types';
1
2
  import { SimulatorConfig, ExecutionContext, SimulationScenario } from './simulator.types';
2
3
  export declare class AgentExecutor {
3
4
  private config;
4
5
  private simulatorAgentBase;
5
6
  private mockCacheInitializer?;
6
7
  private ragManager?;
8
+ private isWorkerMode;
7
9
  constructor(config: SimulatorConfig & {
8
10
  mockCacheInitializer?: (sessionId: string) => Promise<void>;
9
11
  });
10
12
  /**
11
- * Initialiser les contextes agent et simulateur
12
- * @param scenario Le scenario de simulation complet avec persona, goals, result
13
+ * Initialiser les contextes agent et orchestrateur (simulateur ou worker)
14
+ *
15
+ * @param scenario Le scenario de simulation (ignoré en mode worker)
16
+ * @param externalAgentContext Contexte réel de l'agent (mode worker uniquement)
13
17
  */
14
- initializeContexts(scenario: SimulationScenario): Promise<ExecutionContext>;
18
+ initializeContexts(scenario: SimulationScenario, externalAgentContext?: AgenticContext): Promise<ExecutionContext>;
15
19
  /**
16
20
  * ✅ Exécuter l'agent testé et retourner sa réponse (extraction de agent-vs-agent.ts)
17
21
  */
@@ -21,8 +25,7 @@ export declare class AgentExecutor {
21
25
  */
22
26
  executeSimulator(context: ExecutionContext, query: string): Promise<string>;
23
27
  /**
24
- * Construire l'injection de contexte technique pour le simulateur
25
- * Permet au simulateur de connaître les tools utilisés par l'agent testé
28
+ * Construire l'injection de contexte à chaque tour
26
29
  */
27
30
  private buildAgentContextInjection;
28
31
  /**
@@ -34,3 +37,10 @@ export declare class AgentExecutor {
34
37
  */
35
38
  private getLastAssistantMessage;
36
39
  }
40
+ /**
41
+ * Construit le tag <execution-context> injecté à chaque tour.
42
+ * Exporté pour tests unitaires.
43
+ */
44
+ export declare function buildExecutionContextTag(exchangeCount: number, maxTurns?: number, actions?: {
45
+ action: string;
46
+ }[]): string;
@@ -1,71 +1,119 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AgentExecutor = void 0;
4
+ exports.buildExecutionContextTag = buildExecutionContextTag;
5
+ const utils_1 = require("../utils");
4
6
  const rag_1 = require("../rag");
5
7
  const stategraph_1 = require("../stategraph");
6
8
  const execute_1 = require("../execute");
9
+ const simulator_types_1 = require("./simulator.types");
7
10
  const simulator_prompts_1 = require("./simulator.prompts");
8
11
  class AgentExecutor {
9
12
  constructor(config) {
10
13
  this.config = config;
11
- // Configuration de base du simulateur (instructions seront construites dynamiquement avec le scenario)
14
+ this.isWorkerMode = config.mode === 'worker';
15
+ //
16
+ // Configuration de base du LLM orchestrateur
17
+ // - Mode simulator : testeur automatisé avec GENERIC_SIMULATOR_PROMPT
18
+ // - Mode worker : collaborateur avec WORKER_INTERNAL_PROMPT
12
19
  this.simulatorAgentBase = {
13
- name: "simple-simulator",
14
- model: ("HIGH-fast"),
15
- publicDescription: "Simulateur simple pour tests - TOUJOURS retourner JSON valide",
20
+ name: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_NAME : simulator_types_1.SIMULATOR_AGENT_NAME,
21
+ model: (config.workerModel || 'HIGH-fast'),
22
+ publicDescription: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_DESCRIPTION : simulator_types_1.SIMULATOR_AGENT_DESCRIPTION,
16
23
  cancelMemory: true,
17
- instructions: '', // Sera construit dans initializeContexts avec GENERIC_SIMULATOR_PROMPT
24
+ instructions: '', // Sera construit dans initializeContexts
18
25
  tools: [],
19
26
  downstreamAgents: []
20
27
  };
21
28
  //
22
- // Annuler la mémoire pour tous les agents en simulation
23
- config.agents.forEach(agent => {
24
- agent.cancelMemory = true;
25
- });
26
- this.mockCacheInitializer = config.mockCacheInitializer;
27
- // Initialiser le RAGManager si la configuration est fournie
28
- if (config.ragConfig) {
29
- try {
30
- this.ragManager = rag_1.RAGManager.get(config.ragConfig);
31
- console.log(`✅ RAGManager initialisé pour le simulateur (default: ${this.ragManager.getDefault()})`);
32
- }
33
- catch (error) {
34
- console.warn('⚠️ Impossible d\'initialiser le RAGManager pour le simulateur:', error);
29
+ // DANGER: sans ce filtre, le Worker appelle createWorkerJob en boucle
30
+ // récursive (33 jobs créés en <1s, crash sur la limite de 20).
31
+ // IMPORTANT: cloner les agents pour ne pas muter l'original (singleton _defaultAgent)
32
+ // FIXME: remplacer par une construction dynamique du périmètre tools
33
+ // (ex: excludeTools sur AgentConfig, lu par injectTransferTools)
34
+ const EXCLUDES_TOOLS = ['searchNoteMemories', 'updateUserMemory', 'createWorkerJob', 'createTaskListJob', 'sendFeedbackEmail'];
35
+ // const JOB_TOOLS = ['createWorkerJob', 'createTaskListJob'];
36
+ config.agents = config.agents.map(agent => ({
37
+ ...agent,
38
+ tools: agent.tools ? [...agent.tools] : [],
39
+ //
40
+ // Override du modèle de l'agent piloté si spécifié
41
+ ...(this.isWorkerMode && config.agentModel ? { model: config.agentModel } : {})
42
+ }));
43
+ if (this.isWorkerMode) {
44
+ //
45
+ // Mode worker : supprimer les tools de création de jobs (anti-récursion)
46
+ // et les tools mémoire (réservés aux interactions directes utilisateur)
47
+ const excludeWorker = [...EXCLUDES_TOOLS];
48
+ config.agents.forEach(agent => {
49
+ agent.tools = agent.tools.filter(t => !excludeWorker.includes(t.function?.name));
50
+ });
51
+ }
52
+ else {
53
+ //
54
+ // Mode simulator : supprimer les tools mémoire des agents en test
55
+ config.agents.forEach(agent => {
56
+ agent.cancelMemory = true;
57
+ agent.tools = agent.tools.filter(t => !EXCLUDES_TOOLS.includes(t.function?.name));
58
+ });
59
+ }
60
+ //
61
+ // Mode simulator uniquement : mockCacheInitializer et RAGManager
62
+ if (!this.isWorkerMode) {
63
+ this.mockCacheInitializer = config.mockCacheInitializer;
64
+ if (config.ragConfig) {
65
+ try {
66
+ this.ragManager = rag_1.RAGManager.get(config.ragConfig);
67
+ }
68
+ catch (error) {
69
+ console.warn('⚠️ Impossible d\'initialiser le RAGManager pour le simulateur:', error);
70
+ }
35
71
  }
36
72
  }
37
73
  }
38
74
  /**
39
- * Initialiser les contextes agent et simulateur
40
- * @param scenario Le scenario de simulation complet avec persona, goals, result
75
+ * Initialiser les contextes agent et orchestrateur (simulateur ou worker)
76
+ *
77
+ * @param scenario Le scenario de simulation (ignoré en mode worker)
78
+ * @param externalAgentContext Contexte réel de l'agent (mode worker uniquement)
41
79
  */
42
- async initializeContexts(scenario) {
43
- const sessionId = `simulation-${Date.now()}`;
44
- const agentContext = {
45
- user: { id: `test-user`, role: 'user', uid: `test-${sessionId}` },
46
- credential: { test: true, sessionId: `agent-${sessionId}` },
47
- verbose: this.config.verbose,
48
- session: { id: `agent-${sessionId}`, data: {}, messages: [] },
49
- // ✅ Ajouter customRag au contexte si le RAG est configuré
50
- ...(this.ragManager ? { customRag: this.ragManager.getDefault() } : {})
51
- };
52
- const simulatorContext = {
53
- user: { id: `simulator-user`, role: 'user', uid: `sim-${sessionId}` },
54
- credential: { test: true, sessionId: `sim-${sessionId}` },
80
+ async initializeContexts(scenario, externalAgentContext) {
81
+ const sessionId = `${this.isWorkerMode ? 'worker' : 'simulation'}-${Date.now()}`;
82
+ //
83
+ // Mode worker : utiliser le contexte réel fourni
84
+ // Mode simulator : créer un contexte mock
85
+ const agentContext = (this.isWorkerMode && externalAgentContext)
86
+ ? externalAgentContext
87
+ : {
88
+ user: { id: `test-user`, role: 'user', uid: `test-${sessionId}`, mail: `test-${sessionId}@simulator.local` },
89
+ credential: { test: true, sessionId: `agent-${sessionId}` },
90
+ verbose: this.config.verbose,
91
+ session: { id: `agent-${sessionId}`, data: {}, messages: [] },
92
+ ...(this.ragManager ? { customRag: this.ragManager.getDefault() } : {})
93
+ };
94
+ //
95
+ // Contexte isolé pour le LLM orchestrateur (toujours séparé)
96
+ const orchestratorContext = {
97
+ user: { id: `${this.isWorkerMode ? 'worker' : 'simulator'}-user`, role: 'user', uid: `orch-${sessionId}` },
98
+ credential: { test: true, sessionId: `orch-${sessionId}` },
55
99
  verbose: this.config.verbose,
56
- session: { id: `sim-${sessionId}`, data: {}, messages: [] }
100
+ session: { id: `orch-${sessionId}`, data: {}, messages: [] }
57
101
  };
58
- // ✅ Initialiser le cache mock si fourni (pour les tests SGC avec M-Files)
59
- if (this.mockCacheInitializer) {
102
+ //
103
+ // Mode simulator : initialiser le cache mock
104
+ if (!this.isWorkerMode && this.mockCacheInitializer) {
60
105
  await this.mockCacheInitializer(agentContext.session.id);
61
106
  }
62
- // ✅ Construire les instructions complètes avec le scénario intégré via la fonction
63
- const fullInstructions = (0, simulator_prompts_1.GENERIC_SIMULATOR_PROMPT)(scenario, this.config.instructionEx);
64
- if (this.config.verbose)
65
- console.log('---- DBG fullInstructions', fullInstructions);
107
+ //
108
+ // Construire les instructions selon le mode
109
+ // - Simulator : GENERIC_SIMULATOR_PROMPT(scenario) + positionDescription
110
+ // - Worker : WORKER_INTERNAL_PROMPT(positionDescription + personaResult)
111
+ const fullInstructions = this.isWorkerMode
112
+ ? (0, simulator_prompts_1.WORKER_INTERNAL_PROMPT)(this.config.positionDescription || '', this.config.personaResult, (0, utils_1.extractAgentCapabilities)(this.config.agents, this.config.start))
113
+ : (0, simulator_prompts_1.GENERIC_SIMULATOR_PROMPT)(scenario, this.config.positionDescription);
66
114
  return {
67
115
  agentContext,
68
- simulatorContext,
116
+ simulatorContext: orchestratorContext,
69
117
  simulatorAgent: {
70
118
  ...this.simulatorAgentBase,
71
119
  instructions: fullInstructions
@@ -78,7 +126,6 @@ class AgentExecutor {
78
126
  actions: [],
79
127
  lastMessage: '',
80
128
  usage: { prompt: 0, completion: 0, total: 0, cost: 0 }
81
- // moreThinkin removed (obsolete)
82
129
  }
83
130
  };
84
131
  }
@@ -86,27 +133,41 @@ class AgentExecutor {
86
133
  * ✅ Exécuter l'agent testé et retourner sa réponse (extraction de agent-vs-agent.ts)
87
134
  */
88
135
  async executeAgent(context, query) {
136
+ //
137
+ // Mode worker uniquement : signaler à l'Agent qu'il est piloté par un orchestrateur
138
+ // afin d'éviter les questions de clarification sans réponse possible
139
+ const finalQuery = this.isWorkerMode ? simulator_prompts_1.WORKER_AUTONOMOUS_PREFIX + query : query;
89
140
  // Logique extraite de AgentVsAgentTester.executeAgentWithContext()
90
141
  const execResult = await (0, execute_1.executeAgentSet)(this.config.agents, context.agentContext, {
91
- query,
142
+ query: finalQuery,
92
143
  home: this.config.start,
93
144
  stdout: execute_1.DummyWritable,
94
145
  verbose: this.config.verbose,
95
146
  debug: false
96
147
  });
97
- // Accumuler seulement l'usage, pas les actions
148
+ //
149
+ // Accumuler usage ET actions pour la validation des outils
98
150
  if (context.lastExecution) {
151
+ //
152
+ // Accumuler l'usage
99
153
  context.lastExecution.usage.prompt += execResult.usage.prompt;
100
154
  context.lastExecution.usage.completion += execResult.usage.completion;
101
155
  context.lastExecution.usage.total += execResult.usage.total;
102
156
  context.lastExecution.usage.cost += execResult.usage.cost;
157
+ //
158
+ // Accumuler les actions (important pour toolValidation)
159
+ context.lastExecution.actions = [
160
+ ...(context.lastExecution.actions || []),
161
+ ...(execResult.actions || [])
162
+ ];
163
+ //
164
+ // Mettre à jour les autres champs avec les valeurs du dernier échange
165
+ context.lastExecution.runId = execResult.runId;
166
+ context.lastExecution.lastMessage = execResult.lastMessage;
167
+ }
168
+ else {
169
+ context.lastExecution = execResult;
103
170
  }
104
- context.lastExecution = execResult;
105
- // if (context.lastExecution) {
106
- // context.lastExecution = executionResultMerge(context.lastExecution, execResult);
107
- // } else {
108
- // context.lastExecution = execResult;
109
- // }
110
171
  context.exchangeCount++;
111
172
  // ✅ Extraire et retourner le dernier message de l'agent (logique de getLastPRSolverMessage)
112
173
  return this.getLastAgentMessage(context.agentContext);
@@ -119,36 +180,25 @@ class AgentExecutor {
119
180
  // ✅ Injecter le contexte technique si disponible
120
181
  const agentContextInjection = this.buildAgentContextInjection(context);
121
182
  const enrichedQuery = agentContextInjection ? `${query}\n\n${agentContextInjection}` : query;
122
- // console.log('DEBUG: Exécution du simulateur avec query:\n', enrichedQuery);
183
+ // console.log(`📡 Simulator input (turn ${context.exchangeCount}/${context.maxTurns || '?'}):\n query[${enrichedQuery.length}]: ${enrichedQuery.substring(0, 200)}${enrichedQuery.length > 200 ? '...' : ''}\n context: ${agentContextInjection.substring(0, 120)}`);
123
184
  await (0, execute_1.executeAgentSet)([context.simulatorAgent], context.simulatorContext, {
124
185
  query: enrichedQuery,
125
- home: 'simple-simulator',
186
+ home: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_NAME : simulator_types_1.SIMULATOR_AGENT_NAME,
126
187
  stdout: execute_1.DummyWritable,
127
188
  verbose: false,
128
189
  debug: false
129
190
  });
130
191
  const response = this.getLastAssistantMessage(context.simulatorContext);
192
+ // console.log(`📡 Simulator output (turn ${context.exchangeCount}): ${response.substring(0, 200)}${response.length > 200 ? '...' : ''}`);
131
193
  context.conversationHistory.push(`Simulator: ${response}`);
132
194
  return response;
133
195
  }
134
196
  /**
135
- * Construire l'injection de contexte technique pour le simulateur
136
- * Permet au simulateur de connaître les tools utilisés par l'agent testé
197
+ * Construire l'injection de contexte à chaque tour
137
198
  */
138
199
  buildAgentContextInjection(context) {
139
- if (!context.lastExecution || !context.lastExecution.actions || context.lastExecution.actions.length === 0) {
140
- return '';
141
- }
142
- // Extraire les noms des tools appelés (sans les arguments)
143
- const tools = context.lastExecution.actions.map(action => action.action);
144
- if (tools.length === 0) {
145
- return '';
146
- }
147
- const contextData = {
148
- tools: tools,
149
- exchangeCount: context.exchangeCount
150
- };
151
- return `<agent-context>\n${JSON.stringify(contextData, null, 2)}\n</agent-context>`;
200
+ const actions = !this.isWorkerMode ? context.lastExecution?.actions : undefined;
201
+ return buildExecutionContextTag(context.exchangeCount, context.maxTurns, actions);
152
202
  }
153
203
  /**
154
204
  * ✅ Récupérer le dernier message de l'agent testé (extraction de agent-vs-agent.ts ligne 168-191)
@@ -188,3 +238,20 @@ class AgentExecutor {
188
238
  }
189
239
  }
190
240
  exports.AgentExecutor = AgentExecutor;
241
+ /**
242
+ * Construit le tag <execution-context> injecté à chaque tour.
243
+ * Exporté pour tests unitaires.
244
+ */
245
+ function buildExecutionContextTag(exchangeCount, maxTurns, actions) {
246
+ const max = maxTurns || 10;
247
+ const contextData = {
248
+ turn: exchangeCount,
249
+ maxTurns: max,
250
+ // Le simulateur doit toujours disposer d'un tour pour évaluer la réponse courante.
251
+ turnsRemaining: exchangeCount === 0 ? max : Math.max(1, max - exchangeCount)
252
+ };
253
+ if (actions?.length) {
254
+ contextData.tools = actions.map(a => a.action);
255
+ }
256
+ return `<execution-context>\n${JSON.stringify(contextData)}\n</execution-context>`;
257
+ }