@lowire/loop 0.0.15 → 0.0.16

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/lib/cache.d.ts CHANGED
@@ -14,10 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import type * as types from './types';
17
- type ReplayCaches = {
17
+ export type ReplayCaches = {
18
18
  input: types.ReplayCache;
19
19
  output: types.ReplayCache;
20
- secrets: Record<string, string>;
21
20
  };
22
- export declare function cachedComplete(provider: types.Provider, conversation: types.Conversation, caches: ReplayCaches | undefined, options: types.CompletionOptions): ReturnType<types.Provider['complete']>;
23
- export {};
21
+ export declare function cachedComplete(provider: types.Provider, conversation: types.Conversation, caches: ReplayCaches | undefined, options: types.CompletionOptions & {
22
+ secrets?: Record<string, string>;
23
+ }): ReturnType<types.Provider['complete']>;
package/lib/cache.js CHANGED
@@ -21,33 +21,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.cachedComplete = cachedComplete;
22
22
  const crypto_1 = __importDefault(require("crypto"));
23
23
  async function cachedComplete(provider, conversation, caches, options) {
24
+ const c = hideSecrets(conversation, options.secrets);
25
+ const result = await cachedCompleteNoSecrets(provider, c, caches, options);
26
+ return unhideSecrets(result, options.secrets);
27
+ }
28
+ async function cachedCompleteNoSecrets(provider, conversation, caches, options) {
24
29
  if (!caches)
25
30
  return await provider.complete(conversation, options);
26
- const secrets = caches.secrets || {};
27
- const c = hideSecrets(conversation, secrets);
28
- const key = calculateSha1(JSON.stringify(c));
31
+ const key = calculateSha1(JSON.stringify(conversation));
29
32
  if (!process.env.LOWIRE_NO_CACHE && caches.input[key]) {
30
33
  caches.output[key] = caches.input[key];
31
- return unhideSecrets(caches.input[key] ?? caches.output[key], secrets);
34
+ return caches.input[key] ?? caches.output[key];
32
35
  }
33
36
  if (!process.env.LOWIRE_NO_CACHE && caches.output[key])
34
- return unhideSecrets(caches.output[key], secrets);
37
+ return caches.output[key];
35
38
  if (process.env.LOWIRE_FORCE_CACHE)
36
39
  throw new Error('Cache missing but TL_FORCE_CACHE is set' + JSON.stringify(conversation, null, 2));
37
40
  const result = await provider.complete(conversation, options);
38
- caches.output[key] = hideSecrets(result, secrets);
41
+ caches.output[key] = result;
39
42
  return result;
40
43
  }
41
- function hideSecrets(conversation, secrets) {
44
+ function hideSecrets(conversation, secrets = {}) {
42
45
  let text = JSON.stringify(conversation);
43
46
  for (const [key, value] of Object.entries(secrets))
44
- text = text.replaceAll(value, `<${key}>`);
47
+ text = text.replaceAll(value, `%${key}%`);
45
48
  return JSON.parse(text);
46
49
  }
47
- function unhideSecrets(message, secrets) {
50
+ function unhideSecrets(message, secrets = {}) {
48
51
  let text = JSON.stringify(message);
49
52
  for (const [key, value] of Object.entries(secrets))
50
- text = text.replaceAll(`<${key}>`, value);
53
+ text = text.replaceAll(`%${key}%`, value);
51
54
  return JSON.parse(text);
52
55
  }
53
56
  function calculateSha1(text) {
package/lib/loop.d.ts CHANGED
@@ -45,10 +45,8 @@ export type LoopOptions = types.CompletionOptions & LoopEvents & {
45
45
  tools?: types.Tool[];
46
46
  callTool?: types.ToolCallback;
47
47
  maxTurns?: number;
48
- cache?: {
49
- messages: types.ReplayCache;
50
- secrets: Record<string, string>;
51
- };
48
+ cache?: types.ReplayCache;
49
+ secrets?: Record<string, string>;
52
50
  summarize?: boolean;
53
51
  };
54
52
  export declare class Loop {
package/lib/loop.js CHANGED
@@ -47,9 +47,8 @@ class Loop {
47
47
  throw new Error(`Budget tokens ${options.maxTokens} exhausted`);
48
48
  debug?.('lowire:loop')(`Turn ${turns + 1} of (max ${maxTurns})`);
49
49
  const caches = options.cache ? {
50
- input: options.cache.messages,
50
+ input: options.cache,
51
51
  output: this._cacheOutput,
52
- secrets: options.cache.secrets
53
52
  } : undefined;
54
53
  const summarizedConversation = options.summarize ? this._summarizeConversation(task, conversation, options) : conversation;
55
54
  const beforeStatus = await options.onBeforeTurn?.({ conversation: summarizedConversation, totalUsage, budgetTokens });
@@ -161,5 +160,7 @@ function wrapToolWithIsDone(tool) {
161
160
  };
162
161
  }
163
162
  const systemPrompt = `
164
- You are an autonomous agent designed to complete tasks by interacting with tools. Perform the user task.
163
+ - You are an autonomous agent designed to complete tasks by interacting with tools.
164
+ - Perform the user task.
165
+ - If you see text surrounded by %, it is a secret and you should preserve it as such. It will be replaced with the actual value before the tool call.
165
166
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowire/loop",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "Small agentic loop",
5
5
  "repository": {
6
6
  "type": "git",