context.dev 2.0.0 → 2.2.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +1 -1
  4. data/lib/context_dev/models/brand_retrieve_params.rb +46 -3
  5. data/lib/context_dev/models/monitor_create_params.rb +36 -28
  6. data/lib/context_dev/models/monitor_create_response.rb +158 -29
  7. data/lib/context_dev/models/monitor_list_account_runs_response.rb +102 -1
  8. data/lib/context_dev/models/monitor_list_params.rb +4 -4
  9. data/lib/context_dev/models/monitor_list_response.rb +158 -29
  10. data/lib/context_dev/models/monitor_list_runs_response.rb +100 -1
  11. data/lib/context_dev/models/monitor_retrieve_change_response.rb +1 -8
  12. data/lib/context_dev/models/monitor_retrieve_response.rb +158 -29
  13. data/lib/context_dev/models/monitor_update_params.rb +36 -28
  14. data/lib/context_dev/models/monitor_update_response.rb +158 -29
  15. data/lib/context_dev/resources/brand.rb +4 -2
  16. data/lib/context_dev/resources/monitors.rb +1 -1
  17. data/lib/context_dev/version.rb +1 -1
  18. data/rbi/context_dev/models/brand_retrieve_params.rbi +67 -0
  19. data/rbi/context_dev/models/monitor_create_params.rbi +44 -33
  20. data/rbi/context_dev/models/monitor_create_response.rbi +243 -33
  21. data/rbi/context_dev/models/monitor_list_account_runs_response.rbi +204 -3
  22. data/rbi/context_dev/models/monitor_list_params.rbi +9 -6
  23. data/rbi/context_dev/models/monitor_list_response.rbi +247 -33
  24. data/rbi/context_dev/models/monitor_list_runs_response.rbi +204 -3
  25. data/rbi/context_dev/models/monitor_retrieve_change_response.rbi +0 -9
  26. data/rbi/context_dev/models/monitor_retrieve_response.rbi +243 -33
  27. data/rbi/context_dev/models/monitor_update_params.rbi +44 -33
  28. data/rbi/context_dev/models/monitor_update_response.rbi +243 -33
  29. data/rbi/context_dev/resources/brand.rbi +4 -1
  30. data/rbi/context_dev/resources/monitors.rbi +2 -2
  31. data/sig/context_dev/models/brand_retrieve_params.rbs +26 -0
  32. data/sig/context_dev/models/monitor_create_params.rbs +7 -17
  33. data/sig/context_dev/models/monitor_create_response.rbs +81 -17
  34. data/sig/context_dev/models/monitor_list_account_runs_response.rbs +74 -3
  35. data/sig/context_dev/models/monitor_list_params.rbs +2 -2
  36. data/sig/context_dev/models/monitor_list_response.rbs +81 -17
  37. data/sig/context_dev/models/monitor_list_runs_response.rbs +74 -3
  38. data/sig/context_dev/models/monitor_retrieve_change_response.rbs +0 -7
  39. data/sig/context_dev/models/monitor_retrieve_response.rbs +81 -17
  40. data/sig/context_dev/models/monitor_update_params.rbs +7 -17
  41. data/sig/context_dev/models/monitor_update_response.rbs +81 -17
  42. metadata +2 -2
@@ -67,6 +67,19 @@ module ContextDev
67
67
  sig { returns(Time) }
68
68
  attr_accessor :updated_at
69
69
 
70
+ # Current baseline: the last observed value the monitor compares new snapshots
71
+ # against. Its shape follows `target.type` (page/sitemap/extract). Only populated
72
+ # on GET /monitors/{monitor_id}; null until the first baseline run completes (and
73
+ # after a target or change_detection update, which resets the baseline).
74
+ sig do
75
+ returns(
76
+ T.nilable(
77
+ ContextDev::Models::MonitorUpdateResponse::Baseline::Variants
78
+ )
79
+ )
80
+ end
81
+ attr_accessor :baseline
82
+
70
83
  sig { returns(T.nilable(Time)) }
71
84
  attr_accessor :last_change_at
72
85
 
@@ -137,6 +150,14 @@ module ContextDev
137
150
  ContextDev::Models::MonitorUpdateResponse::Target::Extract::OrHash
138
151
  ),
139
152
  updated_at: Time,
153
+ baseline:
154
+ T.nilable(
155
+ T.any(
156
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsPageBaseline::OrHash,
157
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsSitemapBaseline::OrHash,
158
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsExtractBaseline::OrHash
159
+ )
160
+ ),
140
161
  last_change_at: T.nilable(Time),
141
162
  last_error:
142
163
  T.nilable(
@@ -173,6 +194,11 @@ module ContextDev
173
194
  # Discriminated union describing what the monitor watches.
174
195
  target:,
175
196
  updated_at:,
197
+ # Current baseline: the last observed value the monitor compares new snapshots
198
+ # against. Its shape follows `target.type` (page/sitemap/extract). Only populated
199
+ # on GET /monitors/{monitor_id}; null until the first baseline run completes (and
200
+ # after a target or change_detection update, which resets the baseline).
201
+ baseline: nil,
176
202
  last_change_at: nil,
177
203
  # Error from the most recent failed run; null when the last run succeeded.
178
204
  last_error: nil,
@@ -199,6 +225,10 @@ module ContextDev
199
225
  ContextDev::Models::MonitorUpdateResponse::Status::TaggedSymbol,
200
226
  target: ContextDev::Models::MonitorUpdateResponse::Target::Variants,
201
227
  updated_at: Time,
228
+ baseline:
229
+ T.nilable(
230
+ ContextDev::Models::MonitorUpdateResponse::Baseline::Variants
231
+ ),
202
232
  last_change_at: T.nilable(Time),
203
233
  last_error:
204
234
  T.nilable(ContextDev::Models::MonitorUpdateResponse::LastError),
@@ -257,9 +287,6 @@ module ContextDev
257
287
  )
258
288
  end
259
289
 
260
- sig { returns(String) }
261
- attr_accessor :query
262
-
263
290
  sig { returns(Symbol) }
264
291
  attr_accessor :type
265
292
 
@@ -269,21 +296,19 @@ module ContextDev
269
296
  sig { params(confidence_threshold: Float).void }
270
297
  attr_writer :confidence_threshold
271
298
 
272
- # Detect meaning-level changes that match a natural language query.
299
+ # Detect meaning-level changes to tracked page content, ignoring cosmetic or
300
+ # paraphrase-only differences. Which changes are meaningful is judged against the
301
+ # extract target's `instructions` (and `schema`, when provided).
273
302
  sig do
274
- params(
275
- query: String,
276
- confidence_threshold: Float,
277
- type: Symbol
278
- ).returns(T.attached_class)
303
+ params(confidence_threshold: Float, type: Symbol).returns(
304
+ T.attached_class
305
+ )
279
306
  end
280
- def self.new(query:, confidence_threshold: nil, type: :semantic)
307
+ def self.new(confidence_threshold: nil, type: :semantic)
281
308
  end
282
309
 
283
310
  sig do
284
- override.returns(
285
- { query: String, type: Symbol, confidence_threshold: Float }
286
- )
311
+ override.returns({ type: Symbol, confidence_threshold: Float })
287
312
  end
288
313
  def to_hash
289
314
  end
@@ -602,8 +627,9 @@ module ContextDev
602
627
 
603
628
  # Watch a sitemap for URL additions and removals. Crawled URLs are normalized
604
629
  # (lowercased host, no trailing slash/fragment) and scoped to the monitored site
605
- # and its subdomains before comparison. A new URL set must be observed on two
606
- # consecutive runs before a change is reported, suppressing one-run crawl flaps.
630
+ # and its subdomains before comparison. On a detected difference the sitemap is
631
+ # re-fetched within the same run and only URLs both observations agree on are
632
+ # reported, suppressing transient crawl flaps.
607
633
  sig do
608
634
  params(
609
635
  url: String,
@@ -650,6 +676,11 @@ module ContextDev
650
676
  )
651
677
  end
652
678
 
679
+ # Natural-language instructions guiding which pages and facts to track and which
680
+ # changes to report.
681
+ sig { returns(String) }
682
+ attr_accessor :instructions
683
+
653
684
  sig { returns(Symbol) }
654
685
  attr_accessor :type
655
686
 
@@ -663,13 +694,6 @@ module ContextDev
663
694
  sig { params(follow_subdomains: T::Boolean).void }
664
695
  attr_writer :follow_subdomains
665
696
 
666
- # Optional natural-language instructions guiding what to extract.
667
- sig { returns(T.nilable(String)) }
668
- attr_reader :instructions
669
-
670
- sig { params(instructions: String).void }
671
- attr_writer :instructions
672
-
673
697
  # Optional maximum link depth from the starting URL (0 = only the starting page).
674
698
  sig { returns(T.nilable(Integer)) }
675
699
  attr_reader :max_depth
@@ -677,27 +701,37 @@ module ContextDev
677
701
  sig { params(max_depth: Integer).void }
678
702
  attr_writer :max_depth
679
703
 
680
- # Maximum number of pages to analyze during extraction.
704
+ # Maximum number of pages to track.
681
705
  sig { returns(T.nilable(Integer)) }
682
706
  attr_reader :max_pages
683
707
 
684
708
  sig { params(max_pages: Integer).void }
685
709
  attr_writer :max_pages
686
710
 
687
- # JSON Schema describing the structured data to extract and watch for changes. If
688
- # omitted, a default summary + key-points schema is used.
711
+ # JSON Schema describing the data you care about. It is used three ways: it guides
712
+ # which pages are selected for tracking, it gives the change judge extra context
713
+ # on which changes matter (alongside `instructions`), and it defines the shape of
714
+ # the baseline `data` snapshot on GET /monitors/{monitor_id} (refreshed at most
715
+ # about once a day). It is not a response format for changes: change events and
716
+ # webhook payloads always contain diffs, summaries, and evidence excerpts — never
717
+ # data in this schema's shape. If omitted, a default summary + key-points schema
718
+ # is used.
689
719
  sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
690
720
  attr_reader :schema
691
721
 
692
722
  sig { params(schema: T::Hash[Symbol, T.anything]).void }
693
723
  attr_writer :schema
694
724
 
695
- # Watch a site's extracted structured data.
725
+ # Watch the monitor-relevant pages of a site for meaningful changes. A crawl
726
+ # guided by `schema`/`instructions` selects up to `max_pages` relevant pages to
727
+ # track; each run re-checks exactly those pages, and confirmed content changes are
728
+ # judged for relevance against the monitor's `instructions` (and `schema`, when
729
+ # provided). The tracked page set is refreshed by a periodic re-discovery crawl.
696
730
  sig do
697
731
  params(
732
+ instructions: String,
698
733
  url: String,
699
734
  follow_subdomains: T::Boolean,
700
- instructions: String,
701
735
  max_depth: Integer,
702
736
  max_pages: Integer,
703
737
  schema: T::Hash[Symbol, T.anything],
@@ -705,17 +739,24 @@ module ContextDev
705
739
  ).returns(T.attached_class)
706
740
  end
707
741
  def self.new(
742
+ # Natural-language instructions guiding which pages and facts to track and which
743
+ # changes to report.
744
+ instructions:,
708
745
  # Root URL to extract structured data from.
709
746
  url:,
710
747
  follow_subdomains: nil,
711
- # Optional natural-language instructions guiding what to extract.
712
- instructions: nil,
713
748
  # Optional maximum link depth from the starting URL (0 = only the starting page).
714
749
  max_depth: nil,
715
- # Maximum number of pages to analyze during extraction.
750
+ # Maximum number of pages to track.
716
751
  max_pages: nil,
717
- # JSON Schema describing the structured data to extract and watch for changes. If
718
- # omitted, a default summary + key-points schema is used.
752
+ # JSON Schema describing the data you care about. It is used three ways: it guides
753
+ # which pages are selected for tracking, it gives the change judge extra context
754
+ # on which changes matter (alongside `instructions`), and it defines the shape of
755
+ # the baseline `data` snapshot on GET /monitors/{monitor_id} (refreshed at most
756
+ # about once a day). It is not a response format for changes: change events and
757
+ # webhook payloads always contain diffs, summaries, and evidence excerpts — never
758
+ # data in this schema's shape. If omitted, a default summary + key-points schema
759
+ # is used.
719
760
  schema: nil,
720
761
  type: :extract
721
762
  )
@@ -724,10 +765,10 @@ module ContextDev
724
765
  sig do
725
766
  override.returns(
726
767
  {
768
+ instructions: String,
727
769
  type: Symbol,
728
770
  url: String,
729
771
  follow_subdomains: T::Boolean,
730
- instructions: String,
731
772
  max_depth: Integer,
732
773
  max_pages: Integer,
733
774
  schema: T::Hash[Symbol, T.anything]
@@ -749,6 +790,175 @@ module ContextDev
749
790
  end
750
791
  end
751
792
 
793
+ # Current baseline: the last observed value the monitor compares new snapshots
794
+ # against. Its shape follows `target.type` (page/sitemap/extract). Only populated
795
+ # on GET /monitors/{monitor_id}; null until the first baseline run completes (and
796
+ # after a target or change_detection update, which resets the baseline).
797
+ module Baseline
798
+ extend ContextDev::Internal::Type::Union
799
+
800
+ Variants =
801
+ T.type_alias do
802
+ T.any(
803
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsPageBaseline,
804
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsSitemapBaseline,
805
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsExtractBaseline
806
+ )
807
+ end
808
+
809
+ class MonitorsPageBaseline < ContextDev::Internal::Type::BaseModel
810
+ OrHash =
811
+ T.type_alias do
812
+ T.any(
813
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsPageBaseline,
814
+ ContextDev::Internal::AnyHash
815
+ )
816
+ end
817
+
818
+ # When this baseline was last captured or replaced.
819
+ sig { returns(Time) }
820
+ attr_accessor :captured_at
821
+
822
+ # The page's visible text as last observed.
823
+ sig { returns(String) }
824
+ attr_accessor :text
825
+
826
+ # Current baseline of a `page` monitor: the visible page text as last observed.
827
+ sig do
828
+ params(captured_at: Time, text: String).returns(T.attached_class)
829
+ end
830
+ def self.new(
831
+ # When this baseline was last captured or replaced.
832
+ captured_at:,
833
+ # The page's visible text as last observed.
834
+ text:
835
+ )
836
+ end
837
+
838
+ sig { override.returns({ captured_at: Time, text: String }) }
839
+ def to_hash
840
+ end
841
+ end
842
+
843
+ class MonitorsSitemapBaseline < ContextDev::Internal::Type::BaseModel
844
+ OrHash =
845
+ T.type_alias do
846
+ T.any(
847
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsSitemapBaseline,
848
+ ContextDev::Internal::AnyHash
849
+ )
850
+ end
851
+
852
+ # When this baseline was last captured or replaced.
853
+ sig { returns(Time) }
854
+ attr_accessor :captured_at
855
+
856
+ # Number of URLs in the baseline.
857
+ sig { returns(Integer) }
858
+ attr_accessor :url_count
859
+
860
+ # The sitemap URLs as last observed (sorted, normalized).
861
+ sig { returns(T::Array[String]) }
862
+ attr_accessor :urls
863
+
864
+ # Current baseline of a `sitemap` monitor: the normalized URL set as last
865
+ # observed.
866
+ sig do
867
+ params(
868
+ captured_at: Time,
869
+ url_count: Integer,
870
+ urls: T::Array[String]
871
+ ).returns(T.attached_class)
872
+ end
873
+ def self.new(
874
+ # When this baseline was last captured or replaced.
875
+ captured_at:,
876
+ # Number of URLs in the baseline.
877
+ url_count:,
878
+ # The sitemap URLs as last observed (sorted, normalized).
879
+ urls:
880
+ )
881
+ end
882
+
883
+ sig do
884
+ override.returns(
885
+ { captured_at: Time, url_count: Integer, urls: T::Array[String] }
886
+ )
887
+ end
888
+ def to_hash
889
+ end
890
+ end
891
+
892
+ class MonitorsExtractBaseline < ContextDev::Internal::Type::BaseModel
893
+ OrHash =
894
+ T.type_alias do
895
+ T.any(
896
+ ContextDev::Models::MonitorUpdateResponse::Baseline::MonitorsExtractBaseline,
897
+ ContextDev::Internal::AnyHash
898
+ )
899
+ end
900
+
901
+ # When this baseline was last captured or replaced.
902
+ sig { returns(Time) }
903
+ attr_accessor :captured_at
904
+
905
+ # The extracted structured data, matching the monitor's extraction schema (same
906
+ # shape as the /web/extract endpoint's `data`). Refreshed when the monitor
907
+ # re-discovers its page set (at most about once a day); `null` when no extraction
908
+ # has been captured yet.
909
+ sig { returns(T.anything) }
910
+ attr_accessor :data
911
+
912
+ # The page URLs the monitor tracks and analyzes for changes.
913
+ sig { returns(T::Array[String]) }
914
+ attr_accessor :urls_analyzed
915
+
916
+ # Current baseline of an `extract` monitor: the pages it tracks and the structured
917
+ # data as last extracted.
918
+ sig do
919
+ params(
920
+ captured_at: Time,
921
+ data: T.anything,
922
+ urls_analyzed: T::Array[String]
923
+ ).returns(T.attached_class)
924
+ end
925
+ def self.new(
926
+ # When this baseline was last captured or replaced.
927
+ captured_at:,
928
+ # The extracted structured data, matching the monitor's extraction schema (same
929
+ # shape as the /web/extract endpoint's `data`). Refreshed when the monitor
930
+ # re-discovers its page set (at most about once a day); `null` when no extraction
931
+ # has been captured yet.
932
+ data:,
933
+ # The page URLs the monitor tracks and analyzes for changes.
934
+ urls_analyzed:
935
+ )
936
+ end
937
+
938
+ sig do
939
+ override.returns(
940
+ {
941
+ captured_at: Time,
942
+ data: T.anything,
943
+ urls_analyzed: T::Array[String]
944
+ }
945
+ )
946
+ end
947
+ def to_hash
948
+ end
949
+ end
950
+
951
+ sig do
952
+ override.returns(
953
+ T::Array[
954
+ ContextDev::Models::MonitorUpdateResponse::Baseline::Variants
955
+ ]
956
+ )
957
+ end
958
+ def self.variants
959
+ end
960
+ end
961
+
752
962
  class LastError < ContextDev::Internal::Type::BaseModel
753
963
  OrHash =
754
964
  T.type_alias do
@@ -5,7 +5,9 @@ module ContextDev
5
5
  class Brand
6
6
  # Retrieve logos, backdrops, colors, industry, description, and more. Provide
7
7
  # exactly one lookup identifier in the request body: a domain, company name, email
8
- # address, stock ticker, or transaction descriptor.
8
+ # address, stock ticker, transaction descriptor, or direct URL. Note:
9
+ # `by_direct_url` fetches brand data only from the provided URL — not from the
10
+ # entire internet.
9
11
  sig do
10
12
  params(
11
13
  body:
@@ -14,6 +16,7 @@ module ContextDev
14
16
  ContextDev::BrandRetrieveParams::Body::ByName::OrHash,
15
17
  ContextDev::BrandRetrieveParams::Body::ByEmail::OrHash,
16
18
  ContextDev::BrandRetrieveParams::Body::ByTicker::OrHash,
19
+ ContextDev::BrandRetrieveParams::Body::ByDirectURL::OrHash,
17
20
  ContextDev::BrandRetrieveParams::Body::ByTransaction::OrHash
18
21
  ),
19
22
  request_options: ContextDev::RequestOptions::OrHash
@@ -131,8 +131,8 @@ module ContextDev
131
131
  limit: nil,
132
132
  # Free-text search term, matched against the fields named in `search_by`.
133
133
  q: nil,
134
- # Comma-separated fields to search with `q`. Defaults to all of them. Note `query`
135
- # only exists on semantic monitors.
134
+ # Comma-separated fields to search with `q`. Defaults to all of them. Note
135
+ # `instructions` only exists on extract monitors.
136
136
  search_by: nil,
137
137
  # `prefix` for as-you-type prefix matching (default), `exact` for full-token
138
138
  # matching.
@@ -25,6 +25,7 @@ module ContextDev
25
25
  | ContextDev::BrandRetrieveParams::Body::ByName
26
26
  | ContextDev::BrandRetrieveParams::Body::ByEmail
27
27
  | ContextDev::BrandRetrieveParams::Body::ByTicker
28
+ | ContextDev::BrandRetrieveParams::Body::ByDirectURL
28
29
  | ContextDev::BrandRetrieveParams::Body::ByTransaction
29
30
 
30
31
  module Body
@@ -1248,6 +1249,31 @@ module ContextDev
1248
1249
  end
1249
1250
  end
1250
1251
 
1252
+ type by_direct_url =
1253
+ { direct_url: String, type: :by_direct_url, timeout_ms: Integer }
1254
+
1255
+ class ByDirectURL < ContextDev::Internal::Type::BaseModel
1256
+ attr_accessor direct_url: String
1257
+
1258
+ attr_accessor type: :by_direct_url
1259
+
1260
+ attr_reader timeout_ms: Integer?
1261
+
1262
+ def timeout_ms=: (Integer) -> Integer
1263
+
1264
+ def initialize: (
1265
+ direct_url: String,
1266
+ ?timeout_ms: Integer,
1267
+ ?type: :by_direct_url
1268
+ ) -> void
1269
+
1270
+ def to_hash: -> {
1271
+ direct_url: String,
1272
+ type: :by_direct_url,
1273
+ timeout_ms: Integer
1274
+ }
1275
+ end
1276
+
1251
1277
  type by_transaction =
1252
1278
  {
1253
1279
  transaction_info: String,
@@ -75,12 +75,9 @@ module ContextDev
75
75
  def to_hash: -> { type: :exact }
76
76
  end
77
77
 
78
- type semantic =
79
- { query: String, type: :semantic, confidence_threshold: Float }
78
+ type semantic = { type: :semantic, confidence_threshold: Float }
80
79
 
81
80
  class Semantic < ContextDev::Internal::Type::BaseModel
82
- attr_accessor query: String
83
-
84
81
  attr_accessor type: :semantic
85
82
 
86
83
  attr_reader confidence_threshold: Float?
@@ -88,16 +85,11 @@ module ContextDev
88
85
  def confidence_threshold=: (Float) -> Float
89
86
 
90
87
  def initialize: (
91
- query: String,
92
88
  ?confidence_threshold: Float,
93
89
  ?type: :semantic
94
90
  ) -> void
95
91
 
96
- def to_hash: -> {
97
- query: String,
98
- type: :semantic,
99
- confidence_threshold: Float
100
- }
92
+ def to_hash: -> { type: :semantic, confidence_threshold: Float }
101
93
  end
102
94
 
103
95
  def self?.variants: -> ::Array[ContextDev::Models::MonitorCreateParams::change_detection]
@@ -229,16 +221,18 @@ module ContextDev
229
221
 
230
222
  type extract =
231
223
  {
224
+ instructions: String,
232
225
  type: :extract,
233
226
  url: String,
234
227
  follow_subdomains: bool,
235
- instructions: String,
236
228
  max_depth: Integer,
237
229
  max_pages: Integer,
238
230
  schema: ::Hash[Symbol, top]
239
231
  }
240
232
 
241
233
  class Extract < ContextDev::Internal::Type::BaseModel
234
+ attr_accessor instructions: String
235
+
242
236
  attr_accessor type: :extract
243
237
 
244
238
  attr_accessor url: String
@@ -247,10 +241,6 @@ module ContextDev
247
241
 
248
242
  def follow_subdomains=: (bool) -> bool
249
243
 
250
- attr_reader instructions: String?
251
-
252
- def instructions=: (String) -> String
253
-
254
244
  attr_reader max_depth: Integer?
255
245
 
256
246
  def max_depth=: (Integer) -> Integer
@@ -264,9 +254,9 @@ module ContextDev
264
254
  def schema=: (::Hash[Symbol, top]) -> ::Hash[Symbol, top]
265
255
 
266
256
  def initialize: (
257
+ instructions: String,
267
258
  url: String,
268
259
  ?follow_subdomains: bool,
269
- ?instructions: String,
270
260
  ?max_depth: Integer,
271
261
  ?max_pages: Integer,
272
262
  ?schema: ::Hash[Symbol, top],
@@ -274,10 +264,10 @@ module ContextDev
274
264
  ) -> void
275
265
 
276
266
  def to_hash: -> {
267
+ instructions: String,
277
268
  type: :extract,
278
269
  url: String,
279
270
  follow_subdomains: bool,
280
- instructions: String,
281
271
  max_depth: Integer,
282
272
  max_pages: Integer,
283
273
  schema: ::Hash[Symbol, top]