nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: amzn/ion-js
Pull request #648 (2020-11-24 20:02:01)

SharedSymbolTables no longer treat object properties as symbols.
*Issue #, if available:* #645 

*Description of changes:*

Modifies `SharedSymbolTable` (used to represent imported SSTs and the system symbol table) so it avoids co-mingling symbols and object properties.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.



Patch:
diff --git a/src/IonSharedSymbolTable.ts b/src/IonSharedSymbolTable.ts
index 02ac4c9..dfef857 100644
--- a/src/IonSharedSymbolTable.ts
+++ b/src/IonSharedSymbolTable.ts
@@ -30,7 +30,7 @@ export class SharedSymbolTable {
     // Iterate through the symbol array in reverse order so if the same string appears more than
     // once the smaller symbol ID is stored.
     for (let m = _symbols.length - 1; m >= 0; m--) {
-      this._idsByText[_symbols[m]] = m;
+      this._idsByText.set(_symbols[m], m);
     }
   }
 
@@ -61,6 +61,6 @@ export class SharedSymbolTable {
   }
 
   getSymbolId(text: string): number | undefined {
-    return this._idsByText[text];
+    return this._idsByText.get(text);
   }
 }


Test patch:
diff --git a/test/IonLocalSymbolTable.ts b/test/IonLocalSymbolTable.ts
index 05b7640..d59c9d2 100644
--- a/test/IonLocalSymbolTable.ts
+++ b/test/IonLocalSymbolTable.ts
@@ -140,4 +140,16 @@ describe('Local symbol table', () => {
         assert.equal(originalId, duplicateId, "Duplicate symbol was not given original id");
         assert.equal(originalLength + 1, symbolTable.symbols.length, "Duplicate symbol added to symbol table");
     });
-});
\ No newline at end of file
+
+    // See https://github.com/amzn/ion-js/issues/645
+    it('SST Object properties are not treated as symbols (Issue #645)', () => {
+        const symbolTable = defaultLocalSymbolTable();
+        symbolTable.addSymbol("foo");
+        assert.equal(symbolTable.getSymbolId("foo"), 10);
+
+        // 'size' has not been added to the symbol table.
+        // It is, however, a property (an accessor) on the 'Map' data type.
+        // Asking for its symbol ID should return undefined.
+        assert.isUndefined(symbolTable.getSymbolId("size"));
+    });
+});
Repository: amzn/ion-js
Pull request #670 (2021-01-22 20:13:38)

added supoort for JSBI type in Integer equals
*Description of changes:*
Changes to add support for `JSBI.BigInt` comparison in equals API.

*Test:*
Added tests for `JSBI` in Integer comparison.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.



Patch:
diff --git a/src/dom/Integer.ts b/src/dom/Integer.ts
index d372132..6f4aaba 100644
--- a/src/dom/Integer.ts
+++ b/src/dom/Integer.ts
@@ -107,6 +107,9 @@ export class Integer extends Value(Number, IonTypes.INT, _fromJsConstructor) {
       if (other instanceof global.Number || typeof other === "number") {
         isSupportedType = true;
         valueToCompare = other.valueOf();
+      } else if (other instanceof JSBI) {
+        isSupportedType = true;
+        valueToCompare = other;
       }
     }
 


Test patch:
diff --git a/test/dom/equivalence.ts b/test/dom/equivalence.ts
index 08f530f..a738593 100644
--- a/test/dom/equivalence.ts
+++ b/test/dom/equivalence.ts
@@ -1,6 +1,7 @@
 import { assert } from "chai";
 import { Value, load } from "../../src/dom";
 import { Decimal } from "../../src/IonDecimal";
+import JSBI from "jsbi";
 
 /**
  * This file contains 'equals()' tests for each Ion data type:
@@ -62,6 +63,8 @@ describe("Equivalence", () => {
     assert.isFalse(int1.equals(10, { onlyCompareIon: false }));
     assert.isTrue(int1.equals(new Number(7), { onlyCompareIon: false }));
     assert.isFalse(int1.equals(new Number(10), { onlyCompareIon: false }));
+    assert.isTrue(int1.equals(JSBI.BigInt(7), { onlyCompareIon: false }));
+    assert.isFalse(int1.equals(JSBI.BigInt(10), { onlyCompareIon: false }));
   });
 
   it("equals() for Float", () => {
Repository: amzn/ion-js
Pull request #684 (2021-03-15 16:16:15)

Changes for broken struct issue with text parser
*Issue #682*

*Description of changes:*
Changes for throwing error on broken struct as input for text parser. 

*Input:*
```
{broken
```

*Output before change:*
```
Struct { _fields: [Object: null prototype] {} }  // null struct
```

*Output after change:*
```
Error: expected ':'  // throws errror
```

*Test:*
added unit tests for text reader and dom load


Patch:
diff --git a/src/IonParserTextRaw.ts b/src/IonParserTextRaw.ts
index 9591c97..a9fbafd 100644
--- a/src/IonParserTextRaw.ts
+++ b/src/IonParserTextRaw.ts
@@ -687,6 +687,7 @@ export class ParserTextRaw {
       ch = this._read_after_whitespace(true);
       if (ch != CH_CL) {
         this._error("expected ':'");
+        return;
       }
       this._ops.unshift(this._read_struct_comma);
       this._ops.unshift(this._read_value);


Test patch:
diff --git a/test/IonTextReader.ts b/test/IonTextReader.ts
index 9fa9986..6de7f51 100644
--- a/test/IonTextReader.ts
+++ b/test/IonTextReader.ts
@@ -162,6 +162,19 @@ class IonTextReaderTests {
         assert.isNull(ionReader.next());
     }
 
+    @test "Parse through struct throws error on broken input"() {
+        let invalidIonToRead = "{broken";
+
+        let ionReader = ion.makeReader(invalidIonToRead);
+        ionReader.next();
+
+        assert.equal(ion.IonTypes.STRUCT, ionReader.type());
+
+        ionReader.stepIn(); // Step into the base struct.
+
+        assert.throws(() => ionReader.next());
+    }
+
     @test "Reads an array"() {
         let ionToRead = "{ key : ['v1', 'v2'] }";
         let ionReader = ion.makeReader(ionToRead);
diff --git a/test/dom/Value.ts b/test/dom/Value.ts
index a302f25..608a815 100644
--- a/test/dom/Value.ts
+++ b/test/dom/Value.ts
@@ -336,7 +336,7 @@ describe("Value", () => {
       assert.equal(ionSExpression.length, LARGE_CONTAINER_NUM_ENTRIES);
     });
     it("Struct", function () {
-      this.timeout(5_000);
+      this.timeout(6_000);
       let ionStruct = Value.from(largeJsObject) as any;
       assert.equal(ionStruct.getType(), IonTypes.STRUCT);
       assert.equal(ionStruct.fields().length, LARGE_CONTAINER_NUM_ENTRIES);
diff --git a/test/dom/dom.ts b/test/dom/dom.ts
index 510290f..a3b4121 100644
--- a/test/dom/dom.ts
+++ b/test/dom/dom.ts
@@ -491,6 +491,9 @@ describe('DOM', () => {
       }
 
       assert.equal(2, s.fields().length)
+
+      // broken struct
+      assert.throws(() => load('{broken'));
    });
 
    it('load() Struct with duplicate fields as any', () => {
Repository: amzn/ion-js
Pull request #690 (2021-05-07 00:34:39)

added changes for preserving elements() behavior to v4.1.0
*Description of changes:*
This PR works on a breaking change from v4.2.0.

*Changes:*
- modified the `elements()` method from `dom.value#Struct` to return only the last value related to a duplicate fieldname when returning all values. 

*Test:*
- added tests for `elements()` changes. 


Patch:
diff --git a/src/dom/Struct.ts b/src/dom/Struct.ts
index a724bac..ffcbfa8 100644
--- a/src/dom/Struct.ts
+++ b/src/dom/Struct.ts
@@ -140,7 +140,11 @@ export class Struct extends Value(
   }
 
   elements(): Value[] {
-    return Object.values(this._fields);
+    let singleValueFields = Object.create(null);
+    for (const [fieldName, values] of this.allFields()) {
+      singleValueFields[fieldName] = values[values.length - 1];
+    }
+    return Object.values(singleValueFields);
   }
 
   [Symbol.iterator](): IterableIterator<[string, Value]> {


Test patch:
diff --git a/test/dom/dom.ts b/test/dom/dom.ts
index a3b4121..ec6cb76 100644
--- a/test/dom/dom.ts
+++ b/test/dom/dom.ts
@@ -533,6 +533,11 @@ describe('DOM', () => {
       assert.isTrue(s1.getAll('name','middle')![1].equals("Bob"));
       assert.equal(2, s1.getAll('name','middle')!.length);
 
+      // elements returns values for given Struct where for a fieldname it only contains the last value
+      // instead of an array of all values
+      assert.equal(41, s.elements()[0]);
+      assert.isFalse(Array.isArray(s.elements()[0]));
+      assert.equal("Jessie", s1.elements()[0]['first']);
 
       // Iteration
       for (let [fieldName, value] of s) {
Repository: amzn/ion-js
Pull request #726 (2022-10-13 03:01:13)

Support milliseconds when constructing from a Date
*Issue #, if available: #725*

This pull request modifies the constructor behavior to correctly handle a `Date` with non-zero milliseconds.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.


popematt: Thanks for finding and fixing this issue! It looks good, so after the `ion-test-driver` workflow finishes up, I'll go ahead and approve and merge this.
popematt: FYI, @prowe, the `ion-test-driver` is unrelated to your changes. (Probably caused by https://github.com/amzn/ion-test-driver/issues/24.) I'm going to look into it a bit, but if I can't resolve it soon, I think it's safe to merge your change even though we don't have all the usual test coverage. 

Patch:
diff --git a/src/IonTimestamp.ts b/src/IonTimestamp.ts
index 193cedf..5d8562d 100644
--- a/src/IonTimestamp.ts
+++ b/src/IonTimestamp.ts
@@ -97,12 +97,10 @@ export class Timestamp {
   ) {
     if (dateOrLocalOffset instanceof Date) {
       const date = dateOrLocalOffset;
-      const seconds = new Decimal(
-        // The coefficient is the total number of milliseconds as an integer
-        date.getSeconds() + date.getMilliseconds(),
-        // And the exponent is 0 to indicate the scale of that integer
-        0
-      );
+      const seconds =
+        date.getMilliseconds() === 0
+          ? new Decimal(date.getSeconds(), 0)
+          : new Decimal(date.getSeconds() * 1000 + date.getMilliseconds(), -3);
 
       this._localOffset = date.getTimezoneOffset() * -1;
       this._year = date.getFullYear();


Test patch:
diff --git a/test/IonTimestamp.ts b/test/IonTimestamp.ts
index e94a700..7859cbc 100644
--- a/test/IonTimestamp.ts
+++ b/test/IonTimestamp.ts
@@ -250,8 +250,8 @@ describe("Timestamp", () => {
 
         const date2 = new Date(2000, 0, 1, 12, 30, 20, 20);
         let timestamp3 = new ion.Timestamp(date2.getTimezoneOffset() * -1, 2000, 1, 1, 12, 30, new ion.Decimal(
-            40,
-            0
+            20020,
+            -3
         ));
         let timestamp4 = new ion.Timestamp(date2);
         assert.isTrue(timestamp3!.equals(timestamp4!));
Repository: envoyproxy/ai-gateway
Pull request #508 (2025-03-18 15:26:45)

translator: skip adding content if assistant content string is empty
**Commit Message**

AWS Claude 3.5 v1 has cases when assistant returns empty content. Sending that back to AWS will result in a validation error. Will skip adding empty content if string is empty.

```
openai.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/', 'code': '400', 'message': 'The text field in the ContentBlock object at messages.3.content.0 is blank. Add text to the text field, and try again.'}}
```


**Related Issues/PRs (if applicable)**
#486



Patch:
diff --git a/internal/extproc/translator/openai_awsbedrock.go b/internal/extproc/translator/openai_awsbedrock.go
index 0a255af..ba2f99b 100644
--- a/internal/extproc/translator/openai_awsbedrock.go
+++ b/internal/extproc/translator/openai_awsbedrock.go
@@ -245,7 +245,7 @@ func (o *openAIToAWSBedrockTranslatorV1ChatCompletion) openAIMessageToBedrockMes
 ) (*awsbedrock.Message, error) {
 	var bedrockMessage *awsbedrock.Message
 	contentBlocks := make([]*awsbedrock.ContentBlock, 0)
-	if v, ok := openAiMessage.Content.Value.(string); ok {
+	if v, ok := openAiMessage.Content.Value.(string); ok && len(v) > 0 {
 		contentBlocks = append(contentBlocks, &awsbedrock.ContentBlock{Text: &v})
 	} else if content, ok := openAiMessage.Content.Value.(openai.ChatCompletionAssistantMessageParamContent); ok {
 		if content.Type == openai.ChatCompletionAssistantMessageParamContentTypeRefusal {


Test patch:
diff --git a/internal/extproc/translator/openai_awsbedrock_test.go b/internal/extproc/translator/openai_awsbedrock_test.go
index 313c3eb..39beeb0 100644
--- a/internal/extproc/translator/openai_awsbedrock_test.go
+++ b/internal/extproc/translator/openai_awsbedrock_test.go
@@ -107,6 +107,13 @@ func TestOpenAIToAWSBedrockTranslatorV1ChatCompletion_RequestBody(t *testing.T)
 							},
 						}, Type: openai.ChatMessageRoleAssistant,
 					},
+					{
+						Value: openai.ChatCompletionAssistantMessageParam{
+							Content: openai.StringOrAssistantRoleContentUnion{
+								Value: "",
+							},
+						}, Type: openai.ChatMessageRoleAssistant,
+					},
 				},
 			},
 			output: awsbedrock.ConverseInput{
@@ -182,6 +189,10 @@ func TestOpenAIToAWSBedrockTranslatorV1ChatCompletion_RequestBody(t *testing.T)
 							},
 						},
 					},
+					{
+						Role:    openai.ChatMessageRoleAssistant,
+						Content: []*awsbedrock.ContentBlock{},
+					},
 				},
 			},
 		},
Repository: envoyproxy/ai-gateway
Pull request #510 (2025-03-20 17:48:40)

extproc: fixes router to make the first match win
**Commit Message**

Previously, there was a bug in router's code where the matching rule search doesn't break and it iterated over all rules even when there's a matching rule found in the middle. That was a bug in the sense that it is not only an inefficient but also semantically wrong since the last match wins as opposed to the specification of GW API [1] which specifies "If ties still exist within an HTTPRoute, matching precedence MUST be granted to the FIRST matching rule (in list order) with a match meeting the above criteria.".

1: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.HTTPRouteRule


Patch:
diff --git a/internal/extproc/router/router.go b/internal/extproc/router/router.go
index 08b6d4b..63b68bb 100644
--- a/internal/extproc/router/router.go
+++ b/internal/extproc/router/router.go
@@ -32,14 +32,16 @@ func New(config *filterapi.Config, newCustomFn x.NewCustomRouterFn) (x.Router, e
 // Calculate implements [x.Router.Calculate].
 func (r *router) Calculate(headers map[string]string) (backend *filterapi.Backend, err error) {
 	var rule *filterapi.RouteRule
+outer:
 	for i := range r.rules {
 		_rule := &r.rules[i]
-		for _, hdr := range _rule.Headers {
+		for j := range _rule.Headers {
+			hdr := &_rule.Headers[j]
 			v, ok := headers[string(hdr.Name)]
 			// Currently, we only do the exact matching.
 			if ok && v == hdr.Value {
 				rule = _rule
-				break
+				break outer
 			}
 		}
 	}


Test patch:
diff --git a/internal/extproc/router/router_test.go b/internal/extproc/router/router_test.go
index 1e08ea8..194b8ed 100644
--- a/internal/extproc/router/router_test.go
+++ b/internal/extproc/router/router_test.go
@@ -44,6 +44,14 @@ func TestRouter_Calculate(t *testing.T) {
 	outSchema := filterapi.VersionedAPISchema{Name: filterapi.APISchemaOpenAI}
 	_r, err := New(&filterapi.Config{
 		Rules: []filterapi.RouteRule{
+			{
+				Backends: []filterapi.Backend{
+					{Name: "cat", Schema: outSchema},
+				},
+				Headers: []filterapi.HeaderMatch{
+					{Name: "x-some-random-non-model-header", Value: "dog"},
+				},
+			},
 			{
 				Backends: []filterapi.Backend{
 					{Name: "foo", Schema: outSchema, Weight: 1},
@@ -113,6 +121,12 @@ func TestRouter_Calculate(t *testing.T) {
 		require.Greater(t, chosenNames["foo"], 200)
 	})
 
+	t.Run("first match win", func(t *testing.T) {
+		b, err := r.Calculate(map[string]string{"x-some-random-non-model-header": "dog", "x-model-name": "llama3.3333"})
+		require.NoError(t, err)
+		require.Equal(t, "cat", b.Name)
+	})
+
 	t.Run("concurrent access", func(t *testing.T) {
 		var wg sync.WaitGroup
 		wg.Add(1000)
Repository: envoyproxy/ai-gateway
Pull request #511 (2025-03-20 19:56:53)

backport: skip content if assistant content string is empty
**Commit Message**

Ref: (#508)

AWS Claude 3.5 v1 has cases when assistant returns empty content. Sending that back to AWS will result in a validation error. Will skip adding empty content if string is empty.

```
openai.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/', 'code': '400', 'message': 'The text field in the ContentBlock object at messages.3.content.0 is blank. Add text to the text field, and try again.'}}
```


**Related Issues/PRs (if applicable)**
#486


mathetake: nice

Patch:
diff --git a/internal/extproc/translator/openai_awsbedrock.go b/internal/extproc/translator/openai_awsbedrock.go
index 6f94605..b47a981 100644
--- a/internal/extproc/translator/openai_awsbedrock.go
+++ b/internal/extproc/translator/openai_awsbedrock.go
@@ -245,7 +245,7 @@ func (o *openAIToAWSBedrockTranslatorV1ChatCompletion) openAIMessageToBedrockMes
 ) (*awsbedrock.Message, error) {
 	var bedrockMessage *awsbedrock.Message
 	contentBlocks := make([]*awsbedrock.ContentBlock, 0)
-	if v, ok := openAiMessage.Content.Value.(string); ok {
+	if v, ok := openAiMessage.Content.Value.(string); ok && len(v) > 0 {
 		contentBlocks = append(contentBlocks, &awsbedrock.ContentBlock{Text: &v})
 	} else if content, ok := openAiMessage.Content.Value.(openai.ChatCompletionAssistantMessageParamContent); ok {
 		if content.Type == openai.ChatCompletionAssistantMessageParamContentTypeRefusal {


Test patch:
diff --git a/internal/extproc/translator/openai_awsbedrock_test.go b/internal/extproc/translator/openai_awsbedrock_test.go
index 313c3eb..39beeb0 100644
--- a/internal/extproc/translator/openai_awsbedrock_test.go
+++ b/internal/extproc/translator/openai_awsbedrock_test.go
@@ -107,6 +107,13 @@ func TestOpenAIToAWSBedrockTranslatorV1ChatCompletion_RequestBody(t *testing.T)
 							},
 						}, Type: openai.ChatMessageRoleAssistant,
 					},
+					{
+						Value: openai.ChatCompletionAssistantMessageParam{
+							Content: openai.StringOrAssistantRoleContentUnion{
+								Value: "",
+							},
+						}, Type: openai.ChatMessageRoleAssistant,
+					},
 				},
 			},
 			output: awsbedrock.ConverseInput{
@@ -182,6 +189,10 @@ func TestOpenAIToAWSBedrockTranslatorV1ChatCompletion_RequestBody(t *testing.T)
 							},
 						},
 					},
+					{
+						Role:    openai.ChatMessageRoleAssistant,
+						Content: []*awsbedrock.ContentBlock{},
+					},
 				},
 			},
 		},