ag-ai 0.3.0 → 0.3.2

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.
@@ -40,14 +40,18 @@ const opencodeStack = (context) => {
40
40
  (0, common_1.env)('XDG_CACHE_HOME', '/data/opencode/cache'),
41
41
  // The unrestricted /provider response processes thousands of models from
42
42
  // unconfigured providers on every request, exceeding the runner's budget.
43
- // Luna runs at max reasoning so the generation listener advertises and
44
- // honours the effort the cluster fallback asks for.
43
+ // Each advertised model carries the reasoning effort its consumer asks
44
+ // for: sol at high for draft copy, 5.5 at high for draft images, and luna
45
+ // at max for the client's cluster fallback. OpenCode merges these entries
46
+ // with its model catalogue; it does not replace it.
45
47
  (0, common_1.env)('OPENCODE_CONFIG_CONTENT', JSON.stringify({
46
48
  enabled_providers: ['openai', 'google'],
47
49
  provider: {
48
50
  openai: {
49
51
  models: {
52
+ 'gpt-5.6-sol': { options: { reasoningEffort: 'high' } },
50
53
  'gpt-5.6-luna': { options: { reasoningEffort: 'max' } },
54
+ 'gpt-5.5': { options: { reasoningEffort: 'high' } },
51
55
  },
52
56
  },
53
57
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ag-ai",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Provider-neutral AI client and cluster runtime for the rpi-mega cluster.",
5
5
  "license": "ISC",
6
6
  "author": "admin@gec.dev",
@@ -181,6 +181,26 @@ const textFromParts = (parts) => {
181
181
  .join('');
182
182
  };
183
183
 
184
+ /**
185
+ * Read the JSON-schema result of a turn. OpenCode exposes it on the message
186
+ * info (`structured`, or `structured_output` on older builds) and, when the
187
+ * model answers through its synthetic tool, as a completed `StructuredOutput`
188
+ * tool part. Missing structured data stays undefined so the caller can fall
189
+ * back to plain text.
190
+ */
191
+ const structuredFromResponse = (info, parts) => {
192
+ const direct = asObject(info)?.structured ?? asObject(info)?.structured_output;
193
+ if (direct !== undefined) return direct;
194
+ if (!Array.isArray(parts)) return undefined;
195
+ for (const part of parts) {
196
+ const value = asObject(part);
197
+ if (value?.type !== 'tool' || value.tool !== 'StructuredOutput') continue;
198
+ const input = asObject(value.state)?.input;
199
+ if (input !== undefined) return input;
200
+ }
201
+ return undefined;
202
+ };
203
+
184
204
  const usageFromTokens = (tokens) => {
185
205
  const usage = asObject(tokens);
186
206
  if (!usage) return undefined;
@@ -370,7 +390,7 @@ const createOpenCodeExecutor = async ({
370
390
  `OpenCode turn failed: ${asObject(message)?.message ?? info.error.name ?? 'unknown error'}`,
371
391
  );
372
392
  }
373
- const structured = info?.structured_output;
393
+ const structured = structuredFromResponse(info, response?.parts);
374
394
  text =
375
395
  structured === undefined ? textFromParts(response?.parts) : JSON.stringify(structured);
376
396
  model = value.model ?? info?.modelID;