@c4t4/heyamigo 0.8.11 → 0.8.13

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/ai/codex.js CHANGED
@@ -11,9 +11,12 @@
11
11
  // - prompt passed as positional arg
12
12
  //
13
13
  // Configurable via config.codex:
14
- // - yolo (default true): adds --yolo, which bundles no-approvals +
15
- // full sandbox + skip-trust-check. The right default for a headless
16
- // owner-bot; set false to honor runTask's mode-driven sandbox.
14
+ // - model: optional `-m <model>` override. Default = Codex's default.
15
+ // - yolo (default true): emits --dangerously-bypass-approvals-and-sandbox
16
+ // (the documented canonical flag; --yolo is an alias in newer builds).
17
+ // Bundles no-approvals + full sandbox + skip-trust-check. Right
18
+ // default for a headless owner-bot; set false to honor runTask's
19
+ // mode-driven sandbox.
17
20
  // - skipGitRepoCheck (default true): adds --skip-git-repo-check when
18
21
  // yolo is off. Codex refuses to run in untrusted cwds without it.
19
22
  // - extraArgs: appended verbatim. Escape hatch for version drift.
@@ -65,10 +68,15 @@ function laneTimeoutMs(lane) {
65
68
  function buildExecArgs(params) {
66
69
  const cfg = config.codex;
67
70
  const args = ['exec', '--json'];
71
+ if (cfg.model) {
72
+ args.push('-m', cfg.model);
73
+ }
68
74
  if (cfg.yolo) {
69
- // --yolo: no approvals, full sandbox, skip trust check. Single switch
70
- // that covers the owner-bot case. mode is ignored on this path.
71
- args.push('--yolo');
75
+ // Canonical "no approvals + full sandbox + no trust check" switch.
76
+ // Some newer Codex builds expose --yolo as an alias for the same
77
+ // behavior; we use the documented name to stay portable. mode is
78
+ // ignored on this path.
79
+ args.push('--dangerously-bypass-approvals-and-sandbox');
72
80
  }
73
81
  else {
74
82
  if (cfg.skipGitRepoCheck)
@@ -100,6 +108,27 @@ function buildExecArgs(params) {
100
108
  args.push(params.prompt);
101
109
  return args;
102
110
  }
111
+ function extractReply(ev) {
112
+ // Primary shape: item.completed with item.type === 'agent_message'
113
+ if (ev.type === 'item.completed' &&
114
+ ev.item &&
115
+ ev.item.type === 'agent_message' &&
116
+ typeof ev.item.text === 'string') {
117
+ return ev.item.text;
118
+ }
119
+ // Older shape: msg.type === 'agent_message' with msg.message
120
+ if (ev.msg &&
121
+ ev.msg.type === 'agent_message' &&
122
+ typeof ev.msg.message === 'string') {
123
+ return ev.msg.message;
124
+ }
125
+ // Last-ditch top-level fields
126
+ if (typeof ev.message === 'string')
127
+ return ev.message;
128
+ if (typeof ev.text === 'string')
129
+ return ev.text;
130
+ return null;
131
+ }
103
132
  function parseCodexOutput(stdout) {
104
133
  const events = [];
105
134
  for (const line of stdout.split(/\r?\n/)) {
@@ -115,37 +144,29 @@ function parseCodexOutput(stdout) {
115
144
  }
116
145
  if (events.length === 0)
117
146
  return null;
118
- // Find the final agent message. Codex labels it variously across
119
- // versions — try the common shapes in order.
147
+ // Latest agent message wins (handles multi-turn output).
120
148
  let reply = null;
121
149
  for (let i = events.length - 1; i >= 0; i--) {
122
- const ev = events[i];
123
- if (ev.msg?.type === 'agent_message' &&
124
- typeof ev.msg.message === 'string') {
125
- reply = ev.msg.message;
126
- break;
127
- }
128
- if (typeof ev.message === 'string') {
129
- reply = ev.message;
130
- break;
131
- }
132
- if (typeof ev.text === 'string') {
133
- reply = ev.text;
150
+ const r = extractReply(events[i]);
151
+ if (r !== null) {
152
+ reply = r;
134
153
  break;
135
154
  }
136
155
  }
137
156
  if (reply === null)
138
157
  return null;
139
- // Session id — Codex uses different field names across versions.
158
+ // Session id — `thread_id` on thread.started in current Codex; older
159
+ // builds used session_id / conversation_id / response_id.
140
160
  let sessionId;
141
161
  for (const ev of events) {
142
- const id = ev.session_id ?? ev.conversation_id ?? ev.response_id;
162
+ const id = ev.thread_id ?? ev.session_id ?? ev.conversation_id ?? ev.response_id;
143
163
  if (typeof id === 'string' && id) {
144
164
  sessionId = id;
145
165
  break;
146
166
  }
147
167
  }
148
- // Usage — last event with a usage object wins (final turn totals).
168
+ // Usage — turn.completed carries final totals; fall back to any event
169
+ // with a usage object if the type marker is missing.
149
170
  let inputTokens = 0;
150
171
  let outputTokens = 0;
151
172
  let cacheReadTokens = 0;
package/dist/config.js CHANGED
@@ -38,15 +38,21 @@ const ConfigSchema = z.object({
38
38
  }),
39
39
  codex: z
40
40
  .object({
41
- // --yolo on the Codex CLI bundles "no approvals + full sandbox + no
42
- // trust prompts". Right default for a headless owner-bot; flip to
43
- // false if you want runTask's mode to drive the sandbox tier instead.
41
+ // Optional model override. If unset, Codex uses its default. Passed
42
+ // as `-m <model>` to `codex exec`.
43
+ model: z.string().optional(),
44
+ // Field name kept catchy, but the actual flag emitted is the
45
+ // documented one: --dangerously-bypass-approvals-and-sandbox. Some
46
+ // newer Codex builds also accept --yolo as an alias; we use the
47
+ // canonical name for portability. Right default for a headless
48
+ // owner-bot. Set to false to honor runTask's mode-driven sandbox.
44
49
  yolo: z.boolean().default(true),
45
50
  // When yolo=false, still bypass the trust-directory prompt. Codex
46
51
  // refuses to run in an "untrusted" cwd otherwise.
47
52
  skipGitRepoCheck: z.boolean().default(true),
48
53
  // Appended verbatim to every `codex exec` invocation. Escape hatch
49
- // for version-specific flags we haven't first-classed.
54
+ // for version-specific flags we haven't first-classed (e.g. flip
55
+ // back to --yolo if the canonical name ever goes away).
50
56
  extraArgs: z.array(z.string()).default([]),
51
57
  })
52
58
  .default({}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4t4/heyamigo",
3
- "version": "0.8.11",
3
+ "version": "0.8.13",
4
4
  "description": "WhatsApp AI bot powered by Claude with long-term memory, browser control, and role-based access",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",