@hilbras/omninode 2.0.0-alpha.6 → 2.0.0-alpha.8

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/dist/index.js CHANGED
@@ -125,6 +125,7 @@ var providerConfigSchema = z.object({
125
125
  type: z.enum(["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]),
126
126
  base_url: z.string().url(),
127
127
  api_key_env_var: z.string().min(1).optional(),
128
+ timeout_ms: z.number().int().positive().optional(),
128
129
  headers: z.record(z.string()).optional(),
129
130
  enabled: z.boolean().optional(),
130
131
  metadata: z.record(z.unknown()).optional()
@@ -189,7 +190,9 @@ var projectConfigSchema = z.object({
189
190
  memory: z.object({
190
191
  provider: z.string().min(1).default("local"),
191
192
  base_url: z.string().url().optional(),
192
- api_key_env_var: z.string().min(1).optional()
193
+ api_key_env_var: z.string().min(1).optional(),
194
+ /** When true, memory failures fail tasks instead of being tolerated (§12). */
195
+ required: z.boolean().optional()
193
196
  }).strict().optional()
194
197
  }).strict();
195
198
  var appConfigSchema = z.object({
@@ -271,7 +274,8 @@ function toAppConfig(yaml) {
271
274
  memory: {
272
275
  provider: yaml.project.memory.provider,
273
276
  baseUrl: yaml.project.memory.base_url,
274
- apiKeyEnvVar: yaml.project.memory.api_key_env_var
277
+ apiKeyEnvVar: yaml.project.memory.api_key_env_var,
278
+ required: yaml.project.memory.required
275
279
  }
276
280
  } : {}
277
281
  },
@@ -302,6 +306,7 @@ function toProviderConfig(raw) {
302
306
  type: raw.type,
303
307
  baseUrl: raw.base_url,
304
308
  apiKeyEnvVar: raw.api_key_env_var,
309
+ timeoutMs: raw.timeout_ms,
305
310
  headers: raw.headers,
306
311
  enabled: raw.enabled,
307
312
  metadata: raw.metadata
@@ -524,6 +529,7 @@ function providerTransportError(context) {
524
529
  }
525
530
 
526
531
  // src/providers/openai-compatible/index.ts
532
+ var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
527
533
  var OpenAICompatibleProvider = class {
528
534
  config;
529
535
  providerId;
@@ -543,6 +549,10 @@ var OpenAICompatibleProvider = class {
543
549
  };
544
550
  this.log = log.child({ provider: config.name });
545
551
  }
552
+ /** Provider-level request timeout (roadmap §6.6/§11) with the shared default. */
553
+ get requestTimeoutMs() {
554
+ return this.config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
555
+ }
546
556
  /** Authenticate + discover (roadmap §10, Model Discovery). */
547
557
  async connect() {
548
558
  authHeaders(this.config, this.env);
@@ -554,11 +564,17 @@ var OpenAICompatibleProvider = class {
554
564
  const models = this.discovered ?? await this.connect();
555
565
  return models.find((m) => m.id === modelId);
556
566
  }
557
- async listModels() {
567
+ /** Raw /models body (protected so adapters can capture gateway-level metadata). */
568
+ async rawModelsResponse() {
569
+ const response = await this.modelsRequest();
570
+ return response.body;
571
+ }
572
+ async modelsRequest() {
558
573
  let response;
559
574
  try {
560
575
  response = await requestJson(`${this.config.baseUrl}/models`, {
561
- headers: authHeaders(this.config, this.env)
576
+ headers: authHeaders(this.config, this.env),
577
+ timeoutMs: this.requestTimeoutMs
562
578
  });
563
579
  } catch (error) {
564
580
  if (error instanceof ProviderError) throw error;
@@ -573,6 +589,10 @@ var OpenAICompatibleProvider = class {
573
589
  body
574
590
  });
575
591
  }
592
+ return response;
593
+ }
594
+ async listModels() {
595
+ const body = await this.rawModelsResponse();
576
596
  const entries = extractModelEntries(body, this.config);
577
597
  const models = [];
578
598
  let skipped = 0;
@@ -615,6 +635,10 @@ var OpenAICompatibleProvider = class {
615
635
  }
616
636
  };
617
637
  }
638
+ /** Streaming where the gateway supports it (§11). */
639
+ stream(request, onChunk) {
640
+ return streamChatCompletion(this.config, request, onChunk, this.env);
641
+ }
618
642
  async healthCheck() {
619
643
  const lastCheckedAt = (/* @__PURE__ */ new Date()).toISOString();
620
644
  try {
@@ -649,6 +673,7 @@ var OpenAICompatibleProvider = class {
649
673
  response = await requestJson(`${this.config.baseUrl}/chat/completions`, {
650
674
  method: "POST",
651
675
  headers: authHeaders(this.config, this.env),
676
+ timeoutMs: this.requestTimeoutMs,
652
677
  body: {
653
678
  model: request.model,
654
679
  messages: request.messages,
@@ -693,6 +718,74 @@ var OpenAICompatibleProvider = class {
693
718
  };
694
719
  }
695
720
  };
721
+ async function streamChatCompletion(config, request, onChunk, env = process.env) {
722
+ const baseUrl = normalizeBaseUrl(config.baseUrl);
723
+ const timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
724
+ let response;
725
+ try {
726
+ response = await fetch(`${baseUrl}/chat/completions`, {
727
+ method: "POST",
728
+ headers: {
729
+ accept: "text/event-stream",
730
+ "content-type": "application/json",
731
+ ...authHeaders(config, env)
732
+ },
733
+ body: JSON.stringify({
734
+ model: request.model,
735
+ messages: request.messages,
736
+ stream: true,
737
+ ...request.temperature !== void 0 ? { temperature: request.temperature } : {},
738
+ ...request.maxTokens !== void 0 ? { max_tokens: request.maxTokens } : {}
739
+ }),
740
+ signal: AbortSignal.timeout(timeoutMs)
741
+ });
742
+ } catch (error) {
743
+ throw providerTransportError({ provider: config.name, operation: "stream", cause: error });
744
+ }
745
+ if (!response.ok) {
746
+ const body = await response.json().catch(() => void 0);
747
+ throw providerHttpError({ provider: config.name, operation: "stream", status: response.status, body });
748
+ }
749
+ if (!response.body) {
750
+ throw providerHttpError({
751
+ provider: config.name,
752
+ operation: "stream",
753
+ status: 500,
754
+ body: { error: { message: "streaming is not supported by this endpoint" } }
755
+ });
756
+ }
757
+ let content = "";
758
+ let model = request.model;
759
+ let finishReason;
760
+ const decoder = new TextDecoder();
761
+ let buffer = "";
762
+ for await (const piece of response.body) {
763
+ buffer += decoder.decode(piece, { stream: true });
764
+ let newline = buffer.indexOf("\n");
765
+ while (newline >= 0) {
766
+ const line = buffer.slice(0, newline).trim();
767
+ buffer = buffer.slice(newline + 1);
768
+ newline = buffer.indexOf("\n");
769
+ if (line.length === 0 || line.startsWith(":")) continue;
770
+ const data = line.startsWith("data:") ? line.slice(5).trim() : line;
771
+ if (data === "[DONE]") continue;
772
+ let event;
773
+ try {
774
+ event = JSON.parse(data);
775
+ } catch {
776
+ continue;
777
+ }
778
+ if (typeof event.model === "string") model = event.model;
779
+ const choices = Array.isArray(event.choices) ? event.choices : [];
780
+ const first = choices[0];
781
+ const delta = typeof first?.delta?.content === "string" ? first.delta.content : "";
782
+ if (delta.length > 0) content += delta;
783
+ if (typeof first?.finish_reason === "string") finishReason = first.finish_reason;
784
+ onChunk({ delta, ...finishReason !== void 0 ? { finishReason } : {}, raw: event });
785
+ }
786
+ }
787
+ return { model, content, ...finishReason !== void 0 ? { finishReason } : {} };
788
+ }
696
789
  function normalizeModalities(value) {
697
790
  const list = Array.isArray(value) ? value : typeof value === "string" ? [value] : void 0;
698
791
  if (!list) return void 0;
@@ -726,10 +819,32 @@ function inferHealth(error) {
726
819
 
727
820
  // src/providers/omnihilbras/index.ts
728
821
  var OmniHilbrasProvider = class extends OpenAICompatibleProvider {
822
+ gateway;
823
+ async listModels() {
824
+ const raw = await this.rawModelsResponse();
825
+ await this.extractGatewayMetadata(raw);
826
+ const models = await super.listModels();
827
+ return this.gateway ? models.map((model) => ({ ...model, metadata: { ...model.metadata, gateway: this.gateway } })) : models;
828
+ }
729
829
  /**
730
830
  * Run the full connect flow. Throws on authentication or transport failure
731
831
  * (use healthCheck() for a non-throwing probe).
732
832
  */
833
+ /**
834
+ * Gateway metadata reported alongside the model list (gateway version, tier,
835
+ * region…), kept separate from per-model metadata (§11 — provider metadata).
836
+ */
837
+ gatewayMetadata() {
838
+ return this.gateway;
839
+ }
840
+ async extractGatewayMetadata(body) {
841
+ if (body !== null && typeof body === "object") {
842
+ const gateway = body.gateway;
843
+ if (gateway !== null && typeof gateway === "object") {
844
+ this.gateway = gateway;
845
+ }
846
+ }
847
+ }
733
848
  async connectAndRegister(registry) {
734
849
  const apiKey = resolveApiKey(this.config);
735
850
  const discovered = await this.listModels();
@@ -2089,6 +2204,23 @@ var FileAuditLog = class {
2089
2204
  }
2090
2205
  };
2091
2206
 
2207
+ // src/memory/base.ts
2208
+ function defaultSearch(provider, text, options = {}) {
2209
+ return provider.retrieve({
2210
+ text,
2211
+ ...options.scope !== void 0 ? { scope: options.scope } : {},
2212
+ ...options.limit !== void 0 ? { limit: options.limit } : {}
2213
+ });
2214
+ }
2215
+ function defaultMetadata(name, options = {}) {
2216
+ return {
2217
+ name,
2218
+ capabilities: options.capabilities ?? ["retrieve", "store", "search"],
2219
+ relevanceRanking: options.relevanceRanking ?? false,
2220
+ ...options.backend !== void 0 ? { backend: options.backend } : {}
2221
+ };
2222
+ }
2223
+
2092
2224
  // src/memory/local.ts
2093
2225
  var STOPWORDS = /* @__PURE__ */ new Set([
2094
2226
  "the",
@@ -2151,9 +2283,27 @@ var LocalMemoryProvider = class extends JsonFileStore {
2151
2283
  constructor(directory) {
2152
2284
  super({ ...directory !== void 0 ? { directory } : {}, fileName: "memory.json" });
2153
2285
  }
2154
- async query(query) {
2286
+ metadata() {
2287
+ return defaultMetadata(this.name, {
2288
+ capabilities: ["retrieve", "store", "search", "categories", "tags"],
2289
+ relevanceRanking: true,
2290
+ backend: { kind: "json-file", deterministicScoring: true }
2291
+ });
2292
+ }
2293
+ search(text, options = {}) {
2294
+ return defaultSearch(this, text, options);
2295
+ }
2296
+ /** @deprecated v1 alias of {@link retrieve}. */
2297
+ query(query) {
2298
+ return this.retrieve(query);
2299
+ }
2300
+ /** @deprecated v1 alias of {@link store}. */
2301
+ write(entry) {
2302
+ return this.store(entry);
2303
+ }
2304
+ async retrieve(query) {
2155
2305
  const entries = await this.readAll();
2156
- const filtered = entries.filter((entry) => query.scope ? entry.scope === query.scope : true).filter(
2306
+ const filtered = entries.filter((entry) => query.scope ? entry.scope === query.scope : true).filter((entry) => query.category ? entry.category === query.category : true).filter(
2157
2307
  (entry) => query.tags && query.tags.length > 0 ? query.tags.every((tag) => (entry.tags ?? []).includes(tag)) : true
2158
2308
  );
2159
2309
  if (!query.text || query.text.trim().length === 0) {
@@ -2162,7 +2312,7 @@ var LocalMemoryProvider = class extends JsonFileStore {
2162
2312
  const queryKeywords = keywords(query.text);
2163
2313
  return filtered.map((entry) => ({ entry, score: relevanceScore(queryKeywords, entry) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score).slice(0, query.limit ?? 10).map(({ entry }) => entry);
2164
2314
  }
2165
- write(entry) {
2315
+ store(entry) {
2166
2316
  return this.mutate((entries) => {
2167
2317
  const index = entries.findIndex((e) => e.key === entry.key);
2168
2318
  const stamped = {
@@ -2193,11 +2343,40 @@ var RememberaMemoryProvider = class {
2193
2343
  this.env = config.env ?? process.env;
2194
2344
  this.log = log.child({ component: "remembera" });
2195
2345
  }
2346
+ get authenticationConfigured() {
2347
+ return this.apiKeyEnvVar === void 0 || Boolean(this.env[this.apiKeyEnvVar]);
2348
+ }
2196
2349
  headers() {
2197
2350
  const key = this.apiKeyEnvVar ? resolveApiKey({ name: "remembera", apiKeyEnvVar: this.apiKeyEnvVar }, this.env) : void 0;
2198
2351
  return key ? { authorization: `Bearer ${key}` } : {};
2199
2352
  }
2200
- async query(query) {
2353
+ /** Search delegates to the gateway's relevance query. */
2354
+ search(text, options = {}) {
2355
+ return defaultSearch(
2356
+ this,
2357
+ text,
2358
+ {
2359
+ ...options.scope !== void 0 ? { scope: options.scope } : {},
2360
+ ...options.limit !== void 0 ? { limit: options.limit } : {}
2361
+ }
2362
+ );
2363
+ }
2364
+ metadata() {
2365
+ return defaultMetadata(this.name, {
2366
+ capabilities: ["retrieve", "store", "search", "categories", "tags"],
2367
+ relevanceRanking: true,
2368
+ backend: { kind: "http", baseUrl: this.baseUrl, authenticated: this.authenticationConfigured }
2369
+ });
2370
+ }
2371
+ /** @deprecated v1 alias of {@link retrieve}. */
2372
+ query(query) {
2373
+ return this.retrieve(query);
2374
+ }
2375
+ /** @deprecated v1 alias of {@link store}. */
2376
+ write(entry) {
2377
+ return this.store(entry);
2378
+ }
2379
+ async retrieve(query) {
2201
2380
  const { status, body } = await this.request(`${this.baseUrl}/api/memory/query`, query);
2202
2381
  if (status !== 200) {
2203
2382
  throw new MemoryError(`Remembera query returned HTTP ${status}.`);
@@ -2208,7 +2387,7 @@ var RememberaMemoryProvider = class {
2208
2387
  }
2209
2388
  return entries.map((entry) => this.toEntry(entry)).filter((entry) => entry !== void 0);
2210
2389
  }
2211
- async write(entry) {
2390
+ async store(entry) {
2212
2391
  const { status } = await this.request(`${this.baseUrl}/api/memory`, entry);
2213
2392
  if (status !== 200 && status !== 201) {
2214
2393
  throw new MemoryError(`Remembera write returned HTTP ${status}.`);
@@ -2243,6 +2422,7 @@ var RememberaMemoryProvider = class {
2243
2422
  content: entry.content,
2244
2423
  scope: scope === "project" || scope === "role" || scope === "task" || scope === "knowledge" ? scope : "knowledge",
2245
2424
  ...Array.isArray(entry.tags) ? { tags: entry.tags.filter((t) => typeof t === "string") } : {},
2425
+ ...typeof entry.category === "string" ? { category: entry.category } : {},
2246
2426
  ...typeof entry.createdAt === "string" ? { createdAt: entry.createdAt } : {},
2247
2427
  ...typeof entry.updatedAt === "string" ? { updatedAt: entry.updatedAt } : {}
2248
2428
  };
@@ -2273,57 +2453,54 @@ function createMemoryProvider(config) {
2273
2453
  }
2274
2454
 
2275
2455
  // src/memory/service.ts
2456
+ var DEFAULT_ENTRY_LIMIT = 8;
2276
2457
  var MAX_CONTEXT_CHARS = 4e3;
2277
2458
  var MemoryService = class {
2278
- constructor(provider, log = logger) {
2459
+ constructor(provider, log = logger, options = {}) {
2279
2460
  this.provider = provider;
2280
2461
  this.log = log.child({ component: "memory", provider: provider.name });
2462
+ this.required = options.required ?? false;
2463
+ this.maxContextChars = options.maxContextChars ?? MAX_CONTEXT_CHARS;
2281
2464
  }
2282
2465
  provider;
2283
2466
  log;
2467
+ required;
2468
+ maxContextChars;
2284
2469
  get providerRef() {
2285
2470
  return this.provider;
2286
2471
  }
2287
2472
  get providerName() {
2288
2473
  return this.provider.name;
2289
2474
  }
2290
- /** Relevant context for a task objective; empty string when nothing matches. */
2291
- async gatherContext(query) {
2475
+ get isRequired() {
2476
+ return this.required;
2477
+ }
2478
+ /** Structured, budgeted context for a task (§12 — avoid loading all memory). */
2479
+ async contextFor(query) {
2480
+ let entries;
2292
2481
  try {
2293
- const entries = await this.provider.query({
2482
+ entries = await this.provider.retrieve({
2294
2483
  text: query.objective,
2295
2484
  ...query.role ? { tags: [query.role] } : {},
2296
- limit: 8
2485
+ limit: query.limit ?? DEFAULT_ENTRY_LIMIT
2297
2486
  });
2298
- if (entries.length === 0) return "";
2299
- const byScope = /* @__PURE__ */ new Map();
2300
- for (const entry of entries) {
2301
- byScope.set(entry.scope, [...byScope.get(entry.scope) ?? [], entry]);
2302
- }
2303
- const parts = [];
2304
- for (const scope of ["project", "task", "role", "knowledge"]) {
2305
- const scopeEntries = byScope.get(scope) ?? [];
2306
- if (scopeEntries.length === 0) continue;
2307
- const lines = scopeEntries.map((entry) => `- ${entry.content}`).join("\n");
2308
- parts.push(`### Relevant memory (${scope})
2309
- ${lines}`);
2310
- }
2311
- const context = parts.join("\n\n");
2312
- return context.length > MAX_CONTEXT_CHARS ? `${context.slice(0, MAX_CONTEXT_CHARS)}\u2026` : context;
2313
2487
  } catch (error) {
2314
- this.log.warn(
2315
- `Memory query failed (continuing without memory): ${error instanceof Error ? error.message : String(error)}`
2316
- );
2317
- return "";
2488
+ return this.handleFailure("retrieve", error, { text: "", entries: [], truncated: false });
2318
2489
  }
2490
+ return this.format(entries);
2319
2491
  }
2320
- /** Records a finished task's outcome — best-effort. */
2492
+ /** Prompt-ready context text (v1 convenience wrapper). */
2493
+ async gatherContext(query) {
2494
+ return (await this.contextFor(query)).text;
2495
+ }
2496
+ /** Records a finished task's outcome — task history plus "known problems" (§12). */
2321
2497
  async recordTaskOutcome(task) {
2322
2498
  const outcome = task.result?.summary ?? task.result?.error ?? "(no output)";
2323
2499
  try {
2324
- await this.provider.write({
2500
+ await this.provider.store({
2325
2501
  key: `task:${task.id}`,
2326
2502
  scope: "task",
2503
+ category: "tasks",
2327
2504
  content: `Objective: ${task.objective}
2328
2505
  Status: ${task.status}
2329
2506
  Outcome: ${outcome}`,
@@ -2334,18 +2511,53 @@ Outcome: ${outcome}`,
2334
2511
  (report) => report.findings.filter((finding) => finding.severity === "high" || finding.severity === "critical").map((finding) => ({ report, finding }))
2335
2512
  );
2336
2513
  for (const { report, finding } of significant) {
2337
- await this.provider.write({
2514
+ await this.provider.store({
2338
2515
  key: `finding:${report.id}:${finding.id}`,
2339
2516
  scope: "project",
2517
+ category: "problems",
2340
2518
  content: `[${finding.severity}] ${finding.title} \u2014 ${finding.detail}`,
2341
2519
  tags: ["known-problem", report.agent]
2342
2520
  });
2343
2521
  }
2344
2522
  } catch (error) {
2345
- this.log.warn(
2346
- `Memory write failed (continuing): ${error instanceof Error ? error.message : String(error)}`
2523
+ this.handleFailure("store", error, void 0);
2524
+ }
2525
+ }
2526
+ format(entries) {
2527
+ if (entries.length === 0) return { text: "", entries, truncated: false };
2528
+ const byScope = /* @__PURE__ */ new Map();
2529
+ for (const entry of entries) {
2530
+ byScope.set(entry.scope, [...byScope.get(entry.scope) ?? [], entry]);
2531
+ }
2532
+ const parts = [];
2533
+ for (const scope of ["project", "task", "role", "knowledge"]) {
2534
+ const scopeEntries = byScope.get(scope) ?? [];
2535
+ if (scopeEntries.length === 0) continue;
2536
+ const lines = scopeEntries.map((entry) => {
2537
+ const category = entry.category ? `[${entry.category}] ` : "";
2538
+ return `- ${category}${entry.content}`;
2539
+ }).join("\n");
2540
+ parts.push(`### Relevant memory (${scope})
2541
+ ${lines}`);
2542
+ }
2543
+ let text = parts.join("\n\n");
2544
+ const truncated = text.length > this.maxContextChars;
2545
+ if (truncated) text = `${text.slice(0, this.maxContextChars - 1)}\u2026`;
2546
+ return { text, entries, truncated };
2547
+ }
2548
+ /**
2549
+ * Failure policy (§12): continue unless memory is explicitly required.
2550
+ */
2551
+ handleFailure(operation, error, fallback) {
2552
+ const message = error instanceof Error ? error.message : String(error);
2553
+ if (this.required) {
2554
+ throw new MemoryError(
2555
+ `Memory is marked required, but ${operation} failed: ${message}`,
2556
+ { cause: error }
2347
2557
  );
2348
2558
  }
2559
+ this.log.warn(`Memory ${operation} failed (continuing without memory): ${message}`);
2560
+ return fallback ?? { text: "", entries: [], truncated: false };
2349
2561
  }
2350
2562
  };
2351
2563
 
@@ -2357,7 +2569,11 @@ function createTaskEngine(config, log = logger, directory) {
2357
2569
  agents,
2358
2570
  roles,
2359
2571
  store: new FileTaskStore(directory),
2360
- ...config.project.memory !== void 0 ? { memory: new MemoryService(createMemoryProvider(config.project.memory), log) } : {},
2572
+ ...config.project.memory !== void 0 ? {
2573
+ memory: new MemoryService(createMemoryProvider(config.project.memory), log, {
2574
+ required: config.project.memory.required
2575
+ })
2576
+ } : {},
2361
2577
  audit: new FileAuditLog(),
2362
2578
  log
2363
2579
  });
@@ -3439,7 +3655,11 @@ function buildPipelineEngine(config, log = logger) {
3439
3655
  agents,
3440
3656
  roles,
3441
3657
  store: new FileTaskStore(),
3442
- ...config.project.memory !== void 0 ? { memory: new MemoryService(createMemoryProvider(config.project.memory), log) } : {},
3658
+ ...config.project.memory !== void 0 ? {
3659
+ memory: new MemoryService(createMemoryProvider(config.project.memory), log, {
3660
+ required: config.project.memory.required
3661
+ })
3662
+ } : {},
3443
3663
  audit: new FileAuditLog(),
3444
3664
  log
3445
3665
  });
@@ -3477,7 +3697,7 @@ var ProjectStores = class {
3477
3697
  };
3478
3698
 
3479
3699
  // src/version.ts
3480
- var OMNINODE_VERSION = "2.0.0-alpha.6";
3700
+ var OMNINODE_VERSION = "2.0.0-alpha.8";
3481
3701
  export {
3482
3702
  AgentAdapterRegistry,
3483
3703
  AgentError,
@@ -3494,6 +3714,7 @@ export {
3494
3714
  JsonFileStore,
3495
3715
  LocalMemoryProvider,
3496
3716
  Logger,
3717
+ MAX_CONTEXT_CHARS,
3497
3718
  MAX_MESSAGE_BYTES,
3498
3719
  MemoryError,
3499
3720
  MemoryService,
@@ -3542,7 +3763,9 @@ export {
3542
3763
  createTaskEngine,
3543
3764
  decodeMessage,
3544
3765
  decodeStream,
3766
+ defaultMetadata,
3545
3767
  defaultProjectConfigYaml,
3768
+ defaultSearch,
3546
3769
  describeExit,
3547
3770
  encodeMessage,
3548
3771
  envelope,