@ai-ecoverse/slicc-agent 5.5.2 → 5.5.4

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,74 @@
1
+ import {
2
+ AgentDoc,
3
+ defineDoc
4
+ } from "@earendil-works/pi-durable";
5
+ const SELECTION = ["extensions", "tools", "modelTools", "instructions"];
6
+ const ALL = ["model", "thinkingLevel", "cwd", ...SELECTION];
7
+ const SelectionDoc = defineDoc({
8
+ kind: "slicc.selection",
9
+ version: 1,
10
+ scope: "session",
11
+ initial: () => ({ version: 0 })
12
+ });
13
+ const SELECTION_VERSION = 1;
14
+ async function storedAgent(harness, conversationId, context) {
15
+ return structuredClone(await harness.snapshot(AgentDoc, conversationId, context) ?? {});
16
+ }
17
+ function copyAgent(from, fields = ALL) {
18
+ return async (tx, conversationId) => {
19
+ const agent = await tx.doc(AgentDoc, conversationId);
20
+ for (const field of fields) {
21
+ const value = from[field];
22
+ if (value === void 0) delete agent[field];
23
+ else agent[field] = structuredClone(value);
24
+ }
25
+ };
26
+ }
27
+ function unfrozen(agent, choosable) {
28
+ let changed = false;
29
+ if (Array.isArray(agent.extensions)) {
30
+ delete agent.extensions;
31
+ changed = true;
32
+ }
33
+ if (Array.isArray(agent.tools) && !agent.tools.every(choosable)) {
34
+ delete agent.tools;
35
+ changed = true;
36
+ }
37
+ return changed;
38
+ }
39
+ function unfreezeCreated(choosable) {
40
+ return async (tx, conversation) => {
41
+ unfrozen(await tx.doc(AgentDoc, conversation.id), choosable);
42
+ };
43
+ }
44
+ async function unfreeze(harness, storage, choosable, context) {
45
+ const done = await harness.snapshot(SelectionDoc, context);
46
+ if ((done?.version ?? 0) >= SELECTION_VERSION) return 0;
47
+ let fixed = 0;
48
+ let cursor;
49
+ do {
50
+ const page = await storage.scanConversations({}, 100, cursor, context);
51
+ for (const record of page.items)
52
+ if (await harness.commit(
53
+ async (tx) => unfrozen(await tx.doc(AgentDoc, record.id), choosable),
54
+ context
55
+ ))
56
+ fixed++;
57
+ cursor = page.next;
58
+ } while (cursor);
59
+ await harness.commit(async (tx) => {
60
+ (await tx.doc(SelectionDoc)).version = SELECTION_VERSION;
61
+ }, context);
62
+ return fixed;
63
+ }
64
+ export {
65
+ SELECTION,
66
+ SELECTION_VERSION,
67
+ SelectionDoc,
68
+ copyAgent,
69
+ storedAgent,
70
+ unfreeze,
71
+ unfreezeCreated,
72
+ unfrozen
73
+ };
74
+ //# sourceMappingURL=selection.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/selection.ts"],
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n AgentDoc,\n type AgentState,\n type ConversationId,\n type ConversationInit,\n type Cursor,\n defineDoc,\n type Harness,\n type HarnessOptions,\n type Storage,\n} from '@earendil-works/pi-durable';\n\nexport type Choosable = (tool: string) => boolean;\n\ntype Field = keyof AgentState;\n\nexport const SELECTION: readonly Field[] = ['extensions', 'tools', 'modelTools', 'instructions'];\n\nconst ALL: readonly Field[] = ['model', 'thinkingLevel', 'cwd', ...SELECTION];\n\nexport const SelectionDoc = defineDoc<{ version: number }>({\n kind: 'slicc.selection',\n version: 1,\n scope: 'session',\n initial: () => ({ version: 0 }),\n});\n\nexport const SELECTION_VERSION = 1;\n\nexport async function storedAgent(\n harness: Pick<Harness, 'snapshot'>,\n conversationId: ConversationId,\n context: Context\n): Promise<AgentState> {\n return structuredClone((await harness.snapshot(AgentDoc, conversationId, context)) ?? {});\n}\n\nexport function copyAgent(from: AgentState, fields: readonly Field[] = ALL): ConversationInit {\n return async (tx, conversationId) => {\n const agent = (await tx.doc(AgentDoc, conversationId)) as Record<string, unknown>;\n for (const field of fields) {\n const value = from[field];\n if (value === undefined) delete agent[field];\n else agent[field] = structuredClone(value);\n }\n };\n}\n\nexport function unfrozen(agent: AgentState, choosable: Choosable): boolean {\n let changed = false;\n if (Array.isArray(agent.extensions)) {\n delete agent.extensions;\n changed = true;\n }\n if (Array.isArray(agent.tools) && !agent.tools.every(choosable)) {\n delete agent.tools;\n changed = true;\n }\n return changed;\n}\n\nexport function unfreezeCreated(choosable: Choosable): HarnessOptions['conversationCreated'] {\n return async (tx, conversation) => {\n unfrozen(await tx.doc(AgentDoc, conversation.id), choosable);\n };\n}\n\nexport async function unfreeze(\n harness: Pick<Harness, 'snapshot' | 'commit'>,\n storage: Pick<Storage, 'scanConversations'>,\n choosable: Choosable,\n context: Context\n): Promise<number> {\n const done = await harness.snapshot(SelectionDoc, context);\n if ((done?.version ?? 0) >= SELECTION_VERSION) return 0;\n let fixed = 0;\n let cursor: Cursor | undefined;\n do {\n const page = await storage.scanConversations({}, 100, cursor, context);\n for (const record of page.items)\n if (\n await harness.commit(\n async (tx) => unfrozen(await tx.doc(AgentDoc, record.id), choosable),\n context\n )\n )\n fixed++;\n cursor = page.next;\n } while (cursor);\n await harness.commit(async (tx) => {\n (await tx.doc(SelectionDoc)).version = SELECTION_VERSION;\n }, context);\n return fixed;\n}\n"],
5
+ "mappings": "AACA;AAAA,EACE;AAAA,EAKA;AAAA,OAIK;AAMA,MAAM,YAA8B,CAAC,cAAc,SAAS,cAAc,cAAc;AAE/F,MAAM,MAAwB,CAAC,SAAS,iBAAiB,OAAO,GAAG,SAAS;AAErE,MAAM,eAAe,UAA+B;AAAA,EACzD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS,OAAO,EAAE,SAAS,EAAE;AAC/B,CAAC;AAEM,MAAM,oBAAoB;AAEjC,eAAsB,YACpB,SACA,gBACA,SACqB;AACrB,SAAO,gBAAiB,MAAM,QAAQ,SAAS,UAAU,gBAAgB,OAAO,KAAM,CAAC,CAAC;AAC1F;AAEO,SAAS,UAAU,MAAkB,SAA2B,KAAuB;AAC5F,SAAO,OAAO,IAAI,mBAAmB;AACnC,UAAM,QAAS,MAAM,GAAG,IAAI,UAAU,cAAc;AACpD,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ,KAAK,KAAK;AACxB,UAAI,UAAU,OAAW,QAAO,MAAM,KAAK;AAAA,UACtC,OAAM,KAAK,IAAI,gBAAgB,KAAK;AAAA,IAC3C;AAAA,EACF;AACF;AAEO,SAAS,SAAS,OAAmB,WAA+B;AACzE,MAAI,UAAU;AACd,MAAI,MAAM,QAAQ,MAAM,UAAU,GAAG;AACnC,WAAO,MAAM;AACb,cAAU;AAAA,EACZ;AACA,MAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC,MAAM,MAAM,MAAM,SAAS,GAAG;AAC/D,WAAO,MAAM;AACb,cAAU;AAAA,EACZ;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,WAA6D;AAC3F,SAAO,OAAO,IAAI,iBAAiB;AACjC,aAAS,MAAM,GAAG,IAAI,UAAU,aAAa,EAAE,GAAG,SAAS;AAAA,EAC7D;AACF;AAEA,eAAsB,SACpB,SACA,SACA,WACA,SACiB;AACjB,QAAM,OAAO,MAAM,QAAQ,SAAS,cAAc,OAAO;AACzD,OAAK,MAAM,WAAW,MAAM,kBAAmB,QAAO;AACtD,MAAI,QAAQ;AACZ,MAAI;AACJ,KAAG;AACD,UAAM,OAAO,MAAM,QAAQ,kBAAkB,CAAC,GAAG,KAAK,QAAQ,OAAO;AACrE,eAAW,UAAU,KAAK;AACxB,UACE,MAAM,QAAQ;AAAA,QACZ,OAAO,OAAO,SAAS,MAAM,GAAG,IAAI,UAAU,OAAO,EAAE,GAAG,SAAS;AAAA,QACnE;AAAA,MACF;AAEA;AACJ,aAAS,KAAK;AAAA,EAChB,SAAS;AACT,QAAM,QAAQ,OAAO,OAAO,OAAO;AACjC,KAAC,MAAM,GAAG,IAAI,YAAY,GAAG,UAAU;AAAA,EACzC,GAAG,OAAO;AACV,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -10,6 +10,7 @@ export interface AgentOptions {
10
10
  registry?: Registry;
11
11
  settings?: HarnessOptions['settings'];
12
12
  env?: HarnessOptions['env'];
13
+ conversationCreated?: HarnessOptions['conversationCreated'];
13
14
  context?: Context;
14
15
  beforeResume?: (harness: Harness, context: Context) => Promise<unknown>;
15
16
  }
@@ -1,4 +1,4 @@
1
- import { type Extension, type ToolRegistration } from '@earendil-works/pi-durable';
1
+ import { type Extension } from '@earendil-works/pi-durable';
2
2
  import { FACADE_PORT, ownKernelServer } from '../kernel/loopback.ts';
3
3
  import { type ProtectedMatcher } from './origins.ts';
4
4
  export declare const BROWSER_GUARD = "slicc-browser-guard";
@@ -8,4 +8,4 @@ export declare function foreignKernel(url: string): boolean;
8
8
  export declare function forbidden(url: string, matcher: ProtectedMatcher): boolean;
9
9
  export declare function candidates(raw: string): string[];
10
10
  export declare function refused(command: string, matcher: ProtectedMatcher): boolean;
11
- export declare function browserGuard(origins: readonly string[], tools: readonly ToolRegistration[]): Extension;
11
+ export declare function browserGuard(origins: readonly string[]): Extension;
@@ -25,7 +25,7 @@ export interface CodemodeOptions {
25
25
  extra?: (api: ToolExecutionApi, agent: Agent, context: Context) => Promise<CodemodeExtra>;
26
26
  }
27
27
  export declare function codemodeDescription(declared: readonly ToolRegistration[], discovery?: boolean): string;
28
- export declare function callNested(tool: ToolRegistration, args: unknown, api: ToolExecutionApi, context: Context, id: string): Promise<unknown>;
28
+ export declare function callNested(name: string, args: unknown, api: ToolExecutionApi, context: Context): Promise<unknown>;
29
29
  export declare function formatOutput(output: readonly CodemodeOutputItem[]): CodemodeOutputItem[];
30
30
  export declare function joinText(items: readonly CodemodeOutputItem[]): CodemodeOutputItem[];
31
31
  export declare function formatError(error: CodemodeError, calls: CodemodeResult['calls']): string;
@@ -1,5 +1,5 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
- import { type ConversationId, type Extension, type Submission, type ToolRegistration, type Tx } from '@earendil-works/pi-durable';
2
+ import { type ConversationId, type Extension, type Submission, type Tx } from '@earendil-works/pi-durable';
3
3
  import { type ScoopRecord } from '../agents.ts';
4
4
  import { type Layout } from '../layout.ts';
5
5
  import type { LickEvent } from '../licks/licks.ts';
@@ -73,5 +73,5 @@ export declare function scoopsExtension(tasks: ReturnType<typeof scoopTasks>, la
73
73
  export declare function allowed(record: Pick<ScoopRecord, 'folder'> & {
74
74
  roots?: ScoopRecord['roots'];
75
75
  }, coneCwd: string, path: string, writing: boolean, reads?: readonly string[], own?: string): boolean;
76
- export declare function guardExtension(lookup: Lookup, tools: readonly ToolRegistration[]): Extension;
76
+ export declare function guardExtension(lookup: Lookup): Extension;
77
77
  export {};
@@ -6,9 +6,10 @@ import type { ProcessGroups } from '../kernel/groups.ts';
6
6
  import { type Layout } from '../layout.ts';
7
7
  import type { Licks } from '../licks/licks.ts';
8
8
  import { type Roles } from '../roles/roles.ts';
9
+ import type { Choosable } from '../selection.ts';
9
10
  import { type CliOptions } from './cli.ts';
10
11
  import { type ControlPlane } from './requests.ts';
11
- import { type Scoops } from './service.ts';
12
+ import { type EnvOf, type Scoops } from './service.ts';
12
13
  export declare const BUILTIN_ROLES: string[];
13
14
  export declare const PNPM_HOME = "/home/.local/share/pnpm";
14
15
  export declare const BIN_DIR = "/usr/local/bin";
@@ -34,6 +35,7 @@ export interface AttachOptions {
34
35
  mcp?: (names: readonly string[]) => ToolRegistration[];
35
36
  layout?: Layout;
36
37
  enforced?: boolean;
38
+ envOf: EnvOf;
37
39
  spools?: Spools;
38
40
  agentDir?: string;
39
41
  }
@@ -48,6 +50,7 @@ export interface ScoopsRuntime {
48
50
  }
49
51
  export interface ScoopsSetup {
50
52
  scoops: Scoops;
53
+ choosable: Choosable;
51
54
  attach(options: AttachOptions, context: Context): Promise<ScoopsRuntime>;
52
55
  }
53
56
  export declare const COMMANDS: string[];
@@ -1,11 +1,12 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
- import { type AgentChange, type AnyTask, type Conversation, type Harness, type ToolRegistration } from '@earendil-works/pi-durable';
2
+ import { type AgentChange, type AnyTask, type Conversation, type ConversationId, type Harness, type ToolRegistration } from '@earendil-works/pi-durable';
3
3
  import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
4
4
  import { type Agents, type AgentsState, type Mark, type ScoopRecord } from '../agents.ts';
5
5
  import type { ProcessGroups } from '../kernel/groups.ts';
6
6
  import { type Layout } from '../layout.ts';
7
7
  import type { Licks } from '../licks/licks.ts';
8
8
  import type { Role } from '../roles/roles.ts';
9
+ import type { Choosable } from '../selection.ts';
9
10
  export { SCOOPS_ROOT } from '../layout.ts';
10
11
  export declare const LEDGER_SIZE = 512;
11
12
  export type Feed = {
@@ -43,6 +44,7 @@ export interface ScoopTasks {
43
44
  reporter: AnyTask;
44
45
  wait: AnyTask;
45
46
  }
47
+ export type EnvOf = (conversationId: ConversationId, context: Context) => Promise<Pick<ExecutionEnv, 'canonicalPath'> | undefined>;
46
48
  export interface ScoopsHost {
47
49
  harness: Harness;
48
50
  agents: Agents;
@@ -51,6 +53,7 @@ export interface ScoopsHost {
51
53
  tools?: readonly ToolRegistration[];
52
54
  reads?: () => readonly string[];
53
55
  files?: Pick<ExecutionEnv, 'remove' | 'createDir'>;
56
+ envOf?: EnvOf;
54
57
  mcp?: (names: readonly string[]) => ToolRegistration[];
55
58
  layout?: Layout;
56
59
  enforced?: boolean;
@@ -102,6 +105,7 @@ export declare function tail(conversation: Conversation, context: Context): Prom
102
105
  export declare function turnStart(conversation: Conversation, context: Context): Promise<number>;
103
106
  export declare function coneOf(state: Readonly<AgentsState>, conversation: number): string | undefined;
104
107
  export declare function findScoop(state: Readonly<AgentsState>, handle: string, cone: string | null): [string, ScoopRecord] | undefined;
108
+ export declare function choosable(tools: readonly ToolRegistration[]): Choosable;
105
109
  export declare function askerName(state: Readonly<AgentsState>, asker: string | null): string;
106
110
  export declare function createScoops(host: Promise<ScoopsHost>, tasks: () => ScoopTasks): {
107
111
  detach: (made: readonly number[], target: string, context: Context) => Promise<void>;
@@ -1,5 +1,5 @@
1
- import type { Context, JsonValue } from '@earendil-works/chord';
2
- import { type AgentChange, type Extension, type Harness, type Storage, type ToolExecutionResult } from '@earendil-works/pi-durable';
1
+ import type { JsonValue } from '@earendil-works/chord';
2
+ import { type Extension, type ToolExecutionResult } from '@earendil-works/pi-durable';
3
3
  import type { Names, SecretName } from './names.ts';
4
4
  import type { Scrub } from './scrub.ts';
5
5
  import type { Vault } from './vault.ts';
@@ -23,8 +23,6 @@ export declare function secretsEntry(names: readonly SecretName[]): {
23
23
  }[];
24
24
  };
25
25
  export declare function shellGrants(names: Pick<Names, 'state'>): (argv: readonly string[]) => readonly string[];
26
- export declare function pinned<T extends AgentChange>(change: T): T;
27
- export declare function repin(harness: Pick<Harness, 'conversation'>, storage: Pick<Storage, 'scanConversations'>, context: Context): Promise<number>;
28
26
  export declare function secretsExtension(deps: {
29
27
  names: Pick<Names, 'state'>;
30
28
  vault: Pick<Vault, 'ready' | 'texts'>;
@@ -0,0 +1,15 @@
1
+ import type { Context } from '@earendil-works/chord';
2
+ import { type AgentState, type ConversationId, type ConversationInit, type Harness, type HarnessOptions, type Storage } from '@earendil-works/pi-durable';
3
+ export type Choosable = (tool: string) => boolean;
4
+ type Field = keyof AgentState;
5
+ export declare const SELECTION: readonly Field[];
6
+ export declare const SelectionDoc: import("@earendil-works/pi-durable").SessionDocToken<{
7
+ version: number;
8
+ }>;
9
+ export declare const SELECTION_VERSION = 1;
10
+ export declare function storedAgent(harness: Pick<Harness, 'snapshot'>, conversationId: ConversationId, context: Context): Promise<AgentState>;
11
+ export declare function copyAgent(from: AgentState, fields?: readonly Field[]): ConversationInit;
12
+ export declare function unfrozen(agent: AgentState, choosable: Choosable): boolean;
13
+ export declare function unfreezeCreated(choosable: Choosable): HarnessOptions['conversationCreated'];
14
+ export declare function unfreeze(harness: Pick<Harness, 'snapshot' | 'commit'>, storage: Pick<Storage, 'scanConversations'>, choosable: Choosable, context: Context): Promise<number>;
15
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-agent",
3
- "version": "5.5.2",
3
+ "version": "5.5.4",
4
4
  "description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -66,7 +66,7 @@
66
66
  "@ai-ecoverse/slicc-kernel": "1.100.3",
67
67
  "@ai-ecoverse/slicc-scrub": "1.0.0",
68
68
  "@ai-ecoverse/slicc-shared-web": "1.21.0",
69
- "@ai-ecoverse/slicc-spectrum": "1.80.0",
69
+ "@ai-ecoverse/slicc-spectrum": "1.81.0",
70
70
  "@ai-ecoverse/wasm-bash": "5.3.0-18",
71
71
  "@ai-ecoverse/wasm-coreutils": "9.12.0-7",
72
72
  "@ai-ecoverse/wasm-git": "2.55.0-15",