@guuey/host 0.1.0 → 0.2.1

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.
@@ -20,18 +20,21 @@
20
20
  * `@guuey/worker`, `@guuey/config`, and Node built-ins.
21
21
  */
22
22
  import type { CanUseTool, Options, SDKMessage } from "@anthropic-ai/claude-agent-sdk";
23
- import type { Fs, HistoryMessage, JsonValue } from "@guuey/worker";
24
- import { type GuueyAgent } from "@guuey/config";
23
+ import type { Fs, HistoryMessage, JsonValue, ProfileSection } from "@guuey/worker";
24
+ import { type GuueyAgent, type ProfileAccess } from "@guuey/config";
25
25
  export type { SDKMessage };
26
26
  /**
27
27
  * Env-var names the Router injects so agent code reaches the home/app layers
28
- * portably. Host-owned copies of `@guuey/fs`'s `ENV_HOME_DIR`/`ENV_APP_DIR`
29
- * (trivial string literals not imported, to keep this package OSS-legal).
28
+ * portably. Host-owned copies (trivial string literals — not imported, to
29
+ * keep this published package OSS-legal: it cannot depend on the
30
+ * platform-private `@guuey-private/fs-contract`). Sync sites if these ever
31
+ * change: `backend/libs/fs-contract/src/contract.ts` (the platform-internal
32
+ * source of truth) and `oss/packages/fs/src/roots.ts` (the public dev-guidance
33
+ * helper's own copy, same OSS-legality constraint).
30
34
  */
31
35
  export declare const ENV_HOME_DIR = "GUUEY_HOME_DIR";
32
36
  export declare const ENV_APP_DIR = "GUUEY_APP_DIR";
33
- export type { CredentialFile } from "../creds.js";
34
- import type { CredentialFile } from "../creds.js";
37
+ import type { CredentialFile } from "@guuey/worker";
35
38
  /**
36
39
  * SDK's `mcpServers` value shape — recreated structurally rather than imported
37
40
  * because the SDK ships it as part of `Options['mcpServers']` (a record-of-union)
@@ -104,6 +107,43 @@ export interface BuildOptionsContext {
104
107
  priorMemory?: PriorMemoryRecord[];
105
108
  /** Prior working-state blob for the `<working_state>` preamble. */
106
109
  priorState?: JsonValue;
110
+ /**
111
+ * Content of the authenticated caller's `<home>/memories/MEMORY.md` file —
112
+ * prompted memory's RECALL half (memory-mcp spec §4), read Router-side BEFORE
113
+ * this invoke so recall never depends on the model choosing to read a file.
114
+ * Rendered into the RECALL block of the "## What you remember about this user"
115
+ * section when present (the SAVE half is gated on {@link memoryAttached}, not
116
+ * this). DISTINCT from {@link priorMemory}: that is the persistence-fold
117
+ * THREAD-scoped conversation memory (AgJSON `<thread_memory>` preamble); this
118
+ * is the cross-session, cross-thread USER memory file. Absent for an anonymous
119
+ * caller (never read Router-side) and for an authenticated caller with no
120
+ * memory file yet (turn one — the SAVE instruction still renders via
121
+ * {@link memoryAttached}).
122
+ */
123
+ userMemory?: string;
124
+ /**
125
+ * Whether the memory MCP child booted this pod (memory-mcp T5) — the Router
126
+ * threads it per-invoke. Gates the SAVE instruction (`save_memory`) on
127
+ * `authMode === "authenticated" && memoryAttached`, INDEPENDENT of
128
+ * {@link userMemory}: the bootstrap fix so a brand-new authenticated user is
129
+ * told the tool exists before any file. Was previously proxied by `fs`; this
130
+ * is the real signal (the tool is spliced iff this is true for an
131
+ * authenticated invoke).
132
+ */
133
+ memoryAttached?: boolean;
134
+ /**
135
+ * The Router's fail-closed cross-app profile access for this invoke
136
+ * (cross-app-profile T7) — present ONLY for a consenting authenticated caller,
137
+ * clamped to the app's declared posture. Gates the profile system-prompt
138
+ * section ({@link buildProfileSection}): the `save_profile` SAVE instruction on
139
+ * `read-write`, the RECALL block on {@link profileSections}. DISTINCT from
140
+ * {@link memoryAttached}: that is this app's own memory tool; this is the
141
+ * consent-gated cross-app profile.
142
+ */
143
+ profileAccess?: ProfileAccess;
144
+ /** The user's cross-app profile sections for the RECALL push (cross-app-profile
145
+ * T7), read Router-side. Gated by {@link profileAccess}. */
146
+ profileSections?: ProfileSection[];
107
147
  /**
108
148
  * Returns every credential the Router broker wrote to
109
149
  * `<sessionDir>/.guuey/credentials/` this invoke — one `{name, cred}` per
@@ -1 +1 @@
1
- {"version":3,"file":"claude-options.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAE9F,YAAY,EAAE,UAAU,EAAE,CAAC;AAa3B;;;;GAIG;AACH,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAoB3C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACrF;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACpF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9E;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,WAAW,GAAG,eAAe,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,4EAA4E;IAC5E,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,mEAAmE;IACnE,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IACrE,iEAAiE;IACjE,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CA6HpF;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,EAAE,UACiC,CAAC;AAE9D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAgBxF;AA8BD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"claude-options.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude-options.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { GUUEY_DEFAULT_SYSTEM_PROMPT, defaultModelFor } from "@guuey/config";
1
+ import { GUUEY_DEFAULT_SYSTEM_PROMPT, defaultModelFor, } from "@guuey/config";
2
2
  /**
3
3
  * Default Claude model — only used when the snapshot omits `model`. Derived
4
4
  * from the `@guuey/config` registry (single source of truth per the
@@ -10,8 +10,12 @@ const DEFAULT_MODEL = defaultModelFor("claude-agent-sdk");
10
10
  const DEFAULT_MAX_TURNS = 25;
11
11
  /**
12
12
  * Env-var names the Router injects so agent code reaches the home/app layers
13
- * portably. Host-owned copies of `@guuey/fs`'s `ENV_HOME_DIR`/`ENV_APP_DIR`
14
- * (trivial string literals not imported, to keep this package OSS-legal).
13
+ * portably. Host-owned copies (trivial string literals — not imported, to
14
+ * keep this published package OSS-legal: it cannot depend on the
15
+ * platform-private `@guuey-private/fs-contract`). Sync sites if these ever
16
+ * change: `backend/libs/fs-contract/src/contract.ts` (the platform-internal
17
+ * source of truth) and `oss/packages/fs/src/roots.ts` (the public dev-guidance
18
+ * helper's own copy, same OSS-legality constraint).
15
19
  */
16
20
  export const ENV_HOME_DIR = "GUUEY_HOME_DIR";
17
21
  export const ENV_APP_DIR = "GUUEY_APP_DIR";
@@ -29,6 +33,56 @@ const FS_TOOLS = ["Read", "Write", "Edit", "Glob", "Grep"];
29
33
  * bubblewrap inside the Router's bwrap); the Router's bwrap IS the isolation.
30
34
  */
31
35
  const BASH_TOOL = "Bash";
36
+ /**
37
+ * Belt-and-braces (spec §4): guuey's memory mechanism is prompted file memory
38
+ * (a platform-owned system-prompt section, below), never the SDK's own
39
+ * auto-memory. Set UNCONDITIONALLY on every `Options` this module builds so a
40
+ * future SDK default flip can never start writing its own memory format into
41
+ * the durable, quota-billed home layer without Guuey explicitly opting in.
42
+ */
43
+ const AUTO_MEMORY_DISABLED = { autoMemoryEnabled: false };
44
+ /**
45
+ * Build the platform-owned memory system-prompt section (memory-mcp spec §4):
46
+ * the SAVE instruction plus, when {@link BuildOptionsContext.userMemory} is
47
+ * present, a RECALL block rendering the Router-read `MEMORY.md` content. Gated
48
+ * on `authMode === "authenticated"` AND {@link BuildOptionsContext.memoryAttached}
49
+ * — the memory child booted this pod, so the `save_memory` tool is spliced. A
50
+ * guest has no memory tool (the spec forbids offering it), and an unattached pod
51
+ * has no tool to name. Returns `""` (append-safe) when out of scope.
52
+ *
53
+ * The SAVE gate is ATTACHMENT, not file presence — so a brand-new authenticated
54
+ * user (no `MEMORY.md` yet) STILL gets the save instruction (save-only section)
55
+ * and can bootstrap turn-one durable memory. The RECALL block is separately
56
+ * gated on `userMemory` presence INSIDE {@link renderMemorySection}.
57
+ *
58
+ * Gate change (memory-mcp T5 review): was `ctx.fs` (a proxy for attachment).
59
+ * `memoryAttached` is the REAL signal — it no longer over-renders in the
60
+ * transient fs-on-but-child-unattached window, and no longer under-renders when
61
+ * the tool exists. Delegates to the framework-neutral {@link renderMemorySection}
62
+ * (`../preamble.js`) so Claude, OpenAI, and ADK all render the IDENTICAL section;
63
+ * its RECALL block is byte-identical to the pre-factor inline string (pinned).
64
+ */
65
+ function buildMemorySection(ctx) {
66
+ if (ctx.identity.authMode !== "authenticated" || !ctx.memoryAttached)
67
+ return "";
68
+ return renderMemorySection(ctx.userMemory);
69
+ }
70
+ /**
71
+ * Build the platform-owned cross-app profile system-prompt section
72
+ * (cross-app-profile spec §4) — the SIBLING of {@link buildMemorySection},
73
+ * appended AFTER it. Gated on `authMode === "authenticated"` AND a resolved
74
+ * {@link BuildOptionsContext.profileAccess} (the Router's fail-closed grant
75
+ * check produced a live, clamped access level). A guest / an ungranted app never
76
+ * reaches here. Delegates to the framework-neutral {@link renderProfileSection}
77
+ * (`../preamble.js`) so Claude, OpenAI, and ADK render the IDENTICAL section; that
78
+ * renderer owns the two inner gates (SAVE on `read-write`, RECALL on sections
79
+ * presence). Returns `""` (append-safe) when out of scope.
80
+ */
81
+ function buildProfileSection(ctx) {
82
+ if (ctx.identity.authMode !== "authenticated" || ctx.profileAccess === undefined)
83
+ return "";
84
+ return renderProfileSection(ctx.profileSections, ctx.profileAccess);
85
+ }
32
86
  /**
33
87
  * Build the Claude Agent SDK `Options` for one invoke. Pure: all disk/env access
34
88
  * is injected via {@link BuildOptionsContext}. Throws on an unresolved `{file}`
@@ -52,7 +106,12 @@ export function buildOptions(snapshot, ctx) {
52
106
  }
53
107
  const mcpServers = resolveMcpServers(ctx);
54
108
  const allowedTools = buildAllowedTools(snapshot, Object.keys(mcpServers), Boolean(ctx.fs));
55
- const systemPrompt = withContextPreamble(snapshot.systemPrompt ?? GUUEY_DEFAULT_SYSTEM_PROMPT, ctx.history, ctx.priorMemory, ctx.priorState);
109
+ const systemPrompt = withContextPreamble(snapshot.systemPrompt ?? GUUEY_DEFAULT_SYSTEM_PROMPT, ctx.history, ctx.priorMemory, ctx.priorState) +
110
+ buildMemorySection(ctx) +
111
+ // cross-app-profile T7: the profile section is a SIBLING of the memory
112
+ // section, appended AFTER it (memory first, then profile). Both are
113
+ // framework-blind renderers from ../preamble.js.
114
+ buildProfileSection(ctx);
56
115
  const model = snapshot.model ?? DEFAULT_MODEL;
57
116
  const maxTurns = snapshot.runtime?.maxTurns ?? DEFAULT_MAX_TURNS;
58
117
  const fs = ctx.fs;
@@ -70,8 +129,21 @@ export function buildOptions(snapshot, ctx) {
70
129
  // Explicit Record<string, string> annotation prevents TypeScript from widening
71
130
  // the ternary to a union `{ K: string } | {}`, which would make spread targets
72
131
  // produce optional-undefined keys that conflict with Record<string, string>.
132
+ // CLAUDE_CONFIG_DIR pins the CLI's own config/state root to the (ephemeral,
133
+ // pod-local) session dir — spec §4 belt-and-braces, alongside the
134
+ // unconditional `settings.autoMemoryEnabled:false` below — so CLI session
135
+ // state never lands in the durable, quota-billed home layer.
136
+ // XDG_CACHE_HOME likewise: the CLI's cache tree (~/.cache/claude-cli-nodejs,
137
+ // MCP logs etc.) follows $HOME by XDG default, and $HOME resolves inside the
138
+ // durable home mount — live-found on the first G5 gate run (2026-07-20)
139
+ // leaking per-invoke log files into quota-billed storage.
73
140
  const fsEnv = fs
74
- ? { [ENV_HOME_DIR]: fs.home, [ENV_APP_DIR]: fs.app }
141
+ ? {
142
+ [ENV_HOME_DIR]: fs.home,
143
+ [ENV_APP_DIR]: fs.app,
144
+ CLAUDE_CONFIG_DIR: fs.session,
145
+ XDG_CACHE_HOME: fs.session,
146
+ }
75
147
  : {};
76
148
  let env;
77
149
  if (baseUrl !== undefined && authToken !== undefined) {
@@ -102,6 +174,15 @@ export function buildOptions(snapshot, ctx) {
102
174
  model,
103
175
  mcpServers,
104
176
  allowedTools,
177
+ // Token streaming (guuey#91 consumer half): the SDK interleaves
178
+ // `stream_event` partials, which `@silverprotocol/claude-agent-sdk` ≥0.4
179
+ // maps to token-granular text/reasoning/tool.args deltas and dedupes
180
+ // against the complete assistant message that follows. The Router passes
181
+ // stream_event through its structural SDKMessage guard untouched, and the
182
+ // render meter never reads partials (it bills user-message tool-results,
183
+ // idempotent by tool_use id), so this flag's only observable effect is
184
+ // incremental frames on the SSE wire.
185
+ includePartialMessages: true,
105
186
  // With GuueyFS layers bound, expose the file tools PLUS real `Bash`; without
106
187
  // them this is byte-identical to the source (purely MCP-driven). `Bash` is
107
188
  // safe here because the host already runs inside the Router's bubblewrap
@@ -111,6 +192,13 @@ export function buildOptions(snapshot, ctx) {
111
192
  // against a future SDK change auto-pulling `~/.claude/settings.json` and
112
193
  // leaking the operator's logged-in Claude Code MCPs into the tool catalog.
113
194
  settingSources: [],
195
+ // Belt-and-braces (spec §4): the SDK's OWN auto-memory is disabled
196
+ // UNCONDITIONALLY, on every invoke, regardless of fs/authMode — Guuey's
197
+ // memory mechanism is the platform-owned prompted-file scheme above, not
198
+ // the SDK's. This guards against a future SDK default flip writing its
199
+ // own memory format into (durable, quota-billed) home without Guuey ever
200
+ // opting in.
201
+ settings: AUTO_MEMORY_DISABLED,
114
202
  strictMcpConfig: true,
115
203
  maxTurns,
116
204
  env,
@@ -204,5 +292,7 @@ function buildAllowedTools(snapshot, declaredServerNames, fsBound) {
204
292
  }
205
293
  // withContextPreamble now lives in ../preamble.js (framework-neutral — the
206
294
  // ADK runner renders the same preamble); re-exported for existing importers.
295
+ // `renderMemorySection` (the memory SAVE + RECALL block, memory-mcp T5) lives
296
+ // there too — framework-blind, so openai/adk render the identical section.
207
297
  export { withContextPreamble } from "../preamble.js";
208
- import { withContextPreamble } from "../preamble.js";
298
+ import { renderMemorySection, renderProfileSection, withContextPreamble } from "../preamble.js";
@@ -1 +1 @@
1
- {"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude-runner.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,aAAa,CAAC;AAK3E,wBAAgB,YAAY,IAAI,eAAe,CAa9C"}
1
+ {"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude-runner.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,aAAa,CAAC;AAI3E,wBAAgB,YAAY,IAAI,eAAe,CAa9C"}
@@ -14,8 +14,8 @@
14
14
  * per invoke if neither form is present.
15
15
  */
16
16
  import { query } from "@anthropic-ai/claude-agent-sdk";
17
+ import { listCredentials } from "@guuey/worker";
17
18
  import { runInvoke } from "./claude.js";
18
- import { listCredentials } from "../creds.js";
19
19
  import { buildHostContext } from "../boot-context.js";
20
20
  export function createRunner() {
21
21
  const bootCtx = buildHostContext(process.env);
@@ -10,13 +10,14 @@
10
10
  * `query`.
11
11
  */
12
12
  import type { Options, SDKMessage } from "@anthropic-ai/claude-agent-sdk";
13
- import type { Emitter, Fs, HistoryMessage, Identity, JsonValue } from "@guuey/worker";
14
- import { buildOptions, type CredentialFile, type PriorMemoryRecord } from "./claude-options.js";
13
+ import type { CredentialFile, Emitter, Fs, HistoryMessage, Identity, JsonValue, ProfileSection } from "@guuey/worker";
14
+ import { buildOptions, type PriorMemoryRecord } from "./claude-options.js";
15
15
  /**
16
- * The invoke this host consumes. A superset of `@guuey/worker`'s `Invoke`:
17
- * `priorMemory`/`priorState` are the §1.4 push-by-value context the worker reads
18
- * for the preamble (the Worker Protocol `Invoke` is EXTENDED with these in
19
- * Task 3; until then the worker loop parses them off the raw control line).
16
+ * The invoke this host consumes. Mirrors `@guuey/worker`'s `Invoke` (minus the
17
+ * `type` discriminator): `priorMemory`/`priorState` are the §1.4 push-by-value
18
+ * context the worker renders into the preamble; `userMemory` is the
19
+ * guueyfs-slice4 prompted-file-memory RECALL push (Task 3) see the doc on
20
+ * `Invoke.userMemory` in `@guuey/worker` for how it differs from `priorMemory`.
20
21
  */
21
22
  export interface HostInvoke {
22
23
  input: string;
@@ -25,6 +26,25 @@ export interface HostInvoke {
25
26
  history: HistoryMessage[];
26
27
  priorMemory?: PriorMemoryRecord[];
27
28
  priorState?: JsonValue;
29
+ userMemory?: string;
30
+ /**
31
+ * Whether the memory MCP child booted this pod (memory-mcp T5) — gates the
32
+ * SAVE instruction on `authenticated && memoryAttached`, independent of
33
+ * `userMemory` (the bootstrap fix). See `Invoke.memoryAttached` in
34
+ * `@guuey/worker`.
35
+ */
36
+ memoryAttached?: boolean;
37
+ /**
38
+ * The resolved cross-app profile access for this invoke (cross-app-profile
39
+ * T7) — gates the profile system-prompt section: the `save_profile` SAVE
40
+ * instruction on `read-write`, the RECALL block on {@link profileSections}.
41
+ * Present only for a consenting authenticated caller. See `Invoke.profileAccess`
42
+ * in `@guuey/worker`.
43
+ */
44
+ profileAccess?: "read" | "read-write";
45
+ /** The user's cross-app profile sections for the RECALL push (cross-app-profile
46
+ * T7). See `Invoke.profileSections` in `@guuey/worker`. */
47
+ profileSections?: ProfileSection[];
28
48
  }
29
49
  /** Per-process config the worker resolves once at boot. */
30
50
  export interface HostRuntime {
@@ -1 +1 @@
1
- {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAc,MAAM,eAAe,CAAC;AAClG,OAAO,EACL,YAAY,EAEZ,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAQ7B;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,EAAE,EAAE,EAAE,CAAC;IACP,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,EAAE,MAAM,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,8EAA8E;AAC9E,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC;AA0BhC;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,EACrE,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,IAAI,CAAC,CAgDf"}
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/frameworks/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,EAAE,EACF,cAAc,EACd,QAAQ,EACR,SAAS,EACT,cAAc,EAEf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EAEZ,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAQ7B;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,EAAE,EAAE,EAAE,CAAC;IACP,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IACtC;gEAC4D;IAC5D,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACpC;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,EAAE,MAAM,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,8EAA8E;AAC9E,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC;AA0BhC;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,EACrE,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -49,6 +49,10 @@ export async function runInvoke(snapshot, invoke, runtime, emit, query) {
49
49
  ...(runtime.authToken !== undefined ? { authToken: runtime.authToken } : {}),
50
50
  ...(invoke.priorMemory !== undefined ? { priorMemory: invoke.priorMemory } : {}),
51
51
  ...(invoke.priorState !== undefined ? { priorState: invoke.priorState } : {}),
52
+ ...(invoke.userMemory !== undefined ? { userMemory: invoke.userMemory } : {}),
53
+ ...(invoke.memoryAttached !== undefined ? { memoryAttached: invoke.memoryAttached } : {}),
54
+ ...(invoke.profileAccess !== undefined ? { profileAccess: invoke.profileAccess } : {}),
55
+ ...(invoke.profileSections !== undefined ? { profileSections: invoke.profileSections } : {}),
52
56
  };
53
57
  options = buildOptions(snapshot, ctx);
54
58
  }
@@ -1,7 +1,6 @@
1
- import type { GuueyContext } from "@guuey/config";
2
- import type { Emitter, JsonValue } from "@guuey/worker";
1
+ import { type GuueyContext } from "@guuey/config";
2
+ import { type CredentialFile, type Emitter, type JsonValue } from "@guuey/worker";
3
3
  import type { FrameworkRunner, HostSnapshot, HostTurn } from "../index.js";
4
- import { type CredentialFile } from "../creds.js";
5
4
  /**
6
5
  * Given a require-resolved entry file inside a package, walk up to the
7
6
  * package root and return the absolute path of the root export's `import`
@@ -19,7 +18,7 @@ interface AdkModule {
19
18
  LlmAgent: new (params: {
20
19
  name: string;
21
20
  model: string;
22
- instruction: string;
21
+ instruction: string | (() => string);
23
22
  tools: unknown[];
24
23
  }) => AdkAgent;
25
24
  InMemoryRunner: new (params: {
@@ -1 +1 @@
1
- {"version":3,"file":"google-adk.d.ts","sourceRoot":"","sources":["../../src/frameworks/google-adk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"google-adk.d.ts","sourceRoot":"","sources":["../../src/frameworks/google-adk.ts"],"names":[],"mappings":"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"}
@@ -36,9 +36,10 @@ import { readFileSync } from "node:fs";
36
36
  import { createRequire } from "node:module";
37
37
  import { dirname, join } from "node:path";
38
38
  import { pathToFileURL } from "node:url";
39
+ import { defaultModelFor } from "@guuey/config";
40
+ import { listCredentials } from "@guuey/worker";
39
41
  import { AGENT_ENTRY_ENV, WORKER_ROOT_ENV, loadAgentEntry, materializeAgent, nativeLoad, resolveAgentEntry, } from "../agent-entry.js";
40
- import { listCredentials } from "../creds.js";
41
- import { withContextPreamble } from "../preamble.js";
42
+ import { renderMemorySection, renderProfileSection, withContextPreamble } from "../preamble.js";
42
43
  import { resolveSdkVersion } from "../sdk-version.js";
43
44
  const ADK_FRAMEWORK = "google-adk";
44
45
  /**
@@ -70,7 +71,14 @@ export function importConditionEntry(resolvedEntry) {
70
71
  return undefined;
71
72
  }
72
73
  const ADK_PACKAGE = "@google/adk";
73
- const DEFAULT_MODEL = "gemini-3.5-flash";
74
+ /**
75
+ * Default ADK model — only used when the snapshot omits `model`. Derived
76
+ * from the `@guuey/config` registry (single source of truth per the
77
+ * model-release playbook §8 item A) rather than a bare literal, so a
78
+ * registry default change propagates here automatically — the same idiom
79
+ * `claude-options.ts`'s `DEFAULT_MODEL` uses.
80
+ */
81
+ const DEFAULT_MODEL = defaultModelFor("google-adk");
74
82
  /**
75
83
  * Load `@google/adk`, honoring the single-copy rule: when `entryPath` (the
76
84
  * graceful agent module) is given, resolve the SDK from THAT tree so the
@@ -239,7 +247,29 @@ export function createRunner(deps = {}) {
239
247
  emit.error(`@guuey/host: snapshot.systemPrompt must be a resolved string (got ${JSON.stringify(snapshot.systemPrompt)}).`);
240
248
  return;
241
249
  }
242
- const instruction = withContextPreamble(snapshot.systemPrompt ?? "", turn.history, turn.priorMemory, turn.priorState);
250
+ // The context preamble PLUS the framework-blind memory section (memory-mcp
251
+ // T5: `save_memory` instruction + optional RECALL block, identical to the
252
+ // Claude & OpenAI renderers). The SAVE half is gated on `authenticated &&
253
+ // memoryAttached` — the memory child booted, so the `save_memory` tool is
254
+ // spliced (T4) — NOT on `userMemory` presence: a brand-new authenticated
255
+ // user has no file yet but must still be told the tool exists (the
256
+ // bootstrap fix). The RECALL block inside `renderMemorySection` stays
257
+ // gated on `userMemory` presence. Brace-content in recalled memory is
258
+ // safe: no-code rides `instruction` as a FUNCTION (F7 — bypasses ADK
259
+ // `{var}` substitution), and the graceful path hands it to the dev's
260
+ // factory verbatim.
261
+ const memoryOn = turn.identity.authMode === "authenticated" && turn.memoryAttached === true;
262
+ // cross-app-profile T7: the profile section is a SIBLING of the memory
263
+ // section, appended AFTER it, gated on `authenticated && profileAccess`
264
+ // (a live, clamped grant). Brace-content in recalled profile sections is
265
+ // safe: no-code rides `instruction` as a FUNCTION (F7), and the graceful
266
+ // path hands it to the dev's factory verbatim. `profileAccess` is aliased
267
+ // to a const so the truthy branch narrows it to the required `ProfileAccess`.
268
+ const profileAccess = turn.profileAccess;
269
+ const profileOn = turn.identity.authMode === "authenticated" && profileAccess !== undefined;
270
+ const instruction = withContextPreamble(snapshot.systemPrompt ?? "", turn.history, turn.priorMemory, turn.priorState) +
271
+ (memoryOn ? renderMemorySection(turn.userMemory) : "") +
272
+ (profileOn ? renderProfileSection(turn.profileSections, profileAccess) : "");
243
273
  let agent;
244
274
  try {
245
275
  const toolsets = buildToolsets(adk, listCredentials(turn.fs)());
@@ -249,11 +279,15 @@ export function createRunner(deps = {}) {
249
279
  agent = await materializeAgent(exported, ctx, (message) => process.stderr.write(`${message}\n`));
250
280
  }
251
281
  else {
252
- // No-code: construct from the snapshot.
282
+ // No-code: construct from the snapshot. `instruction` rides as a
283
+ // function (F7, see AdkModule) — the preamble embeds user-authored
284
+ // conversation content that may itself contain `{...}`, and a
285
+ // string instruction would run it through ADK's session-state
286
+ // substitution.
253
287
  agent = new adk.LlmAgent({
254
288
  name: "guuey",
255
289
  model: snapshot.model ?? DEFAULT_MODEL,
256
- instruction,
290
+ instruction: () => instruction,
257
291
  tools: toolsets,
258
292
  });
259
293
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openai-runner.d.ts","sourceRoot":"","sources":["../../src/frameworks/openai-runner.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,aAAa,CAAC;AAgB3E,wBAAgB,YAAY,IAAI,eAAe,CAW9C"}
1
+ {"version":3,"file":"openai-runner.d.ts","sourceRoot":"","sources":["../../src/frameworks/openai-runner.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAA0B,MAAM,aAAa,CAAC;AAe3E,wBAAgB,YAAY,IAAI,eAAe,CAW9C"}
@@ -11,8 +11,8 @@
11
11
  * injected by the Router's `buildWorkerEnv` already routes it.
12
12
  */
13
13
  import { run as openaiRun, setDefaultOpenAIKey } from "@openai/agents";
14
+ import { listCredentials } from "@guuey/worker";
14
15
  import { runInvokeOpenai } from "./openai.js";
15
- import { listCredentials } from "../creds.js";
16
16
  import { buildHostContext } from "../boot-context.js";
17
17
  /**
18
18
  * The real `@openai/agents` `run` (streamed overload), narrowed to the
@@ -14,8 +14,10 @@
14
14
  * without a live model — the entrypoint (`index.ts`) passes the real SDK `run`.
15
15
  *
16
16
  * Snapshot → Agent mapping:
17
- * - `model` → `snapshot.model` (or the SDK's own default when absent —
18
- * NOT Claude's; this is the OpenAI path).
17
+ * - `model` → `snapshot.model`, or (when absent) guuey's own
18
+ * `defaultModelFor("openai-agents-sdk")` NOT the
19
+ * `@openai/agents` SDK's own built-in fallback. Mirrors
20
+ * `claude-options.ts`'s `DEFAULT_MODEL` idiom.
19
21
  * - `instructions` → `systemPrompt` + the §1.4 context preamble (reuses
20
22
  * `withContextPreamble`, identical to the Claude path).
21
23
  * - `mcpServers` → the framework-neutral `resolveMcpServers` output (same
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/frameworks/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EACL,KAAK,EAIL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,eAAe,CAAC;AAOxD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAA+B,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ7E;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa,CAAC,cAAc,CAAC;IACpE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,KACzC,OAAO,CAAC,eAAe,CAAC,CAAC;AAgB9B;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,UAAU,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7C,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CA4Gf"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/frameworks/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EACL,KAAK,EAIL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,eAAe,CAAC;AAQxD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAsB9F;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa,CAAC,cAAc,CAAC;IACpE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,KACzC,OAAO,CAAC,eAAe,CAAC,CAAC;AAgB9B;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,UAAU,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7C,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CA+Hf"}
@@ -14,8 +14,10 @@
14
14
  * without a live model — the entrypoint (`index.ts`) passes the real SDK `run`.
15
15
  *
16
16
  * Snapshot → Agent mapping:
17
- * - `model` → `snapshot.model` (or the SDK's own default when absent —
18
- * NOT Claude's; this is the OpenAI path).
17
+ * - `model` → `snapshot.model`, or (when absent) guuey's own
18
+ * `defaultModelFor("openai-agents-sdk")` NOT the
19
+ * `@openai/agents` SDK's own built-in fallback. Mirrors
20
+ * `claude-options.ts`'s `DEFAULT_MODEL` idiom.
19
21
  * - `instructions` → `systemPrompt` + the §1.4 context preamble (reuses
20
22
  * `withContextPreamble`, identical to the Claude path).
21
23
  * - `mcpServers` → the framework-neutral `resolveMcpServers` output (same
@@ -29,12 +31,26 @@
29
31
  */
30
32
  import { Agent, MaxTurnsExceededError, MCPServerStreamableHttp, } from "@openai/agents";
31
33
  import { resolveMcpServers, withContextPreamble, } from "./claude-options.js";
32
- import { GUUEY_DEFAULT_SYSTEM_PROMPT } from "@guuey/config";
34
+ import { renderMemorySection, renderProfileSection } from "../preamble.js";
35
+ import { GUUEY_DEFAULT_SYSTEM_PROMPT, defaultModelFor } from "@guuey/config";
33
36
  import { resolveSdkVersion } from "../sdk-version.js";
34
37
  /** The framework tag this arm runs — matches the `AgentFramework` enum value. */
35
38
  const OPENAI_FRAMEWORK = "openai-agents-sdk";
36
39
  /** The npm package whose installed version is this framework's `hello.sdkVersion`. */
37
40
  const OPENAI_SDK_PACKAGE = "@openai/agents";
41
+ /**
42
+ * Default OpenAI model — only used when the snapshot omits `model`. Derived
43
+ * from the `@guuey/config` registry (single source of truth per the
44
+ * model-release playbook §8 item A) rather than a bare literal, so a registry
45
+ * default change propagates here automatically — the same idiom
46
+ * `claude-options.ts`'s `DEFAULT_MODEL` / `google-adk.ts`'s `DEFAULT_MODEL`
47
+ * use. Before this constant existed, a model-less snapshot silently fell
48
+ * through to `@openai/agents`' OWN built-in default (verified
49
+ * `gpt-5.4-mini`) — not a registry id, so it escaped the rate-card
50
+ * exact-match guard and shadow-resolved through the `gpt-5.4` row,
51
+ * over-metering a mini model (playbook run 2026-07-25, finding M7).
52
+ */
53
+ const DEFAULT_MODEL = defaultModelFor(OPENAI_FRAMEWORK);
38
54
  /**
39
55
  * Run one invoke through `@openai/agents`. Emits `native` per `RunStreamEvent`,
40
56
  * `done` on completion (with the `max_turns` sentinel + reason on a turn-cap),
@@ -71,7 +87,26 @@ export async function runInvokeOpenai(snapshot, invoke, runtime, emit, run) {
71
87
  if (snapshot.systemPrompt !== undefined && typeof snapshot.systemPrompt !== "string") {
72
88
  throw new Error(`@guuey/host: snapshot.systemPrompt must be a resolved string (got ${JSON.stringify(snapshot.systemPrompt)}). The CLI inlines {file} references before upload; workers never read the filesystem.`);
73
89
  }
74
- instructions = withContextPreamble(snapshot.systemPrompt ?? GUUEY_DEFAULT_SYSTEM_PROMPT, ctx.history, ctx.priorMemory, ctx.priorState);
90
+ // `instructions` = the context preamble PLUS the framework-blind memory
91
+ // section (memory-mcp T5: `save_memory` instruction + optional RECALL block,
92
+ // identical to the Claude & ADK renderers). The SAVE half is gated on
93
+ // `authenticated && memoryAttached` — the memory child booted, so the
94
+ // `save_memory` tool is spliced (T4) — NOT on `userMemory` presence: a
95
+ // brand-new authenticated user has no file yet but must still be told the
96
+ // tool exists (the bootstrap fix). The RECALL block inside
97
+ // `renderMemorySection` stays gated on `userMemory` presence.
98
+ const memoryOn = invoke.identity.authMode === "authenticated" && invoke.memoryAttached === true;
99
+ // cross-app-profile T7: the profile section is a SIBLING of the memory
100
+ // section, appended AFTER it. Gated on `authenticated && profileAccess`
101
+ // (a live, clamped grant); `renderProfileSection` owns the inner SAVE/RECALL
102
+ // gates. `profileAccess` is aliased to a const so the truthy branch narrows
103
+ // it to the non-undefined `ProfileAccess` the renderer requires.
104
+ const profileAccess = invoke.profileAccess;
105
+ const profileOn = invoke.identity.authMode === "authenticated" && profileAccess !== undefined;
106
+ instructions =
107
+ withContextPreamble(snapshot.systemPrompt ?? GUUEY_DEFAULT_SYSTEM_PROMPT, ctx.history, ctx.priorMemory, ctx.priorState) +
108
+ (memoryOn ? renderMemorySection(invoke.userMemory) : "") +
109
+ (profileOn ? renderProfileSection(invoke.profileSections, profileAccess) : "");
75
110
  mcpServers = buildOpenaiMcpServers(ctx);
76
111
  }
77
112
  catch (err) {
@@ -97,7 +132,7 @@ export async function runInvokeOpenai(snapshot, invoke, runtime, emit, run) {
97
132
  name: "guuey-agent",
98
133
  instructions,
99
134
  mcpServers: servers,
100
- ...(snapshot.model !== undefined ? { model: snapshot.model } : {}),
135
+ model: snapshot.model ?? DEFAULT_MODEL,
101
136
  });
102
137
  const stream = await run(agent, invoke.input, {
103
138
  stream: true,