@magpie-community/opencode-trae-auth 0.1.7 → 0.1.8

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.
Files changed (2) hide show
  1. package/index.mjs +50 -12
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -610,16 +610,60 @@ class TextTools {
610
610
  function nativeCall(tc) {
611
611
  const f = tc?.function ?? tc?.function_call ?? tc
612
612
  const name = f?.name ?? tc?.tool_name ?? ""
613
- if (!name) return null
614
- const a = f?.arguments ?? tc?.params ?? tc?.input ?? tc?.parameters ?? {}
615
- return { id: tc?.id || tc?.tool_call_id || "", name: String(name), arguments: typeof a === "string" ? a : JSON.stringify(a) }
613
+ const index = Number.isInteger(tc?.index) ? tc.index : null
614
+ if (!name && index === null && !tc?.id) return null
615
+ const a = f?.arguments ?? f?.args ?? tc?.params ?? tc?.input ?? tc?.parameters ?? ""
616
+ return { id: tc?.id || tc?.tool_call_id || "", index, name: String(name), arguments: typeof a === "string" ? a : JSON.stringify(a) }
617
+ }
618
+
619
+ // NativeCalls puts together the tool calls Trae streams: a call comes in
620
+ // several events under one id (or index), each with the arguments so far
621
+ // or only the new piece, so a call is sent on once the answer is whole,
622
+ // not from its first event (#799: bash's command cut to `echo "T`)
623
+ class NativeCalls {
624
+ constructor() {
625
+ this.calls = []
626
+ }
627
+ push(tc) {
628
+ const c = nativeCall(tc)
629
+ if (!c) return
630
+ let o = this.calls.find((x) => (c.id && x.id === c.id) || (!c.id && c.index !== null && x.index === c.index))
631
+ if (!o && !c.id && c.index === null)
632
+ o = this.calls.findLast((x) => x.name === c.name && (x.arguments === c.arguments || (!done(x.arguments) && c.arguments.startsWith(x.arguments))))
633
+ if (!o) {
634
+ if (!c.name) return
635
+ this.calls.push({ ...c })
636
+ return
637
+ }
638
+ if (!o.name) o.name = c.name
639
+ if (c.index !== null && o.index === null) o.index = c.index
640
+ const prev = o.arguments
641
+ const next = c.arguments
642
+ if (!next || prev.startsWith(next)) return // nothing new
643
+ if (next.startsWith(prev) || done(prev)) o.arguments = next // the arguments so far
644
+ else o.arguments = prev + next // a piece
645
+ }
646
+ take() {
647
+ return this.calls.filter((c) => c.name).map(({ id, name, arguments: a }) => ({ id: id || callId(), name, arguments: a || "{}" }))
648
+ }
649
+ }
650
+
651
+ // done says arguments are a whole JSON value already
652
+ function done(a) {
653
+ if (!a) return false
654
+ try {
655
+ JSON.parse(a)
656
+ return true
657
+ } catch {
658
+ return false
659
+ }
616
660
  }
617
661
 
618
662
  // parts turns Trae's events into what the answer is made of: text,
619
663
  // reasoning, tool calls, the token counts, the finish, or an error.
620
664
  async function* parts(events) {
621
665
  const tt = new TextTools()
622
- const seen = new Set()
666
+ const nc = new NativeCalls()
623
667
  for await (const { event, data } of events) {
624
668
  const name = eventName(event)
625
669
  const d = data && typeof data === "object" ? data : {}
@@ -650,20 +694,14 @@ async function* parts(events) {
650
694
  if (r.text) yield { text: r.text }
651
695
  for (const c of r.calls) yield { call: { ...c, id: callId() } }
652
696
  }
653
- for (const tc of Array.isArray(d.tool_calls) ? d.tool_calls : []) {
654
- const c = nativeCall(tc)
655
- if (!c) continue
656
- const key = c.id || c.name + c.arguments
657
- if (seen.has(key)) continue
658
- seen.add(key)
659
- yield { call: { ...c, id: c.id || callId() } }
660
- }
697
+ for (const tc of Array.isArray(d.tool_calls) ? d.tool_calls : []) nc.push(tc)
661
698
  const u = tokensOf(d.usage)
662
699
  if (u) yield { usage: u }
663
700
  }
664
701
  const r = tt.push("", true)
665
702
  if (r.text) yield { text: r.text }
666
703
  for (const c of r.calls) yield { call: { ...c, id: callId() } }
704
+ for (const c of nc.take()) yield { call: c }
667
705
  }
668
706
 
669
707
  // first reads events up to the first that is the answer's, so an answer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-trae-auth",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "OpenCode provider plugin for Trae CN (trae.cn): your Trae CN account's models, free tier included, with Trae's own browser sign-in",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",